| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578 |
- #include <errno.h>
- #include <stdio.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include "elog.h"
- #include "upg.h"
- #include "file.h"
- #include "thread.h"
- #include "modbus_handle.h"
- #if 1
- #define LOGD log_d
- #define LOGE log_e
- #else
- #define LOGD printf
- #define LOGE printf
- #endif
- #define RETRY_MAX 3
- #define REG_UPG_READ 1501
- #define REG_UPG_WRITE 1550
- #define REG_UPG_JUMP 6330
- #define REG_BOARD_INFO 6331
- enum {
- OFFLINE=0,
- ONLINE,
- UPGRADING,
- UPGRADE_OK,
- UPGRADE_FAIL,
- };
- #pragma pack (1)
- typedef struct {
- int16_t pid;
- uint16_t dlen;
- uint8_t data[0];
- }upg_pkt_t;
- #pragma pack ()
- typedef struct {
- uint32_t id[3];
- uint32_t channels;
- char ver[12];
- char date[32];
- }switch_info_t;
- typedef struct {
- int upging;
- char path[200];
- }upg_arg_t;
- typedef struct {
- key_t key;
- upg_arg_t arg;
- handle_t upg;
- handle_t all;
- GlobalDeviceManager *dm;
- int init;
- }upg_handle_t;
- static upg_handle_t uHandle={0};
- static int upg_board_scan(void);
- static void* board_thread(void *arg);
- static void mem_swap(void *buf, int len)
- {
- int i;
- uint8_t tmp,*pbuf=(uint8_t*)buf;
- for(i=0; i<len; i+=2) {
- tmp = pbuf[i];
- pbuf[i] = pbuf[i+1];
- pbuf[i+1] = tmp;
- }
- }
- static int mb_read(Modbus_Manger *mm, uint16_t addr, uint16_t reg, void *data, int len, int timeout)
- {
- int to,r,cnt=(len+len%2)/2;
-
- g_modbus_get_timeout(mm, &to);
- g_modbus_set_timeout(mm, timeout);
- r = g_modbus_read_x_reg(mm, addr, reg, cnt, data);
- g_modbus_set_timeout(mm, to);
- //if(r>0) mem_swap(data, r*2);
- return (r==cnt)?0:-1;
- }
- static int mb_write(Modbus_Manger *mm, uint16_t addr, uint16_t reg, void *data, int len, int timeout)
- {
- int to,r,cnt=(len+len%2)/2;
- g_modbus_get_timeout(mm, &to);
- g_modbus_set_timeout(mm, timeout);
- r = g_modbus_write_x_reg(mm, addr, reg, cnt, data);
- g_modbus_set_timeout(mm, to);
- return (r==cnt)?0:-1;
- }
- //////////////////////////////////////////////////////////////////////
- #define UPG_RW_TIMEOUT 200
- static void sw_to_info(int addr, board_info_t *info, switch_info_t *swinfo, int status)
- {
- info->addr = addr;
- info->brd_id = swinfo->id[0];
- info->channels = swinfo->channels;
- info->status = status;
- strcpy(info->name, "Board");
- strcpy(info->ver, swinfo->ver);
- get_bldtime2(info->date, swinfo->date);
- }
- static int board_is_upgrading(Modbus_Manger* mm, int addr)
- {
- int r;
- uint16_t tmp;
-
- r = mb_read(mm, addr, REG_UPG_READ, &tmp, sizeof(tmp), UPG_RW_TIMEOUT);
- return (r==0)?1:0;
- }
- static int board_upgrade_jump(Modbus_Manger* mm, int addr)
- {
- int r;
- uint16_t tmp=1;
- r = mb_write(mm, addr, REG_UPG_JUMP, &tmp, sizeof(tmp), UPG_RW_TIMEOUT);
- return r;
- }
- static int board_get_info(Modbus_Manger* mm, int addr, switch_info_t *info)
- {
- int r;
- r = mb_read(mm, addr, REG_BOARD_INFO, info, sizeof(switch_info_t), UPG_RW_TIMEOUT);
- if(r==0) {
- LOGD("___board %d ver: %s\n", addr, info->ver);
- LOGD("___board %d date: %s\n", addr, info->date);
- }
- return r;
- }
- static int set_info(handle_t l, node_t *nd, node_t *xd, void *arg, int *act)
- {
- board_info_t *info1=(board_info_t*)nd->buf;
- board_info_t *info2=(board_info_t*)xd->buf;
- if(info1->addr<=0) {
- info2->status = info1->status;
- return 0;
- }
- else {
- if(info1->addr==info2->addr) {
- *act = LIST_ACT_STOP;
- *info2 = *info1;
- return 0;
- }
- else {
- return -1;
- }
- }
- }
- static int board_info_set(board_info_t *info)
- {
- int r=-1;
- node_t node;
- handle_t l=uHandle.all;
- node.buf = info;
- node.dlen = sizeof(board_info_t);
- node.blen = sizeof(board_info_t);
- r = xlist_iterator(l, &node, set_info, NULL);
- return r;
- }
- static int board_send(Modbus_Manger *mm, uint16_t addr, char *data, int dlen)
- {
- int r,pid=0;
- char temp[400];
- int slen=0,onelen=0,onemax=128;
- upg_pkt_t *pkt=(upg_pkt_t*)temp;
- r = board_upgrade_jump(mm, addr);
- while(1) {
- if((slen+onemax)>=dlen) {
- //onelen = dlen-(slen+onemax);
- onelen = onemax;
- pid = -1;
- }
- else {
- onelen = onemax;
- }
- memcpy(pkt->data, data+slen, onelen);
- pkt->pid = pid;
- pkt->dlen = onelen;
- r = mb_write(mm, addr, REG_UPG_WRITE, pkt, onelen+sizeof(upg_pkt_t), 10);
- slen += onelen;
- if(pid==0) sleep(1);
- else usleep(10000);
- if(pid<0) break;
- pid++;
- }
- sleep(1);
- return 0;
- }
- static int board_proc(upg_handle_t *h, int quit)
- {
- int ok=0,err=0;
- buf_t fbuf;
- int i,r,timeout;
- switch_info_t swinfo;
- handle_t l=h->upg;
- list_node_t *ln=NULL;
- board_info_t info,*tmp;
- Modbus_Manger *mm=&h->dm->_globalRelaySampManger;
- r = file_load(h->arg.path, &fbuf);
- if(r) {
- return -1;
- }
- info.addr = -1;
- info.status = UPGRADING;
- board_info_set(&info);
- //broadcase upgrade file
- board_send(mm, 0, fbuf.buf, fbuf.dlen);
- while(1) {
- r = xlist_get_node(l, &ln, 0);
- if(r) {
- break;
- }
- tmp = (board_info_t*)ln->data.buf;
- for(i=0; i<RETRY_MAX; i++) {
- r = board_get_info(mm, tmp->addr, &swinfo);
- if(r==0) {
- break;
- }
- LOGE("___ board upgrade failed, retry %d\n", i+1);
- board_send(mm, i, fbuf.buf, fbuf.dlen);
- }
- if(r) {
- tmp->status = UPGRADE_FAIL;
- err++;
- }
- else {
- sw_to_info(tmp->addr, tmp, &swinfo, UPGRADE_OK);
- ok++;
- }
- board_info_set(tmp);
-
- xlist_remove(l, 0);
- }
- free(fbuf.buf);
- exit(0); //restart app
- return 0;
- }
- static int board_scan(void)
- {
- int i,r;
- board_info_t info={0};
- upg_handle_t *h=&uHandle;
- handle_t l=h->upg;
- Modbus_Manger *mm=&h->dm->_globalRelaySampManger;
-
- for(i=1; i<=h->dm->brdMax; i++) {
- r = board_is_upgrading(mm, i);
- if(r) {
- info.addr = i;
- info.status = UPGRADE_FAIL;
- xlist_append(l, 0, &info, sizeof(info));
- }
- }
- return 0;
- }
- static void start_threads(int flag)
- {
- if(flag) {
- thread_start2(THREAD_ID_SNMP);
- thread_start2(THREAD_ID_POWER);
- //thread_start2(THREAD_ID_CASCADE);
- //thread_start2(THREAD_ID_CASCADE_SCAN);
- //thread_start2(THREAD_ID_BREAKER);
- //thread_start2(THREAD_ID_BREAKER_SCANNER);
- }
- else {
- thread_stop(THREAD_ID_SNMP);
- thread_stop(THREAD_ID_POWER);
- //thread_stop(THREAD_ID_CASCADE);
- //thread_stop(THREAD_ID_CASCADE_SCAN);
- //thread_stop(THREAD_ID_BREAKER);
- //thread_stop(THREAD_ID_BREAKER_SCANNER);
- }
- }
- static void* board_thread(void *arg)
- {
- int r;
- thread_handle_t *th=(thread_handle_t*)arg;
- upg_handle_t *h=(upg_handle_t*)th->arg;
- Modbus_Manger *mm=&h->dm->_globalRelaySampManger;
- board_scan();
- upg_board_all_update();
- while(th->quit==0) {
- if(h->arg.upging) {
-
- start_threads(0);
- r = board_proc(h, th->quit);
- start_threads(1);
-
- file_remove(h->arg.path);
- h->arg.upging = 0;
- }
- else {
- sleep(2);
- }
- }
- pthread_exit(NULL);
- }
- /////////////////////////////////////////////////////
- int upg_init(void)
- {
- int r,msgid;
- list_cfg_t lc={0,LIST_FULL_FIFO,-1};
- upg_handle_t *h=&uHandle;
-
- memset(h, 0, sizeof(upg_handle_t));
- h->dm = &__globalDeviceManage;
- h->key = ftok(UPG_KEY_PATH, UPG_KEY_SN);
- if(h->key<0) {
- LOGE("ftok %s failed, errno: %d\n", UPG_KEY_PATH, errno);
- return -1;
- }
- h->upg = xlist_init(&lc);
- h->all = xlist_init(&lc);
- h->init = 1;
- #ifdef USE_BOARD_UPGRADE
- thread_start(THREAD_ID_BOARD, board_thread, h);
- #endif
- upg_host_send(UPGRADE_EVT_APP_RUNNING);
-
- return 0;
- }
- int upg_host_send(int evt)
- {
- int r,msgid;
- msgbuf_t mb;
- upg_handle_t *h=&uHandle;
- msgid = msgget(h->key, 0666|IPC_CREAT);
- //LOGD("+++++++++++ key: %d, msgid: %d\n", ukey, msgid);
-
- mb.evt = evt;
- r = msgsnd(msgid, &mb, sizeof(mb.evt), IPC_NOWAIT);
- if(r<0) {
- LOGE("msgsnd failed, %d, errno: %d\n", r, errno);
- }
- else {
- LOGD("msgsnd evt 0x%02x ok\n", evt);
- }
-
- return r;
- }
- /////////////////////////////////////////////////////////
- handle_t upg_board_list_get(void)
- {
- upg_handle_t *h=&uHandle;
- return h->upg;
- }
- int upg_board_list_set(char *s)
- {
- int i=0,n=0,max=0;
- char tmp[10],*p=s;
- char *tok="productId=";
- board_info_t info={0};
- handle_t l=uHandle.upg;
- if(!s) {
- return -1;
- }
- p = strstr(p, tok);
- if(!p) {
- return -1;
- }
- p += strlen(tok);
- while(1) {
- if((*p)==',' || (*p)=='&') {
- tmp[i] = 0;
- info.addr = atoi(tmp);
- xlist_append(l, 0, &info, sizeof(info));
- i = 0; n++;
- if((*p)=='&') {
- break;
- }
- }
- else {
- tmp[i++] = *p;
- }
- p++;
- }
- return (n>0)?0:-1;
- }
- handle_t upg_board_all_get(void)
- {
- int r;
- upg_handle_t *h=&uHandle;
- return h->all;
- }
- int upg_board_all_update(void)
- {
- int i,r,addr;
- list_node_t *ln=NULL;
- upg_handle_t *h=&uHandle;
- handle_t l=h->all;
- Modbus_Manger *mm=&h->dm->_globalRelaySampManger;
- GlobalPowerManger *tmp,*hd=&h->dm->_globalPowerManger;
- switch_info_t swinfo;
- board_info_t info;
- if(!h->init) {
- return -1;
- }
- xlist_clear(l);
- list_for_each_entry(tmp,&hd->list,list) {
- if(tmp->product_saddr>0) {
- addr = tmp->product_saddr;
- for(i=0; i<RETRY_MAX; i++) {
- r = board_get_info(mm, addr, &swinfo);
- if(r==0) {
- sw_to_info(addr, &info, &swinfo, ONLINE);
- xlist_append(l, 0, &info, sizeof(info));
- break;
- }
- }
- }
- }
- while(1) {
- r = xlist_take_node(h->upg, &ln, 0);
- if(r) {
- break;
- }
- xlist_append_node(h->all, ln);
- }
- return 0;
- }
- static int fw_check(char *path);
- int upg_board_start(char *path)
- {
- upg_handle_t *h=&uHandle;
- if(h->arg.upging==1) {
- return -1;
- }
- strcpy(h->arg.path,path);
- h->arg.upging = 1;
- return 0;
- }
- #include "md5.h"
- #include "file.h"
- #define FW_HEAD_MAGIC "GOWONE_UPGRADE"
- #pragma pack (1)
- typedef union {
- struct {
- uint8_t magic[14];
- uint16_t size;
- uint32_t partition;
- uint32_t version;
- }hdr;
- uint8_t padd[128];
- }fw_hdr_t;
- #pragma pack ()
- #define CHAR(b) (((b)<=9)?((b)+0x30):((b)-10+0x61));
- static void byte2char(char *chr, uint8_t b)
- {
- chr[0] = CHAR(b>>4);
- chr[1] = CHAR(b&0x0f);
- }
- static void print_md5(char *s, md5_t *m)
- {
- int i;
-
- printf("__%s", s);
- for(i=0; i<32; i++) {
- printf("%c", m->data[i]);
- }
- printf("\n");
- }
- //md5相同返回0,否则返回1
- static int md5_check(buf_t *fb)
- {
- md5_t m1,m2;
- md5_ctx_t ctx;
- uint8_t i,tmp[16];
- md5_init(&ctx);
- md5_update(&ctx, (uint8_t*)fb->buf, fb->dlen-32);
- md5_final(&ctx, tmp);
- for (i=0; i<16; i++) {
- byte2char(&m2.data[i*2], tmp[i]);
- }
- memcpy(&m1, fb->buf+fb->dlen-32, sizeof(md5_t));
- print_md5("ori md5: ", &m1);
- print_md5("cal md5: ", &m2);
- if(memcmp(&m1, &m2, sizeof(md5_t))) {
- return -1;
- }
- return 0;
- }
- int upg_board_file_check(char *path)
- {
- int r=UPG_OK;
- buf_t fb;
- upg_handle_t *h=&uHandle;
- if(h->arg.upging==1) {
- return UPG_BUSYING;
- }
- r = file_load(path, &fb);
- if(r) {
- return -1;
- }
- fw_hdr_t *fh=(fw_hdr_t*)fb.buf;
- if(memcmp(fh->hdr.magic,FW_HEAD_MAGIC,sizeof(FW_HEAD_MAGIC))) {
- LOGE("not found %s, invalid board firmware\n", FW_HEAD_MAGIC);
- r = UPG_HDR_FAIL;
- }
- if(md5_check(&fb)) {
- LOGE("md5 check failed, invalid board firmware\n");
- r = UPG_MD5_FAIL;
- }
- free(fb.buf);
- return r;
- }
- int upg_host_file_check(char *path)
- {
- return 0;
- }
|