diff options
Diffstat (limited to 'lib/chibios/os/various/lwip_bindings/lwipthread.c')
-rw-r--r-- | lib/chibios/os/various/lwip_bindings/lwipthread.c | 530 |
1 files changed, 530 insertions, 0 deletions
diff --git a/lib/chibios/os/various/lwip_bindings/lwipthread.c b/lib/chibios/os/various/lwip_bindings/lwipthread.c new file mode 100644 index 000000000..0260ae61b --- /dev/null +++ b/lib/chibios/os/various/lwip_bindings/lwipthread.c | |||
@@ -0,0 +1,530 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | /* | ||
17 | * **** This file incorporates work covered by the following copyright and **** | ||
18 | * **** permission notice: **** | ||
19 | * | ||
20 | * Copyright (c) 2001-2004 Swedish Institute of Computer Science. | ||
21 | * All rights reserved. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without modification, | ||
24 | * are permitted provided that the following conditions are met: | ||
25 | * | ||
26 | * 1. Redistributions of source code must retain the above copyright notice, | ||
27 | * this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
29 | * this list of conditions and the following disclaimer in the documentation | ||
30 | * and/or other materials provided with the distribution. | ||
31 | * 3. The name of the author may not be used to endorse or promote products | ||
32 | * derived from this software without specific prior written permission. | ||
33 | * | ||
34 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
35 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
36 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT | ||
37 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
38 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT | ||
39 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
40 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
41 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
42 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY | ||
43 | * OF SUCH DAMAGE. | ||
44 | * | ||
45 | * This file is part of the lwIP TCP/IP stack. | ||
46 | * | ||
47 | * Author: Adam Dunkels <[email protected]> | ||
48 | * | ||
49 | */ | ||
50 | |||
51 | /** | ||
52 | * @file lwipthread.c | ||
53 | * @brief LWIP wrapper thread code. | ||
54 | * @addtogroup LWIP_THREAD | ||
55 | * @{ | ||
56 | */ | ||
57 | |||
58 | #include "hal.h" | ||
59 | #include "evtimer.h" | ||
60 | |||
61 | #include "lwipthread.h" | ||
62 | |||
63 | #include <lwip/opt.h> | ||
64 | #include <lwip/def.h> | ||
65 | #include <lwip/mem.h> | ||
66 | #include <lwip/pbuf.h> | ||
67 | #include <lwip/sys.h> | ||
68 | #include <lwip/stats.h> | ||
69 | #include <lwip/snmp.h> | ||
70 | #include <lwip/tcpip.h> | ||
71 | #include <netif/etharp.h> | ||
72 | #include <lwip/netifapi.h> | ||
73 | |||
74 | #if LWIP_DHCP | ||
75 | #include <lwip/dhcp.h> | ||
76 | #endif | ||
77 | |||
78 | #if LWIP_AUTOIP | ||
79 | #include <lwip/autoip.h> | ||
80 | #endif | ||
81 | |||
82 | #define PERIODIC_TIMER_ID 1 | ||
83 | #define FRAME_RECEIVED_ID 2 | ||
84 | |||
85 | /* | ||
86 | * Suspension point for initialization procedure. | ||
87 | */ | ||
88 | thread_reference_t lwip_trp = NULL; | ||
89 | |||
90 | /* | ||
91 | * Stack area for the LWIP-MAC thread. | ||
92 | */ | ||
93 | static THD_WORKING_AREA(wa_lwip_thread, LWIP_THREAD_STACK_SIZE); | ||
94 | |||
95 | /* | ||
96 | * Initialization. | ||
97 | */ | ||
98 | static void low_level_init(struct netif *netif) { | ||
99 | /* set MAC hardware address length */ | ||
100 | netif->hwaddr_len = ETHARP_HWADDR_LEN; | ||
101 | |||
102 | /* maximum transfer unit */ | ||
103 | netif->mtu = LWIP_NETIF_MTU; | ||
104 | |||
105 | /* device capabilities */ | ||
106 | /* don't set NETIF_FLAG_ETHARP if this device is not an Ethernet one */ | ||
107 | netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; | ||
108 | |||
109 | /* Do whatever else is needed to initialize interface. */ | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * This function does the actual transmission of the packet. The packet is | ||
114 | * contained in the pbuf that is passed to the function. This pbuf | ||
115 | * might be chained. | ||
116 | * | ||
117 | * @param netif the lwip network interface structure for this ethernetif | ||
118 | * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) | ||
119 | * @return ERR_OK if the packet could be sent | ||
120 | * an err_t value if the packet couldn't be sent | ||
121 | * | ||
122 | * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to | ||
123 | * strange results. You might consider waiting for space in the DMA queue | ||
124 | * to become available since the stack doesn't retry to send a packet | ||
125 | * dropped because of memory failure (except for the TCP timers). | ||
126 | */ | ||
127 | static err_t low_level_output(struct netif *netif, struct pbuf *p) { | ||
128 | struct pbuf *q; | ||
129 | MACTransmitDescriptor td; | ||
130 | |||
131 | (void)netif; | ||
132 | if (macWaitTransmitDescriptor(ÐD1, &td, TIME_MS2I(LWIP_SEND_TIMEOUT)) != MSG_OK) | ||
133 | return ERR_TIMEOUT; | ||
134 | |||
135 | #if ETH_PAD_SIZE | ||
136 | pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ | ||
137 | #endif | ||
138 | |||
139 | /* Iterates through the pbuf chain. */ | ||
140 | for(q = p; q != NULL; q = q->next) | ||
141 | macWriteTransmitDescriptor(&td, (uint8_t *)q->payload, (size_t)q->len); | ||
142 | macReleaseTransmitDescriptor(&td); | ||
143 | |||
144 | MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); | ||
145 | if (((u8_t*)p->payload)[0] & 1) { | ||
146 | /* broadcast or multicast packet*/ | ||
147 | MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); | ||
148 | } | ||
149 | else { | ||
150 | /* unicast packet */ | ||
151 | MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); | ||
152 | } | ||
153 | /* increase ifoutdiscards or ifouterrors on error */ | ||
154 | |||
155 | #if ETH_PAD_SIZE | ||
156 | pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ | ||
157 | #endif | ||
158 | |||
159 | LINK_STATS_INC(link.xmit); | ||
160 | |||
161 | return ERR_OK; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * Receives a frame. | ||
166 | * Allocates a pbuf and transfers the bytes of the incoming | ||
167 | * packet from the interface into the pbuf. | ||
168 | * | ||
169 | * @param netif the lwip network interface structure for this ethernetif | ||
170 | * @return a pbuf filled with the received packet (including MAC header) | ||
171 | * NULL on memory error | ||
172 | */ | ||
173 | static bool low_level_input(struct netif *netif, struct pbuf **pbuf) { | ||
174 | MACReceiveDescriptor rd; | ||
175 | struct pbuf *q; | ||
176 | u16_t len; | ||
177 | |||
178 | (void)netif; | ||
179 | |||
180 | osalDbgAssert(pbuf != NULL, "invalid null pointer"); | ||
181 | |||
182 | if (macWaitReceiveDescriptor(ÐD1, &rd, TIME_IMMEDIATE) != MSG_OK) | ||
183 | return false; | ||
184 | |||
185 | len = (u16_t)rd.size; | ||
186 | |||
187 | #if ETH_PAD_SIZE | ||
188 | len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ | ||
189 | #endif | ||
190 | |||
191 | /* We allocate a pbuf chain of pbufs from the pool. */ | ||
192 | *pbuf = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); | ||
193 | |||
194 | if (*pbuf != NULL) { | ||
195 | #if ETH_PAD_SIZE | ||
196 | pbuf_header(*pbuf, -ETH_PAD_SIZE); /* drop the padding word */ | ||
197 | #endif | ||
198 | |||
199 | /* Iterates through the pbuf chain. */ | ||
200 | for(q = *pbuf; q != NULL; q = q->next) | ||
201 | macReadReceiveDescriptor(&rd, (uint8_t *)q->payload, (size_t)q->len); | ||
202 | macReleaseReceiveDescriptor(&rd); | ||
203 | |||
204 | MIB2_STATS_NETIF_ADD(netif, ifinoctets, (*pbuf)->tot_len); | ||
205 | |||
206 | if (*(uint8_t *)((*pbuf)->payload) & 1) { | ||
207 | /* broadcast or multicast packet*/ | ||
208 | MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); | ||
209 | } | ||
210 | else { | ||
211 | /* unicast packet*/ | ||
212 | MIB2_STATS_NETIF_INC(netif, ifinucastpkts); | ||
213 | } | ||
214 | |||
215 | #if ETH_PAD_SIZE | ||
216 | pbuf_header(*pbuf, ETH_PAD_SIZE); /* reclaim the padding word */ | ||
217 | #endif | ||
218 | |||
219 | LINK_STATS_INC(link.recv); | ||
220 | } | ||
221 | else { | ||
222 | macReleaseReceiveDescriptor(&rd); // Drop packet | ||
223 | LINK_STATS_INC(link.memerr); | ||
224 | LINK_STATS_INC(link.drop); | ||
225 | MIB2_STATS_NETIF_INC(netif, ifindiscards); | ||
226 | } | ||
227 | |||
228 | return true; | ||
229 | } | ||
230 | |||
231 | /* | ||
232 | * Called at the beginning of the program to set up the | ||
233 | * network interface. It calls the function low_level_init() to do the | ||
234 | * actual setup of the hardware. | ||
235 | * | ||
236 | * This function should be passed as a parameter to netifapi_netif_add(). | ||
237 | * | ||
238 | * @param netif the lwip network interface structure for this ethernetif | ||
239 | * @return ERR_OK if the loopif is initialised | ||
240 | * ERR_MEM if private data couldn't be allocated | ||
241 | * any other err_t on error | ||
242 | */ | ||
243 | static err_t ethernetif_init(struct netif *netif) { | ||
244 | osalDbgAssert((netif != NULL), "netif != NULL"); | ||
245 | |||
246 | /* | ||
247 | * Initialize the snmp variables and counters inside the struct netif. | ||
248 | * The last argument should be replaced with your link speed, in units | ||
249 | * of bits per second. | ||
250 | */ | ||
251 | MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LWIP_LINK_SPEED); | ||
252 | |||
253 | netif->state = NULL; | ||
254 | netif->name[0] = LWIP_IFNAME0; | ||
255 | netif->name[1] = LWIP_IFNAME1; | ||
256 | /* We directly use etharp_output() here to save a function call. | ||
257 | * You can instead declare your own function an call etharp_output() | ||
258 | * from it if you have to do some checks before sending (e.g. if link | ||
259 | * is available...) */ | ||
260 | netif->output = etharp_output; | ||
261 | netif->linkoutput = low_level_output; | ||
262 | |||
263 | /* initialize the hardware */ | ||
264 | low_level_init(netif); | ||
265 | |||
266 | return ERR_OK; | ||
267 | } | ||
268 | |||
269 | static net_addr_mode_t addressMode; | ||
270 | static ip4_addr_t ip, gateway, netmask; | ||
271 | static struct netif thisif; | ||
272 | |||
273 | void lwipDefaultLinkUpCB(void *p) | ||
274 | { | ||
275 | struct netif *ifc = (struct netif*) p; | ||
276 | (void) ifc; | ||
277 | #if LWIP_AUTOIP | ||
278 | if (addressMode == NET_ADDRESS_AUTO) | ||
279 | autoip_start(ifc); | ||
280 | #endif | ||
281 | #if LWIP_DHCP | ||
282 | if (addressMode == NET_ADDRESS_DHCP) | ||
283 | dhcp_start(ifc); | ||
284 | #endif | ||
285 | } | ||
286 | |||
287 | void lwipDefaultLinkDownCB(void *p) | ||
288 | { | ||
289 | struct netif *ifc = (struct netif*) p; | ||
290 | (void) ifc; | ||
291 | #if LWIP_AUTOIP | ||
292 | if (addressMode == NET_ADDRESS_AUTO) | ||
293 | autoip_stop(ifc); | ||
294 | #endif | ||
295 | #if LWIP_DHCP | ||
296 | if (addressMode == NET_ADDRESS_DHCP) | ||
297 | dhcp_stop(ifc); | ||
298 | #endif | ||
299 | } | ||
300 | |||
301 | /** | ||
302 | * @brief LWIP handling thread. | ||
303 | * | ||
304 | * @param[in] p pointer to a @p lwipthread_opts structure or @p NULL | ||
305 | * @return The function does not return. | ||
306 | */ | ||
307 | static THD_FUNCTION(lwip_thread, p) { | ||
308 | event_timer_t evt; | ||
309 | event_listener_t el0, el1; | ||
310 | static const MACConfig mac_config = {thisif.hwaddr}; | ||
311 | err_t result; | ||
312 | tcpip_callback_fn link_up_cb = NULL; | ||
313 | tcpip_callback_fn link_down_cb = NULL; | ||
314 | |||
315 | chRegSetThreadName(LWIP_THREAD_NAME); | ||
316 | |||
317 | /* Initializes the thing.*/ | ||
318 | tcpip_init(NULL, NULL); | ||
319 | |||
320 | /* TCP/IP parameters, runtime or compile time.*/ | ||
321 | if (p) { | ||
322 | lwipthread_opts_t *opts = p; | ||
323 | unsigned i; | ||
324 | |||
325 | for (i = 0; i < 6; i++) | ||
326 | thisif.hwaddr[i] = opts->macaddress[i]; | ||
327 | ip.addr = opts->address; | ||
328 | gateway.addr = opts->gateway; | ||
329 | netmask.addr = opts->netmask; | ||
330 | addressMode = opts->addrMode; | ||
331 | #if LWIP_NETIF_HOSTNAME | ||
332 | thisif.hostname = opts->ourHostName; | ||
333 | #endif | ||
334 | link_up_cb = opts->link_up_cb; | ||
335 | link_down_cb = opts->link_down_cb; | ||
336 | } | ||
337 | else { | ||
338 | thisif.hwaddr[0] = LWIP_ETHADDR_0; | ||
339 | thisif.hwaddr[1] = LWIP_ETHADDR_1; | ||
340 | thisif.hwaddr[2] = LWIP_ETHADDR_2; | ||
341 | thisif.hwaddr[3] = LWIP_ETHADDR_3; | ||
342 | thisif.hwaddr[4] = LWIP_ETHADDR_4; | ||
343 | thisif.hwaddr[5] = LWIP_ETHADDR_5; | ||
344 | LWIP_IPADDR(&ip); | ||
345 | LWIP_GATEWAY(&gateway); | ||
346 | LWIP_NETMASK(&netmask); | ||
347 | #if LWIP_DHCP | ||
348 | addressMode = NET_ADDRESS_DHCP; | ||
349 | #elif LWIP_AUTOIP | ||
350 | addressMode = NET_ADDRESS_AUTO; | ||
351 | #else | ||
352 | addressMode = NET_ADDRESS_STATIC; | ||
353 | #endif | ||
354 | #if LWIP_NETIF_HOSTNAME | ||
355 | thisif.hostname = NULL; | ||
356 | #endif | ||
357 | } | ||
358 | |||
359 | if (!link_up_cb) | ||
360 | link_up_cb = lwipDefaultLinkUpCB; | ||
361 | if (!link_down_cb) | ||
362 | link_down_cb = lwipDefaultLinkDownCB; | ||
363 | |||
364 | #if LWIP_NETIF_HOSTNAME | ||
365 | if (thisif.hostname == NULL) | ||
366 | thisif.hostname = LWIP_NETIF_HOSTNAME_STRING; | ||
367 | #endif | ||
368 | |||
369 | macStart(ÐD1, &mac_config); | ||
370 | |||
371 | MIB2_INIT_NETIF(&thisif, snmp_ifType_ethernet_csmacd, 0); | ||
372 | |||
373 | /* Add interface. */ | ||
374 | result = netifapi_netif_add(&thisif, &ip, &netmask, &gateway, NULL, ethernetif_init, tcpip_input); | ||
375 | if (result != ERR_OK) | ||
376 | { | ||
377 | chThdSleepMilliseconds(1000); // Give some time to print any other diagnostics. | ||
378 | osalSysHalt("netif_add error"); // Not sure what else we can do if an error occurs here. | ||
379 | }; | ||
380 | |||
381 | netifapi_netif_set_default(&thisif); | ||
382 | netifapi_netif_set_up(&thisif); | ||
383 | |||
384 | /* Setup event sources.*/ | ||
385 | evtObjectInit(&evt, LWIP_LINK_POLL_INTERVAL); | ||
386 | evtStart(&evt); | ||
387 | chEvtRegisterMask(&evt.et_es, &el0, PERIODIC_TIMER_ID); | ||
388 | chEvtRegisterMask(macGetReceiveEventSource(ÐD1), &el1, FRAME_RECEIVED_ID); | ||
389 | chEvtAddEvents(PERIODIC_TIMER_ID | FRAME_RECEIVED_ID); | ||
390 | |||
391 | /* Resumes the caller and goes to the final priority.*/ | ||
392 | chThdResume(&lwip_trp, MSG_OK); | ||
393 | chThdSetPriority(LWIP_THREAD_PRIORITY); | ||
394 | |||
395 | while (true) { | ||
396 | eventmask_t mask = chEvtWaitAny(ALL_EVENTS); | ||
397 | if (mask & PERIODIC_TIMER_ID) { | ||
398 | bool current_link_status = macPollLinkStatus(ÐD1); | ||
399 | if (current_link_status != netif_is_link_up(&thisif)) { | ||
400 | if (current_link_status) { | ||
401 | tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up, | ||
402 | &thisif, 0); | ||
403 | tcpip_callback_with_block(link_up_cb, &thisif, 0); | ||
404 | } | ||
405 | else { | ||
406 | tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down, | ||
407 | &thisif, 0); | ||
408 | tcpip_callback_with_block(link_down_cb, &thisif, 0); | ||
409 | } | ||
410 | } | ||
411 | } | ||
412 | |||
413 | if (mask & FRAME_RECEIVED_ID) { | ||
414 | struct pbuf *p; | ||
415 | while (low_level_input(&thisif, &p)) { | ||
416 | if (p != NULL) { | ||
417 | struct eth_hdr *ethhdr = p->payload; | ||
418 | switch (htons(ethhdr->type)) { | ||
419 | /* IP or ARP packet? */ | ||
420 | case ETHTYPE_IP: | ||
421 | case ETHTYPE_ARP: | ||
422 | /* full packet send to tcpip_thread to process */ | ||
423 | if (thisif.input(p, &thisif) == ERR_OK) | ||
424 | break; | ||
425 | LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); | ||
426 | /* Falls through */ | ||
427 | default: | ||
428 | pbuf_free(p); | ||
429 | } | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | } | ||
434 | } | ||
435 | |||
436 | /** | ||
437 | * @brief Initializes the lwIP subsystem. | ||
438 | * @note The function exits after the initialization is finished. | ||
439 | * | ||
440 | * @param[in] opts pointer to the configuration structure, if @p NULL | ||
441 | * then the static configuration is used. | ||
442 | */ | ||
443 | void lwipInit(const lwipthread_opts_t *opts) { | ||
444 | |||
445 | /* Creating the lwIP thread (it changes priority internally).*/ | ||
446 | chThdCreateStatic(wa_lwip_thread, sizeof (wa_lwip_thread), | ||
447 | chThdGetPriorityX() - 1, lwip_thread, (void *)opts); | ||
448 | |||
449 | /* Waiting for the lwIP thread complete initialization. Note, | ||
450 | this thread reaches the thread reference object first because | ||
451 | the relative priorities.*/ | ||
452 | chSysLock(); | ||
453 | chThdSuspendS(&lwip_trp); | ||
454 | chSysUnlock(); | ||
455 | } | ||
456 | |||
457 | typedef struct lwip_reconf_params { | ||
458 | const lwipreconf_opts_t *opts; | ||
459 | semaphore_t completion; | ||
460 | } lwip_reconf_params_t; | ||
461 | |||
462 | static void do_reconfigure(void *p) | ||
463 | { | ||
464 | lwip_reconf_params_t *reconf = (lwip_reconf_params_t*) p; | ||
465 | |||
466 | switch (addressMode) { | ||
467 | #if LWIP_DHCP | ||
468 | case NET_ADDRESS_DHCP: { | ||
469 | if (netif_is_up(&thisif)) | ||
470 | dhcp_stop(&thisif); | ||
471 | break; | ||
472 | } | ||
473 | #endif | ||
474 | case NET_ADDRESS_STATIC: { | ||
475 | ip4_addr_t zero = { 0 }; | ||
476 | netif_set_ipaddr(&thisif, &zero); | ||
477 | netif_set_netmask(&thisif, &zero); | ||
478 | netif_set_gw(&thisif, &zero); | ||
479 | break; | ||
480 | } | ||
481 | #if LWIP_AUTOIP | ||
482 | case NET_ADDRESS_AUTO: { | ||
483 | if (netif_is_up(&thisif)) | ||
484 | autoip_stop(&thisif); | ||
485 | break; | ||
486 | } | ||
487 | #endif | ||
488 | } | ||
489 | |||
490 | ip.addr = reconf->opts->address; | ||
491 | gateway.addr = reconf->opts->gateway; | ||
492 | netmask.addr = reconf->opts->netmask; | ||
493 | addressMode = reconf->opts->addrMode; | ||
494 | |||
495 | switch (addressMode) { | ||
496 | #if LWIP_DHCP | ||
497 | case NET_ADDRESS_DHCP: { | ||
498 | if (netif_is_up(&thisif)) | ||
499 | dhcp_start(&thisif); | ||
500 | break; | ||
501 | } | ||
502 | #endif | ||
503 | case NET_ADDRESS_STATIC: { | ||
504 | netif_set_ipaddr(&thisif, &ip); | ||
505 | netif_set_netmask(&thisif, &netmask); | ||
506 | netif_set_gw(&thisif, &gateway); | ||
507 | break; | ||
508 | } | ||
509 | #if LWIP_AUTOIP | ||
510 | case NET_ADDRESS_AUTO: { | ||
511 | if (netif_is_up(&thisif)) | ||
512 | autoip_start(&thisif); | ||
513 | break; | ||
514 | } | ||
515 | #endif | ||
516 | } | ||
517 | |||
518 | chSemSignal(&reconf->completion); | ||
519 | } | ||
520 | |||
521 | void lwipReconfigure(const lwipreconf_opts_t *opts) | ||
522 | { | ||
523 | lwip_reconf_params_t params; | ||
524 | params.opts = opts; | ||
525 | chSemObjectInit(¶ms.completion, 0); | ||
526 | tcpip_callback_with_block(do_reconfigure, ¶ms, 0); | ||
527 | chSemWait(¶ms.completion); | ||
528 | } | ||
529 | |||
530 | /** @} */ | ||