123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997 |
- #include "includes.h"
- #include "location.h"
- #include "lsapi_gps.h"
- #include "nmea.h"
- #define max_neighbor_cellbun 6//定义LSB能存的最大组数
- //#define NEED_NEAR_CELLS //使用邻近小区
- //最小星数个数条件
- #define GPS_MIN_NUM 2
- //开启GPS后,定位基本条件达到后最多等待时间
- //星数达到一定数目,最多等待GPS_WAIT_MAX_TIME,否则关闭GPS
- #define GPS_WAIT_MAX_TIME 10
- //开启GPS后,定位基本条件未达到最多等待时间
- //星数未达到一定数目,最多等待GPS_WAIT_TIME,否则关闭GPS
- #define GPS_WAIT_TIME 20
- //GPS定位后,延时一定时间等待稳定后取值
- #define GPS_STABLE_TIME 14 //因为GPS回调为5秒,故取14秒吧
- //第一次GPS定位所给予最大时间
- #define GPS_FIRST_VALID_TIME 180
- //每次重启GPS后,如果定位了,直接更新定位标记,否则超过此时间还未定位,则复位定位标志
- #define GPS_RESET_TIME 12
- //在非作业期间,如果采样间隔小于等此值,GPS采用常开工作模式
- #define KEEP_GPS_ON_UN_WORKTIME 15
- #if(GPS_RESET_TIME>=GPS_STABLE_TIME) //如果不加这个限制,当GPS异常不再回调后,每次打开GPS都会认为是已定位并取值,但实际都是以前的定位点
- #error "GPS时间不允许"
- #endif
- #ifdef NOT_USE_SERVER_INTERVAL
- #define GPS_SAMPLE_TIME 20 //采样间隔,测试
- #define GPS_LOCATED_MAX (60*5)
- #endif
- typedef enum{
- GS_IDLE, //GPS空闲,为关闭状态
- GS_START, //开始启动GPS
- GS_WAIT, //GPS已启动,等待定位
- GS_VALID, //GPS已定位
- GS_STABLE, //GPS定位延时稳定后取值
- GS_STOP, //停止GPS
- }GS_ENUM;
- typedef struct{
- T_UINT8 status; //GS_ENUM GPS业务状态
- T_UINT16 waitMaxCnt; //最大等待时间计数
- T_UINT16 waitCnt; //最小等待时间计数
- T_UINT8 resetCnt; //超时未定位复位定位标记计数
- T_UINT8 stableCnt; //等待稳定延时计数
- T_UINT8 gpsValid:1; //GPS定位标志 GPS_LOCATION_ENUM
- T_UINT8 gpsFirstValid:1; //第一次登陆过的标志
- T_UINT8 gpsLstValid:1;
- T_UINT8 gpsOnUse; //在用卫星个数
- T_UINT8 gpsOnView; //在范围卫星个数
- T_UINT8 gpsInterval; //定时起来定位
- T_UINT8 gpsDlyCnt; //用于常开模式下延时取值
- }GPS_DEF;
- GPS_DEF gps={
- .status=GS_START,//开机自动开启GPS任务
- .gpsInterval=0,
- .gpsFirstValid=0,
- .gpsOnUse=0,
- .gpsOnView=0,
- };
- T_UINT16 gpsRealSample;
- void gpsIntervalMaxInit(void){
- #ifdef NOT_USE_SERVER_INTERVAL
- gpsRealSample=GPS_SAMPLE_TIME;
- #else
- gpsRealSample=app.gnssSampleTime;
- #endif
- if(gpsRealSample<ALL_MIN_SAMPLE_TIME) gpsRealSample=ALL_MIN_SAMPLE_TIME;
- }
- T_BOOL isGpsLocated(void){
- if(gps.gpsValid==GPS_ACTIVE) return TRUE;
- else return FALSE;
- }
- /*
- 仅用于打印定位与/未定位的跳变
- */
- void gpsValidInfo(unsigned char status){
- static unsigned char lastStatus=0;
- if(lastStatus==status) return;
- if(status==0) wlog_info("GPS Unlocated");
- else wlog_info("GPS Located");
- lastStatus=status;
- }
- void showNmeaInfo(char *nmea,int len){
- int i;
- char ch,*nextPtr=nmea;
- for(i=0;i<len;i++){
- if(ch=='\r' && nmea[i]=='\n'){
- ch=nmea[i+1];
- nmea[i+1]=0;
- msgToOutter(nextPtr);
- nextPtr=&nmea[i+1];
- nmea[i+1]=ch;
- }
- ch=nmea[i];
- }
- }
- #define AGPS_GET_INTERVAL (60*60*2) //获取AGPS星表时间间隔
- LSAPI_OSI_Thread_t* agpsThread=NULL;
- static int64_t agpsNextTime=0;
- static unsigned char agpsFailNum=0;
- /*
- 尝试打开APGS
- 打开成功后,如果获取成功,会自动关闭,下次需要时再打开
- */
- static void agpsEntry(void *param){
- wlog_info("agpsEntry start ok");
- LSAPI_OSI_Event_t event = {};
- for(;;){
- LSAPI_OSI_EventWait(LSAPI_OSI_ThreadCurrent(), &event);
- if(event.id==USER_ENENT_AGPS){
- if(true==LSAPI_GPS_Check_Eph_Valid()){
- wlog_info("agps is already valid");
- agpsNextTime += AGPS_GET_INTERVAL;
- }else{
- wlog_info("exe agps api");
- if(0==LSAPI_GPS_Write_EPH()){
- agpsNextTime += AGPS_GET_INTERVAL;
- wlog_info("agps set valid ok");
- agpsFailNum=0;
- }else{
- wlog_warn("agps set valid failed");
- agpsNextTime += AGPS_GET_INTERVAL;
- agpsFailNum++;
- }
- }
- }
- }
- agpsThread=NULL;
- LSAPI_OSI_ThreadExit();
- }
- void tryToEnableAgps(void){
- if(agpsThread==NULL){
- agpsThread=LSAPI_OSI_ThreadCreate("agpsEntry", agpsEntry, NULL, LSAPI_OSI_PRIORITY_NORMAL, AGPS_THRAD_THREAD_STACK, 4);
- if(agpsThread==NULL){
- wlog_warn("agpsThread create error");
- agpsNextTime += 30;
- return;
- }
- }
- threadPostEvent(agpsThread,USER_ENENT_AGPS ,NULL);
- }
- /*AGPS控制
- 当打开了GPS时,尝试打开AGPS
- AGPS为一次性,打开成功后会自动关闭
- 下次一次成,最少能使用2个小时
- */
- void agpsCtl(void){
- int64_t tmp;
- static unsigned char cnt=0;
- if(agpsFailNum>=5){
- if(++cnt>=5){
- cnt=0;
- wlog_warn("Agps Open faild in %d time, stop use agps", agpsFailNum);
- }
- return;
- }
- if(app.netWork.netReayd!=0){//尝试打开AGPS
- if(cnt==0){//5秒读一次时间比较
- tmp=LSAPI_OSI_UpTime()/1000;
- if(tmp>agpsNextTime){
- agpsNextTime=tmp;
- tryToEnableAgps();
- }else wlog_info("agps:%d",agpsNextTime-tmp);
- }
- if(++cnt>=5) cnt=0;
- }else cnt=0;
- }
- #ifdef ENABLE_SET_GPS_INTERVAL
- //如果设定GPS回调为5秒,则GPS无响应超时值设置为5*10=50秒
- #define MAX_CNT_FOR_GPS_TIMEOUT 50
- #else
- //如果设定GPS回调为1秒,则GPS无响应超时值设置为1*10=10秒
- #define MAX_CNT_FOR_GPS_TIMEOUT 10
- #endif
- /*
- $GNXXX
- 我们需要
- $GNRMC
- $GNGSA
- */
- static T_UINT8 cntAfterNoCb=0;
- void gpsCntChecker(void){
- static char rstgps=0;
- #if 0
- if(app.gpsPwrStatus==FALSE){
- app.gpsCallBackCnt=0;
- return;
- }
- if(++app.gpsCallBackCnt>=MAX_CNT_FOR_GPS_TIMEOUT){
- app.gpsCallBackCnt=0;
- wlog_error("gpsCallBackCnt over,reboot sys!!!");
- #if 0//for test only
- outterInfo("gpsCntChecker to TG mode\r\n",26);
- app.tgMode=TRUE;
- return;
- #endif
- #ifdef TAKE_NOTE_FOR_REBOOT
- saveRebootReason("gpsCntChecker\r\n");
- #endif
- LSAPI_OSI_ThreadSleep(500);
- LSAPI_SYS_reboot();
- }
- #else
- if(rstgps==1){
- wlog_error("gpsCallBackCnt stop gps!!");
- gpsStop();
- rstgps=2;
- return;
- }else if(rstgps==2){
- wlog_info("gpsCallBackCnt start gps!!");
- gpsStart();
- app.gpsCallBackCnt=0;
- rstgps=0;
- }
- if(app.gpsPwrStatus==FALSE){
- app.gpsCallBackCnt=0;
- return;
- }
-
- if(++app.gpsCallBackCnt>=MAX_CNT_FOR_GPS_TIMEOUT){
- app.gpsCallBackCnt=0;
- if(++cntAfterNoCb>=3){
- cntAfterNoCb=0;
- if(app.vcharge<30){
- wlog_error("gpsCallBackCnt reboot!!");
- #ifdef TAKE_NOTE_FOR_REBOOT
- saveRebootReason("gpsCntChecker\r\n");
- #endif
- LSAPI_OSI_ThreadSleep(500);
- LSAPI_SYS_reboot();
- }else wlog_warn("dev is charging, skip reboot");
- }else{
- wlog_error("gpsCallBackCnt reset gps!!");
- rstgps=1;
- }
- }
- #endif
- }
- char gpsTmp[1024+512];
- int gpsLen;
- void get_location_callback(void *location,int len){
- int i,index;
- char *rmc,*gsa,*src,ch,*nextPtr;
- unsigned char done=0;
- unsigned char onUseGps=0,onViewGps=0,onViewBd=0;
- char *ptr=(char *)location;
- cntAfterNoCb=0;
- app.gpsCallBackCnt=0;
- if(len>=sizeof(gpsTmp)){
- wlog_warn("gpstmp over, return");
- return;
- }
- gpsLen=0;
- for(i=0;i<len;i++) gpsTmp[gpsLen++]=ptr[i];
- gpsTmp[gpsLen]=0;
- if(app.tgMode==TRUE){
- showNmeaInfo(gpsTmp,gpsLen);
- return;
- }
- #if defined ENABLE_QUE_TASK_LOCK
- uint32_t osFlag;
- osFlag=osiSchedulerSuspend();
- #endif
- //处理并更新定位标志gps.gpsValid以及相关位置变量
- src=gpsTmp;
- nextPtr=src;
- for(i=0;i<len;i++){
- if(ch=='\r' && src[i]=='\n'){
- src[i-1]=0;
- if(0==memcmp(nextPtr, "$GNGGA",6)){//获取在使用卫星数
- //$GNGGA,080420.00,2237.25706,N,11402.10753,E,1,07,6.20,85.3,M,-2.2,M,,*68
- //wlog_info(nextPtr);
- index=findByteFromStr(nextPtr, strlen(nextPtr),',',7);
- if(index>=0){
- index=atoi(nextPtr+index);
- onUseGps=index;
- }
- done |= 1<<0;
- }else if(0==memcmp(nextPtr, "$GPGSV",6)){//获取在范围GPS卫星数
- //$GPGSV,3,2,12,12,33,272,,13,21,180,34,15,02,205,,17,29,136,36,0*61
- //wlog_info(nextPtr);
- index=findByteFromStr(nextPtr, strlen(nextPtr),',',3);
- if(index>=0){
- index=atoi(nextPtr+index);
- onViewGps=index;
- }
- done |= 1<<1;
- }else if(0==memcmp(nextPtr, "$BDGSV",6)){//获取在范围GPS卫星数
- //$BDGSV,4,1,13,01,46,124,28,02,48,238,,03,65,189,29,04,33,110,36,0*70
- //wlog_info(nextPtr);
- index=findByteFromStr(nextPtr, strlen(nextPtr),',',3);
- if(index>=0){
- index=atoi(nextPtr+index);
- onViewBd=index;
- }
- done |= 1<<2;
- }else if(0==memcmp(nextPtr, "$GNRMC",6)){//获取定位信息
- //$GNRMC,080410.00,A,2237.25264,N,11402.10765,E,0.018,,030720,,,A,V*16
- //wlog_info(nextPtr);
- nmeaRmc(nextPtr+7);
- done |= 1<<3;
- }
- nextPtr=&src[i+1];
- }
- ch=src[i];
- if(done==0x0F) break;
- }
-
- //更新参数
- gps.gpsOnUse=onUseGps;
- gps.gpsOnView=onViewGps+onViewBd;
- gpsValidInfo(nmeaInfo.isGpsValid);
- gps.gpsValid=nmeaInfo.isGpsValid;
- if(gps.gpsValid==GPS_INVALID){
- gps.gpsDlyCnt=0;
- #if defined ENABLE_QUE_TASK_LOCK
- osiSchedulerResume(osFlag);
- #endif
- return;
- }
- gps.gpsFirstValid=gps.gpsValid;
- #if defined ENABLE_QUE_TASK_LOCK
- osiSchedulerResume(osFlag);
- #endif
- //如果已休眠,定位成功时,可以唤醒一下
- WakeupNow("gps call_cb located");
- }
- #ifdef ENABLE_SET_GPS_INTERVAL
- #define GPS_INTERVAL "$CCINV,5000*78"
- void setGpsInterval(void){
- LSAPI_OSI_ThreadSleep(1000);
- if(false==LSAPI_SendData_To_GPS(GPS_INTERVAL,strlen(GPS_INTERVAL))) wlog_warn("!!!GPS INTERVAL SET FAILSE");
- else wlog_warn("!!!GPS INTERVAL SET OK");
- }
- #else
- void setGpsInterval(void){
- return;
- }
- #endif
- LSAPI_OSI_Thread_t *threadid_gps = NULL;
- void gpsEntry(void *param){
- LSAPI_OSI_Event_t event = {};
- wlog_info("gpsEntry thread start");
- for(;;){
- LSAPI_OSI_EventWait(threadid_gps, &event);
- wlog_info("gpsEntry get event:%d",event.param1);
- if(event.param1==1){//打开GPS
- if(app.gpsPwrStatus==FALSE){
- LSAPI_GPS_Init();
- LSAPI_GPS_Set_StartMode(GPS_START_MODE_HOT);
- LSAPI_GPS_Set_ANTMode(1);//0 无源 1 有源
- LSAPI_GPS_Open(NULL);
- setGpsInterval();
- LSAPI_GPS_Get_ALLData(get_location_callback);
- app.gpsPwrStatus=TRUE;
- wlog_info("gps start done");
- }else wlog_info("gps already on");
- }else if(event.param1==0){//关闭GPS
- LSAPI_GPS_Close();
- nmeaInfo.isGpsValid=GPS_INVALID;
- app.gpsPwrStatus=FALSE;
- wlog_info("gps stop done");
- }
- }
- threadid_gps=NULL;
- LSAPI_OSI_ThreadExit();
- }
- void gpsStart(void){
- wlog_info("try to start gps");
- if(NULL==threadid_gps){
- threadid_gps=LSAPI_OSI_ThreadCreate("gps",gpsEntry,NULL,LSAPI_OSI_PRIORITY_NORMAL,GPS_THREAD_STACK,4);
- if(NULL==threadid_gps){
- wlog_error("gps thread create failed!");
- return;
- }
- }
- wlog_info("gps send start event");
- threadPostEvent(threadid_gps,USER_EVENT_GPS,1);//start gps
- }
- void gpsStop(void){
- wlog_info("try to stop gps");
- gps.status=GS_IDLE;
- if(NULL==threadid_gps){
- wlog_warn("gps thread off, quit gpsStop");
- return;
- }
- wlog_info("gps send stop event");
- threadPostEvent(threadid_gps,USER_EVENT_GPS,0);//stop gps
- wlog_info("GPS Stop,restart after %ds",gpsRealSample);
- }
- void ActiveTgMode(void){
- app.tgMode=TRUE;
- gpsStart();
- }
- /*
- ptLocationTask任务投票处理
- */
- void isLocationTaskIdle(void){
- if(GS_IDLE==gps.status || GS_WAIT==gps.status) ticketVote(TICKET_PT_LOCATION);//开关模式下的等待定位时也可以休眠
- else ticketDeVote(TICKET_PT_LOCATION);
- }
- /*
- 控制GPS任务运行与停止
- 默认情况GPS任务一直运行
- 此功能API只提供mcuiap使用
- */
- void locationWorkCtl(T_BOOL status){
- #ifdef KEEP_GPS_ON_FOEVER
- if(TRUE==status) gpsStart();
- else gpsStop();
- #else
- if(TRUE==status){
- gps.status=GS_START;
- }else gpsStop();
- #endif
- }
- /*非作业期间,根据采样间隔,判定GPS是否执行常开业务或开关业务*/
- T_BOOL isGpsKeepOnByTime(void){
- if(gpsRealSample<=KEEP_GPS_ON_UN_WORKTIME) return TRUE;
- else return FALSE;
- }
- /*作业期间GPS业务逻辑:常开工作
- 非作业期间GPS采样时间小于设定限值:常开工作*/
- void gpsKeepOnToWork(void){
- static T_BOOL isGpsStart=FALSE;
- if(FALSE==isGpsStart){//打开GPS
- gpsStart();
- isGpsStart=TRUE;
- }
- ticketVote(TICKET_PT_LOCATION);
- if(gps.gpsValid != gps.gpsLstValid){
- if(gps.gpsValid==GPS_ACTIVE) gps.gpsInterval=gpsRealSample;//从未定位到定位,直接可以取值,当然,第一次时会延时
- gps.gpsLstValid=gps.gpsValid;
- }
- if(gps.gpsValid==GPS_ACTIVE){//已定位
- if(++gps.gpsInterval>=gpsRealSample){
- if(++gps.gpsDlyCnt>GPS_STABLE_TIME){
- //保存一个记录点
- gps.gpsInterval=0;
- gnssInfoSave();
- gps.gpsDlyCnt=GPS_STABLE_TIME;
- }else{
- wlog_info("Delay cnt:%d<%d",gps.gpsDlyCnt,GPS_STABLE_TIME);
- ticketDeVote(TICKET_PT_LOCATION);//不让休眠,否则gps.gpsDlyCnt不准
- }
- }
- }else gps.gpsInterval=0;//未定位时可以休眠最大时间
- }
- /*非作业期间GPS采样时间大于设定限值:开关工作*/
- void gpsOnOffToWork(void){
- static T_UINT16 lastWaitCnt=0;
- T_BOOL needsave=FALSE;
- switch(gps.status){
- case GS_IDLE:
- if(++gps.gpsInterval >= gpsRealSample){
- gps.gpsInterval=0;
- gps.status=GS_START;
- }
- break;
- case GS_START://启动GPS
- gps.status=GS_WAIT;
- gps.waitCnt=0;
- gps.waitMaxCnt=0;
- gps.resetCnt=0;
- gps.gpsOnUse=0;
- gps.gpsOnView=0;
- //gps.gpsValid=GPS_INVALID;//不主动关闭
- gps.gpsInterval=0;
- gpsStart();
- break;
- case GS_WAIT:
- //定位过程中,打印下计数值吧
- if(gps.waitCnt>lastWaitCnt+5){
- wlog_info("gps onTime:%d",gps.waitCnt);
- lastWaitCnt=gps.waitCnt;
- }
- //检测GPS定位标志,定位则切换状态
- if(gps.gpsValid==GPS_ACTIVE){
- gps.status=GS_VALID;
- break;
- }
- #ifdef NOT_USE_SERVER_INTERVAL
- if(++gps.waitCnt>=GPS_LOCATED_MAX){
- wlog_warn("gps timeout");
- needsave=TRUE;
- gps.status=GS_STOP;
- }
- #else
- //定位时间超时检测
- if(gps.gpsFirstValid==1){//已定位过了
- if(gps.gpsOnUse<GPS_MIN_NUM){
- if(++gps.waitCnt>=GPS_WAIT_TIME){
- //星数条件差但超时未定位,退出
- wlog_warn("gps weak timeout");
- needsave=TRUE;
- gps.status=GS_STOP;
- }
- }else{
- if(++gps.waitMaxCnt>=GPS_WAIT_MAX_TIME){
- //星数条件好但超时未定位,退出
- wlog_warn("gps strong timeout");
- needsave=TRUE;
- gps.status=GS_STOP;
- }
- }
- }else{
- if(++gps.waitCnt>=GPS_FIRST_VALID_TIME){
- wlog_warn("gps first valid timeout");
- needsave=TRUE;
- gps.status=GS_STOP;
- }
- }
- #endif
- //定位标志超时复位检测
- if(++gps.resetCnt>=GPS_RESET_TIME){
- gps.gpsValid=GPS_INVALID;
- gps.resetCnt=0;
- }
- break;
- case GS_VALID:
- gps.stableCnt=0;
- gps.status=GS_STABLE;
- break;
- case GS_STABLE:
- if(gps.gpsValid==GPS_INVALID){
- //在等待稳定期间突然定位不了了,继续回到GS_WAIT状态,计数值不清0,按原来时间顺延
- gps.status=GS_WAIT;
- break;
- }
- if(++gps.stableCnt>=GPS_STABLE_TIME){
- //稳定后得到了定位数据,这里是要保存定位数据等待上传时刻到来执行上传
- wlog_info("Get valid gps data:%lu,%lu",nmeaInfo.Latitude,nmeaInfo.Longitude);
- needsave=TRUE;
- gps.status=GS_STOP;
- }
- break;
- case GS_STOP:
- gpsStop();
- gps.gpsInterval=0;
- break;
- }
- if(needsave==TRUE) gnssInfoSave();
- isLocationTaskIdle();
- }
- /*
- GPS定位及逻辑控制pt任务
- */
- PT_THREAD (ptLocationTask(pt_timer_t *ptPool, struct pt *pt)){
- static pt_timer_t ptTimer;
- static unsigned char lastWorkZone=0xff;
- static unsigned char forceGpsOnOffMode=35;
- PT_BEGIN(pt);
- while(1){
- //检测作业状态变化
- if(sut_para.forceGpsOnOffMode != forceGpsOnOffMode){
- forceGpsOnOffMode=sut_para.forceGpsOnOffMode;
- wlog_warn("gpsForce:%s", (forceGpsOnOffMode!=0)?"keep on":"onOff");
- }
- if(forceGpsOnOffMode==0) gpsOnOffToWork();
- else{
- if(lastWorkZone != app.onWorkZone){
- lastWorkZone=app.onWorkZone;
- //工作状态发变化,检查GPS状态
- if(lastWorkZone==0){//从作业状态变为非作业状态
- wlog_warn("work-->non_work");
- if(isGpsKeepOnByTime()==TRUE){//采样小于设定值,GPS继续常开工作模式
- wlog_warn("gps keep on mode");
- }else{//GPS开关工作模式
- wlog_warn("gps onOff mode");
- gps.status=GS_WAIT;
- gps.waitCnt=0;
- }
- }else{//从非作业状态变为作业状态
- wlog_warn("non_work-->work");
- gps.gpsValid=GPS_INVALID;//消除定位标记
- }
- gps.gpsInterval=0;
- if(app.gpsPwrStatus==FALSE) gpsStart();
- }
- //定向工作模式
- if(lastWorkZone==0) gpsOnOffToWork();
- else gpsKeepOnToWork();
- }
- //apgs工作
- agpsCtl();
- PTTimerStart(ptPool, &ptTimer,100);
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- }
- PT_END(pt);
- }
- /*
- 获取GPS可休眠时间,投票ticket调用
- */
- T_INT32 getLocationCnt(void){
- T_INT32 value;
- if(app.onWorkZone==0 && FALSE==isGpsKeepOnByTime()){//开关模式下
- return 5;//开关模式下可以睡长一些,只要定位上,会唤醒的
- }else{//常开模式下
- value=gpsRealSample-gps.gpsInterval;
- if(value<=0) return 0;
- else return value;
- }
- }
- /*
- 每次休眠唤醒后更新GPS逻辑计数值
- */
- void locationCntUpdate(T_INT32 value){
- if(gps.gpsInterval+value > gpsRealSample) gps.gpsInterval=gpsRealSample;
- else gps.gpsInterval += value;
- gps.waitCnt += value;
- }
- /*将定位信息更新到记录结构体中*/
- void gnssInfoSave(void){
- char ret;
- #if defined ENABLE_QUE_TASK_LOCK
- uint32_t osFlag;
- osFlag=osiSchedulerSuspend();
- #endif
-
- memset((unsigned char *)gGnssInfo, 0, sizeof(GNSSINFO_DEF));
- memcpy(gGnssInfo->BCDTime, getBCDDateTime(), sizeof(gGnssInfo->BCDTime));
- if(gps.gpsValid==GPS_ACTIVE) gGnssInfo->located=1;
- else gGnssInfo->located=0;
- gGnssInfo->onUseGps=gps.gpsOnUse;
- gGnssInfo->onViewGps=gps.gpsOnView;
- gps.gpsOnUse=0;gps.gpsOnView=0;
- if(gps.gpsValid==GPS_ACTIVE){
- gGnssInfo->latitude=nmeaInfo.Latitude;
- gGnssInfo->longitude=nmeaInfo.Longitude;
- gGnssInfo->height=nmeaInfo.Altitude;
- gGnssInfo->speed=nmeaInfo.Speed;
- gGnssInfo->direction=nmeaInfo.Aspect;
- }
- #if defined ENABLE_QUE_TASK_LOCK
- osiSchedulerResume(osFlag);
- #endif
- if(gps.gpsValid!=GPS_ACTIVE) return;
- //保存
- ret=recordSave(REC_GNSSINFO,(void *)&sut_saveRecGnss);
- wlog_info("gnss save ret:%d",ret);
- GnssRecShow();
- }
- ///////////////////////////////////////LSB///////////////////////////////////////////////////
- int getGnssCnt(void){
- int leftTime;
- leftTime=getBaseSeconds()%app.gnssSampleTime;
- if(leftTime==0) return NO_SLEEP_TIME;
- else return (app.gnssSampleTime-leftTime);
- }
- static unsigned char lbsStatus=0; //0未开启获取 1正在获取 2获取超时 3获取成功 4获取失败
- static unsigned char motionStatus=0;//0未开启获取 1正在获取 2获取超时 3获取成功 4获取失败
- static unsigned char lm_cnt=0;
- LSAPI_OSI_Thread_t *lbsThread=NULL;
- void motionGetOk(void){motionStatus=3;}
- #ifdef NEED_NEAR_CELLS
- /*
- 根据LBS值得到经纬度值的回调
- */
- void lbs_callback(void *lac,void *lng){
- wlog_info("lbs_callback:lac=%s,lng=%s",lac,lng);//lac=22.6182549,lng=114.0404818
- }
- #endif
- void lbsStart(void){
- LSAPI_CellLocation_t nCellInfo[max_neighbor_cellbun];
- //SUTDS ds;
- int num,count;
- if(app.netWork.netReayd==0) return;
- //先获取主小区信息
- memset(nCellInfo,0x00,sizeof(nCellInfo));
- LSAPI_NET_CellInfo(nCellInfo,LSAPI_pCurrCellInfo,0);
- if(nCellInfo[0].sCellID != 0){
- lbsStatus=3;
- //mcc
- gDevInfo->mcc=nCellInfo[0].sMcc[0]*100+nCellInfo[0].sMcc[1]*10+nCellInfo[0].sMcc[2];
- //lac
- gDevInfo->lac=nCellInfo[0].sLac;
- //cellid
- gDevInfo->cellid=nCellInfo[0].sCellID;
- //mnc
- if(nCellInfo[0].sMnc[2]==0x0f) gDevInfo->mnc=nCellInfo[0].sMnc[0]*10+nCellInfo[0].sMnc[1];
- else gDevInfo->mnc=nCellInfo[0].sMnc[0]*100+nCellInfo[0].sMnc[1]*10+nCellInfo[0].sMnc[2];
- wlog_info("mcc:%d,mnc:%d,lac:%x,cellid:%x",gDevInfo->mcc,gDevInfo->mnc,gDevInfo->lac,gDevInfo->cellid);
- }else lbsStatus=4;
-
- #ifdef NEED_NEAR_CELLS
- //再获取邻近小区信息
- memset(nCellInfo,0x00,sizeof(nCellInfo));
- LSAPI_NET_CellInfo(nCellInfo,LSAPI_NeighborCellInfo,0);
- num=nCellInfo[0].neighbor_cellnum;
- wlog_info("neighbor num:%d",num);
- if(num>=3) LSAPI_LBS_Location(nCellInfo,lbs_callback,0);//有3个邻近以上则获取经纬度
- #endif
- }
- /*
- LBS获取线程
- */
- void CEllEntry(void *param)
- {
- wlog_info("CellEntry init");
- LSAPI_OSI_Event_t event = {};
- for(;;){
- LSAPI_OSI_EventWait(LSAPI_OSI_ThreadCurrent(), &event);
- if(event.id==USER_EVENT_LSB) lbsStart();
- }
- lbsThread=NULL;
- LSAPI_OSI_ThreadExit();
- }
- /*
- LBS初始化操作
- pt任务会调用
- */
- void CellInit(void){
- static T_BOOL cellActive=FALSE;
- if(app.netWork.netReayd==0) return;
- if(cellActive==TRUE) return;
- //创建LBS线程获取LBS
- lbsThread=LSAPI_OSI_ThreadCreate("cellid", CEllEntry,NULL,LSAPI_OSI_PRIORITY_NORMAL,LBS_THREAD_STACK,4);
- cellActive=TRUE;
- }
- /*
- 获取LBS接口
- */
- void getLbsMotionNow(void){
- threadPostEvent(lbsThread,USER_EVENT_LSB,NULL);
- }
- void isLbsMotionIdle(void){
- int csq;
- char ret;
- lm_cnt++;
- if(lbsStatus==1 && lm_cnt>=5){
- lbsStatus=2;
- wlog_warn("get lbs timeout");
- }
- if(motionStatus==1 && lm_cnt>=5){
- motionStatus=2;
- wlog_warn("get motion timeout");
- }
-
- if(lm_cnt>=5 || ((lbsStatus==3 || lbsStatus==4) && (motionStatus==3 || motionStatus==4))){
- //结束(成功/失败/超时)
- ticketVote(TICKET_PT_LBSMOTION);
- //检测是否需要保存消息
- if(lbsStatus==3 || motionStatus==3){
- //保存记录
- //获取CSQ
- #if 1
- if(0==LSAPI_NET_GetCsq(&csq)) gDevInfo->csq=(unsigned char)csq;
- else gDevInfo->csq=99;//获取失败,认为异常
- gDevInfo->bat=app.vBatPersent;
- gDevInfo->hardWareStatus=app.hardWareSta;
- gDevInfo->warnStatus=app.warnStatus;
- //保存获取到的时间
- memcpy(gDevInfo->BCDTime, getBCDDateTime(), sizeof(gDevInfo->BCDTime));
- //保存
- ret=recordSave(REC_DEVINFO,(void *)&sut_saveRecDev);
- DevRecShow();
- #endif
- wlog_warn("recordSave:lsb=%d,mot=%d,ret=%d",lbsStatus,motionStatus,ret);
- lbsStatus=0;motionStatus=0;
- }
- }
- if((getBaseSeconds()%app.devSampleTime)==0){
- wlog_info("start get lsb/motion");
- lm_cnt=0;
- clearLbsMotionOfDevinfo();
- if(motionStatus != 1){
- motionStatus=1;
- getMotionInfo();
- }
- if(lbsStatus != 1){
- lbsStatus=1;
- getLbsMotionNow();
- }
- ticketDeVote(TICKET_PT_LBSMOTION);
- }
- }
- static T_UINT16 lbsCnt=0;
- /*
- 获取LBS与MOTION逻辑控制pt任务
- */
- PT_THREAD (ptLbsMotionTask(pt_timer_t *ptPool, struct pt *pt)){
- static pt_timer_t ptTimer;
- CellInit();
- PT_BEGIN(pt);
- while(1){
- isLbsMotionIdle();
- PTTimerStart(ptPool, &ptTimer,100);
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- }
- PT_END(pt);
- }
- #define COMPARE_BY_MINUTE
- /*判定当前时间是在工作期间与否*/
- T_BOOL isOnWorkZoneNow(void){
- unsigned char *curTime;
- ARRANGE_SEG_DEF *arrange;
- int i;
- #ifdef FORCE_ONWORK_STATUS
- return TRUE;
- #endif
- #ifdef COMPARE_BY_MINUTE
- unsigned int curT,startT,endT;
- #endif
- curTime=getBCDDateTime();
- if(0!=memcmp(curTime, sut_para.arrange.bcdDate,sizeof(sut_para.arrange.bcdDate))) return FALSE;
- if(sut_para.arrange.num==0) return FALSE;
- for(i=0;i<sut_para.arrange.num;i++){
- arrange=&sut_para.arrange.arrangeList[i];
- #ifdef COMPARE_BY_MINUTE
- //转换成分钟来比较
- curT=bcdToDec(curTime[3])*60+bcdToDec(curTime[4]);
- startT=bcdToDec(arrange->startH)*60+bcdToDec(arrange->startM);
- endT=bcdToDec(arrange->endH)*60+bcdToDec(arrange->endM);
- if(curT>=startT && curT<endT) return TRUE;
- #else
- if(curTime[3]==arrange->startH && curTime[3]==arrange->endH){
- if(curTime[4]>=arrange->startM && curTime[4]<=arrange->endM) return TRUE;
- }else if(curTime[3]>=arrange->startH && curTime[3]<arrange->endH) return TRUE;
- #endif
- }
- return FALSE;
- }
- /*实际使用GPS采样间隔限制*/
- void forceGnssInterval(void){
- T_UINT16 maxInterval;
- if(app.onWorkZone==0) maxInterval=60;
- else maxInterval=20;
- if(app.gnssSampleTime<maxInterval){
- app.gnssSampleTime=maxInterval;
- wlog_warn("gnss interval too small, force to %d",maxInterval);
- }
- }
- /*定期检测当前是否发生工作期与非工作期间的切换
- 通过创建定时器实现每分钟检测
- */
- void onWorkChecking(T_BOOL right_now){
- unsigned char status=TRUE,nowStatus;
- if(app.onWorkZone==0) status=FALSE;
- nowStatus=isOnWorkZoneNow();
- if(status==nowStatus && FALSE==right_now) goto SHOW_INFO;
- //工作状态发生变化
- if(nowStatus==TRUE){
- app.onWorkZone=1;
- app.devSampleTime=sut_para.devSampleInterval;
- app.gnssSampleTime=sut_para.gnssSampleInterval;
- app.nearSampleTime=sut_para.nearSampleInterval;
- app.dataUploadTime=sut_para.dataUploadInterval;
- //是否需要更新当前每项的计数值
- }else{
- app.onWorkZone=0;
- app.devSampleTime=sut_para.devSampleInterval_N;
- app.gnssSampleTime=sut_para.gnssSampleInterval_N;
- app.nearSampleTime=sut_para.nearSampleInterval_N;
- app.dataUploadTime=sut_para.dataUploadInterval_N;
- }
- SHOW_INFO:
- if(nowStatus==TRUE) wlog_info("onWorkNow");
- else wlog_info("non_onWorkNow");
- forceGnssInterval();
- wlog_info("[para]devInt:%d,gnssInt:%d,nearInt:%d,dataInt:%d",sut_para.devSampleInterval,sut_para.gnssSampleInterval,sut_para.nearSampleInterval,sut_para.dataUploadInterval);
- wlog_info("[para]devIntN:%d,gnssIntN:%d,nearIntN:%d,dataIntN:%d",sut_para.devSampleInterval_N,sut_para.gnssSampleInterval_N,sut_para.nearSampleInterval_N,sut_para.dataUploadInterval_N);
- wlog_info("[app]devInt:%d,gnssInt:%d,nearInt:%d,dataInt:%d",app.devSampleTime,app.gnssSampleTime,app.nearSampleTime,app.dataUploadTime);
- gpsIntervalMaxInit();
- }
- LSAPI_OSI_Timer_t *pOnWorktimer_t = NULL;
- LSAPI_OSI_Thread_t *threadid_onworktimer = NULL;
- void onWorkTimeout_cb(void *param){
- WakeupNow("onWorkTimeout_cb");
- LSAPI_OSI_TimerStop(pOnWorktimer_t);
- onWorkChecking(FALSE);
- if(pOnWorktimer_t != NULL){
- LSAPI_OSI_TimerStart(pOnWorktimer_t, 60*1000);
- wlog_info("onWorkTimer restart ok");
- }
- }
- void onWorkTimerEntry(void *param){
- LSAPI_OSI_Event_t event = {};
- wlog_info("onWorkTimerEntry start");
- if(NULL==pOnWorktimer_t){
- pOnWorktimer_t = LSAPI_OSI_TimerCreate(LSAPI_OSI_ThreadCurrent(), onWorkTimeout_cb, NULL);
- if(pOnWorktimer_t==NULL) wlog_error("pOnWorktimer_t create error");
- else{
- LSAPI_OSI_TimerStart(pOnWorktimer_t, 60*1000);
- wlog_info("onWorkTimerInit done");
- }
- }
- for(;;){
- LSAPI_OSI_EventWait(LSAPI_OSI_ThreadCurrent(), &event);
- }
- }
- void onWorkTimerInit(void){
- if(NULL!=threadid_onworktimer) return;
- threadid_onworktimer = LSAPI_OSI_ThreadCreate("onWorkTimer", onWorkTimerEntry,NULL,LSAPI_OSI_PRIORITY_NORMAL,ONWORKTIMER_THREAD_STACK,4);
- if(NULL==threadid_onworktimer) wlog_error("onWorkTimer create failed");
- }
- /////////////////////////////////////////////以下为NEAR信息收集pt任务
- static unsigned char nearStatus=0; //0未开启获取 1正在获取 2获取超时 3获取成功 4获取失败
- static unsigned char near_cnt=0;
- void getNearOk(void){nearStatus=3;}
- void isNearIdle(void){
- char ret;
- near_cnt++;
- if(nearStatus==1 && near_cnt>=5){
- nearStatus=2;
- wlog_warn("get near timeout");
- }
-
- if(near_cnt>=5 || (nearStatus==3 || nearStatus==4)){
- //结束(成功/失败/超时)
- ticketVote(TICKET_PT_NEAR);
- //检测是否需要保存消息
- if(nearStatus==3){
- //保存记录
- if(gNearInfo->num>0){
- //保存获取到的时间
- //时间已在前面保存了
- //保存
- ret=recordSave(REC_NEARINFO,(void *)&sut_saveRecNear);
- NearRecShow();
- wlog_warn("recordSave:nearNum=%d,ret=%d",gNearInfo->num,ret);
- }else wlog_warn("no near num");
- nearStatus=0;
- }
- }
- if((getBaseSeconds()%app.nearSampleTime)==0){
- wlog_info("start get near info");
- near_cnt=0;
- gNearInfo->num=0;//每次获取near前,清掉个数即可
- if(nearStatus != 1){
- nearStatus=1;
- getNearInfo();
- }
- ticketDeVote(TICKET_PT_NEAR);
- }
- }
- PT_THREAD (ptNearTask(pt_timer_t *ptPool, struct pt *pt)){
- static pt_timer_t ptTimer;
- PT_BEGIN(pt);
- while(1){
- isNearIdle();
- PTTimerStart(ptPool, &ptTimer,100);
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- }
- PT_END(pt);
- }
- /*获取near下次采样时间
- 用于投票使用
- */
- int getNearCnt(void){
- int leftTime;
- leftTime=getBaseSeconds()%app.nearSampleTime;
- if(leftTime==0) return NO_SLEEP_TIME;
- else return (app.nearSampleTime-leftTime);
- }
|