#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> //计算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;iinfo[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), "<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; }