| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <netdb.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- #include <pthread.h>
- #include <signal.h>
- #define LOG_REQ_PORT 10001
- #define LOG_TFR_PORT 10002
- #define LOG_FRAME_HEADER_MAGIC 0xFF5AFFA5
- #define LOG_FRAME_TAIL_MAGIC 0xFFA5FF5A
- #define FILENAME_LEN 128
- #define MD5_LEN 32
- #define MAX_LOG_SIZE 0x100000
- #pragma pack(push, 1)
- typedef struct {
- uint32_t header;
- uint32_t type;
- uint32_t sub_type;
- uint32_t sub_type_1;
- uint32_t len;
- uint8_t checksum;
- } LogFrame;
- typedef struct {
- uint8_t request_type;
- uint32_t log_size;
- uint8_t log_md5[MD5_LEN];
- uint8_t log_filename[FILENAME_LEN];
- } LogTfrReq;
- #pragma pack(pop)
- static int log_req_socket = -1;
- static int log_tfr_socket = -1;
- static pthread_t req_thread_id = 0;
- static pthread_t tfr_thread_id = 0;
- #define FRAME_MAX_LEN 0x100000
- #define LOG_TFR_MAX_SIZE 512000
- #define OTA_LOG_FILENAME "log.zip"
- static int log_rev_state = 0;
- static int log_state_len = 0;
- static int log_rev_len = 0;
- static uint32_t log_frame_type = 0;
- static uint32_t log_frame_subtype = 0;
- static uint32_t log_frame_subtype_1 = 0;
- static uint32_t log_frame_len = 0;
- static uint8_t log_frame_checksum = 0;
- static uint8_t *log_frame_buf;
- static uint32_t log_file_size;
- static uint32_t log_file_offset;
- static uint32_t log_file_framenum = 0;
- static char log_file_md5[MD5_LEN];
- static char log_file_name[FILENAME_LEN];
- static uint8_t log_start_req = 1;
- #define LOG_CHECKSUM(x) ((((x) >> 24) & 0xff) + (((x) >> 16) & 0xff) + (((x) >> 8) & 0xff) + ((x) & 0xff))
- static uint8_t calc_log_checksum(uint32_t type, uint32_t subtype, uint32_t subtype_1, uint32_t len)
- {
- uint32_t checksum = 0;
- checksum = LOG_CHECKSUM(type) + LOG_CHECKSUM(subtype) + LOG_CHECKSUM(subtype_1) + LOG_CHECKSUM(len);
- return 0x100 - (uint8_t)checksum;
- }
- static void logSendFrame(int socket, uint32_t type, uint32_t subtype,
- uint32_t subtype_1, void *data, uint32_t len)
- {
- LogFrame *frame = NULL;
- uint8_t *tmp;
- int32_t leftsize;
- int ret;
- printf("send frame type=0x%x, subtype=0x%x, len=%d.\n", type, subtype, len);
- frame = (LogFrame*)malloc(sizeof(LogFrame) + len + 4);
- if (frame) {
- frame->header = LOG_FRAME_HEADER_MAGIC;
- frame->type = type;
- frame->sub_type = subtype;
- frame->sub_type_1 = subtype_1;
- frame->len = len;
- frame->checksum = calc_log_checksum(type, subtype, subtype_1, len);
- tmp = (uint8_t*)frame + sizeof(LogFrame);
- if (len) {
- memcpy(tmp, data, len);
- tmp += len;
- }
- *(uint32_t *)tmp = LOG_FRAME_TAIL_MAGIC;
- }
- leftsize = sizeof(LogFrame) + len + 4;
- tmp = (uint8_t *)frame;
- while (leftsize > 0) {
- ret = send(socket, tmp, leftsize, 0);
- if (ret > 0) {
- leftsize -= ret;
- tmp += leftsize;
- }
- }
- free(frame);
- }
- static int g_exit = 0;
- static void RevLogFrameHandler(uint32_t type, uint32_t subtype, uint32_t subtype_1,
- uint8_t *data, uint32_t len)
- {
- printf("rev frame type=0x%x, subtype=0x%x, len=%d.\n", type, subtype, len);
- switch (type) {
- case 0x1b:
- if (subtype == 0x06) {
- if (data[0] == 0x01) {
- uint8_t ack[2];
- log_file_size = (data[4] << 24) | (data[3] << 16) | (data[2] << 8) | data[1];
- memcpy(log_file_md5, data + 5, MD5_LEN);
- memcpy(log_file_name, data + 5 + MD5_LEN, FILENAME_LEN);
- ack[0] = 0x01; //positive ack
- ack[1] = 0x00; //no error
- logSendFrame(log_req_socket, 0x0b, 0x06, 0, ack, 2);
- }
- }
- break;
- case 0x1f:
- if (subtype == 0x01) {
- int datalen = *(uint32_t*)data;
- int flag = *(uint16_t*)(data + 4);
- if (datalen + 6 != len) {
- printf("invalid datalen %d.\n", datalen);
- break;
- }
-
- if (flag == 0) {
- uint8_t ack[130] = {0};
- printf("log transfer finish.\n");
- if (log_file_framenum == 0) {
- FILE *fp = fopen(log_file_name, "wb");
- if (fp) {
- printf("create log file %s.\n", log_file_name);
- fwrite(data + 6, 1, datalen, fp);
- fclose(fp);
- }
- } else {
- FILE *fp = fopen(log_file_name, "a+");
- if (fp) {
- fwrite(data + 6, 1, datalen, fp);
- fclose(fp);
- }
- }
- strcpy((char*)ack, log_file_name);
- ack[128] = 0; //receive successed
- ack[129] = 0; //no resend
- logSendFrame(log_req_socket, 0x0f, 0x03, 0, ack, 130);
- g_exit = 1;
- break;
- } else if (flag == 1) {
- uint8_t ack= 0;
- // first frame
- FILE *fp = fopen(log_file_name, "wb");
- if (!fp) {
- printf("create %s fail.\n", log_file_name);
- ack = 1; //no send next frame
- logSendFrame(log_req_socket, 0x0f, 0x02, 0, &ack, 1);
- break;
- }
- printf("create log file %s.\n", log_file_name);
- fwrite(data + 6, 1, datalen, fp);
- fclose(fp);
- logSendFrame(log_req_socket, 0x0f, 0x02, 0, &ack, 1);
- } else {
- uint8_t ack= 0;
- FILE *fp = fopen(log_file_name, "a+");
- if (!fp) {
- printf("open %s fail.\n", log_file_name);
- ack = 1; //no send next frame
- logSendFrame(log_req_socket, 0x0f, 0x02, 0, &ack, 1);
- break;
- }
- fwrite(data + 6, 1, datalen, fp);
- fclose(fp);
- logSendFrame(log_req_socket, 0x0f, 0x02, 0, &ack, 1);
- }
- log_file_framenum++;
- }
- break;
- }
- }
- static void RevLogDataHandler(uint8_t *buf, int32_t len)
- {
- int i;
- for (i = 0; i < len; i++) {
- switch (log_rev_state) {
- case 0: //head receive
- if (log_state_len == 0 && buf[i] == 0xa5) {
- log_state_len++;
- } else if (log_state_len == 1 && buf[i] == 0xff) {
- log_state_len++;
- } else if (log_state_len == 2 && buf[i] == 0x5a) {
- log_state_len++;
- } else if (log_state_len == 3 && buf[i] == 0xff) {
- log_rev_state++;
- log_state_len = 0;
- log_frame_type = 0;
- log_frame_subtype = 0;
- log_frame_subtype_1 = 0;
- log_frame_len = 0;
- } else if (buf[i] == 0xff) {
- log_state_len = 1;
- } else {
- log_state_len = 0;
- }
- break;
- case 1: //type receive
- log_frame_type |= buf[i] << (8 * log_state_len);
- if (++log_state_len == 4) {
- log_rev_state++;
- log_state_len = 0;
- }
- break;
- case 2: //sub_type receive
- log_frame_subtype |= buf[i] << (8 * log_state_len);
- if (++log_state_len == 4) {
- log_rev_state++;
- log_state_len = 0;
- }
- break;
- case 3: //sub_type_1 receive
- log_frame_subtype_1 |= buf[i] << (8 * log_state_len);
- if (++log_state_len == 4) {
- log_rev_state++;
- log_state_len = 0;
- }
- break;
- case 4: //data len receive
- log_frame_len |= buf[i] << (8 * log_state_len);
- if (++log_state_len == 4) {
- if (log_frame_len > FRAME_MAX_LEN) {
- printf("Invalid NCM frame len 0x%x.\n", log_frame_len);
- }
- if (log_frame_len == 0)
- log_rev_state += 2;
- else
- log_rev_state++;
- log_rev_len = 0;
- log_state_len = 0;
- }
- break;
- case 5: //checksum receive
- log_frame_checksum = buf[i];
- if (log_frame_checksum != calc_log_checksum(log_frame_type, log_frame_subtype,
- log_frame_subtype_1, log_frame_len)) {
- printf("log frame checksum fail.\n");
- log_rev_state = 0;
- } else {
- log_rev_state++;
- }
- break;
- case 6: //data receive
- if (log_rev_len < FRAME_MAX_LEN)
- log_frame_buf[log_rev_len] = buf[i];
- if (++log_rev_len == log_frame_len)
- log_rev_state++;
- break;
- case 7: //tail receive
- if (log_state_len == 0 && buf[i] == 0x5a) {
- log_state_len++;
- } else if (log_state_len == 1 && buf[i] == 0xff) {
- log_state_len++;
- } else if (log_state_len == 2 && buf[i] == 0xa5) {
- log_state_len++;
- } else if (log_state_len == 3 && buf[i] == 0xff) {
- RevLogFrameHandler(log_frame_type, log_frame_subtype, log_frame_subtype_1,
- log_frame_buf, log_frame_len);
- log_rev_state = 0;
- log_state_len = 0;
- } else {
- log_state_len = 0;
- }
- break;
- default:
- break;
- }
- }
- }
- 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 void *tcp_server_handler(void *arg)
- {
- int domain = AF_INET;
- int type = SOCK_STREAM;
- int protocol = 0;
- int ret = -1;
- int nListenFd = -1;
- int port = *(int*)arg;
- struct sockaddr_in addr_in;
- int backlog = 5; // 默认是128
- int len = 0;
- char chBuffer[1024] = {0};
- int flags = 0;
- int nClientSocket = -1;
- int nMaxFd = -1;
- int i = 0;
- fd_set readfds;
- static const int kOn = 1;
- nListenFd = socket(domain, type, protocol);
- if (nListenFd < 0)
- {
- printf("socket failed ! errno[%d] err[%s]\n", errno, strerror(errno));
- return NULL;
- }
- setsockopt(nListenFd, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
- memset(&addr_in, 0, sizeof(struct sockaddr_in));
- addr_in.sin_family = AF_INET;
- addr_in.sin_port = htons(port); //htons的返回值是16位的网络字节序整型数 htons尾的字母s代表short
- addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
- ret = bind(nListenFd, (struct sockaddr *)(&addr_in), sizeof(struct sockaddr_in));
- if (ret < 0)
- {
- printf("bind failed ! errno[%d] err[%s]\n", errno, strerror(errno));
- close(nListenFd); //避免资源泄漏
- return NULL;
- }
- ret = listen(nListenFd, backlog);
- if (ret < 0)
- {
- printf("listen failed ! errno[%d] err[%s]\n", errno, strerror(errno));
- close(nListenFd); //避免资源泄漏
- return NULL;
- }
- nMaxFd = nListenFd;
- while (!g_exit)
- {
- struct timeval stuTime;
- int time_out_ms = 3000;
- int num = 0;
- FD_ZERO(&readfds);
- FD_SET(nListenFd, &readfds);
- if (nClientSocket != -1)
- FD_SET(nClientSocket, &readfds);
- memset(&stuTime, 0, sizeof(struct timeval));
- stuTime.tv_sec = time_out_ms / 1000;
- stuTime.tv_usec = 1000 * (time_out_ms % 1000);
- num = select(nMaxFd + 1, &readfds, NULL, NULL, &stuTime);
- if (num > 0)
- {
- if (nClientSocket != -1 && FD_ISSET(nClientSocket, &readfds))
- {
- len = recv(nClientSocket, chBuffer, sizeof(chBuffer), flags); //flags为0,阻塞模式
- if (len == 0)
- {
- printf("Recv ret:%d errno:%d\n", ret, errno);
- printf("recv error:%s\n", strerror(errno)); //server close or recv timeout
- printf("recv failed ! errno[%d] err[%s] len[%d]\n", errno, strerror(errno), len);
- close(nClientSocket);
- FD_CLR(nClientSocket, &readfds);
- nClientSocket = -1;
- }
- else if (len < 0)
- {
- if (!(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
- {
- printf("recv error:%s\n", strerror(errno));
- printf("recv failed ! errno[%d] err[%s] len[%d]\n", errno, strerror(errno), len);
- close(nClientSocket);
- FD_CLR(nClientSocket, &readfds);
- nClientSocket = -1;
- }
- }
- else
- {
- //print_hex(chBuffer, sizeof(chBuffer), NULL);
- RevLogDataHandler(chBuffer, len);
- }
- }
- if (FD_ISSET(nListenFd, &readfds))
- {
- nClientSocket = accept(nListenFd, (struct sockaddr *)NULL, NULL); //阻塞模式
- if (nClientSocket < 0)
- {
- printf("accept failed ! errno[%d] err[%s]\n", errno, strerror(errno));
- //close(nListenFd); //避免资源泄漏
- break;
- }
- printf("new client nClientSocket[%d]\n", nClientSocket);
- if (port == LOG_REQ_PORT && log_start_req == 1) {
- logSendFrame(nClientSocket, 0x0a, 0x10, 0, &log_start_req, sizeof(log_start_req));
- log_start_req = 0;
- }
- if (nClientSocket > nMaxFd)
- nMaxFd = nClientSocket;
- if (port == LOG_REQ_PORT)
- log_req_socket = nClientSocket;
- else if (port == LOG_TFR_PORT)
- log_tfr_socket = nClientSocket;
- }
- }
- else if (num == 0)
- {
- //printf("\n time out \n");
- //return 0;
- }
- else
- {
- printf("error \n");
- //return -1;
- }
- }
- printf("tcp_server_handler port=%d exit.\n", port);
- if (nClientSocket != -1)
- close(nClientSocket);
- close(nListenFd);
- return 0;
- }
- void exit_sighandler(int signo)
- {
- printf("exit_handler\n");
- g_exit = 1;
- }
- int main(int argc ,char *argv[])
- {
- int reqport = LOG_REQ_PORT;
- int tfrport = LOG_TFR_PORT;
- log_frame_buf = malloc(FRAME_MAX_LEN);
- if (!log_frame_buf) {
- printf("log_frame_buf malloc fail.\n");
- return -1;
- }
- signal(SIGTERM, exit_sighandler);
- signal(SIGINT, exit_sighandler);
- pthread_create(&req_thread_id, NULL, tcp_server_handler, &reqport);
- pthread_create(&tfr_thread_id, NULL, tcp_server_handler, &tfrport);
- pthread_join(req_thread_id, NULL);
- pthread_join(tfr_thread_id, NULL);
- free(log_frame_buf);
- return 0;
- }
|