| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815 |
- #include "board.h"
- #include "app_nb.h"
- #include "prj_com.h"
- #include "param.h"
- #include "rtc_run.h"
- #include "board.h"
- #include "tdc_tof.h"
- #include "bill.h"
- #include "alarm.h"
- #include "stat.h"
- #include "ymodem.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
- Nb_Run_t NbRun;
- uint8_t NB_CHECK_TDC_COMPLETE_FLAG = 0;
- uint8_t NbIntStep = 0xFFu;
- rt_sem_t Nb_thread_run_sem = RT_NULL; // NB线程运行信号量
- // 补报相关信息
- NbAppFrame_t __attribute__((aligned(4))) NbAppFrame;
- uint8_t Nb_rx_data(void);
- void nb_run_init(void)
- {
- lpuart0_set_rx_itf(NbRxCh); // nb串口中断
- // NbRun.rx_flag = FALSE;
- NbRun.rx_over_time = 0;
- NbRun.rx_idx = 0;
- memset(NbRun.rx_buf, 0, sizeof(NbRun.rx_buf));
- memset(NbRun.tx_buf, 0, sizeof(NbRun.tx_buf));
- NbRun.cur_at = at_end;
- NbRun.rsrp = 0;
- NbRun.rsrq = 0;
- NbRun.rssi = 0;
- NbRun.snr = 0;
- memset(NbRun.imei, 0, sizeof(NbRun.imei));
- memset(NbRun.imsi, 0, sizeof(NbRun.imsi));
- memset(NbRun.ccid, 0, sizeof(NbRun.ccid));
- NbRun.task.count = 0;
- // NbRun.open_time_out = 0;
- memset(&NbAppFrame, 0, sizeof(NbAppFrame));
- NbRun.status = 0;
- Nb_thread_run_sem = rt_sem_create("nb_thread_run", 0, RT_IPC_FLAG_FIFO); // 创建nb运行信号量
- NbRun.get_imei_flag = 0;
- NbRun.get_imsi_flag = 0;
- NbRun.get_ccid_flag = 0;
- }
- static void NbBuildDataHeader(uint16_t data_len)
- {
- Param_t *param;
- GetParam(¶m);
- NbAppFrame.prefix[0] = 0xFE;
- NbAppFrame.prefix[1] = 0xFE;
- NbAppFrame.head = 0x68;
- NbAppFrame.type = 0x10;
- // memcpy(NbAppFrame.addr, param->dev_id, sizeof(param->dev_id));
- NbAppFrame.addr[0] = param->dev_id[5];
- NbAppFrame.addr[1] = param->dev_id[4];
- NbAppFrame.addr[2] = param->dev_id[3];
- NbAppFrame.addr[3] = param->dev_id[2];
- NbAppFrame.addr[4] = param->dev_id[1];
- NbAppFrame.addr[5] = param->dev_id[0];
- // NbAppFrame.addr[6] = param->dev_id[0];
- NbAppFrame.addr[6] = 0x00;
- NbAppFrame.ctrl = 0xA0;
- NbAppFrame.len[0] = (unsigned char)(data_len);
- NbAppFrame.len[1] = (unsigned char)(data_len >> 8);
- }
- static void NbBuildDataTail(uint16_t data_len)
- {
- uint8_t cs = 0;
- // cs
- cs = check_sum((uint8_t *)&NbAppFrame.head, 12);
- cs += check_sum(NbAppFrame.data, data_len);
- NbAppFrame.data[data_len] = cs; // 8位累加和
- NbAppFrame.data[data_len + 1] = 0x16; // 结束位
- }
- /*
- 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;
- }*/
- char *get_frame_start(char *buf, uint16_t len)
- {
- if (buf == NULL || len < 2)
- {
- return NULL;
- }
- for (uint16_t i = 0; i <= len - 2; i++)
- {
- if ((uint8_t)buf[i] == 0x68 && (uint8_t)buf[i + 1] == 0x10)
- {
- return &buf[i];
- }
- }
- return NULL;
- }
- int NbRcvDataValid(void)
- {
- char *p_comma = NULL;
- char *p_start = NULL;
- char len_str[8] = {0};
- uint32_t total_frame_len = 0;
- uint8_t cs;
- uint8_t head_len = 0;
- uint16_t data_len;
- // 1. 检查是否有数据接收完成标志
- if (Nb_rx_data() == 0)
- return 0; // 无数据,继续等待
- // 2. 接收数据关键字
- p_comma = strstr((char *)NbRun.rx_buf, "+QIRD: ");
- if (p_comma == NULL)
- {
- // 没有逗号,检查是否全是空白或OK,如果是则清除
- if (strstr((char *)NbRun.rx_buf, "OK") != NULL || NbRun.rx_idx > 50)
- {
- NbClrRxBuf();
- }
- 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); // 数据总长度
- if (total_frame_len < 14)
- {
- NbClrRxBuf();
- return 4;
- }
- // 6. 检查 Hex 数据完整性
- // char *p_hex_start = p_start + head_len + 2; // 包含关键字+ 长度域+ 回车换行符
- char *p_hex_start = get_frame_start(p_start + 2, NbRun.rx_idx - (p_start + 2 - (char *)NbRun.rx_buf));
- if (p_hex_start == NULL)
- {
- return 0; // 数据不完整,继续等待
- }
- // 6.2 检查校验和
- cs = 0;
- uint16_t available_chars = NbRun.rx_idx - (p_hex_start - (char *)NbRun.rx_buf);
- if (available_chars < total_frame_len) // 这里可能要改为接收二进制数据,(去掉*2)
- {
- return 0; // 数据不完整,继续等待
- }
- // 7. Hex 转 Binary
- // StrToHexBuf((char *)&NbAppFrame.head, p_hex_start, total_frame_len);//如果是二进制数据,则不需要转换
- memcpy((char *)&NbAppFrame.head, p_hex_start, total_frame_len);
- NbClrRxBuf();
- // 8. 校验帧头
- if (NbAppFrame.head != 0x68)
- return 5;
- // 9. 校验长度一致性
- data_len = (NbAppFrame.len[1] << 8) | NbAppFrame.len[0];
- if (total_frame_len != (14 + data_len))
- return 6;
- // 10. 校验 Check Sum
- cs = check_sum((uint8_t *)&NbAppFrame.head, total_frame_len - 2);
- if (cs != NbAppFrame.data[data_len])
- return 7;
- // 11. 校验帧尾
- if (NbAppFrame.data[data_len + 1] != 0x16)
- return 8;
- return 1; // 验证成功
- }
- void GetNbRun(Nb_Run_t **nb_run)
- {
- *nb_run = &NbRun;
- }
- void NbRxCh(uint8_t ch)
- {
- if (NbRun.rx_idx >= NB_RXLEN_MAX - 1)
- {
- return;
- }
- NbRun.rx_buf[NbRun.rx_idx++] = ch;
- NbRun.rx_over_time = 4;
- #ifdef DEBUG_NB
- // LOG("%c",ch);
- #endif
- }
- // void NbRxTimeout(void)
- //{
- // if (NbRun.rx_over_time >= 2) {
- // NbRun.rx_over_time--;
- // } else if (NbRun.rx_over_time == 1) {
- // NbRun.rx_flag = TRUE;
- // NbRun.rx_over_time--;
- // }
- // }
- uint8_t Nb_rx_data(void)
- {
- if (NbRun.rx_over_time != 0)
- {
- NbRun.rx_over_time--;
- }
- if (NbRun.rx_over_time == 1)
- {
- #ifdef DEBUG_NB
- /////////////////////
- unsigned short i;
- for (i = 0; i < NbRun.rx_idx; i++)
- LOG("%c", NbRun.rx_buf[i]);
- // LOG("%s\r\n",NbRun.rx_buf);
- ///////////////////
- #endif
- return 1; // 已收到数据
- // }
- }
- return 0;
- }
- void NbClrRxBuf(void)
- {
- NbRun.rx_idx = 0;
- memset(NbRun.rx_buf, 0, sizeof(NbRun.rx_buf));
- }
- int8_t get_nb_imsi_code(void)
- {
- char *p = NULL;
- char *q = NULL;
- uint8_t i, flag;
- p = strstr((char *)NbRun.rx_buf, "OK");
- if (p == NULL)
- {
- return -1;
- }
- p = strstr((char *)NbRun.rx_buf, "\r\n"); // 找到第一个回车符
- if (p != NULL && strlen(p) > 2)
- {
- q = strstr(p + 2, "\r\n"); // 第二个回车符,id在两个回车符之间
- if (q != NULL && (q - p - 2) > 0 && (q - p - 2) < 16)
- { // 长度大于2小于15
- *q = 0;
- strcpy(NbRun.imsi, p + 2);
- /// LOG("imsi = %s\n", NbRun.imsi);
- }
- }
- flag = 0;
- for (i = 0; NbRun.imsi[i] != 0; i++)
- {
- if (NbRun.imsi[i] < '0' || NbRun.imsi[i] > '9')
- {
- flag = 1;
- break;
- }
- }
- if (flag == 1 || i != 15)
- return -1;
- NbRun.get_imsi_flag = 1; // 已获取IMEI号标志
- return 0;
- }
- int8_t get_nb_imei_code(void)
- {
- char *p = NULL;
- char *q = NULL;
- uint8_t i, flag;
- p = strstr((char *)NbRun.rx_buf, "OK");
- if (p == NULL)
- {
- return -1;
- }
- p = strstr((char *)NbRun.rx_buf, "+CGSN:");
- if (p != NULL)
- {
- p = strstr((char *)NbRun.rx_buf, "\""); // 找到第一个"所在位置
- if (p != NULL && strlen(p + 1) > 1)
- {
- q = strstr(p + 1, "\"\r\n"); // 回车换行符所在位置
- if (q != NULL && (q - p - 1) > 0 && (q - p - 1) < 16)
- { // 存在回车换行符,且:到换行符之间有信息,且长度小于16
- *q = 0; // 把第二个"置0,作为字符串结束位置
- strcpy(NbRun.imei, p + 1);
- }
- }
- }
- flag = 0;
- for (i = 0; NbRun.imei[i] != 0; i++)
- {
- if (NbRun.imei[i] < '0' || NbRun.imei[i] > '9')
- {
- flag = 1;
- break;
- }
- }
- if (flag == 1 || i != 15)
- return -1;
- NbRun.get_imei_flag = 1; // 已获取IMEI号标志
- #ifdef APP_DEBUG_PRINT
- LOG("imei=%s\r\n", NbRun.imei);
- #endif
- return 0;
- }
- int8_t get_nb_ccid_code(void)
- {
- char *p = NULL;
- char *q = NULL;
- uint8_t i, flag;
- p = strstr((char *)NbRun.rx_buf, "OK");
- if (p == NULL)
- {
- return -1;
- }
- p = strstr((char *)NbRun.rx_buf, ":");
- p++;
- if (p != NULL && strlen(p) > 1)
- {
- q = strstr(p + 1, "\r\n");
- if (q != NULL && (q - p - 1) > 0 && (q - p - 1) < 21)
- {
- *q = 0;
- strcpy(NbRun.ccid, p + 1);
- }
- }
- flag = 0;
- for (i = 0; NbRun.ccid[i] != 0; i++)
- {
- if (NbRun.ccid[i] < '0' || NbRun.ccid[i] > '9')
- {
- flag = 1;
- break;
- }
- }
- if (flag == 1 || i != 20)
- return -1;
- NbRun.get_ccid_flag = 1; // 已获取IMEI号标志
- #ifdef APP_DEBUG_PRINT
- LOG("iccid=%s\r\n", NbRun.ccid);
- #endif
- return 0;
- }
- // NUESTATS:CELL,<earfcn>,<physical_cell_id>,<primarycell>,<RSRP>,<RSRQ>,<RSSI>,<SNR>
- // NUESTATS:CELL,2401,476,1,-920,-41,-879,144
- // 在 app_nb.c 中找到 NbSetUploadMode 函数并替换
- void NbSetUploadMode(uint8_t mode)
- {
- // 【修改点】:始终更新 mode,使用 |= 确保不覆盖已有的触发原因
- // 例如:如果之前是定时上报(0x02),现在发生了错误报警(0x10),mode 将变为 0x12
- NbRun.upload.mode |= mode;
- // 只有在尚未标记上传任务时,才设置 flag 并唤醒线程
- if (NbRun.upload.flag == FALSE)
- {
- NbRun.upload.flag = TRUE;
- NbRun.task.flag = 1;
- NbRun.cur_afn = 0x0010;
- rt_sem_release(Nb_thread_run_sem); // 触发nb线程
- }
- }
- /////////////////等待接收指定的回复///////////////////////
- // ack:回复的字符串
- // timeout:等待超时时间 秒单位
- //: 返回0:成功, -1:等待超时
- /////////////////////////////////////
- int8_t Nb_check_rec_valid(uint8_t state, char *ack)
- {
- // if(state == COAP_WAIT_REG){
- // if(strstr((const char *)NbRun.rx_buf, ack) != NULL )
- // }
- // else
- if (strstr((const char *)NbRun.rx_buf, ack) != NULL)
- { // 收到要求的回复
- return 1; // 收到正确回复,进行下一步
- }
- if (strstr((char *)&NbRun.rx_buf[0], "\r\nOK\r\n") != NULL || strstr((char *)&NbRun.rx_buf[0], "\r\nERROR\r\n") != NULL)
- {
- return -1; // 错误回复,重新发送
- }
- return 0; // 其他需要继续等待
- }
- void nb_send_data_route(unsigned char *data, uint16_t len) // 发送数据 TCP
- {
- char tmp[16] = {0};
- memset(NbRun.tx_buf, 0, sizeof(NbRun.tx_buf));
- strcpy((char *)NbRun.tx_buf, "AT+QISENDEX=0,"); // at指令 发送数据
- // int2str(len, tmp); // 转换成字符串
- strcat((char *)NbRun.tx_buf, "\"");
- HexBufToStr((char *)NbRun.tx_buf + strlen((char *)NbRun.tx_buf), data, len); // 不加前面的指令部分,只发送数据部分
- strcat((char *)NbRun.tx_buf, "\"");
- strcat((char *)NbRun.tx_buf, "\r\n\0"); // 末尾回车换行符
- // NbRoutineEventPro((char *)NbRun.tx_buf, (char *)NB_NMGS_ACK, 3, 60);
- }
- UPLOAD_DEF upload_dat;
- const uint8_t monthday[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- ///////////////////////////////////////////
- /////////////////////////////////main.c中运行,判断是否应该触发nb线程//////////////////////////////////////////////
- // 参数 无
- // 返回 无
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- uint8_t settlement_day_upload_check(void)
- { // 结算日上报
- if (Paramx.settlement_day == 0)
- return 0;
- rtc_run_t *rr;
- get_rtc_run(&rr);
- uint8_t days, setday;
- days = monthday[rr->month - 1];
- if (rr->year % 4 == 0 && rr->month == 2)
- {
- days++;
- } // 计算当月天数
- //////////////////////确定当天上报是否是结算日上报/////////////////////////////////////
- int32_t now, start;
- now = (int32_t)(3600 * rr->hour + 60 * rr->minute + rr->second);
- start = (int32_t)(Paramx.report_base_hour * 3600 + Paramx.report_base_min * 60 + (Paramx.report_base_sec & 0xfe));
- if (Paramx.settlement_day == 0)
- {
- return 0;
- }
- if (Paramx.settlement_day > days)
- {
- setday = days;
- }
- else
- {
- setday = Paramx.settlement_day;
- }
- if (now < start)
- return 0;
- if (setday == rr->day && now - start <= 5)
- {
- return NB_UPLOAD_SETTLE_DAY;
- }
- return 0;
- }
- uint8_t regular_upload_check(void)
- { // 定时上报
- uint32_t *alarmbit;
- all_alarm_status(&alarmbit);
- if ((*alarmbit & ERR_LOW_POWER) != 0)
- return 0; // 低电压不上报
- uint8_t i;
- rtc_run_t *rr;
- get_rtc_run(&rr);
- int32_t now, start;
- now = (int32_t)(3600 * rr->hour + 60 * rr->minute + rr->second);
- start = (int32_t)(Paramx.report_base_hour * 3600 + Paramx.report_base_min * 60 + (Paramx.report_base_sec & 0xfe));
- if (now < start)
- return 0; // 未到上报时间
- if (((now - start) % (Paramx.report_interval * 60)) <= 5)
- return NB_UPLOAD_TIMER;
- return 0;
- }
- uint8_t dma_upload_check(void)
- {
- uint32_t *alarmbit;
- all_alarm_status(&alarmbit);
- if ((*alarmbit & ERR_LOW_POWER) != 0)
- return 0; // 低电压DMA不上报
- if (Paramx.dma_interval == 0)
- return 0; // 无dma上报
- int32_t start_sec, end_sec, now_sec;
- rtc_run_t *rr;
- get_rtc_run(&rr);
- start_sec = (int32_t)(3600 * Paramx.dma_report_start[0] + 60 * Paramx.dma_report_start[1] + Paramx.dma_report_start[2]);
- end_sec = (int32_t)(3600 * Paramx.dma_report_end[0] + 60 * Paramx.dma_report_end[1] + Paramx.dma_report_end[2]);
- now_sec = (int32_t)(3600 * rr->hour + 60 * rr->minute + rr->second);
- if (now_sec < start_sec || now_sec > end_sec + 3)
- return 0; // 不在dma时间范围内
- if (((now_sec - start_sec) % (Paramx.dma_interval * 60)) <= 5)
- {
- return NB_UPLOAD_DMA;
- }
- return 0;
- }
- ////////////////故障上报监测///////////////////////
- // 参数:无
- // 返回:有故障NB_UPLOAD_ERR 无故障:0
- ///////////////////////////////////////////////
- uint8_t err_upload_check(void)
- {
- uint32_t *alarmbit;
- uint32_t temp;
- if (StartUp < 15)
- return 0;
- all_alarm_status(&alarmbit);
- temp = (upload_dat.err_mem_dat & (*alarmbit)) ^ (*alarmbit); // 检查是否有异常bit被置位
- if (temp != 0)
- {
- upload_dat.err_mem_dat = *alarmbit;
- return NB_UPLOAD_ERR;
- }
- return 0;
- }
- uint8_t rept_upload_check(void)
- { // 重复上报监测
- uint8_t i;
- rtc_run_t *rr;
- get_rtc_run(&rr);
- tm_t now_time;
- now_time.year = rr->year;
- now_time.month = rr->month;
- now_time.day = rr->day;
- now_time.hour = rr->hour;
- now_time.min = rr->minute;
- now_time.sec = rr->second;
- uint32_t now_sec = (uint32_t)(now_time.hour * 3600 + now_time.min * 60 + now_time.sec);
- uint32_t start_sec = (uint32_t)(upload_dat.rept_time.hour * 3600 + upload_dat.rept_time.min * 60 + (upload_dat.rept_time.sec & 0xfc));
- uint8_t ret = 0;
- if (upload_dat.rept_runflag != 0)
- {
- // if (datecmp(now_time, upload_dat.rept_time) >= 0)
- if (now_sec >= start_sec && now_sec <= start_sec + 3)
- {
- upload_dat.rept_runflag = 0;
- return NB_UPLOAD_REPT;
- }
- }
- return 0;
- }
- // 手动上报
- uint8_t manual_upload_check(void)
- {
- if (upload_dat.manual_runflag == 1)
- {
- upload_dat.manual_runflag = 0;
- return NB_UPLOAD_MANUAL;
- }
- return 0;
- }
- short up_signal_cnt = -100; // 用于上报过程中动态显示信号强度
- /////////////////////////////////main.c中运行,判断是否应该触发nb线程,1秒1一次//////////////////////////////////////////////
- // 参数 无
- // 返回 无
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // 在 app_nb.c 中找到 nb_task_run_check 函数并替换
- void nb_task_run_check(void)
- {
- uint8_t trik_flag = 0;
- extern const int16_t rsrp_level[5];
- // 信号强度动态显示逻辑保持不变
- if (NbRun.upload.flag != 0)
- {
- up_signal_cnt = (up_signal_cnt + 1) % 5;
- NbRun.rsrp = rsrp_level[up_signal_cnt];
- }
- else
- NbRun.rsrp = NbRun.rsrp_bak;
- #ifdef debug_dog
- if (StartUp == 5)
- {
- rt_enter_critical();
- McuFlash_EraseSegment(DIFF_PATCH_PACKET_START, DIFF_PATCH_PACKET_SIZE);
- rt_exit_critical();
- rt_enter_critical();
- uint8_t i;
- for (i = 0; i < 16; i++)
- xx[i] = i + 1;
- write_flash_memory(xx, DIFF_PATCH_PACKET_START, 16);
- rt_exit_critical();
- while (1)
- ;
- }
- #endif
- if (NbRun.reset_mcu_cnt != 0)
- {
- NbRun.reset_mcu_cnt--;
- if (NbRun.reset_mcu_cnt == 2)
- LOG("ready to reset mcu\r\n");
- if (NbRun.reset_mcu_cnt == 1)
- {
- // watchdog_init(WdtResetEn, WdtT3s28);
- // feed_dog();
- NVIC_SystemReset();
- // while (1);
- // {
- // }
- }
- // NVIC_SystemReset();
- }
- // 【修改点】:不再因为 NbRun.upload.flag 为真而直接 return
- // 即使正在上传,我们也要检查是否有新的触发原因(如错误报警),并将其加入 mode
- trik_flag = settlement_day_upload_check();
- trik_flag |= regular_upload_check();
- trik_flag |= dma_upload_check();
- trik_flag |= err_upload_check(); // 错误报警通常优先级最高,但也作为位之一
- trik_flag |= rept_upload_check();
- trik_flag |= manual_upload_check();
- if (trik_flag != 0)
- {
- // 调用 NbSetUploadMode,它内部会处理 |= 逻辑和线程唤醒逻辑
- NbSetUploadMode(trik_flag);
- }
- // 注意:如果上传已经完成或失败,NbRun.upload.flag 会在 NbTread 末尾清零
- // 此时下一次 nb_task_run_check 运行时会正常触发新的上传任务
- }
- // 上报数据准备,在tx_buf中
- void nb_upload_data_ready(void)
- {
- NbBuildDataReport(); // 组织上报数据,在NbAppFrame中
- uint16_t len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16; // 数据总长度
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- }
- void nb_set_ip_para_ack(void)
- {
- // NbBuildSetIpAndPortRsp();
- nb_set_para_rept(5, 0x20, 1);
- uint16_t len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16;
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- }
- void nb_set_regular_report_para_ack(int8_t ret)
- {
- // NbBuildSetReportPointRsp(ret);
- nb_set_para_rept(5, 0x21, ret);
- uint16_t len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16;
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- }
- void nb_set_dma_report_para_ack(int8_t ret)
- {
- /// NbBuildSetDmaReportPointRsp(ret);
- nb_set_para_rept(5, 0x22, ret);
- uint16_t len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16;
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- }
- void nb_set_rtc_data_ack(int8_t ret)
- {
- // NbBuildSetDateTimeRsp(ret);
- nb_set_para_rept(5, 0x23, ret);
- }
- void nb_set_flow_alarm_para_ack(int8_t ret)
- {
- // NbBuildSetFlowAlarmThresRsp(ret);
- nb_set_para_rept(5, 0x24, ret);
- uint16_t len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16;
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- }
- void nb_set_pressure_alarm_para_ack(int8_t ret)
- {
- // NbBuildSetPressureAlarmThresRsp(ret);
- nb_set_para_rept(5, 0x25, ret);
- }
- void nb_set_temp_alarm_para_ack(int8_t ret)
- {
- // NbBuildSetTempAlarmThresRsp(ret);
- nb_set_para_rept(5, 0x26, ret);
- }
- void nb_set_settlment_day_para_ack(int8_t ret)
- {
- // NbBuildSetSettleRsp(ret);
- nb_set_para_rept(5, 0x27, ret);
- }
- void nb_set_meter_bottom_data_ack(int8_t ret)
- {
- // NbBuildSetBaseReadingRsp(ret);
- nb_set_para_rept(5, 0x28, ret);
- }
- void nb_read_month_record_ack(void)
- {
- NbBuildReportMonthRecord();
- }
- void nb_read_day_record_ack(void)
- {
- NbBuildReportDayRecord();
- }
- int8_t nb_read_hour_record_ack(void)
- {
- uint32_t start, end, ndate;
- uint8_t loop_count = 0; // 用于限制循环次数
- start = (NbAppFrame.data[5] << 16) | (NbAppFrame.data[6] << 8) | NbAppFrame.data[7];
- end = (NbAppFrame.data[9] << 16) | (NbAppFrame.data[10] << 8) | NbAppFrame.data[11];
- rtc_run_t *rr;
- get_rtc_run(&rr); // 获取当前时间
- ndate = (rr->year << 16) | (rr->month << 8) | rr->day;
- // 计算30天前的日期边界
- uint32_t b30date = ndate;
- for (uint8_t i = 0; i < 30; i++)
- b30date = prev_day(b30date);
- // --- 修改部分开始 ---
- // 原逻辑:如果时间不合法,直接返回 -1
- // 新逻辑:如果时间不合法,构建一个长度为248且数据全为0的帧发送一次
- // 检查合法性
- uint8_t is_invalid = 0;
- if (start > ndate || end < b30date || start > end)
- {
- is_invalid = 1;
- }
- // 校正 start
- if (start < b30date)
- start = b30date;
- // 校正 end
- if (end > ndate)
- end = ndate;
- // 再次检查校正后是否合法
- if (start > end)
- {
- is_invalid = 1;
- }
- if (is_invalid)
- {
- uint16_t mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- // 定义正常的数据长度 (参考 NbBuildReportHourRecord)
- uint16_t data_len = 248;
- // 构建帧头
- NbBuildDataHeader(data_len);
- // 设置 AFN 为 0x34 (Read Hour Record Response)
- NbAppFrame.data[0] = 0x34;
- NbAppFrame.data[1] = 0x00;
- // 设置 MID
- NbAppFrame.data[2] = (uint8_t)(mid);
- NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- // 将数据区域全部清零 (NbBuildDataHeader 不会自动清零 data 区域,需手动处理)
- // 注意:NbAppFrame.data 的大小通常足够容纳 248 字节
- memset(&NbAppFrame.data[4], 0, data_len);
- // 构建帧尾 (包含校验和)
- NbBuildDataTail(data_len);
- uint16_t len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16;
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- // 发送 AT 命令
- if (at_cmd_send(COAP_QLWDATASEND, (char *)NbRun.tx_buf, NB_AT_ACK, 3, 60) == -1)
- return -1;
- return 0; // 返回成功,表示已处理本次请求
- }
- // --- 修改部分结束 ---
- ndate = start;
- uint16_t len;
- // 无限循环处理所有有效日期,但限制 loop_count < 12 以防死循环或数据过多
- while (ndate <= end && loop_count < 12)
- {
- NbBuildReportHourRecord((uint8_t)(ndate >> 16), (uint8_t)(ndate >> 8), (uint8_t)(ndate));
- len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16;
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- if (at_cmd_send(COAP_QLWDATASEND, (char *)NbRun.tx_buf, NB_AT_ACK, 3, 60) == -1)
- return -1;
- ndate = next_day(ndate);
- loop_count++; // 增加计数器
- }
- return 0;
- }
- int8_t nb_read_5min_record_ack(void)
- {
- // 将大型局部变量改为静态变量,以减少栈使用
- static tm_t start, end, cur;
- static tm_t now_tm, limit_start_tm;
- uint16_t len;
- uint8_t loop_count = 0; // ?
- // 1. е????
- start.year = NbAppFrame.data[5];
- start.month = NbAppFrame.data[6];
- start.day = NbAppFrame.data[7];
- start.hour = NbAppFrame.data[8];
- start.min = NbAppFrame.data[9];
- start.sec = 0;
- end.year = NbAppFrame.data[11];
- end.month = NbAppFrame.data[12];
- end.day = NbAppFrame.data[13];
- end.hour = NbAppFrame.data[14];
- end.min = NbAppFrame.data[15];
- end.sec = 0;
- // 2. ????15??
- rtc_run_t *rr;
- get_rtc_run(&rr);
- // ?? tm_t (??)
- now_tm.year = rr->year;
- now_tm.month = rr->month;
- now_tm.day = rr->day;
- now_tm.hour = rr->hour;
- now_tm.min = rr->minute;
- now_tm.sec = rr->second;
- // 15???
- uint32_t date32 = (rr->year << 16) | (rr->month << 8) | rr->day;
- for (uint8_t i = 0; i < 15; i++)
- {
- date32 = prev_day(date32);
- }
- limit_start_tm.year = (date32 >> 16) & 0xFF;
- limit_start_tm.month = (date32 >> 8) & 0xFF;
- limit_start_tm.day = date32 & 0xFF;
- limit_start_tm.hour = 0;
- limit_start_tm.min = 0;
- limit_start_tm.sec = 0;
- // 3. ??: start ? end
- uint8_t is_invalid = 0;
- if (datecmp(start, end) > 0)
- {
- is_invalid = 1;
- }
- // 4. ?Ч??Χ
- // ЧΧ: [limit_start_tm, now_tm]
- if (datecmp(end, limit_start_tm) < 0) // ?15?
- {
- is_invalid = 1;
- }
- if (datecmp(start, now_tm) > 0) // ?????
- {
- is_invalid = 1;
- }
- // 5. У start end ЧΧ
- if (datecmp(start, limit_start_tm) < 0)
- {
- start = limit_start_tm;
- }
- if (datecmp(end, now_tm) > 0)
- {
- end = now_tm;
- }
- // ?μУ?
- if (datecmp(start, end) > 0)
- {
- is_invalid = 1;
- }
- // --- ???? ---
- // ????388??0??
- if (is_invalid)
- {
- uint16_t mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- //
- uint16_t data_len = 388;
- // ??
- NbBuildDataHeader(data_len);
- // AFN ? 0x37 (Read 5Min Record Response)
- NbAppFrame.data[0] = 0x37;
- NbAppFrame.data[1] = 0x00;
- // MID
- NbAppFrame.data[2] = (uint8_t)(mid);
- NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- // ? (NbBuildDataHeader ? data ?)
- // ??NbAppFrame.data ?С? 388 ?
- memset(&NbAppFrame.data[4], 0, data_len);
- // ?β (У)
- NbBuildDataTail(data_len);
- len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16;
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- // AT
- if (at_cmd_send(COAP_QLWDATASEND, (char *)NbRun.tx_buf, NB_AT_ACK, 3, 60) == -1)
- return -1;
- return 0; // ????
- }
- // --- ??? ---
- // 6. ??12
- cur = start; // 初始化 cur
- while (datecmp(cur, end) < 0) // ? while ???м
- {
- // ?
- if (loop_count >= 12)
- {
- break;
- }
- NbBuildReport5MinRecord(&cur);
- len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16;
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- if (at_cmd_send(COAP_QLWDATASEND, (char *)NbRun.tx_buf, NB_AT_ACK, 3, 60) == -1)
- return -1;
- // 2С?
- time_add_secs(&cur, &cur, 2 * 60 * 60);
- loop_count++; // ?
- }
- return 0;
- }
- void nb_read_log_record_ack(void)
- {
- NbBuildReportLogRecord();
- }
- /////// 设置开始升级信息/////////////////////
- /// 返回 1:成功 2:版本号不对 3:长度超限
- int8_t nb_set_patch_info(void)
- {
- PATCH_INFO_DEF dat;
- uint8_t *src = &NbAppFrame.data[4];
- memcpy(dat.cur_ver, src, 5);
- memcpy(dat.new_ver, src + 5, 5);
- dat.patch_len = src[10] + ((uint16_t)src[11] << 8) + ((uint32_t)src[12] << 16) + ((uint32_t)src[13] << 24);
- dat.per_packet_len = src[14] + 256 * src[15];
- dat.packet_crc = src[16] + 256 * src[17];
- uint8_t ret = set_patch_info(&dat); // 返回1,2,3 //1成功
- // if(ret != 0)return -1;
- // else return 0;
- return ret;
- }
- ////////////////////////////////////
- // 1.升级成功结束
- // 2:升级失败,crc校验失败
- // 3.升级失败,多次尝试未获得升级包
- // 4.失败,未能成功运行
- // 5.失败版本不匹配
- // 0x10:重新读取本包数据
- // 0x20:获取下一包
- ///////////////////////////////////
- void nb_set_patch_info_ack(int8_t stat)
- {
- // if(stat>=1 && stat <= 6 ){
- if (stat <= 3)
- NbBuildReportUpdateStatus(stat);
- //}
- else // if(stat == 0x10){
- NbBuildGetPackage();
- //}
- // else if(stat == 0x20){
- // NbBuildGetPackage();
- // }
- }
- /////////////在采样中断结束,刚好允许进入低功耗时发送指令,避免接收失败//////////////////////
- // dat:要发送的数据
- ////////////////////////////////////
- // uint8_t NB_CHECK_TDC_COMPLETE_FLAG
- // check G_TDC_CAN_DEEP_SLEEP 0->1
- 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)
- {
- nb_tx_str(dat);
- rtc_1s_flag = 0;
- }
- NB_CHECK_TDC_COMPLETE_FLAG = 0;
- }
- int8_t rec_data_check(void)
- {
- // 1. 主动请求数据
- send_nb_data_after_sample("AT+QIRD=0,1500\r\n"); // 读取数据,最长1500 tcp限制
- // 2. 尝试解析数据
- uint8_t result = NbRcvDataValid();
- // --- 情况 A: 没有收到完整数据或正在等待 ---
- if (result == 0)
- {
- // 如果是 OTA 过程,允许较长的等待时间
- if (NbRun.cur_afn == 0x50 || NbRun.cur_afn == 0x51)
- {
- NbRun.get_patch_time_out++;
- if (NbRun.get_patch_time_out < 120) // 约 5-10秒
- return 1; // 继续等待
- else
- return -1; // OTA 超时
- }
- return 1; // 普通命令继续等待
- }
- // --- 情况 B: 数据校验失败 (格式错误、CS错误等) ---
- if (result > 1)
- {
- #ifdef DEBUG_NB
- LOG("Rcv Err: %d\r\n", result);
- #endif
- // 收到垃圾数据,清除状态,让上层循环重试 AT+NMGR
- // 返回 1 表示“本次尝试失败,请重试”,而不是“继续等待当前缓冲”
- return 1;
- }
- // --- 情况 C: 数据校验成功 (result == 1) ---
- NbRun.get_patch_time_out = 0; // 重置 OTA 超时计数
- uint16_t afn = (NbAppFrame.data[1] << 8) | NbAppFrame.data[0];
- uint16_t data_len = (NbAppFrame.len[1] << 8) | NbAppFrame.len[0];
- // 更新当前 AFN 状态,用于后续多包交互(如 OTA)
- if (afn != 0x51)
- { // 数据包通常不改变 cur_afn,除非是第一个包
- NbRun.cur_afn = afn;
- }
- int8_t ret = 0;
- uint8_t need_reply = 0; // 标记是否需要发送应用层回复
- uint8_t update_status = 0;
- #ifdef DEBUG_NB
- LOG("Rec OK, AFN=0x%04X, Len=%d\r\n", afn, data_len);
- #endif
- // --- 业务逻辑分发 ---
- switch (afn)
- {
- case 0x20: // Set IP/Port
- if (data_len != 16)
- return 1;
- ret = set_server_ip_port_para((SERVER_IP_PORT_DEF *)&NbAppFrame.data[4]);
- nb_set_ip_para_ack();
- need_reply = 1;
- break;
- case 0x21: // Set Regular Report
- if (data_len != 9)
- return 1;
- {
- REGULAR_REPORT_DEF dat;
- dat.report_base_hour = NbAppFrame.data[4];
- dat.report_base_min = NbAppFrame.data[5];
- dat.report_base_sec = NbAppFrame.data[6];
- dat.report_interval = NbAppFrame.data[7] + 256 * NbAppFrame.data[8];
- ret = set_regular_report_para(&dat);
- }
- nb_set_regular_report_para_ack(ret == 0 ? 1 : ret);
- need_reply = 1;
- break;
- case 0x22: // Set DMA Report
- if (data_len != 11)
- return 1;
- {
- DMA_REGULAR_REPORT_DEF dat;
- dat.dma_report_start_hour = NbAppFrame.data[4];
- dat.dma_report_start_min = NbAppFrame.data[5];
- dat.dma_report_start_sec = NbAppFrame.data[6];
- dat.dma_report_end_hour = NbAppFrame.data[7];
- dat.dma_report_end_min = NbAppFrame.data[8];
- dat.dma_report_end_sec = NbAppFrame.data[9];
- dat.dma_interval = NbAppFrame.data[10];
- ret = set_dma_regular_report_para(&dat);
- }
- nb_set_dma_report_para_ack(ret == 0 ? 1 : ret);
- need_reply = 1;
- break;
- case 0x23: // Set RTC
- if (data_len != 11)
- return 1;
- {
- tm_t tm;
- // tm.year = ((NbAppFrame.data[4] << 8) | NbAppFrame.data[5]) % 2000;
- tm.year = NbAppFrame.data[5];
- tm.month = NbAppFrame.data[6];
- tm.day = NbAppFrame.data[7];
- tm.hour = NbAppFrame.data[8];
- tm.min = NbAppFrame.data[9];
- tm.sec = NbAppFrame.data[10];
- ret = SetRtcTime(&tm);
- }
- save_cur_flow_flag = 1;
- nb_set_rtc_data_ack(ret);
- need_reply = 1;
- break;
- case 0x24: // Set Flow Alarm
- if (data_len != 18)
- return 1;
- {
- FLOW_ALARM_PARA_DEF flow_alarm_para;
- flow_alarm_para.large_flow_alarm_thres = (NbAppFrame.data[7] << 24) | (NbAppFrame.data[6] << 16) | (NbAppFrame.data[5] << 8) | NbAppFrame.data[4];
- flow_alarm_para.large_flow_cnti_moni_time = (NbAppFrame.data[9] << 8) | NbAppFrame.data[8];
- flow_alarm_para.cnti_flow_cnti_moni_time = (NbAppFrame.data[11] << 8) | NbAppFrame.data[10];
- flow_alarm_para.leak_flow_alarm_thres = (NbAppFrame.data[15] << 24) | (NbAppFrame.data[14] << 16) | (NbAppFrame.data[13] << 8) | NbAppFrame.data[12];
- flow_alarm_para.leak_flow_cnti_moni_time = (NbAppFrame.data[17] << 8) | NbAppFrame.data[16];
- ret = set_flow_alarm_para(&flow_alarm_para);
- }
- nb_set_flow_alarm_para_ack(ret == 0 ? 1 : ret);
- need_reply = 1;
- break;
- case 0x25: // Set Press Alarm
- if (data_len != 6)
- return 1;
- ret = set_press_alarm_para((PRESS_ALARM_PARA_DEF *)&NbAppFrame.data[4]);
- nb_set_pressure_alarm_para_ack(ret == 0 ? 1 : ret);
- need_reply = 1;
- break;
- case 0x26: // Set Temp Alarm
- if (data_len != 8)
- return 1;
- ret = set_temp_alarm_para((TEMP_ALARM_PARA_DEF *)&NbAppFrame.data[4]);
- nb_set_temp_alarm_para_ack(ret == 0 ? 1 : ret);
- need_reply = 1;
- break;
- case 0x27: // Set Settlement Day
- if (data_len != 5)
- return 1;
- ret = set_settlement_day_para((SETTLEMENT_DAY_DEF *)&NbAppFrame.data[4]);
- nb_set_settlment_day_para_ack(ret == 0 ? 1 : ret);
- need_reply = 1;
- break;
- case 0x28: // Set Bottom Data
- if (data_len != 12)
- return 1;
- ret = set_meter_bottom_data((METER_BOTTOM_DEF *)&NbAppFrame.data[4]);
- nb_set_meter_bottom_data_ack(ret == 0 ? 1 : ret);
- need_reply = 1;
- break;
- case 0x30: // Read Month Record
- nb_read_month_record_ack();
- need_reply = 1;
- break;
- case 0x32: // Read Day Record
- nb_read_day_record_ack();
- need_reply = 1;
- break;
- case 0x34: // Read Hour Record
- // 注意:nb_read_hour_record_ack 内部已经完成了所有分包发送和 AT 交互
- ret = nb_read_hour_record_ack();
- if (ret == -1)
- {
- LOG("Read Hour Err\r\n");
- return -1; // 严重错误,退出上传会话
- }
- // 内部已处理完毕,不需要再执行底部的通用回复逻辑
- return 0;
- case 0x36: // Read 5Min Record
- ret = nb_read_5min_record_ack();
- if (ret == -1)
- {
- LOG("Read 5Min Err\r\n");
- return -1;
- }
- // 内部已处理完毕
- return 0;
- case 0x38: // Read Log
- nb_read_log_record_ack();
- need_reply = 1;
- break;
- case 0x40: // Close Link
- LOG("Close Link\r\n");
- return 2; // 特殊返回码,指示关闭链接
- case 0x50: // OTA Start
- if (data_len != 22)
- return 1;
- ret = nb_set_patch_info();
- if (ret != 1)
- {
- nb_set_patch_info_ack(ret);
- need_reply = 1;
- }
- else
- {
- NbRun.mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- nb_set_patch_info_ack(0x10); // Request first package
- need_reply = 1;
- }
- NbRun.get_patch_retry_cnt = 0;
- break;
- case 0x51: // OTA Data Package
- // 检查数据长度是否匹配预期
- if (data_len != (8 + PatchInfo.per_packet_len))
- {
- update_status = 0x20; // Resend request
- }
- else
- {
- DIFF_PACKET_DEF *dat = (DIFF_PACKET_DEF *)&NbAppFrame.data[4];
- ret = write_diff_patch_to_flash(dat);
- if (ret == 1)
- { // Success
- NbRun.get_patch_retry_cnt = 0;
- if (PatchInfo.update_status == 1)
- {
- update_status = 0x10; // Request next
- }
- else
- {
- update_status = 1; // Finish
- }
- }
- else
- {
- update_status = ret; // Error code
- }
- }
- // 重试计数逻辑
- if (update_status == 0x10 || update_status == 1)
- {
- NbRun.get_patch_retry_cnt = 0;
- }
- else
- {
- NbRun.get_patch_retry_cnt++;
- }
- if (NbRun.get_patch_retry_cnt > 20)
- {
- update_status = 3; // Fail
- }
- if (update_status <= 3)
- {
- NbRun.cur_afn = 0; // Reset AFN after handling packet
- }
- nb_set_patch_info_ack(update_status);
- need_reply = 1;
- if (update_status >= 1 && update_status <= 6)
- {
- // OTA finished or failed, will return 2 later
- }
- break;
- default:
- LOG("Unknown AFN: 0x%04X\r\n", afn);
- return 1; // Ignore unknown, wait for next
- }
- // --- 发送应用层回复 ---
- if (need_reply == 1)
- {
- uint16_t len = ((NbAppFrame.len[1] << 8) | NbAppFrame.len[0]) + 16;
- nb_send_data_route((uint8_t *)&NbAppFrame, len);
- // 发送 AT 指令并将数据发往网络
- ret = at_cmd_send(55, (char *)NbRun.tx_buf, NB_AT_ACK, 6, 5);
- if (ret == -1)
- {
- return -1; // Send failed
- }
- // 如果是 OTA 结束状态,返回 2 以退出循环
- if (afn == 0x51 && (update_status >= 1 && update_status <= 6))
- {
- return 2;
- }
- return 0; // Success
- }
- return 1; // Should not reach here if logic is correct
- }
- void rtc_add_secs(TIME_DEF *dest, rtc_run_t *src, unsigned short secs)
- {
- unsigned short dat;
- // dat=secs;
- dest->second = (src->second + dat) % 60;
- dat = (src->second + dat) / 60;
- dest->minute = (src->minute + dat) % 60;
- dat = (src->minute + dat) / 60;
- dest->hour = (dat + src->hour) % 24;
- }
- int8_t connected_flag;
- 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; // 不允许休眠
- nb_power_on(0);
- rt_thread_mdelay(2000);
- do
- {
- npos = 0;
- if (at_cmd_send(npos++, NB_AT, NB_AT_ACK, 10, 2) == -1)
- break; //
- if (at_cmd_send(npos++, NB_ATE0, NB_ATE0_ACK, 3, 2) == -1) // 关闭回显
- break;
- /////////////设置频段//////////////////////////
- if (Paramx.nb_band_flag != 0)
- {
- // if (at_cmd_send(npos++, "AT+QCFG=\"band\",0,0x10,0,1\r\n", NB_AT_ACK, 3, 5) == -1)
- // break;
- if (at_cmd_send(npos++, "AT+QCFG=\"band\",0,0x008800D5,0,1\r\n", NB_AT_ACK, 3, 5) == -1)
- break;
- set_nb_band();
- 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();
- if (at_cmd_send(npos++, NB_CIMI, NB_AT_ACK, 3, 2) == -1)
- break;
- get_nb_imsi_code();
- if (at_cmd_send(npos++, NB_NCCID, NB_NCCID_ACK, 3, 2) == -1) // different from BC28
- break;
- get_nb_ccid_code();
- } while (0);
- nb_power_off();
- //////////////////////////////////////////////////////////////////
- // 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
- 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)
- {
- NbRun.upload.flag = 0;
- NbRun.upload.mode = 0; // 本次上传结束后清零
- LOG("no service upload!\r\n");
- continue;
- }
- G_NB_CAN_DEEP_SLEEP = 0; // 不允许休眠
- nb_power_on(0);
- rt_thread_mdelay(1000);
- do
- {
- if (at_cmd_send(npos++, NB_AT, NB_AT_ACK, 10, 2) == -1) // at测试
- 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)
- break;
- nb_power_on(3);
- rt_thread_mdelay(500);
- if (NbRun.get_imei_flag == 0) // 读取imei号
- { // 读取IMEI号
- if (at_cmd_send(npos++, NB_CGSN, NB_CGSN_ACK, 3, 2) == -1)
- break;
- get_nb_imei_code();
- }
- npos = 5;
- if (at_cmd_send(npos++, NB_CMEE1, NB_CMEE_ACK, 3, 2) == -1) // 错误上报方式 BC800需要
- break;
- retry_time = 0;
- vflag = 1;
- while (at_cmd_send(npos, "AT+CPIN?\r\n", "+CPIN: READY", 3, 3) == -1)
- {
- retry_time++;
- if (retry_time > 3)
- {
- 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);
- }
- 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();
- }
- 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++;
- 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;
- break;
- }
- else if (retry_time != 0) // 首次进入不复位
- {
- 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);
- }
- 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域附着
- break;
- // retry_time = 0;
- if (at_cmd_send(npos + 4, NB_CGATT_QUERY, NB_CGATT_QUERY_ACK, 20, 2) == -1)
- { // 查询附着状态
- retry_time++; // 重试次数
- continue; // 重新注册
- }
- vflag = 1;
- break;
- }
- npos += 5;
- 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有
- {
- if (at_cmd_send(npos++, "AT+QENG=\"servingcell\"\r\n", "+QENG: \"servingcell\"", 3, 2) == -1)
- {
- vflag = 0;
- break;
- }
- if (get_nb_signal(NbRun.rx_buf, NbRun.rx_idx) == 1)
- break;
- rt_thread_mdelay(1000);
- }
- if (vflag == 0)
- break;
- vflag = 0;
- if (at_cmd_send(npos++, "AT+QICSGP=1,1,\"CTNET\",\"\",\"\",1\r\n", NB_AT_ACK, 3, 2) == -1) // 配置场景
- break;
- if (at_cmd_send(npos++, "AT+QIACT=1\r\n", NB_AT_ACK, 3, 3) == -1) // 激活场景
- break;
- if (at_cmd_send(npos++, "AT+QIACT?\r\n", "+QIACT: 1,1", 3, 3) == -1) // 查询场景激活状态
- break;
- #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)
- {
- save_datetime_from_at(NbRun.rx_buf, NbRun.rx_idx);
- LOG("get net time!\t\n");
- }
- }
- #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)
- {
- vflag &= 0x0f;
- do
- {
- #ifdef APP_DEBUG_PRINT
- LOG("main service upload\r\n");
- #endif
- vflag = 0;
- sprintf(ncdp_str, "AT+QIOPEN=1,0,\"TCP\",\"%d.%d.%d.%d\",%d,0,0\r\n", // 倒数第二个0:本地ip自动 最后一个0: 缓存模式
- Paramx.main_server_ip[0],
- 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
- }
- npos += 3;
- ////////////////////////////备用连接/////////////////////////////////////////////////////
- if (((upload_dat.rept_addr & BIT1) != 0 || NbRun.upload.mode != NB_UPLOAD_REPT) && check_sub_service_flag() == 1)
- {
- vflag &= 0x0f;
- do
- {
- #ifdef APP_DEBUG_PRINT
- LOG("sub service upload\r\n");
- #endif
- sprintf(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
- }
- } while (0); // 主循环
- // NB_RUN_UPDATE_FLAG = 0;
- nb_power_off();
- if (vflag & 0x80)
- LOG("no service upload!\r\n");
- else if ((vflag & 3) != 0)
- {
- if ((vflag & BIT0) != 0)
- LOG("MAIN upload ok!\r\n");
- if ((vflag & BIT1) != 0)
- LOG("SUB upload ok!\r\n");
- }
- else if (vflag == 0)
- LOG("upload fail\r\n");
- if ((vflag & 3) != 3 && vflag != 0x80) // 有失败的情况
- { // 上报失败,补报判别
- if (NbRun.upload.mode & ~(NB_UPLOAD_REPT | NB_UPLOAD_DMA | NB_UPLOAD_MANUAL))
- { // 除补报,DMA,手动上报之外,其他需要补报
- upload_dat.rept_runflag = ((~vflag) & 0x3); // 补报
- upload_dat.rept_addr = upload_dat.rept_runflag;
- rtc_run_t *rr;
- get_rtc_run(&rr);
- tm_t ntm;
- ntm.year = rr->year;
- ntm.month = rr->month;
- ntm.day = rr->day;
- ntm.hour = rr->hour;
- ntm.min = rr->minute;
- ntm.sec = rr->second;
- time_add_secs(&upload_dat.rept_time, &ntm, 3600);
- }
- }
- // NbRun.void_load_timout = NB_VOID_UPLOAD_TIME;//这段时间不能上报60s
- NbRun.upload.flag = 0;
- NbRun.upload.mode = 0; // 本次上传结束后清零
- } // while(1)
- }
- /////////////添加上报过程中动态显示信号/////////////////////
- ////////////////////发送at指令并等待处理接收数据//////////////////////////////////////////////////////
- // stat:当前所在流程位置,和每个指令一一对应
- // cmd_str:at指令字符串
- // ack:要求本次回复的字符串
- // retry_time: 重试次数
- // time_out: 超时时间 秒单位
- // 成功:返回0 失败返回-1
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- int8_t at_cmd_send(uint8_t stat, char *cmd_str, char *ack, uint16_t retry_time, uint8_t time_out)
- {
- uint16_t retry = retry_time;
- uint16_t time_cnt;
- int8_t ret = 0;
- NbRun.cur_state = stat;
- NbRun.ack = ack;
- if (time_out > 250)
- time_out = 250; // 最大不超过25秒
- time_cnt = time_out * 10;
- ////////////
- // retry=250;
- //////////////
- // LOG("nbstat=%d\r\n",stat);
- while (retry--)
- {
- NbClrRxBuf();
- time_cnt = time_out * 10;
- nb_tx_str(cmd_str);
- while (--time_cnt)
- {
- if (Nb_rx_data() == 1)
- {
- // if (stat > COAP_CGATT_QUERY && stat < COAP_WAIT_REG)//EC800 不再需要了
- // {
- // if (memstr_exist(NbRun.rx_buf, NbRun.rx_idx, "+QLWEVTIND:3", 12) == 1)
- // {
- // connected_flag = 1;
- // }
- // }
- //////////////////////////////////////////////
- ret = Nb_check_rec_valid(stat, ack);
- if (ret == 1)
- {
- LOG(".");
- return 0;
- } // 收到正确的回复}
- else if (ret == -1)
- break;
- // else if(ret == 0)continue;
- }
- rt_thread_mdelay(NB_REC_DELAY_TICK); // 等100ms
- }
- if (time_cnt == 0)
- { // 超时未收到数据
- continue;
- }
- if (Nb_check_rec_valid(stat, ack) == TRUE)
- { // 检查是否收到正确回复
- return 0;
- }
- }
- return -1;
- }
- int8_t at_cmd_send2(uint8_t stat, char *cmd_str, char *ack1, char *ack2, uint16_t retry_time, uint8_t time_out)
- {
- uint16_t retry = retry_time;
- uint16_t time_cnt;
- int8_t ret1, ret2;
- NbRun.cur_state = stat;
- NbRun.ack = ack1;
- if (time_out > 250)
- time_out = 250; // 最大不超过25秒
- time_cnt = time_out * 10;
- ////////////
- // retry=250;
- //////////////
- // LOG("nbstat=%d\r\n",stat);
- while (retry--)
- {
- NbClrRxBuf();
- time_cnt = time_out * 10;
- nb_tx_str(cmd_str);
- while (--time_cnt)
- {
- if (Nb_rx_data() == 1)
- {
- ret1 = Nb_check_rec_valid(stat, ack1);
- if (ret1 == 1)
- {
- LOG(".");
- return 0;
- } // 收到正确的回复}
- ret2 = Nb_check_rec_valid(stat, ack2);
- if (ret2 == 1)
- {
- LOG(".");
- return 0;
- } // 收到正确的回复
- if (ret1 == -1 || ret2 == -1)
- break;
- // else if(ret == 0)continue;
- }
- rt_thread_mdelay(NB_REC_DELAY_TICK); // 等100ms
- }
- if (time_cnt == 0)
- { // 超时未收到数据
- continue;
- }
- if (Nb_check_rec_valid(stat, ack1) == TRUE)
- { // 检查是否收到正确回复
- return 0;
- }
- if (Nb_check_rec_valid(stat, ack2) == TRUE)
- { // 检查是否收到正确回复
- return 0;
- }
- }
- return -1;
- }
- static void BuildDataReportMeter(rtc_run_t *rr, uint8_t *data)
- {
- rtc_run_t *max_fr_rr;
- // total positive water
- uint32_t temp = (uint32_t)(FwCumFlow * 0.0001 + 0.5); // unit: 0.01m^3
- data[0] = (uint8_t)temp;
- data[1] = (uint8_t)(temp >> 8);
- data[2] = (uint8_t)(temp >> 16);
- data[3] = (uint8_t)(temp >> 24);
- // total reverse water
- temp = (uint32_t)(BwCumFlow * 0.0001 + 0.5); // unit: 0.01m^3
- data[4] = (uint8_t)temp;
- data[5] = (uint8_t)(temp >> 8);
- data[6] = (uint8_t)(temp >> 16);
- data[7] = (uint8_t)(temp >> 24);
- // Daily maximum flow rate
- temp = (uint32_t)(get_max_flow_rate() * 1000); // 3位小数点
- #ifdef DEBUG_NB
- // temp = 12345;
- #endif
- data[8] = (uint8_t)(temp);
- data[9] = (uint8_t)(temp >> 8);
- data[10] = (uint8_t)(temp >> 16);
- data[11] = (uint8_t)(temp >> 24);
- // Daily maximum flow rate time
- get_max_flow_rate_time(&max_fr_rr);
- if (max_fr_rr == NULL || max_fr_rr->year == 0 || max_fr_rr->month == 0 || max_fr_rr->day == 0)
- memset(&data[12], 0, 7);
- else
- {
- data[12] = 0x14;
- data[13] = max_fr_rr->year;
- data[14] = max_fr_rr->month;
- data[15] = max_fr_rr->day;
- data[16] = max_fr_rr->hour;
- 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;
- #endif
- // water temperature
- if (WaterTemp > 100.0f || WaterTemp < 0.0f)
- temp = -1;
- else
- temp = (uint32_t)(WaterTemp * 10 + 0.5);
- #ifdef DEBUG_NB
- // temp = -300;
- #endif
- data[19] = (uint8_t)(temp);
- data[20] = (uint8_t)(temp >> 8);
- // water pressure
- if (Paramx.pressure_sensor == 1)
- {
- data[21] = (uint8_t)(WaterPressure * 100);
- }
- else
- data[21] = 0x00; // 无压力传感器,修改为0
- #ifdef DEBUG_NB
- // data[21]=213;
- #endif
- // battery voltage unit: 0.1V
- /* if (McuVbat > McuVTxbat)
- { // 判断哪个电池低就上传哪个数据
- temp = McuVTxbat / 100;
- }
- else
- temp = McuVbat / 100;
- */
- temp = McuVbat / 100; // wxl2026-6-2
- data[22] = (unsigned char)temp;
- data[23] = 0x14;
- data[24] = rr->year;
- data[25] = rr->month;
- data[26] = rr->day;
- data[27] = rr->hour;
- data[28] = rr->minute;
- data[29] = rr->second;
- }
- static void BuildDataReportParam(uint8_t *data)
- {
- Param_t *param;
- Nb_Run_t *nb_run;
- GetParam(¶m);
- GetNbRun(&nb_run);
- // version
- data[0] = 'V';
- data[1] = VER_TYPE;
- data[2] = VER_OPERATOR;
- data[3] = VER_MODULE;
- data[4] = VER_FIRMWARE;
- // diameter
- data[5] = (unsigned char)(param->diameter);
- data[6] = (unsigned char)(param->diameter >> 8);
- // channel number
- data[7] = param->chan_num;
- // main server ip
- data[8] = param->main_server_ip[0];
- data[9] = param->main_server_ip[1];
- data[10] = param->main_server_ip[2];
- data[11] = param->main_server_ip[3];
- // main server port
- data[12] = (unsigned char)(param->main_server_port);
- data[13] = (unsigned char)(param->main_server_port >> 8);
- // sub server ip
- data[14] = param->sub_server_ip[0];
- data[15] = param->sub_server_ip[1];
- data[16] = param->sub_server_ip[2];
- data[17] = param->sub_server_ip[3];
- // sub server port
- data[18] = (unsigned char)(param->sub_server_port);
- data[19] = (unsigned char)(param->sub_server_port >> 8);
- // report base time
- data[20] = param->report_base_hour;
- data[21] = param->report_base_min;
- data[22] = param->report_base_sec;
- // report interval minutes
- data[23] = (unsigned char)(param->report_interval);
- data[24] = (unsigned char)(param->report_interval >> 8);
- // DMA report start time
- data[25] = param->dma_report_start[0];
- data[26] = param->dma_report_start[1];
- data[27] = param->dma_report_start[2];
- // DMA report end time
- data[28] = param->dma_report_end[0];
- data[29] = param->dma_report_end[1];
- data[30] = param->dma_report_end[2];
- // DMA report interval time
- data[31] = param->dma_interval;
- // settlement day
- data[32] = param->settlement_day;
- // high temperature alarm threshold
- data[33] = (unsigned char)(param->high_temp_alarm_thres);
- data[34] = (unsigned char)(param->high_temp_alarm_thres >> 8);
- // low temperature alarm threshold
- data[35] = (unsigned char)(param->low_temp_alarm_thres);
- data[36] = (unsigned char)(param->low_temp_alarm_thres >> 8);
- // large flow alarm threshold
- data[37] = (unsigned char)(param->large_flow_alarm_thres);
- data[38] = (unsigned char)(param->large_flow_alarm_thres >> 8);
- data[39] = (unsigned char)(param->large_flow_alarm_thres >> 16);
- data[40] = (unsigned char)(param->large_flow_alarm_thres >> 24);
- // large flow continue monitor time
- data[41] = (unsigned char)(param->large_flow_cnti_moni_time);
- data[42] = (unsigned char)(param->large_flow_cnti_moni_time >> 8);
- // continue flow continue monitor time
- data[43] = (unsigned char)(param->cnti_flow_cnti_moni_time);
- data[44] = (unsigned char)(param->cnti_flow_cnti_moni_time >> 8);
- // leak flow alarm threshold
- data[45] = (unsigned char)(param->leak_flow_alarm_thres);
- data[46] = (unsigned char)(param->leak_flow_alarm_thres >> 8);
- data[47] = (unsigned char)(param->leak_flow_alarm_thres >> 16);
- data[48] = (unsigned char)(param->leak_flow_alarm_thres >> 24);
- // leak flow continue monitor time
- data[49] = (unsigned char)(param->leak_flow_cnti_moni_time);
- data[50] = (unsigned char)(param->leak_flow_cnti_moni_time >> 8);
- // high press alarm threshold
- data[51] = (unsigned char)(param->high_press_alarm_thres);
- // low press alarm threshold
- data[52] = (unsigned char)(param->low_press_alarm_thres);
- // pressure sensor
- data[53] = param->pressure_sensor;
- }
- static void BuildDataReportNb(uint8_t *data)
- {
- Nb_Run_t *nb_run;
- char tmp[3];
- uint16_t i;
- GetNbRun(&nb_run);
- // IMEI len = 8
- if (strlen(nb_run->imei) == 15)
- {
- tmp[0] = '0';
- tmp[1] = nb_run->imei[0];
- tmp[2] = 0;
- StrToHexBuf((char *)&data[0], tmp, 2);
- StrToHexBuf((char *)&data[1], &(nb_run->imei[1]), 14);
- }
- else
- {
- StrToHexBuf((char *)&data[0], tmp, 16);
- }
- // cell id in AT+NUESTATS response
- data[8] = (unsigned char)(nb_run->bts_id);
- data[9] = (unsigned char)(nb_run->bts_id >> 8);
- data[10] = (unsigned char)(nb_run->bts_id >> 16);
- data[11] = (unsigned char)(nb_run->bts_id >> 24);
- // physical cell id
- data[12] = (unsigned char)(nb_run->physical_cell_id);
- data[13] = (unsigned char)(nb_run->physical_cell_id >> 8);
- // rsrp
- data[14] = (unsigned char)(nb_run->rsrp_bak);
- data[15] = (unsigned char)(nb_run->rsrp_bak >> 8);
- // snr
- data[16] = (unsigned char)(nb_run->snr);
- data[17] = (unsigned char)(nb_run->snr >> 8);
- // csq
- data[18] = nb_run->rssi;
- // iccid len = 10
- for (i = 0; i < 10; i++)
- { // 这里是不是错了
- data[19 + i] = (unsigned char)(((nb_run->ccid[2 * i] - '0') << 4) | (nb_run->ccid[2 * i + 1] - '0'));
- }
- }
- static void BuildMonthRecord(rtc_run_t *rr, uint8_t *data)
- {
- uint32_t date = ((rr->year << 16) | (rr->month << 8));
- uint16_t i;
- bill_t bill;
- uint8_t vflag;
- for (i = 0; i < 2; i++)
- {
- date = prev_month(date);
- vflag = read_month_bill((uint8_t)(date >> 16), (uint8_t)(date >> 8), &bill);
- if (vflag != 0)
- continue; // no data
- if (bill.date[0] != (uint8_t)(date >> 16) || bill.date[1] != (uint8_t)(date >> 8))
- continue; // 不是当月数据
- data[i * 11] = 0x14;
- data[i * 11 + 1] = bill.date[0];
- data[i * 11 + 2] = bill.date[1];
- data[i * 11] = 0x14;
- data[i * 11 + 1] = bill.date[0];
- data[i * 11 + 2] = bill.date[1];
- data[i * 11 + 3] = (unsigned char)(bill.fw_used);
- data[i * 11 + 4] = (unsigned char)(bill.fw_used >> 8);
- data[i * 11 + 5] = (unsigned char)(bill.fw_used >> 16);
- data[i * 11 + 6] = (unsigned char)(bill.fw_used >> 24);
- data[i * 11 + 7] = (unsigned char)(bill.bw_used);
- data[i * 11 + 8] = (unsigned char)(bill.bw_used >> 8);
- data[i * 11 + 9] = (unsigned char)(bill.bw_used >> 16);
- data[i * 11 + 10] = (unsigned char)(bill.bw_used >> 24);
- }
- }
- static void BuildDayRecord(rtc_run_t *rr, uint8_t *data)
- {
- uint16_t i;
- bill_t bill;
- uint32_t date = ((rr->year << 16) | (rr->month << 8) | rr->day);
- uint8_t vflag;
- for (i = 0; i < 5; i++)
- {
- date = prev_day(date);
- vflag = read_day_bill((uint8_t)(date >> 8), (uint8_t)date, &bill);
- if (vflag != 0)
- continue; // no data
- if (bill.date[0] != (uint8_t)(date >> 16) || bill.date[1] != (uint8_t)(date >> 8) || bill.date[2] != (uint8_t)date)
- continue; // 不是当天的数据
- data[i * 12] = 0x14;
- data[i * 12 + 1] = bill.date[0];
- data[i * 12 + 2] = bill.date[1];
- data[i * 12 + 3] = bill.date[2];
- data[i * 12 + 4] = (unsigned char)(bill.fw_used);
- data[i * 12 + 5] = (unsigned char)(bill.fw_used >> 8);
- data[i * 12 + 6] = (unsigned char)(bill.fw_used >> 16);
- data[i * 12 + 7] = (unsigned char)(bill.fw_used >> 24);
- data[i * 12 + 8] = (unsigned char)(bill.bw_used);
- data[i * 12 + 9] = (unsigned char)(bill.bw_used >> 8);
- data[i * 12 + 10] = (unsigned char)(bill.bw_used >> 16);
- data[i * 12 + 11] = (unsigned char)(bill.bw_used >> 24);
- }
- }
- static void BuildHourRecord(rtc_run_t *rr, uint8_t *data)
- {
- uint8_t i;
- hour_bill_t bill;
- uint8_t vflag;
- uint32_t date = ((rr->year << 16) | (rr->month << 8) | rr->day);
- date = prev_day(date);
- data[0] = 0x14;
- data[1] = (unsigned char)(date >> 16);
- data[2] = (unsigned char)(date >> 8);
- data[3] = (unsigned char)(date);
- for (i = 0; i < 24; i++)
- {
- vflag = read_hour_bill((uint8_t)date, i, &bill);
- if (vflag != 0) // 数据不合法,放弃
- continue;
- if ((bill.date[0] != data[1]) || (bill.date[1] != data[2]) || (bill.date[2] != data[3]))
- {
- continue;
- } // 不是当前日期数据,丢弃
- 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;
- memcpy(&data[4 + 168 + i * 3], bill.flow_rate, 3);
- }
- }
- void NbBuildDataReport(void)
- {
- rtc_run_t *rr;
- Nb_Run_t *nb_run;
- uint16_t data_len = 448;
- uint32_t *err_no;
- // current date time
- get_rtc_run(&rr);
- GetNbRun(&nb_run);
- NbBuildDataHeader(data_len);
- // AFN
- NbAppFrame.data[0] = 0x10;
- NbAppFrame.data[1] = 0x00;
- // MID
- NbAppFrame.data[2] = 0x00;
- NbAppFrame.data[3] = 0x00;
- // DC
- // report trigger mode
- NbAppFrame.data[4] = nb_run->upload.mode;
- BuildDataReportMeter(rr, &NbAppFrame.data[5]); // meter part len 30
- BuildDataReportParam(&NbAppFrame.data[35]); // param part len 54
- BuildDataReportNb(&NbAppFrame.data[89]); // nb part len 29
- BuildMonthRecord(rr, &NbAppFrame.data[118]); // month record part len 22
- BuildDayRecord(rr, &NbAppFrame.data[140]); // day record part len 60
- BuildHourRecord(rr, &NbAppFrame.data[200]); // day record part len 244
- // error no
- all_alarm_status(&err_no);
- //(*err_no) &= 0xffff0fff;
- NbAppFrame.data[444] = (uint8_t)(*err_no);
- NbAppFrame.data[445] = (uint8_t)(*err_no >> 8);
- NbAppFrame.data[446] = (uint8_t)(*err_no >> 16);
- NbAppFrame.data[447] = (uint8_t)(*err_no >> 24);
- NbBuildDataTail(data_len);
- }
- void nb_set_para_rept(uint16_t dat_len, uint16_t afn, int8_t ret)
- {
- // uint16_t data_len = 5;
- // uint16_t mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- NbBuildDataHeader(dat_len);
- // AFN
- NbAppFrame.data[0] = (uint8_t)afn;
- NbAppFrame.data[1] = (uint8_t)(afn >> 8);
- // MID
- // NbAppFrame.data[2] = (uint8_t)(mid);
- // NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- NbAppFrame.data[4] = ret; // set success
- NbBuildDataTail(dat_len);
- }
- void NbBuildReportMonthRecord(void)
- {
- uint16_t data_len = 202;
- uint16_t mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- uint8_t ret;
- // rtc_run_t *rr;
- // get_rtc_run(&rr);
- NbBuildDataHeader(data_len);
- // AFN
- NbAppFrame.data[0] = 0x31;
- NbAppFrame.data[1] = 0x00;
- // MID
- NbAppFrame.data[2] = (uint8_t)(mid);
- NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- uint8_t *data = &NbAppFrame.data[4];
- get_18month_record_data(data);
- NbBuildDataTail(data_len);
- }
- void NbBuildReportDayRecord(void)
- {
- uint16_t data_len = 364;
- uint16_t mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- uint8_t ret;
- NbBuildDataHeader(data_len);
- // AFN
- NbAppFrame.data[0] = 0x33;
- NbAppFrame.data[1] = 0x00;
- // MID
- NbAppFrame.data[2] = (uint8_t)(mid);
- NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- uint8_t *data = &NbAppFrame.data[4];
- get_30day_record_data(data);
- NbBuildDataTail(data_len);
- }
- void NbBuildReportHourRecord(uint8_t year, uint8_t month, uint8_t day)
- {
- uint16_t data_len = 248;
- uint16_t mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- // rtc_run_t *rr;
- // get_rtc_run(&rr);
- NbBuildDataHeader(data_len);
- // AFN
- NbAppFrame.data[0] = 0x35;
- NbAppFrame.data[1] = 0x00;
- // MID
- NbAppFrame.data[2] = (uint8_t)(mid);
- NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- uint8_t *data = &NbAppFrame.data[4];
- get_hour_record_data(year, month, day, data);
- NbBuildDataTail(data_len);
- }
- void NbBuildReport5MinRecord(tm_t *date)
- { // 年月日时分
- uint16_t data_len = 388;
- uint16_t mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- uint32_t i = 0;
- uint8_t ret;
- hour_bill_t bill;
- tm_t src;
- tm_t dest;
- NbBuildDataHeader(data_len);
- memset(NbAppFrame.data, 0, sizeof(NbAppFrame.data));
- // AFN
- NbAppFrame.data[0] = 0x37;
- NbAppFrame.data[1] = 0x00;
- // MID
- NbAppFrame.data[2] = (uint8_t)(mid);
- NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- uint8_t *data = &NbAppFrame.data[4];
- GET_5MIN_REOCORD_DEF mdate;
- mdate.start_time[0] = date->year;
- mdate.start_time[1] = date->month;
- mdate.start_time[2] = date->day;
- mdate.start_time[3] = date->hour;
- mdate.start_time[4] = date->min;
- mdate.start_time[5] = date->sec;
- time_add_secs(&dest, date, 2 * 3600);
- mdate.end_time[0] = dest.year;
- mdate.end_time[1] = dest.month;
- mdate.end_time[2] = dest.day;
- mdate.end_time[3] = dest.hour;
- mdate.end_time[4] = dest.min;
- mdate.end_time[5] = dest.sec;
- get_5min_record_data(&mdate, 0, data);
- NbBuildDataTail(data_len);
- }
- void NbBuildReportLogRecord(void)
- {
- uint16_t data_len = 394;
- uint16_t mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- uint8_t i;
- int8_t j;
- uint8_t num = 0;
- alarm_t alarm;
- uint8_t rec_len = 13;
- NbBuildDataHeader(data_len);
- // AFN
- NbAppFrame.data[0] = 0x39;
- NbAppFrame.data[1] = 0x00;
- // MID
- NbAppFrame.data[2] = (uint8_t)(mid);
- NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- uint8_t *data = &NbAppFrame.data[4];
- num = get_alarm_num();
- if (num > 30)
- {
- num = 30;
- }
- get_log_record(0, num, data);
- NbBuildDataTail(data_len);
- }
- void NbBuildGetPackage(void)
- {
- uint16_t data_len = 21;
- uint16_t mid = (NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- Param_t *param;
- NbBuildDataHeader(data_len);
- // AFN
- NbAppFrame.data[0] = 0x51;
- NbAppFrame.data[1] = 0x00;
- // MID
- NbAppFrame.data[2] = (uint8_t)(mid);
- NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- GetParam(¶m);
- uint8_t *data = &NbAppFrame.data[4];
- data[0] = 'V';
- data[1] = VER_TYPE;
- data[2] = VER_OPERATOR;
- data[3] = VER_MODULE;
- data[4] = VER_FIRMWARE;
- data[5] = 'V';
- data[6] = VER_TYPE;
- data[7] = VER_OPERATOR;
- data[8] = VER_MODULE;
- data[9] = VER_FIRMWARE + 1;
- data[10] = (uint8_t)(PatchInfo.per_packet_len);
- data[11] = (uint8_t)(PatchInfo.per_packet_len >> 8);
- data[12] = (uint8_t)(PatchInfo.cur_num);
- data[13] = (uint8_t)(PatchInfo.cur_num >> 8);
- data[14] = (uint8_t)(PatchInfo.packet_crc);
- data[15] = (uint8_t)(PatchInfo.packet_crc >> 8);
- data[16] = 1;
- NbBuildDataTail(data_len);
- }
- void NbBuildReportUpdateStatus(int8_t stat)
- {
- uint16_t data_len = 5;
- uint16_t mid = NbRun.mid; //(NbAppFrame.data[3] << 8) | NbAppFrame.data[2];
- Param_t *param;
- NbBuildDataHeader(data_len);
- // AFN
- NbAppFrame.data[0] = 0x52;
- NbAppFrame.data[1] = 0x00;
- // MID
- NbAppFrame.data[2] = (uint8_t)(mid);
- NbAppFrame.data[3] = (uint8_t)(mid >> 8);
- NbAppFrame.data[4] = stat;
- NbBuildDataTail(data_len);
- }
- #ifdef DEBUG_LOG_WARM
- void Debug_log(void)
- {
- // #ifdef DEBUG_NB
- uint8_t i;
- for (i = 0; i < 32; i++)
- {
- write_alarm(i / 2, i % 2, i * 10 + 10);
- }
- // #endif
- }
- #endif
- #ifdef APP_DEBUG_PRINT
- static char str[50];
- char *get_upload_type_str(uint8_t type)
- {
- char cnt = 0;
- memset(str, 0, 50);
- if (type & 0x1)
- strcat(str, "manual,");
- if (type & 0x2)
- strcat(str, "regular,");
- if (type & 0x4)
- strcat(str, "rept,");
- if (type & 0x8)
- strcat(str, "settlement,");
- if (type & 0x10)
- strcat(str, "error,");
- if (type & 0x20)
- strcat(str, "dma");
- return str;
- }
- #endif
- uint8_t memstr_exist(uint8_t *hay, size_t hay_len, const char *sub, size_t sub_len)
- {
- if (sub_len == 0)
- return 1;
- if (sub_len > hay_len)
- return 0;
- for (size_t i = 0; i <= hay_len - sub_len; i++)
- {
- if (memcmp(hay + i, sub, sub_len) == 0)
- {
- return 1;
- }
- }
- return 0;
- }
- int8_t get_code(uint8_t *buf, const char *keyword, uint16_t dat_len, int16_t *ret)
- {
- char *pos;
- buf[dat_len] = 0;
- pos = strstr((char *)buf, keyword);
- if (pos == NULL)
- return -1;
- uint16_t dat = 0;
- uint16_t i;
- char vflag;
- pos = pos + strlen(keyword);
- vflag = 0;
- uint8_t flag = 0;
- if (*pos == '+' || *pos == '-')
- {
- if (*pos == '-')
- flag = 1;
- pos++;
- }
- while (*pos >= '0' && *pos <= '9')
- {
- dat *= 10;
- dat += *pos - '0';
- pos++;
- vflag = 1;
- }
- if (vflag == 0)
- return -1;
- if (flag == 1)
- dat = -dat;
- *ret = dat;
- return 1;
- }
- //+QNTP: 0,"2019/09/09,01:32:42+32"
- void save_datetime_from_at(uint8_t *buf, uint16_t dat_len)
- {
- tm_t tm;
- int16_t zone = 0;
- char *p;
- buf[dat_len] = 0; // 确保字符串终止
- p = strstr((char *)buf, "\""); // 定位到双引号开始处
- if (p == NULL)
- return;
- // 利用 sscanf 直接格式化提取年月日时分秒和时区
- // 格式: 2019/09/09,01:32:42+32
- if (sscanf(p + 1, "%hu/%hu/%hu,%u:%u:%u%hd",
- &tm.year, &tm.month, &tm.day,
- &tm.hour, &tm.min, &tm.sec, &zone) != 7)
- {
- return; // 解析失败或格式不匹配
- }
- // 合法性检查
- if (tm.year < 26 || tm.month == 0 || tm.month > 12 ||
- tm.day == 0 || tm.day > 31 || tm.hour > 23 || tm.min > 59 || tm.sec > 59)
- return;
- // 时区转换 (保留原逻辑:正负时区分别调用不同的时间计算函数)
- if (zone > 0)
- {
- time_add_secs(&tm, &tm, zone * 15 * 60);
- }
- else if (zone < 0) // 增加非零判断,避免对0进行无意义的减法
- {
- time_sub_secs(&tm, &tm, -zone * 15 * 60); // 传入正数
- }
- tm.year %= 100;
- SetRtcTime(&tm);
- save_cur_flow_flag = 1;
- }
- //+QENG: "servingcell","NOCONN","LTE","FDD",460,11,EA6CE03,77,100,1,5,5,EA15,-94,-8,-66,24,26
- // rsrp rwrq rssi sinr
- uint8_t get_nb_signal(uint8_t *buf, uint16_t dat_len)
- {
- // 确保数据包含预期的关键字
- if (buf == NULL || strstr((char *)buf, "+QENG: \"servingcell\"") == NULL)
- {
- return 0;
- }
- char temp[256] = {0};
- memcpy(temp, buf, sizeof(temp) - 1);
- char *token = NULL;
- char *tokens[20]; // 足足够容纳所有分割的子字符串
- int count = 0;
- // 使用 strtok 按逗号分割字符串
- token = strtok(temp, ",");
- while (token != NULL && count < 20)
- {
- tokens[count++] = token;
- token = strtok(NULL, ",");
- }
- // 根据您提供的格式,各字段在分割后的索引如下:
- // [0] +QENG: "servingcell"
- // [1] "NOCONN"
- // [2] "LTE"
- // [3] "FDD"
- // [4] 460
- // [5] 11
- // [6] 9C8C712 -> 基站id (需转为uint32_t)
- // [7] 119 -> 物理小区id
- // [8] 2452
- // [9] 5
- // [10] 3
- // [11] 3
- // [12] EA15
- // [13] -85 -> 参考信号接收功率
- // [14] -15 -> 参考信号接收质量
- // [15] -53 -> 接收信号强度指示
- // [16] 0 -> SINR (有效范围 -20~40)
- // 确保分割出的字段数量足够
- if (count > 16)
- {
- // 基站id是16进制字符串,使用 strtoul 转换为 32位无符号数
- NbRun.bts_id = (uint32_t)strtoul(tokens[6], NULL, 16);
- // 物理小区id是10进制数
- NbRun.physical_cell_id = (uint32_t)atoi(tokens[7]);
- // 参考信号接收功率
- NbRun.rsrp_bak = atoi(tokens[13]);
- // 参考信号接收质量
- NbRun.rsrq = atoi(tokens[14]);
- // 接收信号强度指示
- NbRun.rssi = atoi(tokens[15]);
- // SINR
- NbRun.snr = atoi(tokens[16]);
- return 1;
- }
- return 0;
- }
- uint8_t check_sub_service_flag(void)
- {
- uint8_t vflag;
- vflag = 1;
- if (Paramx.main_server_ip[0] == Paramx.sub_server_ip[0] && Paramx.main_server_ip[1] == Paramx.sub_server_ip[1] && Paramx.main_server_ip[2] == Paramx.sub_server_ip[2] && Paramx.main_server_ip[3] == Paramx.sub_server_ip[3] && Paramx.main_server_port == Paramx.sub_server_port)
- {
- vflag = 0;
- } // 主从ip相同,端口号相同
- if (Paramx.sub_server_ip[0] == 0 || Paramx.sub_server_port == 0) // 从ip为空,端口号为空
- {
- vflag = 0;
- }
- return vflag;
- }
- uint8_t check_main_service_flag(void)
- {
- uint8_t vflag;
- vflag = 1;
- if (Paramx.main_server_ip[0] == 0 || Paramx.main_server_port == 0) // 从ip为空,端口号为空
- {
- vflag = 0;
- }
- return vflag;
- }
|