Skip to content

Commit 9cb9866

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 9cb9866

File tree

3 files changed

+95
-21
lines changed

3 files changed

+95
-21
lines changed

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

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

376+
bool ESP8266::ip_info(int enable)
377+
{
378+
_smutex.lock();
379+
_disconnect = true;
380+
bool done = _parser.send("AT+CIPDINFO=%d", enable) && _parser.recv("OK\n");
381+
if(done) {
382+
cip_info = 1;
383+
}
384+
_smutex.unlock();
385+
386+
return done;
387+
}
388+
389+
376390
const char *ESP8266::ip_addr(void)
377391
{
378392
_smutex.lock();
@@ -508,11 +522,13 @@ int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned
508522
return cnt;
509523
}
510524

511-
nsapi_error_t ESP8266::open_udp(int id, const char *addr, int port, int local_port)
525+
nsapi_error_t ESP8266::open_udp(int id, const char *addr, int port, int local_port, int udp_mode)
512526
{
513527
static const char *type = "UDP";
514528
bool done = false;
515529

530+
ip_info(1);
531+
516532
_smutex.lock();
517533

518534
// process OOB so that _sock_i reflects the correct state of the socket
@@ -533,7 +549,7 @@ nsapi_error_t ESP8266::open_udp(int id, const char *addr, int port, int local_po
533549

534550
for (int i = 0; i < 2; i++) {
535551
if (local_port) {
536-
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d,%d", id, type, addr, port, local_port);
552+
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d,%d,%d", id, type, addr, port, local_port, udp_mode);
537553
} else {
538554
done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port);
539555
}
@@ -572,6 +588,8 @@ nsapi_error_t ESP8266::open_tcp(int id, const char *addr, int port, int keepaliv
572588
static const char *type = "TCP";
573589
bool done = false;
574590

591+
ip_info(0);
592+
575593
if (!addr) {
576594
return NSAPI_ERROR_PARAMETER;
577595
}
@@ -754,6 +772,7 @@ nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount)
754772
void ESP8266::_oob_packet_hdlr()
755773
{
756774
int id;
775+
int port;
757776
int amount;
758777
int pdu_len;
759778

@@ -772,8 +791,23 @@ void ESP8266::_oob_packet_hdlr()
772791
}
773792
}
774793
return;
775-
} else if (!_parser.scanf("%d:", &amount)) {
776-
return;
794+
} else {
795+
if (cip_info == 1) {
796+
if (!_parser.scanf("%d,", &amount)) {
797+
return;
798+
}
799+
if (!_parser.scanf("%15[^,],", _ip_buffer)) {
800+
return;
801+
}
802+
if (!_parser.scanf("%d:", &port)) {
803+
return;
804+
}
805+
}
806+
else {
807+
if (!_parser.scanf("%d:", &amount)) {
808+
return;
809+
}
810+
}
777811
}
778812

779813
pdu_len = sizeof(struct packet) + amount;
@@ -791,6 +825,10 @@ void ESP8266::_oob_packet_hdlr()
791825
_heap_usage += pdu_len;
792826

793827
packet->id = id;
828+
if (cip_info == 1) {
829+
packet->remote_port = port;
830+
memcpy(packet->remote_ip, _ip_buffer, 16);
831+
}
794832
packet->len = amount;
795833
packet->alloc_len = amount;
796834
packet->next = 0;
@@ -943,7 +981,7 @@ int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
943981
return NSAPI_ERROR_WOULD_BLOCK;
944982
}
945983

946-
int32_t ESP8266::recv_udp(int id, void *data, uint32_t amount, uint32_t timeout)
984+
int32_t ESP8266::recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, uint32_t timeout)
947985
{
948986
_smutex.lock();
949987
set_timeout(timeout);
@@ -956,9 +994,12 @@ int32_t ESP8266::recv_udp(int id, void *data, uint32_t amount, uint32_t timeout)
956994

957995
// check if any packets are ready for us
958996
for (struct packet **p = &_packets; *p; p = &(*p)->next) {
959-
if ((*p)->id == id) {
997+
if ((*p)->id == socket->id) {
960998
struct packet *q = *p;
961999

1000+
socket->addr.set_ip_address((*p)->remote_ip);
1001+
socket->addr.set_port((*p)->remote_port);
1002+
9621003
// Return and remove packet (truncated if necessary)
9631004
uint32_t len = q->len < amount ? q->len : amount;
9641005
memcpy(data, q + 1, len);

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

Lines changed: 26 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 binded;
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 disconnect Remote IP and Port with +IPD
182+
*
183+
* @param enable, 1 on, 0 off
184+
* @return true only if ESP8266 is disconnected successfully
185+
*/
186+
bool ip_info(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 ones, 2 can change
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
@@ -417,6 +436,9 @@ class ESP8266 {
417436
int uart_enable_input(bool lock);
418437

419438
private:
439+
//Shows the Remote IP and Port with +IPD
440+
int cip_info = 0;
441+
420442
// FW version
421443
struct fw_sdk_version _sdk_v;
422444
struct fw_at_version _at_v;
@@ -442,6 +464,8 @@ class ESP8266 {
442464
struct packet {
443465
struct packet *next;
444466
int id;
467+
char remote_ip[16];
468+
int remote_port;
445469
uint32_t len; // Remaining length
446470
uint32_t alloc_len; // Original length
447471
// 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->binded = 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->binded && !_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->binded = 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->binded)) {
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->binded = (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->binded) {
954959
int err = socket_connect(socket, addr);
955960
if (err < 0) {
956961
return err;
957962
}
958963
socket->addr = addr;
959964
}
960965

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

0 commit comments

Comments
 (0)