| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <unistd.h> // close()
- #include <string.h> // strcpy, memset(), and memcpy()
- #include <stdarg.h>
- #include <errno.h> // errno, perror()
- #include <stdbool.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <math.h>
- #include <dirent.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <getopt.h>
- #include <termios.h>
- #include <netdb.h> // struct addrinfo
- #include <sys/stat.h>
- #include <sys/ioctl.h> // macro ioctl is defined
- #include <bits/ioctls.h> // defines values for argument "request" of ioctl.
- #include <sys/syscall.h>
- #include <sys/types.h> // needed for socket(), uint8_t, uint16_t, uint32_t
- #include <sys/select.h>
- #include <sys/socket.h> // needed for socket()
- #include <sys/time.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <libgen.h>
- #include <netinet/in.h> // IPPROTO_ICMP, INET_ADDRSTRLEN
- #include <netinet/ip.h> // struct ip and IP_MAXPACKET (which is 65535)
- #include <netinet/ip_icmp.h> // struct icmp, ICMP_ECHO
- #include <arpa/inet.h> // inet_pton() and inet_ntop()
- #include <net/if.h> // struct ifreq
- #include <net/ethernet.h>
- #include <linux/if_ether.h> // ETH_P_IP = 0x0800, ETH_P_IPV6 = 0x86DD
- #include <linux/if_packet.h> // struct sockaddr_ll (see man 7 packet)
- #include <linux/serial.h>
- #include <linux/can.h>
- #include <linux/can/raw.h>
- typedef enum
- {
- ACCEPTED,
- REJECTED,
- SUCCESS,
- FAIL,
- IDLE,
- UPDATING,
- }state_t;
- typedef struct update
- {
- int quit;
- int fd;
- int state;
- struct sockaddr_in peer_addr;
- socklen_t peer_addrlen;
- uint8_t rxbuff[1024];
- int rxbyte;
- uint8_t txbuff[1024];
- int txbyte;
- int filesize;
- int majorVersion;
- int minorVersion;
- int buildVersion;
- int major;
- int minor;
- int build;
- char ip_string[64];
- int port;
- FILE *logfp;
- }update_t;
- static update_t update =
- {
- .fd = -1,
- .logfp = NULL
- };
- #define printd(fmt, ...) printf("%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
- // #define printd(fmt, ...) fprintf(dev->logfp, "%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
- int android_RequestUpdateFirmware(update_t* dev,int major, int minor, int build);
- int wait_android_message(update_t* dev)
- {
- dev->rxbyte = 0;
- while(dev->rxbyte < 1024)
- {
- int ret = recv(dev->fd, &dev->rxbuff[dev->rxbyte], 1, 0);
- if (ret <= 0) {
- printd("ret:%d, errno:%d\n", ret, errno);
- shutdown(dev->fd, SHUT_RDWR);
- close(dev->fd);
- dev->fd = -1;
- return -1;
- }
- if (ret > 0) dev->rxbyte += ret;
- if (dev->rxbyte>=5)
- {
- if (strncmp(dev->rxbuff, "Event", 5)==0)
- {
- if (dev->rxbuff[dev->rxbyte-1] == '\n')
- {
- return 0;
- }
- }else{
- memmove(&dev->rxbuff[0], &dev->rxbuff[1], dev->rxbyte - 1);
- dev->rxbyte = dev->rxbyte - 1;
- }
- }
- }
- return -1;
- }
- int android_LoadVersion(update_t* dev, const char* filename)
- {
- char filebuff[256];
- dev->major = dev->major = dev->build = 0;
- memset(filebuff,0,sizeof(filebuff));
- int ret = readlink(filename, filebuff, sizeof(filebuff));
- printd("%s\n",filebuff);
- if (ret > 0)
- {
- // char* basename_str = strchr(filebuff, '/');
- // if (basename_str)
- {
- sscanf(filebuff, "app_XHHW_%d_%d_%d", &dev->major, &dev->minor, &dev->build);
- }
- printd("dev->major =%d, dev->minor=%d, dev->build=%d\n",dev->major,dev->minor,dev->build);
- }
- return 0;
- }
- int android_DowanloadFile(update_t* dev, const char* filename)
- {
- printd("write %s\n",filename);
- FILE *fp = fopen(filename, "w");
- if (fp)
- {
-
- dev->state = UPDATING;
- int recved = 0;
- printd("this =%d,%d\n",__LINE__,dev->filesize);
- android_RequestUpdateFirmware(dev,dev->majorVersion, dev->minorVersion, dev->buildVersion);
- while(recved < dev->filesize)
- {
- int len = dev->filesize - recved;
- if (len > 1024) len = 1024;
- int ret = recv(dev->fd, dev->rxbuff, len, 0);
- printd("recved =%d\n",recved);
- if (ret <= 0) {
- printd("ret:%d, errno:%d\n", ret, errno);
- shutdown(dev->fd, SHUT_RDWR);
- close(dev->fd);
- dev->fd = -1;
- return -1;
- }
- if (ret > 0) recved += ret;
-
- fwrite(dev->rxbuff, ret, 1, fp);
- }
- if (recved == dev->filesize)
- {
- dev->state = SUCCESS;
- printd("recv success\n");
- }else{
- dev->state = FAIL;
- printd("recv fail\n");
- }
- fclose(fp);
- return 0;
- }
- return -1;
- }
- int android_Upgrade(update_t* dev, const char* oldfilename, const char* newfilename)
- {
- int ret ;
- if (dev->state == SUCCESS)
- {
- int idx = 0;
- char cmdbuff[256];
- memset(cmdbuff,0,sizeof(cmdbuff));
- idx += sprintf(&cmdbuff[idx], "pkill app_XHHW\n");
- idx += sprintf(&cmdbuff[idx], "chmod +x %s\n", newfilename);
- idx += sprintf(&cmdbuff[idx], "rm -f %s\n", oldfilename);
- idx += sprintf(&cmdbuff[idx], "ln -s %s %s\n", newfilename, oldfilename);
- idx += sprintf(&cmdbuff[idx], "sync\n");
- idx += sprintf(&cmdbuff[idx], "reboot\n");
- ret = system(cmdbuff);
- printf( "ret = %d, cmd = %s\n", ret, cmdbuff);
- // sleep(1);
- // memset(cmdbuff,0,sizeof(cmdbuff));
- // sprintf(cmdbuff, "chmod +x %s", newfilename);ret = system(cmdbuff);
- // printf( "ret = %d, cmd = %s\n", ret, cmdbuff);
- // sleep(1);
- // memset(cmdbuff,0,sizeof(cmdbuff));
- // sprintf(cmdbuff, "rm -f %s", oldfilename); ret = system(cmdbuff);
- // printf( "ret = %d, cmd = %s\n", ret, cmdbuff);
- // ret = unlink(oldfilename);
- // printf( "ret = %d, unlink = %s\n", ret, cmdbuff);
- // sleep(1);
- // memset(cmdbuff,0,sizeof(cmdbuff));
- // sprintf(cmdbuff, "ln -s %s %s", newfilename, oldfilename);ret = system(cmdbuff);
- // printf( "ret = %d, cmd = %s\n", ret, cmdbuff);
- // sprintf( cmdbuff, "/home/root/hmi.sh");system(cmdbuff);
- // chmod(filename, S_IRUSR|S_IWUSR|S_IXUSR | S_IXGRP|S_IRGRP|S_IXGRP | S_IROTH|S_IWOTH|S_IXOTH);
- // unlink(newfilename);
- // symlink(filename, newfilename);
- dev->state = IDLE;
- return 0;
- }
- return -1;
- }
- int android_NotifyUpdateFirmware_res(update_t* dev, const char* status)
- {
- int len = sprintf(dev->txbuff, "Event=NotifyUpdateFirmware,Type=HW,Status=%s,Message=NONE\n", status);
- printd("%s\n",dev->txbuff);
- if (dev->fd > 0)
- return send(dev->fd, dev->txbuff, len, 0);
- else
- return -1;
- }
- int android_RequestUpdateFirmware(update_t* dev,int major, int minor, int build)
- {
- int len = sprintf(dev->txbuff, "Event=UpdateFirmware,Type=HW,Version=%d.%d.%d\n",major, minor, build);
- printd("%s\n",dev->txbuff);
- if (dev->fd > 0)
- return send(dev->fd, dev->txbuff, len, 0);
- else
- return -1;
- }
- int android_NotifyUpdateFirmwareResult_res(update_t* dev, const char* status,int major, int minor, int build)
- {
- int len = sprintf(dev->txbuff, "Event=NotifyUpdateFirmwareResult,Type=HW,Status=%s,Version=%d.%d.%d,Message=NONE\n", status, major, minor, build);
- printd("%s\n",dev->txbuff);
- if (dev->fd > 0)
- return send(dev->fd, dev->txbuff, len, 0);
- else
- return -1;
- }
- int android_GetFirmwareVersion_res(update_t* dev, int major, int minor, int build)
- {
- int len = sprintf(dev->txbuff, "Event=GetFirmwareVersion,Type=HW,Version=%d.%d.%d\n", major, minor, build);
- printd("%s\n",dev->txbuff);
- if (dev->fd > 0)
- return send(dev->fd, dev->txbuff, len, 0);
- else
- return -1;
- }
- int android_connect(update_t *dev)
- {
- if (dev)
- {
- while (dev->fd < 0)
- {
- dev->fd = socket(AF_INET, SOCK_STREAM, 0);
- dev->peer_addr.sin_family = AF_INET;
- dev->peer_addr.sin_addr.s_addr = inet_addr(dev->ip_string);
- dev->peer_addr.sin_port = htons(dev->port);
- dev->peer_addrlen = sizeof(dev->peer_addr);
- int ret = connect(dev->fd, (struct sockaddr*)&dev->peer_addr, dev->peer_addrlen);
- if (ret >= 0)
- {
- printd("local socket connect to %s.%d ok.\n", dev->ip_string, dev->port);
- return 0;
- }else{
- printd("local socket connect to %s.%d failed.\n", dev->ip_string, dev->port);
- close(dev->fd);
- dev->fd = -1;
- }
- sleep(1);
- }
- }
- return -1;
- }
- void* xh_update_loop(void* argv)
- {
- update_t *dev = (update_t*)argv;
- while(dev->quit == 0)
- {
- if (wait_android_message(dev) == 0)
- {
- printd("%s\n",dev->rxbuff);
- if (strncmp(dev->rxbuff, "Event=NotifyUpdateFirmware,Type=HW", 34)==0)
- {
- printd("update cmd\n");
- char newfilename[256];
- char oldfilename[256];
- memset(newfilename,0,sizeof(newfilename));
- memset(oldfilename,0,sizeof(oldfilename));
- sprintf(oldfilename, "/home/root/bin/app_XHHW");
- sscanf(dev->rxbuff, "Event=NotifyUpdateFirmware,Type=HW,Size=%d,Version=%d.%d.%d\n", &dev->filesize, &dev->majorVersion, &dev->minorVersion, &dev->buildVersion);
- sprintf(newfilename, "/home/root/bin/app_XHHW_%d_%d_%d", dev->majorVersion, dev->minorVersion, dev->buildVersion);
- if (dev->major != dev->majorVersion || dev->minor!=dev->minorVersion || dev->build!=dev->buildVersion)
- {
- android_NotifyUpdateFirmware_res(dev, "Accepted");
- sleep(1);
-
- if (android_DowanloadFile(dev, newfilename)==0)
- {
- printd("android_DowanloadFile==0\n");
- if (android_Upgrade(dev, oldfilename, newfilename)==0)
- {
- dev->major = dev->majorVersion;
- dev->minor = dev->minorVersion;
- dev->build = dev->buildVersion;
- android_NotifyUpdateFirmwareResult_res(dev, "Success", dev->majorVersion, dev->minorVersion, dev->buildVersion);
- }
- printd("android_DowanloadFile==1\n");
- }else{
- printd("android_DowanloadFile==2\n");
- android_NotifyUpdateFirmwareResult_res(dev, "Fail", dev->majorVersion, dev->minorVersion, dev->buildVersion);
- }
- }else {
- android_NotifyUpdateFirmware_res(dev, "Rejected");
- }
- }
- if (strncmp(dev->rxbuff, "Event=NotifyUpdateFirmwareResult,Type=HW", 40)==0)
- {
- continue;
- }
- if (strncmp(dev->rxbuff, "Event=GetFirmwareVersion,Type=HW", 32)==0)
- {
- android_GetFirmwareVersion_res(dev, dev->major, dev->minor, dev->build);
- }
- }
- }
- return NULL;
- }
- int xh_update_init(update_t *dev)
- {
- if (dev)
- {
- // dev->logfp = fopen("/home/root/bin/log.txt", "w");
- android_connect(dev);
- android_LoadVersion(dev, "/home/root/bin/app_XHHW");
- }
- return -1;
- }
- void xh_update_exit(update_t *dev)
- {
- if (dev)
- {
- dev->quit = 1;
- close(dev->fd);
- dev->fd = -1;
- }
- }
- int main(int argc, char* argv[])
- {
- sleep(10);
- update_t* dev = (update_t*)&update;
- {
- int c;
- dev->port = 20248;
- sprintf(dev->ip_string, "%s", "192.168.223.10");
- while ((c = getopt(argc, argv, "ip:")) != -1) {
- switch (c) {
- case 'i':
- sprintf(dev->ip_string, "%s", optarg);
- break;
- case 'p':
- dev->port = atoi(optarg);
- break;
- case '?':
- break;
- default:
- exit(2);
- }
- }
- xh_update_init(dev);
- xh_update_loop(dev);
- xh_update_exit(dev);
- }
- return 0;
- }
|