|
@@ -4,22 +4,297 @@
|
|
|
#include <sys/msg.h>
|
|
#include <sys/msg.h>
|
|
|
#include "elog.h"
|
|
#include "elog.h"
|
|
|
#include "upg.h"
|
|
#include "upg.h"
|
|
|
|
|
+#include "file.h"
|
|
|
|
|
+#include "thread.h"
|
|
|
|
|
+#include "modbus_handle.h"
|
|
|
|
|
+
|
|
|
|
|
|
|
|
#if 1
|
|
#if 1
|
|
|
-#define LOGD log_d
|
|
|
|
|
-#define LOGE log_e
|
|
|
|
|
|
|
+ #define LOGD log_d
|
|
|
|
|
+ #define LOGE log_e
|
|
|
#else
|
|
#else
|
|
|
-#define LOGD printf
|
|
|
|
|
-#define LOGE printf
|
|
|
|
|
|
|
+ #define LOGD printf
|
|
|
|
|
+ #define LOGE printf
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
-static key_t ukey=0;
|
|
|
|
|
-static int upg_send(int evt)
|
|
|
|
|
|
|
+#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 {
|
|
|
|
|
+ ONLINE=0,
|
|
|
|
|
+ OFFLINE,
|
|
|
|
|
+ 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 ()
|
|
|
|
|
+
|
|
|
|
|
+#pragma pack (2)
|
|
|
|
|
+typedef struct {
|
|
|
|
|
+ uint32_t id[3];
|
|
|
|
|
+ uint32_t channels;
|
|
|
|
|
+ char ver[8];
|
|
|
|
|
+ char date[20];
|
|
|
|
|
+}switch_info_t;
|
|
|
|
|
+#pragma pack ()
|
|
|
|
|
+
|
|
|
|
|
+typedef struct {
|
|
|
|
|
+ int flag;
|
|
|
|
|
+ char path[200];
|
|
|
|
|
+}upg_arg_t;
|
|
|
|
|
+
|
|
|
|
|
+typedef struct {
|
|
|
|
|
+ key_t key;
|
|
|
|
|
+ upg_arg_t arg;
|
|
|
|
|
+ board_list_t upg;
|
|
|
|
|
+ board_list_t all;
|
|
|
|
|
+ GlobalDeviceManager *dm;
|
|
|
|
|
+
|
|
|
|
|
+}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_get_timeout(Modbus_Manger *mm)
|
|
|
|
|
+{
|
|
|
|
|
+ int r,timeout=0;;
|
|
|
|
|
+ r = g_modbus_get_timeout(mm, &timeout);
|
|
|
|
|
+ if(r) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ return timeout;
|
|
|
|
|
+}
|
|
|
|
|
+static int mb_set_timeout(Modbus_Manger *mm, int timeout)
|
|
|
|
|
+{
|
|
|
|
|
+ return g_modbus_set_timeout(mm, timeout);
|
|
|
|
|
+}
|
|
|
|
|
+static int mb_read(Modbus_Manger *mm, uint16_t addr, uint16_t reg, void *data, int len)
|
|
|
|
|
+{
|
|
|
|
|
+ int r,cnt=(len+len%2)/2;
|
|
|
|
|
+
|
|
|
|
|
+ r = g_modbus_read_x_reg(mm, addr, reg, cnt, data);
|
|
|
|
|
+ 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 r,cnt=(len+len%2)/2;
|
|
|
|
|
+ r = g_modbus_write_x_reg(mm, addr, reg, cnt, data);
|
|
|
|
|
+ return (r==cnt)?0:-1;
|
|
|
|
|
+}
|
|
|
|
|
+//////////////////////////////////////////////////////////////////////
|
|
|
|
|
+
|
|
|
|
|
+static int board_is_upgrading(void* manger, int addr)
|
|
|
|
|
+{
|
|
|
|
|
+ uint16_t tmp;
|
|
|
|
|
+ int r,timeout=0;
|
|
|
|
|
+
|
|
|
|
|
+ timeout = mb_get_timeout(manger);
|
|
|
|
|
+ mb_set_timeout(manger, 20);
|
|
|
|
|
+ r = mb_write(manger, addr, REG_UPG_READ, &tmp, sizeof(tmp));
|
|
|
|
|
+ mb_set_timeout(manger, timeout);
|
|
|
|
|
+
|
|
|
|
|
+ return r;
|
|
|
|
|
+}
|
|
|
|
|
+static int board_upgrade_set(void* manger, int addr)
|
|
|
|
|
+{
|
|
|
|
|
+ int r;
|
|
|
|
|
+ uint16_t tmp=1;
|
|
|
|
|
+
|
|
|
|
|
+ r = mb_write(manger, addr, REG_UPG_JUMP, &tmp, 1);
|
|
|
|
|
+ return r;
|
|
|
|
|
+}
|
|
|
|
|
+static int board_get_info(void* manger, int addr, switch_info_t *info)
|
|
|
|
|
+{
|
|
|
|
|
+ int r;
|
|
|
|
|
+ r = mb_read(manger, addr, REG_BOARD_INFO, info, sizeof(switch_info_t));
|
|
|
|
|
+ return r;
|
|
|
|
|
+}
|
|
|
|
|
+static int board_status_set(int addr, int status)
|
|
|
|
|
+{
|
|
|
|
|
+ int r=-1;
|
|
|
|
|
+ board_list_t *l=&uHandle.upg;
|
|
|
|
|
+
|
|
|
|
|
+ for(int i=0; i<l->cnt; i++) {
|
|
|
|
|
+ if(addr>0) {
|
|
|
|
|
+ if(l->info[i].addr==addr) {
|
|
|
|
|
+ l->info[i].status = status;
|
|
|
|
|
+ r = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ l->info[i].status = status;
|
|
|
|
|
+ r = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return r;
|
|
|
|
|
+}
|
|
|
|
|
+static int board_send(Modbus_Manger *mm, uint16_t addr, char *data, int dlen)
|
|
|
|
|
+{
|
|
|
|
|
+ int r,pid=0;
|
|
|
|
|
+ int slen=0,onelen=0,onemax=128;
|
|
|
|
|
+ char temp[400];
|
|
|
|
|
+
|
|
|
|
|
+ upg_pkt_t *pkt=(upg_pkt_t*)temp;
|
|
|
|
|
+ r = board_upgrade_set(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));
|
|
|
|
|
+ slen += onelen;
|
|
|
|
|
+ if(pid==0) usleep(100000);
|
|
|
|
|
+ else usleep(100000);
|
|
|
|
|
+
|
|
|
|
|
+ if(pid<0) break;
|
|
|
|
|
+ pid++;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+static int board_check(Modbus_Manger *mm, uint16_t addr)
|
|
|
|
|
+{
|
|
|
|
|
+ int r;
|
|
|
|
|
+ switch_info_t info;
|
|
|
|
|
+
|
|
|
|
|
+ r = mb_read(mm, addr, REG_BOARD_INFO, &info, sizeof(info));
|
|
|
|
|
+ if(r==0) {
|
|
|
|
|
+ LOGD("___board %d ver: %s\n", info.ver);
|
|
|
|
|
+ LOGD("___board %d date: %s\n", info.date);
|
|
|
|
|
+ }
|
|
|
|
|
+ return r;
|
|
|
|
|
+}
|
|
|
|
|
+static int board_proc(upg_handle_t *h, int quit)
|
|
|
|
|
+{
|
|
|
|
|
+ buf_t fbuf;
|
|
|
|
|
+ int i,j,r,timeout;
|
|
|
|
|
+ Modbus_Manger *mm=&h->dm->_globalRelaySampManger;
|
|
|
|
|
+
|
|
|
|
|
+ r = file_load(h->arg.path, &fbuf);
|
|
|
|
|
+ if(r) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ timeout = mb_get_timeout(mm);
|
|
|
|
|
+ mb_set_timeout(mm, 10);
|
|
|
|
|
+
|
|
|
|
|
+ board_status_set(-1, UPGRADING);
|
|
|
|
|
+ //broadcase upgrade file
|
|
|
|
|
+ board_send(mm, 1, fbuf.buf, fbuf.dlen);
|
|
|
|
|
+ for(i=1; i<=h->dm->brdMax; i++) {
|
|
|
|
|
+ if(h->dm->pCtrlBoard[i].product_saddr==0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for(j=0; j<RETRY_MAX; j++) {
|
|
|
|
|
+ r = board_check(mm, i);
|
|
|
|
|
+ if(r==0) break;
|
|
|
|
|
+ LOGE("___ board upgrade failed, retry %d\n", i);
|
|
|
|
|
+ board_send(mm, i, fbuf.buf, fbuf.dlen);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(r) {
|
|
|
|
|
+ board_status_set(i, UPGRADE_FAIL);
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ board_status_set(i, UPGRADE_OK);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ free(fbuf.buf);
|
|
|
|
|
+ mb_set_timeout(mm, timeout);
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+static int board_scan(void)
|
|
|
|
|
+{
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+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;
|
|
|
|
|
+
|
|
|
|
|
+ while(th->quit==0) {
|
|
|
|
|
+ if(h->arg.flag) {
|
|
|
|
|
+ thread_stop(THREAD_ID_SNMP);
|
|
|
|
|
+ thread_stop(THREAD_ID_POWER);
|
|
|
|
|
+
|
|
|
|
|
+ r = board_proc(h, th->quit);
|
|
|
|
|
+
|
|
|
|
|
+ thread_restart(THREAD_ID_SNMP);
|
|
|
|
|
+ thread_restart(THREAD_ID_POWER);
|
|
|
|
|
+
|
|
|
|
|
+ file_remove(h->arg.path);
|
|
|
|
|
+ h->arg.flag = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ sleep(2);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pthread_exit(NULL);
|
|
|
|
|
+}
|
|
|
|
|
+/////////////////////////////////////////////////////
|
|
|
|
|
+int upg_init(void)
|
|
|
|
|
+{
|
|
|
|
|
+ int r,msgid;
|
|
|
|
|
+ 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;
|
|
|
|
|
+ }
|
|
|
|
|
+ thread_start(THREAD_ID_BOARD, board_thread, h);
|
|
|
|
|
+
|
|
|
|
|
+ return upg_host_send(UPGRADE_EVT_APP_RUNNING);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int upg_host_send(int evt)
|
|
|
{
|
|
{
|
|
|
int r,msgid;
|
|
int r,msgid;
|
|
|
msgbuf_t mb;
|
|
msgbuf_t mb;
|
|
|
|
|
+ upg_handle_t *h=&uHandle;
|
|
|
|
|
|
|
|
- msgid = msgget(ukey, 0666| IPC_CREAT);
|
|
|
|
|
|
|
+ msgid = msgget(h->key, 0666|IPC_CREAT);
|
|
|
//LOGD("+++++++++++ key: %d, msgid: %d\n", ukey, msgid);
|
|
//LOGD("+++++++++++ key: %d, msgid: %d\n", ukey, msgid);
|
|
|
|
|
|
|
|
mb.evt = evt;
|
|
mb.evt = evt;
|
|
@@ -35,22 +310,94 @@ static int upg_send(int evt)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
-int upg_init(void)
|
|
|
|
|
|
|
+/////////////////////////////////////////////////////////
|
|
|
|
|
+board_list_t *upg_board_list_get(void)
|
|
|
{
|
|
{
|
|
|
- int r,msgid;
|
|
|
|
|
-
|
|
|
|
|
- ukey = ftok(UPG_KEY_PATH, UPG_KEY_SN);
|
|
|
|
|
- if(ukey<0) {
|
|
|
|
|
- LOGE("ftok %s failed, errno: %d\n", UPG_KEY_PATH, errno);
|
|
|
|
|
|
|
+ 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_list_t *l=&uHandle.upg;
|
|
|
|
|
+
|
|
|
|
|
+ if(!s) {
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- return upg_send(UPGRADE_EVT_APP_RUNNING);
|
|
|
|
|
|
|
+ memset(l, 0, sizeof(board_list_t));
|
|
|
|
|
+
|
|
|
|
|
+ max = sizeof(l->info)/sizeof(l->info[0]);
|
|
|
|
|
+ p = strstr(p, tok);
|
|
|
|
|
+ if(!p) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ while(1) {
|
|
|
|
|
+ if((*p)==',' || (*p)=='&') {
|
|
|
|
|
+ tmp[i] = 0;
|
|
|
|
|
+ l->info[n].addr = atoi(tmp);
|
|
|
|
|
+ i = 0; n++;
|
|
|
|
|
+
|
|
|
|
|
+ if((*p)=='&' || n>=max) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ tmp[i++] = *p;
|
|
|
|
|
+ }
|
|
|
|
|
+ p++;
|
|
|
|
|
+ }
|
|
|
|
|
+ l->cnt = n;
|
|
|
|
|
+
|
|
|
|
|
+ return (n>0)?0:-1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+int upg_board_all_get(board_list_t *l)
|
|
|
|
|
+{
|
|
|
|
|
+ int r,max=0,addr,cnt=0;
|
|
|
|
|
+ upg_handle_t *h=&uHandle;
|
|
|
|
|
+ Modbus_Manger *mm=&h->dm->_globalRelaySampManger;
|
|
|
|
|
+ GlobalPowerManger *tmp,*hd=&h->dm->_globalPowerManger;
|
|
|
|
|
+ switch_info_t swinfo;
|
|
|
|
|
+
|
|
|
|
|
+ memset(l, 0, sizeof(board_list_t));
|
|
|
|
|
+ max = sizeof(l->info)/sizeof(l->info[0]);
|
|
|
|
|
+ list_for_each_entry(tmp,&hd->list,list) {
|
|
|
|
|
+ if(tmp->product_saddr>0) {
|
|
|
|
|
+ board_info_t *info=&l->info[l->cnt];
|
|
|
|
|
+ addr = tmp->product_saddr;
|
|
|
|
|
+ r = board_get_info(mm, addr, &swinfo);
|
|
|
|
|
+ if(r==0) {
|
|
|
|
|
+ info->addr = addr;
|
|
|
|
|
+ info->brd_id = swinfo.id[0];
|
|
|
|
|
+ info->channels = swinfo.channels;
|
|
|
|
|
+ strcpy(info->date, swinfo.date);
|
|
|
|
|
+ strcpy(info->ver, swinfo.ver);
|
|
|
|
|
+ sprintf(info->name, "PowerBoard %d", l->cnt+1);
|
|
|
|
|
+
|
|
|
|
|
+ l->cnt++;
|
|
|
|
|
+ if(l->cnt>=max) break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-int upg_start(void)
|
|
|
|
|
|
|
+int upg_board_start(char *path)
|
|
|
{
|
|
{
|
|
|
- return upg_send(UPGRADE_EVT_UPLOAD_FINISH);
|
|
|
|
|
|
|
+ upg_handle_t *h=&uHandle;
|
|
|
|
|
+
|
|
|
|
|
+ if(h->arg.flag==1) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ strcpy(h->arg.path,path);
|
|
|
|
|
+ h->arg.flag = 1;
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|