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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
_smutex.lock();
|
||||
|
@ -508,11 +519,13 @@ int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned
|
|||
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";
|
||||
bool done = false;
|
||||
|
||||
ip_info_print(1);
|
||||
|
||||
_smutex.lock();
|
||||
|
||||
// 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++) {
|
||||
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 {
|
||||
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";
|
||||
bool done = false;
|
||||
|
||||
ip_info_print(1);
|
||||
|
||||
if (!addr) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
@ -754,6 +769,7 @@ END:
|
|||
void ESP8266::_oob_packet_hdlr()
|
||||
{
|
||||
int id;
|
||||
int port;
|
||||
int amount;
|
||||
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) {
|
||||
//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)) {
|
||||
_sock_i[id].tcp_data_avbl = amount;
|
||||
|
||||
|
@ -772,8 +790,12 @@ void ESP8266::_oob_packet_hdlr()
|
|||
}
|
||||
}
|
||||
return;
|
||||
} else if (!_parser.scanf("%d:", &amount)) {
|
||||
return;
|
||||
} else {
|
||||
if (!(_parser.scanf("%d,", &amount)
|
||||
&& _parser.scanf("%15[^,],", _ip_buffer)
|
||||
&& _parser.scanf("%d:", &port))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pdu_len = sizeof(struct packet) + amount;
|
||||
|
@ -791,6 +813,10 @@ void ESP8266::_oob_packet_hdlr()
|
|||
_heap_usage += pdu_len;
|
||||
|
||||
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->alloc_len = amount;
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
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
|
||||
for (struct packet **p = &_packets; *p; p = &(*p)->next) {
|
||||
if ((*p)->id == id) {
|
||||
if ((*p)->id == socket->id) {
|
||||
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)
|
||||
uint32_t len = q->len < amount ? q->len : amount;
|
||||
memcpy(data, q + 1, len);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "platform/mbed_error.h"
|
||||
#include "rtos/Mutex.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "features/netsocket/SocketAddress.h"
|
||||
|
||||
// Various timeouts for different ESP8266 operations
|
||||
#ifndef ESP8266_CONNECT_TIMEOUT
|
||||
|
@ -64,6 +65,15 @@
|
|||
#define FW_AT_LEAST_VERSION(MAJOR,MINOR,PATCH,NUSED/*Not used*/,REF) \
|
||||
(((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.
|
||||
This is an interface to a ESP8266 radio.
|
||||
*/
|
||||
|
@ -167,6 +177,14 @@ public:
|
|||
*/
|
||||
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
|
||||
*
|
||||
|
@ -236,9 +254,10 @@ public:
|
|||
* @param addr the IP address of the destination
|
||||
* @param port the port on the destination
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
|
@ -271,7 +290,7 @@ public:
|
|||
* @param amount number of bytes to be 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
|
||||
|
@ -442,6 +461,8 @@ private:
|
|||
struct packet {
|
||||
struct packet *next;
|
||||
int id;
|
||||
char remote_ip[16];
|
||||
int remote_port;
|
||||
uint32_t len; // Remaining length
|
||||
uint32_t alloc_len; // Original length
|
||||
// data follows
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
|
||||
#define ESP8266_WIFI_IF_NAME "es0"
|
||||
|
||||
#define LOCAL_ADDR "127.0.0.1"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace rtos;
|
||||
|
||||
|
@ -750,14 +752,6 @@ nsapi_error_t ESP8266Interface::_reset()
|
|||
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)
|
||||
{
|
||||
// Look for an unused socket
|
||||
|
@ -783,6 +777,7 @@ int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
|
|||
socket->id = id;
|
||||
socket->proto = proto;
|
||||
socket->connected = false;
|
||||
socket->bound = false;
|
||||
socket->keepalive = 0;
|
||||
*handle = socket;
|
||||
return 0;
|
||||
|
@ -801,11 +796,16 @@ int ESP8266Interface::socket_close(void *handle)
|
|||
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].data = NULL;
|
||||
core_util_atomic_store_u8(&_cbs[socket->id].deferred, false);
|
||||
|
||||
socket->connected = false;
|
||||
socket->bound = false;
|
||||
_sock_i[socket->id].open = false;
|
||||
_sock_i[socket->id].sport = 0;
|
||||
delete socket;
|
||||
|
@ -828,12 +828,17 @@ int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address)
|
|||
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
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
} else if (id == socket->id && socket->connected) {
|
||||
} else if (id == socket->id && (socket->connected || socket->bound)) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
}
|
||||
_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;
|
||||
|
@ -854,7 +859,7 @@ int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr)
|
|||
}
|
||||
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
recv = _esp.recv_udp(socket->id, data, size);
|
||||
recv = _esp.recv_udp(socket, data, size);
|
||||
}
|
||||
|
||||
return recv;
|
||||
|
@ -950,7 +955,7 @@ int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, con
|
|||
socket->connected = false;
|
||||
}
|
||||
|
||||
if (!socket->connected) {
|
||||
if (!socket->connected && !socket->bound) {
|
||||
int err = socket_connect(socket, addr);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
|
@ -958,6 +963,10 @@ int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, con
|
|||
socket->addr = addr;
|
||||
}
|
||||
|
||||
if (socket->bound) {
|
||||
socket->addr = addr;
|
||||
}
|
||||
|
||||
return socket_send(socket, data, size);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue