123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292 |
- /******************************************************************
- ** Copyright (c) 2009 Wuhan Mozit Technology Co., Ltd .
- ** FileName: core.c
- ** Author: BigHead
- ** Mail: jsrenyw@icloud.com
- ** Editor: bighead
- ** Date: 2020-11-10 13:34
- ** Version: 2020-11-10
- ** File Description: 业务逻辑核心代码实现部分
- ******************************************************************/
- #include "core.h"
- #include "cmd.h"
- //指令发送表device_command:
- #define CTR_RRS 1 //远程重启
- #define CTR_SFR 2 //设备恢复出厂设置
- #define CTR_RS 3 //服务器跳转
- #define CTR_OTA 4 //ota升级
- #define CTR_RDC 5 //远程手动调光
- #define CTR_RSC 6 //远程开关控制 需回复
- #define CTR_RCN 7 //删除子节点指令 需回复
- #define CFG_BKS 8 //备份服务器配置 需回复
- #define CFG_ULI 9 //设备数据上传间隔配置 需回复
- #define CFG_STS 10 //开关时间段设置 需回复
- #define CFG_SRV 11 //额定电压设置 需回复
- #define CFG_SRC 12 //额定电流设置 需回复
- #define CFG_NAT 13 //下发节点信息表配置
- #define CFG_GNV 14 //获取子节点版本号
- #define CFG_SCM 15 //开关控制模式(拉合闸)设置 需回复
- #define CFG_DGS 16 //调光节点分组设置
- #define CFG_DGM 17 //调光节点分组数据修改
- #define CFG_MGM 18 //电表节点分组设置 需回复
- #define CFG_SAT 19 //传感器报警阀值设置 需回复
- #define CTR_RGC 20 //远程开关编组控制 需回复
- //继电器状态:
- #define SW_ON 0 //0x0000:继电器合闸
- #define SW_MANUAL_CONTROL 32 //0x0020:继电器远程拉闸
- #define SW_TIMER_CONTROL 16 //0x0010: 继电器自动时间段拉闸
- #define SW_TEMPERATURE_HUMIDITY_ALARM 513 //0x0201:继电器温湿度报警拉闸 需报警
- #define SW_FIRE_ALARM 514 //0x0202:继电器烟感报警拉闸 需报警
- #define SW_TILT_ALARM 515 //0x0203:继电器倾斜报警拉闸 需报警
- #define SW_LOCK_ALARM 516 //0x0204:继电器锁具报警拉闸 需报警
- #define SW_LINE_TEMPERATURE_ALARM 517 //0x0205:继电器线温报警拉闸 需报警
- #define SW_OVERVOLTAGE 1 //0x0001:过压拉闸 需报警
- #define SW_UNDERVOLTAGE 2 //0x0002:欠压拉闸 需报警
- #define SW_OVERLOAD_ALARM 4 //0x0004: 过载拉闸 需报警
- #define SW_ELECTRIC_EXCESS 8 //0x0008:用电超额拉闸
- #define SW_OVER_SWITCH_OUT_COUNT 64 //0x0040:超自动合闸次数
- #define SW_FAST_CURRENT 128 //0x0080:快速电流拉闸
- int sw[] = {513,514,515,516,517,1,2,4};
- typedef enum {false = 0,true =1} bool;
- static pthread_t threads[32];
- #define CRC32_POLYNOMIAL 0xEDB88320
- list_node* file_list = NULL; //文件链表
- list_node* user_list = NULL; //设备链表
- int have_table = 0;
- static uint32_t crc_table32[256]; //CRC查询表
- unsigned short ota_file_packet_len = 1024;//ota文件每包的数据长度
- //按照大端模式解析数据
- //将1个整型数据填充到缓存中
- #define INT_TO_BUFF(buff, pos, val) \
- buff[(pos)] = (val)&0x000000FF; \
- buff[(pos) + 1] = ((val)&0x0000FF00) >> 8; \
- buff[(pos) + 2] = ((val)&0x00FF0000) >> 16; \
- buff[(pos) + 3] = ((val)&0xFF000000) >> 24
- //从缓存中提取1个整型数据
- #define INT_FROM_BUFF(buff, pos) ((buff[(pos) + 3] << 24) + (buff[(pos) + 2] << 16) + (buff[(pos) + 1] << 8) + buff[(pos)])
- //从缓存中提取1个整型数据
- #define SHORT_FROM_BUFF(buff, pos) ((buff[(pos) + 1] << 8) + buff[(pos)])
- /******************************************************************
- * Function Name: db_init
- * Arguments:
- * Return Value: void
- * Date: 2020-11-10
- * Editor: bighead
- * Description: 程序启动时刻,调用该初始化函数多次,初始化不同mysql 连接
- ******************************************************************/
- int db_init(MYSQL *db)
- {
- int ret = 1;
- if (db)
- {
- MYSQL *_db = db;
- ret = mysqlConnetInit(_db) ? 1 : 0;
- }
- else
- {
- elog("MYSQL.var is NULL \n ");
- exit(0);
- }
- return ret;
- }
- /******************************************************************
- * Function Name: core_init
- * Arguments:
- * Return Value: void
- * Date: 2020-11-10
- * Editor: bighead
- * Description: 程序启动时刻,调用该初始化函数仅 一次,该函数不允许重复调用
- ******************************************************************/
- int core_init(void)
- {
- int ret = 0;
- // 加载Topic服务配置
- initTopicConf();
- //创建队列
- //m_pque = CreateQueue(1000);
- // init mqtt.client
- init_mqtt_client();
- sleep(1);
-
- // 注册Topic
- regTopicFromTable();
- //创建处理任务队列线程
- //if(NUM_THREADS_UPLOAD_g>0)
- // CreateDbHandThread();
- return ret;
- }
- /******************************************************************
- * Function Name: core_heart
- * Arguments:
- * Return Value: void
- * Date: 2020-11-10
- * Editor: bighead
- * Description: 每次主线程心跳调用, 约200ms一次, 可以调整频率在decode.c
- ******************************************************************/
- int core_heart(unsigned int nowTime)
- {
- int ret=0;
- ret=nowTime;
- return ret;
- }
- /******************************************************************
- * Function Name: core_heart_1s
- * Arguments:
- * Return Value: void
- * Date: 2020-11-10
- * Editor: bighead
- * Description: 每次主线程心跳调用, 约1s一次,不超过2s, 在core_heart心跳函数之后调用
- * 可以调整频率在decode.c
- ******************************************************************/
- int core_heart_1s(unsigned int nowTime)
- {
- int ret = 0;
- ret = nowTime;
- //时间同步广播
- ret = TimeSyncBroadcast();
- //从数据库取指令
- SendCmdFromDb();
- return ret;
- }
- //初始化时候进行部分测试,可以随意添加
- int core_do_test(void)
- {
- //decode_msg_handle("TEST", NULL, NULL);
- print_stats();
- return 0;
- }
- //定期调用会话统计信息, 分钟级别
- int core_stats(void)
- {
- print_stats();
- return 0;
- }
- /******************************************************************
- * Function Name: core_alarm_gateway
- * Arguments:
- * Return Value: void
- * Date: 2023-12-5
- * Editor: cc
- * Description: 扫描网关设备数据
- ******************************************************************/
- int CoreAlarmGateway(void)
- {
- static MYSQL *conn = NULL;
- MYSQL_RES* res = NULL;
- MYSQL_ROW row;
- char query[1024] = {0};
- int row_count;
- if (!conn)
- {
- // 先申请内存再初始化
- conn = malloc(sizeof(MYSQL));
- db_init(conn);
- }
- sprintf(query,"SELECT t1.device_mac,t1.gateway_mac,t2.device_name,t2.control_mode,t1.update_time,"
- "t1.current_on_off,t1.current_electric,t1.original_relay,t2.swith_time1,t2.swith_time2,t2.swith_time3,t2.swith_time4,"
- "t2.electric_wave_set,t2.electric_wave_min,t2.electric_wave_max,t1.command_update_time "
- "FROM dev_status AS t1 "
- "INNER JOIN dev_info_gateway AS t2 "
- "ON t1.device_mac = t2.device_mac "
- "WHERE TIMESTAMPDIFF(MINUTE, t1.update_time, NOW()) < 10 "
- "AND t1.current_online=1 "
- "AND t1.original_relay IS NOT NULL "
- "AND t1.current_electric IS NOT NULL "
- "AND t1.electric_update_flag=1 "
- "AND t1.alarm_enable=1 ");
- excuteSql(conn,query);
- res = mysql_store_result(conn);
- if (NULL == res)
- {
- debug("NULL == res \n");
- return 1;
- }
- //获取行数
- row_count = mysql_num_rows(res);
- if(row_count<1)
- {
- mysql_free_result(res);
- debug("row_count<1 查询记录为0\n");
- return 1;
- }
- debug("CoreAlarmGateway row_count:%d \r\n",row_count);
- //循环取出
- while((row = mysql_fetch_row(res)))
- {
- char device_mac[30] = {0}; //0节点
- char gateway_mac[30] = {0}; //1网关
- char device_name[256] = {0}; //2设备名称
- int control_mode = 0; //3控制模式
- char update_time[20]; //4更新时间
- int current_on_off = 0; //5开关状态
- int current_electric = 0; //6电流
- int original_relay = 0; //7原始开关值
- char switch_time1[10] = {0}; //8开关时间1
- char switch_time2[10] = {0}; //9开关时间2
- char switch_time3[10] = {0}; //10开关时间3
- char switch_time4[10] = {0}; //11开关时间4
- int electric_wave_set = 0; //12电流波峰值
- double electric_wave_min = 0.0; //13电流波峰值
- double electric_wave_max = 0.0; //14电流波峰值
- char command_update_time[20]; //15指令更新时间
- struct tm tm_time;
- struct tm tm_time2;
- char timeString[20];
- int result,result1,result2,result3,result4;
- char update_sql[100]={0};
- char strTemp[256] ={0};
- //取出数据
- strcpy(device_mac,row[0]);
- strcpy(gateway_mac,row[1]);
- strcpy(device_name,row[2]);
- control_mode = atoi(row[3]);
- strptime(row[4], "%Y-%m-%d %H:%M:%S", &tm_time);
- strftime(update_time, sizeof(update_time), "%Y-%m-%d %H:%M:%S", &tm_time);
- current_on_off = atoi(row[5]);
- current_electric = atoi(row[6]);
- original_relay = atoi(row[7]);
- if(row[8]) strcpy(switch_time1,row[8]);
- if(row[9]) strcpy(switch_time2,row[9]);
- if(row[10]) strcpy(switch_time3,row[10]);
- if(row[11]) strcpy(switch_time4,row[11]);
- if(row[12]) electric_wave_set = atoi(row[12]);
- if(row[13]) electric_wave_min = atof(row[13]);
- if(row[14]) electric_wave_max = atof(row[14]);
- if(row[15]) strptime(row[15], "%Y-%m-%d %H:%M:%S", &tm_time2);
- strftime(command_update_time, sizeof(command_update_time), "%Y-%m-%d %H:%M:%S", &tm_time2);
-
- // log("CoreAlarmGateway : device_mac:'%s',gateway_mac:'%s',device_name:%s,control_mode:%d,update_time:%s,current_on_off:%d,"
- // "current_electric:%d,original_relay:%d,switch_time1:%s,switch_time2:%s,switch_time3:%s,switch_time4:%s,"
- // "electric_wave_set:%d,electric_wave_min:%f,electric_wave_max:%f \n",
- // device_mac,gateway_mac,device_name,control_mode,update_time,current_on_off,current_electric,original_relay,
- // switch_time1,switch_time2,switch_time3,switch_time4,electric_wave_set,electric_wave_min,electric_wave_max);
- //更新数据取出标记
- sprintf(update_sql,"update dev_status set electric_update_flag=2 where device_mac='%s' and gateway_mac='%s' ",device_mac,gateway_mac);
- excuteSql(conn,update_sql);
- //判断继电器数据,有报警跳过后续判断
- result = RelayAlarm(gateway_mac,"0F0000000001",original_relay,conn);
- if(result==0) continue;
- //判断更新的数据是否在指令下发的2minute内
- if(row[15])
- {
- tm_time2.tm_min +=2; //将指令更新时间加2分钟
- mktime(&tm_time2);//重新计算时间
- int result = compareModifiedTimes(tm_time2,tm_time);
- if(result>=0)//指令更新时间在2分钟内跳过后续判断
- {
- debug("网关:%s,compareModifiedTimes tm_time2>=tm_time ------------>skip\n",device_name);
- continue;
- }
- }
- strftime(timeString, sizeof(timeString), "%H:%M", &tm_time);
- //判断是否在时间段点的2min以内
- if(compareWithUpdateTime(timeString,switch_time1,switch_time2,switch_time3,switch_time4)) continue;
- if(!row[8] && !row[9]) continue;
- debug("timeString:%s \n",timeString);
- //判断自动模式
- if(control_mode==0)
- {
- int isInTime1 = 0;
- int isInTime2 = 0;
- if(row[8]&&row[9]&&(strlen(switch_time1)>4)&&(strlen(switch_time2)>4))//第1个时间段不为空
- {
- debug("网关:%s,strlen(switch_time1)=%zu,strlen(switch_time2)=%zu\n",device_name,strlen(switch_time1),strlen(switch_time2));
- result1 = compareTimes(switch_time1,timeString);
- result2 = compareTimes(timeString,switch_time2);
- //时间正常顺序
- if(compareTimes(switch_time1,switch_time2)<=0)
- {
- debug("网关:%s,时间正常顺序,compareTimes switch_time1<=switch_time2\n",device_name);
- //合闸时间段
- if (result1<=0 && result2<=0) isInTime1=1;
- }
- //时间非正常顺序
- else
- {
- debug("网关:%s,时间非正常顺序,compareTimes switch_time1>=switch_time2\n",device_name);
- //合闸时间段
- if (result1<=0 || result2<=0) isInTime1=1;
- }
- }
- else //第1个时间段为空
- {
- isInTime1=2;
- }
- if(row[10]&&row[11]&&(strlen(switch_time3)>4)&&(strlen(switch_time4)>4))//第2个时间段不为空
- {
- debug("网关:%s,strlen(switch_time3)=%zu,strlen(switch_time4)=%zu\n",device_name,strlen(switch_time3),strlen(switch_time4));
- result3 = compareTimes(switch_time3,timeString);
- result4 = compareTimes(timeString,switch_time4);
- //时间正常顺序
- if(compareTimes(switch_time3,switch_time4)<=0)
- {
- debug("网关:%s,时间正常顺序,compareTimes switch_time3<=switch_time4\n",device_name);
- //合闸时间段
- if (result3<=0 && result4<=0) isInTime2=1;
- }
- //时间非正常顺序
- else
- {
- debug("网关:%s,时间非正常顺序,compareTimes switch_time3>=switch_time4\n",device_name);
- //合闸时间段
- if (result3<=0 || result4<=0) isInTime2=1;
- }
- }
- else //第1个时间段为空
- {
- isInTime2=2;
- }
- if((isInTime1==1||isInTime2==1) && current_on_off==0)
- {
- debug("网关:%s,合闸时间段继电器拉闸 \n",device_name);
- int ret=ElectricAlarm(gateway_mac,"0F0000000001",device_name,device_name,1101,"合闸时间段继电器拉闸",conn);
- if(ret==0) continue;
- }
- else if((isInTime1==0||isInTime2==0) && current_on_off==1)
- {
- debug("网关:%s,拉闸时间段继电器合闸 \n",device_name);
- int ret=ElectricAlarm(gateway_mac,"0F0000000001",device_name,device_name,1102,"拉闸时间段继电器合闸",conn);
- if(ret==0) continue;
- }
- }
- //判断继电器拉闸状态有电流
- if(current_on_off==0 && current_electric>100)
- {
- debug("网关:%s,继电器拉闸状态有电流 \n",device_name);
- int ret=ElectricAlarm(gateway_mac,"0F0000000001",device_name,device_name,1103,"继电器拉闸状态有电流",conn);
- if(ret==0) continue;
- }
- //判断继电器合闸状态无电流
- if(current_on_off==1 && current_electric<100)
- {
- debug("网关:%s,继电器合闸状态无电流 \n",device_name);
- int ret=ElectricAlarm(gateway_mac,"0F0000000001",device_name,device_name,1104,"继电器合闸状态无电流",conn);
- if(ret==0) continue;
- }
- //判断继电器合闸状态电流偏离正常阈值
- if(current_on_off==1 && electric_wave_set==3)
- {
- double fcurrent_electric = current_electric/10000.0;
- if(fcurrent_electric<(electric_wave_min*0.9)|| fcurrent_electric>(electric_wave_max*1.1))
- {
- debug("网关:%s,继电器合闸状态电流偏离正常值 \n",device_name);
- sprintf(strTemp,"继电器合闸状态电流偏离正常值,当前值:%.3f,阈值:%.3f-%.3f",fcurrent_electric,electric_wave_min,electric_wave_max);
- int ret=ElectricAlarm(gateway_mac,"0F0000000001",device_name,device_name,1105,strTemp,conn);
- if(ret==0) continue;
- }
- }
- }
- mysql_free_result(res);
-
- return 0;
- }
- /******************************************************************
- * Function Name: CoreAlarmNode
- * Arguments:
- * Return Value: void
- * Date: 2023-12-8
- * Editor: cc
- * Description: 扫描节点设备数据
- ******************************************************************/
- int CoreAlarmNode(void)
- {
- static MYSQL *conn2 = NULL;
- MYSQL_RES* res = NULL;
- MYSQL_ROW row;
- char query[1024] = {0};
- int row_count;
- if (!conn2)
- {
- // 先申请内存再初始化
- conn2 = malloc(sizeof(MYSQL));
- db_init(conn2);
- }
- sprintf(query,"SELECT t1.device_mac,t1.gateway_mac,t3.device_name,t2.device_name,t2.control_mode,t1.update_time,t1.current_on_off,t1.current_electric,"
- "t1.original_relay,t2.swith_time1,t2.swith_time2,t2.swith_time3,t2.swith_time4,t2.electric_wave_set,t2.electric_wave_min,t2.electric_wave_max,t1.command_update_time "
- "FROM dev_status AS t1 "
- "INNER JOIN dev_info_node AS t2 "
- "ON t1.device_mac = t2.device_mac "
- "AND t1.gateway_mac=t2.gateway_mac "
- "INNER JOIN dev_info_gateway AS t3 "
- "ON t2.gateway_mac = t3.device_mac "
- "WHERE TIMESTAMPDIFF(MINUTE, t1.update_time, NOW()) < 10 "
- "AND t1.current_online=1 "
- "AND t1.original_relay IS NOT NULL "
- "AND t1.current_electric IS NOT NULL "
- "AND t1.electric_update_flag=1 "
- "AND t1.alarm_enable=1 ");
- excuteSql(conn2,query);
- res = mysql_store_result(conn2);
- if (NULL == res)
- {
- debug("NULL == res \n");
- return 1;
- }
- //获取行数
- row_count = mysql_num_rows(res);
- if(row_count<1)
- {
- mysql_free_result(res);
- debug("row_count<1 查询记录为0 \n");
- return 1;
- }
- debug("CoreAlarmNode row_count:%d \r\n",row_count);
- //循环取出
- while((row = mysql_fetch_row(res)))
- {
- char device_mac[30] = {0}; //0节点
- char gateway_mac[30] = {0}; //1网关
- char gateway_name[256] = {0}; //2设备名称
- char node_name[256] = {0}; //3节点名称
- int control_mode = 0; //4控制模式
- char update_time[20]; //5更新时间
- int current_on_off = 0; //6开关状态
- int current_electric = 0; //7电流
- int original_relay = 0; //8原始开关值
- char switch_time1[10] = {0}; //9开关时间1
- char switch_time2[10] = {0}; //10开关时间2
- char switch_time3[10] = {0}; //11开关时间3
- char switch_time4[10] = {0}; //12开关时间4
- int electric_wave_set = 0; //13电流波峰值
- double electric_wave_min = 0.0; //14电流波峰值
- double electric_wave_max = 0.0; //15电流波峰值
- struct tm tm_time;
- struct tm tm_time2;
- char timeString[20];
- int result,result1,result2,result3,result4;
- char update_sql[100]={0};
- char strTemp[256] ={0};
- //取出数据
- strcpy(device_mac,row[0]);
- strcpy(gateway_mac,row[1]);
- strcpy(gateway_name,row[2]);
- strcpy(node_name,row[3]);
- control_mode = atoi(row[4]);
- strptime(row[5], "%Y-%m-%d %H:%M:%S", &tm_time);
- strftime(update_time, sizeof(update_time), "%Y-%m-%d %H:%M:%S", &tm_time);
- current_on_off = atoi(row[6]);
- current_electric = atoi(row[7]);
- original_relay = atoi(row[8]);
- if(row[9]) strcpy(switch_time1,row[9]);
- if(row[10]) strcpy(switch_time2,row[10]);
- if(row[11]) strcpy(switch_time3,row[11]);
- if(row[12]) strcpy(switch_time4,row[12]);
- if(row[13]) electric_wave_set = atoi(row[13]);
- if(row[14]) electric_wave_min = atof(row[14]);
- if(row[15]) electric_wave_max = atof(row[15]);
- if(row[16]) strptime(row[15], "%Y-%m-%d %H:%M:%S", &tm_time2);
-
- // log("CoreAlarmNode : device_mac:'%s',gateway_mac:'%s',gateway_name:%s,node_name:%s,control_mode:%d,update_time:%s,current_on_off:%d,"
- // "current_electric:%d,original_relay:%d,switch_time1:%s,switch_time2:%s,switch_time3:%s,switch_time4:%s,"
- // "electric_wave_set:%d,electric_wave_min:%f,electric_wave_max:%f \n",
- // device_mac,gateway_mac,gateway_name,node_name,control_mode,update_time,current_on_off,current_electric,original_relay,
- // switch_time1,switch_time2,switch_time3,switch_time4,electric_wave_set,electric_wave_min,electric_wave_max);
- //更新数据取出标记
- sprintf(update_sql,"update dev_status set electric_update_flag=2 where device_mac='%s' and gateway_mac='%s' ",device_mac,gateway_mac);
- excuteSql(conn2,update_sql);
- //判断继电器数据
- result = RelayAlarm(gateway_mac,device_mac,original_relay,conn2);
- if(result==0) continue;
- //判断更新的数据是否在指令下发的2minute内
- if(row[16])
- {
- tm_time2.tm_min +=2; //将指令更新时间加2分钟
- mktime(&tm_time2);//重新计算时间
- int result = compareModifiedTimes(tm_time2,tm_time);
- if(result>=0)//指令更新时间在2分钟内跳过后续判断
- {
- debug("网关:%s,节点:%s,compareModifiedTimes tm_time2>=tm_time------------>skip\n",gateway_name,node_name);
- continue;
- }
- }
- strftime(timeString, sizeof(timeString), "%H:%M", &tm_time);
- //判断是否在时间段点的2min以内
- if(compareWithUpdateTime(timeString,switch_time1,switch_time2,switch_time3,switch_time4)) continue;
- if(!row[9] || !row[10] || !row[11] || !row[12]) continue;
- debug("timeString:%s \n",timeString);
- //判断自动模式
- if(control_mode==0)
- {
- int isInTime1 = 0;
- int isInTime2 = 0;
- if(row[9]&&row[10]&&(strlen(switch_time1)>4)&&(strlen(switch_time2)>4))//第1个时间段不为空
- {
- debug("网关:%s,节点:%s,strlen(switch_time1)=%zu,strlen(switch_time2)=%zu\n",gateway_name,node_name,strlen(switch_time1),strlen(switch_time2));
- result1 = compareTimes(switch_time1,timeString);
- result2 = compareTimes(timeString,switch_time2);
- //时间正常顺序
- if(compareTimes(switch_time1,switch_time2)<=0)
- {
- debug("网关:%s,节点:%s,compareTimes switch_time1<=switch_time2\n",gateway_name,node_name);
- //合闸时间段
- if (result1<=0 && result2<=0) isInTime1=1;
- }
- //时间非正常顺序
- else
- {
- debug("网关:%s,节点:%s,compareTimes switch_time1>=switch_time2\n",gateway_name,node_name);
- //合闸时间段
- if (result1<=0 || result2<=0) isInTime1=1;
- }
- }
- else //第1个时间段为空
- {
- isInTime1=2;
- }
- if(row[11]&&row[12]&&(strlen(switch_time3)>4)&&(strlen(switch_time4)>4))//第2个时间段不为空
- {
- debug("网关:%s,节点:%s,strlen(switch_time3)=%zu,strlen(switch_time4)=%zu\n",gateway_name,node_name,strlen(switch_time3),strlen(switch_time4));
- result3 = compareTimes(switch_time3,timeString);
- result4 = compareTimes(timeString,switch_time4);
- //时间正常顺序
- if(compareTimes(switch_time3,switch_time4)<=0)
- {
- debug("网关:%s,节点:%s,compareTimes switch_time3<=switch_time4\n",gateway_name,node_name);
- //合闸时间段
- if (result3<=0 && result4<=0) isInTime2=1;
- }
- //时间非正常顺序
- else
- {
- debug("网关:%s,节点:%s,compareTimes switch_time3>=switch_time4\n",gateway_name,node_name);
- //合闸时间段
- if (result3<=0 || result4<=0) isInTime2=1;
- }
- }
- else //第1个时间段为空
- {
- isInTime2=2;
- }
- if((isInTime1==1||isInTime2==1) && current_on_off==0)
- {
- debug("网关:%s,节点:%s,合闸时间段继电器拉闸 \n",gateway_name,node_name);
- int ret=ElectricAlarm(gateway_mac,device_mac,gateway_name,node_name,1101,"合闸时间段继电器拉闸",conn2);
- if(ret==0) continue;
- }
- else if((isInTime1==0||isInTime2==0) && current_on_off==1)
- {
- debug("网关:%s,节点:%s,拉闸时间段继电器合闸 \n",gateway_name,node_name);
- int ret=ElectricAlarm(gateway_mac,device_mac,gateway_name,node_name,1102,"拉闸时间段继电器合闸",conn2);
- if(ret==0) continue;
- }
-
- }
- //判断继电器拉闸状态有电流
- if(current_on_off==0 && current_electric>100)
- {
- debug("网关:%s,节点:%s,继电器拉闸状态有电流 \n",gateway_name,node_name);
- int ret=ElectricAlarm(gateway_mac,device_mac,gateway_name,node_name,1103,"继电器拉闸状态有电流",conn2);
- if(ret==0) continue;
- }
- //判断继电器合闸状态无电流
- if(current_on_off==1 && current_electric<100)
- {
- debug("网关:%s,节点:%s,继电器合闸状态无电流 \n",gateway_name,node_name);
- int ret=ElectricAlarm(gateway_mac,device_mac,gateway_name,node_name,1104,"继电器合闸状态无电流",conn2);
- if(ret==0) continue;
- }
- //判断继电器合闸状态电流偏离正常阈值
- if(current_on_off==1 && electric_wave_set==3)
- {
- double fcurrent_electric = current_electric/10000.0;
- if(fcurrent_electric<(electric_wave_min*0.9)|| fcurrent_electric>(electric_wave_max*1.1))
- {
- debug("网关:%s,节点:%s,继电器合闸状态电流偏离正常值 \n",gateway_name,node_name);
- sprintf(strTemp,"继电器合闸状态电流偏离正常值,当前值:%.3f,阈值:%.3f-%.3f",fcurrent_electric,electric_wave_min,electric_wave_max);
- int ret=ElectricAlarm(gateway_mac,device_mac,gateway_name,node_name,1105,strTemp,conn2);
- if(ret==0) continue;
- }
- }
- }
- mysql_free_result(res);
-
- return 0;
- }
- /******************************************************************
- * Function Name: ElectricAlarm
- * Arguments:
- * Return Value: void
- * Date: 2023-12-7
- * Editor: cc
- * Description: 电流数据告警判断
- ******************************************************************/
- int ElectricAlarm(char* mac,char* subMac,char* gatewayName,char* nodeName,int alarmCode,char* alarmStr,MYSQL* _db)
- {
- //判断是否需要报警
- MYSQL_RES* res = NULL;
- MYSQL_ROW row;
- char querySql[256] = {0};
- char strName[256] = {0};
- char strAlarm[512] = {0};
- char updateSql[1024] = {0};
- char insertSql[512] = {0};
- int queryRow = 0;
- int fault_state=0;
- int fault_count=0;
- struct tm tm_time;
- //网关或节点名称
- if (strcmp(subMac,"0F0000000001") == 0)//网关
- {
- sprintf(strName,"设备名称:%s",gatewayName);
- }
- else
- {
- sprintf(strName,"设备名称:%s,节点:%s",gatewayName,nodeName);
- }
- //格式化报警内容
- sprintf(strAlarm,"%s,%s,时间:%s \r\n",strName,alarmStr,GetCurrentTime());
-
- //查询当前报警类型是否正在报警 fault_state 1: 未处理 2: 故障正在处理中 3: 处理完成
- sprintf(querySql,"select fault_state,fault_count,fault_time from dev_fault where device_mac = '%s' and device_mac_node = '%s' and relay_code = %d ",mac,subMac,alarmCode);
- excuteSql(_db,querySql);
- res = mysql_store_result(_db);
- queryRow = mysql_num_rows(res);
- if (res && queryRow>0)//有记录
- {
- debug("res && queryRow>0 querySql:%s\n",querySql);
- row = mysql_fetch_row(res);
- fault_state = atoi(row[0]);
- fault_count = atoi(row[1]);
- if(row[2]) strptime(row[2], "%Y-%m-%d %H:%M:%S", &tm_time);
- debug("fault_state:%d fault_count:%d\n",fault_state,fault_count);
- if(fault_state == 1 || fault_state == 2)//正在报警
- {
- log("查询到当前报警类型正在报警,不再重复报警,alarmStr:%s\n",strAlarm);
- mysql_free_result(res);
- return 1;
- }
- if(alarmCode>1100)//电流报警进行3次判断
- {
- //在更新次数前检查是否是连续的告警次数,否则重新计数,通过检查上一次告警时间是否在5min以内
- if(row[2])
- {
- tm_time.tm_min +=5; //将指令更新时间加5分钟
- mktime(&tm_time);//重新计算时间
- int result=compareWithCurrentTime(tm_time);
- if(result>=0)//如果在5min以内
- {
- if(fault_count >= 2)//加上本次报警次数达到3次
- {
- //更新到报警故障表
- sprintf(updateSql,"update dev_fault set fault_details = '%s',fault_state = 1,fault_time = now(),fault_count=0 where "
- "device_mac = '%s' and device_mac_node = '%s' and relay_code = %d",strAlarm,mac,subMac,alarmCode);
- log("触发告警(电流): %s\n",strAlarm);
- }
- else
- {
- fault_count = fault_count + 1;
- //更新报警次数,并不报警
- sprintf(updateSql,"update dev_fault set fault_details = '%s',fault_state = 3,fault_time = now(),fault_count=%d where "
- "device_mac = '%s' and device_mac_node = '%s' and relay_code = %d",strAlarm,fault_count,mac,subMac,alarmCode);
- debug("网关:%s,节点:%s,电流告警更新次数(不报警)\n",gatewayName,nodeName);
- }
- }
- else//不在5min以内 计数重新开始
- {
- //更新到报警故障表
- sprintf(updateSql,"update dev_fault set fault_details = '%s',fault_state = 3,fault_time = now(),fault_count=1 where "
- "device_mac = '%s' and device_mac_node = '%s' and relay_code = %d",strAlarm,mac,subMac,alarmCode);
- debug("不在5min以内 计数重新开始(电流): %s\n",strAlarm);
- }
-
- }
- else //没有时间字段 计数重新开始
- {
- //更新到报警故障表
- sprintf(updateSql,"update dev_fault set fault_details = '%s',fault_state = 3,fault_time = now(),fault_count=1 where "
- "device_mac = '%s' and device_mac_node = '%s' and relay_code = %d",strAlarm,mac,subMac,alarmCode);
- debug("没有时间字段 计数重新开始(电流): %s\n",strAlarm);
- }
-
- }
- else
- {
- //更新到报警故障表
- sprintf(updateSql,"update dev_fault set fault_details = '%s',fault_state = 1,fault_time = now() where "
- "device_mac = '%s' and device_mac_node = '%s' and relay_code = %d",strAlarm,mac,subMac,alarmCode);
- log("触发告警: %s\n",strAlarm);
- }
- debug("updateSql: %s\n",updateSql);
- excuteSql(_db,updateSql);
- }
- else//没有查询到记录
- {
- debug("没有记录 querySql:%s",querySql);
- sprintf(insertSql,"insert into dev_fault(device_mac,device_mac_node,fault_details,relay_code,fault_state,fault_time)values('%s','%s','%s',%d,1,now())",
- mac,subMac,strAlarm,alarmCode);
- log("触发告警(插入): %s\n",strAlarm);
- excuteSql(_db,insertSql);
- }
- mysql_free_result(res);
- // //更新到报警故障表
- // sprintf(updateSql,"update dev_fault set fault_details = '%s',fault_state = 1,fault_time = now() where "
- // "device_mac = '%s' and device_mac_node = '%s' and relay_code = %d",strAlarm,mac,subMac,alarmCode);
- // excuteSql(_db,updateSql);
- // affectedRows = mysql_affected_rows(_db);
- // if (affectedRows < 1)
- // {
- // sprintf(insertSql,"insert into dev_fault(device_mac,device_mac_node,fault_details,relay_code,fault_state,fault_time)values('%s','%s','%s',%d,1,now())",
- // mac,subMac,strAlarm,alarmCode);
- // //log("strAlarm:%s\n",strAlarm);
- // excuteSql(_db,insertSql);
- // }
- return 0;
- }
- //扫描数据库发送指令
- int SendCmdFromDb(void)
- {
- static MYSQL *_db = NULL;
- MYSQL_RES* res = NULL;
- MYSQL_ROW row;
- char query[1024] = {0};
- char deleteSql[256] = {0};
- char updateSql[256] = {0};
- int row_count;
- if (!_db)
- {
- // 先申请内存再初始化
- _db = malloc(sizeof(MYSQL));
- db_init(_db);
- }
- sprintf(query,"select id,device_mac,device_mac_node,device_command,device_group,device_on_off,"
- "device_luminance,dimming_mode,node_type,control_mode from dev_cmd_send where device_mac is not null and current_online = 1 and device_type < 10");
- excuteSql(_db,query);
- res = mysql_store_result(_db);
- if (NULL == res)
- {
- return 1;
- }
- //获取行数
- row_count = mysql_num_rows(res);
- if(row_count<1)
- {
- //debug("%s 没有查询到指令 \n",mac);
- mysql_free_result(res);
- return 1;
- }
- //循环取出
- while((row = mysql_fetch_row(res)))
- {
- int id = 0;
- char device_mac[30] = {0}; //网关mac 1
- char device_mac_node[30] = {0}; //节点mac 2
- int device_command = 0; //指令类型 3
- int device_group = 0; //组号 4
- int device_on_off = 0; //开关 5
- int device_luminance = 0; //亮度 6
- int dimming_mode = 0; //调光类型 7
- int node_type = 0; //节点类型 8
- int control_mode = 0; //开关控制模式 9
- int ret = 0;
- if(row[0])
- id = atoi(row[0]);
- if(!row[1] || strlen((char*)row[1])!=24)
- {
- //删除指令
- sprintf(deleteSql,"delete from dev_cmd_send where id = %d",id);
- excuteSql(_db,deleteSql);
- debug("网关mac不正确!");
- continue;
- }
- strcpy(device_mac,row[1]);
- if(row[2])
- strcpy(device_mac_node,row[2]);
- if(row[3])
- device_command = atoi(row[3]);
- if(row[4])
- device_group = atoi(row[4]);
- if(row[5])
- device_on_off = atoi(row[5]);
-
- if(row[6])
- device_luminance = atoi(row[6]);
- if(row[7])
- dimming_mode = atoi(row[7]);
- if(row[8])
- node_type = atoi(row[8]);
- if(row[9])
- control_mode = atoi(row[9]);
-
- debug("SendCmdFromDb 行数:%d ,device_mac:'%s',device_mac_node:'%s',device_command:%d,device_group:%d,device_on_off:%d,"
- "device_luminance:%d,dimming_mode:%d,node_type:'%d',control_mode:%d \n",
- row_count,device_mac,device_mac_node,device_command,device_group,device_on_off,device_luminance,dimming_mode,node_type,control_mode);
- //删除指令
- sprintf(deleteSql,"delete from dev_cmd_send where id = %d",id);
- excuteSql(_db,deleteSql);
-
- switch (device_command)
- {
- case CTR_RRS: //远程重启
- {
- ret = SendRestart(device_mac);
- }
- break;
- case CTR_SFR: //设备恢复出厂设置
- {
- ret = SendFactoryReset(device_mac);
- }
- break;
- case CTR_RS: //服务器跳转
- {
- ret = SendServerJump(device_mac,_db);
- }
- break;
- case CTR_OTA: //ota升级
- {
- ret = SendRemoteUpgrade(device_mac,_db);
- }
- break;
- case CTR_RDC: //远程手动调光
- {
- if(row[4] && row[6]) //row[7] 调光类型判断暂去掉
- {
- ret = SendManualDimming(device_mac,device_group,device_luminance,dimming_mode);
- }
- }
- break;
- case CTR_RSC: //远程开关控制 需回复
- {
- if (row[2] && (strlen(device_mac_node) == 12) && row[5] && row[8]) //节点
- {
- ret = SendSwitchControl(device_mac,device_mac_node,node_type,device_on_off);
- sprintf(updateSql,"update dev_status set command_update_time = now() where gateway_mac = '%s' and device_mac='%s'",device_mac,device_mac_node);
- }
- else if(!row[2] && row[5] && row[8]) //网关
- {
- ret = SendSwitchControl(device_mac,"",node_type,device_on_off);
- sprintf(updateSql,"update dev_status set command_update_time = now() where gateway_mac = '%s' and device_mac='%s'",device_mac,device_mac);
- }
- if(ret == 0)
- {
- excuteSql(_db,updateSql);
- }
- }
- break;
- case CTR_RCN: //删除子节点指令 需回复
- {
- if(row[2] && (strlen(device_mac_node) == 12) && row[8])
- {
- ret = SendDeleteNode(device_mac,device_mac_node,node_type);
- }
- }
- break;
- case CFG_BKS: //备份服务器配置 需回复
- {
- ret = SendBakIP(device_mac,_db);
- }
- break;
- case CFG_ULI: //设备数据上传间隔配置 需回复
- {
- ret = SendDataInterval(device_mac,_db);
- }
- break;
- case CFG_STS: //开关时间段设置 需回复
- {
- if (row[2] && (strlen(device_mac_node) == 12)) //节点
- {
- ret = SendOnOffTimeMuilt(device_mac,device_mac_node,_db);
- sprintf(updateSql,"update dev_status set command_update_time = now() where gateway_mac = '%s' and device_mac='%s'",device_mac,device_mac_node);
- }
- else if(!row[2]) //网关
- {
- ret = SendOnOffTimeMuilt(device_mac,"",_db);
- sprintf(updateSql,"update dev_status set command_update_time = now() where gateway_mac = '%s' and device_mac='%s'",device_mac,device_mac);
- }
- if(ret == 0)
- {
- excuteSql(_db,updateSql);
- }
- }
- break;
- case CFG_SRV: //额定电压设置 需回复
- {
- if (row[2] && (strlen(device_mac_node) == 12)) //节点
- {
- ret = SendRatedVoltage(device_mac,device_mac_node,_db);
- }
- else if(!row[2]) //网关
- {
- ret = SendRatedVoltage(device_mac,"",_db);
- }
- }
- break;
- case CFG_SRC: //额定电流设置 需回复
- {
- if (row[2] && (strlen(device_mac_node) == 12)) //节点
- {
- ret = SendRatedCurrent(device_mac,device_mac_node,_db);
- }
- else if(!row[2]) //网关
- {
- ret = SendRatedCurrent(device_mac,"",_db);
- }
- }
- break;
- case CFG_NAT: //下发节点信息表配置
- {
- ret = SendSubInfo(device_mac,_db);
- }
- break;
- case CFG_GNV: //获取子节点版本号
- {
- if (row[2] && (strlen(device_mac_node) == 12)) //节点
- {
- ret = SendGetSubVersion(device_mac,device_mac_node);
- }
- }
- break;
- case CFG_SCM: //开关控制模式(拉合闸)设置 需回复
- {
- if (row[2] && (strlen(device_mac_node) == 12)) //节点
- {
- ret = SendSwitchModeFromDB(device_mac,device_mac_node,_db);
- }
- else if(!row[2]) //网关
- {
- ret = SendSwitchModeFromDB(device_mac,"",_db);
- }
- }
- break;
- case CFG_DGS: //调光节点分组设置
- {
- if (row[2] && (strlen(device_mac_node) == 12)) //节点
- {
- ret = SendDimmingNodeGroup(device_mac,device_mac_node,_db);
- }
- }
- break;
- case CFG_DGM: //调光节点分组数据修改
- {
- if(row[4])
- {
- ret = SendDimmingNodeGroupModify(device_mac,device_group,_db);
- }
- }
- break;
- case CFG_MGM: //电表节点分组设置 需回复
- {
-
- }
- break;
- case CFG_SAT: //传感器报警阀值设置 需回复
- {
- ret = SendSensorThreshold(device_mac,_db);
- }
- break;
- case CTR_RGC: //远程开关编组控制 需回复
- {
- if(row[4] && row[5])
- {
- ret = SendSwitchGroupControl(device_mac,device_group,2,device_on_off);
- }
- }
- break;
- default:
- debug("指令不能识别:%d",device_command);
- break;
- }
- }
- mysql_free_result(res);
- return 0;
- }
- //时间同步广播
- int TimeSyncBroadcast(void)
- {
- //TIME_SYNC_INTERVAL_g 配置文件读取
- if(timeGloble_g%TIME_SYNC_INTERVAL_g==0)
- {
- int ret = 0;
- ret = SendNTP("");
- debug("时间同步广播结果:%d,当前时间同步间隔 %d \n",ret,TIME_SYNC_INTERVAL_g);
- }
- return 0;
- }
- //1.字节流转换为十六进制字符串
- void ByteToHexStr(const unsigned char* source, char* dest, int sourceLen)
- {
- short i;
- unsigned char highByte, lowByte;
- for (i = 0; i < sourceLen; i++)
- {
- highByte = source[i] >> 4;
- lowByte = source[i] & 0x0f ;
- highByte += 0x30;
- if (highByte > 0x39)
- dest[i * 2] = highByte + 0x07;
- else
- dest[i * 2] = highByte;
- lowByte += 0x30;
- if (lowByte > 0x39)
- dest[i * 2 + 1] = lowByte + 0x07;
- else
- dest[i * 2 + 1] = lowByte;
- }
- return ;
- }
- //2.字节流转换为十六进制字符串
- void Hex2Str( const char *sSrc, char *sDest, int nSrcLen )
- {
- int i;
- char szTmp[3];
- for( i = 0; i < nSrcLen; i++ )
- {
- sprintf( szTmp, "%02X", (unsigned char) sSrc[i] );
- memcpy( &sDest[i * 2], szTmp, 2 );
- }
- return ;
- }
- //十六进制字符串转换为字节流
- void HexStrToByte(const char* source, unsigned char* dest, int sourceLen)
- {
- short i;
- unsigned char highByte, lowByte;
- for (i = 0; i < sourceLen; i += 2)
- {
- highByte = toupper(source[i]);
- lowByte = toupper(source[i + 1]);
- if (highByte > 0x39)
- highByte -= 0x37;
- else
- highByte -= 0x30;
- if (lowByte > 0x39)
- lowByte -= 0x37;
- else
- lowByte -= 0x30;
- dest[i / 2] = (highByte << 4) | lowByte;
- }
- return ;
- }
- //改变字节顺序
- void EndianSwap(unsigned char *pData, int startIndex, int length)
- {
- int i,cnt,end,start;
- cnt = length / 2;
- start = startIndex;
- end = startIndex + length - 1;
- unsigned char tmp;
- for (i = 0; i < cnt; i++)
- {
- tmp = pData[start+i];
- pData[start+i] = pData[end-i];
- pData[end-i] = tmp;
- }
- return ;
- }
- //获取当前月份历史表
- char* GetCurrentNYTable(void)
- {
- time_t t = time(0);
- static char str[64] = {0};
- strftime(str,sizeof(str),"dev_status_history_%Y%m",localtime(&t));
- return str;
- }
- //获取系统时间年月日 时分秒
- char* GetCurrentTime(void)
- {
- time_t t = time(0);
- static char str[64] = {0};
- strftime(str,sizeof(str),"%Y%m%d %H:%M:%S",localtime(&t));
- return str;
- }
- //字符串中查找指定字符的个数
- int find_char(char str[], char substr[])
- {
- int count = 0,i,j,check;
- int len = strlen(str);
- int sublen = strlen(substr);
- for(i = 0; i < len; i++)
- {
- check = 1;
- for(j = 0; j + i < len && j < sublen; j++)
- {
- if(str[i+j] != substr[j])
- {
- check = 0;
- break;
- }
- }
- if(check == 1)
- {
- count++;
- i = i + sublen;
- }
- }
- return count;
- }
- //从主题中查找指定'/'分割的段
- char* find_string(char* topicName, int section)
- {
- static char tmp[50][50];
- memset(tmp,0x0,2500);
- char* p1 = (char*)malloc(1024);
- int i = 0;
- while ((p1 = strchr(topicName, '/')) != NULL)
- {
- strncpy(tmp[i], topicName,strlen(topicName)-strlen(p1));
- topicName = p1 + 1;
- i++;
- }
- strncpy(tmp[i], topicName, strlen(topicName));
- free(p1);
- return tmp[section];
- }
- //判断是否属于报警code
- int IsRelayAlarmCode(int relayCode)
- {
- int i = 0;
- for(i = 0;i<(int)(sizeof(sw)/sizeof(int));i++)
- {
- if(relayCode == sw[i])
- return 1;
- }
- return -1;
- }
- //继电器报警
- int RelayAlarm(char* mac,char* subMac,int relayCode,MYSQL* _db)
- {
- MYSQL_RES* res = NULL;
- MYSQL_ROW row;
- char querySql[256] = {0};
- char updateSql[256] = {0};
- char insertSql[256] = {0};
- char strAlarm[256] = {0};
- bool isExist = false;
- char strAlarmType[256] = {0};
- char strName[256] = {0};
- char macName[256] = {0};
- char subMacName[256] = {0};
- int affectedRows = 0;
- int queryRow = 0;
- //判断是否需要报警
- int i = 0;
- for(i = 0;i<(int)(sizeof(sw)/sizeof(int));i++)
- {
- if(relayCode == sw[i])
- isExist = true;
- }
- if(!isExist)
- return 1;
- //查询当前报警类型是否正在报警 fault_state 1: 未处理 2: 故障正在处理中 3: 处理完成
- sprintf(querySql,"select * from dev_fault where device_mac = '%s' and device_mac_node = '%s' and relay_code = %d and (fault_state = 1 or fault_state = 2)",mac,subMac,relayCode);
- excuteSql(_db,querySql);
- res = mysql_store_result(_db);
- queryRow = mysql_num_rows(res);
- if (res && queryRow>0)
- {
- //debug("res && queryRow>0 querySql:%s",querySql);
- mysql_free_result(res);
- return 1;
- }
- mysql_free_result(res);
- //查询网关节点名称
- if (strcmp(subMac,"0F0000000001") == 0)//网关
- {
- sprintf(querySql,"select device_name from dev_info_gateway where device_mac = '%s' ",mac);
- excuteSql(_db,querySql);
- res = mysql_store_result(_db);
- if (NULL == res)
- {
- return 1;
- }
- row = mysql_fetch_row(res);
- if (NULL == row)
- {
- mysql_free_result(res);
- return 1;
- }
-
- if(!row[0])
- {
- debug("device_name 为空");
- mysql_free_result(res);
- return 1;
- }
- strcpy(macName,row[0]);
- sprintf(strName,"设备名称:%s",macName);
- mysql_free_result(res);
- }
- else
- {
- sprintf(querySql,"select a.device_name as 'gateway_name',b.device_name as 'node_name' from dev_info_gateway a,dev_info_node b "
- "where a.device_mac = b.gateway_mac and b.gateway_mac = '%s' and b.device_mac = '%s'",mac,subMac);
- excuteSql(_db,querySql);
- res = mysql_store_result(_db);
- if (NULL == res)
- {
- return 1;
- }
- row = mysql_fetch_row(res);
- if (NULL == row)
- {
- mysql_free_result(res);
- return 1;
- }
-
- if(!row[0] || !row[1])
- {
- debug("gateway_name 或者 node_name 为空 ");
- mysql_free_result(res);
- return 1;
- }
- strcpy(macName,row[0]);
- strcpy(subMacName,row[1]);
- mysql_free_result(res);
- sprintf(strName,"设备:%s,节点:%s",macName,subMacName);
- }
-
- //判断报警类型
- if(relayCode == SW_TEMPERATURE_HUMIDITY_ALARM)
- {
- strcpy(strAlarmType,"温湿度报警拉闸");
- }
- else if(relayCode == SW_FIRE_ALARM)
- {
- strcpy(strAlarmType,"烟感报警拉闸");
- }
- else if(relayCode == SW_TILT_ALARM)
- {
- strcpy(strAlarmType,"倾斜报警拉闸");
- }
- else if(relayCode == SW_LOCK_ALARM)
- {
- strcpy(strAlarmType,"锁具报警拉闸");
- }
- else if(relayCode == SW_LINE_TEMPERATURE_ALARM)
- {
- strcpy(strAlarmType,"线温报警拉闸");
- }
- else if(relayCode == SW_OVERVOLTAGE)
- {
- strcpy(strAlarmType,"过压报警拉闸");
- }
- else if(relayCode == SW_UNDERVOLTAGE)
- {
- strcpy(strAlarmType,"欠压报警拉闸");
- }
- else if(relayCode == SW_OVERLOAD_ALARM)
- {
- strcpy(strAlarmType,"过载报警拉闸");
- }
- else if(relayCode == SW_ELECTRIC_EXCESS)
- {
- strcpy(strAlarmType,"用电超额报警拉闸");
- }
- else if(relayCode == SW_OVER_SWITCH_OUT_COUNT)
- {
- strcpy(strAlarmType,"超自动合闸次数报警拉闸");
- }
- else if(relayCode == SW_FAST_CURRENT)
- {
- strcpy(strAlarmType,"快速电流报警拉闸");
- }
- else
- {
- debug("无法识别报警!");
- return 1;
- }
-
- //格式化报警内容
- sprintf(strAlarm,"%s,%s,时间:%s \n",strName,strAlarmType,GetCurrentTime());
- log(strAlarm);
-
- //更新到报警故障表
- sprintf(updateSql,"update dev_fault set fault_details = '%s',fault_state = 1,fault_time = now() where "
- "device_mac = '%s' and device_mac_node = '%s' and relay_code = %d",strAlarm,mac,subMac,relayCode);
- excuteSql(_db,updateSql);
- affectedRows = mysql_affected_rows(_db);
- if (affectedRows < 1)
- {
- sprintf(insertSql,"insert into dev_fault(device_mac,device_mac_node,fault_details,relay_code,fault_state,fault_time)values('%s','%s','%s',%d,1,now())",
- mac,subMac,strAlarm,relayCode);
- excuteSql(_db,insertSql);
- }
-
- return 0;
- }
- //比较两个时间字符串的大小
- int compareTimes(const char *time1, const char *time2)
- {
- struct tm tm_base, tm_time1, tm_time2;
- // 设置基准日期为当前日期
- time_t current_time = time(NULL);
- localtime_r(¤t_time, &tm_base);
- // 解析时间字符串1
- if (strptime(time1, "%H:%M", &tm_time1) == 0)
- {
- fprintf(stderr, "Failed to parse time1\n");
- return 0; // or handle the error in an appropriate way
- }
- // 解析时间字符串2
- if (strptime(time2, "%H:%M", &tm_time2) == 0)
- {
- fprintf(stderr, "Failed to parse time2\n");
- return 0; // or handle the error in an appropriate way
- }
- // 设置日期部分为基准日期的日期部分
- tm_time1.tm_year = tm_base.tm_year;
- tm_time1.tm_mon = tm_base.tm_mon;
- tm_time1.tm_mday = tm_base.tm_mday;
- tm_time2.tm_year = tm_base.tm_year;
- tm_time2.tm_mon = tm_base.tm_mon;
- tm_time2.tm_mday = tm_base.tm_mday;
- // 将 struct tm 结构转换为 time_t 类型
- time_t t1 = mktime(&tm_time1);
- time_t t2 = mktime(&tm_time2);
- // 检查转换是否成功
- if (t1 == -1 || t2 == -1)
- {
- fprintf(stderr, "Failed to convert time to time_t\n");
- return 0; // or handle the error in an appropriate way
- }
- // 比较时间并返回相应的结果
- if (t1 < t2)
- {
- return -1;
- } else if (t1 > t2)
- {
- return 1;
- } else
- {
- return 0;
- }
- }
- //比较两个时间结构体的的大小
- int compareModifiedTimes(struct tm t1, struct tm t2)
- {
- // 将时间结构体转换为秒数
- time_t time1 = mktime(&t1);
- time_t time2 = mktime(&t2);
- // 比较秒数
- if (time1 < time2) {
- return -1;
- } else if (time1 > time2) {
- return 1;
- } else {
- return 0;
- }
- }
- //比较给定时间和系统当前时间的函数
- int compareWithCurrentTime(struct tm t1)
- {
- // 获取系统当前时间
- time_t currentTime;
- time(¤tTime);
- // 将给定时间结构体转换为秒数
- time_t givenTime = mktime(&t1);
- // 比较秒数
- if (givenTime < currentTime) {
- return -1;
- } else if (givenTime > currentTime) {
- return 1;
- } else {
- return 0;
- }
- }
- // 将时间字符串转换为秒数
- int timeStringToSeconds(const char *timeString) {
- int hours, minutes;
- if (sscanf(timeString, "%02d:%02d", &hours, &minutes) == 2) {
- return hours * 3600 + minutes * 60;
- }
- return INT_MIN; // 解析失败
- }
- // 比较两个时间字符串的时间差(秒)
- int compareTimeDifference(const char *timeString1, const char *timeString2) {
- int seconds1 = timeStringToSeconds(timeString1);
- int seconds2 = timeStringToSeconds(timeString2);
- debug("seconds1:%d,seconds2:%d\n",seconds1,seconds2);
- if (seconds1 != INT_MIN && seconds2 != INT_MIN) {
- return seconds1 - seconds2;
- } else {
- return INT_MIN; // 解析失败
- }
- }
- //更新时间和拉合闸的时间点比较
- int compareWithUpdateTime(const char *timeString,const char *time1,const char *time2,const char *time3,const char *time4)
- {
- int diff1 = compareTimeDifference(timeString, time1);
- // 解析时间字符串1
- if (strlen(time1)==5 && diff1!= INT_MIN)
- {
- debug("time1:%s,和更新时间:%s,差值为%d\n",time1 ,timeString,diff1);
- if(fabs(diff1)<120)//更新时间在2分钟内
- {
- debug("time1更新时间在2分钟内\n");
- return 1;
- }
- }
- int diff2 = compareTimeDifference(timeString, time2);
- // 解析时间字符串2
- if (strlen(time2)==5 && diff2!= INT_MIN)
- {
- debug("time2:%s,和更新时间:%s,差值为%d\n",time2 ,timeString,diff2);
- if(fabs(diff2)<120)//更新时间在2分钟内
- {
- debug("time2更新时间在2分钟内\n");
- return 1;
- }
- }
- int diff3 = compareTimeDifference(timeString, time3);
- // 解析时间字符串3
- if (strlen(time1)==5 && diff3!= INT_MIN)
- {
- debug("time3:%s,和更新时间:%s,差值为%d\n",time3 ,timeString,diff3);
- if(fabs(diff3)<120)//更新时间在2分钟内
- {
- debug("time1更新时间在2分钟内\n");
- return 1;
- }
- }
- int diff4 = compareTimeDifference(timeString, time4);
- // 解析时间字符串4
- if (strlen(time4)==5 && diff4!= INT_MIN)
- {
- debug("time4:%s,和更新时间:%s,差值为%d\n",time4 ,timeString,diff4);
- if(fabs(diff4)<120)//更新时间在2分钟内
- {
- debug("time4更新时间在2分钟内\n");
- return 1;
- }
- }
-
- return 0;
- }
- //将需要处理sql放入队列
- void* sendtoqueue(ArrQueue *pQueue,char* stringSql)
- {
- ElemType *elememt = (ElemType *)malloc(sizeof(ElemType));
- if(elememt==NULL)
- {
- printf("0 malloc(sizeof(ElemType)) \n");
- exit(0);
- }
- memset(elememt,0,sizeof(ElemType));
- if(strlen(stringSql)>1024)
- {
- printf("stringSql length is too long \n");
- exit(0);
- }
- elememt->len = strlen(stringSql);
- strcpy(elememt->buf,stringSql);
- EnQueue(pQueue,elememt);
- return NULL;
- }
- //循环从队列中取出数据处理
- void* getqueue(void *data)
- {
- MYSQL *_db = NULL;
- ElemType *elememt;
- if (!_db)
- {
- // 先申请内存再初始化
- _db = malloc(sizeof(MYSQL));
- db_init(_db);
- }
-
- struct my_thread_info *info = data;
-
- while(1)
- {
- usleep(1000*1);
- DeQueue(m_pque,&elememt);
- if(elememt == NULL)
- {
- printf("elememt == NULL,number:%d\n",info->which);
- continue;
- }
- excuteSql(_db,elememt->buf);
- free(elememt);
- //log("getqueue sql number:%d \n",info->which);
- }
- free(info);
- return NULL;
- }
- //创建任务线程处理数据库执行
- void CreateDbHandThread(void)
- {
- int rc;
- long t;
- struct my_thread_info *info;
- sleep(1);
- for (t = 0; t < NUM_THREADS_UPLOAD_g; t++)
- {
- info = malloc(sizeof(struct my_thread_info));
- info->which = t;
- rc = pthread_create(&threads[t], NULL, getqueue, info);
- if (rc)
- {
- printf("ERROR; return code from pthread_create() is %d\n", rc);
- exit(-1);
- }
- printf("pthread_create() threadid:%lu is started \n",threads[t]);
- sleep(1);
- }
- // for (t = 0; t < NUM_THREADS; t++)
- // {
- // pthread_join(threads[t], NULL);
- // }
- }
- //打印队列状态,队列处理线程状态,10min打印一次
- int PrintQueueThreadState(void)
- {
- if(timeGloble_g%600 == 0 && NUM_THREADS_UPLOAD_g>0)
- {
- int i = 0;
- char strState[256] = {0};
- int pthread_kill_err;
- memset(strState,0x0,256);
- sprintf(strState,"pid:%d,队列大小:%d",getpid(),GetLength(m_pque));
- for(i=0;i<NUM_THREADS_UPLOAD_g;i++)
- {
- pthread_kill_err = pthread_kill(threads[i],0);
- sprintf(strState,"%s,tid:%lu(%s)",strState,threads[i],(pthread_kill_err==0)?"alive":"death");
- }
- log("%s \n",strState);
- }
-
- return 0;
- }
- //关于远程升级
- //生成CRC查询表
- void init_crc32_tab(void)
- {
- int32_t i, j;
- uint32_t crc;
- if (have_table)
- {
- return;
- }
- have_table = 1;
-
- for(i = 0; i < 256; i++)
- {
- crc = (uint32_t )i;
- for(j = 0; j < 8; j++)
- {
- if(crc & 0X00000001L)
- {
- crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
- }
- else
- {
- crc = crc >> 1;
- }
- }
- crc_table32[i] = crc;
- }
- }
- //获得CRC
- uint32_t get_crc32(uint32_t crcinit, uint8_t *bs, uint32_t bssize)
- {
- uint32_t crc = crcinit ^ 0XFFFFFFFF;
- while(bssize--)
- {
- crc = (crc>>8)^crc_table32[(crc&0XFF)^*bs++];
- }
- return crc ^ 0XFFFFFFFF;
- }
- //根据mac查询对应升级文件名
- char* GetFileNameByMac(list_node* u_list,char* mac)
- {
- list_node* list = u_list;
- if(list == NULL) return NULL;
-
- while(list)
- {
- upgrade_user_info* info = (upgrade_user_info*)list->data;
- if(strcmp(info->mac,mac) == 0)
- {
- return info->ota_file_name;
- }
- list = list->next;
- }
- return NULL;
- }
- //根据文件名和包序号查询分包数据
- ota_info* GetOtaInfoByFileName(list_node* f_list,char* filename)
- {
- list_node* list = f_list;
- if(list == NULL) return NULL;
-
- while(list)
- {
- ota_info* info = (ota_info*)list->data;
- if(strcmp(info->new_file_name,filename) == 0)
- {
- return info;
- }
- list = list->next;
- }
- return NULL;
- }
- /******************************************************************
- * Function Name: UpgradeFileAddFromDB
- * Arguments:
- * Return Value: void
- * Date: 2022-04-02
- * Editor: chw
- * Description: 新增升级文件映射节点
- ******************************************************************/
- void UpgradeFileAddFromDB(list_node* f_list,char* filename,MYSQL *_db,int ota_mode)
- {
- char logstr[512] = {0};
- unsigned short ota_file_total_packets = 0;
- int file_length_bytes = 0;
- unsigned int ota_length_bytes = 0;
- list_node* list = f_list;
- ota_info* info = (ota_info*)malloc(sizeof(ota_info));
- memset(info,0x0,sizeof(ota_info));
- ota_info* s = GetOtaInfoByFileName(file_list,filename);
- if(s != NULL)
- {
- log("有文件节点,不新增! \n");
- free(info);
- info = NULL;
- return;
- }
- //读取数据库升级文件
- unsigned char *fp = readfile_from_db(filename,_db,&file_length_bytes);
- if (file_length_bytes <= 0)
- {
- log("%d file_length_bytes <= 0 ! \n",file_length_bytes);
- free(info);
- info = NULL;
- return;
- }
- //计算数据库升级文件crc32校验
- init_crc32_tab();
- uint32_t crc_value = 0;
- if(calc_crc32_from_buff((const char*)fp,file_length_bytes,&crc_value) == 0)
- {
- log("crc_value = %x\n",crc_value);
- }
- //全量
- if(ota_mode == 1)
- {
- ota_length_bytes = file_length_bytes;
- memcpy(info->buf,fp,file_length_bytes);
- crc_value = get_crc32(0,info->buf,file_length_bytes);//ota文件crc校验
- info->ota_mode = 1;//模式
- strcpy(info->new_file_name,filename);//新文件名
- info->new_file_len = (uint32_t)file_length_bytes;//新文件长度
- info->ota_file_len = (uint32_t)file_length_bytes;//升级文件长度
- info->new_file_crc = crc_value;//新文件crc32校验
- info->ota_file_crc = info->new_file_crc;//升级文件crc32校验
- ota_file_total_packets = (uint32_t)file_length_bytes/ota_file_packet_len + 1;
- info->ota_file_total_packets = ota_file_total_packets;//升级文件总包数
- info->ota_file_packet_len = ota_file_packet_len;//升级文件每包数据长度
- sprintf(logstr,"新文件名:%s,新文件长度:%d,升级文件长度:%d,升级文件总包数:%d,升级文件每包数据长度:%d,新文件crc32校验:%X,升级文件crc32校验:%X \n",
- info->new_file_name,info->new_file_len,info->ota_file_len,info->ota_file_total_packets,info->ota_file_packet_len,info->new_file_crc,info->ota_file_crc);
- log(logstr);
- }
- //差分
- else
- {
- ota_length_bytes = (unsigned int)file_length_bytes;
- memcpy(info->buf,fp,ota_length_bytes);
- crc_value = get_crc32(0,info->buf,ota_length_bytes);//ota文件crc校验
- info->ota_mode = 0;//模式
- memcpy(info->old_file_name,fp,48);//旧文件名
- info->old_file_len = INT_FROM_BUFF(fp,48);//旧文件长度
- info->old_file_crc = INT_FROM_BUFF(fp,52);//旧文件crc32 校验值
- memcpy(info->new_file_name,fp+56,48);//新文件名
- info->new_file_len = INT_FROM_BUFF(fp,104);//新文件的长度
- info->new_file_crc = INT_FROM_BUFF(fp,108);//新文件crc32 校验值
- info->ota_state = (char)0;//升级状态
- info->ota_file_len = ota_length_bytes;//ota 文件的长度
- info->ota_file_crc = crc_value;//ota 文件的crc32校验值
- info->ota_file_total_packets = ota_length_bytes/ota_file_packet_len + 1;//ota文件的总的包数
- info->ota_file_packet_len = ota_file_packet_len;//ota文件每包的数据长度
- log("info->buf 模式:%d,旧文件名:%s,旧文件长度:%d,旧文件crc32:%X,新文件名:%s,新文件的长度:%d,新文件crc32:%X,ota状态:%d,ota文件的长度:%d,"
- "ota文件的crc32:%X,ota文件的总的包数:%d,ota文件每包的数据长度:%d \n", info->ota_mode,info->old_file_name,info->old_file_len,
- info->old_file_crc,info->new_file_name,info->new_file_len,info->new_file_crc,info->ota_state,info->ota_file_len,info->ota_file_crc,
- info->ota_file_total_packets,info->ota_file_packet_len);
- }
- if(fp != NULL)
- {
- free(fp);
- fp = NULL;
- }
- //第一个文件
- if(list == NULL)
- {
- file_list = list_create((void*)info);
- log("当前为文件映射第一个节点 \n");
- }
- //没有文件节点
- else
- {
- list_insert_end(file_list,(void*)info);
- log("没有文件节点,加入! \n");
- }
- return;
- }
- //数据库查询升级文件名
- void GetUpgradeFileFromDB(char *mac,MYSQL *_db,char* filename)
- {
- MYSQL_RES* res = NULL;
- MYSQL_ROW row;
- char query[1024] = {0};
- char ota_file[256] = {0};
- int ota_mode = 0;
- sprintf(query,"select file_name,ota_mode from dev_info_gateway where device_mac ='%s'",mac);
- excuteSql(_db,query);
- res = mysql_store_result(_db);
- if (NULL == res)
- {
- return ;
- }
- row = mysql_fetch_row(res);
- if (NULL == row)
- {
- mysql_free_result(res);
- return ;
- }
-
- if(!row[0] || !row[1])
- {
- log("%s file_name、ota_mode为空 \n",mac);
- mysql_free_result(res);
- return ;
- }
- strcpy(ota_file,row[0]);
- ota_mode = atoi(row[1]);
- strcpy(filename,ota_file);
- mysql_free_result(res);
-
- //log("mac:%s,file_name:%s \n",mac,ota_file);
- return ;
- }
- /******************************************************************
- * Function Name: readfile_from_db
- * Arguments:
- * Return Value: void
- * Date: 2022-04-29
- * Editor: chw
- * Description: 从数据库读取升级文件
- ******************************************************************/
- unsigned char *readfile_from_db(const char *filename, MYSQL *_db,int *file_length_bytes)
- {
- //MYSQL_RES* res = NULL;
- //MYSQL_ROW row;
- char sql[512] = {0};
- int ret = 0;
- //unsigned long *lengths;
- unsigned char* data;
- MYSQL_BIND result;
- MYSQL_STMT* stmt = mysql_stmt_init(_db);
- assert(NULL!=stmt);
- sprintf(sql,"select file_src from dev_upgrade_file where file_name ='%s'",filename);
- ret = mysql_stmt_prepare(stmt, sql, strlen(sql));
- assert(0==ret);
- ret = mysql_stmt_execute(stmt);
- assert(0==ret);
- memset(&result,0x0,sizeof(result));
- unsigned long total_length = 0;
- result.buffer_type = MYSQL_TYPE_LONG_BLOB;
- result.length = &total_length;
- ret = mysql_stmt_bind_result(stmt, &result);
- assert(0==ret);
- ret = mysql_stmt_store_result(stmt);
- assert(0==ret);
- ret = mysql_stmt_fetch(stmt);
- if(total_length <= 0)
- {
- log("total_length <= 0!\n");
- mysql_stmt_close(stmt);
- return NULL;
- }
- unsigned long start = 0;
- //char buf[1024] = {0};
- //lengths = mysql_fetch_lengths(stmt);
- data = (unsigned char*)malloc(total_length);
- *file_length_bytes = total_length;
- if(data == NULL)
- {
- log("malloc data failed!");
- return NULL;
- }
- log("readfile_from_db函数,total_length=%lu\n", total_length);
- while (start<total_length)
- {
- result.buffer = (data+start);
- if(total_length < 1024)
- {
- result.buffer_length = total_length;
- }
- else if((start+1024) < total_length)
- {
- result.buffer_length = 1024;
- }
- else
- {
- result.buffer_length = total_length % 1024;
- }
-
- ret = mysql_stmt_fetch_column(stmt, &result, 0, start);
- if (ret!=0)
- {
- log("code=%d, msg=%s", (int)mysql_errno(_db), mysql_error(_db));
- free(data);
- mysql_stmt_close(stmt);
- return NULL;
- }
- start += result.buffer_length;
- }
- //log("%.*s\n", total_length, data);
- //free(data);
- mysql_stmt_close(stmt);
- return data;
- }
- /******************************************************************
- * Function Name: 获取缓存中的crc32
- * Arguments:
- * Return Value: void
- * Date: 2022-04-29
- * Editor: chw
- * Description: 获取缓存中的crc32
- ******************************************************************/
- int32_t calc_crc32_from_buff(const char *buff,int len, uint32_t *uiCrcValue)
- {
- const uint32_t size = 2*1024;
- uint32_t crc = 0; // CRC初始值为0
- int remain = len; //剩余未计算长度
- int index = 0;
- while(remain>0)
- {
- if(remain > (int)size)
- {
- crc = get_crc32(crc, (uint8_t*)(buff + index), size);
- index += size;
- remain = remain-(int)size;
- }
- else
- {
- crc = get_crc32(crc, (uint8_t*)(buff + index), remain);
- index += remain;
- remain = 0;
- }
-
- }
- *uiCrcValue = crc;
- return 0;
- }
- #ifdef UPGRADE_BY_FILE
- //获取文件长度
- int GetFileLength(char* file_path)
- {
- FILE* pFile = fopen(file_path,"r");
- if(pFile == NULL)
- {
- return -1;
- }
- fseek(pFile,0,SEEK_END);
- unsigned int file_length_bytes = ftell(pFile);
- fclose(pFile);
- pFile = NULL;
- return file_length_bytes;
- }
- //获得文件CRC
- int32_t calc_file_crc32(const char *pFileName, uint32_t *uiCrcValue)
- {
- if(!pFileName || !uiCrcValue)
- {
- log("bad parameter\n");
- return -1;
- }
- if(access(pFileName, F_OK|R_OK)!=0)
- {
- log("file not exist or reading file has not permission\n");
- return -1;
- }
- const uint32_t size = 2*1024;
- uint8_t crcbuf[size];
- uint32_t rdlen;
- uint32_t crc = 0; // CRC初始值为0
- FILE *fd = NULL;
- if((fd = fopen(pFileName, "r"))==NULL)
- {
- log("to do crc 32 check, open file error\n");
- return -1;
- }
- while((rdlen=fread(crcbuf, sizeof(uint8_t), size, fd))>0)
- {
- crc = get_crc32(crc, crcbuf, rdlen);
- }
- log("calc_file_crc32:%X \n",crc);
- *uiCrcValue = crc;
- fclose(fd);
- return 0;
- }
- //读取文件
- // unsigned char *read_myfile(const char *path, int *file_size)
- // {
- // if(!path||!file_size)
- // {
- // log("bad parameter\n");
- // return NULL;
- // }
- // //access
- // if(access(path, F_OK|R_OK))
- // {
- // log("access test file error\n");
- // return NULL;
- // }
- // //read file
- // struct stat calib_stat;
- // int ret = stat(path, &calib_stat);
- // if(ret!=0)
- // {
- // log("File error\n");
- // return NULL;
- // }
- // FILE *fd = fopen(path, "r");
- // if(NULL == fd)
- // {
- // log("Open test file error\n");
- // return NULL;
- // }
- // unsigned char *buffer = malloc(calib_stat.st_size);
- // if(!buffer)
- // {
- // log("malloc error\n");
- // fclose(fd);
- // return NULL;
- // }
- // memset(buffer, 0, calib_stat.st_size);
- // int totalSize = 0, readed = 0;
- // while((readed = fread(buffer + totalSize,1, 1024,fd)) > 0)
- // {
- // totalSize += readed;
- // }
- // *file_size = totalSize;
- // fclose(fd);
- // return buffer;
- // }
- // //增加用户
- // void UpgradeUserAdd(list_node* u_list,char* mac,char* file_name)
- // {
- // list_node* list = u_list;
- // upgrade_user_info* info = (upgrade_user_info*)malloc(sizeof(upgrade_user_info));
- // strcpy(info->mac,mac);
- // strcpy(info->ota_file_name,file_name);
- // //第一个用户
- // if(list == NULL)
- // {
- // user_list = list_create((void*)info);
- // }
- // else
- // {
- // //没查询到用户
- // if(GetFileNameByMac(u_list,mac) == NULL)
- // {
- // list_insert_end(u_list,(void*)info);
- // }
- // //查询到用户,修改
- // else
- // {
- // while(list)
- // {
- // upgrade_user_info* old_info = (upgrade_user_info*)list->data;
- // if(strcmp(old_info->mac,mac) == 0)
- // {
- // list->data = (void*)info;
- // free(old_info);
- // old_info = NULL;
- // break;
- // }
- // list = list->next;
- // }
- // }
- // }
- // return;
- // }
- // //新增升级文件映射节点
- // void UpgradeFileAdd(list_node* f_list,char* filename,int ota_mode)
- // {
- // char file_path[256];
- // char logstr[512];
- // unsigned short ota_file_total_packets = 0;
- // unsigned int file_length_bytes = 0;
- // unsigned int ota_length_bytes = 0;
- // list_node* list = f_list;
- // ota_info* info = (ota_info*)malloc(sizeof(ota_info));
- // memset(info,0x0,sizeof(ota_info));
- // sprintf(file_path,"/home/cao/ota/%s",filename);
- // //计算文件crc32校验
- // init_crc32_tab();
- // uint32_t crc_value = 0;
- // if(calc_file_crc32(file_path, &crc_value) == 0)
- // {
- // log("file_path:%s,crc_value = %x\n", file_path,crc_value);
- // }
- // //读取文件
- // unsigned char *fp = read_myfile(file_path,(int*)&file_length_bytes);
- // if (file_length_bytes <= 0)
- // {
- // log("%s file_length_bytes <= 0 ! \n",file_path);
- // free(info);
- // info = NULL;
- // return;
- // }
- // //全量
- // if(ota_mode == 1)
- // {
- // ota_length_bytes = file_length_bytes;
- // memcpy(info->buf,fp,file_length_bytes);
- // crc_value = get_crc32(0,info->buf,file_length_bytes);//ota文件crc校验
- // info->ota_mode = 1;//模式
- // strcpy(info->new_file_name,filename);//新文件名
- // info->new_file_len = file_length_bytes;//新文件长度
- // info->ota_file_len = file_length_bytes;//升级文件长度
- // info->new_file_crc = crc_value;//新文件crc32校验
- // info->ota_file_crc = info->new_file_crc;//升级文件crc32校验
- // ota_file_total_packets = file_length_bytes/ota_file_packet_len + 1;
- // info->ota_file_total_packets = ota_file_total_packets;//升级文件总包数
- // info->ota_file_packet_len = ota_file_packet_len;//升级文件每包数据长度
- // sprintf(logstr,"新文件名:%s,新文件长度:%d,升级文件长度:%d,升级文件总包数:%d,升级文件每包数据长度:%d,新文件crc32校验:%X,升级文件crc32校验:%X \n",
- // info->new_file_name,info->new_file_len,info->ota_file_len,info->ota_file_total_packets,info->ota_file_packet_len,info->new_file_crc,info->ota_file_crc);
- // log(logstr);
- // }
- // //差分
- // else
- // {
- // ota_length_bytes = file_length_bytes-130;
- // memcpy(info->buf,fp+130,ota_length_bytes);
- // //crc_value = get_crc32(0,info->buf,file_length_bytes-130);//ota文件crc校验
- // info->ota_mode = 0;//模式
- // memcpy(info->old_file_name,fp+1,48);//旧文件名
- // info->old_file_len = INT_FROM_BUFF(fp,49);//旧文件长度
- // info->old_file_crc = INT_FROM_BUFF(fp,53);//旧文件crc32 校验值
- // memcpy(info->new_file_name,fp+58,48);//新文件名
- // info->new_file_len = INT_FROM_BUFF(fp,105);//新文件的长度
- // info->new_file_crc = INT_FROM_BUFF(fp,109);//新文件crc32 校验值
- // info->ota_state = (char)*(fp+113);//ota 状态
- // info->ota_file_len = INT_FROM_BUFF(fp,114);//ota 文件的长度
- // info->ota_file_crc = INT_FROM_BUFF(fp,118);//ota 文件的crc32校验值
- // info->ota_file_total_packets = SHORT_FROM_BUFF(fp,122);//ota文件的总的包数
- // info->ota_file_packet_len = SHORT_FROM_BUFF(fp,124);//ota文件每包的数据长度
- // info->boot_addr = INT_FROM_BUFF(fp,126);//app 程序的启动地址
- // log("info->buf 模式:%d,旧文件名:%s,旧文件长度:%d,旧文件crc32:%X,新文件名:%s,新文件的长度:%d,新文件crc32:%X,ota状态:%d,ota文件的长度:%d,"
- // "ota文件的crc32:%X,ota文件的总的包数:%d,ota文件每包的数据长度:%d,app程序的启动地址:%X \n", info->ota_mode,info->old_file_name,info->old_file_len,
- // info->old_file_crc,info->new_file_name,info->new_file_len,info->new_file_crc,info->ota_state,info->ota_file_len,info->ota_file_crc,
- // info->ota_file_total_packets,info->ota_file_packet_len,info->boot_addr);
- // }
- // //log("info->buf crc = %x ,file_length_bytes = %d,ota_length_bytes = %d \n", crc_value,file_length_bytes,ota_length_bytes);
- // if(fp != NULL)
- // {
- // free(fp);
- // }
-
- // //第一个文件
- // if(list == NULL)
- // {
- // file_list = list_create((void*)info);
- // log("当前为文件映射第一个节点 \n");
- // }
- // else
- // {
- // ota_info* s = GetOtaInfoByFileName(file_list,filename);
- // if(s == NULL)
- // {
- // list_insert_end(file_list,(void*)info);
- // log("没有文件节点,加入! \n");
- // }
- // else
- // {
- // log("有文件节点,不新增! \n");
- // }
-
- // }
- // return;
- // }
- #endif
|