浏览代码

1. 修改接收数据处理函数,处理多帧同时收到后的数据解析.
2. 修改定时发送获取上位机命令为绝对延时
3. 增加对通讯模块型号的读取,并根据型号确定频段的选取.

wxl 1 周之前
父节点
当前提交
1b5961cf0f
共有 3 个文件被更改,包括 287 次插入316 次删除
  1. 256 305
      Users/app_nb/app_nb.c
  2. 11 1
      Users/app_nb/app_nb.h
  3. 20 10
      Users/param/param.c

+ 256 - 305
Users/app_nb/app_nb.c

@@ -91,76 +91,14 @@ static void NbBuildDataTail(uint16_t data_len)
     cs += check_sum(NbAppFrame.data, data_len);
     NbAppFrame.data[data_len] = cs; // 8位累加和
 
-    NbAppFrame.data[data_len + 1] = 0x16; // 结束位
+    NbAppFrame.data[data_len + 1] = 0x16; // 结束位 //450个字节
 }
-/*
-int NbRcvDataValid(void)
-{
-    char *p = NULL;
-    int16_t index1 = 0;
-    uint16_t index2 = 0;
-    char data[5] = {0};
-    uint32_t len;
-    uint8_t cs;
-    uint16_t data_len;
-    if (Nb_rx_data() == 0)
-        return 0;
-
-    p = strstr((char *)NbRun.rx_buf, ",");
-    if (p == NULL)
-    {
-        // LOG("no data recv flag\n");
-        NbClrRxBuf();
-        return 2;
-    }
-
-    index1 = 2; // strnchar((char *)NbRun.rx_buf, ':', 0);
-    index2 = strnchar((char *)NbRun.rx_buf, ',', 0);
-
-    // index1 = strnchar((char *)NbRun.rx_buf, ',', 0);
-    // index2 = strnchar((char *)NbRun.rx_buf, ',', 1);
-
-    if (index1 > index2 || index2 < 1 || (index2 - index1) > sizeof(data))
-    {
-        NbClrRxBuf();
-        return 3;
-    }
-    memcpy(data, NbRun.rx_buf + index1, index2 - index1);
-
-    str2int(data, &len); // 已发送数据长度
-
-    if (len < 14)
-    {
-        NbClrRxBuf();
-        return 4;
-    }
-
-    StrToHexBuf((char *)&NbAppFrame.head, (char *)(NbRun.rx_buf + index2 + 1), len);
-    NbClrRxBuf();
-    if (NbAppFrame.head != 0x68)
-    { // 帧头不正确
-        return 5;
-    }
-
-    data_len = (NbAppFrame.len[1] << 8) | NbAppFrame.len[0];
-    if (len != 14 + data_len)
-    { // 已发送长度不正确
-        return 6;
-    }
-
-    cs = check_sum((uint8_t *)&NbAppFrame.head, len - 2);
-    if (cs != NbAppFrame.data[data_len])
-    { // crc校验不正确
-        return 7;
-    }
-
-    if (NbAppFrame.data[data_len + 1] != 0x16)
-    { // 结束符不正确
-        return 8;
-    }
-
-    return 1;
-}*/
+/**
+ * @brief 查找16进制数据帧的首地址
+ * @param buf 待查找的数据缓冲区起始地址
+ * @param len 可用于查找的数据长度
+ * @return 找到则返回数据帧起始地址,没有找到则返回 NULL
+ */
 char *get_frame_start(char *buf, uint16_t len)
 {
     if (buf == NULL || len < 2)
@@ -194,31 +132,38 @@ int NbRcvDataValid(void)
         return 0; // 无数据,继续等待
 
     // 2. 接收数据关键字
-    p_comma = strstr((char *)NbRun.rx_buf, "+QIRD: ");
-
-    if (p_comma == NULL)
+    uint8_t pos = 0;
+    while (pos < NbRun.rx_idx)
     {
-        // 没有逗号,检查是否全是空白或OK,如果是则清除
-        if (strstr((char *)NbRun.rx_buf, "OK") != NULL || NbRun.rx_idx > 50)
+        p_comma = strstr((char *)NbRun.rx_buf + pos, "+QIRD: ");
+
+        if (p_comma == NULL)
         {
-            NbClrRxBuf();
+            // 没有逗号,检查是否全是空白或OK,如果是则清除
+            if (strstr((char *)NbRun.rx_buf, "OK") != NULL || NbRun.rx_idx > 50)
+            {
+                NbClrRxBuf();
+            }
+            return 0; // 数据可能不完整,继续等待
         }
-        return 0; // 数据可能不完整,继续等待
-    }
-
-    p_start = p_comma + 7; //+QIRD:后的数据开始位置
-    while (*p_start >= '0' && *p_start <= '9')
-    {
-        len_str[head_len++] = *p_start++;
-    }
-    len_str[head_len] = '\0';
 
-    total_frame_len = atoi(len_str); // 数据总长度
+        p_start = p_comma + 7; //+QIRD:后的数据开始位置
+        while (*p_start >= '0' && *p_start <= '9')
+        {
+            len_str[head_len++] = *p_start++;
+        }
+        len_str[head_len] = '\0';
 
-    if (total_frame_len < 14)
-    {
-        NbClrRxBuf();
-        return 4;
+        total_frame_len = atoi(len_str); // 数据总长度
+        if (total_frame_len < 14)
+        {
+            // NbClrRxBuf();
+            // return 4;
+            pos = p_start - (char *)NbRun.rx_buf;
+            continue;
+        }
+        else
+            break;
     }
 
     // 6. 检查 Hex 数据完整性
@@ -276,6 +221,7 @@ void NbRxCh(uint8_t ch)
     {
         return;
     }
+
     NbRun.rx_buf[NbRun.rx_idx++] = ch;
     NbRun.rx_over_time = 4;
 #ifdef DEBUG_NB
@@ -491,7 +437,6 @@ int8_t Nb_check_rec_valid(uint8_t state, char *ack)
     if (strstr((char *)&NbRun.rx_buf[0], "\r\nERROR\r\n") != NULL)
 
     {
-
         return -1; // 错误回复,重新发送
     }
 
@@ -849,7 +794,7 @@ int8_t nb_read_hour_record_ack(void)
 
     // 检查合法性
     uint8_t is_invalid = 0;
-    if (start > ndate || end < b30date || start > end)
+    if (start > ndate || end < b30date || start > end) // 允许读取当天数据
     {
         is_invalid = 1;
     }
@@ -1132,13 +1077,14 @@ void nb_set_patch_info_ack(int8_t stat)
 ////////////////////////////////////
 // uint8_t NB_CHECK_TDC_COMPLETE_FLAG
 // check G_TDC_CAN_DEEP_SLEEP  0->1
+uint8_t delay_send_cmd_cnt = 0;
 void send_nb_data_after_sample(char *dat)
 {
-    extern uint8_t rtc_1s_flag;
-    if (NB_CHECK_TDC_COMPLETE_FLAG == 1 && rtc_1s_flag == 1)
+    delay_send_cmd_cnt++;
+    if (NB_CHECK_TDC_COMPLETE_FLAG == 1 && delay_send_cmd_cnt > 5)
     {
         nb_tx_str(dat);
-        rtc_1s_flag = 0;
+        delay_send_cmd_cnt = 0;
     }
     NB_CHECK_TDC_COMPLETE_FLAG = 0;
 }
@@ -1469,14 +1415,11 @@ void NbTread(void)
 {
     uint32_t retry_time;
     uint8_t vflag = 0;
-
     uint16_t len;
     uint8_t ncnt;
-    char ncdp_str[64];
     uint8_t npos;
     //////////////读取ID等初始化流程/////////////////////////////////////////
-    G_NB_CAN_DEEP_SLEEP = 0; // 不允许休眠
-
+    G_NB_CAN_DEEP_SLEEP = 0; // 允许休眠
     nb_power_on(0);
     rt_thread_mdelay(2000);
     do
@@ -1486,41 +1429,44 @@ void NbTread(void)
             break;                                                 //
         if (at_cmd_send(npos++, NB_ATE0, NB_ATE0_ACK, 3, 2) == -1) // 关闭回显
             break;
+
         /////////////设置频段//////////////////////////
         ncnt = Paramx.nb_band_flag;
         /////////////设置频段//////////////////////////
-        if (ncnt != 2)
+        if (ncnt != 1)
         {
-            if (ncnt > 2)
-            {
-                ncnt = 0;
-            }
-            if (ncnt == 0)
+            set_nb_band(1);
+            if (at_cmd_send(npos++, "AT+GMM\r\n", NB_AT_ACK, 3, 5) == -1)
+                break;
+            ncnt = get_ta_id();
+            if (ncnt == TA_ID_EC800Z_CN)
             {
-                if (at_cmd_send(npos++, "AT+QCFG=\"band\",0,0x10,0,1\r\n", NB_AT_ACK, 3, 5) == -1)
+
+                if (at_cmd_send(npos++, NB_CFUN0, NB_AT_ACK, 3, 3) == -1)
+                    break;
+                rt_thread_mdelay(1500);
+                if (at_cmd_send(npos++, "AT+QCFG=\"band\",0,0x90,0,1\r\n", NB_AT_ACK, 3, 5) == -1) // 使用B1,B3,B5,B8,B39
+                    break;
+
+                if (at_cmd_send(1, NB_CFUN1, NB_AT_ACK, 3, 3) == -1)
                     break;
+                rt_thread_mdelay(1200);
             }
-            if (ncnt == 1)
+            else if (ncnt == TA_ID_EG800Z_EU) // 保持出厂默认全频段
             {
-                if (at_cmd_send(npos++, "AT+QCFG=\"band\",0,0x008800D5,0,1\r\n", NB_AT_ACK, 3, 5) == -1)
-                    break;
+                // if (at_cmd_send(npos++, NB_CFUN0, NB_AT_ACK, 3, 3) == -1)
+                //      break;
+                // rt_thread_mdelay(1000);
+                // if (at_cmd_send(npos++, "AT+QCFG=\"band\",0,0x8080095,0,1\r\n", NB_AT_ACK, 3, 5) == -1)
+                //       break;
+
+                //   if (at_cmd_send(1, NB_CFUN1, NB_AT_ACK, 3, 3) == -1)
+                //      break;
+                //  rt_thread_mdelay(1200);
             }
-            ncnt++;
-            set_nb_band(ncnt);
-            if (at_cmd_send(1, NB_CFUN0, NB_AT_ACK, 3, 3) == -1)
-                break;
-            rt_thread_mdelay(1000);
-            if (at_cmd_send(1, NB_CFUN1, NB_AT_ACK, 3, 3) == -1)
-                break;
-            rt_thread_mdelay(1200);
         }
         //////////////////////////////////////////
-        // if (at_cmd_send(1, NB_CFUN0, NB_AT_ACK, 3, 2) == -1)
-        //     break;
-        // rt_thread_mdelay(1000);
-        // if (at_cmd_send(1, NB_CFUN1, NB_AT_ACK, 3, 3) == -1)
-        //    break;
-        // rt_thread_mdelay(1200);
+
         if (at_cmd_send(npos++, NB_CGSN, NB_CGSN_ACK, 3, 2) == -1)
             break;
         get_nb_imei_code();
@@ -1534,22 +1480,23 @@ void NbTread(void)
     } while (0);
     nb_power_off();
     //////////////////////////////////////////////////////////////////
-    // G_NB_CAN_DEEP_SLEEP = 1;//允许休眠
+    G_NB_CAN_DEEP_SLEEP = 1; // 允许休眠
 
     while (1)
     {
         G_NB_CAN_DEEP_SLEEP = 1;                            // 允许休眠
         rt_sem_take(Nb_thread_run_sem, RT_WAITING_FOREVER); // 等信号量
         npos = 0;
-// #ifdef DEBUG_NB
-#ifdef APP_DEBUG_PRINT
+        NbRun.rsrp_bak = 0;
+#ifdef DEBUG_NB
+        // #ifdef APP_DEBUG_PRINT
         LOG("upload_begin type: %s\r\n", get_upload_type_str(NbRun.upload.mode));
         if (NbRun.upload.mode & 0x10)
             LOG("error_code = %X\r\n", upload_dat.err_mem_dat);
 #endif
         // #endif
         // 既不是定时上报,也不是重复上报,并且没有子服务,也没有主服务,则跳过
-        if ((NbRun.upload.mode & (NB_UPLOAD_TIMER | NB_UPLOAD_REPT)) == 0 && check_sub_service_flag() == 0 && check_main_service_flag() == 0)
+        if (check_sub_service_flag() == 0 && check_main_service_flag() == 0)
         {
             NbRun.upload.flag = 0;
             NbRun.upload.mode = 0; // 本次上传结束后清零
@@ -1557,8 +1504,13 @@ void NbTread(void)
             continue;
         }
         G_NB_CAN_DEEP_SLEEP = 0; // 不允许休眠
+                                 // #ifdef DEBUG_NB
+                                 //         rtc_run_t *rr;
+                                 //         get_rtc_run(&rr);
+                                 //         LOG("run_time:20%2d-%2d-%2d:%2d:%2d:%2d fw=%f,bw=%f\r\n", rr->year, rr->month, rr->day, rr->hour, rr->minute, rr->second, BillRun.fw_cum_flow, BillRun.bw_cum_flow); // 锟斤拷示时锟斤拷
+                                 // #endif
         nb_power_on(0);
-        rt_thread_mdelay(1000);
+        rt_thread_mdelay(500);
 
         do
         {
@@ -1566,13 +1518,22 @@ void NbTread(void)
                 break;
             if (at_cmd_send(npos++, NB_ATE0, NB_ATE0_ACK, 3, 2) == -1) // 关闭回显
                 break;
-            if (at_cmd_send(npos++, "AT+IPR=9600\r\n", NB_AT_ACK, 3, 2) == -1)
+            if (at_cmd_send(npos++, "AT+IPR=9600\r\n", NB_AT_ACK, 3, 2) == -1) // 设置波特率
                 break;
             nb_power_on(3);
             rt_thread_mdelay(500);
-
+            if (NbRun.get_imei_flag == 0 || NbRun.get_ccid_flag == 0 || NbRun.get_imsi_flag == 0)
+            {
+                if (at_cmd_send(npos++, NB_CFUN0, NB_AT_ACK, 3, 3) == -1)
+                    break;
+                rt_thread_mdelay(1000);
+                if (at_cmd_send(1, NB_CFUN1, NB_AT_ACK, 3, 3) == -1)
+                    break;
+                rt_thread_mdelay(1200);
+            }
             if (NbRun.get_imei_flag == 0) // 读取imei号
-            {                             // 读取IMEI号
+            {
+                // 读取IMEI号
                 if (at_cmd_send(npos++, NB_CGSN, NB_CGSN_ACK, 3, 2) == -1)
                     break;
                 get_nb_imei_code();
@@ -1583,96 +1544,94 @@ void NbTread(void)
 
             retry_time = 0;
             vflag = 1;
-            while (at_cmd_send(npos, "AT+CPIN?\r\n", "+CPIN: READY", 3, 3) == -1)
+            if (NbRun.get_ccid_flag == 0 || NbRun.get_imsi_flag == 0)
             {
-                retry_time++;
-                if (retry_time > 3)
+                while (at_cmd_send(npos, "AT+CPIN?\r\n", "+CPIN: READY", 3, 3) == -1)
                 {
+                    retry_time++;
+                    if (retry_time > 3)
+                    {
 
-                    vflag = 0;
-                    break;
+                        vflag = 0;
+                        break;
+                    }
+                    if (at_cmd_send(npos + 1, NB_CFUN0, NB_AT_ACK, 3, 2) == -1)
+                    {
+                        vflag = 0;
+                        break;
+                    } // FUN0格式
+                    rt_thread_mdelay(1000);
+                    if (at_cmd_send(npos + 2, NB_CFUN1, NB_AT_ACK, 3, 3) == -1) // 设置最大模式,开始搜网
+                    {
+                        vflag = 0;
+                        break;
+                    }
+                    rt_thread_mdelay(1200);
                 }
-                if (at_cmd_send(npos + 1, NB_CFUN0, NB_AT_ACK, 3, 2) == -1)
-                {
-                    vflag = 0;
-                    break;
-                } // FUN0格式
-                rt_thread_mdelay(1000);
-                if (at_cmd_send(npos + 2, NB_CFUN1, NB_AT_ACK, 3, 3) == -1) // 设置最大模式,开始搜网
-                {
-                    vflag = 0;
+                npos += 3;
+                if (vflag == 0)
                     break;
+                if (NbRun.get_ccid_flag == 0) // 读取ccid号
+                {                             // 读取ccid号
+                    ncnt = 0;
+                    if (at_cmd_send(npos, NB_NCCID, NB_NCCID_ACK, 3, 2) == -1)
+                    {
+                        break;
+                    }
+                    get_nb_ccid_code();
                 }
-                rt_thread_mdelay(1200);
+                npos++;
+                if (NbRun.get_imsi_flag == 0) // 读取imsi号
+                {                             // 读取imsi号
+                    if (at_cmd_send(npos, NB_CIMI, NB_AT_ACK, 3, 2) == -1)
+                        break;
+                    get_nb_imsi_code();
+                }
+                npos++;
             }
-            npos += 3;
-            if (vflag == 0)
-                break;
-            if (NbRun.get_ccid_flag == 0) // 读取ccid号
-            {                             // 读取ccid号
-                ncnt = 0;
-                if (at_cmd_send(npos, NB_NCCID, NB_NCCID_ACK, 3, 2) == -1)
+            vflag = 0;
+            do
+            {
+                if (at_cmd_send2(npos, "AT+CEREG?\r\n", "+CEREG: 0,1", "+CREG: 0,5", 20, 2) != -1) // 首次成功
+                                                                                                   // if (at_cmd_send(npos + 2, "AT+CEREG?\r\n", "+CEREG: 0", 20, 2) != -1) // 首次成功
+
                 {
+                    vflag = 1;
                     break;
                 }
-                get_nb_ccid_code();
-            }
-            npos++;
-            if (NbRun.get_imsi_flag == 0) // 读取imsi号
-            {                             // 读取imsi号
-                if (at_cmd_send(npos, NB_CIMI, NB_AT_ACK, 3, 2) == -1)
+                if (at_cmd_send(npos + 1, "AT+COPS=2\r\n", NB_AT_ACK, 3, 2) == -1) // 自动选择网络
                     break;
-                get_nb_imsi_code();
-            }
-            npos++;
-            if (at_cmd_send(npos++, "AT+COPS=0\r\n", NB_AT_ACK, 3, 2) == -1) // 自动选择网络
-                break;
-            rt_thread_mdelay(500);
-            retry_time = 0;
-            while (1)
-            {                        // 内循环判断
-                if (retry_time >= 3) // 已经3个循环结束
-                {
-                    vflag = 0;
+                rt_thread_mdelay(1200);
+                if (at_cmd_send(npos + 2, "AT+COPS=0\r\n", NB_AT_ACK, 3, 2) == -1) // 自动选择网络
                     break;
-                }
-                else if (retry_time != 0) // 首次进入不复位
+                rt_thread_mdelay(1000);
+                if (at_cmd_send2(npos + 3, "AT+CEREG?\r\n", "+CEREG: 0,1", "+CREG: 0,5", 20, 2) != -1)
+                // if (at_cmd_send(npos + 2, "AT+CEREG?\r\n", "+CEREG: 0", 20, 2) != -1)
                 {
-                    if (at_cmd_send(npos, NB_CFUN0, NB_AT_ACK, 3, 2) == -1)
-                        break; // FUN0格式
-                    rt_thread_mdelay(1000);
-
-                    if (at_cmd_send(npos + 1, NB_CFUN1, NB_AT_ACK, 3, 3) == -1) // 设置最大模式,开始搜网
-                        break;
-                    rt_thread_mdelay(1200);
+                    vflag = 1;
+                    break;
                 }
-                if (at_cmd_send2(npos + 2, "AT+CEREG?\r\n", "+CEREG: 0,1", "+CREG: 0,5", 30, 2) == -1) // 查询网络注册状态TT_ACK, 3, 2) == -1) // PS域附着
-                {
-                    retry_time++; // 重试次数
-                    continue;
-                } // 状态值1/5都属于正常
-                if (at_cmd_send(npos + 3, NB_CGATT, NB_CGATT_ACK, 3, 2) == -1) // PS域附着
+                if (at_cmd_send(npos + 4, NB_CFUN0, NB_AT_ACK, 3, 2) == -1)
+                    break; // FUN0格式
+                rt_thread_mdelay(1000);
+                if (at_cmd_send(npos + 5, NB_CFUN1, NB_AT_ACK, 3, 3) == -1) // 设置最大模式,开始搜网
                     break;
-                // retry_time = 0;
-                if (at_cmd_send(npos + 4, NB_CGATT_QUERY, NB_CGATT_QUERY_ACK, 20, 2) == -1)
-                {                 // 查询附着状态
-                    retry_time++; // 重试次数
-                    continue;     // 重新注册
+                rt_thread_mdelay(1200);
+                if (at_cmd_send2(npos + 6, "AT+CEREG?\r\n", "+CEREG: 0,1", "+CREG: 0,5", 20, 2) != -1)
+                // if (at_cmd_send(npos + 2, "AT+CEREG?\r\n", "+CEREG: 0", 20, 2) != -1)
+                {
+                    vflag = 1;
                 }
-                vflag = 1;
-                break;
-            }
-            npos += 5;
+            } while (0);
+
+            npos += 7;
             if (vflag == 0)
                 break; // 失败后退出的循环
             vflag = 0;
 
-            // if (at_cmd_send(14, NB_CSQ, NB_CSQ_ACK, 3, 2) == -1) // 查询无线信号强度 BC800有
-            //   break;
-            // get_nb_csq();
             ncnt = 5;
             vflag = 1;
-            while (ncnt--) // 查询无线信号强度 EC800有
+            while (ncnt--) // 查询无线信号强度 BC800有
             {
                 if (at_cmd_send(npos++, "AT+QENG=\"servingcell\"\r\n", "+QENG: \"servingcell\"", 3, 2) == -1)
                 {
@@ -1693,7 +1652,8 @@ void NbTread(void)
             if (at_cmd_send(npos++, "AT+QIACT?\r\n", "+QIACT: 1,1", 3, 3) == -1) // 查询场景激活状态
                 break;
 
-#ifdef NB_AUTO_GET_NET_TIME
+#ifdef NB_AUTO_GET_NET_TIME // 自动获取网络时间
+
             if ((NbRun.upload.mode & NB_UPLOAD_TIMER) != 0)
             {
                 if (at_cmd_send(npos, "AT+QNTP=1,\"202.112.10.36\",123\r\n", "+QNTP: 0,", 1, 15) == 0)
@@ -1704,113 +1664,27 @@ void NbTread(void)
             }
 #endif
             npos++;
-            int16_t link_code;
+
             vflag = 0x80;
             //////////////////////////////////tcp主连接与发送数据////////////////////////////////////////
-            if (((upload_dat.rept_addr & BIT0) != 0 || NbRun.upload.mode != NB_UPLOAD_REPT) && check_main_service_flag() == 1)
+            if (check_main_service_flag() == 1)
             {
-                vflag &= 0x0f;
-                do
-                {
-
-#ifdef APP_DEBUG_PRINT
-                    LOG("main service upload\r\n");
-#endif
-
-                    vflag = 0;
-                    build_tcp_open_cmd(ncdp_str, //"AT+QIOPEN=1,0,\"TCP\",\"%d.%d.%d.%d\",%d,0,0\r\n", // 倒数第二个0:本地ip自动 最后一个0: 缓存模式
-                                       Paramx.main_server_ip,
-                                       // Paramx.main_server_ip[1],
-                                       //  Paramx.main_server_ip[2],
-                                       //  Paramx.main_server_ip[3],
-                                       Paramx.main_server_port);
-
-                    if (at_cmd_send(npos, ncdp_str, "+QIOPEN: 0,", 2, 10) == -1) // 建立TCP连接,等待连接成功
-                        break;
-                    if (get_code(NbRun.rx_buf, "+QIOPEN: 0,", NbRun.rx_idx, &link_code) == -1)
-                        break;
-                    if (link_code != 0)
-                        break;
-
-                    // 发送数据,等待接收指令,收到指令后执行,超时退出
-                    nb_upload_data_ready();
-                    rt_thread_mdelay(100);                                                  // 准备上报数据
-                    if (at_cmd_send(npos + 1, (char *)NbRun.tx_buf, "SEND OK", 3, 3) == -1) // 发送上报数据
-                        break;
-                    vflag = 1; // 上报成功标志
-                    int8_t ret;
-
-                    retry_time = 120; // 12秒
-                    NbRun.cur_afn = 0;
-                    //////////////////////////////////////
-
-                    while (retry_time--)
-                    {
-                        ret = rec_data_check();
-                        rt_thread_mdelay(100);
-                        if (ret == 0)
-                            retry_time = 120; // 判断接收数据是否合法,以及读取协议层afn和长度,并回复
-                        else if (ret == -1 || ret == 2)
-                            break;
-                    }
-
-                } while (0);
-                at_cmd_send(npos + 2, "AT+QICLOSE=0\r\n", NB_AT_ACK, 3, 3); // 关闭tcpLINK
+                rec_cmd_handler(npos, PORT_MAIN, &vflag);
             }
             npos += 3;
             ////////////////////////////备用连接/////////////////////////////////////////////////////
-            if (((upload_dat.rept_addr & BIT1) != 0 || NbRun.upload.mode != NB_UPLOAD_REPT) && check_sub_service_flag() == 1)
+            if (check_sub_service_flag() == 1)
             {
-                vflag &= 0x0f;
-                do
-                {
-#ifdef APP_DEBUG_PRINT
-                    LOG("sub service upload\r\n");
-#endif
-                    build_tcp_open_cmd(ncdp_str,             //"AT+QIOPEN=1,0,\"TCP\",\"%d.%d.%d.%d\",%d,0,0\r\n", // 倒数第二个0:本地ip自动 最后一个0: 缓存模式
-                                       Paramx.sub_server_ip, //[0],
-                                                             // Paramx.sub_server_ip[1],
-                                                             //  Paramx.sub_server_ip[2],
-                                                             //   Paramx.sub_server_ip[3],
-                                       Paramx.sub_server_port);
-
-                    if (at_cmd_send(npos, ncdp_str, "+QIOPEN: 0,", 2, 10) == -1) // 建立TCP连接,等待连接成功
-                        break;
-                    if (get_code(NbRun.rx_buf, "+QIOPEN: 0,", NbRun.rx_idx, &link_code) == -1)
-                        break;
-                    if (link_code != 0)
-                        break;
-                    // 发送数据,等待接收指令,收到指令后执行,超时退出
-                    nb_upload_data_ready();
-                    rt_thread_mdelay(100);                                                  // 准备上报数据
-                    if (at_cmd_send(npos + 1, (char *)NbRun.tx_buf, "SEND OK", 3, 3) == -1) // 发送上报数据
-                        break;
-                    vflag |= 2; // 上报成功标志
-
-                    int8_t ret;
-
-                    retry_time = 120; // 12秒
-                    NbRun.cur_afn = 0;
-                    //////////////////////////////////////
-
-                    while (retry_time--)
-                    {
-                        ret = rec_data_check();
-                        rt_thread_mdelay(100);
-                        if (ret == 0)
-                            retry_time = 120; // 判断接收数据是否合法,以及读取协议层afn和长度,并回复
-                        else if (ret == -1 || ret == 2)
-                            break;
-                    }
-
-                } while (0);
-                at_cmd_send(npos + 2, "AT+QICLOSE=0\r\n", NB_AT_ACK, 3, 2); // 关闭tcpLINK
+                rec_cmd_handler(npos, PORT_SUB, &vflag);
             }
         } while (0); // 主循环
         //		 NB_RUN_UPDATE_FLAG = 0;
 
         nb_power_off();
-
+        // #ifdef DEBUG_NB
+        //         get_rtc_run(&rr);
+        //         LOG("run_time:20%2d-%2d-%2d:%2d:%2d:%2d fw=%f,bw=%f\r\n", rr->year, rr->month, rr->day, rr->hour, rr->minute, rr->second, BillRun.fw_cum_flow, BillRun.bw_cum_flow); // 锟斤拷示时锟斤拷
+        // #endif
         if (vflag & 0x80)
             LOG("no service upload!\r\n");
         else if ((vflag & 3) != 0)
@@ -1984,6 +1858,7 @@ int8_t at_cmd_send2(uint8_t stat, char *cmd_str, char *ack1, char *ack2, uint16_
     }
     return -1;
 }
+
 static void BuildDataReportMeter(rtc_run_t *rr, uint8_t *data)
 {
     rtc_run_t *max_fr_rr;
@@ -2005,8 +1880,8 @@ static void BuildDataReportMeter(rtc_run_t *rr, uint8_t *data)
     // Daily maximum flow rate
     temp = (uint32_t)(get_max_flow_rate() * 1000); // 3位小数点
 
-#ifdef DEBUG_NB
-    //	temp = 12345;
+#ifdef DEBUG_4G_DATA
+    temp = 12345;
 #endif
 
     data[8] = (uint8_t)(temp);
@@ -2028,21 +1903,22 @@ static void BuildDataReportMeter(rtc_run_t *rr, uint8_t *data)
         data[17] = max_fr_rr->minute;
         data[18] = max_fr_rr->second;
     }
-#ifdef DEBUG_NB
-//		data[13] = 26;
-//    data[14] = 3;
-//    data[15] = 31;
-//    data[16] = 9;
-//    data[17] = 30;
-//    data[18] = 45;
+#ifdef DEBUG_4G_DATA
+    data[12] = 0x14;
+    data[13] = 26;
+    data[14] = 3;
+    data[15] = 31;
+    data[16] = 9;
+    data[17] = 30;
+    data[18] = 45;
 #endif
     // water temperature
     if (WaterTemp > 100.0f || WaterTemp < 0.0f)
         temp = 0x8000; // wxl 2026-5-22
     else
         temp = (uint32_t)(WaterTemp * 10 + 0.5);
-#ifdef DEBUG_NB
-//	 temp = -300;
+#ifdef DEBUG_4G_DATA
+    //  temp = -300;
 #endif
 
     data[19] = (uint8_t)(temp);
@@ -2321,6 +2197,11 @@ static void BuildHourRecord(rtc_run_t *rr, uint8_t *data)
             continue;
         memcpy(&data[4 + i * 3], bill.fw_used, 3);
         memcpy(&data[4 + 72 + i * 3], bill.bw_used, 3);
+#ifdef DEBUG_4G_DATA
+        bill.pressure = 102;
+        *(uint16_t *)bill.flow_rate = 12345;
+        bill.flow_rate[2] = 0;
+#endif
         data[4 + 144 + i] = bill.pressure;
         memcpy(&data[4 + 168 + i * 3], bill.flow_rate, 3);
     }
@@ -2880,3 +2761,73 @@ void build_tcp_open_cmd(char *out_str, uint8_t *ip, uint16_t port)
     strcat(out_str, num_buf);
     strcat(out_str, ",0,0\r\n");
 }
+int8_t get_ta_id(void)
+{
+    NbRun.rx_buf[NbRun.rx_idx] = 0;
+    if (strstr((char *)NbRun.rx_buf, "EC800Z") != NULL)
+        return TA_ID_EC800Z_CN;
+    else if (strstr((char *)NbRun.rx_buf, "EG800Z") != NULL)
+        return TA_ID_EG800Z_EU;
+    return -1;
+}
+// port ==0 main
+// port ==1 sub
+
+void rec_cmd_handler(uint8_t npos, uint8_t mport, uint8_t *vflag)
+{
+    uint8_t *ip;
+    uint16_t port_num;
+    int16_t link_code;
+    char ncdp_str[64];
+    int8_t ret, retry_time;
+
+    *vflag &= 0x0f; // 已启动上报,清除BIT7
+#ifdef APP_DEBUG_PRINT
+    if (mport == PORT_MAIN)
+        LOG("main service upload\r\n");
+    else
+        LOG("sub service upload\r\n");
+#endif
+    do
+    {
+        if (mport == PORT_MAIN)
+        {
+            ip = Paramx.main_server_ip;
+            port_num = Paramx.main_server_port;
+        }
+        else
+        {
+            ip = Paramx.sub_server_ip;
+            port_num = Paramx.sub_server_port;
+        }
+        build_tcp_open_cmd(ncdp_str, ip, port_num); // 字符串生成
+
+        if (at_cmd_send(npos, ncdp_str, "+QIOPEN: 0,", 2, 10) == -1) // 建立TCP连接,等待连接成功
+            break;
+        if (get_code(NbRun.rx_buf, "+QIOPEN: 0,", NbRun.rx_idx, &link_code) == -1)
+            break;
+        if (link_code != 0) // 连接失败
+            break;
+        nb_upload_data_ready();                                                 // 准备上报数据
+        rt_thread_mdelay(100);                                                  // 准备上报数据
+        if (at_cmd_send(npos + 1, (char *)NbRun.tx_buf, "SEND OK", 3, 3) == -1) // 发送上报数据
+            break;
+        *vflag |= mport; // 上报成功标志
+
+        retry_time = WAIT_CMD_DELAY_TIME * 10; // 12秒
+        NbRun.cur_afn = 0;
+        //////////////////////////////////////
+
+        while (retry_time--)
+        {
+            ret = rec_data_check();
+            rt_thread_mdelay(100);
+            if (ret == 0)
+                retry_time = WAIT_CMD_DELAY_TIME * 10; // 判断接收数据是否合法,以及读取协议层afn和长度,并回复
+            else if (ret == 2)
+                break;
+        }
+
+    } while (0);
+    at_cmd_send(npos + 2, "AT+QICLOSE=0\r\n", NB_AT_ACK, 3, 3); // 关闭tcpLINK
+}

+ 11 - 1
Users/app_nb/app_nb.h

@@ -17,6 +17,11 @@ extern "C"
 #define MB_MAX_RETRY_GATT_QUERY_TIME 4
 #define QUERY_RETRY_TIME 90
 
+#define WAIT_CMD_DELAY_TIME 12 // 12Ãë
+
+#define PORT_MAIN 1
+#define PORT_SUB 2
+
   // #define NB_AUTO_GET_NET_TIME	//×Ô¶¯»ñÈ¡ÍøÂçʱ¼ä
 
 #define NB_FLAG_ARG_VLD (0x0001u)
@@ -107,6 +112,9 @@ extern "C"
 #define NB_UPLOAD_ERR 0x10
 #define NB_UPLOAD_DMA 0x20
 
+#define TA_ID_EC800Z_CN 1
+#define TA_ID_EG800Z_EU 2
+
 #define NB_VOID_UPLOAD_TIME 120
   typedef enum en_at_num
   {
@@ -378,7 +386,9 @@ extern "C"
   extern uint8_t check_sub_service_flag(void);
   extern uint8_t check_main_service_flag(void);
   extern void build_tcp_open_cmd(char *out_str, uint8_t *ip, uint16_t port);
-  // #endif
+  extern int8_t get_ta_id(void);
+  extern void rec_cmd_handler(uint8_t npos, uint8_t mport, uint8_t *vflag);
+// #endif
 #ifdef __cplusplus
 }
 #endif

+ 20 - 10
Users/param/param.c

@@ -121,8 +121,8 @@ void LoadDefaultParam(void) // 
 
 	Paramx.pipe_coe = DEFAULT_PIPE_COE; // coe系数
 
-	//	strcpy(Paramx.imei, DEFAULT_IMEI); // imei号
-	//	Paramx.imei[sizeof(DEFAULT_IMEI) - 1] = 0;
+	// strcpy(Paramx.imei, DEFAULT_IMEI); // imei号
+	// Paramx.imei[sizeof(DEFAULT_IMEI) - 1] = 0;
 
 	// strcpy(Paramx.ccid, DEFAULT_CCID); // CCID号
 	// Paramx.ccid[sizeof(DEFAULT_CCID) - 1] = 0;
@@ -237,7 +237,7 @@ void get_para_to_tdcitf(void) // 
 	TdcItf.pipe_coe = Paramx.pipe_coe;
 	TdcItf.ch_num = Paramx.chan_num;
 
-	if (TdcItf.ch_num == 1)
+	if (TdcItf.ch_num == 1) // wxl2026-5-21 bug修复
 	{
 		TdcItf.ch_bit_map = 1;
 	}
@@ -531,7 +531,7 @@ void SaveParam(void)
 	Paramx.path_skew[2] = TdcItf.path_skew[2];
 	Paramx.path_skew[3] = TdcItf.path_skew[3];
 	Paramx.pipe_coe = TdcItf.pipe_coe;
-	//	memcpy(Paramx.imei, nb_run->imei, 16);								  // imei号保存
+	// memcpy(Paramx.imei, nb_run->imei, 16);								  // imei号保存
 	// memcpy(Paramx.ccid, nb_run->ccid, 32);								  // ccid号保存
 	memcpy(Paramx.mux_ch_no, TdcItf.mux_ch_no, sizeof(TdcItf.mux_ch_no)); // 多路开关地址
 
@@ -806,7 +806,7 @@ int8_t get_server_ip_port_para(SERVER_IP_PORT_DEF *server_ip_para)
 	return 0;
 }
 ////////////////////////////设置定时上报周期和时间间隔/////////////////////////////////////////////////////
-//                                                                        参数:regular_report_para定时上报数据结构体,包含起始基准时间,间隔时间u\
+//                                                                                                     参数:regular_report_para定时上报数据结构体,包含起始基准时间,间隔时间u\
 //返回:1:成功2:失败
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 int8_t set_regular_report_para(REGULAR_REPORT_DEF *regular_report_para)
@@ -891,7 +891,7 @@ int8_t set_nb_band(uint8_t band)
 	uint8_t flag = 0, ret = 0;
 	uint8_t dat = 0;
 	// 判断数据是否在正常范围内
-	Paramx.nb_band_flag = band;
+	dat = band;
 	ret = set_para_if_nessary(&dat, &Paramx.nb_band_flag, 1, &flag); // 参数整体保存
 	if (flag == 1)
 	{ // 保存crc校验
@@ -1001,7 +1001,7 @@ int8_t get_settlement_day_para(SETTLEMENT_DAY_DEF *settlement_day_para)
 ///////////////////////////////设置表端底读///////////////////////////////////////////////////
 // 参数:指向表端底读数据指针
 // 返回:1:成功 2:失败
-//////////////////////////////////////////////////////////////////////////////////////////////int8_t set_meter_bottom_data(METER_BOTTOM_DEF *bottom_data)
+//////////////////////////////////////////////////////////////////////////////////////////////
 int8_t set_meter_bottom_data(METER_BOTTOM_DEF *bottom_data)
 {
 	uint8_t flag = 0, ret = 0;
@@ -1161,7 +1161,11 @@ int8_t get_hour_record_data(uint8_t year, uint8_t month, uint8_t day, uint8_t *d
 			data[0] = 0x14; // 标记有效? 原代码在循环外设置 data[0]=0x14, 这里如果部分失败怎么处理?
 							// 原代码逻辑:只要进入else,data[0]就被设为0x14。
 							// 如果某个小时失败,bill是全零,拷贝进去也是零。
-
+#ifdef DEBUG_4G_DATA
+			*(uint16_t *)bill.flow_rate = 23456;
+			bill.flow_rate[2] = 0;
+			bill.pressure = 115;
+#endif
 			memcpy(&data[4 + i * 3], bill.fw_used, 3);
 			memcpy(&data[4 + 72 + i * 3], bill.bw_used, 3);
 			data[4 + 144 + i] = bill.pressure;
@@ -1280,6 +1284,11 @@ int8_t get_5min_record_data(GET_5MIN_REOCORD_DEF *get_5min_record_info, uint16_t
 			// 这里暂且填入 index_time.min (10:05),因为这是数据的真实标记。
 			data[5 + i * 16] = index_time.min;
 
+#ifdef DEBUG_4G_DATA
+			*(uint16_t *)bill.flow_rate = 34567;
+			bill.flow_rate[2] = 0;
+			bill.pressure = 118;
+#endif
 			memcpy(&data[6 + i * 16], bill.fw_used, 10);
 		}
 
@@ -1556,7 +1565,8 @@ uint16_t pack_crc_check(uint16_t prev_data, uint8_t *data, uint16_t len)
 	return crc;
 }
 ///////////////////1秒一次运行的一些零星任务//////////////////////
-uint8_t rtc_1s_flag;
+
+// uint8_t rtc_1s_flag;
 void run_clk_task_handler(void)
 {
 #ifdef LED_DEF
@@ -1565,7 +1575,7 @@ void run_clk_task_handler(void)
 	SetLed(LED1, rr->second % 2); // 1秒闪烁
 #endif
 	check_rewrite_para(); // 相关参数判断,不合法的重写eeprom
-	rtc_1s_flag = 1;
+						  // rtc_1s_flag = 1;
 }
 //////////////////////////////////////
 ///////////检查是否是新app第一次运行,如果是,则更新flash中的运行信息//////////////////