User | Revision | Line number | New contents of line |
kevman |
0:38ceb79fef03
|
1
|
/* LWIP common helpers
|
kevman |
0:38ceb79fef03
|
2
|
* Copyright (c) 2017 ARM Limited
|
kevman |
0:38ceb79fef03
|
3
|
*
|
kevman |
0:38ceb79fef03
|
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
kevman |
0:38ceb79fef03
|
5
|
* you may not use this file except in compliance with the License.
|
kevman |
0:38ceb79fef03
|
6
|
* You may obtain a copy of the License at
|
kevman |
0:38ceb79fef03
|
7
|
*
|
kevman |
0:38ceb79fef03
|
8
|
* http://www.apache.org/licenses/LICENSE-2.0
|
kevman |
0:38ceb79fef03
|
9
|
*
|
kevman |
0:38ceb79fef03
|
10
|
* Unless required by applicable law or agreed to in writing, software
|
kevman |
0:38ceb79fef03
|
11
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
kevman |
0:38ceb79fef03
|
12
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
kevman |
0:38ceb79fef03
|
13
|
* See the License for the specific language governing permissions and
|
kevman |
0:38ceb79fef03
|
14
|
* limitations under the License.
|
kevman |
0:38ceb79fef03
|
15
|
*/
|
kevman |
0:38ceb79fef03
|
16
|
|
kevman |
0:38ceb79fef03
|
17
|
#include <stdbool.h>
|
kevman |
0:38ceb79fef03
|
18
|
#include <string.h>
|
kevman |
0:38ceb79fef03
|
19
|
|
kevman |
0:38ceb79fef03
|
20
|
#include "lwip/opt.h"
|
kevman |
0:38ceb79fef03
|
21
|
#include "lwip/netif.h"
|
kevman |
0:38ceb79fef03
|
22
|
#include "lwip/ip.h"
|
kevman |
0:38ceb79fef03
|
23
|
#include "lwip/api.h"
|
kevman |
0:38ceb79fef03
|
24
|
|
kevman |
0:38ceb79fef03
|
25
|
#include "LWIPStack.h"
|
kevman |
0:38ceb79fef03
|
26
|
|
kevman |
0:38ceb79fef03
|
27
|
#include "netsocket/nsapi_types.h"
|
kevman |
0:38ceb79fef03
|
28
|
|
kevman |
0:38ceb79fef03
|
29
|
/* LWIP error remapping */
|
kevman |
0:38ceb79fef03
|
30
|
nsapi_error_t LWIP::err_remap(err_t err) {
|
kevman |
0:38ceb79fef03
|
31
|
switch (err) {
|
kevman |
0:38ceb79fef03
|
32
|
case ERR_OK:
|
kevman |
0:38ceb79fef03
|
33
|
case ERR_CLSD:
|
kevman |
0:38ceb79fef03
|
34
|
return 0;
|
kevman |
0:38ceb79fef03
|
35
|
case ERR_MEM:
|
kevman |
0:38ceb79fef03
|
36
|
case ERR_BUF:
|
kevman |
0:38ceb79fef03
|
37
|
return NSAPI_ERROR_NO_MEMORY;
|
kevman |
0:38ceb79fef03
|
38
|
case ERR_CONN:
|
kevman |
0:38ceb79fef03
|
39
|
case ERR_RST:
|
kevman |
0:38ceb79fef03
|
40
|
case ERR_ABRT:
|
kevman |
0:38ceb79fef03
|
41
|
return NSAPI_ERROR_NO_CONNECTION;
|
kevman |
0:38ceb79fef03
|
42
|
case ERR_TIMEOUT:
|
kevman |
0:38ceb79fef03
|
43
|
case ERR_RTE:
|
kevman |
0:38ceb79fef03
|
44
|
case ERR_WOULDBLOCK:
|
kevman |
0:38ceb79fef03
|
45
|
return NSAPI_ERROR_WOULD_BLOCK;
|
kevman |
0:38ceb79fef03
|
46
|
case ERR_VAL:
|
kevman |
0:38ceb79fef03
|
47
|
case ERR_USE:
|
kevman |
0:38ceb79fef03
|
48
|
case ERR_ARG:
|
kevman |
0:38ceb79fef03
|
49
|
return NSAPI_ERROR_PARAMETER;
|
kevman |
0:38ceb79fef03
|
50
|
case ERR_INPROGRESS:
|
kevman |
0:38ceb79fef03
|
51
|
return NSAPI_ERROR_IN_PROGRESS;
|
kevman |
0:38ceb79fef03
|
52
|
case ERR_ALREADY:
|
kevman |
0:38ceb79fef03
|
53
|
return NSAPI_ERROR_ALREADY;
|
kevman |
0:38ceb79fef03
|
54
|
case ERR_ISCONN:
|
kevman |
0:38ceb79fef03
|
55
|
return NSAPI_ERROR_IS_CONNECTED;
|
kevman |
0:38ceb79fef03
|
56
|
default:
|
kevman |
0:38ceb79fef03
|
57
|
return NSAPI_ERROR_DEVICE_ERROR;
|
kevman |
0:38ceb79fef03
|
58
|
}
|
kevman |
0:38ceb79fef03
|
59
|
}
|
kevman |
0:38ceb79fef03
|
60
|
|
kevman |
0:38ceb79fef03
|
61
|
#if LWIP_IPV4
|
kevman |
0:38ceb79fef03
|
62
|
const ip_addr_t *LWIP::get_ipv4_addr(const struct netif *netif)
|
kevman |
0:38ceb79fef03
|
63
|
{
|
kevman |
0:38ceb79fef03
|
64
|
if (!netif_is_up(netif)) {
|
kevman |
0:38ceb79fef03
|
65
|
return NULL;
|
kevman |
0:38ceb79fef03
|
66
|
}
|
kevman |
0:38ceb79fef03
|
67
|
|
kevman |
0:38ceb79fef03
|
68
|
if (!ip4_addr_isany(netif_ip4_addr(netif))) {
|
kevman |
0:38ceb79fef03
|
69
|
return netif_ip_addr4(netif);
|
kevman |
0:38ceb79fef03
|
70
|
}
|
kevman |
0:38ceb79fef03
|
71
|
|
kevman |
0:38ceb79fef03
|
72
|
return NULL;
|
kevman |
0:38ceb79fef03
|
73
|
}
|
kevman |
0:38ceb79fef03
|
74
|
#endif
|
kevman |
0:38ceb79fef03
|
75
|
|
kevman |
0:38ceb79fef03
|
76
|
#if LWIP_IPV6
|
kevman |
0:38ceb79fef03
|
77
|
const ip_addr_t *LWIP::get_ipv6_addr(const struct netif *netif)
|
kevman |
0:38ceb79fef03
|
78
|
{
|
kevman |
0:38ceb79fef03
|
79
|
if (!netif_is_up(netif)) {
|
kevman |
0:38ceb79fef03
|
80
|
return NULL;
|
kevman |
0:38ceb79fef03
|
81
|
}
|
kevman |
0:38ceb79fef03
|
82
|
|
kevman |
0:38ceb79fef03
|
83
|
for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
|
kevman |
0:38ceb79fef03
|
84
|
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
|
kevman |
0:38ceb79fef03
|
85
|
!ip6_addr_islinklocal(netif_ip6_addr(netif, i))) {
|
kevman |
0:38ceb79fef03
|
86
|
return netif_ip_addr6(netif, i);
|
kevman |
0:38ceb79fef03
|
87
|
}
|
kevman |
0:38ceb79fef03
|
88
|
}
|
kevman |
0:38ceb79fef03
|
89
|
|
kevman |
0:38ceb79fef03
|
90
|
return NULL;
|
kevman |
0:38ceb79fef03
|
91
|
}
|
kevman |
0:38ceb79fef03
|
92
|
#endif
|
kevman |
0:38ceb79fef03
|
93
|
|
kevman |
0:38ceb79fef03
|
94
|
bool LWIP::is_local_addr(const ip_addr_t *ip_addr)
|
kevman |
0:38ceb79fef03
|
95
|
{
|
kevman |
0:38ceb79fef03
|
96
|
struct netif *netif;
|
kevman |
0:38ceb79fef03
|
97
|
|
kevman |
0:38ceb79fef03
|
98
|
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
kevman |
0:38ceb79fef03
|
99
|
if (!netif_is_up(netif)) {
|
kevman |
0:38ceb79fef03
|
100
|
continue;
|
kevman |
0:38ceb79fef03
|
101
|
}
|
kevman |
0:38ceb79fef03
|
102
|
#if LWIP_IPV6
|
kevman |
0:38ceb79fef03
|
103
|
if (IP_IS_V6(ip_addr)) {
|
kevman |
0:38ceb79fef03
|
104
|
for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
|
kevman |
0:38ceb79fef03
|
105
|
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
|
kevman |
0:38ceb79fef03
|
106
|
ip6_addr_cmp(netif_ip6_addr(netif, i), ip_2_ip6(ip_addr))) {
|
kevman |
0:38ceb79fef03
|
107
|
return true;
|
kevman |
0:38ceb79fef03
|
108
|
}
|
kevman |
0:38ceb79fef03
|
109
|
}
|
kevman |
0:38ceb79fef03
|
110
|
}
|
kevman |
0:38ceb79fef03
|
111
|
#endif
|
kevman |
0:38ceb79fef03
|
112
|
|
kevman |
0:38ceb79fef03
|
113
|
#if LWIP_IPV4
|
kevman |
0:38ceb79fef03
|
114
|
if (IP_IS_V4(ip_addr)) {
|
kevman |
0:38ceb79fef03
|
115
|
if (!ip4_addr_isany(netif_ip4_addr(netif)) &&
|
kevman |
0:38ceb79fef03
|
116
|
ip4_addr_cmp(netif_ip4_addr(netif), ip_2_ip4(ip_addr))) {
|
kevman |
0:38ceb79fef03
|
117
|
return true;
|
kevman |
0:38ceb79fef03
|
118
|
}
|
kevman |
0:38ceb79fef03
|
119
|
}
|
kevman |
0:38ceb79fef03
|
120
|
#endif
|
kevman |
0:38ceb79fef03
|
121
|
}
|
kevman |
0:38ceb79fef03
|
122
|
return false;
|
kevman |
0:38ceb79fef03
|
123
|
}
|
kevman |
0:38ceb79fef03
|
124
|
|
kevman |
0:38ceb79fef03
|
125
|
const ip_addr_t *LWIP::get_ip_addr(bool any_addr, const struct netif *netif)
|
kevman |
0:38ceb79fef03
|
126
|
{
|
kevman |
0:38ceb79fef03
|
127
|
const ip_addr_t *pref_ip_addr = 0;
|
kevman |
0:38ceb79fef03
|
128
|
const ip_addr_t *npref_ip_addr = 0;
|
kevman |
0:38ceb79fef03
|
129
|
|
kevman |
0:38ceb79fef03
|
130
|
#if LWIP_IPV4 && LWIP_IPV6
|
kevman |
0:38ceb79fef03
|
131
|
#if IP_VERSION_PREF == PREF_IPV4
|
kevman |
0:38ceb79fef03
|
132
|
pref_ip_addr = get_ipv4_addr(netif);
|
kevman |
0:38ceb79fef03
|
133
|
npref_ip_addr = get_ipv6_addr(netif);
|
kevman |
0:38ceb79fef03
|
134
|
#else
|
kevman |
0:38ceb79fef03
|
135
|
pref_ip_addr = get_ipv6_addr(netif);
|
kevman |
0:38ceb79fef03
|
136
|
npref_ip_addr = get_ipv4_addr(netif);
|
kevman |
0:38ceb79fef03
|
137
|
#endif
|
kevman |
0:38ceb79fef03
|
138
|
#elif LWIP_IPV6
|
kevman |
0:38ceb79fef03
|
139
|
pref_ip_addr = get_ipv6_addr(netif);
|
kevman |
0:38ceb79fef03
|
140
|
#elif LWIP_IPV4
|
kevman |
0:38ceb79fef03
|
141
|
pref_ip_addr = get_ipv4_addr(netif);
|
kevman |
0:38ceb79fef03
|
142
|
#endif
|
kevman |
0:38ceb79fef03
|
143
|
|
kevman |
0:38ceb79fef03
|
144
|
if (pref_ip_addr) {
|
kevman |
0:38ceb79fef03
|
145
|
return pref_ip_addr;
|
kevman |
0:38ceb79fef03
|
146
|
} else if (npref_ip_addr && any_addr) {
|
kevman |
0:38ceb79fef03
|
147
|
return npref_ip_addr;
|
kevman |
0:38ceb79fef03
|
148
|
}
|
kevman |
0:38ceb79fef03
|
149
|
|
kevman |
0:38ceb79fef03
|
150
|
return NULL;
|
kevman |
0:38ceb79fef03
|
151
|
}
|
kevman |
0:38ceb79fef03
|
152
|
|
kevman |
0:38ceb79fef03
|
153
|
void LWIP::arena_init(void)
|
kevman |
0:38ceb79fef03
|
154
|
{
|
kevman |
0:38ceb79fef03
|
155
|
memset(arena, 0, sizeof(arena));
|
kevman |
0:38ceb79fef03
|
156
|
}
|
kevman |
0:38ceb79fef03
|
157
|
|
kevman |
0:38ceb79fef03
|
158
|
struct LWIP::mbed_lwip_socket *LWIP::arena_alloc()
|
kevman |
0:38ceb79fef03
|
159
|
{
|
kevman |
0:38ceb79fef03
|
160
|
LWIP &lwip = LWIP::get_instance();
|
kevman |
0:38ceb79fef03
|
161
|
|
kevman |
0:38ceb79fef03
|
162
|
lwip.adaptation.lock();
|
kevman |
0:38ceb79fef03
|
163
|
|
kevman |
0:38ceb79fef03
|
164
|
for (int i = 0; i < MEMP_NUM_NETCONN; i++) {
|
kevman |
0:38ceb79fef03
|
165
|
if (!arena[i].in_use) {
|
kevman |
0:38ceb79fef03
|
166
|
struct mbed_lwip_socket *s = &arena[i];
|
kevman |
0:38ceb79fef03
|
167
|
memset(s, 0, sizeof(*s));
|
kevman |
0:38ceb79fef03
|
168
|
s->in_use = true;
|
kevman |
0:38ceb79fef03
|
169
|
lwip.adaptation.unlock();
|
kevman |
0:38ceb79fef03
|
170
|
return s;
|
kevman |
0:38ceb79fef03
|
171
|
}
|
kevman |
0:38ceb79fef03
|
172
|
}
|
kevman |
0:38ceb79fef03
|
173
|
|
kevman |
0:38ceb79fef03
|
174
|
lwip.adaptation.unlock();
|
kevman |
0:38ceb79fef03
|
175
|
|
kevman |
0:38ceb79fef03
|
176
|
return 0;
|
kevman |
0:38ceb79fef03
|
177
|
}
|
kevman |
0:38ceb79fef03
|
178
|
|
kevman |
0:38ceb79fef03
|
179
|
void LWIP::arena_dealloc(struct mbed_lwip_socket *s)
|
kevman |
0:38ceb79fef03
|
180
|
{
|
kevman |
0:38ceb79fef03
|
181
|
s->in_use = false;
|
kevman |
0:38ceb79fef03
|
182
|
|
kevman |
0:38ceb79fef03
|
183
|
while (s->multicast_memberships_count > 0) {
|
kevman |
0:38ceb79fef03
|
184
|
uint32_t index = 0;
|
kevman |
0:38ceb79fef03
|
185
|
index = next_registered_multicast_member(s, index);
|
kevman |
0:38ceb79fef03
|
186
|
|
kevman |
0:38ceb79fef03
|
187
|
setsockopt(s, NSAPI_SOCKET, NSAPI_DROP_MEMBERSHIP, &s->multicast_memberships[index],
|
kevman |
0:38ceb79fef03
|
188
|
sizeof(s->multicast_memberships[index]));
|
kevman |
0:38ceb79fef03
|
189
|
index++;
|
kevman |
0:38ceb79fef03
|
190
|
}
|
kevman |
0:38ceb79fef03
|
191
|
|
kevman |
0:38ceb79fef03
|
192
|
free(s->multicast_memberships);
|
kevman |
0:38ceb79fef03
|
193
|
s->multicast_memberships = NULL;
|
kevman |
0:38ceb79fef03
|
194
|
}
|