Skip to content

Commit 2513863

Browse files
author
Marcin Tomczyk
committed
ONME-3433 ESP8266 driver support for UDP get - modified ESP8266 driver to support UDP connection in server mode (get)
1 parent f469f71 commit 2513863

File tree

3 files changed

+79
-22
lines changed

3 files changed

+79
-22
lines changed

components/wifi/esp8266-driver/ESP8266/ESP8266.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,17 @@ bool ESP8266::disconnect(void)
373373
return done;
374374
}
375375

376+
bool ESP8266::ip_info_print(int enable)
377+
{
378+
_smutex.lock();
379+
_disconnect = true;
380+
bool done = _parser.send("AT+CIPDINFO=%d", enable) && _parser.recv("OK\n");
381+
_smutex.unlock();
382+
383+
return done;
384+
}
385+
386+
376387
const char *ESP8266::ip_addr(void)
377388
{
378389
_smutex.lock();
@@ -508,11 +519,13 @@ int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned
508519
return cnt;
509520
}
510521

511-
nsapi_error_t ESP8266::open_udp(int id, const char *addr, int port, int local_port)
522+
nsapi_error_t ESP8266::open_udp(int id, const char *addr, int port, int local_port, int udp_mode)
512523
{
513524
static const char *type = "UDP";
514525
bool done = false;
515526

527+
ip_info_print(1);
528+
516529
_smutex.lock();
517530

518531
// 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
533546

534547
for (int i = 0; i < 2; i++) {
535548
if (local_port) {
536-
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d,%d", id, type, addr, port, local_port);
549+
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d,%d,%d", id, type, addr, port, local_port, udp_mode);
537550
} else {
538551
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port);
539552
}
@@ -572,6 +585,8 @@ nsapi_error_t ESP8266::open_tcp(int id, const char *addr, int port, int keepaliv
572585
static const char *type = "TCP";
573586
bool done = false;
574587

588+
ip_info_print(1);
589+
575590
if (!addr) {
576591
return NSAPI_ERROR_PARAMETER;
577592
}
@@ -754,6 +769,7 @@ nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount)
754769
void ESP8266::_oob_packet_hdlr()
755770
{
756771
int id;
772+
int port;
757773
int amount;
758774
int pdu_len;
759775

@@ -763,7 +779,9 @@ void ESP8266::_oob_packet_hdlr()
763779
}
764780

765781
if (_tcp_passive && _sock_i[id].open == true && _sock_i[id].proto == NSAPI_TCP) {
766-
if (_parser.recv("%d\n", &amount)) {
782+
if (_parser.scanf("%d,", &amount)
783+
&& _parser.scanf("%15[^,],", _ip_buffer)
784+
&& _parser.scanf("%d:", &port)) {
767785
_sock_i[id].tcp_data_avbl = amount;
768786

769787
// notify data is available
@@ -772,8 +790,12 @@ void ESP8266::_oob_packet_hdlr()
772790
}
773791
}
774792
return;
775-
} else if (!_parser.scanf("%d:", &amount)) {
776-
return;
793+
} else {
794+
if (!(_parser.scanf("%d,", &amount)
795+
&& _parser.scanf("%15[^,],", _ip_buffer)
796+
&& _parser.scanf("%d:", &port))) {
797+
return;
798+
}
777799
}
778800

779801
pdu_len = sizeof(struct packet) + amount;
@@ -791,6 +813,8 @@ void ESP8266::_oob_packet_hdlr()
791813
_heap_usage += pdu_len;
792814

793815
packet->id = id;
816+
packet->remote_port = port;
817+
memcpy(packet->remote_ip, _ip_buffer, 16);
794818
packet->len = amount;
795819
packet->alloc_len = amount;
796820
packet->next = 0;
@@ -943,7 +967,7 @@ int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
943967
return NSAPI_ERROR_WOULD_BLOCK;
944968
}
945969

946-
int32_t ESP8266::recv_udp(int id, void *data, uint32_t amount, uint32_t timeout)
970+
int32_t ESP8266::recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, uint32_t timeout)
947971
{
948972
_smutex.lock();
949973
set_timeout(timeout);
@@ -956,9 +980,12 @@ int32_t ESP8266::recv_udp(int id, void *data, uint32_t amount, uint32_t timeout)
956980

957981
// check if any packets are ready for us
958982
for (struct packet **p = &_packets; *p; p = &(*p)->next) {
959-
if ((*p)->id == id) {
983+
if ((*p)->id == socket->id) {
960984
struct packet *q = *p;
961985

986+
socket->addr.set_ip_address((*p)->remote_ip);
987+
socket->addr.set_port((*p)->remote_port);
988+
962989
// Return and remove packet (truncated if necessary)
963990
uint32_t len = q->len < amount ? q->len : amount;
964991
memcpy(data, q + 1, len);

components/wifi/esp8266-driver/ESP8266/ESP8266.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "platform/mbed_error.h"
3030
#include "rtos/Mutex.h"
3131
#include "rtos/ThisThread.h"
32+
#include "features/netsocket/SocketAddress.h"
3233

3334
// Various timeouts for different ESP8266 operations
3435
#ifndef ESP8266_CONNECT_TIMEOUT
@@ -64,6 +65,15 @@
6465
#define FW_AT_LEAST_VERSION(MAJOR,MINOR,PATCH,NUSED/*Not used*/,REF) \
6566
(((MAJOR)*1000000+(MINOR)*10000+(PATCH)*100) >= REF ? true : false)
6667

68+
struct esp8266_socket {
69+
int id;
70+
nsapi_protocol_t proto;
71+
bool connected;
72+
bool bound;
73+
SocketAddress addr;
74+
int keepalive; // TCP
75+
};
76+
6777
/** ESP8266Interface class.
6878
This is an interface to a ESP8266 radio.
6979
*/
@@ -167,6 +177,14 @@ class ESP8266 {
167177
*/
168178
bool disconnect(void);
169179

180+
/**
181+
* Enable or disable Remote IP and Port printing with +IPD
182+
*
183+
* @param enable, 1 on, 0 off
184+
* @return true only if ESP8266 is disconnected successfully
185+
*/
186+
bool ip_info_print(int enable);
187+
170188
/**
171189
* Get the IP address of ESP8266
172190
*
@@ -236,9 +254,10 @@ class ESP8266 {
236254
* @param addr the IP address of the destination
237255
* @param port the port on the destination
238256
* @param local_port UDP socket's local port, zero means any
257+
* @param udp_mode UDP socket's mode, zero means can't change remote, 1 can change once, 2 can change multiple times
239258
* @return NSAPI_ERROR_OK in success, negative error code in failure
240259
*/
241-
nsapi_error_t open_udp(int id, const char *addr, int port, int local_port = 0);
260+
nsapi_error_t open_udp(int id, const char *addr, int port, int local_port = 0, int udp_mode = 0);
242261

243262
/**
244263
* Open a socketed connection
@@ -271,7 +290,7 @@ class ESP8266 {
271290
* @param amount number of bytes to be received
272291
* @return the number of bytes received
273292
*/
274-
int32_t recv_udp(int id, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
293+
int32_t recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
275294

276295
/**
277296
* Receives stream data from an open TCP socket
@@ -442,6 +461,8 @@ class ESP8266 {
442461
struct packet {
443462
struct packet *next;
444463
int id;
464+
char remote_ip[16];
465+
int remote_port;
445466
uint32_t len; // Remaining length
446467
uint32_t alloc_len; // Original length
447468
// data follows

components/wifi/esp8266-driver/ESP8266Interface.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454

5555
#define ESP8266_WIFI_IF_NAME "es0"
5656

57+
#define LOCAL_ADDR "127.0.0.1"
58+
5759
using namespace mbed;
5860
using namespace rtos;
5961

@@ -750,14 +752,6 @@ nsapi_error_t ESP8266Interface::_reset()
750752
return _esp.at_available() ? NSAPI_ERROR_OK : NSAPI_ERROR_DEVICE_ERROR;
751753
}
752754

753-
struct esp8266_socket {
754-
int id;
755-
nsapi_protocol_t proto;
756-
bool connected;
757-
SocketAddress addr;
758-
int keepalive; // TCP
759-
};
760-
761755
int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
762756
{
763757
// Look for an unused socket
@@ -783,6 +777,7 @@ int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
783777
socket->id = id;
784778
socket->proto = proto;
785779
socket->connected = false;
780+
socket->bound = false;
786781
socket->keepalive = 0;
787782
*handle = socket;
788783
return 0;
@@ -801,11 +796,16 @@ int ESP8266Interface::socket_close(void *handle)
801796
err = NSAPI_ERROR_DEVICE_ERROR;
802797
}
803798

799+
if (socket->bound && !_esp.close(socket->id)) {
800+
err = NSAPI_ERROR_DEVICE_ERROR;
801+
}
802+
804803
_cbs[socket->id].callback = NULL;
805804
_cbs[socket->id].data = NULL;
806805
core_util_atomic_store_u8(&_cbs[socket->id].deferred, false);
807806

808807
socket->connected = false;
808+
socket->bound = false;
809809
_sock_i[socket->id].open = false;
810810
_sock_i[socket->id].sport = 0;
811811
delete socket;
@@ -828,12 +828,17 @@ int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address)
828828
for (int id = 0; id < ESP8266_SOCKET_COUNT; id++) {
829829
if (_sock_i[id].sport == address.get_port() && id != socket->id) { // Port already reserved by another socket
830830
return NSAPI_ERROR_PARAMETER;
831-
} else if (id == socket->id && socket->connected) {
831+
} else if (id == socket->id && (socket->connected || socket->bound)) {
832832
return NSAPI_ERROR_PARAMETER;
833833
}
834834
}
835835
_sock_i[socket->id].sport = address.get_port();
836-
return 0;
836+
837+
int ret = _esp.open_udp(socket->id, LOCAL_ADDR, address.get_port(), _sock_i[socket->id].sport, 2);
838+
839+
socket->bound = (ret == NSAPI_ERROR_OK) ? true : false;
840+
841+
return ret;
837842
}
838843

839844
return NSAPI_ERROR_UNSUPPORTED;
@@ -854,7 +859,7 @@ int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr)
854859
}
855860

856861
if (socket->proto == NSAPI_UDP) {
857-
ret = _esp.open_udp(socket->id, addr.get_ip_address(), addr.get_port(), _sock_i[socket->id].sport);
862+
ret = _esp.open_udp(socket->id, addr.get_ip_address(), addr.get_port(), _sock_i[socket->id].sport, 0);
858863
} else {
859864
ret = _esp.open_tcp(socket->id, addr.get_ip_address(), addr.get_port(), socket->keepalive);
860865
}
@@ -925,7 +930,7 @@ int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size)
925930
socket->connected = false;
926931
}
927932
} else {
928-
recv = _esp.recv_udp(socket->id, data, size);
933+
recv = _esp.recv_udp(socket, data, size);
929934
}
930935

931936
return recv;
@@ -950,14 +955,18 @@ int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, con
950955
socket->connected = false;
951956
}
952957

953-
if (!socket->connected) {
958+
if (!socket->connected && !socket->bound) {
954959
int err = socket_connect(socket, addr);
955960
if (err < 0) {
956961
return err;
957962
}
958963
socket->addr = addr;
959964
}
960965

966+
if (socket->bound) {
967+
socket->addr = addr;
968+
}
969+
961970
return socket_send(socket, data, size);
962971
}
963972

0 commit comments

Comments
 (0)