/* ********************************************************************************************************* * IAR Development Kits * on the * * M451 * * Filename : uart_dtu.c * Version : V1.00 * Programmer(s) : Qian Xianghong ********************************************************************************************************* */ #include "includes.h" #include "drv_dtu.h" #include "drv_gps.h" // 是否打印DTU串口收到的字符 uint8_t DTU_uartPrint = 0; // 串口超时定时器 const uint16_t DTU_tmrQPendLong = 120; // 120s const uint16_t DTU_tmrQPendShort = 5; // 5s const uint16_t DTU_tmrQPendSpec = 40; // 40s // 4G模块型号(决定是否基站定位等) uint8_t DTU_model = DTU_MODEL_NONE; // 基站定位获取的经纬度 int32_t DTU_longitude = 0, DTU_latitude = 0; // DTU上电标志 uint8_t DTU_hasPowered = 0; uint8_t DTU_imeiRead = 0; uint8_t DTU_simCard = 0; uint8_t DTU_simReg = 0; uint8_t DTU_gprsReg = 0; uint8_t DTU_isATMode = 0; uint8_t DTU_gprsAttached = 0; uint8_t DTU_linkEstablished = 0; uint8_t DTU_sslConfig = 0; uint8_t DTU_mqttConfig = 0; uint8_t DTU_ipFetched = 0; char DTU_APN[20] = ""; uint8_t DTU_isRMCFormat = 0; uint8_t DTU_fail_count = 0; uint8_t DTU_shutdown_count = 0; // 清空无效数据 static void DTU_ClearQueue() { uint8_t timeOut; uint32_t timeOutTick; do { timeOut = 1; timeOutTick = GetDelayTick(500); while(!IsTickOut(timeOutTick)) { if(LoopBuff_GetCount(&DTU_TaskM)) { timeOut = 0; break; } } LoopBuff_Clear(&DTU_TaskM); } while(!timeOut); } // 等待DTU命令的返回,检查期待的结果字符串 uint32_t DTU_ParseResult(char *checkPattern, char *checkErrPattern, char *resultBuff, uint16_t waitSeconds) { uint8_t done = 0, timeOut; uint32_t timeOutTick; uint8_t u8DTU; uint16_t count, idx = 0; uint32_t ret = FALSE; uint8_t strLen = strlen(checkPattern); uint8_t errLen = strlen(checkErrPattern); memset(DTU_recvBuff, 0, DTU_RECVBUFF_SIZE); // 检测返回信息 do { timeOut = 1; timeOutTick = GetDelayTick(waitSeconds * 1000); while(!IsTickOut(timeOutTick)) { if(LoopBuff_GetCount(&DTU_TaskM)) { timeOut = 0; break; } } if(!timeOut) { count = LoopBuff_GetCount(&DTU_TaskM); while(count--) { // 取数据 memmove(&u8DTU, LoopBuff_GetDataPtr(&DTU_TaskM, DTU_TaskM.info.rdPtr), 1); LoopBuff_RemoveItems(&DTU_TaskM, 1); // if(u8DTU == '\n') // printf("\\n"); // else if(u8DTU == '\r') // printf("\\r"); // else // printf("%c", u8DTU); // 如果是检测发送的提示符(>),直接返回成功 if(strcmp(checkPattern, ">") == 0 && u8DTU == '>') { strcpy(resultBuff, ">"); ret = TRUE; done = 1; break; } // 换行符 if(u8DTU == '\n') { // 丢掉\n前面的\r if(idx > 0 && DTU_recvBuff[idx - 1] == '\r') DTU_recvBuff[--idx] = 0; // 先检查字符串(电话号码没有特征字符串) if((strLen > 0 && strstr(DTU_recvBuff, checkPattern)) || (strLen == 0 && idx > 0)) { DTU_recvBuff[idx] = 0; strcpy(resultBuff, DTU_recvBuff); ret = TRUE; done = 1; break; } // 检查返回错误的字符串 if(errLen > 0 && strstr(DTU_recvBuff, checkErrPattern)) { DTU_recvBuff[idx] = 0; strcpy(resultBuff, DTU_recvBuff); ret = FALSE; done = 1; break; } // 没有所要的字符串,清空 memset(DTU_recvBuff, 0, DTU_RECVBUFF_SIZE); idx = 0; continue; } if(idx < DTU_RECVBUFF_SIZE) DTU_recvBuff[idx++] = u8DTU; } } } while(!done && !timeOut); return ret; } // 执行命令,等待结果 uint32_t DTU_ExecuteCmd(char *cmd, char *checkPattern, char *checkErrPattern, char *resultBuff, uint16_t waitSeconds) { uint32_t ret = FALSE; // 检查并及时打开GPS电源 if(DTU_needCheckGPS) DTU_CheckGPS(); if(DTU_hasPowered) { // 唤醒 // UART_Transmit(&huart1, (uint8_t *) "AT\r", 3); // delay_ms(5); printf("\n=> %s\n", cmd); // 清空数据 DTU_ClearQueue(); // 发送命令, 并附加回车换行符 UART_Transmit(&huart1, (uint8_t *) cmd, strlen(cmd)); UART_Transmit(&huart1, (uint8_t *) "\r", 1); // 等待结果 ret = DTU_ParseResult(checkPattern, checkErrPattern, resultBuff, waitSeconds); } return ret; } // 等待服务器端返回(至少len个字节,最多size个字节),直到收完或超时 // 返回值为实际收到的数据长度 uint16_t DTU_WaitResponse(uint8_t ssl, uint16_t len, uint8_t *buff, uint16_t size, uint16_t waitSeconds) { uint8_t timeOut; uint32_t timeOutTick; uint8_t u8DTU, phase; uint16_t i, count, data_count; uint16_t preidx, idx; char cntbuff[40], prebuff[40], *p, *p1; // 等待返回数据 idx = 0; memset(prebuff, 0, sizeof(prebuff)); preidx = 0; phase = 0; do { timeOut = 1; timeOutTick = GetDelayTick(idx == 0 ? waitSeconds * 1000 : 1000); while(!IsTickOut(timeOutTick)) { if(LoopBuff_GetCount(&DTU_TaskM)) { timeOut = 0; break; } } if(!timeOut) { count = LoopBuff_GetCount(&DTU_TaskM); while(count--) { // 取数据 memmove(&u8DTU, LoopBuff_GetDataPtr(&DTU_TaskM, DTU_TaskM.info.rdPtr), 1); LoopBuff_RemoveItems(&DTU_TaskM, 1); // if(u8DTU == '\n') // printf("\\n"); // else if(u8DTU == '\r') // printf("\\r"); // else if(isprint(u8DTU)) // printf("%c", u8DTU); // else // printf("[%02X]", u8DTU); if(phase == 0) { // 接收URC消息错误 if(preidx >= sizeof(prebuff) - 1) return 0; prebuff[preidx++] = u8DTU; if(u8DTU == '\n') { if(!ssl) p = strstr(prebuff, "+QIURC: \"recv\",0,"); else p = strstr(prebuff, "+QSSLURC: \"recv\",1,"); if(p) // 获取数据长度 { p += (ssl ? 19 : 17); p1 = strstr(p, "\r\n"); // 接收URC消息错误 if(!p1 || p1 >= p + sizeof(cntbuff)) return 0; memset(cntbuff, 0, sizeof(cntbuff)); strncpy(cntbuff, p, p1 - p); data_count = atoi(cntbuff); phase = 1; } else { memset(prebuff, 0, sizeof(prebuff)); preidx = 0; } } } else if(idx < size) { if(data_count--) buff[idx++] = u8DTU; if(data_count == 0) { memset(prebuff, 0, sizeof(prebuff)); preidx = 0; phase = 0; } } } } } while(idx < size && !timeOut); if(!ssl) { printf("\nresponse from server (%d bytes):\n", idx); for(i = 0; i < idx && i < 128; i++) printf("%02X ", buff[i]); if(idx > 128) printf("..."); printf("\n"); } if(idx < len) strcpy(dcBuff.powerInfo.gprsFailCode, "RECV"); else { // 不清除错误代码(始终保留最近一次的错误代码) // strcpy(dcBuff.powerInfo.gprsFailCode, ""); } return idx; } // 模块DEACT uint8_t DTU_Shutdown() { uint8_t ret = 0; char buff[40]; // 设置标志 DTU_imeiRead = 0; DTU_simCard = 0; DTU_simReg = 0; DTU_gprsReg = 0; DTU_gprsAttached = 0; DTU_linkEstablished = 0; DTU_sslConfig = 0; DTU_mqttConfig = 0; DTU_ipFetched = 0; DTU_fail_count = 0; dcBuff.dtuData.connected = 0; DTU_shutdown_count++; if(DTU_ExecuteCmd("AT+QIDEACT=1", "OK", "ERROR", buff, DTU_tmrQPendSpec)) { strcpy(DTU_APN, ""); printf("\nDTU shutdown.\n"); ret = 1; } else printf("\nDTU shutdown failed.\n"); return ret; } // 发送数据, 等待服务器返回 uint32_t DTU_SendAndRecv(uint8_t ssl, uint8_t *data, uint16_t len, uint16_t *recvLen, uint8_t *recvBuff, uint16_t recvSize) { char cmd[40], buff[40]; int8_t try_count = 2; uint32_t ret = TRUE; uint16_t rlen = *recvLen; uint16_t totalLen = 0, rslen; S_RTC_TIME_DATA_T sRTC; // 唤醒 // UART_Transmit(&huart1, (uint8_t *) "AT\r", 3); // delay_ms(5); // 清空数据 DTU_ClearQueue(); // EC20一次最多只能发送1460字节 while(totalLen < len) { if(len - totalLen > 1460) rslen = 1460; else rslen = len - totalLen; // 发送命令, 并附加回车换行符 if(!ssl) sprintf(cmd, "AT+QISEND=0,%d", rslen); else sprintf(cmd, "AT+QSSLSEND=1,%d", rslen); do { ret = FALSE; UART_Transmit(&huart1, (uint8_t *) cmd, strlen(cmd)); UART_Transmit(&huart1, (uint8_t *) "\r", 1); if(DTU_ParseResult(">", "", buff, DTU_tmrQPendShort)) { delay_ms(10); UART_Transmit(&huart1, data + totalLen, rslen); ret = DTU_ParseResult("SEND OK", "SEND FAIL", buff, DTU_tmrQPendSpec); } if(ret) { totalLen += rslen; break; } delay_ms(200); } while(--try_count > 0); if(!ret) { strcpy(dcBuff.powerInfo.gprsFailCode, "SEND"); break; } } if(ret && rlen > 0) { do { rslen = DTU_WaitResponse(ssl, rlen, recvBuff, recvSize, DTU_tmrQPendSpec); memmove(recvLen, &rslen, 2); ret = (rslen >= rlen); if(ret) break; delay_ms(200); } while(--try_count > 0); } if(ret) { DTU_fail_count = 0; DTU_shutdown_count = 0; printf("\nSend %d bytes ok\n", len); // 记录发送成功的时间 RTC_GetDateAndTime(&sRTC); DTU_succTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); return TRUE; } printf("\nSend failed\n"); // 如果2次失败,模块关机/关电 if(++DTU_fail_count >= 2) { if(DTU_shutdown_count >= 1 || !DTU_Shutdown()) DTU_PowerOff(); } return FALSE; } // 定时器检查DTU是否休眠,如未休眠则关电 void DTU_CheckSleep() { } void DTU_Sleep() { DTU_PowerOff(); } // 模块上电,等1秒钟才能发送命令 void DTU_PowerOn() { char buff[40]; S_RTC_TIME_DATA_T sRTC; uint8_t try_count = 2; if(!DTU_hasPowered) { printf("\nDTU power on ...\n"); delay_ms(200); VCC_GSM_ON(); // delay_ms(10000); if(DTU_ParseResult("Lierda", "", buff, DTU_tmrQPendShort)) DTU_model = DTU_MODEL_LIERDA; else if(DTU_ParseResult("RDY", "", buff, DTU_tmrQPendShort * 2)) DTU_model = DTU_MODEL_QUECTEL; else DTU_model = DTU_MODEL_NONE; // 获取当前时间 RTC_GetDateAndTime(&sRTC); // 重设自上次gps定位以来的时间 DTU_gpsTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); // 设置标志 DTU_hasPowered = 1; // 关闭命令回显 while(try_count--) { if(DTU_ExecuteCmd("ATE0", "OK", "", buff, DTU_tmrQPendShort)) { printf("\nDTU echo off.\n"); break; } printf("\nDTU echo off failed.\n"); delay_ms(2000); } // 版本 if(DTU_ExecuteCmd("ATI", "Revision: ", "", buff, DTU_tmrQPendShort)) printf("\n%s\n", buff); if(GPS_Waiting || dcBuff.configDisplay.op_SEND_GPS_DATA) { if(try_count > 0) delay_ms(2000); // 在这里主动打开GPS DTU_EnableGPS(); } } } // 模块关电 void DTU_PowerOff() { char buff[40]; // 禁止重启GPS DTU_needCheckGPS = 0; if(DTU_hasPowered) { // 关闭GPS DTU_DisableGPS(); if(DTU_ExecuteCmd("AT+QPOWD=1", "POWERED DOWN", "", buff, DTU_tmrQPendShort * 2)) printf("\nGPRS disconnected.\n"); else printf("\nGPRS disconnect failed.\n"); // 设置标志 DTU_hasPowered = 0; DTU_imeiRead = 0; DTU_simCard = 0; DTU_simReg = 0; DTU_gprsReg = 0; DTU_isATMode = 0; DTU_gprsAttached = 0; DTU_linkEstablished = 0; DTU_sslConfig = 0; DTU_mqttConfig = 0; DTU_ipFetched = 0; strcpy(DTU_APN, ""); DTU_isRMCFormat = 0; DTU_fail_count = 0; dcBuff.dtuData.connected = 0; DTU_shutdown_count = 0; printf("\nDTU power off ...\n"); VCC_GSM_OFF(); } } // 读取IMEI号码(测试4G模块是否正常) uint32_t DTU_ReadIMEI() { char buff[40]; uint8_t try_count = 2; if(DTU_imeiRead) return TRUE; while(try_count--) { if(DTU_ExecuteCmd("AT+GSN", "", "ERROR", buff, DTU_tmrQPendShort)) { if(strlen(buff) == 15) { DTU_imeiRead = 1; printf("\nThe IMEI is: %s\n", buff); return TRUE; } } delay_ms(200); } printf("\nRead IMEI failed.\n"); return FALSE; } // 检查sim card uint32_t DTU_CheckSimCard() { char buff[40]; uint8_t try_count = 4; if(DTU_simCard) return TRUE; while(try_count--) { if(DTU_ExecuteCmd("AT+CPIN?","+CPIN:", "", buff, DTU_tmrQPendShort) && strstr(buff, "+CPIN: READY")) { DTU_simCard = 1; printf("\nSim card ready.\n"); return TRUE; } delay_ms(200); } DTU_simReg = 0; DTU_gprsReg = 0; DTU_gprsAttached = 0; DTU_linkEstablished = 0; DTU_sslConfig = 0; DTU_mqttConfig = 0; DTU_ipFetched = 0; printf("\nSim card not ready.\n"); return FALSE; } // 检查GPRS附着情况:最多等40秒 uint32_t DTU_CheckGprs() { char buff[40]; uint32_t check_time; S_RTC_TIME_DATA_T sRTC; if(DTU_gprsAttached) return TRUE; // 获取当前时间 RTC_GetDateAndTime(&sRTC); check_time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); DTU_ExecuteCmd("AT+CGATT=1", "OK", "ERROR", buff, DTU_tmrQPendLong); do { if(DTU_ExecuteCmd("AT+CGATT?", "+CGATT: 1", "+CGATT: 0", buff, DTU_tmrQPendShort)) { DTU_gprsAttached = 1; printf("\nGprs attached.\n"); return TRUE; } delay_ms(1000); RTC_GetDateAndTime(&sRTC); } while(Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) < check_time + 120); DTU_gprsAttached = 0; DTU_linkEstablished = 0; DTU_sslConfig = 0; DTU_mqttConfig = 0; DTU_ipFetched = 0; printf("\nGprs not attached.\n"); // 如果1次失败,模块关机/关电 if(++DTU_fail_count >= 1) { if(DTU_shutdown_count >= 1 || !DTU_Shutdown()) DTU_PowerOff(); } return FALSE; } // 设置APN uint32_t DTU_SetAPN(char *APN, char *User, char *Pwd) { char cmd[50], buff[40]; uint8_t try_count = 2; if(strcmp(DTU_APN, APN) == 0) return TRUE; while(try_count--) { sprintf(cmd, "AT+QICSGP=1,1,\"%s\",\"%s\",\"%s\"", APN, User, Pwd); if(DTU_ExecuteCmd(cmd, "OK", "ERROR", buff, DTU_tmrQPendShort)) { strcpy(DTU_APN, APN); printf("\nSet APN to \"%s\".\n", APN); return TRUE; } delay_ms(200); } printf("\nSet APN failed.\n"); return FALSE; } // 建立无线链路 uint32_t DTU_EstablishLink() { char buff[40]; uint8_t try_count = 2; if(DTU_linkEstablished) return TRUE; while(try_count--) { if(DTU_ExecuteCmd("AT+QIACT=1", "OK", "ERROR", buff, DTU_tmrQPendLong)) { DTU_linkEstablished = 1; printf("\nGprs link established\n"); // DTU_ExecuteCmd("AT+QIDNSCFG=1", "OK", "ERROR", buff, DTU_tmrQPendShort); return TRUE; } delay_ms(200); } DTU_ipFetched = 0; printf("\nGprs link not established.\n"); // 如果2次失败,模块关机/关电 if(++DTU_fail_count >= 1) { if(DTU_shutdown_count >= 1 || !DTU_Shutdown()) DTU_PowerOff(); } return FALSE; } uint32_t DTU_ConfigSSL() { char cmd[40], buff[40]; if(DTU_sslConfig) return TRUE; // 检查、上传CA证书 while(!DTU_ExecuteCmd("AT+QFLST=\"RAM:ca_cert.pem\"", "+QFLST: \"RAM:ca_cert.pem\"", "ERROR", buff, DTU_tmrQPendShort)) { sprintf(cmd, "AT+QFUPL=\"RAM:ca_cert.pem\",%d", strlen(ca_cert)); if(DTU_ExecuteCmd(cmd, "CONNECT", "ERROR", buff, DTU_tmrQPendShort)) { UART_Transmit(&huart1, (uint8_t *) ca_cert, strlen(ca_cert)); if(DTU_ParseResult("+QFUPL:", "ERROR", buff, DTU_tmrQPendShort)) { printf("\nca_cert.pem uploaded\n"); break; } } printf("\nca_cert.pem upload failed\n"); return FALSE; } // 检查、上传CLIENT证书 while(!DTU_ExecuteCmd("AT+QFLST=\"RAM:client_cert.pem\"", "+QFLST: \"RAM:client_cert.pem\"", "ERROR", buff, DTU_tmrQPendShort)) { sprintf(cmd, "AT+QFUPL=\"RAM:client_cert.pem\",%d", strlen(client_cert)); if(DTU_ExecuteCmd(cmd, "CONNECT", "ERROR", buff, DTU_tmrQPendShort)) { UART_Transmit(&huart1, (uint8_t *) client_cert, strlen(client_cert)); if(DTU_ParseResult("+QFUPL:", "ERROR", buff, DTU_tmrQPendShort)) { printf("\nclient_cert.pem uploaded\n"); break; } } printf("\nclient_cert.pem upload failed\n"); return FALSE; } // 检查、上传CLIENT密钥 while(!DTU_ExecuteCmd("AT+QFLST=\"RAM:client_key.pem\"", "+QFLST: \"RAM:client_key.pem\"", "ERROR", buff, DTU_tmrQPendShort)) { sprintf(cmd, "AT+QFUPL=\"RAM:client_key.pem\",%d", strlen(client_key)); if(DTU_ExecuteCmd(cmd, "CONNECT", "ERROR", buff, DTU_tmrQPendShort)) { UART_Transmit(&huart1, (uint8_t *) client_key, strlen(client_key)); if(DTU_ParseResult("+QFUPL:", "ERROR", buff, DTU_tmrQPendShort)) { printf("\nclient_key.pem uploaded\n"); break; } } printf("\nclient_key.pem upload failed\n"); return FALSE; } if(!DTU_ExecuteCmd("AT+QSSLCFG=\"ignorelocaltime\",1,1", "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; if(!DTU_ExecuteCmd("AT+QSSLCFG=\"sslversion\",1,4", "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; if(!DTU_ExecuteCmd("AT+QSSLCFG=\"ciphersuite\",1,0xFFFF", "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; if(!DTU_ExecuteCmd("AT+QSSLCFG=\"seclevel\",1,2", "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; if(!DTU_ExecuteCmd("AT+QSSLCFG=\"cacert\",1,\"RAM:ca_cert.pem\"", "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; if(!DTU_ExecuteCmd("AT+QSSLCFG=\"clientcert\",1,\"RAM:client_cert.pem\"", "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; if(!DTU_ExecuteCmd("AT+QSSLCFG=\"clientkey\",1,\"RAM:client_key.pem\"", "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; DTU_sslConfig = 1; return TRUE; } uint32_t DTU_ConfigMQTT(char *product, char *device, char *secret) { char cmd[100], buff[40], psn[14]; if(DTU_mqttConfig) return TRUE; sprintf(psn, "20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); // 每次重连服务器,需要重新订阅topic if(!DTU_ExecuteCmd("AT+QMTCFG=\"session\",0,1", "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; // URC只报长度,不报内容 if(!DTU_ExecuteCmd("AT+QMTCFG=\"recv/mode\",0,1,1", "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; // 阿里云授权码 sprintf(cmd, "AT+QMTCFG=\"aliauth\",0,\"%s\",\"%s\",\"%s\"", product, device, secret); if(!DTU_ExecuteCmd(cmd, "OK", "ERROR", buff, DTU_tmrQPendShort)) return FALSE; DTU_mqttConfig = 1; return TRUE; } // 获取基站定位经纬度(移远) uint32_t DTU_GetCellLocPosition_Quectel() { char buff[40]; uint8_t try_count = 2; char *p, *p1 = NULL; // 查询当前multi PDNs是否enabled(默认enabled) // if(!DTU_ExecuteCmd("AT+QCFG=\"PDP/DuplicateChk\"", "+QCFG: \"pdp/duplicatechk\"", "ERROR", buff, DTU_tmrQPendShort) // || strstr(buff, ",1") == 0) // { // // 设置当前multi PDNs为enabled // if(!DTU_ExecuteCmd("AT+QCFG=\"PDP/DuplicateChk\",1", "OK", "ERROR", buff, DTU_tmrQPendShort)) // { // printf("\nSet multi PDNs failed.\n"); // return FALSE; // } // } // // 查询当前contextid是否为1(默认为1) // if(!DTU_ExecuteCmd("AT+QLOCCFG=\"contextid\"", "+QLOCCFG: \"contextid\"", "ERROR", buff, DTU_tmrQPendShort) // || strstr(buff, ",1") == 0) // { // // 设置当前contextid为1 // if(!DTU_ExecuteCmd("AT+QLOCCFG=\"contextid\",1", "OK", "ERROR", buff, DTU_tmrQPendShort)) // { // printf("\nSet Cell-Loc contextid failed.\n"); // return FALSE; // } // } // 设置token(默认为空) if(!DTU_ExecuteCmd("AT+QLOCCFG=\"token\"", "+QLOCCFG: \"token\"", "ERROR", buff, DTU_tmrQPendShort) || strstr(buff, "exist") == 0) { if(!DTU_ExecuteCmd("AT+QLOCCFG=\"token\",\"u3S224CX18r4O045\"", "OK", "ERROR", buff, DTU_tmrQPendShort)) { printf("\nSet Cell-Loc token failed.\n"); return FALSE; } } // 查询当前基站定位服务器是否为www.queclocator.com:80 if(!DTU_ExecuteCmd("AT+QLOCCFG=\"server\"", "+QLOCCFG: \"server\"", "ERROR", buff, DTU_tmrQPendShort) || strstr(buff, "www.queclocator.com:80") == 0) { // 设置当前基站定位服务器为www.queclocator.com:80 if(!DTU_ExecuteCmd("AT+QLOCCFG=\"server\",\"www.queclocator.com:80\"", "OK", "ERROR", buff, DTU_tmrQPendShort)) { printf("\nSet Cell-Loc server failed.\n"); return FALSE; } } while(try_count--) { if(DTU_ExecuteCmd("AT+QCELLLOC", "+QCELLLOC: ", "ERROR", buff, DTU_tmrQPendSpec)) { p = strstr(buff, "+QCELLLOC: "); if(p) { p += 11; p1 = strstr(p, ","); if(p1) { *p1 = 0; DTU_longitude = atof(p) * 1000000; p = p1 + 1; DTU_latitude = atof(p) * 1000000; printf("\nLatitude:\t%10.6f\n", DTU_latitude * 0.000001); printf("Longitude:\t%10.6f\n", DTU_longitude * 0.000001); return TRUE; } } } // 有可能是原来的token不对,重新设一次 if(!DTU_ExecuteCmd("AT+QLOCCFG=\"token\",\"u3S224CX18r4O045\"", "OK", "ERROR", buff, DTU_tmrQPendShort)) { printf("\nSet Cell-Loc token failed.\n"); return FALSE; } delay_ms(200); } printf("\nGet Cell-Loc position failed.\n"); return FALSE; } // 获取基站定位经纬度(利尔达) uint32_t DTU_GetCellLocPosition_Lierda() { char buff[40]; uint8_t try_count = 2; char *p, *p1 = NULL; // 设置基站定位的链接和token if(!DTU_ExecuteCmd("AT+LBSPARA=\"http://locator-aep.xiot.senthink.com/locator/v0.1/locate\",\"218AF70AC4DFF1D60CEE0C09AF7425C2\"", "OK", "ERROR", buff, DTU_tmrQPendShort)) { printf("\nSet Cell-Loc token failed.\n"); return FALSE; } while(try_count--) { if(DTU_ExecuteCmd("AT+LBS=0", "+LBS: ", "ERROR", buff, DTU_tmrQPendSpec)) { p = strstr(buff, "+LBS: "); if(p) { p += 6; p1 = strstr(p, ","); if(p1) { *p1 = 0; DTU_longitude = atof(p) * 1000000; p = p1 + 1; DTU_latitude = atof(p) * 1000000; printf("\nLatitude:\t%10.6f\n", DTU_latitude * 0.000001); printf("Longitude:\t%10.6f\n", DTU_longitude * 0.000001); if(((DTU_longitude < 5) && (DTU_longitude > -5)) && ((DTU_latitude < 5) && (DTU_latitude > -5))) return FALSE; return TRUE; } } } delay_ms(200); } printf("\nGet Cell-Loc position failed.\n"); return FALSE; } // 设置普通(AT命令,非透传)模式 // !!! 此命令在4G模块无效 !!! uint32_t DTU_SetATMode() { char buff[40]; uint8_t try_count = 2; if(DTU_isATMode) return TRUE; while(try_count--) { if(DTU_ExecuteCmd("AT+QIMODE=0","OK", "ERROR", buff, DTU_tmrQPendShort)) { DTU_isATMode = 1; printf("\nSet to AT cmd mode.\n"); return TRUE; } delay_ms(200); } printf("\nSet AT mode failed.\n"); return FALSE; } // 获得本机IP地址 uint32_t DTU_FetchIP() { char buff[40]; uint8_t try_count = 2; if(DTU_ipFetched) return TRUE; while(try_count--) { if(DTU_ExecuteCmd("AT+QIACT?", "+QIACT: 1,1", "+QIACT: 1,0", buff, DTU_tmrQPendShort)) { DTU_ipFetched = 1; printf("\nLocal ip is: %s\n", buff + 14); return TRUE; } delay_ms(200); } printf("\nFetch ip failed.\n"); return FALSE; } // 设置服务器格式为DNS // !!! 此命令在4G模块无效 !!! uint32_t DTU_SetDNSIP() { char buff[40]; uint8_t try_count = 2; while(try_count--) { if(DTU_ExecuteCmd("AT+QIDNSIP=1", "OK", "ERROR", buff, DTU_tmrQPendShort)) { printf("\nSet remote server to domain name.\n"); return TRUE; } delay_ms(200); } printf("\nSet remote server to domain name failed.\n"); return FALSE; } // 连接服务器:Direct push mode uint32_t DTU_Connect(uint8_t ssl, char *server, short port) { char cmd[80], buff[40]; uint32_t ret = FALSE; uint8_t try_count = 1; while(try_count--) { if(!ssl) { sprintf(cmd, "AT+QIOPEN=1,0,\"TCP\",\"%s\",%d,0,1", server, port); if(!DTU_ExecuteCmd(cmd, "+QIOPEN: 0,", "ERROR", buff, DTU_tmrQPendSpec)) break; if(strstr(buff, "+QIOPEN: 0,0")) { ret = TRUE; break; } } else { sprintf(cmd, "AT+QSSLOPEN=1,1,1,\"%s\",%d,1", server, port); if(!DTU_ExecuteCmd(cmd, "+QSSLOPEN: 1,", "ERROR", buff, DTU_tmrQPendSpec)) break; if(strstr(buff, "+QSSLOPEN: 1,0")) { ret = TRUE; break; } } delay_ms(200); } if(ret) { dcBuff.dtuData.connected = 1; printf("\nConnect to %s: %d\n", server, port); return TRUE; } dcBuff.dtuData.connected = 0; printf("\nCan not connect to %s: %d\n", server, port); // 如果2次失败,模块关机/关电 if(++DTU_fail_count >= 2) { if(DTU_shutdown_count >= 1 || !DTU_Shutdown()) DTU_PowerOff(); } return FALSE; } // 关闭连接 uint32_t DTU_Close(uint8_t ssl) { char buff[40]; uint8_t try_count = 2; uint8_t ret; if(!dcBuff.dtuData.connected) return TRUE; dcBuff.dtuData.connected = 0; while(try_count--) { // 可能返回OK,也可能返回错误(如连接已关闭,或被服务器主动关闭),都视为关闭成功 if(!ssl) ret = DTU_ExecuteCmd("AT+QICLOSE=0", "OK", "ERROR", buff, DTU_tmrQPendSpec); else ret = DTU_ExecuteCmd("AT+QSSLCLOSE=1", "OK", "ERROR", buff, DTU_tmrQPendSpec); if(ret) { printf("\nConnection closed.\n"); return TRUE; } delay_ms(200); } printf("\nConnection close failed.\n"); return FALSE; } // 读取sim卡电话号码 uint32_t DTU_ReadPhoneNo() { char buff[40]; uint8_t try_count = 2; if(strlen(dcBuff.powerInfo.simNumber)) return TRUE; while(try_count--) { if(DTU_ExecuteCmd("AT+QCCID", "+QCCID: ", "ERROR", buff, DTU_tmrQPendShort)) { strcpy(dcBuff.powerInfo.simNumber, buff + 8); printf("\nThe phone no is: %s\n", dcBuff.powerInfo.simNumber); return TRUE; } delay_ms(200); } printf("\nRead phone no failed.\n"); return FALSE; } // 读取IMSI(15位卡号) uint32_t DTU_ReadIMSI() { char buff[40]; uint8_t try_count = 2; if(strlen(dcBuff.powerInfo.simNumber)) return TRUE; while(try_count--) { if(DTU_ExecuteCmd("AT+CIMI", "", "ERROR", buff, DTU_tmrQPendShort)) { if(strlen(buff) == 15) { strcpy(dcBuff.powerInfo.simNumber, buff); printf("\nThe phone no is: %s\n", dcBuff.powerInfo.simNumber); return TRUE; } } delay_ms(200); } printf("\nRead phone no failed.\n"); return FALSE; } // 读取信号强度 uint32_t DTU_ReadRssi(uint8_t *rssi) { char buff[40]; uint8_t try_count = 6; char *pCSQ, *pCommon; uint8_t csq; *rssi = 0; while(try_count--) { if(DTU_ExecuteCmd("AT+CSQ", "+CSQ:", "ERROR", buff, DTU_tmrQPendShort)) { pCSQ = strstr(buff, "+CSQ: "); pCommon = strstr(buff, ","); if(pCommon) *pCommon = 0; // 将0~31的强度值转换为百分比 csq = atoi(pCSQ + 6); printf("\nThe CSQ is: %d\n", csq); if(csq != 99 && csq != 199) { if(csq < 100) { if(csq <= 31) *rssi = csq * 100 / 31; } else { if(csq <= 191) *rssi = csq - 100 + 9; } if(*rssi > 100) *rssi = 100; printf("\nThe rssi is: %d\n", *rssi); return TRUE; } } delay_ms(500); } printf("\nRead rssi failed.\n"); return FALSE; } // 读取入网标志 uint32_t DTU_ReadRegistry(uint8_t *reg) { char buff[40]; char *pReg; uint32_t check_time; uint16_t DTU_regTime = 60; uint8_t rssi = 0; S_RTC_TIME_DATA_T sRTC; if(DTU_simReg) { *reg = 1; return TRUE; } DTU_ReadRssi(&rssi); if(rssi >= 50) DTU_regTime = 150; // 获取当前时间 RTC_GetDateAndTime(&sRTC); check_time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); *reg = 0; do { if(DTU_ExecuteCmd("AT+CREG?", "+CREG:", "ERROR", buff, DTU_tmrQPendShort)) { pReg = strstr(buff, ","); if(pReg) { *reg = *(pReg + 1) - '0'; if(*reg == 0) break; } //printf("\n%s\n", buff); if(*reg == 1 || *reg == 5) { printf("\nRegistry status: %d.\n", *reg); *reg = 1; DTU_simReg = 1; return TRUE; } } delay_ms(1000); RTC_GetDateAndTime(&sRTC); } while(Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) < check_time + DTU_regTime); printf("\nRegistry status: %d.\n", *reg); // 如果2次失败,模块关机/关电 if(++DTU_fail_count >= 2) { if(DTU_shutdown_count >= 1 || !DTU_Shutdown()) DTU_PowerOff(); } else { DTU_gprsReg = 0; DTU_gprsAttached = 0; DTU_linkEstablished = 0; DTU_sslConfig = 0; DTU_mqttConfig = 0; DTU_ipFetched = 0; } return FALSE; } // 读取GPRS入网标志 uint32_t DTU_ReadGPRSRegistry(uint8_t *reg) { char buff[40]; char *pReg; uint32_t check_time; S_RTC_TIME_DATA_T sRTC; if(DTU_gprsReg) { *reg = 1; return TRUE; } // 获取当前时间 RTC_GetDateAndTime(&sRTC); check_time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); *reg = 0; do { if(DTU_ExecuteCmd("AT+CGREG?", "+CGREG:", "", buff, DTU_tmrQPendShort)) { pReg = strstr(buff, ","); if(pReg) { *reg = *(pReg + 1) - '0'; if(*reg == 0) break; } if(*reg == 1 || *reg == 5) { printf("\nGPRS registry status: %d.\n", *reg); *reg = 1; DTU_gprsReg = 1; return TRUE; } } delay_ms(1000); RTC_GetDateAndTime(&sRTC); } while(Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) < check_time + 60); printf("\nGPRS registry status: %d.\n", *reg); return FALSE; } char *DTU_DecideAPN() { if(strncmp(dcBuff.powerInfo.simNumber, "898604", 6) == 0) return "CMIOT"; if(strncmp(dcBuff.powerInfo.simNumber, "898607", 6) == 0) return "CMIOT"; if(strncmp(dcBuff.powerInfo.simNumber, "898602", 6) == 0) return "CMIOT"; if(strncmp(dcBuff.powerInfo.simNumber, "898600", 6) == 0) return "CMIOT"; if(strncmp(dcBuff.powerInfo.simNumber, "898608", 6) == 0) return "CMIOT"; if(strcmp(dcBuff.configDisplay.APN, "CMNET") == 0) return "CMIOT"; return dcBuff.configDisplay.APN; } char *DTU_DecideAPNUser() { if(strncmp(dcBuff.powerInfo.simNumber, "898604", 6) == 0) return ""; if(strncmp(dcBuff.powerInfo.simNumber, "898607", 6) == 0) return ""; if(strncmp(dcBuff.powerInfo.simNumber, "898602", 6) == 0) return ""; if(strncmp(dcBuff.powerInfo.simNumber, "898600", 6) == 0) return ""; if(strcmp(dcBuff.configDisplay.APN, "CMNET") == 0) return ""; return dcBuff.configDisplay.User; } char *DTU_DecideAPNPwd() { if(strncmp(dcBuff.powerInfo.simNumber, "898604", 6) == 0) return ""; if(strncmp(dcBuff.powerInfo.simNumber, "898607", 6) == 0) return ""; if(strncmp(dcBuff.powerInfo.simNumber, "898602", 6) == 0) return ""; if(strncmp(dcBuff.powerInfo.simNumber, "898600", 6) == 0) return ""; if(strcmp(dcBuff.configDisplay.APN, "CMNET") == 0) return ""; return dcBuff.configDisplay.Pwd; } // 读取GPRS网络信息信息 uint32_t Sim808_ReadGPRS() { uint8_t val; printf("\nRead RSSI data ....\n"); DTU_PowerOn(); if(!DTU_ReadIMEI()) { strcpy(dcBuff.powerInfo.gprsFailCode, "EC20"); return FALSE; } if(!DTU_CheckSimCard()) { strcpy(dcBuff.powerInfo.gprsFailCode, "SIM"); return FALSE; } if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_CHAOYANG) DTU_ReadIMSI(); else DTU_ReadPhoneNo(); if(!DTU_SetAPN(DTU_DecideAPN(), DTU_DecideAPNUser(), DTU_DecideAPNPwd())) { strcpy(dcBuff.powerInfo.gprsFailCode, "APN"); return FALSE; } if(!DTU_ReadRegistry(&val)) { strcpy(dcBuff.powerInfo.gprsFailCode, "REG"); return FALSE; } dcBuff.dtuData.networked = (val == 1 ? 1 : 0); if(DTU_ReadRssi(&val)) dcBuff.dtuData.rssi = val; return TRUE; } void DTU_setOffsetSeconds() { char buff[40], *p; S_RTC_TIME_DATA_T sRTC; uint32_t totalSeconds1, totalSeconds2; int8_t zz; if(DTU_ExecuteCmd("AT+QLTS=2", "+QLTS: ", "ERROR", buff, DTU_tmrQPendShort)) // Get UTC time { // 获取当前时间 RTC_GetDateAndTime(&sRTC); totalSeconds1 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); // UTC日期 p = strstr(buff, "+QLTS: \"") + 8; printf("\n%s\n", p); // 4位年份 p[4] = 0; sRTC.u32Year = atoi(p); p += 5; // 2位月份 p[2] = 0; sRTC.u32Month = atoi(p); p += 3; // 2位日期 p[2] = 0; sRTC.u32Day = atoi(p); p += 3; // 2位小时 p[2] = 0; sRTC.u32Hour = atoi(p); p += 3; // 2位分钟 p[2] = 0; sRTC.u32Minute = atoi(p); p += 3; // 2位秒 sRTC.u32Second = (*p - '0') * 10 + (*(p + 1) - '0'); p += 2; // 3位时差(按1/4小时, 带符号) p[3] = 0; zz = atoi(p); totalSeconds2 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); // 将UTC时间转换为GMT时间(时差为0) totalSeconds2 -= zz * 900; // 将GMT时间转换为UTC时间(按配置的时差) totalSeconds2 += dcBuff.configData.timeLag * 3600; if(RTC_offsetSeconds == 0) RTC_offsetSeconds = totalSeconds2 - totalSeconds1; } } // GPRS拨号 uint32_t Sim808_GPRSDial() { uint8_t reg; printf("\nGPRS Dialing ....\n"); DTU_PowerOn(); if(!DTU_ReadIMEI()) { strcpy(dcBuff.powerInfo.gprsFailCode, "EC20"); return FALSE; } if(!DTU_CheckSimCard()) { strcpy(dcBuff.powerInfo.gprsFailCode, "SIM"); return FALSE; } if(!DTU_SetAPN(DTU_DecideAPN(), DTU_DecideAPNUser(), DTU_DecideAPNPwd())) { strcpy(dcBuff.powerInfo.gprsFailCode, "APN"); return FALSE; } if(!DTU_ReadRegistry(®)) { strcpy(dcBuff.powerInfo.gprsFailCode, "REG"); return FALSE; } DTU_ReadGPRSRegistry(®); // if(!DTU_CheckGprs()) // { // strcpy(dcBuff.powerInfo.gprsFailCode, "GPRS"); // return FALSE; // } // if(!DTU_SetATMode()) // { // strcpy(dcBuff.powerInfo.gprsFailCode, "AT"); // return FALSE; // } if(!DTU_EstablishLink()) { strcpy(dcBuff.powerInfo.gprsFailCode, "ACT"); return FALSE; } // 修正时间基准(可显示绝对时间) if(RTC_offsetSeconds == 0) DTU_setOffsetSeconds(); if(RTC_offsetSeconds == 0) DTU_setOffsetSecondsFromServer(); return TRUE; } uint32_t Sim808_Connect(uint8_t ssl, char *server, int port) { if(!Sim808_GPRSDial()) return FALSE; // if(!DTU_FetchIP()) // { // strcpy(dcBuff.powerInfo.gprsFailCode, "IP"); // return FALSE; // } // if(!DTU_SetDNSIP()) // { // strcpy(dcBuff.powerInfo.gprsFailCode, "DNS"); // return FALSE; // } if(ssl && !DTU_ConfigSSL()) { strcpy(dcBuff.powerInfo.gprsFailCode, "SSL"); return FALSE; } printf("\nConnect to server....\n"); if(!DTU_Connect(ssl, server, port)) { strcpy(dcBuff.powerInfo.gprsFailCode, "CONN"); return FALSE; } return TRUE; } // 获取基站定位经纬度 uint32_t Sim808_GetCellLocPosition() { if(!Sim808_GPRSDial()) return FALSE; printf("\nGet Cell-Loc position....\n"); // 获取基站定位经纬度 if(DTU_model == DTU_MODEL_LIERDA) return DTU_GetCellLocPosition_Lierda(); // if(DTU_model == DTU_MODEL_QUECTEL) // return DTU_GetCellLocPosition_Quectel(); return FALSE; } uint32_t Sim808_SendAndRecv(uint8_t ssl, uint8_t *data, uint16_t len, uint16_t *recvLen, uint8_t *recvBuff, uint16_t recvSize) { return DTU_SendAndRecv(ssl, data, len, recvLen, recvBuff, recvSize); } // EC20一次最多只能发送1500字节 uint32_t DTU_MqttPublish(uint8_t *data, uint16_t len, char *product, char *device) { static uint16_t msgid = 1; char cmd[100], buff[40], psn[14]; int8_t try_count = 2; S_RTC_TIME_DATA_T sRTC; sprintf(psn, "20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); while(try_count--) { // 唤醒 // UART_Transmit(&huart1, (uint8_t *) "AT\r", 3); // delay_ms(5); // 清空数据 DTU_ClearQueue(); // 发送命令, 并附加回车换行符 sprintf(cmd, "AT+QMTPUBEX=0,%d,1,0,\"/sys/%s/%s/thing/model/up_raw\",%d", msgid, product, device, len); // printf("\n%s\n", cmd); UART_Transmit(&huart1, (uint8_t *) cmd, strlen(cmd)); UART_Transmit(&huart1, (uint8_t *) "\r", 1); if(DTU_ParseResult(">", "ERROR", buff, DTU_tmrQPendShort)) { delay_ms(10); UART_Transmit(&huart1, data, len); if(DTU_ParseResult("+QMTPUBEX: ", "ERROR", buff, DTU_tmrQPendSpec)) { sprintf(cmd, "+QMTPUBEX: 0,%d,0", msgid); if(strstr(buff, cmd)) { DTU_fail_count = 0; DTU_shutdown_count = 0; printf("\nSend %d bytes ok\n", len); msgid++; if(msgid == 0) msgid++; // 记录发送成功的时间 RTC_GetDateAndTime(&sRTC); DTU_succTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); return TRUE; } } } strcpy(dcBuff.powerInfo.gprsFailCode, "SEND"); delay_ms(200); } printf("\nSend failed\n"); // 如果2次失败,模块关机/关电 if(++DTU_fail_count >= 2) { if(DTU_shutdown_count >= 1 || !DTU_Shutdown()) DTU_PowerOff(); } return FALSE; } uint32_t Sim808_MqttPublish(uint8_t *data, uint16_t len, char *product, char *device) { return DTU_MqttPublish(data, len, product, device); } // 关闭连接 uint32_t MQTT_Close() { char buff[40]; uint8_t try_count = 2; if(!dcBuff.dtuData.connected) return TRUE; dcBuff.dtuData.connected = 0; while(try_count--) { // 可能返回OK,也可能返回错误(如连接已关闭,或被服务器主动关闭),都视为关闭成功 if(DTU_ExecuteCmd("AT+QMTDISC=0","+QMTDISC: 0,0", "ERROR", buff, DTU_tmrQPendShort)) { printf("\nConnection closed.\n"); return TRUE; } delay_ms(200); } printf("\nConnection close failed.\n"); return FALSE; } // 连接服务器:MQTT uint32_t DTU_MqttConnect(const char *server, int port) { char cmd[80], buff[40]; uint8_t try_count = 1; while(try_count--) { sprintf(cmd, "AT+QMTOPEN=0,\"%s\",%d", server, port); if(DTU_ExecuteCmd(cmd, "+QMTOPEN: 0,0", "ERROR", buff, DTU_tmrQPendSpec) && DTU_ExecuteCmd("AT+QMTCONN=0,\"Anjiehui_4G\"","+QMTCONN: 0,0,0", "ERROR", buff, DTU_tmrQPendShort)) { dcBuff.dtuData.connected = 1; printf("\nConnect to %s:%d\n", server, port); return TRUE; } delay_ms(200); } dcBuff.dtuData.connected = 0; printf("\nCan not connect to %s:%d\n", server, port); // 如果2次失败,模块关机/关电 if(++DTU_fail_count >= 2) { if(DTU_shutdown_count >= 1 || !DTU_Shutdown()) DTU_PowerOff(); } return FALSE; } uint32_t Sim808_MqttConnect(const char *server, int port, char *product, char *device, char *secret) { if(!Sim808_GPRSDial()) return FALSE; // if(!DTU_FetchIP()) // { // strcpy(dcBuff.powerInfo.gprsFailCode, "IP"); // return FALSE; // } // if(!DTU_SetDNSIP()) // { // strcpy(dcBuff.powerInfo.gprsFailCode, "DNS"); // return FALSE; // } if(!DTU_ConfigMQTT(product, device, secret)) { strcpy(dcBuff.powerInfo.gprsFailCode, "MQTT"); return FALSE; } printf("\nConnect to MQTT-Server....\n"); if(!DTU_MqttConnect(server, port)) { strcpy(dcBuff.powerInfo.gprsFailCode, "CONN"); return FALSE; } return TRUE; }