MQTT client api and example
This code based on ESP8266 port of the embedded C client in Eclipse Paho project (http://www.eclipse.org/paho/) and it port for espressif ESP8266_RTOS_SDK by baoshi (https://github.com/baoshi/ESP-RTOS-Paho.git)
This commit is contained in:
parent
83c5f91bc0
commit
7e9d5bd2e2
21 changed files with 2793 additions and 0 deletions
187
extras/paho_mqtt_c/MQTTESP8266.c
Normal file
187
extras/paho_mqtt_c/MQTTESP8266.c
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file MQTTESP8266.c
|
||||
* @author Baoshi <mail(at)ba0sh1(dot)com>
|
||||
* @version 0.1
|
||||
* @date Sep 9, 2015
|
||||
* @brief Eclipse Paho ported to ESP8266 RTOS
|
||||
*
|
||||
******************************************************************************
|
||||
* @copyright
|
||||
*
|
||||
* Copyright (c) 2015, Baoshi Zhu. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE.txt file.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED 'AS-IS', WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN NO EVENT WILL THE AUTHOR(S) BE HELD LIABLE FOR ANY DAMAGES
|
||||
* ARISING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <espressif/esp_common.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/inet.h>
|
||||
#include <lwip/netdb.h>
|
||||
#include <lwip/sys.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MQTTESP8266.h"
|
||||
|
||||
char expired(Timer* timer)
|
||||
{
|
||||
portTickType now = xTaskGetTickCount();
|
||||
int32_t left = timer->end_time - now;
|
||||
return (left < 0);
|
||||
}
|
||||
|
||||
|
||||
void countdown_ms(Timer* timer, unsigned int timeout)
|
||||
{
|
||||
portTickType now = xTaskGetTickCount();
|
||||
timer->end_time = now + timeout / portTICK_RATE_MS;
|
||||
}
|
||||
|
||||
|
||||
void countdown(Timer* timer, unsigned int timeout)
|
||||
{
|
||||
countdown_ms(timer, timeout * 1000);
|
||||
}
|
||||
|
||||
|
||||
int left_ms(Timer* timer)
|
||||
{
|
||||
portTickType now = xTaskGetTickCount();
|
||||
int32_t left = timer->end_time - now;
|
||||
return (left < 0) ? 0 : left / portTICK_RATE_MS;
|
||||
}
|
||||
|
||||
|
||||
void InitTimer(Timer* timer)
|
||||
{
|
||||
timer->end_time = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int mqtt_esp_read(Network* n, unsigned char* buffer, int len, int timeout_ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set fdset;
|
||||
int rc = 0;
|
||||
int rcvd = 0;
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(n->my_socket, &fdset);
|
||||
// It seems tv_sec actually means FreeRTOS tick
|
||||
tv.tv_sec = timeout_ms / portTICK_RATE_MS;
|
||||
tv.tv_usec = 0;
|
||||
rc = select(n->my_socket + 1, &fdset, 0, 0, &tv);
|
||||
if ((rc > 0) && (FD_ISSET(n->my_socket, &fdset)))
|
||||
{
|
||||
rcvd = recv(n->my_socket, buffer, len, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// select fail
|
||||
return -1;
|
||||
}
|
||||
return rcvd;
|
||||
}
|
||||
|
||||
|
||||
int mqtt_esp_write(Network* n, unsigned char* buffer, int len, int timeout_ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set fdset;
|
||||
int rc = 0;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(n->my_socket, &fdset);
|
||||
// It seems tv_sec actually means FreeRTOS tick
|
||||
tv.tv_sec = timeout_ms / portTICK_RATE_MS;
|
||||
tv.tv_usec = 0;
|
||||
rc = select(n->my_socket + 1, 0, &fdset, 0, &tv);
|
||||
if ((rc > 0) && (FD_ISSET(n->my_socket, &fdset)))
|
||||
{
|
||||
rc = send(n->my_socket, buffer, len, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// select fail
|
||||
return -1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NewNetwork(Network* n)
|
||||
{
|
||||
n->my_socket = -1;
|
||||
n->mqttread = mqtt_esp_read;
|
||||
n->mqttwrite = mqtt_esp_write;
|
||||
}
|
||||
|
||||
static int host2addr(const char *hostname , struct in_addr *in)
|
||||
{
|
||||
struct addrinfo hints, *servinfo, *p;
|
||||
struct sockaddr_in *h;
|
||||
int rv;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
rv = getaddrinfo(hostname, 0 , &hints , &servinfo);
|
||||
if (rv != 0)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
|
||||
// loop through all the results and get the first resolve
|
||||
for (p = servinfo; p != 0; p = p->ai_next)
|
||||
{
|
||||
h = (struct sockaddr_in *)p->ai_addr;
|
||||
in->s_addr = h->sin_addr.s_addr;
|
||||
}
|
||||
freeaddrinfo(servinfo); // all done with this structure
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ConnectNetwork(Network* n, const char* host, int port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int ret;
|
||||
|
||||
if (host2addr(host, &(addr.sin_addr)) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
n->my_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if( n->my_socket < 0 )
|
||||
{
|
||||
// error
|
||||
return -1;
|
||||
}
|
||||
ret = connect(n->my_socket, ( struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||
if( ret < 0 )
|
||||
{
|
||||
// error
|
||||
close(n->my_socket);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int DisconnectNetwork(Network* n)
|
||||
{
|
||||
close(n->my_socket);
|
||||
n->my_socket = -1;
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue