tcp_client.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <netdb.h>
  5. #include <sys/types.h>
  6. #include <netinet/in.h>
  7. #include <sys/socket.h>
  8. #include <unistd.h>
  9. #include <arpa/inet.h>
  10. #include <errno.h>
  11. #include <sys/stat.h>
  12. #define FRAME_HEADER_MAGIC 0xA5FF5AFF
  13. #define FRAME_TAIL_MAGIC 0x5AFFA5FF
  14. #define BUF_LEN 65536
  15. #define VERSION_LEN 64
  16. #define FILENAME_LEN 128
  17. #define MD5_LEN 32
  18. #define MAX_PATH 256
  19. #define FRAME_MAX_LEN 0x100000
  20. #define FRAME_LEN 1024000
  21. typedef struct {
  22. uint32_t header;
  23. uint32_t type;
  24. uint32_t sub_type;
  25. uint32_t len;
  26. } HUFrame;
  27. typedef struct {
  28. char hard_partnumber[VERSION_LEN];
  29. char hard_version[VERSION_LEN];
  30. char soft_partnumber[VERSION_LEN];
  31. char soft_version[VERSION_LEN];
  32. } ReqVersionPosiRsp;
  33. typedef struct {
  34. char file_name[FILENAME_LEN];
  35. uint32_t file_length;
  36. char file_md5[MD5_LEN];
  37. } FileWriteReq;
  38. typedef FileWriteReq FileCheckReq;
  39. typedef FileWriteReq FileCheckRsp;
  40. typedef struct {
  41. char file_name[FILENAME_LEN];
  42. uint32_t file_length;
  43. char file_md5[MD5_LEN];
  44. uint32_t offset;
  45. } ReqFileWriteRsp;
  46. static char update_file_name[FILENAME_LEN];
  47. static char update_file_md5[MD5_LEN];
  48. static int update_file_length;
  49. static int update_file_offset;
  50. static int sockfd;
  51. static int g_exit = 0;
  52. static int net_rev_state = 0;
  53. static int net_state_len = 0;
  54. static int net_rev_len = 0;
  55. static uint32_t net_frame_type = 0;
  56. static uint32_t net_frame_subtype = 0;
  57. static uint32_t net_frame_rspflag = 0;
  58. static uint32_t net_frame_len = 0;
  59. static int net_toolong_frame = 0;
  60. static uint8_t *net_frame_buf;
  61. static char cur_file_md5[32];
  62. static char cur_file_name[MAX_PATH];
  63. static void netSendFrame(uint32_t type, uint32_t subtype, void *data, uint32_t len)
  64. {
  65. HUFrame *huframe = NULL;
  66. uint8_t *tmp;
  67. printf("send frame type=0x%x, subtype=0x%x, len=%d.\n", type, subtype, len);
  68. huframe = (HUFrame*)malloc(sizeof(HUFrame) + len + 4);
  69. if (huframe) {
  70. huframe->header = FRAME_HEADER_MAGIC;
  71. huframe->type = type;
  72. huframe->sub_type = subtype;
  73. huframe->len = len;
  74. tmp = (uint8_t*)huframe + sizeof(HUFrame);
  75. if (len) {
  76. memcpy(tmp, data, len);
  77. tmp += len;
  78. }
  79. *(uint32_t *)tmp = FRAME_TAIL_MAGIC;
  80. }
  81. send(sockfd, huframe, sizeof(HUFrame) + len + 4, 0);
  82. free(huframe);
  83. }
  84. static void RevFrameHandler(uint32_t type, uint32_t subtype, uint32_t rspflag, uint8_t *data, uint32_t len)
  85. {
  86. printf("rev frame type=0x%x, subtype=0x%x, rspflag=0x%x, len=%d.\n", type, subtype, rspflag, len);
  87. switch (type) {
  88. case 0x70:
  89. if (subtype == 0x01) {
  90. ReqVersionPosiRsp *rsp = (ReqVersionPosiRsp*)data;
  91. printf("get version info:\n");
  92. printf("hard_partnumber=%s.\n", rsp->hard_partnumber);
  93. printf("hard_version=%s.\n", rsp->hard_version);
  94. printf("soft_partnumber=%s.\n", rsp->soft_partnumber);
  95. printf("soft_version=%s.\n", rsp->soft_version);
  96. FileWriteReq req = {0};
  97. strncpy(req.file_name, update_file_name, FILENAME_LEN);
  98. memcpy(req.file_md5, update_file_md5, MD5_LEN);
  99. req.file_length = update_file_length;
  100. netSendFrame(0x71, 0x01, &req, sizeof(req));
  101. }
  102. break;
  103. case 0x71:
  104. if (subtype == 0x01) {
  105. ReqFileWriteRsp *rsp = (ReqFileWriteRsp*)data;
  106. if (!rspflag || len != sizeof(ReqFileWriteRsp)) {
  107. g_exit = 1;
  108. break;
  109. }
  110. if (!strcmp(rsp->file_name, update_file_name) && !memcmp(rsp->file_md5, update_file_md5, MD5_LEN) &&
  111. rsp->file_length == update_file_length) {
  112. update_file_offset = 0;
  113. FILE *fp = fopen(update_file_name, "rb");
  114. if (!fp) {
  115. g_exit = 1;
  116. break;
  117. }
  118. unsigned char *buf = malloc(FILENAME_LEN + 12 + FRAME_LEN);
  119. if (!buf) {
  120. g_exit = 1;
  121. break;
  122. }
  123. int size = update_file_length > FRAME_LEN ? FRAME_LEN : update_file_length;
  124. memcpy(buf, update_file_name, FILENAME_LEN);
  125. *(uint32_t *)(buf + FILENAME_LEN) = update_file_length;
  126. *(uint32_t *)(buf + FILENAME_LEN + 4) = size;
  127. *(uint32_t *)(buf + FILENAME_LEN + 8) = 0;
  128. fseek(fp, update_file_offset, SEEK_SET);
  129. fread(buf + FILENAME_LEN + 12, 1, size, fp);
  130. netSendFrame(0x71, 0x02, buf, FILENAME_LEN + 12 + size);
  131. free(buf);
  132. fclose(fp);
  133. } else {
  134. g_exit = 1;
  135. break;
  136. }
  137. } else if (subtype == 0x02) {
  138. ReqFileWriteRsp *rsp = (ReqFileWriteRsp*)data;
  139. if (!rspflag || len != sizeof(ReqFileWriteRsp)) {
  140. printf("frame write fail\n");
  141. /* 模拟中控收到否定应答时会发送一个长度和md5清零的帧 */
  142. FileWriteReq req = {0};
  143. memset(req.file_name, 0, FILENAME_LEN);
  144. memset(req.file_md5, 0, MD5_LEN);
  145. req.file_length = 0;
  146. netSendFrame(0x71, 0x01, &req, sizeof(req));
  147. g_exit = 1;
  148. break;
  149. }
  150. if (!strcmp(rsp->file_name, update_file_name) && !memcmp(rsp->file_md5, update_file_md5, MD5_LEN) &&
  151. rsp->file_length == update_file_length && rsp->offset == update_file_offset) {
  152. update_file_offset += FRAME_LEN;
  153. if (update_file_offset >= update_file_length) {
  154. printf("file transfer finished.\n");
  155. netSendFrame(0x71, 0x03, NULL, 0);
  156. } else {
  157. int size = update_file_length - update_file_offset;
  158. size = size > FRAME_LEN ? FRAME_LEN : size;
  159. FILE *fp = fopen(update_file_name, "rb");
  160. if (!fp) {
  161. g_exit = 1;
  162. break;
  163. }
  164. unsigned char *buf = malloc(FILENAME_LEN + 12 + size);
  165. if (!buf) {
  166. g_exit = 1;
  167. break;
  168. }
  169. memcpy(buf, update_file_name, FILENAME_LEN);
  170. *(uint32_t *)(buf + FILENAME_LEN) = update_file_length;
  171. *(uint32_t *)(buf + FILENAME_LEN + 4) = size;
  172. *(uint32_t *)(buf + FILENAME_LEN + 8) = update_file_offset;
  173. fseek(fp, update_file_offset, SEEK_SET);
  174. fread(buf + FILENAME_LEN + 12, 1, size, fp);
  175. netSendFrame(0x71, 0x02, buf, FILENAME_LEN + 12 + size);
  176. free(buf);
  177. fclose(fp);
  178. }
  179. } else {
  180. g_exit = 1;
  181. break;
  182. }
  183. } else if (subtype == 0x03) {
  184. FileCheckReq req = {0};
  185. strcpy(req.file_name, update_file_name);
  186. memcpy(req.file_md5, update_file_md5, MD5_LEN);
  187. req.file_length = update_file_length;
  188. printf("req file check\n");
  189. netSendFrame(0x71, 0x04, &req, sizeof(req));
  190. } else if (subtype == 0x04) {
  191. FileCheckRsp *rsp = (FileCheckRsp*)data;
  192. if (!rspflag || len != sizeof(FileWriteReq)) {
  193. printf("file check fail\n");
  194. g_exit = 1;
  195. break;
  196. }
  197. if (!strcmp(rsp->file_name, update_file_name) && !memcmp(rsp->file_md5, update_file_md5, MD5_LEN) &&
  198. rsp->file_length == update_file_length) {
  199. printf("req install condition check\n");
  200. netSendFrame(0x73, 0x01, NULL, 0);
  201. }
  202. }
  203. break;
  204. case 0x73:
  205. if (subtype == 0x01) {
  206. if (!rspflag || len != 256) {
  207. printf("install condition check fail\n");
  208. g_exit = 1;
  209. break;
  210. }
  211. uint32_t install_type = 0;
  212. netSendFrame(0x74, 0x01, &install_type, sizeof(install_type));
  213. printf("wait for install finished...\n");
  214. }
  215. break;
  216. case 0x74:
  217. if (subtype == 0x01) {
  218. if (!rspflag || len != 256) {
  219. printf("install fail\n");
  220. g_exit = 1;
  221. break;
  222. }
  223. printf("install ok\n");
  224. g_exit = 1;
  225. }
  226. break;
  227. }
  228. }
  229. static void RevDataHandler(uint8_t *buf, int32_t len)
  230. {
  231. int i;
  232. for (i = 0; i < len; i++) {
  233. switch (net_rev_state) {
  234. case 0: //head receive
  235. if (net_state_len == 0 && buf[i] == 0xff) {
  236. net_state_len++;
  237. } else if (net_state_len == 1 && buf[i] == 0x5a) {
  238. net_state_len++;
  239. } else if (net_state_len == 2 && buf[i] == 0xff) {
  240. net_state_len++;
  241. } else if (net_state_len == 3 && buf[i] == 0xa5) {
  242. net_rev_state++;
  243. net_state_len = 0;
  244. net_frame_type = 0;
  245. net_frame_subtype = 0;
  246. net_frame_rspflag = 0;
  247. net_frame_len = 0;
  248. } else if (buf[i] == 0xff) {
  249. net_state_len = 1;
  250. } else {
  251. net_state_len = 0;
  252. }
  253. break;
  254. case 1: //type receive
  255. net_frame_type |= buf[i] << (8 * net_state_len);
  256. if (++net_state_len == 4) {
  257. net_rev_state++;
  258. net_state_len = 0;
  259. }
  260. break;
  261. case 2: //sub_type receive
  262. net_frame_subtype |= buf[i] << (8 * net_state_len);
  263. if (++net_state_len == 4) {
  264. net_rev_state++;
  265. net_state_len = 0;
  266. }
  267. break;
  268. case 3: //rsp_flag receive
  269. net_frame_rspflag |= buf[i] << (8 * net_state_len);
  270. if (++net_state_len == 4) {
  271. net_rev_state++;
  272. net_state_len = 0;
  273. }
  274. break;
  275. case 4: //data len receive
  276. net_frame_len |= buf[i] << (8 * net_state_len);
  277. if (++net_state_len == 4) {
  278. if (net_frame_len > FRAME_MAX_LEN) {
  279. printf("Invalid NCM frame len 0x%x.\n", net_frame_len);
  280. net_toolong_frame = 1;
  281. } else {
  282. net_toolong_frame = 0;
  283. }
  284. if (net_frame_len == 0)
  285. net_rev_state += 2;
  286. else
  287. net_rev_state++;
  288. net_rev_len = 0;
  289. net_state_len = 0;
  290. }
  291. break;
  292. case 5: //data receive
  293. if (net_rev_len < FRAME_MAX_LEN)
  294. net_frame_buf[net_rev_len] = buf[i];
  295. if (++net_rev_len == net_frame_len)
  296. net_rev_state++;
  297. break;
  298. case 6: //tail receive
  299. if (net_state_len == 0 && buf[i] == 0xff) {
  300. net_state_len++;
  301. } else if (net_state_len == 1 && buf[i] == 0xa5) {
  302. net_state_len++;
  303. } else if (net_state_len == 2 && buf[i] == 0xff) {
  304. net_state_len++;
  305. } else if (net_state_len == 3 && buf[i] == 0x5a) {
  306. RevFrameHandler(net_frame_type, net_frame_subtype, net_frame_rspflag, net_frame_buf, net_frame_len);
  307. net_rev_state = 0;
  308. net_state_len = 0;
  309. } else {
  310. net_state_len = 0;
  311. }
  312. break;
  313. default:
  314. break;
  315. }
  316. }
  317. }
  318. void print_hex(unsigned char *data, int len, const char* tag)
  319. {
  320. unsigned long i, j, l;
  321. unsigned char tmp_str[140];
  322. unsigned char tmp_str1[10];
  323. for (i = 0; i < len; i += 16) {
  324. int n ;
  325. tmp_str[0] = '\0';
  326. n = i ;
  327. for (j = 0; j < 4; j++) {
  328. l = n % 16;
  329. if (l >= 10)
  330. tmp_str[3 - j] = (unsigned char)('A' + l - 10);
  331. else
  332. tmp_str[3 - j] = (unsigned char)(l + '0');
  333. n >>= 4 ;
  334. }
  335. tmp_str[4] = '\0';
  336. strcat((char *) tmp_str, ": ");
  337. /*
  338. Output the hex bytes
  339. */
  340. for (j = i; j < (i + 16); j ++) {
  341. int m ;
  342. if (j < len) {
  343. m = ((unsigned int)((unsigned char) * (data + j))) / 16 ;
  344. if (m >= 10)
  345. tmp_str1[0] = 'A' + (unsigned char) m - 10;
  346. else
  347. tmp_str1[0] = (unsigned char) m + '0';
  348. m = ((unsigned int)((unsigned char) * (data + j))) % 16 ;
  349. if (m >= 10)
  350. tmp_str1[1] = 'A' + (unsigned char) m - 10;
  351. else
  352. tmp_str1[1] = (unsigned char) m + '0';
  353. tmp_str1[2] = '\0';
  354. strcat((char *) tmp_str, (char *) tmp_str1);
  355. strcat((char *) tmp_str, " ");
  356. } else {
  357. strcat((char *) tmp_str, " ");
  358. }
  359. }
  360. strcat((char *) tmp_str, " ");
  361. l = strlen((char *) tmp_str);
  362. /* Output the ASCII bytes */
  363. for (j = i; j < (i + 16); j++) {
  364. if (j < len) {
  365. char c = * (data + j);
  366. if (c < ' ' || c > 'z') {
  367. c = '.';
  368. }
  369. tmp_str[l ++] = c;
  370. } else {
  371. tmp_str[l ++] = ' ';
  372. }
  373. }
  374. tmp_str[l ++] = '\r';
  375. tmp_str[l ++] = '\n';
  376. tmp_str[l ++] = '\0';
  377. printf("%s\r\n", (const char *) tmp_str);
  378. }
  379. }
  380. unsigned long get_file_size(const char *path)
  381. {
  382. unsigned long filesize = -1;
  383. struct stat statbuff;
  384. if(stat(path, &statbuff) < 0){
  385. return filesize;
  386. }else{
  387. filesize = statbuff.st_size;
  388. }
  389. return filesize;
  390. }
  391. int main(int argc,char *argv[])
  392. {
  393. char sendbuffer[BUF_LEN];
  394. char recvbuffer[BUF_LEN];
  395. struct sockaddr_in server_addr;
  396. struct hostent *host;
  397. int portnumber,nbytes;
  398. int len;
  399. if (argc != 4) {
  400. fprintf(stderr,"Usage :%s hostname portnumber filename\a\n", argv[0]);
  401. exit(1);
  402. }
  403. if ((host = gethostbyname(argv[1])) == NULL) {
  404. herror("Get host name error\n");
  405. exit(1);
  406. }
  407. if ((portnumber = atoi(argv[2])) < 0)
  408. {
  409. fprintf(stderr,"Usage:%s hostname portnumber\a\n", argv[0]);
  410. exit(1);
  411. }
  412. strncpy(update_file_name, argv[3], FILENAME_LEN);
  413. update_file_length = get_file_size(update_file_name);
  414. char cmdstring[16 + FILENAME_LEN] = "md5sum ";
  415. strcat(cmdstring, update_file_name) ;
  416. FILE *fpipe = popen(cmdstring, "r");
  417. fread(update_file_md5, 1, MD5_LEN, fpipe);
  418. pclose(fpipe);
  419. if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) {
  420. fprintf(stderr,"Socket Error:%s\a\n", strerror(errno));
  421. exit(1);
  422. }
  423. bzero(&server_addr, sizeof(server_addr));
  424. server_addr.sin_family = AF_INET;
  425. server_addr.sin_port = htons(portnumber);
  426. server_addr.sin_addr = *((struct in_addr *)host->h_addr);
  427. if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
  428. fprintf(stderr,"Connect error:%s\n",strerror(errno));
  429. exit(1);
  430. }
  431. net_frame_buf = malloc(FRAME_MAX_LEN);
  432. if (!net_frame_buf) {
  433. fprintf(stderr,"malloc fail:%s\n",strerror(errno));
  434. exit(1);
  435. }
  436. netSendFrame(0x70, 0x01, NULL, 0);
  437. while (!g_exit) {
  438. len = recv(sockfd, recvbuffer, BUF_LEN, 0);
  439. //print_hex(recvbuffer, len, NULL);
  440. RevDataHandler(recvbuffer, len);
  441. }
  442. free(net_frame_buf);
  443. close(sockfd);
  444. exit(0);
  445. }