소스 검색

1、添加升级文件格式检查
2、添加ws刷新

guohui 1 년 전
부모
커밋
7629a8694e
11개의 변경된 파일과 445개의 추가작업 그리고 22개의 파일을 삭제
  1. 3 2
      pro/CMakeLists.txt
  2. 13 3
      pro/src/appweb_handle.c
  3. 50 13
      pro/src/json_handle.c
  4. 2 1
      pro/src/json_handle.h
  5. 192 0
      pro/src/md5.c
  6. 68 0
      pro/src/md5.h
  7. 9 0
      pro/src/paras.c
  8. 96 2
      pro/src/upg.c
  9. 10 0
      pro/src/upg.h
  10. 1 1
      pro/src/websocket_handle.c
  11. 1 0
      pro/src/xlist.c

+ 3 - 2
pro/CMakeLists.txt

@@ -66,8 +66,8 @@ set(PDU_SRC_LIST
 	${PROJECT_SOURCE_DIR}/ini/dictionary.c
 	${PROJECT_SOURCE_DIR}/ini/iniparser.c
 
-        ${PROJECT_SOURCE_DIR}/qrcode/qrcode.c
-        ${PROJECT_SOURCE_DIR}/qrcode/qrc.c
+    ${PROJECT_SOURCE_DIR}/qrcode/qrcode.c
+    ${PROJECT_SOURCE_DIR}/qrcode/qrc.c
 
 	${PROJECT_SOURCE_DIR}/mongoose/mongoose.c
 	${PROJECT_SOURCE_DIR}/src/websocket_handle.c
@@ -97,6 +97,7 @@ set(PDU_SRC_LIST
 	${PROJECT_SOURCE_DIR}/src/lock.c
 	${PROJECT_SOURCE_DIR}/src/mail.c
 	${PROJECT_SOURCE_DIR}/src/mqtt.c
+	${PROJECT_SOURCE_DIR}/src/md5.c
 	${PROJECT_SOURCE_DIR}/src/netswitch.c
 	${PROJECT_SOURCE_DIR}/src/main.c
 

+ 13 - 3
pro/src/appweb_handle.c

@@ -5796,7 +5796,7 @@ static void controlBoardUpgrade(void *conn)
 
     if(strstr(hm->uri.buf, "listCbQuery")) {
         handle_t l=upg_board_all_get();
-        ack_str = board_to_json(l);
+        ack_str = board_to_json(l, 0);
         
         http_reply(conn, 200, ack_str);
         cJSON_free(ack_str);
@@ -5804,7 +5804,7 @@ static void controlBoardUpgrade(void *conn)
 }
 static void controlBoardUpgradeUpload(void *conn)
 {
-    int r = -1 ;
+    int r=-1,code;
     char* ack_str=NULL ;
     mg_stream_t *s=(mg_stream_t*)conn;
     struct mg_http_message *hm=s->ev_data;
@@ -5818,7 +5818,17 @@ static void controlBoardUpgradeUpload(void *conn)
             upg_board_list_set(hm->uri.buf);
 
             printf("_____ board upgrade now ...\n");
-            upg_board_start(path);
+            r = upg_board_file_check(path);
+            if(r==UPG_OK) {
+                upg_board_start(path);
+                code = 200;
+            }
+            else {
+                code = 500;
+            }
+            ack_str = upg_chk_to_json(r);
+            http_reply(conn, code, ack_str);
+            cJSON_free(ack_str);
         }
     }
 }

+ 50 - 13
pro/src/json_handle.c

@@ -1570,35 +1570,72 @@ static int add_item(handle_t l, node_t *node, node_t *xd, void *arg, int *act)
     cJSON_AddItemToArray(array, tmp);
     return 0;
 }
-char* board_to_json(handle_t l)
+char* board_to_json(handle_t l, int is_ws)
 {
     int i;
     cJSON* tmp;
     char* str=NULL;
     char *p,temp[100];
-    GlobalDeviceManager *dm=&__globalDeviceManage;
-    GlobalDeviceInfo *info=&dm->_globalDevInfo;
     
-    // 创建 JSON 对象
-    cJSON* root = cJSON_CreateObject(); 
-    // 添加基本键值对
-    cJSON_AddNumberToObject(root, "code", 200);       
+    cJSON* root = cJSON_CreateObject();
+    cJSON_AddNumberToObject(root, "code", 200);
+           
     cJSON* array = cJSON_CreateArray();
 
     xlist_iterator(l, NULL, add_item, array);
-    cJSON_AddItemToObject(root, "data", array);
 
-    cJSON_AddStringToObject(root, "socketIdx", "PDU-WebSocket");
-    cJSON_AddStringToObject(root, "type", "controlBoardUpgrade");
-    cJSON_AddStringToObject(root, "message", "操作成功");
-    cJSON_AddBoolToObject(root, "success",true);
-    
+    if(is_ws) {
+        cJSON* data = cJSON_CreateObject();
+        cJSON_AddItemToObject(data, "data", array);
+
+        cJSON_AddItemToObject(root, "data", data);
+
+        cJSON_AddStringToObject(root, "socketIdx", "PDU-WebSocket");
+        cJSON_AddStringToObject(root, "type", "controlBoardUpgrade");
+        cJSON_AddStringToObject(root, "message", "操作成功");
+        cJSON_AddBoolToObject(root, "success",true);
+    }
+    else {
+        cJSON_AddItemToObject(root, "data", array);
+    }
     str = cJSON_Print(root);
     
     cJSON_Delete(root);
     return str;
 }
 
+#include "upg.h"
+char *upg_chk_to_json(int r)
+{
+    char* str = NULL;
+    int code=200;
+    cJSON* root = cJSON_CreateObject(); 
+
+    if(r!=UPG_OK) {
+        code = 500;
+    }
+    
+    if(r>UPG_OK) {
+        if(r==UPG_BUSYING) {
+            cJSON_AddStringToObject(root, "msg", "upgrading now"); 
+        }
+        else if(r==UPG_HDR_FAIL || r==UPG_MD5_FAIL) {
+            cJSON_AddStringToObject(root, "msg", "invalid upgrade file"); 
+        }
+    }
+    else if(r<0) {
+        cJSON_AddStringToObject(root, "msg", "failed");
+    }
+    else {
+        cJSON_AddStringToObject(root, "msg", "ok");
+    }
+    
+    cJSON_AddNumberToObject(root, "code", code);       
+    str = cJSON_Print(root);
+    cJSON_Delete(root);
+    return str;
+}
+
 
 
 char* vendor_info_to_json(GlobalDeviceInfo *dev)

+ 2 - 1
pro/src/json_handle.h

@@ -653,6 +653,7 @@ char* over_all_breaker_chn_info_to_json(_OverBreakerChnInfo* _over_all_breaker_b
 char* over_all_breaker_switch_info_to_json(_OverBreakerSwitchInfo* _over_all_breaker_switch_info,int nWSType);
 char *breaker_status_ack_to_json(GlobalDeviceManager *gm,int slave);
 char* upgrade_to_json(void);
-char* board_to_json(handle_t l);
+char* board_to_json(handle_t l, int is_ws);
+char *upg_chk_to_json(int r);
 #endif
 

+ 192 - 0
pro/src/md5.c

@@ -0,0 +1,192 @@
+#include <string.h>
+#include "md5.h"  
+  
+uint8_t PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  
+  
+void md5_init(md5_ctx_t *ctx)
+{  
+    ctx->count[0] = 0;
+    ctx->count[1] = 0;
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+}  
+void md5_update(md5_ctx_t* ctx, uint8_t *input,uint32_t inputlen)
+{  
+    uint32_t i = 0,index = 0,partlen = 0;  
+    index = (ctx->count[0] >> 3) & 0x3F;
+    partlen = 64 - index;  
+    ctx->count[0] += inputlen << 3;
+    if(ctx->count[0] < (inputlen << 3))
+        ctx->count[1]++;
+    ctx->count[1] += inputlen >> 29;
+  
+    if(inputlen >= partlen)  
+    {  
+        memcpy(&ctx->buffer[index],input,partlen);
+        md5_transform(ctx->state, ctx->buffer);
+        for(i = partlen;i+64 <= inputlen;i+=64)  
+            md5_transform(ctx->state,&input[i]);
+        index = 0;          
+    }    
+    else  
+    {  
+        i = 0;  
+    }  
+    memcpy(&ctx->buffer[index],&input[i],inputlen-i);
+}  
+void md5_final(md5_ctx_t* ctx,uint8_t digest[16])
+{  
+    uint32_t index = 0,padlen = 0;  
+    uint8_t bits[8];  
+    index = (ctx->count[0] >> 3) & 0x3F;
+    padlen = (index < 56)?(56-index):(120-index);  
+    md5_encode(bits, ctx->count,8);
+    md5_update(ctx,PADDING,padlen);
+    md5_update(ctx,bits,8);
+    md5_encode(digest, ctx->state,16);
+}  
+void md5_encode(uint8_t *output,uint32_t *input,uint32_t len)  
+{  
+    uint32_t i = 0,j = 0;  
+    while(j < len)  
+    {  
+        output[j] = input[i] & 0xFF;    
+        output[j+1] = (input[i] >> 8) & 0xFF;  
+        output[j+2] = (input[i] >> 16) & 0xFF;  
+        output[j+3] = (input[i] >> 24) & 0xFF;  
+        i++;  
+        j+=4;  
+    }  
+}  
+void md5_decode(uint32_t *output,uint8_t *input,uint32_t len)  
+{  
+    uint32_t i = 0,j = 0;  
+    while(j < len)  
+    {  
+        output[i] = (input[j]) |  
+            (input[j+1] << 8) |  
+            (input[j+2] << 16) |  
+            (input[j+3] << 24);  
+        i++;  
+        j+=4;   
+    }  
+}  
+void md5_transform(uint32_t state[4],uint8_t block[64])  
+{  
+    uint32_t a = state[0];  
+    uint32_t b = state[1];  
+    uint32_t c = state[2];  
+    uint32_t d = state[3];  
+    uint32_t x[64];  
+    md5_decode(x,block,64);  
+    FF(a, b, c, d, x[ 0], 7, 0xd76aa478);   
+    FF(d, a, b, c, x[ 1], 12, 0xe8c7b756);   
+    FF(c, d, a, b, x[ 2], 17, 0x242070db);   
+    FF(b, c, d, a, x[ 3], 22, 0xc1bdceee);   
+    FF(a, b, c, d, x[ 4], 7, 0xf57c0faf);   
+    FF(d, a, b, c, x[ 5], 12, 0x4787c62a);   
+    FF(c, d, a, b, x[ 6], 17, 0xa8304613);   
+    FF(b, c, d, a, x[ 7], 22, 0xfd469501);   
+    FF(a, b, c, d, x[ 8], 7, 0x698098d8);   
+    FF(d, a, b, c, x[ 9], 12, 0x8b44f7af);   
+    FF(c, d, a, b, x[10], 17, 0xffff5bb1);   
+    FF(b, c, d, a, x[11], 22, 0x895cd7be);   
+    FF(a, b, c, d, x[12], 7, 0x6b901122);   
+    FF(d, a, b, c, x[13], 12, 0xfd987193);   
+    FF(c, d, a, b, x[14], 17, 0xa679438e);   
+    FF(b, c, d, a, x[15], 22, 0x49b40821);   
+  
+      
+    GG(a, b, c, d, x[ 1], 5, 0xf61e2562);   
+    GG(d, a, b, c, x[ 6], 9, 0xc040b340);   
+    GG(c, d, a, b, x[11], 14, 0x265e5a51);   
+    GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);   
+    GG(a, b, c, d, x[ 5], 5, 0xd62f105d);   
+    GG(d, a, b, c, x[10], 9,  0x2441453);   
+    GG(c, d, a, b, x[15], 14, 0xd8a1e681);   
+    GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);   
+    GG(a, b, c, d, x[ 9], 5, 0x21e1cde6);   
+    GG(d, a, b, c, x[14], 9, 0xc33707d6);   
+    GG(c, d, a, b, x[ 3], 14, 0xf4d50d87);   
+    GG(b, c, d, a, x[ 8], 20, 0x455a14ed);   
+    GG(a, b, c, d, x[13], 5, 0xa9e3e905);   
+    GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8);   
+    GG(c, d, a, b, x[ 7], 14, 0x676f02d9);   
+    GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);   
+  
+      
+    HH(a, b, c, d, x[ 5], 4, 0xfffa3942);   
+    HH(d, a, b, c, x[ 8], 11, 0x8771f681);   
+    HH(c, d, a, b, x[11], 16, 0x6d9d6122);   
+    HH(b, c, d, a, x[14], 23, 0xfde5380c);   
+    HH(a, b, c, d, x[ 1], 4, 0xa4beea44);   
+    HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9);   
+    HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60);   
+    HH(b, c, d, a, x[10], 23, 0xbebfbc70);   
+    HH(a, b, c, d, x[13], 4, 0x289b7ec6);   
+    HH(d, a, b, c, x[ 0], 11, 0xeaa127fa);   
+    HH(c, d, a, b, x[ 3], 16, 0xd4ef3085);   
+    HH(b, c, d, a, x[ 6], 23,  0x4881d05);   
+    HH(a, b, c, d, x[ 9], 4, 0xd9d4d039);   
+    HH(d, a, b, c, x[12], 11, 0xe6db99e5);   
+    HH(c, d, a, b, x[15], 16, 0x1fa27cf8);   
+    HH(b, c, d, a, x[ 2], 23, 0xc4ac5665);   
+  
+      
+    II(a, b, c, d, x[ 0], 6, 0xf4292244);   
+    II(d, a, b, c, x[ 7], 10, 0x432aff97);   
+    II(c, d, a, b, x[14], 15, 0xab9423a7);   
+    II(b, c, d, a, x[ 5], 21, 0xfc93a039);   
+    II(a, b, c, d, x[12], 6, 0x655b59c3);   
+    II(d, a, b, c, x[ 3], 10, 0x8f0ccc92);   
+    II(c, d, a, b, x[10], 15, 0xffeff47d);   
+    II(b, c, d, a, x[ 1], 21, 0x85845dd1);   
+    II(a, b, c, d, x[ 8], 6, 0x6fa87e4f);   
+    II(d, a, b, c, x[15], 10, 0xfe2ce6e0);   
+    II(c, d, a, b, x[ 6], 15, 0xa3014314);   
+    II(b, c, d, a, x[13], 21, 0x4e0811a1);   
+    II(a, b, c, d, x[ 4], 6, 0xf7537e82);   
+    II(d, a, b, c, x[11], 10, 0xbd3af235);   
+    II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);   
+    II(b, c, d, a, x[ 9], 21, 0xeb86d391);   
+    state[0] += a;  
+    state[1] += b;  
+    state[2] += c;  
+    state[3] += d;  
+}
+
+#define CHAR(b) (b<=9)?(b+0x30):(b-10+0x61);
+static void byte2char(char *chr, uint8_t b)
+{
+    char h,l;
+    
+    l = b&0x0f;
+    h = (b>>4)&0x0f;
+    
+    chr[0] = CHAR(h);
+    chr[1] = CHAR(l);
+}
+
+int md5_calc(void *p1, int len1, void *p2, int len2, char *md5)
+{
+    int i;
+    uint8_t tmp[16];
+    md5_ctx_t ctx;
+    
+    md5_init(&ctx);
+    md5_update(&ctx, (uint8_t*)p1, len1);
+    md5_update(&ctx, (uint8_t*)p2, len2);
+    md5_final(&ctx, tmp);
+    
+    for (i=0; i<16; i++) {
+        byte2char(&md5[i*2], tmp[i]);
+    }
+    
+    return 0;
+}
+

+ 68 - 0
pro/src/md5.h

@@ -0,0 +1,68 @@
+#ifndef MD5_H  
+#define MD5_H  
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct
+{
+	uint32_t count[2];
+	uint32_t state[4];
+	uint8_t buffer[64];
+}md5_ctx_t;
+
+
+#define F(x,y,z) ((x & y) | (~x & z))  
+#define G(x,y,z) ((x & z) | (y & ~z))  
+#define H(x,y,z) (x^y^z)  
+#define I(x,y,z) (y ^ (x | ~z))  
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))  
+
+#define FF(a,b,c,d,x,s,ac) \
+	{ \
+		a += F(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define GG(a,b,c,d,x,s,ac) \
+	{ \
+		a += G(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define HH(a,b,c,d,x,s,ac) \
+	{ \
+		a += H(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define II(a,b,c,d,x,s,ac) \
+	{ \
+		a += I(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+void md5_init(md5_ctx_t* context);
+void md5_update(md5_ctx_t* context, uint8_t* input, uint32_t inputlen);
+void md5_final(md5_ctx_t* context, uint8_t digest[16]);
+void md5_transform(uint32_t state[4], uint8_t block[64]);
+void md5_encode(uint8_t* output, uint32_t* input, uint32_t len);
+void md5_decode(uint32_t* output, uint8_t* input, uint32_t len);
+
+int md5_calc(void* p1, int len1, void* p2, int len2, char* md5);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif  

+ 9 - 0
pro/src/paras.c

@@ -461,6 +461,7 @@ static int proc_prod(dictionary *dic, int op, ProductInfo_t *prod)
         }
     }
 
+    r = 0;
     if(op==PARAS_READ) {
         prod->count = 0;
         prod->status[0] = 0;
@@ -551,6 +552,7 @@ static int proc_modbus(dictionary *dic, int op, ModbusInfo_t *mb)
         }
     }
 
+    r = 0;
     if(op==PARAS_READ) {
         r = proc_modbus(dic, PARAS_CHECK, mb);
     }
@@ -668,6 +670,7 @@ static int proc_ptotal(dictionary *dic, int op, PowerTotal_t *ptotal)
         }
     }
 
+    r = 0;
     if(op==PARAS_READ) {
         r = proc_ptotal(dic, PARAS_CHECK, ptotal);
     }
@@ -812,6 +815,7 @@ static int proc_webcfg(dictionary *dic, int op, WebcfgInfo_t *webcfg)
         }
     }
 
+    r = 0;
     if(op==PARAS_READ) {
         r = proc_webcfg(dic, PARAS_CHECK, webcfg);
     }
@@ -883,6 +887,11 @@ static int proc_misc(dictionary *dic, int op, MiscInfo_t *misc)
         }
     }
 
+    r = 0;
+    if(op==PARAS_READ) {
+        r = proc_misc(dic, PARAS_CHECK, misc);
+    }
+
     return r;
 }
 

+ 96 - 2
pro/src/upg.c

@@ -236,7 +236,7 @@ static int board_proc(upg_handle_t *h, int quit)
                     break;
                 }
                 LOGE("___ board upgrade failed, retry %d\n", i+1);
-                //board_send(mm, i, fbuf.buf, fbuf.dlen);
+                board_send(mm, i, fbuf.buf, fbuf.dlen);
             }
 
             if(r) {
@@ -248,12 +248,15 @@ static int board_proc(upg_handle_t *h, int quit)
                 ok++;
             }
             board_info_set(tmp);
-
             xlist_remove(l, 0);
         }
     }
     free(fbuf.buf);
 
+    if(ok>0) {
+        exit(0);        //restart app
+    }
+
     return 0;
 }
 static int board_scan(void)
@@ -466,6 +469,7 @@ int upg_board_all_update(void)
     return 0;
 }
 
+static int fw_check(char *path);
 int upg_board_start(char *path)
 {
     upg_handle_t *h=&uHandle;
@@ -473,9 +477,99 @@ int upg_board_start(char *path)
     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;
+    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);
+        return UPG_HDR_FAIL;
+    }
+
+    if(md5_check(&fb)) {
+        return UPG_MD5_FAIL;
+    }
+    free(fb.buf);
+
+    return UPG_OK;
+}
+
+int upg_host_file_check(char *path)
+{
+    return 0;
+}

+ 10 - 0
pro/src/upg.h

@@ -5,6 +5,14 @@
 #include "common.h"
 #include "xlist.h"
 
+enum {
+    UPG_OK=0,
+    UPG_BUSYING,
+    UPG_HDR_FAIL,
+    UPG_MD5_FAIL,
+};
+
+
 int upg_init(void);
 int upg_host_send(int evt);
 
@@ -13,5 +21,7 @@ handle_t upg_board_all_get(void);
 int upg_board_all_update(void);
 int upg_board_start(char *path);
 
+int upg_host_file_check(char *path);
+int upg_board_file_check(char *path);
 #endif
 

+ 1 - 1
pro/src/websocket_handle.c

@@ -221,7 +221,7 @@ static int ws_upg_update(ws_handle_t *h)
 {
     handle_t l=upg_board_all_get();
 
-    char* json = board_to_json(l);
+    char* json = board_to_json(l, 1);
     ws_send_data(h, json, strlen(json));
     cJSON_free(json);
 

+ 1 - 0
pro/src/xlist.c

@@ -830,6 +830,7 @@ int xlist_iterator(handle_t l, node_t *node, list_callback_t callback, void *arg
     xd = dl->head;
     while (xd) {
         if (callback) {
+            act = LIST_ACT_NONE;
             r = callback(hl, node, &xd->data, arg, &act);
             if(act==LIST_ACT_STOP) {
                 break;