update_07_25.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <unistd.h> // close()
  5. #include <string.h> // strcpy, memset(), and memcpy()
  6. #include <stdarg.h>
  7. #include <errno.h> // errno, perror()
  8. #include <stdbool.h>
  9. #include <pthread.h>
  10. #include <semaphore.h>
  11. #include <math.h>
  12. #include <dirent.h>
  13. #include <fcntl.h>
  14. #include <signal.h>
  15. #include <getopt.h>
  16. #include <termios.h>
  17. #include <netdb.h> // struct addrinfo
  18. #include <sys/stat.h>
  19. #include <sys/ioctl.h> // macro ioctl is defined
  20. #include <bits/ioctls.h> // defines values for argument "request" of ioctl.
  21. #include <sys/syscall.h>
  22. #include <sys/types.h> // needed for socket(), uint8_t, uint16_t, uint32_t
  23. #include <sys/select.h>
  24. #include <sys/socket.h> // needed for socket()
  25. #include <sys/time.h>
  26. #include <sys/ipc.h>
  27. #include <sys/sem.h>
  28. #include <libgen.h>
  29. #include <netinet/in.h> // IPPROTO_ICMP, INET_ADDRSTRLEN
  30. #include <netinet/ip.h> // struct ip and IP_MAXPACKET (which is 65535)
  31. #include <netinet/ip_icmp.h> // struct icmp, ICMP_ECHO
  32. #include <arpa/inet.h> // inet_pton() and inet_ntop()
  33. #include <net/if.h> // struct ifreq
  34. #include <net/ethernet.h>
  35. #include <linux/if_ether.h> // ETH_P_IP = 0x0800, ETH_P_IPV6 = 0x86DD
  36. #include <linux/if_packet.h> // struct sockaddr_ll (see man 7 packet)
  37. #include <linux/serial.h>
  38. #include <linux/can.h>
  39. #include <linux/can/raw.h>
  40. typedef enum
  41. {
  42. ACCEPTED,
  43. REJECTED,
  44. SUCCESS,
  45. FAIL,
  46. IDLE,
  47. UPDATING,
  48. }state_t;
  49. typedef struct update
  50. {
  51. int quit;
  52. int fd;
  53. int state;
  54. struct sockaddr_in peer_addr;
  55. socklen_t peer_addrlen;
  56. uint8_t rxbuff[1024];
  57. int rxbyte;
  58. uint8_t txbuff[1024];
  59. int txbyte;
  60. int filesize;
  61. int majorVersion;
  62. int minorVersion;
  63. int buildVersion;
  64. int major;
  65. int minor;
  66. int build;
  67. char ip_string[64];
  68. int port;
  69. FILE *logfp;
  70. }update_t;
  71. static update_t update =
  72. {
  73. .fd = -1,
  74. .logfp = NULL
  75. };
  76. // #define printd(fmt, ...) printf("%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
  77. #define printd(fmt, ...) fprintf(dev->logfp, "%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
  78. int wait_android_message(update_t* dev)
  79. {
  80. dev->rxbyte = 0;
  81. while(dev->rxbyte < 1024)
  82. {
  83. int ret = recv(dev->fd, &dev->rxbuff[dev->rxbyte], 1, 0);
  84. if (ret <= 0) {
  85. printd("ret : %d, errno:%d\n", ret, errno);
  86. shutdown(dev->fd, SHUT_RDWR);
  87. close(dev->fd);
  88. dev->fd = -1;
  89. return -1;
  90. }
  91. if (ret > 0) dev->rxbyte += ret;
  92. if (dev->rxbyte>=5)
  93. {
  94. if (strncmp(dev->rxbuff, "Event", 5)==0)
  95. {
  96. if (dev->rxbuff[dev->rxbyte-1] == '\n')
  97. {
  98. printd("recv:%s\n",dev->rxbuff);
  99. return 0;
  100. }
  101. }else{
  102. memmove(&dev->rxbuff[0], &dev->rxbuff[1], dev->rxbyte - 1);
  103. dev->rxbyte = dev->rxbyte - 1;
  104. }
  105. }
  106. }
  107. return -1;
  108. }
  109. int android_LoadVersion(update_t* dev, const char* filename)
  110. {
  111. char filebuff[256];
  112. dev->major = dev->major = dev->build = 0;
  113. memset(filebuff,0,sizeof(filebuff));
  114. int ret = readlink(filename, filebuff, sizeof(filebuff));
  115. printd("app_version.linkname=%s\n", filebuff);
  116. if (ret > 0)
  117. {
  118. // char* basename_str = strchr(filebuff, '/');
  119. // if (basename_str)
  120. {
  121. sscanf(filebuff, "app_XHHW_%d_%d_%d", &dev->major, &dev->minor, &dev->build);
  122. printd("app_XHHW_%d_%d_%d\n", dev->major, dev->minor, dev->build);
  123. }
  124. }
  125. return 0;
  126. }
  127. int android_DowanloadFile(update_t* dev, const char* filename)
  128. {
  129. FILE *fp = fopen(filename, "rw");
  130. if (fp)
  131. {
  132. dev->state = UPDATING;
  133. int recved = 0;
  134. while(recved < dev->filesize)
  135. {
  136. int len = dev->filesize - recved;
  137. if (len > 1024) len = 1024;
  138. int ret = recv(dev->fd, dev->rxbuff, len, 0);
  139. if (ret <= 0) {
  140. printd("ret:%d, errno:%d\n", ret, errno);
  141. shutdown(dev->fd, SHUT_RDWR);
  142. close(dev->fd);
  143. dev->fd = -1;
  144. return -1;
  145. }
  146. if (ret > 0) recved += ret;
  147. fwrite(dev->rxbuff, ret, 1, fp);
  148. }
  149. if (recved == dev->filesize)
  150. {
  151. dev->state = SUCCESS;
  152. }else{
  153. dev->state = FAIL;
  154. }
  155. fclose(fp);
  156. printd("recvd.filename=%s, recvd.bytes:%d\n", filename, recved);
  157. return 0;
  158. }
  159. return -1;
  160. }
  161. int android_Upgrade(update_t* dev, const char* oldfilename, const char* newfilename)
  162. {
  163. if (dev->state == SUCCESS)
  164. {
  165. int idx = 0;
  166. char cmdbuff[256];
  167. memset(cmdbuff,0,sizeof(cmdbuff));
  168. idx += sprintf(&cmdbuff[idx], "pkill app_XHHW\n");
  169. idx += sprintf(&cmdbuff[idx], "chmod +x %s\n", newfilename);
  170. idx += sprintf(&cmdbuff[idx], "rm -f %s\n", oldfilename);
  171. idx += sprintf(&cmdbuff[idx], "ln -s %s %s\n", newfilename, oldfilename);
  172. idx += sprintf(&cmdbuff[idx], "sync\n");
  173. idx += sprintf(&cmdbuff[idx], "reboot\n");
  174. int ret = system(cmdbuff);
  175. printf( "ret = %d, cmd = %s\n", ret, cmdbuff);
  176. // sprintf(cmdbuff, "chmod +x %s", newfilename);system(cmdbuff);
  177. // sprintf(cmdbuff, "rm -f %s", oldfilename);system(cmdbuff);
  178. // sprintf(cmdbuff, "ln -s %s %s", newfilename, oldfilename);system(cmdbuff);
  179. // sprintf(cmdbuff, "/home/root/bin/hmi.sh");system(cmdbuff);
  180. // chmod(filename, S_IRUSR|S_IWUSR|S_IXUSR | S_IXGRP|S_IRGRP|S_IXGRP | S_IROTH|S_IWOTH|S_IXOTH);
  181. // unlink(newfilename);
  182. // symlink(filename, newfilename);
  183. dev->state = IDLE;
  184. return 0;
  185. }
  186. return -1;
  187. }
  188. int android_NotifyUpdateFirmware_res(update_t* dev, const char* status)
  189. {
  190. int len = sprintf(dev->txbuff, "Event=NotifyUpdateFirmware,Type=HW,Status=%s,Message=NONE\n", status);
  191. printd("send : %s\n",dev->txbuff);
  192. if (dev->fd > 0)
  193. return send(dev->fd, dev->txbuff, len, 0);
  194. else
  195. return -1;
  196. }
  197. int android_RequestUpdateFirmware_req(update_t* dev,int major, int minor, int build)
  198. {
  199. int len = sprintf(dev->txbuff, "Event=UpdateFirmware,Type=HW,Version=%d.%d.%d\n",major, minor, build);
  200. printd("send : %s\n",dev->txbuff);
  201. if (dev->fd > 0)
  202. return send(dev->fd, dev->txbuff, len, 0);
  203. else
  204. return -1;
  205. }
  206. int android_NotifyUpdateFirmwareResult_res(update_t* dev, const char* status,int major, int minor, int build)
  207. {
  208. int len = sprintf(dev->txbuff, "Event=NotifyUpdateFirmwareResult,Type=HW,Status=%s,Version=%d.%d.%d,Message=NONE\n", status, major, minor, build);
  209. printd("send : %s\n",dev->txbuff);
  210. if (dev->fd > 0)
  211. return send(dev->fd, dev->txbuff, len, 0);
  212. else
  213. return -1;
  214. }
  215. int android_GetFirmwareVersion_res(update_t* dev, int major, int minor, int build)
  216. {
  217. int len = sprintf(dev->txbuff, "Event=GetFirmwareVersion,Type=HW,Version=%d.%d.%d\n", major, minor, build);
  218. printd("send : %s\n",dev->txbuff);
  219. if (dev->fd > 0)
  220. return send(dev->fd, dev->txbuff, len, 0);
  221. else
  222. return -1;
  223. }
  224. int android_connect(update_t *dev)
  225. {
  226. if (dev)
  227. {
  228. while (dev->fd < 0)
  229. {
  230. dev->fd = socket(AF_INET, SOCK_STREAM, 0);
  231. if (dev->fd > 0)
  232. {
  233. dev->peer_addr.sin_family = AF_INET;
  234. dev->peer_addr.sin_addr.s_addr = inet_addr(dev->ip_string);
  235. dev->peer_addr.sin_port = htons(dev->port);
  236. dev->peer_addrlen = sizeof(dev->peer_addr);
  237. while(connect(dev->fd, (struct sockaddr*)&dev->peer_addr, dev->peer_addrlen) < 0){
  238. printd("local socket connect to %s.%d failed.retry...\n", dev->ip_string, dev->port);
  239. sleep(1);
  240. }
  241. printf("local socket connect to %s.%d ok.\n", dev->ip_string, dev->port);
  242. return 0;
  243. }
  244. printd("create socket failed.retry...\n");
  245. sleep(1);
  246. }
  247. return 0;
  248. }
  249. return -1;
  250. }
  251. void* xh_update_loop(void* argv)
  252. {
  253. update_t *dev = (update_t*)argv;
  254. while(dev->quit == 0)
  255. {
  256. android_connect(dev);
  257. if (wait_android_message(dev) == 0)
  258. {
  259. if (strncmp(dev->rxbuff, "Event=NotifyUpdateFirmware,Type=HW", 34)==0)
  260. {
  261. char newfilename[256];
  262. char oldfilename[256];
  263. memset(newfilename,0,sizeof(newfilename));
  264. memset(oldfilename,0,sizeof(oldfilename));
  265. sprintf(oldfilename, "/home/root/bin/app_XHHW");
  266. sscanf(dev->rxbuff, "Event=NotifyUpdateFirmware,Type=HW,Size=%d,Version=%d.%d.%d\n", &dev->filesize, &dev->majorVersion, &dev->minorVersion, &dev->buildVersion);
  267. sprintf(newfilename, "/home/root/bin/app_XHHW_%d_%d_%d", dev->majorVersion, dev->minorVersion, dev->buildVersion);
  268. if (dev->major != dev->majorVersion || dev->minor!=dev->minorVersion || dev->build!=dev->buildVersion)
  269. {
  270. if (android_NotifyUpdateFirmware_res(dev, "Accepted") == 0)
  271. {
  272. sleep(1);
  273. if (android_RequestUpdateFirmware_req(dev, dev->major, dev->minor, dev->build) == 0)
  274. {
  275. if (android_DowanloadFile(dev, newfilename) == 0)
  276. {
  277. if (android_Upgrade(dev, oldfilename, newfilename) == 0)
  278. {
  279. dev->major = dev->majorVersion;
  280. dev->minor = dev->minorVersion;
  281. dev->build = dev->buildVersion;
  282. android_NotifyUpdateFirmwareResult_res(dev, "Success", dev->majorVersion, dev->minorVersion, dev->buildVersion);
  283. }
  284. }else{
  285. android_NotifyUpdateFirmwareResult_res(dev, "Fail", dev->majorVersion, dev->minorVersion, dev->buildVersion);
  286. }
  287. }
  288. }
  289. }else{
  290. android_NotifyUpdateFirmware_res(dev, "Rejected");
  291. }
  292. }
  293. if (strncmp(dev->rxbuff, "Event=NotifyUpdateFirmwareResult,Type=HW", 40)==0)
  294. {
  295. continue;
  296. }
  297. if (strncmp(dev->rxbuff, "Event=GetFirmwareVersion,Type=HW", 32)==0)
  298. {
  299. android_GetFirmwareVersion_res(dev, dev->major, dev->minor, dev->build);
  300. }
  301. }
  302. }
  303. return NULL;
  304. }
  305. int xh_update_init(update_t *dev)
  306. {
  307. if (dev)
  308. {
  309. dev->fd = -1;
  310. // dev->logfp = fopen("/home/root/bin/log.txt", "w");
  311. android_connect(dev);
  312. android_LoadVersion(dev, "/home/root/bin/app_XHHW");
  313. }
  314. return -1;
  315. }
  316. void xh_update_exit(update_t *dev)
  317. {
  318. if (dev)
  319. {
  320. dev->quit = 1;
  321. close(dev->fd);
  322. dev->fd = -1;
  323. }
  324. }
  325. int main(int argc, char* argv[])
  326. {
  327. sleep(10);
  328. update_t* dev = (update_t*)&update;
  329. {
  330. int c;
  331. dev->port = 20248;
  332. sprintf(dev->ip_string, "%s", "192.168.223.10");
  333. while ((c = getopt(argc, argv, "ip:")) != -1) {
  334. switch (c) {
  335. case 'i':
  336. sprintf(dev->ip_string, "%s", optarg);
  337. break;
  338. case 'p':
  339. dev->port = atoi(optarg);
  340. break;
  341. case '?':
  342. break;
  343. default:
  344. exit(2);
  345. }
  346. }
  347. xh_update_init(dev);
  348. xh_update_loop(dev);
  349. xh_update_exit(dev);
  350. }
  351. return 0;
  352. }