#include "nb.h"
#include "led.h"
#define BUF_TAB 150//320
#define MAX_BUF_BODY 150//320
#define BUF_PTAB 32
#define BUF_PTAB2 32
char HARDWARE_VER[] = {"V10"};
char SOFTWARE_VER[] = {"ZX-D22-NB-A"};
char MANUFACTURER_NAME[] = {"zhongxunzhikong"};
char TERMINAL_TYPE[] = {"AEP"};
const u16 LEDflashSearchSignal[]={60,500,0};///
const u16 LEDflash_NB_conn_aep[]={550,0,0};//
const u16 LEDflash_NB_fault[]={50,50,0};//
STRU_NB *nb = &struNb;
AT_STAT at_cmd_return( const STRU_AT *at );
AT_STAT at_cmd_list_return( const STRU_AT *at );
u16 nb_parse( const char *p);
u8 run_nbTask_lock=0;
u16 delaytime_nb_alarm = 0;
extern const char *server_ip;
extern const u16 server_port;
extern const u16 LEDflashTcpOK[3];
extern const u16 LEDflashTcpEER[3];
char tab[BUF_TAB];
char ptab[BUF_PTAB];
char ptab2[BUF_PTAB2];
char body_buf[MAX_BUF_BODY];
char imei[20];
char imsi[20];
char iccid[25];
u8 sn;
/*********************************************************************************************************
AT指令定义表
*********************************************************************************************************/
#if (NBIOT == Y7025)
const STRU_AT struAtInitNB[] =
{
{ "ATE0\r","OK\r\n",0,1,5},
{ "AT+WORKLOCK=1\r","OK\r\n",0,1,5},
{ "AT+NBAND=3,5,8\r","OK\r\n",0,2,10},
{ "AT+NBAND?\r","OK\r\n",0,2,10},
//{ "AT+CIMI\r","OK\r\n",0,2,10},
#if BAND_7025
{ "AT+NPOWERCLASS=3,5\r","OK\r\n",0,1,5},
{ "AT+NPOWERCLASS=5,5\r","OK\r\n",0,1,5},
{ "AT+NPOWERCLASS=8,5\r","OK\r\n",0,1,5},
{ "AT+NPOWERCLASS=20,5\r","OK\r\n",0,1,5},
#endif
{ "AT+NPOWERCLASS?\r","OK\r\n",0,2,10},
{ "AT+CGMR\r","OK\r\n",0,1,5},
{ "AT+NSET=SWVER\r","OK\r\n",0,1,5},
{ "AT+NNMI=1\r","OK\r\n",0,1,5},
{ "AT+RESETCTL=1\r","OK\r\n",0,1,5},
{ "AT+NV=SET,\"CLOUDALIVE\",1\r","OK\r\n",0,1,5},
{ "AT+NV=SET,\"SAVECLOUD\",1\r","OK\r\n",0,1,5},
{ "AT+NPSMR=1\r","OK\r\n",0,1,5},
{ "AT+CPSMS=1,,,00111000,00000101\r","OK\r\n",0,2,10},
{ NULL, NULL, 0,0,0},
};
const STRU_AT struAtNetwork[] =
{
{ "AT+CSQ\r","+CSQ:",0,2,60},
{ "AT+CGPADDR=0\r","+CGPADDR:",0,2,10},//{ "AT+CGPADDR?\r","+CGPADDR:",0,2,10},
{ "AT+NUESTATS\r","+Cell ID:",0,1,5}, //{ "AT+QENG=0\r","+QENG:",0,1,5},
{ NULL, NULL, 0,0,0},
};
const STRU_AT struAtCloseConn[] =
{
{ "AT+QLWSREGIND=1\r","OK\r\n",0,1,3},
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtAepConn[] =
{
{ "AT+QCFG=\"LWM2M/lifetime\",172800\r","OK\r\n",0,2,6},
//{"AT+NCDP=\"221.229.214.202\",5683\r","+QLWEVTIND:3",0,15,45},//连接电信AEP平台
{"AT+NCDP=\"221.229.214.202\",5683\r","OK\r\n",0,2,6},//连接电信AEP平台
{"AT+QLWSREGIND=0\r","+QLWEVTIND:3",0,15,45},//{ "AT+QLWSREGIND=0\r","OK\r\n",0,2,6},
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtRfOff[] =
{
{ "AT+CFUN=0\r","OK\r\n",0,1,3},
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtExitPSM[] =
{
{ "AT+WORKLOCK=1\r","OK\r\n",0,1,5},
//{ "AT+NMSTATUS?\r","+NMSTATUS:",0,5,15},
//{ "AT+CDPRMLFT\r","OK\r\n",0,1,5},
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtEnPSM[] =
{
{ "AT+WORKLOCK=0\r","OK\r\n",0,1,5},
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtDisPSM[] =
{
{ "AT+WORKLOCK=1\r","OK\r\n",0,1,5},
{ NULL, NULL,0, 0, 0},
};
#else
const STRU_AT struAtNetwork[] =
{
{ "AT+CSQ\r","+CSQ:",0,2,60},
{ "AT+CGPADDR?\r","+CGPADDR:",0,2,10},
{ "AT+QENG=0\r","+QENG:",0,1,5},
{ NULL, NULL, 0,0,0},
};
const STRU_AT struAtInitNB[] =
{
{ "ATE0\r","OK\r\n",0,1,5},
{ "AT+QSCLK=0\r","OK\r\n",0,1,5},
{ "AT+QBAND=0\r","OK\r\n",0,1,5},
{ "AT+NNMI=1\r","OK\r\n",0,1,5},
{ "AT+CGMR\r","OK\r\n",0,1,5},
#if (NBIOT == BC260Y_CN)
{ "AT+QCFG=\"dsevent\",0\r","OK\r\n",0,1,5},
//{ "AT+CEREG=0\r","OK\r\n",0,1,5},
#else
{ "AT+QATWAKEUP=1\r","OK\r\n",0,1,5},
#endif
{ "AT+CPSMS=1,,,\"00111000\",\"00000101\"\r","OK\r\n",0,1,5},
{ NULL, NULL, 0,0,0},
};
const STRU_AT struAtCloseConn[] =
{
{ "AT+NCDPCLOSE\r","OK\r\n",0,1,3},
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtAepConn[] =
{
{ "AT+NCFG=0,172800\r","OK\r\n",0,2,6},
{"AT+NCDPOPEN=\"221.229.214.202\",5683\r","+QLWEVTIND: 3",0,15,45},//连接电信AEP平台
#if (NBIOT == BC260Y_CN)
//{ "AT+CEREG?\r","OK\r\n",0,1,5},
#endif
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtRfOff[] =
{
{ "AT+CFUN=0\r","OK\r\n",0,1,3},
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtExitPSM[] =
{
{ "AT+QSCLK=0\r","OK\r\n",0,1,5},
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtEnPSM[] =
{
{ "AT+QSCLK=1\r","OK\r\n",0,1,5},
{ NULL, NULL,0, 0, 0},
};
const STRU_AT struAtDisPSM[] =
{
{ "AT+QSCLK=0\r","OK\r\n",0,1,5},
{ NULL, NULL,0, 0, 0},
};
#endif
const u16 TempVol[102]={
1857 ,1822 ,1788 ,1753 ,1718 ,1683 ,1648 ,1613 ,1577 ,1541,
1505 ,1468 ,1432 ,1397 ,1363 ,1330 ,1296 ,1263 ,1229 ,1196,
1162 ,1129 ,1096 ,1063 ,1031 ,1000 ,970 ,943 ,917 ,893,
872 ,847 ,823 ,798 ,773 ,749 ,724 ,700 ,676 ,653,
631 ,610 ,589 ,570 ,553 ,538 ,520 ,503 ,487 ,471,
456 ,442 ,428 ,415 ,402 ,389 ,377 ,364 ,352 ,341,
329 ,318 ,308 ,298 ,288 ,279 ,269 ,261 ,252 ,244,
236 ,228 ,221 ,214 ,207 ,201 ,195 ,189 ,184 ,178,
173 ,168 ,163 ,158 ,153 ,149 ,144 ,140 ,135 ,131,
127 ,123 ,119 ,115 ,112 ,109 ,106 ,103 ,100 ,97,
94 ,0};
const u16 TempIndex[12]=
{1857 ,1505 ,1162 ,872 ,631 ,456 ,329 ,173 ,127 ,94 ,0};
/*********************************************************************************************************
** Function name: u8 TemperatureConvert(u16 adcTemp)
** Descriptions: 把热敏电阻的AD值转换为温度
** input parameters: NONE
** Output parameters: 温度值
** Returned value: 无
*********************************************************************************************************/
u8 TemperatureConvert(u16 adcTemp)
{
#define VOL_NUM 102
#define INDEX_NUM 12
u16 envi_temp;
u8 i,j,k,j_index=0;
if(adcTemp>TempVol[0])
{
return 0;
}
else if(adcTemp<TempVol[VOL_NUM-2])
{
return 100;
}
else
{
if((adcTemp/100)>=17)k=0;
else k=(INDEX_NUM/2)-1;
for(j=k;j<(INDEX_NUM-1);j++)
{
if(adcTemp>=TempIndex[j+1] && adcTemp<=TempIndex[j])
{
j_index = j*10;
break;
}
}
if(adcTemp<=TempVol[j_index+5] && adcTemp>=TempVol[j_index+6])
{
j_index = j_index+5;
}
for(i=j_index;i<VOL_NUM-1;i++)
{
if(adcTemp>=TempVol[i+1] && adcTemp<=TempVol[i])
{
if((TempVol[i]-adcTemp) < (adcTemp-TempVol[i+1]))
{
envi_temp = i;
}
else envi_temp = i+1;
break;
}
}
return envi_temp;
}
}
/*********************************************************************************************************
** Function name: void ClearBufptr(char *p,u8 len)
** Descriptions:
** input parameters: NONE
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
void ClearBufptr(char *p,u16 len)
{
char *ptr;
u16 i;
ptr=(char *)p;
for(i=0;i<len;i++)
{
*ptr=0;
ptr++;
}
}
/*********************************************************************************************************
** Function name: check_sum
** Descriptions:
** input parameters:
** Output parameters:
** Returned value:
*********************************************************************************************************/
u8 enet_check_sum( u8 *p,u8 len )
{
u8 sum;
if( p == NULL || len < 8 ) return 0;
sum = 0;
len--;
while( len-- ) sum += *p++;
sum = ~sum+1;
return sum;
}
/*********************************************************************************************************
** Function name: void strcan(u8 *buf,u16 len,char *p,char *p1)
** Descriptions:
** input parameters:
** Output parameters:
** Returned value:
*********************************************************************************************************/
void strcan(u8 *buf,u16 len,char *p,char *p1)
{
u16 le=0;
u16 i;
for(i=0;i<len;i++)
{
*p++ = hex_to_asciiH(*buf);
*p++ = hex_to_asciiL(*buf);
buf++;
}
le = strlen(p1)+1;
for(i=0;i<le;i++)
{
*p++=*p1++;
}
}
int mystrlen(const char *p)
{
int i = 0;
while(p[i])
i++;
return i;
}
#if KAI_WAN
AepString nb_aep_event_report(void)
{
event.head[0]=HEAD0;
event.head[1]=HEAD1;
event.protocol_version=PROTOCOL_VER;
event.command=CMD_REPORT;
event.data_length=EVENT_DATA_LENGTH;
event.device_type=DEVICE_TYPE_DOOR;
memcpy(event.Imei,&imei[0],15);
//event.door_state=door_updata.door_stat;
event.battery_vol=sys_vol_adc/10;
event.CSQ=nb->rssi;
event.reserve=0;
event.reserve2=0;
event.reserve3=0;
event.Tail[0] = TAIL0;
event.Tail[1] = TAIL1;
event.Tail[2] = TAIL2;
aep_string = Event_report_CodeDataReport(event);
return aep_string;
}
AepString nb_aep_heartbeat_report(void)
{
Heartbeat.head[0]=HEAD0;
Heartbeat.head[1]=HEAD1;
Heartbeat.protocol_version=PROTOCOL_VER;
Heartbeat.command=CMD_REPORT;
Heartbeat.data_length=EVENT_DATA_LENGTH;
Heartbeat.device_type=DEVICE_TYPE_DOOR;
memcpy(Heartbeat.Imei,&imei[0],15);
Heartbeat.event_type=EVENT_HEART_BEAT;
Heartbeat.door_state=DOOR();
Heartbeat.battery_vol=sys_vol_adc/10;
Heartbeat.CSQ=nb->rssi;
Heartbeat.reserve=0;
Heartbeat.reserve2=0;
Heartbeat.reserve3=0;
Heartbeat.Tail[0] = TAIL0;
Heartbeat.Tail[1] = TAIL1;
Heartbeat.Tail[2] = TAIL2;
aep_string = Event_report_CodeDataReport(Heartbeat);
return aep_string;
}
AepString set_aep_device_register(void)
{
device.head[0]=HEAD0;
device.head[1]=HEAD1;
device.protocol_version=PROTOCOL_VER;
device.command=CMD_REGISTER;
device.data_length=REGISTER_DATA_LENGTH;
device.device_type=DEVICE_TYPE_DOOR;
memcpy(device.Imei,&imei[0],15);
memcpy(device.Imsi,imsi,15);
memcpy(device.ICCID,&iccid[0],20);
device.battery_vol=sys_vol_adc/10;
device.CSQ=nb->rssi;
device.Tail[0] = TAIL0;
device.Tail[1] = TAIL1;
device.Tail[2] = TAIL2;
aep_string = device_register_CodeDataReport(device);
return aep_string;
}
#endif
/*********************************************************************************************************
** Function name: set_aep_event_report(void)
** Descriptions:
** input parameters:
** Output parameters:
** Returned value:
*********************************************************************************************************/
AepString set_aep_event_report(void)
{
#if KAI_WAN
aep_string = nb_aep_event_report();
#else
if(door_event_report.open_state == DOOR_STAT_OPEN)door_event_report.arming_state = 1;
else door_event_report.arming_state = 0;
aep_string = event_report_CodeEventReport(door_event_report);
#endif
return aep_string;
}
/*********************************************************************************************************
** Function name: set_heartbeat_report(void)
** Descriptions:
** input parameters:
** Output parameters:
** Returned value:
*********************************************************************************************************/
AepString set_aep_heartbeat_report(void)
{
#if KAI_WAN
aep_string = nb_aep_heartbeat_report();
#else
StruHeartbeat.heartbeat_time = TIME_EAP_HEARTBEAT;
StruHeartbeat.manufacturer_name.len = mystrlen(MANUFACTURER_NAME);
StruHeartbeat.manufacturer_name.str = MANUFACTURER_NAME;
StruHeartbeat.terminal_type.len = mystrlen(TERMINAL_TYPE);
StruHeartbeat.terminal_type.str = TERMINAL_TYPE;
StruHeartbeat.hardware_version.len = mystrlen(HARDWARE_VER);
StruHeartbeat.hardware_version.str = HARDWARE_VER;
StruHeartbeat.software_version.len = mystrlen(SOFTWARE_VER);
StruHeartbeat.software_version.str = SOFTWARE_VER;
StruHeartbeat.IMEI.len = mystrlen(imei);
StruHeartbeat.IMEI.str = imei;
StruHeartbeat.IMSI.len = mystrlen(imsi);
StruHeartbeat.IMSI.str = imsi;
StruHeartbeat.battery_value = door_updata.bat_vaule;
StruHeartbeat.battery_voltage = door_updata.bat_vol;
aep_string = heartbeat_CodeDataReport(StruHeartbeat);
#endif
return aep_string;
}
/*********************************************************************************************************
** Function name: nb_aep_send
** Descriptions:
** input parameters: tcp_ack!=0: TCP
** Output parameters:
** Returned value:
*********************************************************************************************************/
AT_STAT nb_aep_send(AepString aep_string,u8 rai )
{
char *p;
u16 i,le;
AT_STAT result;
STRU_AT struAt_send = {NULL,"OK\r\n",0,2,8};
p = aep_string.str;
ClearBufptr(&body_buf[0],MAX_BUF_BODY);
sprintf(body_buf,"AT+NMGS=%u,",aep_string.len/2);
le = mystrlen(body_buf);
for(i=0;i<aep_string.len;i++)
{
body_buf[le+i] = *(p++);
}
if(rai == 0) strcat(body_buf,"\r");
else strcat(body_buf,",1\r");
struAt_send.s_comm = body_buf;
free(aep_string.str);
result = at_cmd_return(&struAt_send);
return result;
}
/*********************************************************************************************************
** Function name: nb_enet_tcp_send
** Descriptions:
** input parameters: <ack>服务器需要返回的确认包bit位
** Output parameters:
** Returned value:
*********************************************************************************************************/
AT_STAT nb_enet_tcp_send( AepString aep_string, char *ack,u8 rai )
{
//AT_STAT result;
// SYS_ERR at_result;
u8 temp;
static STRU_AT atTemp;
temp = 2;
while( temp-- )
{
/* eNET协议通过判断Server的返回数据判断本包是否发送成功(无需判断TCP是否到达对岸) */
if( nb_aep_send(aep_string,rai) != RET_OK ) return RET_ERR;
if(ack == NULL ) return RET_OK;
atTemp.r_comm = ack;
atTemp.status=RET_WAIT;
atTemp.timeout=20;//等待20秒
pStruAT=&atTemp;
while( 1 )
{
/* 5秒内等待服务器应答 */
/*如果没有消息发送,则发生超时错误,此时指针无效*/
if(pStruAT->status==RET_OK)
{
pStruAT=NULL;
return RET_OK;
}
if(pStruAT->status==RET_TIMEOUT)
{
break;
}
if(pStruAT->status == RET_CONNECT_ERR)
{
break;
}
if(pStruAT->status==RET_ERR)
{
pStruAT->status=RET_WAIT;
}
OSTimeDly2ms(1);
}
/* 如果失败原因是模块TCP ACK失败,则不再重发 */
//if( nb_check_tcp_ack( TCP_INDEX_ENET ) != RET_OK ) {pStruAT=NULL; return RET_ERR;}
}
pStruAT=NULL;
return RET_ERR;
}
/*********************************************************************************************************
** Function name: check_gizwits_protocol
** Descriptions: 协议验证
** input parameters: *p
** Output parameters:
** Returned value: 0: OK
*********************************************************************************************************/
u8 check_enet_protocol( u8 *p,u16 len )
{
/*
ad+9909+sn+07000000+sum+
*/
if( p[0] != 0xAD || len < sizeof(STRU_ENET_HEAD) ) return Error_Other; /* check header */
if( enet_check_sum( p,sizeof(STRU_ENET_HEAD) ) != p[sizeof(STRU_ENET_HEAD)-1] ) return Error_AckSum;
return 0;
}
/*********************************************************************************************************
** Function name: check_gsm_alarm_task
** Descriptions:
** input parameters:
** Output parameters:
** Returned value:
*********************************************************************************************************/
void check_nb_alarm_task(void)
{
//static u16 time_gprs_alarm = 0;
if(nb_event.delay != 0)nb_event.delay--;
//if(task_global!= 0)
if(nb_event.cnt > 0)
{
#if KAI_WAN
if(pgsNb != PGS_NB_TCP_ALARM && (struNb.task&NB_TASK_ENET_ALARM ) == 0 && nb_event.delay == 0)
{
event.event_type=nb_event.buf[nb_event.head];
if(event.event_type == EVENT_DOOR_ALARM)
{
event.door_state = DOOR_STAT_OPEN;
}
else if(event.event_type == EVENT_DOOR_ALARM_RECOVER)
{
event.door_state = DOOR_STAT_CLOSE;
}
else event.door_state = DOOR();
nb_event.cnt--;
nb_event.head++;
if(nb_event.head >= MAX_EVENT)nb_event.head = 0;
// if(time_gprs_alarm==0)
// {
struNb.task |= NB_TASK_ENET_ALARM;
// }
if((struNb.status&NB_STAT_TCP_SEND) == 0 && delaytime_nb_alarm == 0)
{
delaytime_nb_alarm = 30*1000/10;
struNb.status |= NB_STAT_TCP_SEND;
}
// if(++time_gprs_alarm>=30*1000/10)time_gprs_alarm=0;
if(nb_event.cnt > 0)
{
nb_event.delay = 1*1000/10;//数据包之间间隔1s
}
}
#else
if(pgsNb != PGS_NB_TCP_ALARM && (struNb.task&NB_TASK_ENET_ALARM ) == 0)
{
door_event_report.battery_voltage = door_updata.bat_vol;
door_event_report.battery_value = door_updata.bat_vaule;
door_event_report.open_state = nb_event.buf[nb_event.head];
door_stat.open_state = door_event_report.open_state;
nb_event.cnt--;
nb_event.head++;
if(nb_event.head >= MAX_EVENT)nb_event.head = 0;
// if(time_gprs_alarm==0)
// {
struNb.task |= NB_TASK_ENET_ALARM;
// }
if((struNb.status&NB_STAT_TCP_SEND) == 0 && delaytime_nb_alarm == 0)
{
delaytime_nb_alarm = 30*1000/10;
struNb.status |= NB_STAT_TCP_SEND;
}
// if(++time_gprs_alarm>=30*1000/10)time_gprs_alarm=0;
}
#endif
}
else
{
if(nb_heartbeat_task != 0&& (struNb.status&NB_STAT_TCP_SEND) == 0
&& pgsNb != PGS_NB_TCP_PULSE && (struNb.task&NB_TASK_ENET_PULSE ) == 0)
{
delaytime_nb_alarm = 30*1000/10;
struNb.status |= NB_STAT_TCP_SEND;
struNb.task |= NB_TASK_ENET_PULSE;
nb_heartbeat_task = 0;
}
//else time_gprs_alarm=0;
}
if(delaytime_nb_alarm != 0 && (struNb.status&NB_STAT_TCP_SEND) != 0)
{
if(--delaytime_nb_alarm == 0)
{
#if nb_debug
printf( "TCP发送超时\r\n");
#endif
struNb.status &= ~NB_STAT_TCP_SEND;
init_event_queue();
}
}
if((nb->task&NB_TASK_ENTER_SLEEP) != 0)
{
struNb.status &= ~NB_STAT_TCP_SEND;
delaytime_nb_alarm = 0;
//time_gprs_alarm = 0;
}
}
/*********************************************************************************************************
** Function name: void nb_reset(void)
** Descriptions: 复位NB模块
** input parameters: none
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
void nb_reset(void)
{
RST_NB(0);
#if (NBIOT == Y7025)
OSTimeDly2ms(3025);
#else
OSTimeDly2ms(600);
#endif
RST_NB(1);
OSTimeDly2ms(200);
}
/*********************************************************************************************************
** Function name: gsm_power_down
** Descriptions: GSM断电2秒钟
** input parameters: none
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
void nb_power_off()
{
#if (NBIOT != BC260Y_CN)
POW_NB(0);
OSTimeDly2ms(600);
POW_NB(1);
OSTimeDly2ms(10);
#endif
}
/*********************************************************************************************************
** Function name: nb_task_init
** Descriptions:
** input parameters: NONE
** Output parameters: NONE
** Returned value: ?
*********************************************************************************************************/
void nb_task_init(void)
{
pStruUsartNB = &struUsart[USART0_ID];
nb->reset = 1;
//nb_power_off();
}
/*********************************************************************************************************
** Function name: nb_power_down
** Descriptions: NB关机机(对于MG323:TERM_ON口一直拉低直到收不到AT返回)
** input parameters: none
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
AT_STAT nb_power_down()
{
#if 0
const STRU_AT struAt = {"AT\r","OK\r\n",0,1,5};
u8 ctr;
PWRKEY(1);
OSTimeDly2ms(600);
PWRKEY(0);
OSTimeDly2ms(200);
ctr = 30;
while(ctr--)
{
if( at_cmd_return(&struAt) == RET_ERR )
{
OSTimeDly2ms(1000);
return RET_OK;
}
OSTimeDly2ms(500);
}
nb_power_off();
#endif
return RET_ERR;
}
/*********************************************************************************************************
** Function name: at_cmd_return
** Descriptions: 在timeout时间内等待指定返回,失败则重发,直到总时间耗尽
** input parameters: STRU_AT
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
AT_STAT at_cmd_return( const STRU_AT *at )
{
u8 ctr;
u8 tx_timeout;
STRU_AT atTemp;
atTemp.s_comm = at->s_comm;
atTemp.r_comm = at->r_comm;
atTemp.status=at->status;
atTemp.timeout=at->timeout;
atTemp.time_total=at->time_total;
tx_timeout=at->timeout;
SendATtimeout=at->timeout;
pStruAT=&atTemp;
ctr = at->time_total/at->timeout;
while(ctr--)
{
/******************************************************/
pStruAT->s_comm=atTemp.s_comm;
pStruAT->r_comm=atTemp.r_comm;
// pStruAT->timeout=atTemp.timeout;
pStruAT=&atTemp;
pStruAT->timeout=tx_timeout;
pStruAT->status=RET_WAIT;
/******************************************************/
#if nb_debug
printf("\r\nsend:\r\n%s",pStruAT->s_comm);
#endif
usart_send_str( pStruAT->s_comm );
/*如果没有消息发送,则发生超时错误,此时指针无效*/
while(1)
{
if(pStruAT->status==RET_OK)
{
pStruAT->status=SEN_READY;
pStruAT=NULL;
return RET_OK;
}
else if(pStruAT->status==RET_TIMEOUT)
{
break;
}
else if(pStruAT->status==RET_AT_ERR)break;
else if(pStruAT->status==RET_ERR)
{
pStruAT->status=RET_WAIT;
}
else if(pStruAT->status==RET_CONNECT_ERR)
{
SendATtimeout=0;
pStruAT->timeout=0;
pStruAT->status=SEN_READY;
pStruAT=NULL;
return RET_ERR;
}
if((nb->status&NB_STAT_SLEEP) != 0)return RET_ERR;
OSTimeDly2ms(1);
}
}
SendATtimeout=0;
pStruAT->timeout=0;
pStruAT->status=SEN_READY;
pStruAT=NULL;
return RET_ERR;
}
/*********************************************************************************************************
** Function name: gsm_power_on
** Descriptions: GSM开机(对于MG323:TERM_ON口拉低750ms)
** input parameters: none
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
AT_STAT nb_power_on()
{
u8 ctr;
const STRU_AT struAt = {"AT\r","OK\r\n",0,1,18};
ctr = 2;
while(ctr--)
{
#if 1
printf( "正在启动NB模块...\r\n" );
#endif
OSTimeDly2ms(1000);
if( at_cmd_return(&struAt) == RET_OK ) return RET_OK;
nb_reset();
}
#if 1
printf( "NB模块启动失败\r\n" );
#endif
nb_power_off();
return RET_ERR;
}
/*********************************************************************************************************
** Function name: gsm_power_on
** Descriptions: 唤醒NB模块
** input parameters: none
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
void nb_wake_up()
{
#if 0
u8 ctr;
const STRU_AT struAt = {"AT\r","OK\r\n",0,1,18};
ctr = 10;
while(ctr--)
{
OSTimeDly2ms(1000);
if( at_cmd_return(&struAt) == RET_OK ) return ;
}
#if 1
printf( "AT启动失败\r\n" );
#endif
return ;
#else
OSTimeDly2ms(200);
PSM_NB(0);
OSTimeDly2ms(80);
PSM_NB(1);
OSTimeDly2ms(100);
#endif
}
/*********************************************************************************************************
** Function name: at_cmd_list_return
** Descriptions:
** input parameters:
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
AT_STAT at_cmd_list_return( const STRU_AT *at )
{
while( at->s_comm != NULL )
{
if( at_cmd_return(at) != RET_OK ) return RET_ERR;
at++;
}
return RET_OK;
}
/*********************************************************************************************************
** Function name: check_network_stat
** Descriptions:
** input parameters:
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
AT_STAT check_network_stat()
{
const STRU_AT *at = &struAtNetwork[0];
return at_cmd_list_return(at);
}
/*********************************************************************************************************
** Function name: get_gsm_level
** Descriptions: 将GSM场强转换为3格信号显示
** input parameters: NONE
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
u8 get_gsm_level( void )
{
if( nb->rssi <= 2 || nb->rssi == 99 ) return 0;
else if( nb->rssi >= 15 ) return 3;
else if( nb->rssi >= 8 ) return 2;
else if( nb->rssi >= 4 ) return 1;
else return 1;
}
/*********************************************************************************************************
** Function name: nb_usart_handle
** Descriptions: NB数据处理
** input parameters: NONE
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
void nb_usart_handle(void)
{
RXBUF_UART *p;
u16 t=0;
//u16 at_return_result;
t = get_usart_buffer(pStruUsartNB,&p);
if( t != 0 )
{
/* 此程序段执行时偶尔会复位?? */
#if nb_debug
printf("\r\n%u bytes received:\r\n%s",t,(char *)p); //发送接收到的数据到串口1
#endif
nb_parse((char *)p);//at_return_result = nb_parse((char *)p);
FreeRxBuf(pStruUsartNB);//解析完数据后要释放串口缓存
}
}
/*********************************************************************************************************
** Function name: nb_parse
** Descriptions: NB数据处理
** input parameters: NONE
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
//u16 gsm_parse( const char *p,STRU_GSM *gsm )
u16 nb_parse( const char *p)
{
uint16_t result = 0;
u8 temp;
//u16 t;
#if (NBIOT == Y7025)
char *pstr;
char *p1;
ClearBufptr((char*)&ptab[0],BUF_PTAB);
pstr=&ptab[0];
#else
char *pstr,*pstr2;
char *p1;
ClearBufptr((char*)&ptab[0],BUF_PTAB);
ClearBufptr((char*)&ptab2[0],BUF_PTAB2);
pstr=&ptab[0];
pstr2=&ptab2[0];
#endif
if( strstr( p,"OK\r\n" ) != NULL )
{
if(strstr(pStruAT->r_comm,"OK\r\n" )!=NULL && pStruAT!=NULL)
{
if(pStruAT->status==RET_WAIT && (nb->status&NB_STAT_RECEIVE_DATA) == 0)
{
pStruAT->status=RET_OK;
}
result |= RET_OK;
}
if((nb->status&NB_STAT_RECEIVE_DATA) != 0) //读取IMSI号
{
nb->status &= ~NB_STAT_RECEIVE_DATA;
#if (NBIOT == Y7025)
temp = getsubstr2( (char *)p,':','\r',&imsi[0] );
#else
temp = getsubstr2( (char *)p,'\n','\r',&imsi[0] );
#endif
if(temp <= 18 && temp != 0)
{
pStruAT->status=RET_OK;
imsi[temp] = '\0';
printf( "\r\nIMSI:%s\r\n",imsi );
}
else pStruAT->status=RET_ERR;
}
}
// if( strstr( p,"ERROR\r\n" ) != NULL)
// {
// if(pStruAT!=NULL)
// {
// if(pStruAT->status==RET_WAIT)
// {
// pStruAT->status=RET_AT_ERR;
// }
// result |= RETU_ERROR;
// }
// }
/*+CSQ: 13,99*/
p1 = strstr( p,"+CSQ:" );
if( p1 != NULL && getsubstr2( p1,':',',',pstr ) != 0 )
{
temp = atoi(pstr);
nb->rssi = temp;
result |= ( temp > 0 && temp < 99 )?RETU_OK:RETU_ERROR;
if(strstr(pStruAT->r_comm,"+CSQ:" )!=NULL && pStruAT!=NULL )
{
if(((result&RETU_OK)!=0) && (pStruAT->status==RET_WAIT))
{
pStruAT->status=RET_OK;
}
else
{
pStruAT->status=RET_ERR;
}
}
}
p1 = strstr( p,"+CEREG:" );
if( p1 != NULL && getsubstr2( p1,',','\r',pstr ) != 0 )
{
temp = atoi(pstr);
if( temp == 1 || temp == 5 )
{
if( ( nb->status&NB_STAT_CREG ) == 0 )
{
#if 1
printf( "NB注册成功!信号强度:%u\r\n",nb->rssi );
#endif
}
nb->status |= NB_STAT_CREG|NB_STAT_CREG_OK;
result |= RETU_OK;
}
else
{
nb->status &= ~NB_STAT_CREG;
result |= RETU_ERROR;
}
if(strstr(pStruAT->r_comm,"+CEREG:" )!=NULL && pStruAT!=NULL)
{
if(((result&RETU_OK)!=0) && (pStruAT->status==RET_WAIT))
{
pStruAT->status=RET_OK;
}
else
{
pStruAT->status=RET_ERR;
}
}
}
p1 = strstr( p,"+QATWAKEUP:" );
if( p1 != NULL )
{
nb->status |= NB_STAT_NB_WAKEUP;
}
p1 = strstr( p,"+QATSLEEP" );
if( p1 != NULL )
{
if(((nb->status&NB_STAT_SLEEP) == 0) && (nb_event.cnt > 0 || (nb->task&NB_TASK_ENET_ALARM) != 0))
{
#if nb_debug
printf( "NB模块进入睡眠模式\r\n");
#endif
PSM_NB(1);
OSTimeDly2ms(800);
PSM_NB(0);
OSTimeDly2ms(80);
PSM_NB(1);
OSTimeDly2ms(10);
}
}
#if (NBIOT == BC260Y_CN)
p1 = strstr( p,"ENTER DEEPSLEEP" );
if( p1 != NULL )
{
if(((nb->status&NB_STAT_SLEEP) == 0) && (nb_event.cnt > 0 || (nb->task&NB_TASK_ENET_ALARM) != 0))
{
#if nb_debug
printf( "NB模块进入睡眠模式\r\n");
#endif
PSM_NB(1);
OSTimeDly2ms(800);
PSM_NB(0);
OSTimeDly2ms(80);
PSM_NB(1);
OSTimeDly2ms(10);
}
else
{
nb->status |= NB_STAT_SLEEP;
}
}
#endif
p1 = strstr( p,"+CGSN:" );//读取ISMI号
if( p1 != NULL)
{
temp = getsubstr2( p1,':','\r',&imei[0] );
if(temp <= 18 && temp != 0)
{
pStruAT->status=RET_OK;
imei[temp] = '\0';
printf( "\r\nIMEI:%s\r\n",imei );
}
else pStruAT->status=RET_ERR;
}
#if (NBIOT == Y7025)
p1 = strstr( p,"+NCCID:" );//读取ICCID号
if( p1 != NULL)
{
temp = getsubstr2( p1,':','\r',&iccid[0] );
if(temp != 0)
{
pStruAT->status=RET_OK;
iccid[temp] = '\0';
printf( "\r\nNCCID:%s\r\n",iccid );
}
else pStruAT->status=RET_ERR;
}
#else
p1 = strstr( p,"+QCCID:" );//读取ICCID号
if( p1 != NULL)
{
temp = getsubstr2( p1,':','\r',&iccid[0] );
if(temp != 0)
{
pStruAT->status=RET_OK;
iccid[temp] = '\0';
printf( "\r\nQCCID:%s\r\n",iccid );
}
else pStruAT->status=RET_ERR;
}
#endif
p1 = strstr( p,"+QLWEVTIND:" );//平台连接状态
if( p1 != NULL)
{
if(getsubstr2( p1,':','\r',pstr ) != 0)
{
temp = atoi(pstr);
if(temp == 7)
{
pStruAT->status=RET_ERR;
nb->status &= ~NB_STAT_AEP_CONNECT;
}
// }
if(strstr(pStruAT->r_comm,"+QLWEVTIND:3" )!=NULL && pStruAT!=NULL)
{
if(temp == 3 && pStruAT->status==RET_WAIT)
{
pStruAT->status=RET_OK;
}
}
}
}
p1 = strstr( p,"+CGPADDR:" );//NB模块注册到网络
if( p1 != NULL && strstr(pStruAT->r_comm,"+CGPADDR:" )!=NULL)
{
#if 1
printf( "NB网络注册成功,信号:%u\r\n",nb->rssi );
#endif
nb->status |= NB_STAT_CREG|NB_STAT_CREG_OK;
pStruAT->status=RET_OK;
}
#if (NBIOT == Y7025)
p1 = strstr( p,"+Cell ID:" );
if( p1 != NULL )
{
pStruAT->status=RET_OK;
if(getsubstr2( p1,':','\r',pstr ) != 0)
{
ascii_2_hex((u8*)&StruSignal.cell_id,pstr,mystrlen(pstr)+1);
StruSignal.cell_id = aep_htoni(StruSignal.cell_id);
StruSignal.cell_id >>= 4;
StruSignal.cell_id &= 0x0fffffff;
#if nb_debug
printf( "cell_id:%4X\r\n",StruSignal.cell_id );
#endif
}
p1 = strstr( p,"+ECL:" );
if(getsubstr2( p1,':','\r',pstr ) != 0)
{
StruSignal.ecl = my_atoi(pstr);
#if nb_debug
printf( "ecl:%u\r\n",StruSignal.ecl );
#endif
}
p1 = strstr( p,"+SNR:" );
if(getsubstr2( p1,':','\r',pstr ) != 0)
{
StruSignal.sinr = my_atoi(pstr);
#if nb_debug
printf( "sinr:%i\r\n",StruSignal.sinr );
#endif
}
p1 = strstr( p,"+PCI:" );
if(getsubstr2( p1,':','\r',pstr ) != 0)
{
temp = atoi(pstr);
StruSignal.pci = temp;
#if nb_debug
printf( "pci:%u\r\n",temp );
#endif
}
p1 = strstr( p,"+RSRQ:" );
if(getsubstr2( p1,':','\r',pstr ) != 0)
{
StruSignal.rsrp = my_atoi(pstr);
#if nb_debug
printf( "rsrp:%i\r\n",StruSignal.rsrp );
#endif
}
}
#else
p1 = strstr( p,"+QENG:" );
if( p1 != NULL )
{
pStruAT->status=RET_OK;
if(getsubstr(3,p1,pstr ) != 0)
{
temp = atoi(pstr);
StruSignal.pci = temp;
#if nb_debug
printf( "pci:%u\r\n",temp );
#endif
}
if(getsubstr(4,p1,pstr ) != 0)
{
getsubstr2( pstr,'"','"',pstr2);
ascii_2_hex((u8*)&StruSignal.cell_id,pstr2,mystrlen(pstr2)+1);
StruSignal.cell_id = aep_htoni(StruSignal.cell_id);
StruSignal.cell_id >>= 4;
StruSignal.cell_id &= 0x0fffffff;
#if nb_debug
printf( "cell_id:%4X\r\n",StruSignal.cell_id );
#endif
}
if(getsubstr(5,p1,pstr ) != 0)
{
StruSignal.rsrp = my_atoi(pstr);
#if nb_debug
printf( "rsrp:%i\r\n",StruSignal.rsrp );
#endif
}
if(getsubstr(8,p1,pstr ) != 0)
{
StruSignal.sinr = my_atoi(pstr);
#if nb_debug
printf( "sinr:%i\r\n",StruSignal.sinr );
#endif
}
if(getsubstr(11,p1,pstr ) != 0)
{
StruSignal.ecl = my_atoi(pstr);
#if nb_debug
printf( "ecl:%u\r\n",StruSignal.ecl );
#endif
}
}
#endif
return result;
}
/*********************************************************************************************************
GSM??1s??????(????1s??????)
*********************************************************************************************************/
void nb_task_time_callback(void)
{
static u32 tmrCreg = 0;
tmrCreg++;
if( tmrCreg%5 == 0 ) nb->task |= NB_TASK_CREG;
// if( tmrCreg%30 == 0 )
// {
// nb->task |= NB_TASK_ENET_PULSE;
// }
if( tmrCreg >= 24*60*60 )
{
tmrCreg = 0;
nb->status &= ~NB_STAT_INIT; /* ?24????????:24*60*60 */
}
}
/*********************************************************************************************************
** Function name: nb_enter_sleep
** Descriptions:
** input parameters:
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
AT_STAT nb_enter_sleep()
{
return at_cmd_list_return(struAtEnPSM);
}
/*********************************************************************************************************
** Function name: nb_enter_sleep
** Descriptions:
** input parameters:
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
AT_STAT nb_exit_sleep()
{
const STRU_AT *at = &struAtDisPSM[0];
return at_cmd_list_return(at);
}
/*********************************************************************************************************
** Function name: nb_set_tcp_connect
** Descriptions:
** input parameters:
** Output parameters:
** Returned value:
*********************************************************************************************************/
AT_STAT nb_set_aep_connect(void )
{
AT_STAT result;
const STRU_AT *at = &struAtAepConn[0];
result = at_cmd_list_return(at);
return result;
}
/*********************************************************************************************************
** Function name: AT_STAT read_imei_imsi(void)
** Descriptions:
** input parameters:
** Output parameters:
** Returned value:
*********************************************************************************************************/
AT_STAT read_imei_imsi(void)
{
AT_STAT result;
STRU_AT struAt_imei = {"AT+CGSN=1\r","+CGSN:",0,1,3};
STRU_AT struAt_imsi = {"AT+CIMI\r","OK\r\n",0,1,3};
#if (NBIOT == Y7025)
STRU_AT struAt_iccid = {"AT+NCCID\r","+NCCID:",0,3,9};
#else
STRU_AT struAt_iccid = {"AT+QCCID\r","+QCCID:",0,3,9};
#endif
result = at_cmd_return( &struAt_imei );
if(result == RET_OK)
{
nb->status |= NB_STAT_RECEIVE_DATA;
result = at_cmd_return( &struAt_imsi );
if(result == RET_OK)
{
result = at_cmd_return( &struAt_iccid );
}
else return result;
}
return result;
}
/*********************************************************************************************************
** Function name: nb_task
** Descriptions:
** input parameters: NONE
** Output parameters: NONE
** Returned value: 无
*********************************************************************************************************/
void nb_task(void)
{
//char *p;
static u8 ctr_tcp_connect,ctr_tcp_send;
//u8 temp;
AT_STAT result;
if(run_nbTask_lock==0)
{
run_nbTask_lock++;
if(( nb->status&NB_STAT_SLEEP ) == 0 )//模块运行在正常模式
{
if( ( nb->task&NB_TASK_ENTER_SLEEP ) != 0)//NB进入睡眠模式任务
{
result = nb_enter_sleep();
if(result == RET_OK )
{
if(nb_event.cnt > 0)//进入PSM模式后,报警器又产生报警任务
{
nb->task &= ~NB_TASK_ENTER_SLEEP;
nb->task |= NB_TASK_EXIT_SLEEP;
delaytime_nb_alarm = MAX_NET_DELAY;
struNb.status |= (NB_STAT_TCP_SEND|NB_STAT_SLEEP);//先退出睡眠模式
}
else
{
#if 1
printf( "NB进入睡眠\r\n");
#endif
nb->status |= NB_STAT_SLEEP;
nb->reset = 0;
nb->task = 0;
}
}
else
{
//nb_power_off();
#if 1
printf( "NB关机睡眠\r\n");
#endif
nb->status |= NB_STAT_SLEEP;
nb->task = 0;
}
run_nbTask_lock=0;
return;
}
if( nb->reset != 0 )
{
nb->status &= ~(NB_STAT_CREG|NB_STAT_INIT|NB_STAT_WAKEUP_AEP_CONNECT|NB_STAT_AEP_CONNECT|NB_STAT_NB_SLEEP|
NB_STAT_SLEEP|NB_STAT_INIT_OK|NB_STAT_FAULT|NB_STAT_RECEIVE_DATA|NB_STAT_READ_IMEI);
pgsNb = PGS_NB_FREE;
nb->rssi = 0;
if( ( nb->status&NB_STAT_AT_OK ) != 0 )
{
#if nb_debug
printf( "正在关闭模块...\r\n" );
#endif
//nb_power_off();
nb->status &= ~NB_STAT_AT_OK;
}
if( nb_power_on() == RET_OK )
{
#if 1
printf( "NB启动正常!\r\n" );
#endif
if(flg_sys_start == 0)StartLEDLighting( LEDflashSearchSignal,GREEN_COLOR,0);
nb->reset = 0;
nb->status |= NB_STAT_AT_OK;
nb->status &= ~NB_STAT_FAULT;
}
else
{
if(flg_sys_start == 0)StartLEDLighting( LEDflash_NB_fault,GREEN_COLOR,10);
nb->status |= NB_STAT_FAULT;
#if 1
printf( "NB模块启动失败,模块关机!\r\n" );
#endif
}
ctr_tcp_connect = 0;
ctr_tcp_send = 0;
}
else if( ( nb->status&NB_STAT_INIT_OK ) == 0)
{
if( at_cmd_list_return(struAtInitNB) == RET_OK )nb->status |= NB_STAT_INIT_OK;
else nb->reset = 1;
}
else if( ( nb->status&NB_STAT_CREG ) == 0)
{
nb->task &= ~NB_TASK_CREG;
if((nb->status&NB_STAT_CREG)==0)
{
#if nb_debug
printf( "正在搜索NB网络信号...\r\n" );
#endif
}
else
{
#if 1
printf( "NB信号值:%u\r\n",nb->rssi );
#endif
}
if(time_register_NB==0)time_register_NB = MAX_NET_DELAY;
if( check_network_stat() != RET_OK )
{
nb->status &= ~NB_STAT_CREG;
nb->status &= ~NB_STAT_CREG_OK;
nb->reset = 1;
}
}
else if( ( nb->status&NB_STAT_READ_IMEI ) == 0)
{
nb->status |= NB_STAT_READ_IMEI;
if( read_imei_imsi() != RET_OK )nb->reset = 1;
}
else if((nb->status&NB_STAT_NB_WAKEUP) != 0)
{
if(at_cmd_list_return(struAtExitPSM) != RET_OK)nb->reset = 1;//at_cmd_list_return(struAtExitPSM);nb->reset = 1;
}
else if( ( nb->status&NB_STAT_AEP_CONNECT ) == 0 )
{
if( nb_set_aep_connect() == RET_OK )
{
nb->status |= NB_STAT_AEP_CONNECT;
#if 1
printf( "AEP平台连接成功...\r\n" );
#endif
StopLEDLighting(GREEN_COLOR);
if(flg_sys_start == 0)StartLEDLighting( LEDflash_NB_conn_aep,GREEN_COLOR,10);
#if KAI_WAN
nb_aep_send(set_aep_device_register(),0);
nb_aep_send(set_aep_heartbeat_report(),0);//nb_aep_send(set_aep_heartbeat_report(),1);
#else
nb_aep_send(set_aep_heartbeat_report(),0);
nb_aep_send(signal_report_CodeDataReport(StruSignal),1);
#endif
}
else
{
if((nb->status&NB_STAT_AEP_CONNECT) == 0)StopLEDLighting(GREEN_COLOR);
at_cmd_list_return(struAtCloseConn);
if( ++ctr_tcp_connect >= 3 )
{
#if 1
printf( "AEP平台连接超时...\r\n" );
#endif
if((struNb.status&NB_STAT_TCP_SEND) == 0 )
{
nb->task &= ~NB_TASK_ENET_ALARM;
}
nb->reset = 1;
}
}
}
else if( ( nb->task&NB_TASK_ENET_ALARM) != 0 || ( nb->task&NB_TASK_ENET_PULSE) != 0 )
{
if( ( nb->task&NB_TASK_ENET_ALARM) != 0)
{
#if 1
printf( "准备发报警信息\r\n" );
#endif
pgsNb = PGS_NB_TCP_ALARM;
result = nb_aep_send(set_aep_event_report(),0);
#if KAI_WAN==0
if( result == RET_OK )
{
result = nb_aep_send(data_report_CodeDataReport(door_stat),1);
}
#endif
}
else
{
#if 1
printf( "准备发报NB心跳\r\n" );
#endif
pgsNb = PGS_NB_TCP_PULSE;
read_battery_vol();
result = nb_aep_send(set_aep_heartbeat_report(),0);
}
if( result == RET_OK )
{
#if 1
printf( "发送成功\r\n" );
#endif
nb_event.delay = 1*1000/10;//数据包之间间隔1s
ctr_tcp_send = 0;
struNb.status &= ~NB_STAT_TCP_SEND;
if( ( nb->task&NB_TASK_ENET_ALARM) != 0)
{
nb->task &= ~NB_TASK_ENET_ALARM;
if(flg_sys_start != 0)StartLEDLighting( LEDflash_NB_conn_aep,GREEN_COLOR,2);
}
else nb->task &= ~NB_TASK_ENET_PULSE;
//tcp_even = TCP_EVEN_ALARM;
}
else
{
#if 1
printf( "发送失败\r\n" );
#endif
if( ++ctr_tcp_send >= 2 )
{
nb->task &= ~NB_TASK_ENET_ALARM;
nb->reset = 1;
}
}
pgsNb = PGS_NB_FREE;
}
}
else //模块运行睡眠模式
{
if( ( nb->task&NB_TASK_EXIT_SLEEP ) != 0 )
{
#if 1
printf( "NB退出睡眠\r\n");
#endif
nb->task &= ~NB_TASK_EXIT_SLEEP;
nb->status &= ~NB_STAT_SLEEP;
time_register_NB = MAX_NET_DELAY;
nb_wake_up();
if(at_cmd_list_return(struAtExitPSM) != RET_OK)nb->reset = 1;
}
}
run_nbTask_lock--;
}
}
/*********************************************************
函数名: void ATAckTimeoutCallback(void)
描 述: 响GSM模块发送AT命令,模块回应超时回调函数,2ms定时回调一次
输入值: 无
输出值: 无
返回值: 无
**********************************************************/
void ATAckTimeoutCallback(void)
{
if(pStruAT!=NULL)
{
if(pStruAT->timeout!=0)
{
pStruAT->timeout--;
if(pStruAT->timeout==0 && pStruAT->status==RET_WAIT)
{
pStruAT->status=RET_TIMEOUT;
}
}
}
}
/*********************************************************nb.h******************************************/
#ifndef __NB_H
#define __NB_H
#include "includes.h"
#include "config.h"
#ifndef GLOBAL
#define EXT extern
#else
#define EXT
#endif
#ifndef NULL
#define NULL 0
#endif
#define MUX 1
#define TCP_INDEX_ENET 0 /* ENET协议通道号 */
#define TCP_MODE_TCP 0
#define TCP_MODE_UDP 1
#define RETU_OK BIT0
#define RETU_ERROR BIT1
#define RETU_CGATT BIT2
#define RETU_CONNECT BIT3
#define RETU_TCP_ACK BIT4
#define RETU_TCP_ACK2 BIT5
#define RETU_TCP_ACK3 BIT6
#define RETU_AGPS BIT7
#define RETU_LARGE BIT8
#define RETU_CMGS BIT9
#define RETU_NO_CARRIER BIT10
#define RETU_CLCC BIT11
#define RETU_CALL_CONNECT BIT12
#define RETU_NTP BIT13
#define RETU_S2D_ACK BIT14
#define RETU_SIM_OK BIT15
#define TIME_EAP_HEARTBEAT 24
#if 0
/*****************************************************
* 非法报文类型
******************************************************/
typedef enum
{
Error_AckSum = 0x01, /* 校验错误 */
Error_Cmd = 0x02, /* 命令码错误 */
Error_Other = 0x03, /* 其他 */
} Error_PacketsTypeDef; /* 本枚举定义非法协议类型 用于WIFI模组协议、ENET协议检测返回 */
#endif
/* 本命令字类型定义后直接用小端模式传输,ENET协议基于小端模式传输 */
typedef enum
{
D2S_PULSE = 0x0301,
D2S_ALARM = 0x0302,
D2S_ACK = 0x030A,
S2D_ACK = 0x9909,
S2D_CONTROL = 0x9911,
}ENUM_ENET_CLASSIFICATION; /* 本枚举定义数据方向及类别 D2S为设备-》服务器 S2D为服务器-》设备 */
typedef enum
{
D2S_CMD_PULSE = 0x12000000,
D2S_CMD_ALARM = 0x14000000,
D2S_CMD_ACK = 0x00000000,
S2D_CMD_ACK = 0x07000000,
S2D_CMD_ARM = 0x00000001,
S2D_CMD_DISARM = 0x00000002,
}ENUM_ENET_CMD; /* 本枚举定义命令类型 */
#if KAI_WAN
typedef enum
{
EVENT_HEART_BEAT = 0x01,
EVENT_DOOR_ALARM,
EVENT_DOOR_ALARM_RECOVER,
EVENT_TAMP_ALARM,
EVENT_TAMP_ALARM_RECOVER,
EVENT_LOW_BATTERY,
EVENT_LOW_BATTERY_RECOVER,
EVENT_SENSOR_FAULT,
EVENT_SENSOR_FAULT_RECOVER,
EVENT_TEST_ALARM,
EVENT_TEST_ALARM_RECOVER,
EVENT_SOS_ALARM = 0x0C,
EVENT_SOS_ALARM_RECOVER,
}ENUM_EVENT_TYPE;
typedef enum
{
CMD_REGISTER = 0x01,
CMD_REPORT = 0x02,
CMD_RECEIVE = 0x03,
CMD_RESP = 0x04,
}ENUM_COMMAND;
typedef enum
{
DEVICE_TYPE_DOOR = 0x01,
DEVICE_TYPE_GAS,
}ENUM_DEVICE_TYPE;
#endif
typedef struct
{
u8 second;
u8 minute;
u8 hour;
u8 day;
u8 month;
u8 year_low;
u8 year_high;
}
STRU_ENET_TIME;
/*********************************************************************************************************
协议标准头
*********************************************************************************************************/
typedef struct
{
u8 start;
u16 classification; /* 此处不能用枚举定义,防止大小端转换时被编译器优化 */
u8 sn;
u32 cmd;
u8 sum;
}STRU_ENET_HEAD;
/*********************************************************************************************************
设备 -》服务器: 心跳协议包
*********************************************************************************************************/
typedef struct
{
STRU_ENET_HEAD head;
u16 id;
u8 sn[6];
u8 arm;
u8 csq;
u16 ac_voltage;
u16 out_voltage;
u16 battery;
u32 end;
}STRU_ENET_D2S_PULSE;
/*********************************************************************************************************
设备 -》服务器: 报警协议包
*********************************************************************************************************/
typedef struct
{
STRU_ENET_HEAD head;
STRU_ENET_TIME alarm_time;
u16 id;
u8 sn[6];
u16 event; /* ENET报警代码 */
u16 zone; /* ENET防区号,有可能为空 */
u8 subzone; /* ENET分区号,为0 */
u16 end;
}
STRU_ENET_D2S_ALARM;
/*********************************************************************************************************
服务器 -》设备: 控制协议包
*********************************************************************************************************/
typedef struct
{
STRU_ENET_HEAD head;
u32 cmd;
u8 zone;
u8 subzone; /* 协议未做定义,保留 */
u16 end;
}
STRU_ENET_S2D_CTRL;
#if 0
typedef enum
{
LANGUAGE_CHINESE,
LANGUAGE_ENGLISH,
}
ENUM_LANGUAGE; /* 本枚举定义语言,同数据点<LanguageSet> */
typedef enum
{
CMD_RET_INVALID=0,
CMD_RET_OK,
CMD_RET_PWD_ERR,
CMD_RET_USER_PWD_ERR
}
ENUM_CMD_RET; /* 本枚举定义命令解析后结果返回 */
typedef enum
{
ECHO_NULL = 0,
ECHO_CONST_ASCII,
ECHO_CONST_HANZI,
ECHO_DETECTOR_LEARNED,
ECHO_PHONE,
ECHO_SYSTEM2, /* 返回IP、NTP_IP。。。 */
ECHO_DELAY,
ECHO_ENABLE,
ECHO_INIT_OK,
ECHO_SYSTEM,
}
ENUM_CMD_ECHO; /* 本枚举定义命令解析后需要返回内容类型的定义 */
typedef enum
{
CMD_SET_LEARN_RMT = 21,
CMD_SET_DELETE_RMT = 22,
CMD_SET_LEARN_DETECTOR = 23,
CMD_SET_DELETE_DETECTOR = 24,
CMD_SET_DELETE_DETECTOR_ALL = 25,
CMD_SET_RF_ZONE_MODE = 26, /* 设置每个无线防区类型(出入防区,内部防区,24小时防区) */
CMD_SET_ZONE_MODE = 47, /* 设置每个有线防区类型(出入防区,内部防区,24小时防区) */
CMD_SET_RF_ID = 27, /* 设置产品序列号 */
CMD_SET_SIREN_ENABLE = 31,
CMD_SET_SIREN_DELAY = 32, /* unit:m range:0~255 */
CMD_SET_EXIT_DELAY = 33, /* unit:s range:0~255 */
CMD_SET_ENTRY_DELAY = 34, /* unit:s range:0~255 */
CMD_SET_REDIAL_COUNTER = 35,
CMD_SET_RING_COUNTER = 36,
CMD_SET_AUDIO_RECORD = 37,
CMD_SET_USER_PASSWORD = 38,
CMD_SET_ENGINEER_PASSWORD = 39,
CMD_SET_KEY_LOCK_ENABLE = 40,
CMD_SET_AUTO_ARM_ENABLE = 41,
CMD_SET_AUTO_ARM = 42,
CMD_SET_FORMAT_PARTIAL = 43, /* 参数初始化(遥控器、探测器保留)*/
CMD_SET_QUERY_RECORD = 44,
CMD_SET_DELETE_RECORD = 45,
CMD_SET_ARM_SMS_ENABLE = 46,
CMD_SET_CLOCK = 48,
CMD_SET_SMS_PHONE1 = 49,
CMD_SET_SMS_PHONE2 = 50,
CMD_SET_MONITOR_PHONE1 = 51,
CMD_SET_MONITOR_PHONE2 = 52,
CMD_SET_MONITOR_PHONE3 = 53,
CMD_SET_MONITOR_PHONE4 = 54,
CMD_SET_MONITOR_PHONE5 = 55,
CMD_SET_MONITOR_PHONE6 = 56,
CMD_SET_ZONE_NAME = 60, /* 设置每个防区的报警名字 */
CMD_SET_GSM_CSQ = 62,
CMD_SET_LANGUAGE = 65, /* 设置短信语言,同数据点定义 */
CMD_SET_IP = 90, /* *1234*90123,34,26,89,8899* */
CMD_SET_NTP_IP = 91, /* 设置默认的网络时间服务器(由M26模块AT+QNTP命令专用) */
CMD_SET_APN = 92, /* 设置APN */
}
ENUM_CMD_SET;
#endif
typedef enum
{
PGS_NB_FREE,
PGS_NB_TCP_PULSE, // 心跳
PGS_NB_TCP_ALARM, // 开关门
}
ENUM_PGS_NB; /* 本枚举定义GSM正在进行的工作流程 */
typedef enum /*本枚举定义AT命令的发送状态*/
{
SEN_READY=0,
RET_WAIT,
RET_ERR,
RET_OK,
RET_TIMEOUT,//单次发送超时
RET_TOTAL_OUT,//总时间超时
RET_CONNECT_ERR,
RET_SYS_ALM, //系统有报警任务
RET_AT_ERR,
}
AT_STAT;
typedef enum
{
SYS_ERR_OK = 0,
SYS_ERR_AT_FAIL,
SYS_ERR_TCP_ACK_FAIL, /* 模块进行TCP传输时,ACK失败 */
SYS_ERR_CONNECTED, /* 通话呼出时,如果对方接通则有效 */
SYS_ERR_FAIL_OTHERS
}SYS_ERR; /* 本枚举定义执行AT指令得返回结果状态 */
//**********************NB状态定义*******************************/
/* these bits defined for <status> */
#define NB_STAT_AT_OK BIT0
#define NB_STAT_CREG BIT1
#define NB_STAT_INIT BIT2
#define NB_STAT_WAKEUP_AEP_CONNECT BIT3
#define NB_STAT_AEP_CONNECT BIT4
#define NB_STAT_QENG BIT5
#define NB_STAT_DISARM BIT6 /* NB报警流程中收到撤防指令后置位,用于中断报警流程 */
#define NB_STAT_INIT_OK BIT7
#define NB_STAT_SLEEP BIT8
#define NB_STAT_FAULT BIT9
#define NB_STAT_TCP_SEND BIT10
#define NB_STAT_RECEIVE_DATA BIT11
#define NB_STAT_READ_IMEI BIT12
#define NB_STAT_NB_WAKEUP BIT13
#define NB_STAT_CREG_OK BIT14
#define NB_STAT_NB_SLEEP BIT15
/* these bits defined for <task> */
#define NB_TASK_CREG BIT0
#define NB_TASK_AGPS BIT1
#define NB_TASK_CMGR BIT2
#define NB_TASK_CMGD BIT3
#define NB_TASK_HANGUP BIT4
#define NB_TASK_CALL_IN BIT5
#define NB_TASK_ENET_PULSE BIT6 /* GPRS通道心跳任务 */
#define NB_TASK_ENET_ALARM BIT7 /* GPRS通道报警任务 */
#define NB_TASK_ENET_ACK BIT8 /* 设备返回ACK */
#define NB_TASK_ENTER_SLEEP BIT9
#define NB_TASK_EXIT_SLEEP BIT10
#define NB_TASK_RECEIVE_DATA BIT11
#if 0
/*********************************************************************************************************
设置参数结构定义(为了在模拟EEPROM中兼容16bit数据读写,两字节对齐)__align(2)
*********************************************************************************************************/
typedef struct
{
u8 ip[4];
u16 port;
}
STRU_IP;
typedef struct
{
u32 id;
u16 user_pwd; /* 4 numbers default:1234 */
u16 engineer_pwd; /* 4 numbers default:6666 */
STRU_IP gprs_ip;
u8 language;
u32 flg_eeprom_init;
}
STRU_PARA_SET;
#endif
typedef struct
{
const u16 code;
const u8 zone;
STRU_ENET_TIME alarm_time;
}
STRU_ENET_ALARM; /* 本结构用于所有防区最新报警:待ENET上传的报警模块 */
/*********************************************************************************************************
NB操作状态结构定义
*********************************************************************************************************/
typedef struct
{
uint8_t flg; //
uint8_t reset; //复位标志位
uint8_t rssi; //信号强度
uint8_t socket_id;//端口ID
uint16_t task; //NB的任务
uint16_t status; //NB模块的状态
u8 enet_ack_sn;
u16 rev_len;
STRU_ENET_ALARM *enet_alarm;
}STRU_NB;
typedef struct
{
char* s_comm; //要发送的AT命令
char* r_comm; //要收到的AT命令
uint8_t status; //当前AT命令收发的状态
u8 timeout;//单次发送超时时间
u8 time_total;//超时重发
}STRU_AT;
EXT STRU_AT* pStruAT;
EXT STRU_NB struNb;
//EXT STRU_PARA_SET struParaSet;
EXT u8 pgsNb;
EXT void nb_task_init(void);
EXT void nb_usart_handle(void);
EXT void nb_task(void);
EXT void ATAckTimeoutCallback(void);
EXT void nb_task_time_callback(void);
EXT void check_nb_alarm_task(void);
//EXT void get_tcp_ip_bit(STRU_PARA_SET * para);
EXT u8 TemperatureConvert(u16 adcTemp);
#endif