/** ****************************************************************************** * @file ME3616.c * @author 度云未来 DOIOT * @brief EC20模块AT指令简易串口驱动 ****************************************************************************** * @attention *

© Copyright (c) 2019 成都度云未来 * All rights reserved.

* 注意:本程序针对cubemx 生成的hal库快速开发 * 环境:keil5.0 * 描述: * 文件版本:1.3 更新时间2020/10/15 已支持TCP,LWM2M的连接 ********************************************************************************/ /*必备依赖*/ #include "includes.h" #include "trace.h" #include "me3616.h" /*文件的头文件*/ #include "at_module.h" /*AT指令相关的头文件*/ #include "string_fuc.h" #include #include #include #include /********************************************************************************/ /* 测试了strstr和kmp的性能,最终用strstr。 */ /* me3616类的句柄,该句柄会默认调用 */ ME3616 me3616; /*发送的指令组,需要校验的响应组,校验组数量,校验等级,重发次数,跳转位置,超时时间*/ /** * @brief ME3616句柄的构造函数 * @param 该函数会对本文件核心全局句柄进行函数构造 */ ME3616 * ME3616_Init() { ME3616 * me=&me3616; #if(config_MQTT_Enable) MQTT mqtt; me->MQTT=mqtt; me->MQTT.SetNet=MQTT_Set_Net; me->MQTT.Connect=MQTT_Connet; me->MQTT.Sub=MQTT_SUB; me->MQTT.Pub=MQTT_PUB; #endif me->imei_iccid_get = ME3616_IMEI_ICCID_INFO_GET; #if(config_TCP_Enable) TCP tcp; /*创建实体*/ me->TCP=tcp; me->TCP.CreateChannel=ME3616_Connect_TCP; me->TCP.CloseChannel=Close_TCP_Socket; me->TCP.SendStr=ME3616_TCP_SEND_String; me->TCP.SendHex=ME3616_TCP_SEND_Hex; me->TCP.GetData=ME3616_TCP_DATA_purification; #endif me->PowerOn=ME3616_Power_On; #if(Hvertion_data) me->HardRest=ME3616_HARD_Rest; #endif #if(SoftRest_fun) me->SoftRest=ME3616_SOFT_Rest; #endif #if(GetEPS_fun) me->GetEPS=ME3616_READ_EPS; #endif #if(GetCSQ_fun) me->GetCSQ=ME3616_READ_CSQ; #endif me->GetCESQ=ME3616_READ_CESQ; #if(GetCCID_fun) me->GetCCID=ME3616_READ_CCID; #endif me->GetPIN=ME3616_READ_PIN; #if(IMEI_ME3616_INFOrmation) me->GetIMEI=ME3616_READ_IMEI; #endif #if(Svertion_data) me->Version=ME3616_READ_Revision; #endif #if(ICCID_ME3616_INFOrmation) memset(me->State.iccid,0,50); #endif #if(IMEI_ME3616_INFOrmation) memset(me->State.imei,0,50); #endif memset(me->State.imsi,0,50); #if(MAC_ME3616_INFOrmation) memset(me->State.mac,0,50); #endif #if(Hvertion_data) memset(me->State.Hvertion,0,50); #endif #if(Svertion_data) memset(me->State.Svertion,0,50); #endif #if(config_LMW2M_Enable) memset(me->State.msgid,0,20); #endif #if(ICCID_ME3616_INFOrmation) me->flug.iccid=0; #endif #if(IMEI_ME3616_INFOrmation) me->flug.imei=0; #endif me->flug.imsi=0; #if(MAC_ME3616_INFOrmation) me->flug.mac=0; #endif #if(Hvertion_data) me->flug.Hvertion=0; #endif #if(Svertion_data) me->flug.Svertion=0; #endif me->flug.pwr=0; me->flug.rssi=0; me->flug.ber=0; me->flug.eps=0; me->flug.pin=0; me->flug.rest=0; #if defined (config_TCP_Enable_Disconnection_reconnection) me->flug.tcp_recon=0; #endif #if(config_LMW2M_Enable) me->flug.msgid=0; #endif // UartModuleInit(); return me; } uint8_t ME3616_Check_State() { #if (config_TCP_Enable_heart) /*心跳*/ if(me3616.State.TCP_State==1) { debug_printf("\r\n开始心跳\r\n"); char temp[256]={0}; Chaoyou_package("01","",temp); Check_Package(temp); me3616.TCP.send_Str(temp); } #endif #if (config_CEREG) /*网络检查*/ if(me3616.State.TCP_State==1) { } #endif #if (config_TCP_Enable_Disconnection_reconnection) /*重连检查*/ if(me3616.flug.tcp_recon) { if(me3616.State.TCP_State==0) { /*检查到掉线*/ me3616.flug.rest=1; } else { debug_printf("TCP连接正常"); } } #endif return 1; } /** * @brief ME3616硬件开机 * @param flug = 1,阻塞开机,会直到开机成功,且读取完全部开机信息后才会退出 * @param flug = 0,操作完硬件开机后立即返回 * @param [Antiphase_flug]额外参数 : 以宏形式的标志,1为反相,0为不反相 * 【是否反相根据硬件电路决定,如果mcu拉低,模组也被拉低,则不需要反相,否则给反相位置1即可】 * 如果在计时器启动前调用了,建议选择直接返回[针对RTOS] */ uint8_t ME3616_Power_On(uint8_t flug) { OS_ERR err; #if(config_CHINESE_LOG) ME3616_INFO("ME3616 硬件开机"); #else ME3616_INFO("ME3616 Hardware Power On"); #endif if(AT_CMD_Polling("AT\r\n","OK",100,300)) { me3616.State.pwr=1; #if(config_CHINESE_LOG) ME3616_INFO("ME3616 完成开机"); #else ME3616_INFO("ME3616 Power On"); #endif return 1; } #if 0 if(config_Antiphase_flug) { PWR_IO_PORT->ODR|=PWR_IO_PIN;/*拉低PWR引脚*/ OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err); //HAL_Delay(2000); /*延时两秒*/ PWR_IO_PORT->ODR&=!PWR_IO_PIN; /*拉高PWR引脚*/ } else { PWR_IO_PORT->ODR&=!PWR_IO_PIN;/*拉低PWR引脚*/ OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err); //HAL_Delay(2000); /*延时两秒*/ PWR_IO_PORT->ODR|=PWR_IO_PIN; /*拉高PWR引脚*/ } #endif if(flug) { char buff[MODULE_RDA_MAXlen]={0}; /*这里是为了吃掉三条开机信息,如果直接开始往下运行,开就信息可能会干扰*/ if(Module_Blocking_Read(buff,20000)) { me3616.State.pwr=1; if(strstr(buff,"*MATREADY:")) { memset(buff,0,MODULE_RDA_MAXlen); if(Module_Blocking_Read(buff,6000)) { if(strstr(buff,"+CPIN:")) { memset(buff,0,MODULE_RDA_MAXlen); if(Module_Blocking_Read(buff,60000)) { if(strstr(buff,"+IP:")) { /*完整开机需要的时常很长*/ AT_CMD_Polling("AT\r\n","OK",200,15000); AT_CMD_Polling("AT\r\n","OK",200,15000); AT_CMD_Polling("AT\r\n","OK",200,15000); ME3616_INFO("ME3616 Hardware Power On OK!"); return 1; } } } } } } } return 0; } /** * @brief ME3616硬件复位 * @param flug:复位标志,1,阻塞复位,会直到开机成功才退出,开机时间较长,2,立即返回*/ uint8_t ME3616_HARD_Rest(uint8_t flug) { OS_ERR err; #if(config_CHINESE_LOG) ME3616_INFO("ME3616开始硬件复位"); #else ME3616_INFO("ME3616 Hardware Reset"); #endif if(config_Antiphase_flug) { RST_IO_PORT->ODR|=RST_IO_PIN;/*拉低PWR引脚*/ OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err); //HAL_Delay(2000); /*延时两秒*/ RST_IO_PORT->ODR&=!RST_IO_PIN; /*拉高PWR引脚*/ } else { RST_IO_PORT->ODR&=!RST_IO_PIN;/*拉低PWR引脚*/ OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err); //HAL_Delay(2000); /*延时两秒*/ RST_IO_PORT->ODR|=RST_IO_PIN; /*拉高PWR引脚*/ } if(flug) { /*这里是为了吃掉三条开机信息,如果直接开始往下运行,开就信息可能会干扰*/ char buff[MODULE_RDA_MAXlen]={0}; if(Module_Blocking_Read(buff,20000)) { me3616.State.pwr=1; if(strstr(buff,"*MATREADY:")) { memset(buff,0,MODULE_RDA_MAXlen); if(Module_Blocking_Read(buff,6000)) { if(strstr(buff,"+CPIN:")) { memset(buff,0,MODULE_RDA_MAXlen); if(Module_Blocking_Read(buff,6000)) { if(strstr(buff,"+IP:")) { /*完整开机需要的时常很长*/ AT_CMD_Polling("AT\r\n","OK",200,15000); AT_CMD_Polling("AT\r\n","OK",200,15000); AT_CMD_Polling("AT\r\n","OK",200,15000); ME3616_INFO("ME3616 Hardware Reset OK!"); return 1; } } } } } } } return 1; } /** * @brief ME3616软件复位 * @param flug:复位标志,1,阻塞复位,会直到开机成功才退出,软复位很快,2,立即返回*/ uint8_t ME3616_SOFT_Rest(uint8_t flug) { #if(config_CHINESE_LOG) ME3616_INFO("ME3616开始软件复位"); #else ME3616_INFO("ME3616 Software Reset"); #endif Module_SEND_CRC("AT+ZRST\r\n","OK",500); if(flug) { /*这里是为了吃掉三条开机信息,如果直接开始往下运行,开就信息可能会干扰*/ char buff[MODULE_RDA_MAXlen]={0}; if(Module_Blocking_Read(buff,20000)) { me3616.State.pwr=1; if(strstr(buff,"*MATREADY:")) { memset(buff,0,MODULE_RDA_MAXlen); if(Module_Blocking_Read(buff,6000)) { if(strstr(buff,"+CPIN:")) { memset(buff,0,MODULE_RDA_MAXlen); if(Module_Blocking_Read(buff,6000)) { if(strstr(buff,"+IP:")) { /*完整开机需要的时常很长*/ AT_CMD_Polling("AT\r\n","OK",200,15000); AT_CMD_Polling("AT\r\n","OK",200,15000); AT_CMD_Polling("AT\r\n","OK",200,15000); ME3616_INFO("ME3616 Software Reset OK!"); return 1; } } } } } } } return 1; } /** * @brief ME3616读取网络状态并打印数据 **/ uint8_t ME3616_READ_EPS() { char buff[MODULE_RDA_MAXlen]={0}; char get_buff[100]; int log; ME3616_INFO("Start to query network registration status"); module_printf("AT+CEREG?\r\n"); if(Module_Blocking_Read(buff,1000)) { if(strstr(buff,"+CEREG:")) { AT_GET_Data_2Param(buff,(uint8_t*)get_buff,",","OK"); log=atoi(get_buff); me3616.State.eps=log; /*装载标数据*/ me3616.flug.eps=1; /*装载成功标志*/ switch(log) { case 0: ME3616_INFO("You are not logged on to the network. You are not searching the network at present"); break; case 1: ME3616_INFO("Local network already logged in"); break; case 2: ME3616_INFO("\r\nYou are not logged on to the network. You are currently searching the network\r\n"); break; case 3: ME3616_INFO("\r\nRegistration denied\r\n"); break; case 4: ME3616_INFO("\r\nUnknown state\r\n"); break; case 5: ME3616_INFO("\r\nYou have logged in to the network and are roaming\r\n"); break; default: { ME3616_ERROR("Response ME3616_ERROR:%s",buff); return 33;//设定的错误码 } } return log+1; } { ME3616_ERROR("%s",buff); return 0; } } ME3616_INFO("Response timeout"); return 0; } /** * @brief ME3616读取网络信号强度 * @param rssi:用来装载的参数,会装载信号强度原文[弃用] * @param ber:用来装载的参数, 会装载错码率原文[弃用] * */ uint8_t ME3616_READ_CSQ() { char buff[MODULE_RDA_MAXlen]={0}; char get_buff[32]={0}; int log; #if(config_CHINESE_LOG) ME3616_INFO("开始查询网络信号强度"); #else ME3616_INFO("Start querying network signal strength"); #endif module_printf("AT+CSQ\r\n"); if(Module_Blocking_Read(buff,1000)) { if(strstr(buff,"+CSQ:")) { AT_GET_Data_2Param(buff,(uint8_t*)get_buff,"+CSQ:",","); log=atoi(get_buff); me3616.State.rssi=log; me3616.flug.rssi=1; /*装载成功标志*/ if(log==99) {ME3616_INFO("signal intensity:there is no signal");} else if(log>=31&&log<=99) {ME3616_INFO("signal intensity:-51dBm or higher");} else if(log>=2&&log<31) {ME3616_INFO("signal intensity:-109dBm ~ -53dBm");} else if(log==1) {ME3616_INFO("signal intensity:-111dBm");} else {ME3616_INFO("signal intensity:-111dBm or less");} AT_GET_Data_2Param(buff,(uint8_t*)get_buff,",","OK"); log=atoi(get_buff); me3616.State.ber=log; me3616.flug.ber=1; /*装载成功标志*/ //*ber=log; switch(log) { case 0: ME3616_INFO("Bit error rate:<0.01%"); break; case 1: ME3616_INFO("Bit error rate:0.01% --- 0.1%"); break; case 2: ME3616_INFO("Bit error rate:0.1% --- 0.5%"); break; case 3: ME3616_INFO("Bit error rate:0.5% --- 1.0%"); break; case 4: ME3616_INFO("Bit error rate:1.0% --- 2.0%"); break; case 5: ME3616_INFO("Bit error rate:2.0% --- 4.0%"); break; case 6: ME3616_INFO("Bit error rate:4.0% --- 8.0%"); break; case 7: ME3616_INFO("Bit error rate:> 8.0%"); break; case 8: ME3616_INFO("Bit error rate:So far or not measurable");break; default: { ME3616_ERROR("So far or not measurable"); return 33;//设定的错误码 } } return log+1; } { ME3616_ERROR("%s",buff); return 0; } } ME3616_INFO("Response timeout"); return 0; } /** * @brief ME3616读取精确的网络信号强度 * */ int ME3616_READ_CESQ() { char buff[MODULE_RDA_MAXlen]={0}; char get_buff[100]={0}; int log; ME3616_INFO("Start querying network signal strength"); module_printf("AT+CESQ\r\n"); if(Module_Blocking_Read(buff,1000)) { if(strstr(buff,"+CESQ:")) { AT_GET_Data_2Param(buff,(uint8_t*)get_buff,"+CESQ: ",","); log=atoi(get_buff); //me3616.State.rssi=log; me3616.flug.dBm=1; /*装载成功标志*/ log=atoi(get_buff); log+=-110;/*转化成dBm*/ me3616.State.dBm=log; ME3616_INFO("signal intensity:%ddBm"); return log+1; } { ME3616_ERROR("%s",buff); return 0; } } ME3616_INFO("Response timeout"); return 0; } /** * @brief ME3616读取SIM卡的CCID * @param rssi:用来装载的参数,会装载信号强度原文 * @param ber:用来装载的参数, 会装载错码率原文 * */ uint8_t ME3616_READ_CCID() { char buff[MODULE_RDA_MAXlen]={0}; char get_buff[32]={'\0'}; ME3616_INFO("Start to query SIM card iccid"); module_printf("AT*MICCID\r\n"); if(Module_Blocking_Read(buff,1000)) { if(strstr(buff,"*MICCID:")) { if(AT_GET_Data_2Param(buff,(uint8_t*)get_buff,"*MICCID: ","\n\r"))//0d0a { #if(IMEI_ME3616_INFOrmation) strcpy(me3616.State.iccid,get_buff); me3616.flug.iccid=1; /*装载成功标志*/ #endif debug_printf("\r\nICCID:"); debug_printf("%s\r\n", get_buff); } else { ME3616_ERROR("%s",buff); ME3616_INFO("%s",buff); return 0; } return 1; } else{ if(strstr(buff,"SIM not inserted")) { ME3616_INFO("SIM card not inserted,Please check the SIM card"); return 0; } else { ME3616_ERROR("%s",buff); return 0; } } } ME3616_INFO("Response timeout"); return 0; } /** * @brief ME3616查询pin状态 * @param return 1 为ready,0 其他 * */ uint8_t ME3616_READ_PIN() { char buff[256]={0}; #if(config_CHINESE_LOG) ME3616_INFO("开始查询PIN状态"); #else ME3616_INFO("Start to query pin status"); #endif module_printf("AT+CPIN?\r\n"); if(Module_Blocking_Read(buff,1000)) { if(strstr(buff,"+CPIN:")) { me3616.State.pin=1; me3616.flug.pin=1; /*装载成功标志*/ #if(config_CHINESE_LOG) if(strstr(buff,"READY")) {ME3616_INFO("PIN状态: READY,已准备好");return 1;} else if(strstr(buff,"SIM PIN")) {ME3616_INFO("PIN状态: 需要pin码");return 1;} else if(strstr(buff,"SIM PUK")) {ME3616_INFO("PIN状态: PIN 码解锁密码");return 1;} else if(strstr(buff,"PH-SIM PIN")) {ME3616_INFO("PIN状态: SIM 卡绑定密码");return 1;} else if(strstr(buff,"SIM PIN2")) {ME3616_INFO("PIN状态: PIN2 码密码");return 1;} else if(strstr(buff,"SIM PUK2")) {ME3616_INFO("PIN状态: PIN2 码解锁密码");return 1;} else if(strstr(buff,"PH-NET PIN")) {ME3616_INFO("PIN状态: 网络密码");return 1;} #else if(strstr(buff,"READY")) {ME3616_INFO("Pin status: READY");return 1;} else if(strstr(buff,"SIM PIN")) {ME3616_INFO("Pin status: need pin");return 1;} else if(strstr(buff,"SIM PUK")) {ME3616_INFO("Pin status: Pin code unlock password");return 1;} else if(strstr(buff,"PH-SIM PIN")) {ME3616_INFO("Pin status: SIM card binding password");return 1;} else if(strstr(buff,"SIM PIN2")) {ME3616_INFO("Pin status: Pin2 code");return 1;} else if(strstr(buff,"SIM PUK2")) {ME3616_INFO("Pin status: Pin2 code unlock password");return 1;} else if(strstr(buff,"PH-NET PIN")) {ME3616_INFO("Pin status: Network password");return 1;} #endif } else{ ME3616_ERROR("%s",buff); return 0; } } ME3616_INFO("Response timeout"); return 0; } /** * @brief ME3616查询CIMI状态 * */ uint8_t ME3616_READ_CIMI() { char buff[MODULE_RDA_MAXlen]={0}; #if(config_CHINESE_LOG) ME3616_INFO("开始查询PIN状态"); #else ME3616_INFO("Start to query pin status"); #endif module_printf("AT+CPIN?\r\n"); if(Module_Blocking_Read(buff,1000)) { if(strstr(buff,"+CPIN:")) { #if(config_CHINESE_LOG) if(strstr(buff,"READY")) {ME3616_INFO("PIN状态: READY,已准备好");return 1;} else if(strstr(buff,"SIM PIN")) {ME3616_INFO("PIN状态: 需要pin码");return 1;} else if(strstr(buff,"SIM PUK")) {ME3616_INFO("PIN状态: PIN 码解锁密码");return 1;} else if(strstr(buff,"PH-SIM PIN")) {ME3616_INFO("PIN状态: SIM 卡绑定密码");return 1;} else if(strstr(buff,"SIM PIN2")) {ME3616_INFO("PIN状态: PIN2 码密码");return 1;} else if(strstr(buff,"SIM PUK2")) {ME3616_INFO("PIN状态: PIN2 码解锁密码");return 1;} else if(strstr(buff,"PH-NET PIN")) {ME3616_INFO("PIN状态: 网络密码");return 1;} #else if(strstr(buff,"READY")) {ME3616_INFO("Pin status: READY");return 1;} else if(strstr(buff,"SIM PIN")) {ME3616_INFO("Pin status: need pin");return 1;} else if(strstr(buff,"SIM PUK")) {ME3616_INFO("Pin status: Pin code unlock password");return 1;} else if(strstr(buff,"PH-SIM PIN")) {ME3616_INFO("Pin status: SIM card binding password");return 1;} else if(strstr(buff,"SIM PIN2")) {ME3616_INFO("Pin status: Pin2 code");return 1;} else if(strstr(buff,"SIM PUK2")) {ME3616_INFO("Pin status: Pin2 code unlock password");return 1;} else if(strstr(buff,"PH-NET PIN")) {ME3616_INFO("Pin status: Network password");return 1;} #endif } else{ ME3616_ERROR("%s",buff); return 0; } } ME3616_INFO("Response timeout"); return 0; } #if(IMEI_ME3616_INFOrmation) /** * @brief ME3616查询IMEI并装载至寄存器 * @param * */ uint8_t ME3616_READ_IMEI() { rxbuff(buff); clear(buff); ME3616_INFO("Start query IMEI"); module_printf("ATI\r\n"); if(Module_Blocking_Read(buff,6000)) { if(strstr(buff,"IMEI")) { #if 0 char temp[32]={0}; memset(temp, 0 , sizeof(temp)); AT_GET_Data_2Param(buff,(uint8_t*)temp,"IMEI: ","OK"); /*头尾提取方法*/ AT_Extract_numbers(temp); /*提纯数字*/ strcat(me3616.State.imei,temp); ME3616_INFO("IMEI:%s\r\n",temp); #else AT_GET_Data_2Param(buff,me3616.State.imei,"IMEI: ","OK"); /*头尾提取方法*/ #endif me3616.flug.imei=1; ME3616_INFO("IMEI:%s\r\n",me3616.State.imei); return 1; } else{ ME3616_ERROR("%s",buff); return 0; } } ME3616_INFO("Response timeout"); return 0; } #endif #if(Hvertion_data) /** * @brief ME3616查询IMEI并装载至寄存器 * @param * */ uint8_t ME3616_READ_Revision() { char buff[MODULE_RDA_MAXlen]={0}; debug_printf("\r\n开始查询软硬件环境\r\n"); module_printf("ATI\r\n"); if(Module_Blocking_Read(buff,2000)) { if(strstr(buff,"SwRevision: ")) { char temp[256]={0}; AT_GET_Data_2Param(buff,(uint8_t*)temp,"SwRevision: ","HwR"); /*头尾提取方法*/ AT_Extract_numbers_letters(temp); /*提纯数字*/ strcat(me3616.State.Svertion,temp); me3616.flug.Svertion=1; AT_GET_Data_2Param(buff,(uint8_t*)temp,"HwRevision: ","SVN"); /*头尾提取方法*/ AT_Extract_numbers_letters(temp); /*提纯数字*/ strcat(me3616.State.Hvertion,temp); me3616.flug.Hvertion=1; debug_printf("\r\nSvertion:%s",me3616.State.Svertion); debug_printf("Hvertion:%s\r\n",me3616.State.Hvertion); return 1; } else{ debug_printf("原文:"); debug_printf(buff); return 0; } } ME3616_INFO("Response timeout"); return 0; } #endif void ME3616_IMEI_ICCID_INFO_GET(char *imei, char *iccid) { memcpy(imei, me3616.State.imei, strlen(me3616.State.imei)); memcpy(iccid, me3616.State.iccid, strlen(me3616.State.iccid)); } #if(config_TCP_Enable) /** * @brief ME3616关闭一个套接字 * @param socket:套接字的句柄编号 * */ uint8_t ME3616_Close_Socket(uint8_t socket) { char buff[MODULE_RDA_MAXlen]={0}; module_printf("AT+ESOCL=%d\r\n",socket);//printf的重映射有问题,正在修改 if(Module_Blocking_Read(buff,1000)) { if(strstr(buff,"OK")) { ME3616_INFO("socket:%d Close OK!",socket); return 1; } else if(strstr(buff,"ERROR")){ //debug_printf("\r\n关闭失败\r\n"); return 0; }else { // debug_printf("\r\nunknow\r\n"); } }else { ME3616_INFO("Response timeout"); } return 99; } /** * @brief ME3616关闭一个套接字[内部调用] * */ uint8_t Close_TCP_Socket() { char buff[MODULE_RDA_MAXlen]={0}; module_printf("AT+ESOCL=%d\r\n",me3616.State.TCP_Socket);//printf的重映射有问题,正在修改 if(Module_Blocking_Read(buff,1000)) { if(strstr(buff,"OK")) { ME3616_INFO("socket:%d Close OK!",me3616.State.TCP_Socket); return 1; } else if(strstr(buff,"ERROR")){ ME3616_INFO("Closing failed"); return 0; }else { ME3616_ERROR("%s",buff); } } else { ME3616_INFO("Response timeout"); } return 0; } /** * @brief ME3616创建一个Socket * @param IPvX : 1 - IPv4 ,2 - IPv6 * @param TCP_UDP : 1 - TCP ,2 - UDP ,3 - RAW * @param protocol: 1 - IP ,2 - ICMP * 【创建失败返回99,创建成功返回socket的句柄编号,范围0-4】 */ uint8_t ME3616_Create_Socket(int IPvX,int TCP_UDP,int protocol) { char buff[MODULE_RDA_MAXlen]={'\0'}; char get_buff[100]={'\0'}; uint8_t socket=99; module_printf("AT+ESOC=%d,%d,%d\r\n",IPvX,TCP_UDP,protocol); if(Module_Blocking_Read(buff,1000)) { if(strstr(buff,"ERROR")) { if(strstr(buff,"too much socket instance")) { ME3616_INFO("There is no socket channel left. Please close the socket channel"); return 88; } else { ME3616_ERROR("%s",buff); } } else if(strstr(buff,"+ESOC=")) { char *p; // ME3616_ERROR("\r\n原文:"); // ME3616_ERROR((char*)buff); if(strlen(buff)>15) p=buff+13; else p=buff; if(AT_GET_Data_2Param(p,(uint8_t*)get_buff,"OC=","OK")) { socket=atoi(get_buff); me3616.State.TCP_Socket=socket; ME3616_INFO("Socket created successfully, No.:%d",socket); return socket; } else { ME3616_INFO("Socket creation failed :%d",socket); ME3616_ERROR("%s",buff); return 99; } } else{ ME3616_ERROR("%s",buff); return 99; } }else { ME3616_INFO("Response timeout"); return 99; } return 99; } /** * @brief ME3616连接到一个Socket * @param socket : socket创建好的socket通道句柄编号 * @param port : 端口 * @param ip : ip地址,或者域名支持域名解析 * 【创建失败返回99,创建成功返回socket的句柄编号,范围0-5】 */ int ME3616_Connect_Socket(uint8_t socket,char *port,char *ip) { char buff[MODULE_RDA_MAXlen]={0}; char get_buff[100]={'\0'}; char send_data[256]={0}; char data_crc[256]={0}; /*导入句柄编号*/ sprintf(send_data,"AT+ESOCON=%d,",socket); /*导入端口号*/ strcat(send_data,port); strcat(send_data,",\""); /*导入ip地址或域名*/ strcat(send_data,ip); strcpy(data_crc,send_data); strcat(data_crc,"\""); strcat(send_data,"\"\r\n"); //debug_printf("\r\nSEND TO ME3616\r\n"); //debug_printf(send_data); //debug_printf("\r\nCRC FIFO\r\n"); //debug_printf(data_crc); /*发送指令*/ module_printf(send_data); if(Module_Blocking_Read(buff,8000)) { if(strstr(buff,"ERROR")) { ME3616_INFO("Socket connection error"); return 0; } else if(strstr(buff,"OK")) { ME3616_INFO("Socket connection successful"); return 1; } else if(strstr(buff,data_crc)) { memset(buff,0,MODULE_RDA_MAXlen); if(Module_Blocking_Read(buff,10000)) { /*注册成功*/ if(strstr(buff,"OK")) { ME3616_INFO("Socket connection successful"); return 1; } else if(strstr(buff,"ERROR")) { ME3616_INFO("Socket connection error"); //ME3616_ERROR("%s",buff); return 0; } } else { ME3616_INFO("Response timeout"); } } else if(strstr(buff,"+ESOERR")) { int code=0; /*套接字错误指示器*/ if(AT_GET_Data_2Param(buff,(uint8_t*)get_buff,",","\n\r")) { code=atoi(get_buff); ESOERR_PRINT(code); return code+10; } } else { ME3616_ERROR("%s",buff); } } else { ME3616_INFO("Response timeout"); return 99; } return 0; } /** * @brief ME3616创建一个TCP连接 * @param port : 端口 * @param ip : ip地址,或者域名支持域名解析 * 【创建失败返回99,创建成功返回socket的句柄编号,范围0-5】 */ uint8_t ME3616_Connect_TCP(char *port,char *ip) { OS_ERR err; ME3616_Close_Socket(0); ME3616_Close_Socket(1); ME3616_Close_Socket(2); ME3616_Close_Socket(3); ME3616_Close_Socket(4); /*静态的Socket句柄*/ static int TCP_Socket; uint8_t Try_count=0; create: Try_count++;/*尝试次数*/ /*创建一个套接字,并返回一个句柄*/ TCP_Socket=ME3616_Create_Socket(1,1,1); if(TCP_Socket>=0&&TCP_Socket<=4) {/*创套接字编号满足要求则继续*/ ME3616_INFO("Start Connection TCP"); //me3616.State.TCP_Socket=TCP_Socket; } else if(TCP_Socket==88) { /*88是套接字通道用尽标志*/ ME3616_INFO("Socket Channel has no more left,Start clear"); ME3616_Close_Socket(0); ME3616_Close_Socket(1); ME3616_Close_Socket(2); ME3616_Close_Socket(3); ME3616_Close_Socket(4); if(Try_count<3) goto create; else return 0; } else if(TCP_Socket==99) { /*99是其他error,暂未处理*/ ME3616_INFO("Socket creation failed"); ME3616_INFO("Try again"); ME3616_Close_Socket(0); ME3616_Close_Socket(1); ME3616_Close_Socket(2); ME3616_Close_Socket(3); ME3616_Close_Socket(4); if(Try_count<3) goto create; else return 0; } OSTimeDlyHMSM(0, 0, 500, 0, OS_OPT_TIME_DLY, &err); //HAL_Delay(500); /*创建一个TCP通道*/ int code=ME3616_Connect_Socket(TCP_Socket,port,ip); if(code!=1) { ME3616_INFO("TCP creation failed:%d",code); ME3616_INFO("Try again"); ME3616_Close_Socket(0); ME3616_Close_Socket(1); ME3616_Close_Socket(2); ME3616_Close_Socket(3); ME3616_Close_Socket(4); if(Try_count<3) goto create; if(code==99) { return 0; } else if(code>=9&&code<=11) { /*带错误码返回的套接字错误*/ return 0; } else return 0; }else if(code==1) { /*装载参数*/ me3616.State.TCP_State=1; #if defined (config_TCP_Enable_Disconnection_reconnection) me3616.flug.tcp_recon=1; #endif ME3616_INFO("TCP connection successful (*^▽^*) "); ME3616_INFO("IP Address:%s\r\n>> Port:%s\r\n>> Socket:%d ",ip,port,TCP_Socket); return 1; } /*code==1是唯一正确的返回*/ else { ME3616_INFO("TCP creation failed "); return 0; } } uint8_t ME3616_TCP_SEND_String(char *str) { if(me3616.State.TCP_State==1) { uint16_t len=strlen(str); if(len>0&&len<512) { char str_arry[strlen(str)+1]; memset(str_arry,0,strlen(str)+1); AsciiStr_2_HexStr(str,str_arry); module_printf("AT+ESOSEND=%d,%d,%s\r\n",me3616.State.TCP_Socket,strlen(str),str_arry); //ME3616_INFO("\r\nAT+ESOSEND=%d,%d,%s\r\n",me3616.State.TCP_Socket,strlen(str),str_arry); char rxbuf[MODULE_RDA_MAXlen]={0}; if(Module_Blocking_Read(rxbuf,5000)) { //debug_printf(rxbuf); if(strstr(rxbuf,"+ESONMI")||strstr(rxbuf,"OK")) { ME3616_INFO("Send:%s",str); ME3616_INFO("Sent successfully"); } else if(strstr(rxbuf,"ERROR")) { ME3616_ERROR("%s",rxbuf); } }else { ME3616_INFO("Response timeout"); return 99; } } else { ME3616_INFO("Data length violation"); return 0; } } else{ ME3616_INFO("Send failed, TCP channel not open"); return 0; } return 0; } uint8_t ME3616_TCP_SEND_Hex(char *str) { if(me3616.State.TCP_State==1) { uint16_t len=strlen(str); if(len%2!=0) { ME3616_INFO("hex data不符合规范"); return 0; } if(len>0&&len<512) { module_printf("AT+ESOSEND=%d,%d,%s\r\n",me3616.State.TCP_Socket,len/2,str); //debug_printf("AT+ESOSEND=%d,%d,%s\r\n",me3616.State.TCP_Socket,len/2,str); char rxbuf[MODULE_RDA_MAXlen]; if(Module_Blocking_Read(rxbuf,3000)) { //debug_printf(rxbuf); if(strstr(rxbuf,"+ESONMI")||strstr(rxbuf,"OK")) { ME3616_INFO("发送成功"); } else if(strstr(rxbuf,"ERROR")) { ME3616_INFO("发送失败"); } }else { ME3616_INFO("响应超时"); return 99; } } else { ME3616_INFO("数据长度违规"); return 0; } } else{ ME3616_INFO("\r\nTCP通道未打开\r\n"); return 0; } return 0; } uint8_t ME3616_TCP_DATA_purification(uint8_t data[]) { /**/ if(me3616.State.TCP_State) { char temp[15]={0}; sprintf(temp,"+ESONMI=%d",me3616.State.TCP_Socket); if(strstr((char*)data,temp))/*校验数据是否来自指定的socket*/ { /*读取数据长度*/ char temp[10]={0}; AT_GET_Data((char*)data,(uint8_t*)temp,",",1); int i=atoi(temp); //debug_printf("\r\nlen:%d\r\n",i); int loc=0; for(int n=0;loc<50;loc++) { if(*(data+loc)==',') n++; if(n==2) break; } Shift_left((char*)data,loc+1); //Str.convert.R_CUT((char*)data,i*2+2);/*因为数据还包括odoa,所以额外+2*/ return 1; } else return 0; } return 0; } #endif /** * @brief ME3616打印套接字错误码 */ void ESOERR_PRINT(int code) { switch(code) { case -1:debug_printf("\r\n错误:通用错误\r\n"); break; case 1:debug_printf("\r\n错误:没有找到路由信息,一般是掉网的情况下会出现\r\n"); break; case 2:debug_printf("\r\n错误:TCP 链接被动断开,一般掉网的情况下会出现\r\n"); break; case 3:debug_printf("\r\n错误:TCP 链接被 server 断连,一般是 device 收到 server 的 reset 数据包\r\n"); break; case 4:debug_printf("\r\n错误:TCP 连接错误\r\n"); break; case 5:debug_printf("\r\n错误:非法值\r\n"); break; case 6:debug_printf("\r\n错误:socket 阻塞\r\n"); break; case 7:debug_printf("\r\n错误:地址已经被使用\r\n"); break; case 8:debug_printf("\r\n错误:正在连接中\r\n"); break; case 9:debug_printf("\r\n错误:已经建立连接\r\n"); break; case 10:debug_printf("\r\n错误:网络接口错误\r\n"); break; default: debug_printf("\r\n错误:通用错误\r\n"); break; } } /*--------------------------------MQTT------------------------------------------------------*/ #if(config_MQTT_Enable) uint8_t MQTT_Set_Net(char *ip,char *port) { if(strcpy(me3616.State.mqtt_ip,ip)) if(strcpy(me3616.State.mqtt_port,port)) { me3616.flug.mqtt_ip=1; me3616.flug.mqtt_port=1; ME3616_INFO("Net Set OK!"); return 1; } return 0; } uint8_t MQTT_Connet(char *_productID,char *_deviceID,char *_secret) { int mqttid; /*申请一个接收缓存*/ rxbuff(buff); if(!(me3616.flug.mqtt_ip&&me3616.flug.mqtt_port)) { ME3616_INFO("The network port has not been configured"); return 0; } module_printf("AT+EMQNEW=\"%s\",\"%s\",12000,512\r\n",me3616.State.mqtt_ip,me3616.State.mqtt_port); /*conenet的地址*/ //module_printf("AT+EMQNEW=\"183.230.40.39\",\"6002\",12000,100\r\n"); clear(buff); if(Module_Blocking_Read(buff,5000)) { if(strstr(buff,"+EMQNEW:")&&strstr(buff,"OK")) { uint8_t getid[5]={0}; AT_GET_Data_2Param(buff,getid,":","OK"); AT_Remove_spaces((char*)getid); mqttid=atoi((char*)getid); ME3616_INFO("NEW mqtt server ok! Start Connect..."); module_printf("AT+EMQCON=%d,4,\"%s\",1000,1,0\r\n",mqttid,_deviceID); clear(buff); if(Module_Blocking_Read(buff,5000)) { if(strstr(buff,"OK")) { me3616.State.mqtt_id=mqttid; me3616.State.MQTT_State=1; ME3616_INFO("Connect MQTT Successful,MQTT id:%d",mqttid); return 1; } } }else { ME3616_ERROR("%s",buff); } } else { ME3616_INFO("Response timeout"); } return 0; } uint8_t MQTT_SUB(char * topic) { if(!me3616.State.MQTT_State) { ME3616_INFO("Cannot Connect MQTT"); return 0; } /*往模组打印*/ module_printf("AT+EMQSUB=%d,\"%s\",1\r\n",me3616.State.mqtt_id,topic); Module_Read_A_CRC("AT+EMQSUB=",5000); if(Module_Read_A_CRC("OK",15000)) { ME3616_INFO("Sub \"%s\" Successful",topic); return 1; }else { ME3616_INFO("Sub ERROR"); return 0; } } uint8_t MQTT_PUB(char * topic,char *data, uint32_t len) { if(!me3616.State.MQTT_State) { ME3616_INFO("Cannot Connect MQTT"); return 0; } /*往模组打印*/ module_printf("AT+EMQPUB=%d,\"%s\",1,0,0,%d,\"%s\"\r\n",me3616.State.mqtt_id,topic,strlen(data)/2,data); //Module_Read_A_CRC("AT+EMQPUB=",5000); if(Module_Read_A_CRC("OK",3000)) { /* if(Module_Read_A_CRC("+EMQPUB:",15000)) { ME3616_INFO("Pub Successful \r\n[%s]<-[%s]",topic,data); return 1; } */ ME3616_INFO("Pub Successful \r\n[%s]<-[%s]",topic,data); return 1; }else { ME3616_INFO("Pub ERROR"); return 0; } } #endif