472 lines
14 KiB
C
472 lines
14 KiB
C
#include "app_config.h"
|
||
#include "typedef.h"
|
||
#include "syscfg/syscfg_id.h"
|
||
|
||
//#define CONFIG_USER_DEBUG_ENABLE //开启user_printf
|
||
//#define CONFIG_SDCARD_DEBUG_ENABLE //开关SD卡记录打印信息
|
||
//#define CONFIG_NETWORK_DEBUG_ENABLE //可以触发打印信息上传到服务器端
|
||
//#define CONFIG_USB_DEBUG_ENABLE //开关USB虚拟串口打印信息
|
||
|
||
|
||
#if (defined CONFIG_DEBUG_ENABLE && defined CONFIG_NETWORK_DEBUG_ENABLE)
|
||
#include "os/os_api.h"
|
||
#include "spinlock.h"
|
||
#include "wifi/wifi_connect.h"
|
||
#include "device/device.h"
|
||
#include "http/http_cli.h"
|
||
#include "json_c/json_object.h"
|
||
extern unsigned int time_lapse(unsigned int *handle, unsigned int time_out);
|
||
extern int lwip_dhcp_bound(void);
|
||
extern struct json_object *json_tokener_parse(const char *str);
|
||
static u32 log_cnt, log_time_hdl;
|
||
static char log_part, uploading_log_flag;
|
||
static spinlock_t lock;
|
||
static char log_buf[100 * 1024];
|
||
|
||
static int tmp_cnt = 0;
|
||
static u8 mac[6];
|
||
static u8 keycode_legal = 0;
|
||
static u8 check_keycode_cnt = 0;
|
||
#define LOG_BRAND "jieli"
|
||
#define LOG_NAME "APP"
|
||
#define LOG_VERSION "1.0.0"
|
||
#define LOG_UUID "12345678"
|
||
#define LOG_KEYCODE "" //客户随机填写12-16个字符串,用于日志查询
|
||
|
||
static void upload_log_task(void *priv)
|
||
{
|
||
#define LOG_BOUNDARY "----385424468743051437018271"
|
||
#define LOG_HTTP_HEAD_OPTION_TWO \
|
||
"POST /status/v1/log/file HTTP/1.1\r\n"\
|
||
"cache-control: no-cache\r\n"\
|
||
"Host: log.jieliapp.com\r\n"\
|
||
"content-type: multipart/form-data; boundary="LOG_BOUNDARY"\r\n"\
|
||
"content-length: %lu\r\n"\
|
||
"Connection: close\r\n\r\n"
|
||
|
||
#define LOG_BODY_OPTION_THREE \
|
||
"--"LOG_BOUNDARY"\r\n" \
|
||
"Content-Disposition: form-data; name=\"file\"; filename=\"%s.txt\"\r\n" \
|
||
"Content-Type: text/plain\r\n\r\n"
|
||
|
||
#define LOG_BODY_OPTION_FOUR \
|
||
"\r\n--"LOG_BOUNDARY"\r\n"\
|
||
"Content-Disposition: form-data; name=\"filename\"\r\n\r\n"\
|
||
"%s.txt"\
|
||
"\r\n--"LOG_BOUNDARY"\r\n"\
|
||
"Content-Disposition: form-data; name=\"platform\"\r\n\r\n"\
|
||
"device"\
|
||
"\r\n--"LOG_BOUNDARY"\r\n"\
|
||
"Content-Disposition: form-data; name=\"brand\"\r\n\r\n"\
|
||
""LOG_BRAND""\
|
||
"\r\n--"LOG_BOUNDARY"\r\n"\
|
||
"Content-Disposition: form-data; name=\"name\"\r\n\r\n"\
|
||
""LOG_NAME""\
|
||
"\r\n--"LOG_BOUNDARY"\r\n"\
|
||
"Content-Disposition: form-data; name=\"version\"\r\n\r\n"\
|
||
""LOG_VERSION""\
|
||
"\r\n--"LOG_BOUNDARY"\r\n"\
|
||
"Content-Disposition: form-data; name=\"mac\"\r\n\r\n"\
|
||
"%s"\
|
||
"\r\n--"LOG_BOUNDARY"\r\n"\
|
||
"Content-Disposition: form-data; name=\"uuid\"\r\n\r\n"\
|
||
""LOG_UUID""\
|
||
"\r\n--"LOG_BOUNDARY"\r\n"\
|
||
"Content-Disposition: form-data; name=\"keycode\"\r\n\r\n"\
|
||
""LOG_KEYCODE""\
|
||
"\r\n--"LOG_BOUNDARY"--\r\n"
|
||
|
||
int ret = 0;
|
||
char http_body_begin[512] = {0};
|
||
char user_head_buf[512] = {0};
|
||
char http_body_end[1024] = {0};
|
||
char recv_buf[1024] = {0};
|
||
|
||
if (mac[0] == '\0') {
|
||
wifi_get_mac(mac);
|
||
}
|
||
char temp_buf1[20] = {0}, temp_buf2[20] = {0};
|
||
sprintf(temp_buf1, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||
sprintf(temp_buf2, "%s-%d", temp_buf1, tmp_cnt++);
|
||
sprintf(http_body_begin, LOG_BODY_OPTION_THREE, temp_buf2);
|
||
sprintf(http_body_end, LOG_BODY_OPTION_FOUR, temp_buf2, temp_buf1);
|
||
|
||
|
||
|
||
httpcli_ctx ctx = {0};
|
||
//mode data的传输方式
|
||
int http_more_data_addr[3] = {0};
|
||
int http_more_data_len[3 + 1] = {0};
|
||
http_more_data_addr[0] = (int)(http_body_begin);
|
||
http_more_data_addr[1] = (int)log_buf;
|
||
http_more_data_addr[2] = (int)(http_body_end);
|
||
http_more_data_len[0] = strlen(http_body_begin);
|
||
http_more_data_len[1] = strlen(log_buf);
|
||
http_more_data_len[2] = strlen(http_body_end);
|
||
http_more_data_len[3] = 0;
|
||
|
||
ctx.more_data = http_more_data_addr;
|
||
ctx.more_data_len = http_more_data_len;
|
||
|
||
http_body_obj http_recv_body = {0};
|
||
http_recv_body.recv_len = 0;
|
||
http_recv_body.buf_len = 1024;
|
||
http_recv_body.buf_count = 1;
|
||
http_recv_body.p = recv_buf;
|
||
|
||
ctx.timeout_millsec = 5000;
|
||
ctx.priv = &http_recv_body;
|
||
ctx.url = "http://log.jieliapp.com/status/v1/log/file";
|
||
|
||
sprintf(user_head_buf, LOG_HTTP_HEAD_OPTION_TWO, strlen(http_body_begin) + strlen(log_buf) + strlen(http_body_end));
|
||
ctx.user_http_header = user_head_buf;
|
||
ret = httpcli_post(&ctx);
|
||
/* extern void efgh(int i); */
|
||
/* if (ret) { */
|
||
/* efgh(1); */
|
||
/* } else { */
|
||
/* efgh(0); */
|
||
/* } */
|
||
|
||
|
||
memset(log_buf, 0, sizeof(log_buf));
|
||
log_cnt = 0;
|
||
|
||
|
||
|
||
uploading_log_flag = 0;
|
||
}
|
||
|
||
static void check_keycode(void)
|
||
{
|
||
char url[128] = {0};
|
||
char recv_buf[1024] = {0};
|
||
http_body_obj http_recv_body = {0};
|
||
http_recv_body.recv_len = 0;
|
||
http_recv_body.buf_len = 1024;
|
||
http_recv_body.buf_count = 1;
|
||
http_recv_body.p = recv_buf;
|
||
httpcli_ctx ctx = {0};
|
||
sprintf(url, "http://log.jieliapp.com/status/v1/log/keycode/check?keycode=%s", LOG_KEYCODE);
|
||
ctx.timeout_millsec = 5000;
|
||
ctx.priv = &http_recv_body;
|
||
ctx.url = url;
|
||
ctx.connection = "close";
|
||
httpcli_post(&ctx);
|
||
json_object *root_node = NULL, *first_node = NULL, *second_node = NULL;
|
||
root_node = json_tokener_parse((unsigned char *)http_recv_body.p);
|
||
if (strcmp(json_object_get_string(json_object_object_get(root_node, "data")), "true") == 0) {
|
||
keycode_legal = 1;
|
||
}
|
||
json_object_put(root_node);
|
||
|
||
}
|
||
|
||
|
||
void upload_log_trig(void)
|
||
{
|
||
if (!lwip_dhcp_bound()) {
|
||
return;
|
||
}
|
||
|
||
while (keycode_legal == 0 && check_keycode_cnt < 5) {
|
||
check_keycode();
|
||
check_keycode_cnt++;
|
||
}
|
||
if (keycode_legal == 1) {
|
||
spin_lock(&lock);
|
||
if (!uploading_log_flag) {
|
||
uploading_log_flag = 1;
|
||
spin_unlock(&lock);
|
||
if (thread_fork("upload_log_task", 11, 2048, 0, 0, upload_log_task, NULL)) {
|
||
uploading_log_flag = 0;
|
||
}
|
||
return;
|
||
}
|
||
spin_unlock(&lock);
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
|
||
#if (defined CONFIG_DEBUG_ENABLE && defined CONFIG_SDCARD_DEBUG_ENABLE)
|
||
#include "system/includes.h"//cbuffer_t
|
||
#include "os/os_api.h"//创建线程,系统延时
|
||
#include "storage_device.h"//检查SD卡
|
||
#include "system/init.h"//early_initcall
|
||
#include "fs/fs.h"//操作写文件
|
||
|
||
/* 定义初始化循环BUF的大小 */
|
||
#define DATA_BUF_SIZE (20*1024)
|
||
/* CBUF数据多于DATA_BUF_SIZE/2就写入一次数据 */
|
||
#define WRITE_SIZE (DATA_BUF_SIZE/2)
|
||
|
||
static char lg_buf[DATA_BUF_SIZE]; //打印信息缓存buf
|
||
static u8 write_index; //记录写的乒乓buf的位置
|
||
static u8 write_busy; //SD卡写忙碌状态
|
||
static u8 write_flush;
|
||
static u32 write_flush_num;
|
||
static u32 write_flush_offset;
|
||
static u32 write_flush_fseek_offset;
|
||
static u8 write_flush_set_buf;
|
||
static OS_SEM sd_log_sem;
|
||
|
||
static void change_file_name(char *file_name, int len)
|
||
{
|
||
u32 log_num = 0; //文件序号变量
|
||
syscfg_read(VM_SD_LOG_INDEX, &log_num, sizeof(log_num)); //从VM读出
|
||
snprintf(file_name, len, CONFIG_ROOT_PATH"log%u.txt", log_num);
|
||
log_num++;
|
||
syscfg_write(VM_SD_LOG_INDEX, &log_num, sizeof(log_num)); //从VM写入
|
||
}
|
||
static int write_log_to_sd(const char *file_name, char *data, u32 len, u32 write_count, u8 index)
|
||
{
|
||
FILE *file = fopen(file_name, "w");
|
||
if (!file) {
|
||
file = fopen(file_name, "w+");
|
||
if (!file) {
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
fseek(file, write_count * WRITE_SIZE + write_flush_fseek_offset, SEEK_SET);
|
||
|
||
if (write_flush == 1) {
|
||
write_flush_offset = write_flush_num;
|
||
if (index) {
|
||
write_flush_fseek_offset += write_flush_offset;
|
||
} else {
|
||
write_flush_fseek_offset += (write_flush_offset - WRITE_SIZE);
|
||
}
|
||
|
||
write_flush_set_buf = 1;
|
||
fwrite(index ? data : (data + WRITE_SIZE), index ? write_flush_offset : (write_flush_offset - WRITE_SIZE), 1, file);
|
||
} else {
|
||
fwrite(index ? data : (data + len), len, 1, file);
|
||
}
|
||
fclose(file);
|
||
return 0;
|
||
}
|
||
static void sd_log_task(void *priv)
|
||
{
|
||
u32 write_count = 0; //记录写的总次数
|
||
u8 last_write_time = 0xff;
|
||
u8 sd_state = 0;
|
||
char file_name[64];
|
||
|
||
write_flush = 0;
|
||
write_flush_offset = 0;
|
||
write_flush_fseek_offset = 0;
|
||
write_flush_set_buf = 0;
|
||
|
||
change_file_name(file_name, sizeof(file_name));
|
||
|
||
while (1) {
|
||
if (!storage_device_ready()) { //SD卡未就绪
|
||
if (sd_state) {
|
||
sd_state = 0;
|
||
/* write_busy = 0; //清空标记位 */
|
||
write_count = 0;
|
||
last_write_time = 0xff;
|
||
change_file_name(file_name, sizeof(file_name));
|
||
}
|
||
os_time_dly(20);
|
||
} else { //SD卡就绪
|
||
sd_state = 1;
|
||
if (last_write_time != write_index && write_busy) {
|
||
write_busy = 0; //标记已经写入数据
|
||
last_write_time = write_index; //记录上一包数据号
|
||
if (0 == write_log_to_sd(file_name, lg_buf, WRITE_SIZE, write_count, write_index)) {
|
||
if (write_flush == 1) {
|
||
write_flush = 0;
|
||
} else {
|
||
++write_count;
|
||
}
|
||
}
|
||
}
|
||
if (write_busy && last_write_time == write_index) { //需要写入数据并且数据包和上一包一样
|
||
printf("SD_WRITE_[ERROR],Packet maybe loss!!!!!");
|
||
}
|
||
|
||
os_sem_pend(&sd_log_sem, 0);
|
||
}
|
||
}
|
||
}
|
||
|
||
static int sd_log_task_create(void)
|
||
{
|
||
#define SD_LOG_STK_SIZE 512
|
||
static u8 sd_log_tcb_stk_q[sizeof(StaticTask_t) + SD_LOG_STK_SIZE * 4] ALIGNE(4);
|
||
os_sem_create(&sd_log_sem, 0);
|
||
os_task_create_static(sd_log_task, 0, 5, SD_LOG_STK_SIZE, 0, "sd_log_task", sd_log_tcb_stk_q);
|
||
return 0;
|
||
}
|
||
module_initcall(sd_log_task_create);
|
||
#endif
|
||
|
||
|
||
|
||
#if (defined CONFIG_DEBUG_ENABLE && defined CONFIG_USB_DEBUG_ENABLE)
|
||
#include "os/os_api.h"//创建线程,系统延时
|
||
#include "system/init.h"//early_initcall
|
||
|
||
extern u32 cdc_write_data(int usb_id, u8 *buf, u32 len);
|
||
|
||
#define DATA_BUF_SIZE (200 * 1024)
|
||
|
||
static u32 lg_cnt, last_cnt;
|
||
static char lg_buf[DATA_BUF_SIZE]; //打印信息缓存值
|
||
|
||
static void usb_log_task(void *priv)
|
||
{
|
||
os_time_dly(300);
|
||
|
||
while (1) {
|
||
if (lg_cnt > last_cnt && last_cnt != lg_cnt) {
|
||
if (lg_cnt / sizeof(lg_buf) > last_cnt / sizeof(lg_buf)) {
|
||
cdc_write_data(0, (u8 *)lg_buf + (last_cnt % sizeof(lg_buf)), sizeof(lg_buf) - last_cnt % sizeof(lg_buf));
|
||
cdc_write_data(1, (u8 *)lg_buf + (last_cnt % sizeof(lg_buf)), sizeof(lg_buf) - last_cnt % sizeof(lg_buf));
|
||
cdc_write_data(0, (u8 *)lg_buf, lg_cnt - last_cnt - (sizeof(lg_buf) - last_cnt % sizeof(lg_buf)));
|
||
cdc_write_data(1, (u8 *)lg_buf, lg_cnt - last_cnt - (sizeof(lg_buf) - last_cnt % sizeof(lg_buf)));
|
||
} else {
|
||
cdc_write_data(0, (u8 *)lg_buf + (last_cnt % sizeof(lg_buf)), lg_cnt - last_cnt);
|
||
cdc_write_data(1, (u8 *)lg_buf + (last_cnt % sizeof(lg_buf)), lg_cnt - last_cnt);
|
||
}
|
||
}
|
||
last_cnt = lg_cnt;
|
||
os_time_dly(10);
|
||
}
|
||
}
|
||
|
||
static int usb_log_task_create(void)
|
||
{
|
||
#define USB_LOG_STK_SIZE 256
|
||
static u8 usb_log_tcb_stk_q[sizeof(StaticTask_t) + USB_LOG_STK_SIZE * 4 + sizeof(StaticQueue_t)] ALIGNE(4);
|
||
return os_task_create_static(usb_log_task, 0, 1, USB_LOG_STK_SIZE, 0, "usb_log_task", usb_log_tcb_stk_q);
|
||
}
|
||
module_initcall(usb_log_task_create);
|
||
#endif
|
||
|
||
|
||
|
||
//////////////////////////////////////////
|
||
|
||
#if (defined CONFIG_NETWORK_DEBUG_ENABLE || defined CONFIG_SDCARD_DEBUG_ENABLE || defined CONFIG_USB_DEBUG_ENABLE)
|
||
void putbyte(char c)
|
||
{
|
||
#if defined CONFIG_NETWORK_DEBUG_ENABLE
|
||
log_buf[(log_cnt++) % (sizeof(log_buf))] = c;
|
||
#endif
|
||
#if defined CONFIG_SDCARD_DEBUG_ENABLE
|
||
static u32 lg_cnt = 0; //记录数据个数
|
||
static u8 first_write = 1;
|
||
u32 t;
|
||
if (write_flush_set_buf) {
|
||
if (write_index) {
|
||
lg_cnt = WRITE_SIZE;
|
||
|
||
} else {
|
||
lg_cnt = 0;
|
||
}
|
||
t = (lg_cnt++) % (sizeof(lg_buf));
|
||
|
||
first_write = 1;
|
||
|
||
write_flush_set_buf = 0;
|
||
|
||
} else {
|
||
t = (lg_cnt++) % (sizeof(lg_buf));
|
||
}
|
||
lg_buf[t] = c;
|
||
write_flush_num = t;
|
||
if (!first_write && !(t % WRITE_SIZE)) {//判断t为WRITE_SIZE的整数倍
|
||
write_busy = 1;//标记需要写入数据
|
||
write_index = t / WRITE_SIZE;//write_index只为0或1,为1时是第一包数据,为0时是第二包数据
|
||
if (os_sem_valid(&sd_log_sem)) {
|
||
os_sem_set(&sd_log_sem, 1);
|
||
os_sem_post(&sd_log_sem);
|
||
}
|
||
}
|
||
first_write = 0;
|
||
#endif
|
||
#if defined CONFIG_USB_DEBUG_ENABLE
|
||
if (c == '\r') {
|
||
return;
|
||
}
|
||
if (c == '\n') {
|
||
lg_buf[(lg_cnt++) % (sizeof(lg_buf))] = '\r';
|
||
}
|
||
lg_buf[(lg_cnt++) % (sizeof(lg_buf))] = c;
|
||
#endif
|
||
}
|
||
|
||
#if defined CONFIG_SDCARD_DEBUG_ENABLE
|
||
int sd_log_flush()
|
||
{
|
||
write_busy = 1;//标记需要写入数据
|
||
if (os_sem_valid(&sd_log_sem)) {
|
||
write_flush = 1;
|
||
|
||
if (write_index) {
|
||
write_index = 0;
|
||
} else {
|
||
write_index = 1;
|
||
}
|
||
|
||
os_sem_set(&sd_log_sem, 1);
|
||
os_sem_post(&sd_log_sem);
|
||
|
||
while (write_flush) {
|
||
os_time_dly(3);
|
||
printf("sd_log_flush wait write\n\r");
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
#endif
|
||
|
||
#endif
|
||
|
||
#if (!defined CONFIG_DEBUG_ENABLE && !defined CONFIG_USER_DEBUG_ENABLE)
|
||
//关闭user_printf用户打印
|
||
int user_putchar(int a)
|
||
{
|
||
return a;
|
||
}
|
||
int user_puts(const char *out)
|
||
{
|
||
return 0;
|
||
}
|
||
int user_printf(const char *format, ...)
|
||
{
|
||
return 0;
|
||
}
|
||
int user_vprintf(const char *restrict format, va_list arg)
|
||
{
|
||
return 0;
|
||
}
|
||
void user_put_buf(const u8 *buf, int len)
|
||
{
|
||
}
|
||
void user_put_u8hex(u8 dat)
|
||
{
|
||
}
|
||
void user_put_u16hex(u16 dat)
|
||
{
|
||
}
|
||
void user_put_u32hex(u32 dat)
|
||
{
|
||
}
|
||
#elif (defined CONFIG_USER_DEBUG_ENABLE)
|
||
int user_putchar(int a)//用户的user_printf 的底层发送函数
|
||
{
|
||
putbyte(a);//可以换用户的串口发送函数
|
||
return a;
|
||
}
|
||
#endif
|
||
|