mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #12320 from mtomczykmobica/ONME-3433
ONME-3433 ESP8266 driver support for UDP get - modified ESP8266 drive…pull/12339/head
commit
acece11e7a
|
@ -373,6 +373,17 @@ bool ESP8266::disconnect(void)
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ESP8266::ip_info_print(int enable)
|
||||||
|
{
|
||||||
|
_smutex.lock();
|
||||||
|
_disconnect = true;
|
||||||
|
bool done = _parser.send("AT+CIPDINFO=%d", enable) && _parser.recv("OK\n");
|
||||||
|
_smutex.unlock();
|
||||||
|
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *ESP8266::ip_addr(void)
|
const char *ESP8266::ip_addr(void)
|
||||||
{
|
{
|
||||||
_smutex.lock();
|
_smutex.lock();
|
||||||
|
@ -508,11 +519,13 @@ int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t ESP8266::open_udp(int id, const char *addr, int port, int local_port)
|
nsapi_error_t ESP8266::open_udp(int id, const char *addr, int port, int local_port, int udp_mode)
|
||||||
{
|
{
|
||||||
static const char *type = "UDP";
|
static const char *type = "UDP";
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
|
ip_info_print(1);
|
||||||
|
|
||||||
_smutex.lock();
|
_smutex.lock();
|
||||||
|
|
||||||
// process OOB so that _sock_i reflects the correct state of the socket
|
// process OOB so that _sock_i reflects the correct state of the socket
|
||||||
|
@ -533,7 +546,7 @@ nsapi_error_t ESP8266::open_udp(int id, const char *addr, int port, int local_po
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (local_port) {
|
if (local_port) {
|
||||||
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d,%d", id, type, addr, port, local_port);
|
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d,%d,%d", id, type, addr, port, local_port, udp_mode);
|
||||||
} else {
|
} else {
|
||||||
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port);
|
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port);
|
||||||
}
|
}
|
||||||
|
@ -572,6 +585,8 @@ nsapi_error_t ESP8266::open_tcp(int id, const char *addr, int port, int keepaliv
|
||||||
static const char *type = "TCP";
|
static const char *type = "TCP";
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
|
ip_info_print(1);
|
||||||
|
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
return NSAPI_ERROR_PARAMETER;
|
return NSAPI_ERROR_PARAMETER;
|
||||||
}
|
}
|
||||||
|
@ -754,6 +769,7 @@ END:
|
||||||
void ESP8266::_oob_packet_hdlr()
|
void ESP8266::_oob_packet_hdlr()
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
int port;
|
||||||
int amount;
|
int amount;
|
||||||
int pdu_len;
|
int pdu_len;
|
||||||
|
|
||||||
|
@ -763,6 +779,8 @@ void ESP8266::_oob_packet_hdlr()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_tcp_passive && _sock_i[id].open == true && _sock_i[id].proto == NSAPI_TCP) {
|
if (_tcp_passive && _sock_i[id].open == true && _sock_i[id].proto == NSAPI_TCP) {
|
||||||
|
//For TCP +IPD return only id and amount and it is independent on AT+CIPDINFO settings
|
||||||
|
//Unfortunately no information about that in ESP manual but it has sense.
|
||||||
if (_parser.recv("%d\n", &amount)) {
|
if (_parser.recv("%d\n", &amount)) {
|
||||||
_sock_i[id].tcp_data_avbl = amount;
|
_sock_i[id].tcp_data_avbl = amount;
|
||||||
|
|
||||||
|
@ -772,8 +790,12 @@ void ESP8266::_oob_packet_hdlr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (!_parser.scanf("%d:", &amount)) {
|
} else {
|
||||||
return;
|
if (!(_parser.scanf("%d,", &amount)
|
||||||
|
&& _parser.scanf("%15[^,],", _ip_buffer)
|
||||||
|
&& _parser.scanf("%d:", &port))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pdu_len = sizeof(struct packet) + amount;
|
pdu_len = sizeof(struct packet) + amount;
|
||||||
|
@ -791,6 +813,10 @@ void ESP8266::_oob_packet_hdlr()
|
||||||
_heap_usage += pdu_len;
|
_heap_usage += pdu_len;
|
||||||
|
|
||||||
packet->id = id;
|
packet->id = id;
|
||||||
|
if (_sock_i[id].proto == NSAPI_UDP) {
|
||||||
|
packet->remote_port = port;
|
||||||
|
memcpy(packet->remote_ip, _ip_buffer, 16);
|
||||||
|
}
|
||||||
packet->len = amount;
|
packet->len = amount;
|
||||||
packet->alloc_len = amount;
|
packet->alloc_len = amount;
|
||||||
packet->next = 0;
|
packet->next = 0;
|
||||||
|
@ -943,7 +969,7 @@ int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
|
||||||
return NSAPI_ERROR_WOULD_BLOCK;
|
return NSAPI_ERROR_WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ESP8266::recv_udp(int id, void *data, uint32_t amount, uint32_t timeout)
|
int32_t ESP8266::recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, uint32_t timeout)
|
||||||
{
|
{
|
||||||
_smutex.lock();
|
_smutex.lock();
|
||||||
set_timeout(timeout);
|
set_timeout(timeout);
|
||||||
|
@ -956,9 +982,12 @@ int32_t ESP8266::recv_udp(int id, void *data, uint32_t amount, uint32_t timeout)
|
||||||
|
|
||||||
// check if any packets are ready for us
|
// check if any packets are ready for us
|
||||||
for (struct packet **p = &_packets; *p; p = &(*p)->next) {
|
for (struct packet **p = &_packets; *p; p = &(*p)->next) {
|
||||||
if ((*p)->id == id) {
|
if ((*p)->id == socket->id) {
|
||||||
struct packet *q = *p;
|
struct packet *q = *p;
|
||||||
|
|
||||||
|
socket->addr.set_ip_address((*p)->remote_ip);
|
||||||
|
socket->addr.set_port((*p)->remote_port);
|
||||||
|
|
||||||
// Return and remove packet (truncated if necessary)
|
// Return and remove packet (truncated if necessary)
|
||||||
uint32_t len = q->len < amount ? q->len : amount;
|
uint32_t len = q->len < amount ? q->len : amount;
|
||||||
memcpy(data, q + 1, len);
|
memcpy(data, q + 1, len);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "platform/mbed_error.h"
|
#include "platform/mbed_error.h"
|
||||||
#include "rtos/Mutex.h"
|
#include "rtos/Mutex.h"
|
||||||
#include "rtos/ThisThread.h"
|
#include "rtos/ThisThread.h"
|
||||||
|
#include "features/netsocket/SocketAddress.h"
|
||||||
|
|
||||||
// Various timeouts for different ESP8266 operations
|
// Various timeouts for different ESP8266 operations
|
||||||
#ifndef ESP8266_CONNECT_TIMEOUT
|
#ifndef ESP8266_CONNECT_TIMEOUT
|
||||||
|
@ -64,6 +65,15 @@
|
||||||
#define FW_AT_LEAST_VERSION(MAJOR,MINOR,PATCH,NUSED/*Not used*/,REF) \
|
#define FW_AT_LEAST_VERSION(MAJOR,MINOR,PATCH,NUSED/*Not used*/,REF) \
|
||||||
(((MAJOR)*1000000+(MINOR)*10000+(PATCH)*100) >= REF ? true : false)
|
(((MAJOR)*1000000+(MINOR)*10000+(PATCH)*100) >= REF ? true : false)
|
||||||
|
|
||||||
|
struct esp8266_socket {
|
||||||
|
int id;
|
||||||
|
nsapi_protocol_t proto;
|
||||||
|
bool connected;
|
||||||
|
bool bound;
|
||||||
|
SocketAddress addr;
|
||||||
|
int keepalive; // TCP
|
||||||
|
};
|
||||||
|
|
||||||
/** ESP8266Interface class.
|
/** ESP8266Interface class.
|
||||||
This is an interface to a ESP8266 radio.
|
This is an interface to a ESP8266 radio.
|
||||||
*/
|
*/
|
||||||
|
@ -167,6 +177,14 @@ public:
|
||||||
*/
|
*/
|
||||||
bool disconnect(void);
|
bool disconnect(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable Remote IP and Port printing with +IPD
|
||||||
|
*
|
||||||
|
* @param enable, 1 on, 0 off
|
||||||
|
* @return true only if ESP8266 is disconnected successfully
|
||||||
|
*/
|
||||||
|
bool ip_info_print(int enable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the IP address of ESP8266
|
* Get the IP address of ESP8266
|
||||||
*
|
*
|
||||||
|
@ -236,9 +254,10 @@ public:
|
||||||
* @param addr the IP address of the destination
|
* @param addr the IP address of the destination
|
||||||
* @param port the port on the destination
|
* @param port the port on the destination
|
||||||
* @param local_port UDP socket's local port, zero means any
|
* @param local_port UDP socket's local port, zero means any
|
||||||
|
* @param udp_mode UDP socket's mode, zero means can't change remote, 1 can change once, 2 can change multiple times
|
||||||
* @return NSAPI_ERROR_OK in success, negative error code in failure
|
* @return NSAPI_ERROR_OK in success, negative error code in failure
|
||||||
*/
|
*/
|
||||||
nsapi_error_t open_udp(int id, const char *addr, int port, int local_port = 0);
|
nsapi_error_t open_udp(int id, const char *addr, int port, int local_port = 0, int udp_mode = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a socketed connection
|
* Open a socketed connection
|
||||||
|
@ -271,7 +290,7 @@ public:
|
||||||
* @param amount number of bytes to be received
|
* @param amount number of bytes to be received
|
||||||
* @return the number of bytes received
|
* @return the number of bytes received
|
||||||
*/
|
*/
|
||||||
int32_t recv_udp(int id, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
|
int32_t recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives stream data from an open TCP socket
|
* Receives stream data from an open TCP socket
|
||||||
|
@ -442,6 +461,8 @@ private:
|
||||||
struct packet {
|
struct packet {
|
||||||
struct packet *next;
|
struct packet *next;
|
||||||
int id;
|
int id;
|
||||||
|
char remote_ip[16];
|
||||||
|
int remote_port;
|
||||||
uint32_t len; // Remaining length
|
uint32_t len; // Remaining length
|
||||||
uint32_t alloc_len; // Original length
|
uint32_t alloc_len; // Original length
|
||||||
// data follows
|
// data follows
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
|
|
||||||
#define ESP8266_WIFI_IF_NAME "es0"
|
#define ESP8266_WIFI_IF_NAME "es0"
|
||||||
|
|
||||||
|
#define LOCAL_ADDR "127.0.0.1"
|
||||||
|
|
||||||
using namespace mbed;
|
using namespace mbed;
|
||||||
using namespace rtos;
|
using namespace rtos;
|
||||||
|
|
||||||
|
@ -750,14 +752,6 @@ nsapi_error_t ESP8266Interface::_reset()
|
||||||
return _esp.at_available() ? NSAPI_ERROR_OK : NSAPI_ERROR_DEVICE_ERROR;
|
return _esp.at_available() ? NSAPI_ERROR_OK : NSAPI_ERROR_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct esp8266_socket {
|
|
||||||
int id;
|
|
||||||
nsapi_protocol_t proto;
|
|
||||||
bool connected;
|
|
||||||
SocketAddress addr;
|
|
||||||
int keepalive; // TCP
|
|
||||||
};
|
|
||||||
|
|
||||||
int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
|
int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
|
||||||
{
|
{
|
||||||
// Look for an unused socket
|
// Look for an unused socket
|
||||||
|
@ -783,6 +777,7 @@ int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
|
||||||
socket->id = id;
|
socket->id = id;
|
||||||
socket->proto = proto;
|
socket->proto = proto;
|
||||||
socket->connected = false;
|
socket->connected = false;
|
||||||
|
socket->bound = false;
|
||||||
socket->keepalive = 0;
|
socket->keepalive = 0;
|
||||||
*handle = socket;
|
*handle = socket;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -801,11 +796,16 @@ int ESP8266Interface::socket_close(void *handle)
|
||||||
err = NSAPI_ERROR_DEVICE_ERROR;
|
err = NSAPI_ERROR_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (socket->bound && !_esp.close(socket->id)) {
|
||||||
|
err = NSAPI_ERROR_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
_cbs[socket->id].callback = NULL;
|
_cbs[socket->id].callback = NULL;
|
||||||
_cbs[socket->id].data = NULL;
|
_cbs[socket->id].data = NULL;
|
||||||
core_util_atomic_store_u8(&_cbs[socket->id].deferred, false);
|
core_util_atomic_store_u8(&_cbs[socket->id].deferred, false);
|
||||||
|
|
||||||
socket->connected = false;
|
socket->connected = false;
|
||||||
|
socket->bound = false;
|
||||||
_sock_i[socket->id].open = false;
|
_sock_i[socket->id].open = false;
|
||||||
_sock_i[socket->id].sport = 0;
|
_sock_i[socket->id].sport = 0;
|
||||||
delete socket;
|
delete socket;
|
||||||
|
@ -828,12 +828,17 @@ int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address)
|
||||||
for (int id = 0; id < ESP8266_SOCKET_COUNT; id++) {
|
for (int id = 0; id < ESP8266_SOCKET_COUNT; id++) {
|
||||||
if (_sock_i[id].sport == address.get_port() && id != socket->id) { // Port already reserved by another socket
|
if (_sock_i[id].sport == address.get_port() && id != socket->id) { // Port already reserved by another socket
|
||||||
return NSAPI_ERROR_PARAMETER;
|
return NSAPI_ERROR_PARAMETER;
|
||||||
} else if (id == socket->id && socket->connected) {
|
} else if (id == socket->id && (socket->connected || socket->bound)) {
|
||||||
return NSAPI_ERROR_PARAMETER;
|
return NSAPI_ERROR_PARAMETER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_sock_i[socket->id].sport = address.get_port();
|
_sock_i[socket->id].sport = address.get_port();
|
||||||
return 0;
|
|
||||||
|
int ret = _esp.open_udp(socket->id, LOCAL_ADDR, address.get_port(), _sock_i[socket->id].sport, 2);
|
||||||
|
|
||||||
|
socket->bound = (ret == NSAPI_ERROR_OK) ? true : false;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NSAPI_ERROR_UNSUPPORTED;
|
return NSAPI_ERROR_UNSUPPORTED;
|
||||||
|
@ -854,7 +859,7 @@ int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket->proto == NSAPI_UDP) {
|
if (socket->proto == NSAPI_UDP) {
|
||||||
ret = _esp.open_udp(socket->id, addr.get_ip_address(), addr.get_port(), _sock_i[socket->id].sport);
|
ret = _esp.open_udp(socket->id, addr.get_ip_address(), addr.get_port(), _sock_i[socket->id].sport, 0);
|
||||||
} else {
|
} else {
|
||||||
ret = _esp.open_tcp(socket->id, addr.get_ip_address(), addr.get_port(), socket->keepalive);
|
ret = _esp.open_tcp(socket->id, addr.get_ip_address(), addr.get_port(), socket->keepalive);
|
||||||
}
|
}
|
||||||
|
@ -925,7 +930,7 @@ int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size)
|
||||||
socket->connected = false;
|
socket->connected = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
recv = _esp.recv_udp(socket->id, data, size);
|
recv = _esp.recv_udp(socket, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return recv;
|
return recv;
|
||||||
|
@ -950,7 +955,7 @@ int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, con
|
||||||
socket->connected = false;
|
socket->connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!socket->connected) {
|
if (!socket->connected && !socket->bound) {
|
||||||
int err = socket_connect(socket, addr);
|
int err = socket_connect(socket, addr);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
return err;
|
return err;
|
||||||
|
@ -958,6 +963,10 @@ int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, con
|
||||||
socket->addr = addr;
|
socket->addr = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (socket->bound) {
|
||||||
|
socket->addr = addr;
|
||||||
|
}
|
||||||
|
|
||||||
return socket_send(socket, data, size);
|
return socket_send(socket, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue