(简单版)FreeRTOS 阿里云MQTT 上报温湿度 下行命令控制led三色灯
注意:反复检查+测试之后,程序还是跑不起来的话,一定是栈的问题
软件定时器的栈也要设大点,否则跑不起来
设置了三个任务,一个软件定时器(周期为20s)
入口函数 | 优先级 | ||
任务1 | mqttTask06 | 5 | 挂起态 |
任务2 | ReceiveTask5 | 4 | 信号量、发送队列xStreamBufferReceive() |
任务3 | buffer_task03 | 3 | 信号量、接收队列xStreamBufferSend() |
任务1
void mqttTask06(void const * argument)
{
/* USER CODE BEGIN mqttTask06 */
/* Infinite loop */
for(;;)
{
int rv;
char ipaddr[16];
char gateway[16];
unsigned char wifi_flag=0;
//连接WiFi
if(!(wifi_flag&FLAG_WIFI_CONNECTED))
{
if( esp8266_join_network(DEF_ROUTER_SSID,DEF_ROUTER_PWD))
{//0 is connect success
esp8266_module_init();
osDelay(2000);
continue;
}
if(esp8266_get_ipaddr(ipaddr,gateway,sizeof(ipaddr)))
{
osDelay(1000);
continue;
}
if(esp8266_ping_test(gateway))
{
osDelay(1000);
continue;
}
wifi_flag |= FLAG_WIFI_CONNECTED;
}
//连接MQTT
if(!(wifi_flag&FLAG_SOCK_CONNECTED))
{
rv=mqtt_connect(MQTT_BROKER_HOSTNAME,MQTT_BROKER_PORT,MQTT_CLIENT_ID,MQTT_BROKER_USERNAME,MQTT_BROKER_PASSWORD);
if( rv )
{//0 is connect success
osDelay(2000);
continue;
}
mqtt_subscribe_topic(MQTT_SUB_TOPIC,Qos0,1);
wifi_flag |= FLAG_SOCK_CONNECTED;
xTimerChangePeriod(myTimer01Handle,20000,0);//定时器周期改为20s
xTimerStart(myTimer01Handle,0);//启动定时器
vTaskSuspend(NULL);//挂起(挂起自己)
}
}
/* USER CODE END mqttTask06 */
}
任务2
void ReceiveTask5(void const * argument)
{
/* USER CODE BEGIN buffer_task03 */
/* Infinite loop */
for(;;)
{
unsigned char buf[256];
MQTTString topicName;
unsigned char dup;
int qos;
unsigned char retained;
unsigned short msgid;
unsigned char *payload = NULL;
int payloadlen = 0;
int rv;
char correct_json[256]={0};
BaseType_t xReturn=pdFALSE;
xReturn=xSemaphoreTake(myBinarySem01Handle,portMAX_DELAY);//获取信号量成功时,返回值为pdTRUE。否则进入阻塞状态
if( pdTRUE == xReturn )
{
memset(buf,0,sizeof(buf));
xStreamBufferReceive(xStreamBuffer,buf, sizeof(buf), portMAX_DELAY);
}
//报文解析
rv=MQTTDeserialize_publish(&dup,&qos,&retained,&msgid,&topicName,&payload,&payloadlen,buf,sizeof(buf));
if( rv == 1)
{
printf("MQTT payload:%s\n",payload);
aliyun_json((char *)payload,payloadlen,correct_json);//截取出标准的有效的JSON格式(代码下面有展示)
parser_led_json(correct_json,strlen(correct_json));//JSON解析(代码下面有展示)
}
else
{
printf("ERROR:MQTTDeserialize_publish failure,rv=%d\n",rv);
}
/* USER CODE END buffer_task03 */
}
任务三
void buffer_task03(void const * argument)
{
/* USER CODE BEGIN buffer_task03 */
/* Infinite loop */
for(;;)
{
unsigned char buf[256];
int packet_type;
int rv;
memset(buf,0,sizeof(buf));
if( (packet_type=MQTTPacket_read(buf,sizeof(buf),transport_getdata)) <0 )
{
printf("Wait aliyun command\n");
osDelay(2000);
continue;
}
if( PUBLISH == packet_type )
{
rv=xStreamBufferSend(xStreamBuffer,buf,sizeof(buf),portMAX_DELAY);
if( !(rv>0) )
{
printf("ERROR:xStreamBufferSend\n");
}
}
xSemaphoreGive( myBinarySem01Handle );
}
/* USER CODE END buffer_task03 */
}
软件定时器 回调函数
//软件定时器的回调函数,定时 上报温湿度
void Callback01(void const * argument)
{
/* USER CODE BEGIN Callback01 */
int rv;
rv=report_tempRH2_json();//sht20温湿度上报的函数(代码下面有展示)
if( 0 == rv )
{
printf("ESP8266 MQTT publish message ok\n");
clear_atcmd_buf();//清空串口接收的buffer
//因为每次上报成功后,阿里云会反馈一段数据回来,若此时收到阿里云下发控制led灯的命令也存在buffer中,会导致buffer溢出
}
/* USER CODE END Callback01 */
}
温湿度上报函数(传感器是sht20)
/*sht20*/
int report_tempRH2_json(void)
{
char buf[128];
float temperature,humidity;
int rv;
if( (sht20_sample_temp_or_hum(0xF3,&temperature) <0 ) || (sht20_sample_temp_or_hum(0xF5,&humidity) <0 ))
{
printf("ERROR:sht20 sample data failure\n");
return -1;
}
memset(buf,0,sizeof(buf));
snprintf(buf,sizeof(buf),"{\"params\":{\"CurrentTemperature\":%.2f,\"CurrentHumidity\":%.2f}}",temperature,humidity);
rv=mqtt_publish(MQTT_PUB_TOPIC,Qos0,buf);
printf("MQTT publish topic [%s] with msg '%s'%s,rv=%d\n",MQTT_PUB_TOPIC,buf,rv? "failure":"ok",rv);
return rv;
}
sht20.c
/*
* sht20.c
*/
#include "sht20.h"
#include <stdio.h>
#include "stm32l4xx_hal.h"
#include "tim.h"
#define CONFIG_GPIO_I2C
#ifdef CONFIG_GPIO_I2C
#include "gpio_i2c.h" /*GPIO模拟I2C*/
#else
#include "i2c.h" /* I2C */
#endif
int sht20_sample_temp_or_hum(int cmd, float *data)
{
uint8_t buf[2];
unsigned short sht20_data=0;
int rv;
#ifdef CONFIG_GPIO_I2C
/*主设备向发送从设备地址信号,这里sht20的写地址是0x80,成功则返回1个字节*/
rv=I2C_Master_Transmit(0x80,&cmd,1);
#else
rv=HAL_I2C_Master_Transmit(&hi2c1,0x80,&cmd,1,0xFF);
#endif
if(0!=rv)
return -1;
if(cmd==0xF3)/*SHT20_NO_MEASURE_TEMP_CMD=0xF3 触发温度测量,非主机模式*/
HAL_Delay(85);
else if(cmd==0xF5)/*SHT20_NO_MEASURE_RH_CMD=0xF5 触发湿度测量,非主机模式*/
HAL_Delay(29);
#ifdef CONFIG_GPIO_I2C
/*主设备向发送从设备地址信号,这里sht20的读地址是0x81,成功则返回2个字节,分别是温湿度的整数和小数,并且数据放在buf中*/
rv=I2C_Master_Receive(0x81,buf,2);
#else
rv=HAL_I2C_Master_Receive(&hi2c1,0x81,buf,2,0xFF);
#endif
if(0!=rv)
return -1;
sht20_data=buf[0];
sht20_data=(sht20_data<<8);
sht20_data+=buf[1]&0xFC;
if(cmd==0xF3)
{
*data= -46.85+175.72*((float)sht20_data/65536);//计算
//printf("Temperature=%d\n",sht20_data);
}
else if(cmd==0xF5)
{
*data= -6.0+125.0*((float)sht20_data/65536);//计算
//printf("Humidity=%d\n",sht20_data);
}
return *data;
}
截取出标准的有效的JSON格式
int aliyun_json(char *payload,int payloadlen,char *correct_json)
{
char *ptr=NULL, *start=NULL, *end=NULL;
ptr=strstr(payload,"LEDRGB");
start=strchr(ptr,'{');
end=strchr(ptr,'}');
end++;
if( start==NULL || end==NULL || start>end )
{
printf("ERROR:str not find\n");
HAL_Delay(2000);
return 0;
}
else
{
memcpy(correct_json,start,end-start);
}
return 0;
}
JSON解析
int parser_led_json(char *json_string,int bytes)
{
JSONStatus_t result;
char save;
char *value;
size_t valen;
int i;
printf("DBUG:Start parsar JSON string:%s\r\n",json_string);
result=JSON_Validate(json_string,bytes);
if(JSONPartial==result)
{
printf("WARN:JSON document is valid so far but incomplete!\r\n");
return 0;
}
if(JSONSuccess!=result)
{
printf("ERROR:JSON document is valid JSON!\r\n");
return -1;
}
for(i=0;i<LedMax;i++)
{
result=JSON_Search(json_string,bytes, leds[i].name,strlen(leds[i].name),&value,&valen);
if(JSONSuccess==result)
{
save = value[valen];
value[valen]='\0';
if(!strncasecmp(value,"on",2))
{
printf("DBUG:turn %s ON \r\n",leds[i].name);
turn_led(i,ON);
}
else if(!strncasecmp(value,"off",3))
{
printf("DBUG:turn %s OFF \r\n",leds[i].name);
turn_led(i,OFF);
}
value[valen]=save;
}
}
return 1;
}
上层的MQTT订阅和发送功能代码 core_mqtt.c
/*+---------------+
*| MQTT |
+---------------*/
#include "core_mqtt.h"
#include "stm32l4xx_hal.h"
#include <stdio.h>
#include <string.h>
int mqtt_connect(char *host,int port,char *clientid,char *username,char *passwd)
{
MQTTPacket_connectData data=MQTTPacket_connectData_initializer;
int rv;
unsigned char buf[256];
unsigned char sessionPresent;
unsigned char connack_rc;
if(!host || port<=0 || !clientid )
{
printf("ERROR:Invalid input arguments\n");
}
if((rv=transport_open(host,port))<0)
{
printf("socket connect [%s:%d] failure,rv=%d\n",host,port,rv);
return rv;
}
data.clientID.cstring=clientid;
data.keepAliveInterval=MQTT_KEEP_ALIVE_TIMEOUT_SECONDS;
data.cleansession=1;
if( username && passwd)
{
data.username.cstring=username;
data.password.cstring=passwd;
}
rv=MQTTSerialize_connect(buf,sizeof(buf),&data);
if( rv<0 )
{
printf("MQTTSerialize_connect failure,rv=%d\n",rv);
return -1;
}
if ( rv != transport_sendPacketBuffer(buf,rv) )
{
printf("transport_sendPackBuffer for mqtt_connect failure,rv=%d\n",rv);
return -2;
}
HAL_Delay(800);
memset(buf,0,sizeof(buf));
rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
if(CONNACK != rv)
{
printf("MQTTPacket_read for MQTT CONNACK failure,rv=%d\n",rv);
return -3;
}
if((rv=MQTTDeserialize_connack(&sessionPresent,&connack_rc,buf,sizeof(buf))) !=1 || connack_rc!=0)
{
printf("MQTTDeserialize_connack failire,rv=%d\n",rv);
return -4;
}
return 0;
}
int mqtt_disconnect(void)
{
int rv;
unsigned buf[256];
rv=MQTTSerialize_disconnect(buf,sizeof(buf));
if(rv < 0 )
{
printf("MQTT_Serialize_disconnect failure,rv=%d\n",rv);
return -1;
}
if( rv != transport_sendPacketBuffer(buf,rv) )
{
printf("transport_sendPacketBuffer for mqtt_disconnect failure,rv=%d\n",rv);
return -2;
}
return 0;
}
int mqtt_subscribe_topic(char *topic,int qos,int msgid)
{
MQTTString topicString = MQTTString_initializer;
unsigned short submsgid;
int subcount,granted_qos;
int rv;
unsigned char buf[256];
topicString.cstring = topic;
rv=MQTTSerialize_subscribe(buf,sizeof(buf),0,msgid,1,&topicString,&qos);
if( rv<0 )
{
printf("MQTTSerialize_subscribe failure,rv=%d\n",rv);
return -1;
}
if( rv != transport_sendPacketBuffer(buf,rv) )
{
printf("transport_sendPacketBuffer for mqtt_subscribe_topic failure,rv=%d\n",rv);
return -2;
}
HAL_Delay(800);
memset(buf,0,sizeof(buf));
rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
if(SUBACK != rv)
{
printf("MQTTPacket_read for MQTT SUBACK failure,rv=%d\n",rv);
return -3;
}
rv=MQTTDeserialize_suback(&submsgid,1,&subcount,&granted_qos,buf,sizeof(buf));
if( !rv || submsgid!=msgid || granted_qos == 0x80)
{
printf("MQTTDeserialize_suback failure,rv=%d\n",rv);
return -4;
}
printf("mqtt_subscribe_topic ok\n");
return 0;
}
int mqtt_unsubscribe_topic(char *topic,int msgid)
{
MQTTString topicString = MQTTString_initializer;
unsigned short submsgid;
int rv;
unsigned char buf[256];
rv=MQTTSerialize_unsubscribe(buf,sizeof(buf),0,msgid,1,&topicString);
if( rv<0 )
{
printf("MQTTSerialize_unsubscribe failure,rv=%d\n",rv);
return -1;
}
if( rv != transport_sendPacketBuffer(buf,rv) )
{
printf("transport_sendPacketBuffer for mqtt_unsubscribe_topic failure,rv=%d\n",rv);
return -2;
}
HAL_Delay(800);
memset(buf,0,sizeof(buf));
rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
if( UNSUBACK != rv )
{
printf("MQTTPacket_read for MQTT UNSUBACK failure,rv=%d\n",rv);
return -3;
}
rv=MQTTDeserialize_unsuback(&submsgid,buf,sizeof(buf));
if( !rv || submsgid!=msgid )
{
printf("MQTTDeserialize_unsuback failure,rv=%d\n",rv);
return -4;
}
return 0;
}
int mqtt_publish(char *topic,int qos,char *payload)
{
MQTTString topicString = MQTTString_initializer;
int rv;
unsigned char buf[256];
unsigned char dup=0;
unsigned char retained=0;
unsigned short packetid=0;
topicString.cstring = topic;
rv=MQTTSerialize_publish(buf,sizeof(buf),dup,qos,retained,packetid,topicString,(unsigned char*)payload,strlen(payload));
if( rv<0 )
{
printf("MQTTSerialize_publish failure,rv=%d\n",rv);
return -1;
}
if( rv != transport_sendPacketBuffer(buf,rv) )
{
printf("transport_sendPacketBuffer for MQTTSerialize_publish failure,rv=%d\n",rv);
return -2;
}
HAL_Delay(800);
memset(buf,0,sizeof(buf));
rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
if( PUBLISH!=rv && -1!=rv )
{
printf("MQTTPacket_read for MQTT PUBLISH failure,rv=%d\n",rv);
return -3;
}
return 0;
}
int mqtt_pingreq(void)
{
int rv;
unsigned char buf[256];
rv=MQTTSerialize_pingreq(buf,sizeof(buf));
if( rv<0 )
{
printf("MQTTSerialize_pingreq failure,rv=%d\n",rv);
return -1;
}
if( rv != transport_sendPacketBuffer(buf,rv) )
{
printf("transport_sendPacketBuffer for MQTTSerialize_pingreq failure,rv=%d\n",rv);
return -2;
}
HAL_Delay(800);
memset(buf,0,sizeof(buf));
rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
if( PINGRESP!=rv )
{
printf("MQTTPacket_read for MQTT PINGRESP failure,rv=%d\n",rv);
return -3;
}
return 0;
}
底层的MQTT消息发送代码 transport.c
#include "transport.h"
#include "esp8266.h"
#include <string.h>
static unsigned char s_sock_buf[256];
static int s_rx_bytes;
int transport_open(char* addr,int port)
{
return esp8266_sock_connect(addr,port)? -1 : 0 ;
}
int transport_close(void)
{
return esp8266_sock_disconnect();
}
int transport_sendPacketBuffer(unsigned char* buf,int buflen)
{
return esp8266_sock_send(buf,buflen);
}
int transport_getdata(unsigned char* buf,int count)
{
int rv=0;
if( !s_rx_bytes )
{
rv=esp8266_sock_recv(s_sock_buf,sizeof(s_sock_buf));
if( !rv )
{
return 0;
}
s_rx_bytes =rv;
}
rv= count > s_rx_bytes ? s_rx_bytes : count;
memcpy(buf,s_sock_buf,rv);
s_rx_bytes -= rv;
if( s_rx_bytes > 0 )
{
memmove(s_sock_buf,&s_sock_buf[rv],s_rx_bytes);
}
return rv;
}
void transport_clearBuf(void)
{
memset(s_sock_buf,0,sizeof(s_sock_buf));
s_rx_bytes = 0;
}
底层的消息发送接收 esp8266.c
/*
* esp8266.c
*/
#include "esp8266.h"
//#define CONFIG_WIFI_DEBUG
#define CONFIG_WIFI_PRINT
#ifdef CONFIG_WIFI_DEBUG
#define wifi_dbg(format,args...) printf(format,##args)
#else
#define wifi_dbg(format,args...) do{} while(0)
#endif
#ifdef CONFIG_WIFI_PRINT
#define wifi_print(format,args...) printf(format,##args)
#else
#define wifi_print(format,args...) do{} while(0)
#endif
int send_atcmd(char *atcmd,char *expect_reply,unsigned int timeout)
{
int rv= 1;
unsigned int i;
char *expect;
if( !atcmd || strlen(atcmd)<=0 )
{
wifi_print("ERROR:Invalid input arguments\r\n");
}
wifi_dbg("\r\n Start send AT command:%s,atcmd");
clear_atcmd_buf();
HAL_UART_Transmit(wifi_huart,(uint8_t *)atcmd,strlen(atcmd),1000);
expect=expect_reply ? expect_reply : "OK\r\n";
for(i=0;i<timeout;i++)
{
if(strstr(g_wifi_rxbuf,expect))
{
wifi_dbg("AT command Got expect replay '%s'\r\n",expect);
rv = 0;
goto CleanUp;
}
if(strstr(g_wifi_rxbuf,"ERROR\r\n") || strstr(g_wifi_rxbuf,"FAIL\r\n"))
{
rv = 2;
goto CleanUp;
}
HAL_Delay(1);
}
CleanUp:
wifi_dbg("<<<< AT command replay:\r\n%s",g_wifi_rxbuf);
return rv;
}
int atcmd_send_data(unsigned char *data,int bytes,unsigned int timeout)
{
int rv= -1;
unsigned int i;
if( !data || bytes<=0 )
{
wifi_print("ERROR: Invalid input arguments\r\n");
return -1;
}
wifi_dbg("\r\n Start AT command send [%d] bytes data\n,bytes");
clear_atcmd_buf();
HAL_UART_Transmit(wifi_huart,(uint8_t *)data,bytes,1000);
for(i=0;i<timeout;i++)
{
if(strstr(g_wifi_rxbuf,"SEND OK\r\n"))
{
rv = 0;
goto CleanUp;
}
if(strstr(g_wifi_rxbuf,"ERROR\r\n"))
{
rv = 1;
goto CleanUp;
}
HAL_Delay(1);
}
CleanUp:
wifi_dbg("<<<< AT command replay:\r\n%s",g_wifi_rxbuf);
return rv;
}
int esp8266_module_init(void)
{
int i;
wifi_print("INFO:Reset ESP8266 module now...\r\n");
send_atcmd("AT+RST\r\n",EXPECT_OK,500);
for(i=0;i<6;i++)
{
if(!send_atcmd("AT\r\n",EXPECT_OK,500))//0 is success
{
wifi_print("INFO:Send AT to ESP8266 and Got replay ok\r\n");
break;
}
HAL_Delay(100);
}
if(i>=6)
{
wifi_print("ERROR:Can't receive AT replay after reset\r\n");
return -2;
}
if(send_atcmd("AT+CWMODE=1\r\n",EXPECT_OK,500))//0 is success
{
wifi_print("ERROR:Set ESP8266 work as Station mode failure\r\n");
return -3;
}
if(send_atcmd("AT+CWDHCP=1,1\r\n",EXPECT_OK,500))//0 is success
{
wifi_print("ERROR:Enable ESP8266 Station mode DHCP failure\r\n");
return -4;
}
#if 0
if(send_atcmd("AT+GMR\r\n",EXPECT_OK,500))//0 is success
{
wifi_print("ERROR:AT+GMR check ESP8266 reversion failure\r\n");
return -5;
}
#endif
HAL_Delay(500);
return 0;
}
int esp8266_join_network(char *ssid,char *pwd)
{
char atcmd[128]={0x00};
int i;
if( !ssid || !pwd)
{
wifi_print("ERROR:Invalid input arguments\r\n");
return -1;
}
snprintf(atcmd,sizeof(atcmd),"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pwd);
if( send_atcmd(atcmd,"CONNECTED",10000) )
{
wifi_print("ERROR:ESP8266 connect to '%s' failure\r\n",ssid);
}
wifi_print("INFO:ESP8266 connect to '%s' ok\r\n",ssid);
for(i=0;i<10;i++)
{
if( !send_atcmd("AT+CIPSTA?\r\n","255.",1000))
{
wifi_print("INFO:ESP8266 go to IP address ok\r\n");
return 0;
}
HAL_Delay(300);
}
wifi_print("ERROR:ESP8266 assigned IP address failure\r\n");
return -3;
}
/*
* AT+CIPSTA:ip:"192.168.2.100"
* AT+CIPSTA:gateway:"192.168.2.1"
*/
static int util_parser_ipaddr(char *buf,char *key,char *ipaddr,int size)
{
char *start;
char *end;
int len;
if(!buf || !key || !ipaddr)
{
return -1;
}
start =strstr(buf,key);/*ָ��ip����ַi*/
if(!start)
{
return -2;
}
start+=strlen(key)+1;/*ָ�š��ĵ�ַ*/
end=strchr(start,'"');
if(!end)
{
return -3;
}
len= end - start;
len= len>size?size:len;
memset(ipaddr,0,size);
strncpy(ipaddr,start,len);
return 0;
}
int esp8266_get_ipaddr(char *ipaddr,char *gateway,int ipaddr_size)
{
if(!ipaddr || !gateway || ipaddr_size<7)
{
wifi_print("ERROR:Invalid input arguments\r\n");
return -1;
}
if( send_atcmd("AT+CIPSTA?\r\n","255.",1000))
{
wifi_print("ERROR: ESP8266 AT+CIPSTA? command failure\r\n");
return -2;
}
if(util_parser_ipaddr(g_wifi_rxbuf,"ip:",ipaddr,ipaddr_size))
{
wifi_print("ERROR: ESP8266 AT+CIPSTA? parser IP address failure\r\n");
return -3;
}
if(util_parser_ipaddr(g_wifi_rxbuf,"gateway:",gateway,ipaddr_size))
{
wifi_print("ERROR: ESP8266 AT+CIPSTA? parser gateway failure\r\n");
return -4;
}
wifi_print("INFO:ESP8266 got IP address [%s] gateway[%s] ok\r\n",ipaddr,gateway);
return 0;
}
int esp8266_ping_test(char *host)
{
char atcmd[128]={0x00};
if(!host)
{
wifi_print("ERROR:Invalid input arguments\r\n");
return -1;
}
snprintf(atcmd,sizeof(atcmd),"AT+PING=\"%s\"\r\n",host);
if(send_atcmd(atcmd,EXPECT_OK,3000))
{
wifi_print("ERROR:ESP8266 ping test [%s] failure\r\n",host);
return -2;
}
wifi_print("INFO:ESP8266 ping test [%s] ok\r\n",host);
return 0;
}
int esp8266_sock_connect(char *servip,int port)
{
char atcmd[128]={0x00};
if(!servip || !port)
{
wifi_print("ERROR:Invalid input arguments\r\n");
return -1;
}
send_atcmd("AT+CIPMUX=0\r\n",EXPECT_OK,1500);
snprintf(atcmd,sizeof(atcmd),"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",servip,port);
if(send_atcmd(atcmd,"CONNECT\r\n",1000))
{
wifi_print("ERROR:ESP8266 socket connect to [%s:%d] failure\r\n",servip,port);
return -2;
}
wifi_print("INFO:ESP8266 socket connect to [%s:%d] ok\r\n",servip,port);
return 0;
}
int esp8266_sock_disconnect(void)
{
send_atcmd("AT+CIPCLOSE\r\n",EXPECT_OK,1500);
return 0;
}
int esp8266_sock_send(unsigned char *data,int bytes)
{
char atcmd[128]={0x00};
if(!data || bytes<=0)
{
wifi_print("ERROR:Invalid input arguments\r\n");
return -1;
}
snprintf(atcmd,sizeof(atcmd),"AT+CIPSEND=%d\r\n",bytes);
if(send_atcmd(atcmd,">",500))
{
wifi_print("ERROR:AT+CIPSEND command failure\r\n");
return 0;
}
if(atcmd_send_data((unsigned char *)data,bytes,1000))
{
wifi_print("ERROR:AT+CIPSEND send data failure\r\n");
return 0;
}
return bytes;
}
int esp8266_sock_recv(unsigned char *buf,int size)
{
char *data=NULL;
char *ptr=NULL;
int len;
int rv;
int bytes;
if( !buf || size<=0 )
{
wifi_print("ERROR:Invalid input arguments\r\n");
return -1;
}
if(g_wifi_rxbytes<=0)
{
// printf("g_wifi_rxbytes<=0\n");
// HAL_Delay(2000);
return 0;
}
if( !(ptr=strstr(g_wifi_rxbuf,"+IPD,")) || !(data=strchr(g_wifi_rxbuf,':')) )
{
return 0;
}
// printf("g_uart2_rxbuf:%s\n",g_uart2_rxbuf);
data++;
bytes = atoi(ptr+strlen("+IPD,"));
len = g_wifi_rxbytes - (data-g_uart2_rxbuf);
if( len < bytes )
{
wifi_dbg("+IPD data not receive over,receive again later ...\r\n");
return 0;
}
memset(buf,0,size);
rv=bytes>size?size:bytes;
memcpy(buf,data,rv);
clear_atcmd_buf();
return rv;
}