123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526 |
- #include "atCmdList.h"
- #include "mcuCmds.h"
- #include "devMsg.h"
- #include "para.h"
- #include "nmea.h"
- #include "app.h"
- #include "records.h"
- #define MCU_PRO_CRC16_INIT 0x1234
- const T_INT8 *cmdListTable[]=
- {
- "DevInfo",
- "KeyPress",
- "KeyFree",
- "Motion",
- "NearDev",
- "ShutDown",
- "LowPower",
- "\r\n",
- ""
- };
- typedef enum{
- CMD_MUC_DEVINFO,
- CMD_MCU_KEYPRESS,
- CMD_MCU_KEYFREE,
- CMD_MCU_MOTION,
- CMD_MCU_NEARDEV,
- CMD_MCU_SHUTDOWN,
- CMD_MCU_LOWPOWER,
- CMD_MCU_NONE=-1
- }CMD_MCU_TYPEDEF;
- #define BAT_TABLE_NUM 9
- const unsigned char batTable[BAT_TABLE_NUM][2]={
- {33,3}, //<=3.3 3%
- {34,10}, //<=3.4 10%
- {35,26}, //<=3.5 26%
- {36,52}, //<=3.6 52%
- {37,65}, //<=3.7 65%
- {38,75}, //<=3.8 75%
- {39,86}, //<=3.9 86%
- {40,93}, //<=4.0 93%
- {41,100} //>4.0 100%
- };
- void batSwitchNow(void){
- const char lowperTable[]="RT+LSHTTS=1,\"C9E8B1B8B5E7C1BFB5CDA3ACC7EBBCB0CAB1B3E4B5E7\"";
- int i;
- //低电检测
- static int64_t lbatTime=0;
- static T_BOOL lbatReport=FALSE;
- static T_BOOL firstLbat=FALSE;
- int64_t curTime,dttime;
- if(app.bat>34){//未到低电压
- lbatReport=FALSE;
- firstLbat=FALSE;
- app.warnStatus=WARN_NORMAL;
- wlog_warn("bat normal");
- }else{//低电压了
- if(FALSE==firstLbat){
- wlog_warn("bat first low");
- lbatTime=LSAPI_OSI_UpTime();
- firstLbat=TRUE;
- }else{
- curTime=LSAPI_OSI_UpTime();
- dttime=curTime-lbatTime;
- wlog_warn("bat status:%lld,%lld,%lld",lbatTime,dttime,curTime);
- //检测是否持续了1分钟
- if(dttime>=60000 && lbatReport==FALSE){
- //提示"设备电量低,请及时充电",同时上报低压事件0x0e
- wlog_warn("low power, report now");
- lbatReport=TRUE;
- if(app.vcharge<=30) cmdTTSHandler(lowperTable, strlen(lowperTable));
- else wlog_warn("skip voice warn when charging");
- app.warnStatus=WARN_LOW_PWR;
- warnSendNow(WARN_LOW_PWR);
- }
- }
- }
- //电压百分比判定
- for(i=0;i<BAT_TABLE_NUM;i++){
- if(app.bat<=batTable[i][0]){
- app.vBatPersent=batTable[i][1];
- goto BAT_END;
- }
- }
- app.vBatPersent=100;
- BAT_END:
- wlog_info("Bat=%d,persent=%d",app.bat,app.vBatPersent);
- }
- void KeyHandler(unsigned char keyvalue,unsigned char keyType);
- void McuStringHandler(unsigned char *msg, int cmd_len){
- T_BOOL needUpdateMcu=FALSE;
- T_INT16 cmd,i,j;
- T_UINT32 psn;
- int tmp,index;
- T_UINT16 crc16A,crc16B;
- unsigned char *ptr=msg+cmd_len-4;
- unsigned char KeyPress,KeyFree,temp[2];
- char SubStr[20];
- char *ver;
- T_BOOL needFeedBackDevInfo=FALSE;
- //wlog_info("Get[%d]:%s",cmd_len,msg);//msg,cmd_len没回车换行也没>>
- //计算CRC16
- if(0!=restoreDataFormatByHex(ptr,4)){//获取最后的crc16串
- wlog_warn("get mcu crc16 failed:%s",ptr);
- return;
- }
- crc16A=((unsigned short)ptr[0]<<8)|ptr[1];
- crc16B=crc16Check(MCU_PRO_CRC16_INIT,msg,cmd_len-4-1);//不算crc16前面那个逗号
- if(crc16A != crc16B){
- wlog_warn("mcu crc16 unfit:%04x,%04x",crc16A,crc16B);
- return;
- }
- cmd_len -= 5;//长度去掉4个字节CRC和一个逗号
- cmd=matchCmdList(cmdListTable,msg);
- switch(cmd){
- case CMD_MUC_DEVINFO://DevInfo,RTL271MCU_V101,200510001,38,30,e209 -->设备信息:MCU版本,PSN,VBat
- needFeedBackDevInfo=TRUE;
- //获取psn
- index=findByteFromStr(msg, cmd_len,',',2);
- if(index>=0){
- tmp=atoi(msg+index);
- if(tmp != sut_psn.psn){
- wlog_warn("psn error,setmcu:%d,%d",sut_psn.psn, tmp);
- break;
- }
- }
- //PSN匹配后
- //获取MCU版本号串
- index=findByteFromStr(msg, cmd_len,',',1);
- if(index>=0){
- ver=getMcuAppVer();
- if(0!=memcmp(msg+index, ver, strlen(ver))){
- //有新版本
- needUpdateMcu=TRUE;
- }
- }
- //获取BAT
- index=findByteFromStr(msg, cmd_len,',',3);
- if(index>=0){
- tmp=atoi(msg+index);
- app.bat=tmp;
- batSwitchNow();
- }
- //获取充电电压
- index=findByteFromStr(msg, cmd_len,',',4);
- if(index>=0){
- tmp=atoi(msg+index);
- app.vcharge=tmp;
- }
- wlog_info("DevInfo:%d,%d,%d",needUpdateMcu,app.bat,app.vcharge);
- if(needUpdateMcu==TRUE){
- apUpgradeMcu();
- McuIapStart();
- }
- break;
- case CMD_MCU_KEYPRESS://>>KeyPress,01,386A -->按键按下值:01/02/04或组合
- //获取键值
- index=findByteFromStr(msg, cmd_len,',',1);
- if(index>=0){
- if(0!=isBytesAreHex(msg+index, 2)){
- wlog_warn("KeyPress invalid1");
- break;
- }
- memcpy(temp, msg+index,2);
- if(0!=restoreDataFormatByHex(temp,2)){
- wlog_warn("KeyPress invalid2");
- break;
- }
- KeyPress=temp[0];
- KeyHandler(KeyPress,0);
- }
- break;
- case CMD_MCU_KEYFREE://>>KeyFree,01,386A -->按键放开值:01/02/04或组合
- //获取键值
- index=findByteFromStr(msg, cmd_len,',',1);
- if(index>=0){
- if(0!=isBytesAreHex(msg+index, 2)){
- wlog_warn("KeyFress invalid1");
- break;
- }
- memcpy(temp, msg+index,2);
- if(0!=restoreDataFormatByHex(temp,2)){
- wlog_warn("KeyFress invalid2");
- break;
- }
- KeyFree=temp[0];
- KeyHandler(KeyFree,1);
- }
- break;
- case CMD_MCU_MOTION://>>Motion,1234,89,511,1028,7902 -->运动传感器值:StepCount,Ax,Ay,Az
- //获取步数
- index=findByteFromStr(msg, cmd_len,',',1);
- if(index>=0){
- tmp=atoi(msg+index);
- gDevInfo->steps=tmp;
- }
- //获取Ax
- index=findByteFromStr(msg, cmd_len,',',2);
- if(index>=0){
- tmp=atoi(msg+index);
- gDevInfo->aspeed_x=(short)tmp;
- }
- //获取Ay
- index=findByteFromStr(msg, cmd_len,',',3);
- if(index>=0){
- tmp=atoi(msg+index);
- gDevInfo->aspeed_y=(short)tmp;
- }
- //获取Az
- index=findByteFromStr(msg, cmd_len,',',4);
- if(index>=0){
- tmp=atoi(msg+index);
- gDevInfo->aspeed_z=(short)tmp;
- }
- motionGetOk();
- wlog_info("GetMotion:%d,%d,%d,%d",gDevInfo->steps,gDevInfo->aspeed_x,gDevInfo->aspeed_y,gDevInfo->aspeed_z);
- break;
- case CMD_MCU_NEARDEV://>>NearDev,4,200510002,12,200510005,3C,200530004,0A,200510325,9E,13B3-->临近设备:PSN1,RSSI1,PSN2,RSSI2....
- #if 0
- //模拟NEAR数据上传
- gNearInfo->num=2;
- for(i=0;i<6;i++) gNearInfo->info[0].mac[i]=0x55;
- gNearInfo->info[0].rssi=0x55;
- for(i=0;i<6;i++) gNearInfo->info[1].mac[i]=0xAA;
- gNearInfo->info[1].rssi=0xAA;
- #else
- if(GetSubStrWithComma(msg,SubStr,sizeof(SubStr),1)){//获取个数
- wlog_warn("NearDev:Num error!\r\n");
- break;
- }
- int num=strtol(SubStr,NULL,16);
- wlog_warn("NearDev:Num=%d\r\n",num);
- if(GetCommaNum(msg)!=num*2+2){//统计逗号个数
- wlog_warn("NearDev:comma num error!\r\n");//逗号个数不对
- break;
- }
- if(num==0) break;
- memset((unsigned char *)gNearInfo, 0, sizeof(NEARINFO_DEF));
- for(i=0;i<num;i++){
- //get PSN
- GetSubStrWithComma(msg,SubStr,sizeof(SubStr),2+i*2);
- psn=strtol(SubStr,NULL,16);
- DecToBCD(psn, gNearInfo->info[i].mac,sizeof(gNearInfo->info[i].mac));
- //get RSSI
- GetSubStrWithComma(msg,SubStr,sizeof(SubStr),3+i*2);
- j=strtol(SubStr,NULL,16);
- gNearInfo->info[i].rssi=j;
- wlog_warn("PSN=%d RSSI=%02x\r\n",psn,j);
- }
- gNearInfo->num=num;
- #endif
- memcpy(gNearInfo->BCDTime,getBCDDateTime(),sizeof(gNearInfo->BCDTime));
- getNearOk();
- break;
- case CMD_MCU_SHUTDOWN://>>ShutDown,A657 -->控制关机
- #ifdef TAKE_NOTE_FOR_REBOOT
- saveRebootReason("CMD_MCU_SHUTDOWN\r\n");
- #endif
- outterInfo("ShutDown\r\n",10);
- vibraNow();
- if(getLoginStatus()==0){
- LSAPI_SYS_PowerOff();
- for(;;){LSAPI_OSI_ThreadSleep(100);}
- }else warnSendNow(WARN_PWROFF);
- break;
- case CMD_MCU_LOWPOWER://>>LowPower, -->低电关机
- #ifdef TAKE_NOTE_FOR_REBOOT
- saveRebootReason("CMD_MCU_LOWPOWER\r\n");
- #endif
- wlog_warn("LowPower ShutDown");
- if(getLoginStatus()==0){
- LSAPI_SYS_PowerOff(); //未登陆成功说明此时连接不行的
- for(;;){LSAPI_OSI_ThreadSleep(100);}
- }else warnSendNow(WARN_LOW_PWR_DOWN);
- break;
- default:break;
- }
- if(needFeedBackDevInfo==TRUE) setMcuPara(TRUE);
- }
- #define KEY_SOS 0x04
- #define KEY_REC 0x02
- //////////////////////////录音按键处理////////////////////////
- char recIsPress=0;
- static int64_t ltm=0;
- void clearLtm(void){ltm=LSAPI_OSI_UpTime();}
- void recHandler(keyType){
- int64_t dt;
- if(keyType==0){//按下
- recIsPress=1;
- wlog_info("rec is press");
- //检测dt
- dt=LSAPI_OSI_UpTime()-ltm;
- if(dt<600){//一定时间内按了两次,为双击
- stopRecTimer();
- wlog_info("Double key");
- TryvFileRePlay(LV_PLAYED);
- }else startRecTimer();//打开定时器检测单击
- clearLtm();
- }else{//放开
- recIsPress=0;
- wlog_info("rec is free");
- RecCloseNowApi();
- }
- }
- /*处理MCU发过来的按键值
- keyvalue:键值,低3位有效
- keyType:0 按下的键值 1 松开的键值
- */
- void KeyHandler(unsigned char keyvalue,unsigned char keyType){
- if(keyType==0) wlog_info("KeyPress:%02x",keyvalue);
- else wlog_info("KeyFress:%02x",keyvalue);
- switch(keyvalue){
- case KEY_SOS://SOS
- sosHandler(keyType);
- break;
- case KEY_REC://录音
- recHandler(keyType);
- break;
- default:
- wlog_info("keyvalue skip");
- break;
- }
- }
- typedef enum{
- LNET_NORMAL, //网络正常
- LNET_CONNTING, //正在找网
- LNET_HERROR //硬件故障
- }LNET_ENUM;
- typedef enum{
- LGPS_LOCATED, //已定位
- LGPS_LOCATING, //正在定位
- LGPS_HERROR //硬件故障
- }LGPS_ENUM;
- void triggerMcuAndSend(char *info){
- #if 1
- wlog_info("Send:%s",info);
- uartOutPut(info,strlen(info));//用于唤醒MCU
- LSAPI_OSI_ThreadSleep(1);
- uartOutPut(info,strlen(info));//发送消息给MCU
- #else
- const unsigned char buffer[1]={0};
- wlog_info("Send:%s",info);
- uartOutPut(buffer,sizeof(buffer));//用于唤醒MCU
- LSAPI_OSI_ThreadSleep(1);
- uartOutPut(info,strlen(info));//发送消息给MCU
- #endif
- }
- /*初始化MCU灯状态*/
- void setInitMcu(void){
- char info[100],tmp[10];
- unsigned short crc16;
- snprintf(info, sizeof(info), "<<SetMCU,%d,%d,%d",sut_psn.psn,LNET_HERROR,LGPS_HERROR);
- crc16=crc16Check(MCU_PRO_CRC16_INIT,info+2,strlen(info)-2);
- snprintf(tmp, sizeof(tmp),",%04x\r\n",crc16);
- strcat(info, tmp);
- triggerMcuAndSend(info);
- }
- /*
- 设置MCU参数
- psn: 设备序列号
- led1:led1状态 网络状态 LNET_ENUM
- led2:led2状态 定位状态 LGPS_ENUM
- "<<SetMCU,psn,led1,led2,devinfotime,motiontime"
- */
- void setMcuPara(T_BOOL right_now){
- char info[100],tmp[10];
- unsigned short crc16;
- unsigned char led1=LNET_CONNTING;
- unsigned char led2=LGPS_LOCATING;
- static unsigned char lastLed1=LNET_HERROR;
- static unsigned char lastLed2=LGPS_HERROR;
- if(getServerAuth()==TRUE) led1=LNET_NORMAL;
- if(TRUE==isGpsLocated()) led2=LGPS_LOCATED;
- if(lastLed1==led1 && lastLed2==led2 && right_now==FALSE) return;
- lastLed1=led1;lastLed2=led2;
- snprintf(info, sizeof(info), "<<SetMCU,%d,%d,%d",sut_psn.psn,led1,led2);
- crc16=crc16Check(MCU_PRO_CRC16_INIT,info+2,strlen(info)-2);
- snprintf(tmp, sizeof(tmp),",%04x\r\n",crc16);
- strcat(info, tmp);
- triggerMcuAndSend(info);
- }
- /*获取Near信息
- near为LTE主动定时向MCU请求获取
- "<<GetNear,CRC"
- */
- void getNearInfo(void){
- char info[100],tmp[10];
- unsigned short crc16;
- snprintf(info, sizeof(info),"<<GetNear");
- crc16=crc16Check(MCU_PRO_CRC16_INIT,info+2,strlen(info)-2);
- snprintf(tmp, sizeof(tmp),",%04x\r\n",crc16);
- strcat(info, tmp);
- triggerMcuAndSend(info);
- }
- /*获取Motion信息
- motion为LTE主动定时向MCU请求获取
- "<<GetMotion,CRC"
- */
- void getMotionInfo(void){
- char info[100],tmp[10];
- unsigned short crc16;
- snprintf(info, sizeof(info),"<<GetMotion");
- crc16=crc16Check(MCU_PRO_CRC16_INIT,info+2,strlen(info)-2);
- snprintf(tmp, sizeof(tmp),",%04x\r\n",crc16);
- strcat(info, tmp);
- triggerMcuAndSend(info);
- }
- /*AP控制MCU升级
- psn:目标设备序列号
- version:最新版本号
- "<<Upgrade,psn,version"
- */
- void apUpgradeMcu(void){
- char info[100],tmp[10];
- unsigned short crc16;
- snprintf(info, sizeof(info),"<<Upgrade");
- crc16=crc16Check(MCU_PRO_CRC16_INIT,info+2,strlen(info)-2);
- snprintf(tmp, sizeof(tmp),",%04x\r\n",crc16);
- strcat(info, tmp);
- triggerMcuAndSend(info);
- }
- /*AP侧通知MCU复位整机*/
- void apRebootSys(void){
- char info[100],tmp[10];
- unsigned short crc16;
- snprintf(info, sizeof(info),"<<Reboot");
- crc16=crc16Check(MCU_PRO_CRC16_INIT,info+2,strlen(info)-2);
- snprintf(tmp, sizeof(tmp),",%04x\r\n",crc16);
- strcat(info, tmp);
- triggerMcuAndSend(info);
- }
- /*AP侧通知MCU关机*/
- void apShutDownSys(void){
- char info[100],tmp[10];
- unsigned short crc16;
- snprintf(info, sizeof(info),"<<ShutDown");
- crc16=crc16Check(MCU_PRO_CRC16_INIT,info+2,strlen(info)-2);
- snprintf(tmp, sizeof(tmp),",%04x\r\n",crc16);
- strcat(info, tmp);
- triggerMcuAndSend(info);
- }
- /*服务器通知LTE重启/关机整机,每秒定时发信息给MCU*/
- void apCtlMcu(void){
- if(app.sysCtl==0) return;
- else if(app.sysCtl==1) apRebootSys();
- else if(app.sysCtl==2) apShutDownSys();
- }
- /*
- 在一个字符串里获取字串,指定从第几个逗号开始,到下一个逗号或非打印字符结束
- 参数:
- Str: 指定源串
- subStr: 获取到的字串存放在此
- subStrLen:限制字串长度
- StartComma:从第几个逗号开始。 如果是0 表示从源串第一个字节开始,如果是1表示从第一个逗号后一个字节开始,以此类推
- 返回: 0--已找到 -1--未找到 -2--字串存放区空间不够(实际获取的字串长度大于subStrLen)
- */
- int GetSubStrWithComma(const char *Str,char *subStr,int subStrLen,int StartComma)
- {
- const char *p;
- char *ss;
- p=Str;
- ss=subStr;
- if(subStrLen<1)return -1;
- subStrLen-=1;//预留一个'\0'
- if(StartComma>0){
- while(StartComma>0){
- if(*p==',')StartComma--;
- p++;
- if(*p<33 || *p>127)break;
- }
- if(StartComma!=0)return -1;
- }
- if(*p<33 || *p>127)return -1;
- //--拷贝
- while(subStrLen>0){
- *ss=*p;
- ss++;
- p++;
- if(*p<33 || *p>127 || *p==',')break;
- subStrLen--;
- }
- if(subStrLen==0)return -2;
- *ss=0;
- return 0;
- }
- /*
- 统计字符串中逗号个数,搜索到非可见字符结束
- */
- int GetCommaNum(const char *Str)
- {
- int i=0;
- char ch;
- const char *p;
- p=Str;
- ch=*p;
- while(ch>=33 && ch<=127){
- if(ch==',')i++;
- p++;
- ch=*p;
- }
- return i;
- }
|