| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784 |
- #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"
- 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;
- 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--) // 查询无线信号强度 BC800有
- {
- 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;
- 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");
- }
- }
- 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 = 50; // 12秒
- NbRun.cur_afn = 0;
- //////////////////////////////////////
- while (retry_time--)
- {
- ret = rec_data_check();
- rt_thread_mdelay(100);
- if (ret == 0)
- retry_time = 150; // 判断接收数据是否合法,以及读取协议层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 = 50; // 12秒
- NbRun.cur_afn = 0;
- //////////////////////////////////////
- while (retry_time--)
- {
- ret = rec_data_check();
- rt_thread_mdelay(100);
- if (ret == 0)
- retry_time = 50; // 判断接收数据是否合法,以及读取协议层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] = 0x00;
- data[11] = 0x00;
- // 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);
- data[15] = (unsigned char)(nb_run->rsrp >> 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);
- }
- //+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)
- {
- char temp[8];
- char *p;
- int8_t index1 = 0, index2 = 0;
- int16_t *out_val = NULL;
- uint8_t ret = 0;
- buf[dat_len] = 0; // 确保终止位
- p = strstr((char *)buf, "servingcell");
- if (p == NULL)
- return 0;
- index1 = strnchar(p, ',', 12);
- // 依次提取 rsrp_bak, rsrq, rssi, snr
- for (uint8_t i = 0; i < 4; i++)
- {
- if (index1 == -1)
- break; // 上一次查找失败,直接退出
- index2 = strnchar(p, ',', 13 + i);
- if (index2 != -1 && index1 < index2)
- {
- memset(temp, 0, sizeof(temp));
- memcpy(temp, p + index1 + 1, index2 - index1 - 1);
- int16_t val = atoi(temp);
- switch (i)
- {
- case 0:
- NbRun.rsrp_bak = val;
- break;
- case 1:
- NbRun.rsrq = val;
- break;
- case 2:
- NbRun.rssi = val;
- ret = 1;
- break;
- }
- }
- index1 = index2; // 将当前的右边界作为下一次的左边界
- }
- return ret;
- }
- 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;
- }
|