update.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  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 = strstr(filebuff, "app_XHHW_");
  119. printf("%s\n",basename_str);
  120. if (basename_str)
  121. {
  122. sscanf(basename_str, "app_XHHW_%d_%d_%d", &dev->major, &dev->minor, &dev->build);
  123. printd("app_XHHW_%d_%d_%d\n", dev->major, dev->minor, dev->build);
  124. }
  125. }
  126. return 0;
  127. }
  128. int android_DowanloadFile(update_t* dev, const char* filename)
  129. {
  130. FILE *fp = fopen(filename, "a+");
  131. printf("fp =%p\n",fp);
  132. if (fp)
  133. {
  134. dev->state = UPDATING;
  135. int recved = 0;
  136. while(recved < dev->filesize)
  137. {
  138. int len = dev->filesize - recved;
  139. if (len > 1024) len = 1024;
  140. int ret = recv(dev->fd, dev->rxbuff, len, 0);
  141. if (ret <= 0) {
  142. printd("ret:%d, errno:%d\n", ret, errno);
  143. shutdown(dev->fd, SHUT_RDWR);
  144. close(dev->fd);
  145. dev->fd = -1;
  146. return -1;
  147. }
  148. if (ret > 0) recved += ret;
  149. fwrite(dev->rxbuff, ret, 1, fp);
  150. }
  151. if (recved == dev->filesize)
  152. {
  153. dev->state = SUCCESS;
  154. }else{
  155. dev->state = FAIL;
  156. }
  157. fclose(fp);
  158. printd("recvd.filename=%s, recvd.bytes:%d\n", filename, recved);
  159. return 0;
  160. }
  161. return -1;
  162. }
  163. int android_Upgrade(update_t* dev, const char* oldfilename, const char* newfilename)
  164. {
  165. if (dev->state == SUCCESS)
  166. {
  167. int idx = 0;
  168. char cmdbuff[256];
  169. memset(cmdbuff,0,sizeof(cmdbuff));
  170. idx += sprintf(&cmdbuff[idx], "pkill app_XHHW\n");
  171. idx += sprintf(&cmdbuff[idx], "chmod +x %s\n", newfilename);
  172. idx += sprintf(&cmdbuff[idx], "rm -f %s\n", oldfilename);
  173. idx += sprintf(&cmdbuff[idx], "ln -s %s %s\n", newfilename, oldfilename);
  174. idx += sprintf(&cmdbuff[idx], "sync\n");
  175. idx += sprintf(&cmdbuff[idx], "reboot\n");
  176. int ret = system(cmdbuff);
  177. printf( "ret = %d, cmd = %s\n", ret, cmdbuff);
  178. // sprintf(cmdbuff, "chmod +x %s", newfilename);system(cmdbuff);
  179. // sprintf(cmdbuff, "rm -f %s", oldfilename);system(cmdbuff);
  180. // sprintf(cmdbuff, "ln -s %s %s", newfilename, oldfilename);system(cmdbuff);
  181. // sprintf(cmdbuff, "/home/root/bin/hmi.sh");system(cmdbuff);
  182. // chmod(filename, S_IRUSR|S_IWUSR|S_IXUSR | S_IXGRP|S_IRGRP|S_IXGRP | S_IROTH|S_IWOTH|S_IXOTH);
  183. // unlink(newfilename);
  184. // symlink(filename, newfilename);
  185. dev->state = IDLE;
  186. return 0;
  187. }
  188. return -1;
  189. }
  190. int android_NotifyUpdateFirmware_res(update_t* dev, const char* status)
  191. {
  192. int len = sprintf(dev->txbuff, "Event=NotifyUpdateFirmware,Type=HW,Status=%s,Message=NONE\n", status);
  193. printd("send : %s\n",dev->txbuff);
  194. if (dev->fd > 0)
  195. return send(dev->fd, dev->txbuff, len, 0);
  196. else
  197. return -1;
  198. }
  199. int android_RequestUpdateFirmware_req(update_t* dev,int major, int minor, int build)
  200. {
  201. int len = sprintf(dev->txbuff, "Event=UpdateFirmware,Type=HW,Version=%d.%d.%d\n",major, minor, build);
  202. printd("send : %s\n",dev->txbuff);
  203. if (dev->fd > 0)
  204. return send(dev->fd, dev->txbuff, len, 0);
  205. else
  206. return -1;
  207. }
  208. int android_NotifyUpdateFirmwareResult_res(update_t* dev, const char* status,int major, int minor, int build)
  209. {
  210. int len = sprintf(dev->txbuff, "Event=NotifyUpdateFirmwareResult,Type=HW,Status=%s,Version=%d.%d.%d,Message=NONE\n", status, major, minor, build);
  211. printd("send : %s\n",dev->txbuff);
  212. if (dev->fd > 0)
  213. return send(dev->fd, dev->txbuff, len, 0);
  214. else
  215. return -1;
  216. }
  217. int android_GetFirmwareVersion_res(update_t* dev, int major, int minor, int build)
  218. {
  219. int len = sprintf(dev->txbuff, "Event=GetFirmwareVersion,Type=HW,Version=%d.%d.%d\n", major, minor, build);
  220. printd("send : %s\n",dev->txbuff);
  221. if (dev->fd > 0)
  222. return send(dev->fd, dev->txbuff, len, 0);
  223. else
  224. return -1;
  225. }
  226. int android_connect(update_t *dev)
  227. {
  228. if (dev)
  229. {
  230. while (dev->fd < 0)
  231. {
  232. dev->fd = socket(AF_INET, SOCK_STREAM, 0);
  233. if (dev->fd > 0)
  234. {
  235. dev->peer_addr.sin_family = AF_INET;
  236. dev->peer_addr.sin_addr.s_addr = inet_addr(dev->ip_string);
  237. dev->peer_addr.sin_port = htons(dev->port);
  238. dev->peer_addrlen = sizeof(dev->peer_addr);
  239. while(connect(dev->fd, (struct sockaddr*)&dev->peer_addr, dev->peer_addrlen) < 0){
  240. printd("local socket connect to %s.%d failed.retry...\n", dev->ip_string, dev->port);
  241. sleep(1);
  242. }
  243. printf("local socket connect to %s.%d ok.\n", dev->ip_string, dev->port);
  244. return 0;
  245. }
  246. printd("create socket failed.retry...\n");
  247. sleep(1);
  248. }
  249. return 0;
  250. }
  251. return -1;
  252. }
  253. void* xh_update_loop(void* argv)
  254. {
  255. update_t *dev = (update_t*)argv;
  256. while(dev->quit == 0)
  257. {
  258. android_connect(dev);
  259. if (wait_android_message(dev) == 0)
  260. {
  261. if (strncmp(dev->rxbuff, "Event=NotifyUpdateFirmware,Type=HW", 34)==0)
  262. {
  263. char newfilename[256];
  264. char oldfilename[256];
  265. memset(newfilename,0,sizeof(newfilename));
  266. memset(oldfilename,0,sizeof(oldfilename));
  267. sprintf(oldfilename, "/home/root/bin/app_XHHW");
  268. sscanf(dev->rxbuff, "Event=NotifyUpdateFirmware,Type=HW,Size=%d,Version=%d.%d.%d\n", &dev->filesize, &dev->majorVersion, &dev->minorVersion, &dev->buildVersion);
  269. sprintf(newfilename, "/home/root/bin/app_XHHW_%d_%d_%d", dev->majorVersion, dev->minorVersion, dev->buildVersion);
  270. printf("as =%d,%d,%d,%d\n",dev->filesize, dev->majorVersion, dev->minorVersion, dev->buildVersion);
  271. if (dev->major != dev->majorVersion || dev->minor!=dev->minorVersion || dev->build!=dev->buildVersion)
  272. {
  273. if (android_NotifyUpdateFirmware_res(dev, "Accepted") >= 0)
  274. {
  275. sleep(1);
  276. if (android_RequestUpdateFirmware_req(dev, dev->majorVersion, dev->minorVersion, dev->buildVersion) >= 0)
  277. {
  278. if (android_DowanloadFile(dev, newfilename) == 0)
  279. {
  280. if (android_Upgrade(dev, oldfilename, newfilename) == 0)
  281. {
  282. dev->major = dev->majorVersion;
  283. dev->minor = dev->minorVersion;
  284. dev->build = dev->buildVersion;
  285. android_NotifyUpdateFirmwareResult_res(dev, "Success", dev->majorVersion, dev->minorVersion, dev->buildVersion);
  286. }
  287. }else{
  288. android_NotifyUpdateFirmwareResult_res(dev, "Fail", dev->majorVersion, dev->minorVersion, dev->buildVersion);
  289. }
  290. }
  291. }
  292. }else{
  293. android_NotifyUpdateFirmware_res(dev, "Rejected");
  294. }
  295. }
  296. if (strncmp(dev->rxbuff, "Event=NotifyUpdateFirmwareResult,Type=HW", 40)==0)
  297. {
  298. continue;
  299. }
  300. if (strncmp(dev->rxbuff, "Event=GetFirmwareVersion,Type=HW", 32)==0)
  301. {
  302. android_GetFirmwareVersion_res(dev, dev->major, dev->minor, dev->build);
  303. }
  304. }
  305. }
  306. return NULL;
  307. }
  308. int xh_update_init(update_t *dev)
  309. {
  310. if (dev)
  311. {
  312. dev->fd = -1;
  313. // dev->logfp = fopen("/home/root/bin/log.txt", "w");
  314. android_connect(dev);
  315. android_LoadVersion(dev, "/home/root/bin/app_XHHW");
  316. }
  317. return -1;
  318. }
  319. void xh_update_exit(update_t *dev)
  320. {
  321. if (dev)
  322. {
  323. dev->quit = 1;
  324. close(dev->fd);
  325. dev->fd = -1;
  326. }
  327. }
  328. int main(int argc, char* argv[])
  329. {
  330. sleep(10);
  331. update_t* dev = (update_t*)&update;
  332. {
  333. int c;
  334. dev->port = 20248;
  335. sprintf(dev->ip_string, "%s", "192.168.223.10");
  336. while ((c = getopt(argc, argv, "ip:")) != -1) {
  337. switch (c) {
  338. case 'i':
  339. sprintf(dev->ip_string, "%s", optarg);
  340. break;
  341. case 'p':
  342. dev->port = atoi(optarg);
  343. break;
  344. case '?':
  345. break;
  346. default:
  347. exit(2);
  348. }
  349. }
  350. xh_update_init(dev);
  351. xh_update_loop(dev);
  352. xh_update_exit(dev);
  353. }
  354. return 0;
  355. }