Skip to content

Commit 38e28dc

Browse files
authored
Merge pull request #6903 from ARMmbed/feature-emac-15May-merge
Feature-emac combined merge
2 parents d95acbc + 33a38a5 commit 38e28dc

File tree

41 files changed

+2911
-1609
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2911
-1609
lines changed

features/FEATURE_LWIP/lwip-interface/LWIPStack.cpp

Lines changed: 73 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "lwip/dns.h"
3434
#include "lwip/udp.h"
3535
#include "lwip/lwip_errno.h"
36+
#include "lwip-sys/arch/sys_arch.h"
3637

3738
#include "LWIPStack.h"
3839

@@ -47,10 +48,10 @@ void LWIP::socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len)
4748
return;
4849
}
4950

50-
sys_prot_t prot = sys_arch_protect();
51-
5251
LWIP &lwip = LWIP::get_instance();
5352

53+
lwip.adaptation.lock();
54+
5455
for (int i = 0; i < MEMP_NUM_NETCONN; i++) {
5556
if (lwip.arena[i].in_use
5657
&& lwip.arena[i].conn == nc
@@ -59,7 +60,7 @@ void LWIP::socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len)
5960
}
6061
}
6162

62-
sys_arch_unprotect(prot);
63+
lwip.adaptation.unlock();
6364
}
6465

6566
#if !LWIP_IPV4 || !LWIP_IPV6
@@ -149,6 +150,7 @@ void LWIP::tcpip_init_irq(void *eh)
149150
{
150151
LWIP *lwip = static_cast<LWIP *>(eh);
151152
lwip->tcpip_inited.release();
153+
sys_tcpip_thread_set();
152154
}
153155

154156
/* LWIP network stack implementation */
@@ -173,80 +175,85 @@ LWIP::LWIP()
173175
arena_init();
174176
}
175177

176-
nsapi_error_t LWIP::gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version)
178+
nsapi_error_t LWIP::get_dns_server(int index, SocketAddress *address)
177179
{
178-
ip_addr_t lwip_addr;
179-
180-
#if LWIP_IPV4 && LWIP_IPV6
181-
u8_t addr_type;
182-
if (version == NSAPI_UNSPEC) {
183-
const ip_addr_t *ip_addr = NULL;
184-
if (default_interface) {
185-
ip_addr = get_ip_addr(true, &default_interface->netif);
186-
}
187-
// Prefer IPv6
188-
if (IP_IS_V6(ip_addr)) {
189-
// If IPv4 is available use it as backup
190-
if (get_ipv4_addr(&default_interface->netif)) {
191-
addr_type = NETCONN_DNS_IPV6_IPV4;
192-
} else {
193-
addr_type = NETCONN_DNS_IPV6;
194-
}
195-
// Prefer IPv4
196-
} else {
197-
// If IPv6 is available use it as backup
198-
if (get_ipv6_addr(&default_interface->netif)) {
199-
addr_type = NETCONN_DNS_IPV4_IPV6;
200-
} else {
201-
addr_type = NETCONN_DNS_IPV4;
180+
int dns_entries = 0;
181+
182+
for (int i = 0; i < DNS_MAX_SERVERS; i++) {
183+
const ip_addr_t *ip_addr = dns_getserver(i);
184+
if (!ip_addr_isany(ip_addr)) {
185+
if (index == dns_entries) {
186+
nsapi_addr_t addr;
187+
convert_lwip_addr_to_mbed(&addr, ip_addr);
188+
address->set_addr(addr);
189+
return NSAPI_ERROR_OK;
202190
}
191+
dns_entries++;
203192
}
204-
} else if (version == NSAPI_IPv4) {
205-
addr_type = NETCONN_DNS_IPV4;
206-
} else if (version == NSAPI_IPv6) {
207-
addr_type = NETCONN_DNS_IPV6;
208-
} else {
209-
return NSAPI_ERROR_DNS_FAILURE;
210193
}
211-
err_t err = netconn_gethostbyname_addrtype(host, &lwip_addr, addr_type);
212-
#elif LWIP_IPV4
213-
if (version != NSAPI_IPv4 && version != NSAPI_UNSPEC) {
214-
return NSAPI_ERROR_DNS_FAILURE;
194+
return NSAPI_ERROR_NO_ADDRESS;
195+
}
196+
197+
void LWIP::tcpip_thread_callback(void *ptr)
198+
{
199+
lwip_callback *cb = static_cast<lwip_callback *>(ptr);
200+
201+
if (cb->delay) {
202+
sys_timeout(cb->delay, LWIP::tcpip_thread_callback, ptr);
203+
cb->delay = 0;
204+
} else {
205+
cb->callback();
206+
delete cb;
215207
}
216-
err_t err = netconn_gethostbyname(host, &lwip_addr);
217-
#elif LWIP_IPV6
218-
if (version != NSAPI_IPv6 && version != NSAPI_UNSPEC) {
219-
return NSAPI_ERROR_DNS_FAILURE;
208+
}
209+
210+
nsapi_error_t LWIP::call_in(int delay, mbed::Callback<void()> func)
211+
{
212+
lwip_callback *cb = new lwip_callback;
213+
if (!cb) {
214+
return NSAPI_ERROR_NO_MEMORY;
220215
}
221-
err_t err = netconn_gethostbyname(host, &lwip_addr);
222-
#endif
223216

224-
if (err != ERR_OK) {
225-
return NSAPI_ERROR_DNS_FAILURE;
217+
cb->delay = delay;
218+
cb->callback = func;
219+
220+
if (tcpip_callback_with_block(LWIP::tcpip_thread_callback, cb, 1) != ERR_OK) {
221+
return NSAPI_ERROR_NO_MEMORY;
226222
}
227223

228-
nsapi_addr_t addr;
229-
convert_lwip_addr_to_mbed(&addr, &lwip_addr);
230-
address->set_addr(addr);
224+
return NSAPI_ERROR_OK;
225+
}
231226

232-
return 0;
227+
LWIP::call_in_callback_cb_t LWIP::get_call_in_callback()
228+
{
229+
call_in_callback_cb_t cb(this, &LWIP::call_in);
230+
return cb;
233231
}
234232

235-
nsapi_error_t LWIP::add_dns_server(const SocketAddress &address)
233+
const char *LWIP::get_ip_address()
236234
{
237-
// Shift all dns servers down to give precedence to new server
238-
for (int i = DNS_MAX_SERVERS-1; i > 0; i--) {
239-
dns_setserver(i, dns_getserver(i-1));
235+
if (!default_interface) {
236+
return NULL;
240237
}
241238

242-
nsapi_addr_t addr = address.get_addr();
243-
ip_addr_t ip_addr;
244-
if (!convert_mbed_addr_to_lwip(&ip_addr, &addr)) {
245-
return NSAPI_ERROR_PARAMETER;
246-
}
239+
const ip_addr_t *addr = get_ip_addr(true, &default_interface->netif);
247240

248-
dns_setserver(0, &ip_addr);
249-
return 0;
241+
if (!addr) {
242+
return NULL;
243+
}
244+
#if LWIP_IPV6
245+
if (IP_IS_V6(addr)) {
246+
return ip6addr_ntoa_r(ip_2_ip6(addr), ip_address, sizeof(ip_address));
247+
}
248+
#endif
249+
#if LWIP_IPV4
250+
if (IP_IS_V4(addr)) {
251+
return ip4addr_ntoa_r(ip_2_ip4(addr), ip_address, sizeof(ip_address));
252+
}
253+
#endif
254+
#if LWIP_IPV6 && LWIP_IPV4
255+
return NULL;
256+
#endif
250257
}
251258

252259
nsapi_error_t LWIP::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
@@ -439,6 +446,7 @@ nsapi_size_or_error_t LWIP::socket_sendto(nsapi_socket_t handle, const SocketAdd
439446
}
440447

441448
struct netbuf *buf = netbuf_new();
449+
442450
err_t err = netbuf_ref(buf, data, (u16_t)size);
443451
if (err != ERR_OK) {
444452
netbuf_free(buf);
@@ -588,7 +596,7 @@ nsapi_error_t LWIP::setsockopt(nsapi_socket_t handle, int level, int optname, co
588596

589597
member_pair_index = next_free_multicast_member(s, 0);
590598

591-
sys_prot_t prot = sys_arch_protect();
599+
adaptation.lock();
592600

593601
#if LWIP_IPV4
594602
if (IP_IS_V4(&if_addr)) {
@@ -601,7 +609,7 @@ nsapi_error_t LWIP::setsockopt(nsapi_socket_t handle, int level, int optname, co
601609
}
602610
#endif
603611

604-
sys_arch_unprotect(prot);
612+
adaptation.unlock();
605613

606614
if (igmp_err == ERR_OK) {
607615
set_multicast_member_registry_bit(s, member_pair_index);
@@ -616,7 +624,7 @@ nsapi_error_t LWIP::setsockopt(nsapi_socket_t handle, int level, int optname, co
616624
clear_multicast_member_registry_bit(s, member_pair_index);
617625
s->multicast_memberships_count--;
618626

619-
sys_prot_t prot = sys_arch_protect();
627+
adaptation.lock();
620628

621629
#if LWIP_IPV4
622630
if (IP_IS_V4(&if_addr)) {
@@ -629,7 +637,7 @@ nsapi_error_t LWIP::setsockopt(nsapi_socket_t handle, int level, int optname, co
629637
}
630638
#endif
631639

632-
sys_arch_unprotect(prot);
640+
adaptation.unlock();
633641
}
634642

635643
return err_remap(igmp_err);

features/FEATURE_LWIP/lwip-interface/LWIPStack.h

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -198,29 +198,23 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable<LWIP> {
198198
*/
199199
nsapi_error_t _add_ppp_interface(void *pcb, bool default_if, LWIP::Interface **interface_out);
200200

201-
/** Translates a hostname to an IP address with specific version
201+
/** Get a domain name server from a list of servers to query
202202
*
203-
* The hostname may be either a domain name or an IP address. If the
204-
* hostname is an IP address, no network transactions will be performed.
203+
* Returns a DNS server address for a index. If returns error no more
204+
* DNS servers to read.
205205
*
206-
* If no stack-specific DNS resolution is provided, the hostname
207-
* will be resolve using a UDP socket on the stack.
208-
*
209-
* @param host Hostname to resolve
210-
* @param address Destination for the host SocketAddress
211-
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
212-
* version is chosen by the stack (defaults to NSAPI_UNSPEC)
206+
* @param index Index of the DNS server, starts from zero
207+
* @param address Destination for the host address
213208
* @return 0 on success, negative error code on failure
214209
*/
215-
virtual nsapi_error_t gethostbyname(const char *host,
216-
SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC);
210+
virtual nsapi_error_t get_dns_server(int index, SocketAddress *address);
217211

218-
/** Add a domain name server to list of servers to query
212+
/** Get the local IP address
219213
*
220-
* @param address Destination for the host address
221-
* @return 0 on success, negative error code on failure
214+
* @return Null-terminated representation of the local IP address
215+
* or null if not yet connected
222216
*/
223-
virtual nsapi_error_t add_dns_server(const SocketAddress &address);
217+
virtual const char *get_ip_address();
224218

225219
protected:
226220
LWIP();
@@ -423,6 +417,37 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable<LWIP> {
423417
int optname, void *optval, unsigned *optlen);
424418
private:
425419

420+
/** Call in callback
421+
*
422+
* Callback is used to call the call in method of the network stack.
423+
*/
424+
typedef mbed::Callback<nsapi_error_t (int delay_ms, mbed::Callback<void()> user_cb)> call_in_callback_cb_t;
425+
426+
/** Get a call in callback
427+
*
428+
* Get a call in callback from the network stack context.
429+
*
430+
* Callback should not take more than 10ms to execute, otherwise it might
431+
* prevent underlying thread processing. A portable user of the callback
432+
* should not make calls to network operations due to stack size limitations.
433+
* The callback should not perform expensive operations such as socket recv/send
434+
* calls or blocking operations.
435+
*
436+
* @return Call in callback
437+
*/
438+
virtual call_in_callback_cb_t get_call_in_callback();
439+
440+
/** Call a callback after a delay
441+
*
442+
* Call a callback from the network stack context after a delay. If function
443+
* returns error callback will not be called.
444+
*
445+
* @param delay Delay in milliseconds
446+
* @param func Callback to be called
447+
* @return 0 on success, negative error code on failure
448+
*/
449+
nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
450+
426451
struct mbed_lwip_socket {
427452
bool in_use;
428453

@@ -439,6 +464,11 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable<LWIP> {
439464
uint32_t multicast_memberships_registry;
440465
};
441466

467+
struct lwip_callback {
468+
unsigned int delay;
469+
mbed::Callback<void()> callback;
470+
};
471+
442472
static nsapi_error_t err_remap(err_t err);
443473
static bool is_local_addr(const ip_addr_t *ip_addr);
444474
static const ip_addr_t *get_ip_addr(bool any_addr, const struct netif *netif);
@@ -475,9 +505,14 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable<LWIP> {
475505
static void socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len);
476506

477507
static void tcpip_init_irq(void *handle);
508+
static void tcpip_thread_callback(void *ptr);
509+
510+
char ip_address[40];
478511
rtos::Semaphore tcpip_inited;
479512
Interface *default_interface;
480513
LWIPMemoryManager memory_manager;
514+
osThreadId tcpip_thread_id;
515+
rtos::Mutex adaptation;
481516
};
482517

483518
#endif /* LWIPSTACK_H_ */

features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NUVOTON/TARGET_M480/lwipopts_conf.h

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)