769 lines
21 KiB
C
769 lines
21 KiB
C
|
#include <stdlib.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include "FreeRTOS.h"
|
||
|
#include "task.h"
|
||
|
#include "queue.h"
|
||
|
|
||
|
#include "board.h"
|
||
|
#include "chip.h"
|
||
|
#include "animation.h"
|
||
|
#include "sfud.h"
|
||
|
#include "romfile.h"
|
||
|
#include "updatefile.h"
|
||
|
#include "sysinfo.h"
|
||
|
#include "mmcsd_core.h"
|
||
|
#include "ff_stdio.h"
|
||
|
#include "ota_update.h"
|
||
|
#include "md5.h"
|
||
|
#include "unzip.h"
|
||
|
#include "ff_sddisk.h"
|
||
|
|
||
|
#include "FreeRTOS_Sockets.h"
|
||
|
#include "FreeRTOS_IP.h"
|
||
|
#include "FreeRTOS_DHCP.h"
|
||
|
#include "iperf_task.h"
|
||
|
#include "iot_wifi.h"
|
||
|
#include "FreeRTOS_DHCP_Server.h"
|
||
|
|
||
|
extern FF_Disk_t *sdmmc_disk;
|
||
|
|
||
|
#ifdef NCM_UPDATE_SUPPORT
|
||
|
|
||
|
#define FRAME_HEADER_MAGIC 0xA5FF5AFF
|
||
|
#define FRAME_TAIL_MAGIC 0x5AFFA5FF
|
||
|
#define VERSION_LEN 64
|
||
|
#define FILENAME_LEN 128
|
||
|
#define MD5_LEN 32
|
||
|
#define MAX_PATH 256
|
||
|
|
||
|
typedef enum {
|
||
|
IP_CANNOT_FILE_TFR = 7111,
|
||
|
IP_FW_CANNOT_TFR = 7121,
|
||
|
IP_ERR_DATA_LEN = 7122,
|
||
|
IP_ERR_OFFSET = 7123,
|
||
|
IP_ERR_FILE_CHECK = 7141,
|
||
|
IP_SPEED_FAIL = 7301,
|
||
|
IP_POWER_FAIL = 7302,
|
||
|
IP_GEAR_FAIL = 7304,
|
||
|
IP_UPDATE_ABORT = 7411,
|
||
|
IP_ROLL_BACK_FAIL = 7511,
|
||
|
} ENegCode;
|
||
|
|
||
|
typedef struct {
|
||
|
uint32_t header;
|
||
|
uint32_t type;
|
||
|
uint32_t sub_type;
|
||
|
uint32_t len;
|
||
|
} HUFrame;
|
||
|
|
||
|
typedef struct {
|
||
|
uint32_t header;
|
||
|
uint32_t type;
|
||
|
uint32_t sub_type;
|
||
|
uint32_t rsp_flag;
|
||
|
uint32_t len;
|
||
|
} IPFrame;
|
||
|
|
||
|
typedef struct {
|
||
|
char hard_partnumber[VERSION_LEN];
|
||
|
char hard_version[VERSION_LEN];
|
||
|
char soft_partnumber[VERSION_LEN];
|
||
|
char soft_version[VERSION_LEN];
|
||
|
} ReqVersionPosiRsp;
|
||
|
|
||
|
typedef struct {
|
||
|
uint32_t negative_code;
|
||
|
} ReqVersionNegRsp;
|
||
|
|
||
|
typedef struct {
|
||
|
char file_name[FILENAME_LEN];
|
||
|
uint32_t file_length;
|
||
|
char file_md5[MD5_LEN];
|
||
|
} ReqFileCheckRsp;
|
||
|
|
||
|
typedef struct {
|
||
|
char file_name[FILENAME_LEN];
|
||
|
uint32_t file_length;
|
||
|
char file_md5[MD5_LEN];
|
||
|
uint32_t offset;
|
||
|
} ReqFileWriteRsp;
|
||
|
|
||
|
static Socket_t net_client_socket;
|
||
|
|
||
|
#define FRAME_MAX_LEN 0x100000
|
||
|
static int net_rev_state = 0;
|
||
|
static int net_state_len = 0;
|
||
|
static int net_rev_len = 0;
|
||
|
static uint32_t net_frame_type = 0;
|
||
|
static uint32_t net_frame_subtype = 0;
|
||
|
static uint32_t net_frame_len = 0;
|
||
|
static int net_toolong_frame = 0;
|
||
|
static uint8_t *net_frame_buf;
|
||
|
static char cur_file_md5[MD5_LEN];
|
||
|
static char cur_file_name[MAX_PATH];
|
||
|
|
||
|
static void netSendFrame(uint32_t type, uint32_t subtype, uint32_t rsp_flag, void *data, uint32_t len)
|
||
|
{
|
||
|
IPFrame *ipframe = NULL;
|
||
|
uint8_t *tmp;
|
||
|
int32_t leftsize;
|
||
|
BaseType_t ret;
|
||
|
u32 errcnt = 0;
|
||
|
|
||
|
printf("send frame type=0x%x, subtype=0x%x, rsp_flag=%d, data=0x%x, len=%d.\n",
|
||
|
type, subtype, rsp_flag, data, len);
|
||
|
ipframe = (IPFrame*)pvPortMalloc(sizeof(IPFrame) + len + 4);
|
||
|
if (ipframe) {
|
||
|
ipframe->header = FRAME_HEADER_MAGIC;
|
||
|
ipframe->type = type;
|
||
|
ipframe->sub_type = subtype;
|
||
|
ipframe->rsp_flag = rsp_flag;
|
||
|
ipframe->len = len;
|
||
|
tmp = (uint8_t*)ipframe + sizeof(IPFrame);
|
||
|
if (len) {
|
||
|
memcpy(tmp, data, len);
|
||
|
tmp += len;
|
||
|
}
|
||
|
*(uint32_t *)tmp = FRAME_TAIL_MAGIC;
|
||
|
}
|
||
|
|
||
|
leftsize = sizeof(IPFrame) + len + 4;
|
||
|
tmp = (uint8_t *)ipframe;
|
||
|
while (leftsize > 0) {
|
||
|
ret = FreeRTOS_send(net_client_socket, tmp, leftsize, 0);
|
||
|
if (ret > 0) {
|
||
|
leftsize -= ret;
|
||
|
tmp += leftsize;
|
||
|
errcnt = 0;
|
||
|
} else {
|
||
|
//printf("FreeRTOS_send err %d.\n", ret);
|
||
|
TRACE_INFO("FreeRTOS_send err %d.\n", ret);
|
||
|
if (errcnt++ > 100) {
|
||
|
//printf("FreeRTOS_send fail.\n");
|
||
|
TRACE_INFO("FreeRTOS_send fail.\n");
|
||
|
break;
|
||
|
}
|
||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||
|
}
|
||
|
}
|
||
|
vPortFree(ipframe);
|
||
|
}
|
||
|
|
||
|
static int install_update_file(char *filename)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < UPFILE_TYPE_NUM; i++) {
|
||
|
if (!strcmp(filename, g_upfilename[i])) {
|
||
|
return update_from_media(OTA_MOUNT_PATH, i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
static u32 create_file_err_count = 0;
|
||
|
static void RevFrameHandler(uint32_t type, uint32_t subtype, uint8_t *data, uint32_t len)
|
||
|
{
|
||
|
printf("rev frame type=0x%x, subtype=0x%x, data=0x%x, len=%d.\n", type, subtype, data, len);
|
||
|
switch (type) {
|
||
|
case 0x70:
|
||
|
if (subtype == 0x01) {
|
||
|
if (1) {
|
||
|
ReqVersionPosiRsp rsp = {0};
|
||
|
//strcpy(rsp.hard_partnumber, "aaa");
|
||
|
//strcpy(rsp.hard_version, "01.00.00");
|
||
|
strcpy(rsp.soft_partnumber, "23847069");
|
||
|
strcpy(rsp.soft_version, "SW:-.-.-");
|
||
|
netSendFrame(0x70, 0x01, 0x01, &rsp, sizeof(rsp));
|
||
|
} else {
|
||
|
ReqVersionNegRsp rsp = {0};
|
||
|
rsp.negative_code = 7011;
|
||
|
netSendFrame(0x70, 0x01, 0x00, &rsp, sizeof(rsp));
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 0x71:
|
||
|
if (subtype == 0x01) {
|
||
|
FF_FILE *fp = NULL;
|
||
|
ReqFileWriteRsp rsp = {0};
|
||
|
char filename[FILENAME_LEN+4];
|
||
|
FF_FILE *fmd5 = NULL;
|
||
|
char md5name[FILENAME_LEN+16];
|
||
|
char md5[MD5_LEN];
|
||
|
uint32_t err_code =IP_CANNOT_FILE_TFR;
|
||
|
|
||
|
if (len != FILENAME_LEN + 4 + MD5_LEN && len != FILENAME_LEN + 4) {
|
||
|
printf("invalid len %d.\n", len);
|
||
|
netSendFrame(0x71, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
memcpy(rsp.file_name, data, FILENAME_LEN);
|
||
|
memcpy(&rsp.file_length, data + FILENAME_LEN, 4);
|
||
|
if (len == FILENAME_LEN + 4 + MD5_LEN) {
|
||
|
memcpy(rsp.file_md5, data + FILENAME_LEN + 4, MD5_LEN);
|
||
|
memcpy(cur_file_md5, data + FILENAME_LEN + 4, MD5_LEN);
|
||
|
} else {
|
||
|
memset(cur_file_md5, 0, MD5_LEN);
|
||
|
}
|
||
|
printf("rev update file %s, length is 0x%x.\n", rsp.file_name, rsp.file_length);
|
||
|
|
||
|
strcpy(md5name, OTA_MOUNT_PATH "/");
|
||
|
strcat(md5name, rsp.file_name);
|
||
|
strcat(md5name, ".md5");
|
||
|
strcpy(filename, OTA_MOUNT_PATH "/");
|
||
|
strcat(filename, rsp.file_name);
|
||
|
fp = ff_fopen(filename, "rb");
|
||
|
if (fp) {
|
||
|
fmd5 = ff_fopen(md5name, "rb");
|
||
|
if (fmd5) {
|
||
|
ff_fread(md5, 1, MD5_LEN, fmd5);
|
||
|
if (memcmp(md5, cur_file_md5, MD5_LEN)) {
|
||
|
printf("md5 is not same as previous, rev new file.\n");
|
||
|
ff_fclose(fp);
|
||
|
ff_remove(filename);
|
||
|
ff_fclose(fmd5);
|
||
|
ff_remove(md5name);
|
||
|
fmd5 = NULL;
|
||
|
} else {
|
||
|
printf("md5 is same as previous, continue rev.\n");
|
||
|
rsp.offset = ff_filelength(fp);
|
||
|
ff_fclose(fmd5);
|
||
|
ff_fclose(fp);
|
||
|
}
|
||
|
} else {
|
||
|
ff_fclose(fp);
|
||
|
ff_remove(filename);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!fmd5) {
|
||
|
fmd5 = ff_fopen(md5name, "wb");
|
||
|
if (!fmd5) {
|
||
|
uint32_t err_code = IP_CANNOT_FILE_TFR;
|
||
|
netSendFrame(0x71, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
if (++create_file_err_count > 3) {
|
||
|
FF_SDDiskFormatRemount(sdmmc_disk, SDMMC_MOUNT_PATH);
|
||
|
create_file_err_count = 0;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
ff_fwrite(cur_file_md5, 1, MD5_LEN, fmd5);
|
||
|
ff_fclose(fmd5);
|
||
|
rsp.offset = 0;
|
||
|
}
|
||
|
netSendFrame(0x71, 0x01, 0x01, &rsp, sizeof(rsp));
|
||
|
} else if (subtype == 0x02) {
|
||
|
FF_FILE *fp;
|
||
|
ReqFileWriteRsp rsp = {0};
|
||
|
char filename[FILENAME_LEN + 4];
|
||
|
uint32_t data_length;
|
||
|
uint32_t offset;
|
||
|
uint32_t err_code;
|
||
|
|
||
|
memcpy(rsp.file_name, data, FILENAME_LEN);
|
||
|
memcpy(&rsp.file_length, data + FILENAME_LEN, 4);
|
||
|
memcpy(&data_length, data + FILENAME_LEN + 4, 4);
|
||
|
memcpy(&offset, data + FILENAME_LEN + 8, 4);
|
||
|
printf("rev update data %s, offset=0x%x, data_length=0x%x.\n",
|
||
|
rsp.file_name, offset, data_length);
|
||
|
|
||
|
if (len != FILENAME_LEN + 12 + data_length) {
|
||
|
printf("invalid len %d.\n", len);
|
||
|
err_code= IP_ERR_DATA_LEN;
|
||
|
netSendFrame(0x71, 0x02, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (net_toolong_frame) {
|
||
|
err_code= IP_ERR_DATA_LEN;
|
||
|
netSendFrame(0x71, 0x02, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
strcpy(filename, OTA_MOUNT_PATH "/");
|
||
|
strcat(filename, rsp.file_name);
|
||
|
fp = ff_fopen(filename, "a+");
|
||
|
if (fp) {
|
||
|
rsp.offset = ff_filelength(fp);
|
||
|
if (rsp.offset != offset) {
|
||
|
printf("error! rev offset isn't equal to saved file length.\n");
|
||
|
err_code= IP_FW_CANNOT_TFR;
|
||
|
netSendFrame(0x71, 0x02, 0x00, &err_code, sizeof(err_code));
|
||
|
} else {
|
||
|
if (ff_fwrite(data + 140, 1, data_length, fp) == data_length) {
|
||
|
memcpy(rsp.file_md5, cur_file_md5, MD5_LEN);
|
||
|
netSendFrame(0x71, 0x02, 0x01, &rsp, sizeof(rsp));
|
||
|
} else {
|
||
|
err_code= IP_FW_CANNOT_TFR;
|
||
|
netSendFrame(0x71, 0x02, 0x00, &err_code, sizeof(err_code));
|
||
|
}
|
||
|
}
|
||
|
ff_fclose(fp);
|
||
|
} else {
|
||
|
printf("create %s fail.\n", filename);
|
||
|
err_code= IP_FW_CANNOT_TFR;
|
||
|
netSendFrame(0x71, 0x02, 0x00, &err_code, sizeof(err_code));
|
||
|
}
|
||
|
} else if (subtype == 0x03) {
|
||
|
uint8_t reserved[256] = {0};
|
||
|
printf("file transfer finished.\n");
|
||
|
netSendFrame(0x71, 0x03, 0x01, reserved, 256);
|
||
|
} else if (subtype == 0x04) {
|
||
|
printf("start file check...\n");
|
||
|
FF_FILE *fp;
|
||
|
ReqFileCheckRsp rsp = {0};
|
||
|
char filename[FILENAME_LEN+4];
|
||
|
uint32_t err_code = IP_ERR_FILE_CHECK;
|
||
|
|
||
|
if (len != FILENAME_LEN + 4 + MD5_LEN) {
|
||
|
printf("invalid len %d.\n", len);
|
||
|
netSendFrame(0x71, 0x04, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
memcpy(rsp.file_name, data, FILENAME_LEN);
|
||
|
memcpy(&rsp.file_length, data + FILENAME_LEN, 4);
|
||
|
memcpy(rsp.file_md5, data + FILENAME_LEN + 4, MD5_LEN);
|
||
|
|
||
|
strcpy(filename, OTA_MOUNT_PATH "/");
|
||
|
strcat(filename, rsp.file_name);
|
||
|
fp = ff_fopen(filename, "rb");
|
||
|
if (fp && ff_filelength(fp) == rsp.file_length) {
|
||
|
md5_context ctx = {0};
|
||
|
int leftsize = rsp.file_length;
|
||
|
void *cbuf = pvPortMalloc(IMAGE_RW_SIZE);
|
||
|
int rsize;
|
||
|
unsigned char md5out[16];
|
||
|
char md5string[MD5_LEN + 1];
|
||
|
int i;
|
||
|
|
||
|
if (cbuf) {
|
||
|
md5_starts(&ctx);
|
||
|
while (leftsize > 0) {
|
||
|
rsize = leftsize > IMAGE_RW_SIZE ? IMAGE_RW_SIZE : leftsize;
|
||
|
ff_fread(cbuf, 1, rsize, fp);
|
||
|
md5_update(&ctx, cbuf, rsize);
|
||
|
leftsize -= rsize;
|
||
|
}
|
||
|
md5_finish(&ctx, md5out);
|
||
|
vPortFree(cbuf);
|
||
|
for (i = 0; i < 16; i++)
|
||
|
sprintf(md5string + 2*i, "%.2x", md5out[i]);
|
||
|
if (!memcmp(md5string, rsp.file_md5, MD5_LEN)) {
|
||
|
printf("file check ok.\n");
|
||
|
ff_fclose(fp);
|
||
|
strcpy(cur_file_name, rsp.file_name);
|
||
|
netSendFrame(0x71, 0x04, 0x01, &rsp, sizeof(rsp));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
printf("file check fail.\n");
|
||
|
if (fp) {
|
||
|
ff_fclose(fp);
|
||
|
ff_remove(filename);
|
||
|
}
|
||
|
memset(cur_file_name, 0, MAX_PATH);
|
||
|
netSendFrame(0x71, 0x04, 0x00, &err_code, sizeof(err_code));
|
||
|
}
|
||
|
break;
|
||
|
case 0x72:
|
||
|
if (subtype == 0x01) {
|
||
|
} else if (subtype == 0x02) {
|
||
|
}
|
||
|
break;
|
||
|
case 0x73:
|
||
|
if (subtype == 0x01) {
|
||
|
uint8_t reserved[256] = {0};
|
||
|
printf("installation condition check ok\n");
|
||
|
netSendFrame(0x73, 0x01, 0x01, reserved, 256);
|
||
|
}
|
||
|
break;
|
||
|
case 0x74:
|
||
|
if (subtype == 0x01) {
|
||
|
uint8_t reserved[256] = {0};
|
||
|
uint32_t err_code = IP_UPDATE_ABORT;
|
||
|
FF_FILE *fp;
|
||
|
unzFile zf;
|
||
|
unz_global_info ginfo;
|
||
|
unz_file_info finfo;
|
||
|
char filename[256];
|
||
|
char *buf;
|
||
|
int leftsize, wsize;
|
||
|
int ret;
|
||
|
int i;
|
||
|
char filepath[256 + 16];
|
||
|
|
||
|
if (strlen(cur_file_name) == 0) {
|
||
|
printf("not found update file.\n");
|
||
|
netSendFrame(0x74, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
printf("start install update file...\n");
|
||
|
strcpy(filepath, OTA_MOUNT_PATH "/");
|
||
|
strcat(filepath, cur_file_name);
|
||
|
zf = unzOpen(filepath);
|
||
|
if (!zf) {
|
||
|
printf("open zip file fail.\n");
|
||
|
netSendFrame(0x74, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
buf = malloc(IMAGE_RW_SIZE);
|
||
|
if (!buf) {
|
||
|
netSendFrame(0x74, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
unzGetGlobalInfo(zf, &ginfo);
|
||
|
for (i = 0; i < ginfo.number_entry; i++) {
|
||
|
ret = unzGetCurrentFileInfo(zf, &finfo, filename, 256, NULL, 0, NULL, 0);
|
||
|
if (ret != UNZ_OK) {
|
||
|
printf("unzGetCurrentFileInfo fail.\n");
|
||
|
netSendFrame(0x74, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
printf("unzip file %s.\n", filename);
|
||
|
ret = unzOpenCurrentFile(zf);
|
||
|
if (ret != UNZ_OK) {
|
||
|
printf("unzOpenCurrentFile fail.\n");
|
||
|
netSendFrame(0x74, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
leftsize = finfo.uncompressed_size;
|
||
|
strcpy(filepath, OTA_MOUNT_PATH "/");
|
||
|
strcat(filepath, filename);
|
||
|
fp = ff_fopen(filepath, "wb");
|
||
|
if (!fp) {
|
||
|
printf("create %s fail.\n", filepath);
|
||
|
unzCloseCurrentFile(zf);
|
||
|
netSendFrame(0x74, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
if (++create_file_err_count > 3) {
|
||
|
FF_SDDiskFormatRemount(sdmmc_disk, SDMMC_MOUNT_PATH);
|
||
|
create_file_err_count = 0;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
while (leftsize > 0) {
|
||
|
wsize = leftsize > IMAGE_RW_SIZE ? IMAGE_RW_SIZE : leftsize;
|
||
|
unzReadCurrentFile(zf, buf, wsize);
|
||
|
if (ff_fwrite(buf, 1, wsize, fp) != wsize) {
|
||
|
printf("ff_fwrite fail.\n");
|
||
|
break;
|
||
|
}
|
||
|
leftsize -= wsize;
|
||
|
}
|
||
|
ff_fclose(fp);
|
||
|
if (leftsize > 0) {
|
||
|
netSendFrame(0x74, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
if (install_update_file(filename)) {
|
||
|
printf("install update file %s fail.\n", filename);
|
||
|
netSendFrame(0x74, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
unzCloseCurrentFile(zf);
|
||
|
ret = unzGoToNextFile(zf);
|
||
|
if (ret != UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE) {
|
||
|
printf("unzGoToNextFile fail.\n");
|
||
|
netSendFrame(0x74, 0x01, 0x00, &err_code, sizeof(err_code));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
free(buf);
|
||
|
unzClose(zf);
|
||
|
if (i == ginfo.number_entry && ret == UNZ_END_OF_LIST_OF_FILE)
|
||
|
netSendFrame(0x74, 0x01, 0x01, reserved, 256);
|
||
|
}
|
||
|
break;
|
||
|
case 0x75:
|
||
|
if (subtype == 0x01) {
|
||
|
uint8_t reserved[256] = {0};
|
||
|
printf("roll back ok\n");
|
||
|
netSendFrame(0x75, 0x01, 0x01, reserved, 256);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void RevDataHandler(uint8_t *buf, int32_t len)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < len; i++) {
|
||
|
switch (net_rev_state) {
|
||
|
case 0: //head receive
|
||
|
if (net_state_len == 0 && buf[i] == 0xff) {
|
||
|
net_state_len++;
|
||
|
} else if (net_state_len == 1 && buf[i] == 0x5a) {
|
||
|
net_state_len++;
|
||
|
} else if (net_state_len == 2 && buf[i] == 0xff) {
|
||
|
net_state_len++;
|
||
|
} else if (net_state_len == 3 && buf[i] == 0xa5) {
|
||
|
net_rev_state++;
|
||
|
net_state_len = 0;
|
||
|
net_frame_type = 0;
|
||
|
net_frame_subtype = 0;
|
||
|
net_frame_len = 0;
|
||
|
} else if (buf[i] == 0xff) {
|
||
|
net_state_len = 1;
|
||
|
} else {
|
||
|
net_state_len = 0;
|
||
|
}
|
||
|
break;
|
||
|
case 1: //type receive
|
||
|
net_frame_type |= buf[i] << (8 * net_state_len);
|
||
|
if (++net_state_len == 4) {
|
||
|
net_rev_state++;
|
||
|
net_state_len = 0;
|
||
|
}
|
||
|
break;
|
||
|
case 2: //sub_type receive
|
||
|
net_frame_subtype |= buf[i] << (8 * net_state_len);
|
||
|
if (++net_state_len == 4) {
|
||
|
net_rev_state++;
|
||
|
net_state_len = 0;
|
||
|
}
|
||
|
break;
|
||
|
case 3: //data len receive
|
||
|
net_frame_len |= buf[i] << (8 * net_state_len);
|
||
|
if (++net_state_len == 4) {
|
||
|
if (net_frame_len > FRAME_MAX_LEN) {
|
||
|
printf("Invalid NCM frame len 0x%x.\n", net_frame_len);
|
||
|
net_toolong_frame = 1;
|
||
|
} else {
|
||
|
net_toolong_frame = 0;
|
||
|
}
|
||
|
if (net_frame_len == 0)
|
||
|
net_rev_state += 2;
|
||
|
else
|
||
|
net_rev_state++;
|
||
|
net_rev_len = 0;
|
||
|
net_state_len = 0;
|
||
|
}
|
||
|
break;
|
||
|
case 4: //data receive
|
||
|
if (net_rev_len < FRAME_MAX_LEN)
|
||
|
net_frame_buf[net_rev_len] = buf[i];
|
||
|
if (++net_rev_len == net_frame_len)
|
||
|
net_rev_state++;
|
||
|
break;
|
||
|
case 5: //tail receive
|
||
|
if (net_state_len == 0 && buf[i] == 0xff) {
|
||
|
net_state_len++;
|
||
|
} else if (net_state_len == 1 && buf[i] == 0xa5) {
|
||
|
net_state_len++;
|
||
|
} else if (net_state_len == 2 && buf[i] == 0xff) {
|
||
|
net_state_len++;
|
||
|
} else if (net_state_len == 3 && buf[i] == 0x5a) {
|
||
|
RevFrameHandler(net_frame_type, net_frame_subtype, net_frame_buf, net_frame_len);
|
||
|
net_rev_state = 0;
|
||
|
net_state_len = 0;
|
||
|
} else {
|
||
|
net_state_len = 0;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void set_socket_win_net(Socket_t xSockets)
|
||
|
{
|
||
|
WinProperties_t xWinProperties;
|
||
|
|
||
|
memset(&xWinProperties, '\0', sizeof xWinProperties);
|
||
|
|
||
|
xWinProperties.lTxBufSize = ipconfigIPERF_TX_BUFSIZE; /* Units of bytes. */
|
||
|
xWinProperties.lTxWinSize = ipconfigIPERF_TX_WINSIZE; /* Size in units of MSS */
|
||
|
xWinProperties.lRxBufSize = ipconfigIPERF_RX_BUFSIZE; /* Units of bytes. */
|
||
|
xWinProperties.lRxWinSize = ipconfigIPERF_RX_WINSIZE; /* Size in units of MSS */
|
||
|
|
||
|
FreeRTOS_setsockopt( xSockets, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProperties, sizeof( xWinProperties ) );
|
||
|
}
|
||
|
|
||
|
void print_hex(unsigned char *data, int len, const char* tag)
|
||
|
{
|
||
|
unsigned long i, j, l;
|
||
|
unsigned char tmp_str[140];
|
||
|
unsigned char tmp_str1[10];
|
||
|
|
||
|
for (i = 0; i < len; i += 16) {
|
||
|
int n ;
|
||
|
tmp_str[0] = '\0';
|
||
|
n = i ;
|
||
|
|
||
|
for (j = 0; j < 4; j++) {
|
||
|
l = n % 16;
|
||
|
|
||
|
if (l >= 10)
|
||
|
tmp_str[3 - j] = (unsigned char)('A' + l - 10);
|
||
|
else
|
||
|
tmp_str[3 - j] = (unsigned char)(l + '0');
|
||
|
|
||
|
n >>= 4 ;
|
||
|
}
|
||
|
|
||
|
tmp_str[4] = '\0';
|
||
|
strcat((char *) tmp_str, ": ");
|
||
|
|
||
|
/*
|
||
|
Output the hex bytes
|
||
|
*/
|
||
|
for (j = i; j < (i + 16); j ++) {
|
||
|
int m ;
|
||
|
|
||
|
if (j < len) {
|
||
|
m = ((unsigned int)((unsigned char) * (data + j))) / 16 ;
|
||
|
|
||
|
if (m >= 10)
|
||
|
tmp_str1[0] = 'A' + (unsigned char) m - 10;
|
||
|
else
|
||
|
tmp_str1[0] = (unsigned char) m + '0';
|
||
|
|
||
|
m = ((unsigned int)((unsigned char) * (data + j))) % 16 ;
|
||
|
|
||
|
if (m >= 10)
|
||
|
tmp_str1[1] = 'A' + (unsigned char) m - 10;
|
||
|
else
|
||
|
tmp_str1[1] = (unsigned char) m + '0';
|
||
|
|
||
|
tmp_str1[2] = '\0';
|
||
|
strcat((char *) tmp_str, (char *) tmp_str1);
|
||
|
strcat((char *) tmp_str, " ");
|
||
|
} else {
|
||
|
strcat((char *) tmp_str, " ");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
strcat((char *) tmp_str, " ");
|
||
|
l = strlen((char *) tmp_str);
|
||
|
|
||
|
/* Output the ASCII bytes */
|
||
|
for (j = i; j < (i + 16); j++) {
|
||
|
if (j < len) {
|
||
|
char c = * (data + j);
|
||
|
|
||
|
if (c < ' ' || c > 'z') {
|
||
|
c = '.';
|
||
|
}
|
||
|
|
||
|
tmp_str[l ++] = c;
|
||
|
} else {
|
||
|
tmp_str[l ++] = ' ';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
tmp_str[l ++] = '\r';
|
||
|
tmp_str[l ++] = '\n';
|
||
|
tmp_str[l ++] = '\0';
|
||
|
|
||
|
printf("%s\r\n", (const char *) tmp_str);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//static uint8_t *testbuf;
|
||
|
//static uint32_t testbuf_len = 0;
|
||
|
static uint8_t ncm_data_buffer[65536] = {0};
|
||
|
static int vCreateNCMUpdateServerSocket( void )
|
||
|
{
|
||
|
SocketSet_t xFD_Set;
|
||
|
struct freertos_sockaddr xAddress, xRemoteAddr;
|
||
|
Socket_t xSockets = FREERTOS_INVALID_SOCKET, xClientSocket = FREERTOS_INVALID_SOCKET;
|
||
|
socklen_t xClientLength = sizeof( xAddress );
|
||
|
static const TickType_t xNoTimeOut = pdMS_TO_TICKS( 10000 );
|
||
|
BaseType_t ret = -1;
|
||
|
BaseType_t xResult;
|
||
|
|
||
|
xFD_Set = FreeRTOS_CreateSocketSet();
|
||
|
xSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||
|
configASSERT( xSockets != FREERTOS_INVALID_SOCKET );
|
||
|
FreeRTOS_setsockopt( xSockets,
|
||
|
0,
|
||
|
FREERTOS_SO_RCVTIMEO,
|
||
|
&xNoTimeOut,
|
||
|
sizeof( xNoTimeOut ) );
|
||
|
set_socket_win_net(xSockets);
|
||
|
//xAddress.sin_port = ( uint16_t ) 10003;
|
||
|
xAddress.sin_port = FreeRTOS_htons( 10003 );
|
||
|
FreeRTOS_bind( xSockets, &xAddress, sizeof( xAddress ) );
|
||
|
FreeRTOS_listen( xSockets, 3 );
|
||
|
|
||
|
//testbuf = pvPortMalloc(0x200000);
|
||
|
//memset(testbuf, 0, 0x200000);
|
||
|
while (1) {
|
||
|
FreeRTOS_FD_CLR(xSockets, xFD_Set, eSELECT_READ);
|
||
|
FreeRTOS_FD_SET(xSockets, xFD_Set, eSELECT_READ);
|
||
|
if (xClientSocket && xClientSocket != FREERTOS_INVALID_SOCKET) {
|
||
|
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||
|
FreeRTOS_FD_SET( xClientSocket, xFD_Set, eSELECT_READ );
|
||
|
}
|
||
|
|
||
|
xResult = FreeRTOS_select( xFD_Set, portMAX_DELAY );
|
||
|
if (xResult < 0) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if( FreeRTOS_FD_ISSET ( xSockets, xFD_Set ) ) {
|
||
|
xClientSocket = FreeRTOS_accept( xSockets, &xRemoteAddr, &xClientLength);
|
||
|
if( ( xClientSocket != NULL ) && ( xClientSocket != FREERTOS_INVALID_SOCKET ) ) {
|
||
|
char pucBuffer[32] = {0};
|
||
|
//FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||
|
//FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
|
||
|
set_socket_win_net(xClientSocket);
|
||
|
FreeRTOS_GetRemoteAddress( xClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
|
||
|
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
|
||
|
printf("NCM: Received a connection from %s:%u\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
|
||
|
net_client_socket = xClientSocket;
|
||
|
}
|
||
|
continue;
|
||
|
} else if( FreeRTOS_FD_ISSET ( xClientSocket, xFD_Set ) ) {
|
||
|
|
||
|
ret = FreeRTOS_recv(xClientSocket, ncm_data_buffer, sizeof(ncm_data_buffer), 0);
|
||
|
if (ret > 0) {
|
||
|
printf("@@recv buf size:%d\r\n", ret);
|
||
|
//print_hex(ncm_data_buffer, 160, NULL);
|
||
|
//print_hex(ncm_data_buffer + ret - 16, 16, NULL);
|
||
|
RevDataHandler(ncm_data_buffer, ret);
|
||
|
//memcpy(testbuf + testbuf_len, ncm_data_buffer, ret);
|
||
|
//testbuf_len += ret;
|
||
|
} else {
|
||
|
printf("FreeRTOS_recv err:%d\r\n", ret);
|
||
|
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||
|
FreeRTOS_closesocket(xClientSocket);
|
||
|
xClientSocket = FREERTOS_INVALID_SOCKET;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FreeRTOS_closesocket(xClientSocket);
|
||
|
FreeRTOS_closesocket(xSockets);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void ncm_update_demo_thread(void *param)
|
||
|
{
|
||
|
net_frame_buf = pvPortMalloc(FRAME_MAX_LEN);
|
||
|
if (!net_frame_buf) {
|
||
|
printf("net_frame_buf malloc fail.\n");
|
||
|
return;
|
||
|
}
|
||
|
vCreateNCMUpdateServerSocket();
|
||
|
|
||
|
while(1)
|
||
|
vTaskDelay(portMAX_DELAY);
|
||
|
}
|
||
|
|
||
|
void ncm_update_demo(void)
|
||
|
{
|
||
|
if (xTaskCreate(ncm_update_demo_thread, "ncmupdate", configMINIMAL_STACK_SIZE * 16, NULL,
|
||
|
1, NULL) != pdPASS) {
|
||
|
printf("create ncm update demo task fail.\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|