1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
69
70
71
74
75
76
77
78
79
87
91
92
93
95
96
101
106
107
110
111
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
136
137
138
139
140
158
159
160
161
169
170
174
175
179
180
181
182
183
185
186
187
191
192
193
194
195
199
200
201
202
203
204
205
206
207
208
212
213
214
215
216
217
218
219
222
223
224
225
226
227
228
229
238
239
248
249
258
259
266
267
274
283
284
291
306
307
312
313
314
315
316
317
318
319
328
329
334
335
349
350
351
373
374
375
376
377
383
387
388
392
393
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
422
423
424
425
426
427
428
431
432
435
436
437
438
445
446
447
448
449
450
451
452
453
454
458
459
463
464
465
473
474
482
483
487
488
494
495
502
503
504
505
506
509
510
513
518
519
520
521
522
523
524
525
526
530
531
532
533
534
535
536
537
538
548
549
550
554
555
559
560
561
562
563
564
565
570
571
572
573
587
588
589
590
591
592
607
608
609
610
611
614
615
616
617
618
626
627
628
629
630
631
632
635
638
641
642
643
654
655
656
657
680
681
682
683
698
699
700
701
705
706
710
711
712
713
714
715
716
717
722
723
724
732
733
734
735
740
741
742
743
749
750
751
752
753
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
789
790
791
792
798
799
800
803
804
805
806
807
808
814
815
820
821
827
828
832
833
845
846
855
856
857
858
859
862
863
864
868
869
873
878
879
880
881
882
883
884
885
891
892
893
904
905
906
920
921
922
923
926
927
931
932
933
934
935
936
937
938
946
947
948
949
950
951
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
978
979
980
981
982
983
984
991
992
993
994
995
996
997
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1036
1037
1038
1039
1042
1045
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1068
1069
1070
1071
1072
1073
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1140
1141
1142
1143
1144
1149
1153
1154
1155
1156
1157
1158
1159
1163
1164
1165
1168
1169
1170
1171
1172
1176
1177
1178
1179
1180
1181
1190
1191
1192
1195
1196
1200
1201
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1235
1236
1240
1241
1245
1246
1247
1248
1249
1254
1255
1256
1257
1258
1259
1260
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1304
1305
1319
1320
1321
1322
1323
1332
1333
1334
1335
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1370
1371
1372
1373
1374
1375
1376
1377
1378
1381
1382
1383
1384
1385
1386
1389
1390
1391
1392
1395
1400
1401
1402
1403
1404
1405
1406
1410
1411
1412
1413
1414
1415
1416
1417
1418
1421
1422
1423
1424
1425
1432
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1448
1449
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1472
1473
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1513
1514
1515
1516
1517
1518
1519
1520
1523
1524
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1548
1549
1550
1554
1555
1556
1557
1562
1563
1564
1565
1566
1567
1568
1569
1570
1573
1574
1575
1576
1577
1578
1579
1580
1581
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1599
1600
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1619
1620
1621
1622
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1640
1641
1642
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1670
1671
1672
1673
1674
1675
1678
1679
1680
1683
1684
1688
1689
1690
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1707
1708
1709
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1731
1732
1733
1734
1735
1737
1738
1739
1740
1741
1742
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1760
1761
1762
1763
1772
1773
1785
1786
1787
1788
1789
1790
1791
1796
1797
1798
1799
1800
1801
1802
1803
1804
1819
1820
1821
1822
1823
1824
1825
1828
1829
1830
1831
1832
1833
1834
1835
1836
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1864
1865
1866
1867
1868
1869
1870
1871
1872
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1892
1893
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1923
1924
1925
1926
1927
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1947
1948
1949
1950
1951
1952
1953
1956
1957
1958
1959
1960
1961
1962
1963
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
2009
2010
2011
2012
2013
2014
2015
2016
2020
2021
2025
2026
2030
2031
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2053
2054
2055
2056
2057
2058
2059
2065
2066
2067
2070
2071
2072
2073
2074
2075
2076
2077
2078
2082
2083
2087
2088
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2106
2107
2108
2109
2110
2111
2119
2120
2127
2128
2129
2130
2131
2132
2133
2134
2145
2146
2147
2148
2149
2150
2151
2152
2153
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2198
2199
2200
2201
2202
2203
2204
2205
2206
2209
2210
2211
2216
2217
2218
2219
2220
2221
2222
2223
2226
2227
2228
2229
2230
2239
2240
2241
2242
2243
2244
2245
2246
2247
2250
2251
2252
2253
2254
2261
2262
2263
2264
2265
2266
2267
2268
2271
2272
2273
2274
2275
2285
2286
2287
2288
2289
2293
2294
2298
2299
2303
2304
2311
2312
2323
2324
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2342
2343
2378
2381
2382
2383
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2431
2432
2433
2434
2435
2438
2439
2442
2445
2446
2449
2450
2451
2452
2453
2474
2476
2477
2478
2481
2482
2483
2484
2485
2486
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2507
2544
2545
2546
2547
2548
2556
2557
2558
2559
2566
2567
2573
2574
2575
2576
2577
2578
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2595
2596
2597
2598
2599
2606
2607
2608
2609
2612
2613
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2636
2637
2642
2643
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2769
2770
2771
2772
2773
2774
2775
/* ... */
#include <string.h>
#include <inttypes.h>
#include <lwip/ip_addr.h>
#include <lwip/sockets.h>
#include "esp_compiler.h"
#include "esp_check.h"
#include "esp_netif_lwip_internal.h"
#include "lwip/esp_netif_net_stack.h"
#include "esp_netif.h"
#include "esp_netif_private.h"
#include "esp_random.h"
#include "esp_system.h"
#include "lwip/tcpip.h"
#include "lwip/dhcp.h"
#include "lwip/ip_addr.h"
#include "lwip/ip6_addr.h"
#include "lwip/mld6.h"
#include "lwip/prot/mld6.h"
#include "lwip/nd6.h"
#include "lwip/snmp.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/netif.h"
#include "lwip/etharp.h"23 includes
#if CONFIG_ESP_NETIF_BRIDGE_EN
#include "netif/bridgeif.h"
#endif
#if LWIP_DNS
#include "lwip/dns.h"
#endif
#if CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
#include "lwip_default_hooks.h"
#endif
#include "esp_netif_lwip_ppp.h"
#if ESP_DHCPS
#include "dhcpserver/dhcpserver.h"
#include "dhcpserver/dhcpserver_options.h"/* ... */
#endif
#include "netif/dhcp_state.h"
#include "esp_event.h"
#include "esp_log.h"
#if IP_NAPT
#include "lwip/lwip_napt.h"
#endif
#define ESP_NETIF_HOSTNAME_MAX_SIZE 32
#define DHCP_CB_CHANGE (LWIP_NSC_IPV4_SETTINGS_CHANGED | LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_GATEWAY_CHANGED | LWIP_NSC_IPV4_NETMASK_CHANGED)
/* ... */
#define _RUN_IN_LWIP_TASK(function, netif, param) { return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); }
/* ... */
#if CONFIG_PPP_SUPPORT
#define _IS_NETIF_ANY_POINT2POINT_TYPE(netif) (netif && netif->related_data && netif->related_data->is_point2point)
#else
#define _IS_NETIF_ANY_POINT2POINT_TYPE(netif) false
#endif
#define _RUN_IN_LWIP_TASK_IF_SUPPORTED(function, netif, param) \
{ \
if (_IS_NETIF_ANY_POINT2POINT_TYPE(netif)) { \
return ESP_ERR_NOT_SUPPORTED; \
}{...} \
return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); \
}{...}
...
/* ... */
#if LWIP_IPV4 && LWIP_IPV6
#define ESPIP_TO_IP(espip, ip) memcpy((ip), (espip), sizeof(ip_addr_t));
#define IP_TO_ESPIP(ip, espip) memcpy((espip), (ip), sizeof(ip_addr_t));/* ... */
#elif LWIP_IPV4
#define ESPIP_TO_IP(espip, ip) memcpy((ip), &((espip)->u_addr.ip4), sizeof(ip_addr_t));
#define IP_TO_ESPIP(ip, espip) do { memcpy(&((espip)->u_addr.ip4), (ip), sizeof(ip4_addr_t)); \
(espip)->type = ESP_IPADDR_TYPE_V4; \
}{...} while(0)...
/* ... */#elif LWIP_IPV6
#define ESPIP_TO_IP(espip, ip) memcpy((ip), &((espip)->u_addr.ip6), sizeof(ip_addr_t));
#define IP_TO_ESPIP(ip, espip) do { memcpy(&((espip)->u_addr.ip6), (ip), sizeof(ip6_addr_t)); \
(espip)->type = ESP_IPADDR_TYPE_V6; \
}{...} while(0)...
/* ... */#endif
/* ... */
#define LOG_NETIF_DISABLED_AND_DO(proto, action) \
do { \
ESP_LOGE(TAG, "%s not supported, please enable it in lwIP component configuration", proto); \
action; \
}{...} while(0)...
static const char *TAG = "esp_netif_lwip";
#if LWIP_ESP_NETIF_DATA
static u8_t lwip_netif_client_id = 0xff;
#endif
static esp_netif_t *s_last_default_esp_netif = NULL;
static bool s_is_last_default_esp_netif_overridden = false;
static netif_ext_callback_t netif_callback = { .callback_fn = NULL, .next = NULL };
#if LWIP_IPV4
static void esp_netif_internal_dhcpc_cb(struct netif *netif);
#endif
#if LWIP_IPV6
static void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index);
static void netif_set_mldv6_flag(esp_netif_t *netif);
static void netif_unset_mldv6_flag(esp_netif_t *netif);/* ... */
#endif
static esp_err_t esp_netif_destroy_api(esp_netif_api_msg_t *msg);
static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args)
{
#if LWIP_IPV4
if (reason & DHCP_CB_CHANGE) {
esp_netif_internal_dhcpc_cb(netif);
}{...}
#endif/* ... */
#if LWIP_IPV6
if ((reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) && (args != NULL)) {
s8_t addr_idx = args->ipv6_addr_state_changed.addr_index;
if (!(args->ipv6_addr_state_changed.old_state & IP6_ADDR_VALID) &&
netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) {
esp_netif_internal_nd6_cb(netif, addr_idx);
}{...}
}{...}
#endif/* ... */
}{ ... }
#ifdef CONFIG_LWIP_GARP_TMR_INTERVAL
static void netif_send_garp(void *arg)
{
struct netif *netif = arg;
if (!ip4_addr_cmp(netif_ip4_addr(netif), IP4_ADDR_ANY4)) {
etharp_gratuitous(netif);
}{...}
sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif);
}{ ... }
static void netif_set_garp_flag(struct netif *netif)
{
sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif);
}{ ... }
static void netif_unset_garp_flag(struct netif *netif)
{
sys_untimeout(netif_send_garp, netif);
}{ ... }
/* ... */#endif
#if !LWIP_TCPIP_CORE_LOCKING
static sys_sem_t api_sync_sem = NULL;
static sys_sem_t api_lock_sem = NULL;/* ... */
#endif
/* ... */
static void esp_netif_api_cb(void *api_msg)
{
esp_netif_api_msg_t *msg = (esp_netif_api_msg_t *)api_msg;
if (!msg || !msg->api_fn) {
ESP_LOGD(TAG, "null msg/api_fn");
return;
}{...}
msg->ret = msg->api_fn(msg);
ESP_LOGD(TAG, "call api in lwip: ret=0x%x, give sem", msg->ret);
#if !LWIP_TCPIP_CORE_LOCKING
sys_sem_signal(&api_sync_sem);
#endif
}{ ... }
/* ... */
static inline esp_err_t esp_netif_lwip_ipc_call_msg(esp_netif_api_msg_t *msg)
{
if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) {
ESP_LOGD(TAG, "check: remote, if=%p fn=%p", msg->esp_netif, msg->api_fn);
#if LWIP_TCPIP_CORE_LOCKING
tcpip_send_msg_wait_sem((tcpip_callback_fn)esp_netif_api_cb, msg, NULL);
#else
sys_arch_sem_wait(&api_lock_sem, 0);
tcpip_send_msg_wait_sem((tcpip_callback_fn)esp_netif_api_cb, msg, &api_sync_sem);
sys_sem_signal(&api_lock_sem);/* ... */
#endif
return msg->ret;
}{...}
ESP_LOGD(TAG, "check: local, if=%p fn=%p", msg->esp_netif, msg->api_fn);
return msg->api_fn(msg);
}{ ... }
static inline esp_err_t esp_netif_lwip_ipc_call(esp_netif_api_fn fn, esp_netif_t* netif, void *data)
{
esp_netif_api_msg_t msg = {
.esp_netif = netif,
.data = data,
.api_fn = fn
}{...};
return esp_netif_lwip_ipc_call_msg(&msg);
}{ ... }
static inline esp_err_t esp_netif_lwip_ipc_call_fn(esp_netif_api_fn fn, esp_netif_callback_fn user_fn, void *ctx)
{
esp_netif_api_msg_t msg = {
.user_fn = user_fn,
.data = ctx,
.api_fn = fn
}{...};
return esp_netif_lwip_ipc_call_msg(&msg);
}{ ... }
static inline esp_err_t esp_netif_lwip_ipc_call_get_netif(esp_netif_api_fn fn, esp_netif_t **netif, void *ctx)
{
esp_netif_api_msg_t msg = {
.p_esp_netif = netif,
.data = ctx,
.api_fn = fn
}{...};
return esp_netif_lwip_ipc_call_msg(&msg);
}{ ... }
static inline esp_err_t esp_netif_lwip_ipc_no_args(esp_netif_api_fn fn)
{
esp_netif_api_msg_t msg = {
.api_fn = fn
}{...};
return esp_netif_lwip_ipc_call_msg(&msg);
}{ ... }
/* ... */
static esp_netif_t* esp_netif_is_active(esp_netif_t *arg)
{
if (esp_netif_is_netif_listed(arg)) {
return arg;
}{...}
return NULL;
}{ ... }
/* ... */
static void esp_netif_set_default_netif_internal(esp_netif_t *esp_netif)
{
if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
#if CONFIG_PPP_SUPPORT
esp_netif_ppp_set_default_netif(esp_netif->netif_handle);
#endif
}{...} else {
netif_set_default(esp_netif->lwip_netif);
}{...}
#ifdef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF
for (int i = 0; i < DNS_MAX_SERVERS; ++i) {
dns_setserver(i, &esp_netif->dns[i]);
}{...}
#endif/* ... */
}{ ... }
/* ... */
static esp_err_t esp_netif_update_default_netif_lwip(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
esp_netif_route_prio_action_t action = (esp_netif_route_prio_action_t)msg->data;
ESP_LOGD(TAG, "%s %p", __func__, esp_netif);
if (s_is_last_default_esp_netif_overridden && action != ESP_NETIF_SET_DEFAULT) {
s_last_default_esp_netif = esp_netif_is_active(s_last_default_esp_netif);
if (s_last_default_esp_netif != NULL) {
return ESP_OK;
}{...}
s_is_last_default_esp_netif_overridden = false;
}{...}
switch (action) {
case ESP_NETIF_SET_DEFAULT:
s_last_default_esp_netif = esp_netif;
s_is_last_default_esp_netif_overridden = true;
esp_netif_set_default_netif_internal(s_last_default_esp_netif);
break;...
case ESP_NETIF_STARTED:
case ESP_NETIF_GOT_IP:
{
s_last_default_esp_netif = esp_netif_is_active(s_last_default_esp_netif);
if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)
&& (s_last_default_esp_netif->route_prio > esp_netif->route_prio)) {
esp_netif_set_default_netif_internal(s_last_default_esp_netif);
}{...} else if (esp_netif_is_netif_up(esp_netif)) {
s_last_default_esp_netif = esp_netif;
esp_netif_set_default_netif_internal(s_last_default_esp_netif);
}{...}
}{...}
break;
...
default:
case ESP_NETIF_STOPPED:
case ESP_NETIF_LOST_IP:
{
s_last_default_esp_netif = NULL;
esp_netif_t *netif = esp_netif_next_unsafe(NULL);
while (netif) {
if (esp_netif_is_netif_up(netif)) {
if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)) {
if (netif->route_prio > s_last_default_esp_netif->route_prio) {
s_last_default_esp_netif = netif;
}{...}
}{...} else {
s_last_default_esp_netif = netif;
}{...}
}{...}
netif = esp_netif_next_unsafe(netif);
}{...}
if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)) {
esp_netif_set_default_netif_internal(s_last_default_esp_netif);
}{...}
}{...}
break;...
}{...}
return ESP_OK;
}{ ... }
/* ... */
esp_err_t esp_netif_update_default_netif(esp_netif_t *esp_netif, esp_netif_route_prio_action_t action)
{
return esp_netif_lwip_ipc_call(esp_netif_update_default_netif_lwip, esp_netif, (void*)action);
}{ ... }
esp_err_t esp_netif_set_default_netif(esp_netif_t *esp_netif)
{
return esp_netif_update_default_netif(esp_netif, ESP_NETIF_SET_DEFAULT);
}{ ... }
esp_netif_t *esp_netif_get_default_netif(void)
{
return s_last_default_esp_netif;
}{ ... }
static inline esp_netif_t* lwip_get_esp_netif(struct netif *netif)
{
#if LWIP_ESP_NETIF_DATA
return (esp_netif_t*)netif_get_client_data(netif, lwip_netif_client_id);
#else
return (esp_netif_t*)netif->state;
#endif
}{ ... }
static inline void lwip_set_esp_netif(struct netif *netif, esp_netif_t* esp_netif)
{
#if LWIP_ESP_NETIF_DATA
netif_set_client_data(netif, lwip_netif_client_id, esp_netif);
#else
netif->state = esp_netif;
#endif
}{ ... }
#if CONFIG_ESP_NETIF_BRIDGE_EN
esp_err_t esp_netif_bridge_add_port(esp_netif_t *esp_netif_br, esp_netif_t *esp_netif_port)
{
if (ERR_OK != bridgeif_add_port(esp_netif_br->lwip_netif, esp_netif_port->lwip_netif)) {
return ESP_FAIL;
}{...}
return ESP_OK;
}{...}
esp_err_t esp_netif_bridge_fdb_add(esp_netif_t *esp_netif_br, uint8_t *addr, uint64_t ports_mask)
{
bridgeif_portmask_t ports = (bridgeif_portmask_t)ports_mask;
if (ports_mask & ESP_NETIF_BR_FDW_CPU) {
ports |= 1 << BRIDGEIF_MAX_PORTS;
}{...}
if (ERR_OK != bridgeif_fdb_add(esp_netif_br->lwip_netif, (const struct eth_addr *)addr, ports)) {
return ESP_FAIL;
}{...}
return ESP_OK;
}{...}
esp_err_t esp_netif_bridge_fdb_remove(esp_netif_t *esp_netif_br, uint8_t *addr)
{
if (ERR_OK != bridgeif_fdb_remove(esp_netif_br->lwip_netif, (const struct eth_addr *)addr)) {
return ESP_FAIL;
}{...}
return ESP_OK;
}{...}
/* ... */#endif
#if CONFIG_LWIP_IPV4
void esp_netif_set_ip4_addr(esp_ip4_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
ip4_addr_t *address = (ip4_addr_t*)addr;
IP4_ADDR(address, a, b, c, d);
}{ ... }
char * esp_ip4addr_ntoa(const esp_ip4_addr_t *addr, char *buf, int buflen)
{
return ip4addr_ntoa_r((ip4_addr_t *)addr, buf, buflen);
}{ ... }
uint32_t esp_ip4addr_aton(const char *addr)
{
return ipaddr_addr(addr);
}{ ... }
#endif/* ... */
esp_err_t esp_netif_str_to_ip4(const char *src, esp_ip4_addr_t *dst)
{
if (src == NULL || dst == NULL) {
return ESP_ERR_INVALID_ARG;
}{...}
int err = inet_pton(AF_INET, src, dst);
return err == 1 ? ESP_OK : ESP_FAIL;
}{ ... }
esp_err_t esp_netif_str_to_ip6(const char *src, esp_ip6_addr_t *dst)
{
if (src == NULL || dst == NULL) {
return ESP_ERR_INVALID_ARG;
}{...}
int err = inet_pton(AF_INET6, src, dst);
return err == 1 ? ESP_OK : ESP_FAIL;
}{ ... }
esp_netif_iodriver_handle esp_netif_get_io_driver(esp_netif_t *esp_netif)
{
return esp_netif->driver_handle;
}{ ... }
esp_netif_t* esp_netif_get_handle_from_netif_impl(void *dev)
{
struct netif *lwip_netif = dev;
return lwip_get_esp_netif(lwip_netif);
}{ ... }
void* esp_netif_get_netif_impl(esp_netif_t *esp_netif)
{
if (esp_netif) {
return esp_netif->lwip_netif;
}{...}
return NULL;
}{ ... }
#if CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF
static void store_dnsserver_info(struct netif* netif, u8_t numdns, const ip_addr_t *dnsserver)
{
if (netif == NULL) {
return;
}{...}
esp_netif_t *esp_netif = lwip_get_esp_netif(netif);
if (esp_netif == NULL || !esp_netif_is_netif_listed(esp_netif)) {
return;
}{...}
if (!ip_addr_isany(dnsserver)) {
ip_addr_copy(esp_netif->dns[numdns], *dnsserver);
}{...} else {
ip_addr_copy(esp_netif->dns[numdns], *IP_ADDR_ANY);
}{...}
}{...}
/* ... */#endif
static void tcpip_init_done(void *arg)
{
sys_sem_t *init_sem = arg;
#if LWIP_ESP_NETIF_DATA
if (lwip_netif_client_id == 0xFF) {
lwip_netif_client_id = netif_alloc_client_data_id();
}{...}
#endif/* ... */
sys_sem_signal(init_sem);
}{ ... }
esp_err_t esp_netif_init(void)
{
if (!sys_thread_tcpip(LWIP_CORE_IS_TCPIP_INITIALIZED)) {
#if CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
uint8_t rand_buf[16];
/* ... */
esp_fill_random(rand_buf, sizeof(rand_buf));
lwip_init_tcp_isn(esp_log_timestamp(), rand_buf);/* ... */
#endif
sys_sem_t init_sem;
if (sys_sem_new(&init_sem, 0) != ERR_OK) {
ESP_LOGE(TAG, "esp netif cannot create tcpip_init semaphore");
return ESP_FAIL;
}{...}
#if LWIP_TCPIP_CORE_LOCKING
/* ... */
sys_thread_tcpip(LWIP_CORE_LOCK_MARK_HOLDER);/* ... */
#endif
tcpip_init(tcpip_init_done, &init_sem);
sys_sem_wait(&init_sem);
sys_sem_free(&init_sem);
ESP_LOGD(TAG, "LwIP stack has been initialized");
#if CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF
if (dns_setserver_callback(store_dnsserver_info) != ERR_OK) {
ESP_LOGE(TAG, "Feiled to configure DNS set server callback");
return ESP_FAIL;
}{...}
#endif/* ... */
}{...}
#if !LWIP_TCPIP_CORE_LOCKING
if (!api_sync_sem) {
if (ERR_OK != sys_sem_new(&api_sync_sem, 0)) {
ESP_LOGE(TAG, "esp netif api sync sem init fail");
return ESP_FAIL;
}{...}
}{...}
if (!api_lock_sem) {
if (ERR_OK != sys_sem_new(&api_lock_sem, 1)) {
ESP_LOGE(TAG, "esp netif api lock sem init fail");
return ESP_FAIL;
}{...}
}{...}
#endif/* ... */
ESP_LOGD(TAG, "esp-netif has been successfully initialized");
return ESP_OK;
}{ ... }
esp_err_t esp_netif_deinit(void)
{
if (sys_thread_tcpip(LWIP_CORE_IS_TCPIP_INITIALIZED)) {
/* ... */
return ESP_ERR_NOT_SUPPORTED;
}{...}
return ESP_ERR_INVALID_STATE;
}{ ... }
static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_netif_config_t *cfg)
{
if (cfg == NULL || cfg->base == NULL || cfg->stack == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
memcpy(esp_netif->mac, cfg->base->mac, NETIF_MAX_HWADDR_LEN);
#if CONFIG_LWIP_IPV4
if (cfg->base->ip_info == NULL) {
ip4_addr_set_zero(&esp_netif->ip_info->ip);
ip4_addr_set_zero(&esp_netif->ip_info->gw);
ip4_addr_set_zero(&esp_netif->ip_info->netmask);
}{...} else {
memcpy(esp_netif->ip_info, cfg->base->ip_info, sizeof(esp_netif_ip_info_t));
}{...}
memcpy(esp_netif->ip_info_old, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));/* ... */
#endif
esp_netif->lost_ip_event = cfg->base->lost_ip_event;
esp_netif->get_ip_event = cfg->base->get_ip_event;
esp_netif->flags = cfg->base->flags;
if (cfg->base->if_key) {
esp_netif->if_key = strdup(cfg->base->if_key);
}{...}
if (cfg->base->if_desc) {
esp_netif->if_desc = strdup(cfg->base->if_desc);
}{...}
if (cfg->base->route_prio) {
esp_netif->route_prio = cfg->base->route_prio;
}{...}
#if CONFIG_ESP_NETIF_BRIDGE_EN
if (cfg->base->flags & ESP_NETIF_FLAG_IS_BRIDGE) {
if (cfg->base->bridge_info != NULL) {
esp_netif->max_fdb_dyn_entries = cfg->base->bridge_info->max_fdb_dyn_entries;
esp_netif->max_fdb_sta_entries = cfg->base->bridge_info->max_fdb_sta_entries;
esp_netif->max_ports = cfg->base->bridge_info->max_ports;
}{...} else {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
}{...}
#endif/* ... */
const esp_netif_netstack_config_t *esp_netif_stack_config = cfg->stack;
if (cfg->base->flags & ESP_NETIF_FLAG_IS_PPP) {
#if CONFIG_PPP_SUPPORT
esp_netif->related_data = esp_netif_new_ppp(esp_netif, esp_netif_stack_config);
if (esp_netif->related_data == NULL) {
return ESP_ERR_ESP_NETIF_INIT_FAILED;
}{...}
esp_netif->lwip_input_fn = esp_netif_stack_config->lwip_ppp.input_fn;
esp_netif->netif_handle = esp_netif->related_data;/* ... */
#else
LOG_NETIF_DISABLED_AND_DO("PPP", return ESP_ERR_NOT_SUPPORTED);
#endif
}{...} else {
if (esp_netif_stack_config-> lwip.init_fn) {
esp_netif->lwip_init_fn = esp_netif_stack_config->lwip.init_fn;
}{...}
if (esp_netif_stack_config->lwip.input_fn) {
esp_netif->lwip_input_fn = esp_netif_stack_config->lwip.input_fn;
}{...}
esp_netif->netif_handle = esp_netif->lwip_netif;
}{...}
if (cfg->driver) {
const esp_netif_driver_ifconfig_t *esp_netif_driver_config = cfg->driver;
if (esp_netif_driver_config->handle) {
esp_netif->driver_handle = esp_netif_driver_config->handle;
}{...}
if (esp_netif_driver_config->transmit) {
esp_netif->driver_transmit = esp_netif_driver_config->transmit;
}{...}
if (esp_netif_driver_config->transmit_wrap) {
esp_netif->driver_transmit_wrap = esp_netif_driver_config->transmit_wrap;
}{...}
if (esp_netif_driver_config->driver_free_rx_buffer) {
esp_netif->driver_free_rx_buffer = esp_netif_driver_config->driver_free_rx_buffer;
}{...}
}{...}
return ESP_OK;
}{ ... }
static esp_err_t tcpip_exec_api(esp_netif_api_msg_t *msg)
{
return msg->user_fn(msg->data);
}{ ... }
esp_err_t esp_netif_tcpip_exec(esp_netif_callback_fn fn, void*ctx)
{
return esp_netif_lwip_ipc_call_fn(tcpip_exec_api, fn, ctx);
}{ ... }
static esp_err_t esp_netif_new_api(esp_netif_api_msg_t *msg)
{
const esp_netif_config_t *esp_netif_config = msg->data;
if (esp_netif_config == NULL ||
esp_netif_config->base->if_key == NULL ||
NULL != esp_netif_get_handle_from_ifkey_unsafe(esp_netif_config->base->if_key)) {
ESP_LOGE(TAG, "%s: Failed to configure netif with config=%p (config or if_key is NULL or duplicate key)",
__func__, esp_netif_config);
return ESP_FAIL;
}{...}
#if ESP_DHCPS
if((esp_netif_config->base->flags & ESP_NETIF_DHCP_SERVER) &&
(esp_netif_config->base->flags & ESP_NETIF_DHCP_CLIENT)) {
ESP_LOGE(TAG, "%s: Failed to configure netif with config=%p (DHCP server and client cannot be configured together)",
__func__, esp_netif_config);
return ESP_FAIL;
}{...}
#endif/* ... */
esp_netif_t *esp_netif = calloc(1, sizeof(struct esp_netif_obj));
if (!esp_netif) {
ESP_LOGE(TAG, "Failed to allocate %" PRIu32 " bytes (free heap size %" PRIu32 ")", (uint32_t)sizeof(struct esp_netif_obj),
esp_get_free_heap_size());
return ESP_FAIL;
}{...}
esp_netif_ip_info_t *ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
if (!ip_info) {
ESP_LOGE(TAG, "Failed to allocate %" PRIu32 " bytes (free heap size %" PRIu32 ")", (uint32_t)sizeof(esp_netif_ip_info_t),
esp_get_free_heap_size());
free(esp_netif);
return ESP_FAIL;
}{...}
esp_netif->ip_info = ip_info;
ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
if (!ip_info) {
ESP_LOGE(TAG, "Failed to allocate %" PRIu32 " bytes (free heap size %" PRIu32 ")", (uint32_t)sizeof(esp_netif_ip_info_t),
esp_get_free_heap_size());
free(esp_netif->ip_info);
free(esp_netif);
return ESP_FAIL;
}{...}
esp_netif->ip_info_old = ip_info;
struct netif * lwip_netif = calloc(1, sizeof(struct netif));
if (!lwip_netif) {
ESP_LOGE(TAG, "Failed to allocate %" PRIu32 " bytes (free heap size %" PRIu32 ")", (uint32_t)sizeof(struct netif),
esp_get_free_heap_size());
free(esp_netif->ip_info_old);
free(esp_netif->ip_info);
free(esp_netif);
return ESP_FAIL;
}{...}
esp_netif->lwip_netif = lwip_netif;
esp_netif_add_to_list_unsafe(esp_netif);
#if ESP_DHCPS
if (esp_netif_config->base->flags & ESP_NETIF_DHCP_SERVER) {
esp_netif->dhcps = dhcps_new();
if (esp_netif->dhcps == NULL) {
ESP_LOGE(TAG, "Failed to create dhcp server handle");
esp_netif_api_msg_t to_destroy = { .esp_netif = esp_netif};
esp_netif_destroy_api(&to_destroy);
return ESP_FAIL;
}{...}
}{...}
#endif/* ... */
esp_err_t ret = esp_netif_init_configuration(esp_netif, esp_netif_config);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Initial configuration of esp_netif failed with %d", ret);
esp_netif_api_msg_t to_destroy = { .esp_netif = esp_netif};
esp_netif_destroy_api(&to_destroy);
return ESP_FAIL;
}{...}
lwip_set_esp_netif(lwip_netif, esp_netif);
if (netif_callback.callback_fn == NULL ) {
netif_add_ext_callback(&netif_callback, netif_callback_fn);
}{...}
*msg->p_esp_netif = esp_netif;
return ESP_OK;
}{ ... }
esp_netif_t *esp_netif_new(const esp_netif_config_t *config)
{
esp_netif_t *netif = NULL;
esp_netif_lwip_ipc_call_get_netif(esp_netif_new_api, &netif, (void *)config);
return netif;
}{ ... }
static esp_err_t get_handle_from_ifkey_api(esp_netif_api_msg_t *msg)
{
*msg->p_esp_netif = esp_netif_get_handle_from_ifkey_unsafe(msg->data);
return ESP_OK;
}{ ... }
esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key)
{
esp_netif_t *netif = NULL;
esp_netif_lwip_ipc_call_get_netif(get_handle_from_ifkey_api, &netif, (void*)if_key);
return netif;
}{ ... }
typedef struct find_if_api {
esp_netif_find_predicate_t fn;
void *ctx;
}{ ... } find_if_api_t;
static esp_err_t esp_netif_find_if_api(esp_netif_api_msg_t *msg)
{
find_if_api_t *find_if_api = msg->data;
esp_netif_t *esp_netif = NULL;
while ((esp_netif = esp_netif_next_unsafe(esp_netif)) != NULL) {
if (find_if_api->fn(esp_netif, find_if_api->ctx)) {
*msg->p_esp_netif = esp_netif;
return ESP_OK;
}{...}
}{...}
return ESP_FAIL;
}{ ... }
esp_netif_t *esp_netif_find_if(esp_netif_find_predicate_t fn, void *ctx)
{
esp_netif_t *netif = NULL;
find_if_api_t find_if_api = { .fn = fn, .ctx = ctx };
if (esp_netif_lwip_ipc_call_get_netif(esp_netif_find_if_api, &netif, &find_if_api) == ESP_OK) {
return netif;
}{...}
return NULL;
}{ ... }
static void esp_netif_lwip_remove(esp_netif_t *esp_netif)
{
if (esp_netif->lwip_netif) {
if (netif_is_up(esp_netif->lwip_netif)) {
netif_set_down(esp_netif->lwip_netif);
}{...}
netif_remove(esp_netif->lwip_netif);
#if ESP_GRATUITOUS_ARP
if (esp_netif->flags & ESP_NETIF_FLAG_GARP) {
netif_unset_garp_flag(esp_netif->lwip_netif);
}{...}
#endif/* ... */
#if ESP_MLDV6_REPORT && LWIP_IPV6
if (esp_netif->flags & ESP_NETIF_FLAG_MLDV6_REPORT) {
netif_unset_mldv6_flag(esp_netif);
}{...}
#endif/* ... */
if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
#if CONFIG_LWIP_IPV4
dhcp_cleanup(esp_netif->lwip_netif);
#endif
}{...}
}{...}
}{ ... }
static esp_err_t esp_netif_lwip_add(esp_netif_t *esp_netif)
{
ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak");
if (esp_netif->lwip_netif == NULL) {
esp_netif->lwip_netif = calloc(1, sizeof(struct netif));
if (esp_netif->lwip_netif == NULL) {
return ESP_ERR_NO_MEM;
}{...}
}{...}
ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak");
if (esp_netif->flags & ESP_NETIF_FLAG_IS_PPP) {
#if CONFIG_PPP_SUPPORT
err_t err = esp_netif->lwip_init_fn(NULL);
if (err != ERR_OK) {
ESP_LOGE(TAG, "Init netif failed with %" PRId8 "", err);
return ESP_ERR_ESP_NETIF_INIT_FAILED;
}{...}
#else/* ... */
LOG_NETIF_DISABLED_AND_DO("PPP", return ESP_ERR_NOT_SUPPORTED);
#endif
}{...}
#if CONFIG_ESP_NETIF_BRIDGE_EN
if (esp_netif->flags & ESP_NETIF_FLAG_IS_BRIDGE) {
bridgeif_initdata_t bridge_initdata = {
.max_fdb_dynamic_entries = esp_netif->max_fdb_dyn_entries,
.max_fdb_static_entries = esp_netif->max_fdb_sta_entries,
.max_ports = esp_netif->max_ports
}{...};
memcpy(&bridge_initdata.ethaddr, esp_netif->mac, ETH_HWADDR_LEN);
if (NULL == netif_add(esp_netif->lwip_netif, (struct ip4_addr*)&esp_netif->ip_info->ip,
(struct ip4_addr*)&esp_netif->ip_info->netmask, (struct ip4_addr*)&esp_netif->ip_info->gw,
&bridge_initdata, esp_netif->lwip_init_fn, tcpip_input)) {
esp_netif_lwip_remove(esp_netif);
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
}{...} else {
#endif
if (NULL == netif_add(esp_netif->lwip_netif,
#if CONFIG_LWIP_IPV4
(struct ip4_addr*)&esp_netif->ip_info->ip,
(struct ip4_addr*)&esp_netif->ip_info->netmask,
(struct ip4_addr*)&esp_netif->ip_info->gw,/* ... */
#endif
esp_netif, esp_netif->lwip_init_fn, tcpip_input)) {
esp_netif_lwip_remove(esp_netif);
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
#if CONFIG_ESP_NETIF_BRIDGE_EN
}{...}
#endif
lwip_set_esp_netif(esp_netif->lwip_netif, esp_netif);
return ESP_OK;
}{ ... }
static void esp_netif_destroy_related(esp_netif_t *esp_netif)
{
if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
#if CONFIG_PPP_SUPPORT
esp_netif_destroy_ppp(esp_netif->related_data);
#endif
}{...}
}{ ... }
static esp_err_t esp_netif_destroy_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
esp_netif_remove_from_list_unsafe(esp_netif);
if (esp_netif_get_nr_of_ifs() == 0) {
netif_remove_ext_callback(&netif_callback);
netif_callback.callback_fn = NULL;
}{...}
free(esp_netif->ip_info);
free(esp_netif->ip_info_old);
free(esp_netif->if_key);
free(esp_netif->if_desc);
esp_netif_lwip_remove(esp_netif);
esp_netif_destroy_related(esp_netif);
free(esp_netif->lwip_netif);
free(esp_netif->hostname);
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);
#if ESP_DHCPS
dhcps_delete(esp_netif->dhcps);
#endif
free(esp_netif);
return ESP_OK;
}{ ... }
void esp_netif_destroy(esp_netif_t *esp_netif)
{
if (esp_netif == NULL) {
return;
}{...}
esp_netif_lwip_ipc_call(esp_netif_destroy_api, esp_netif, NULL);
}{ ... }
esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle driver_handle)
{
esp_netif_driver_base_t *base_driver = driver_handle;
esp_netif->driver_handle = driver_handle;
if (base_driver->post_attach) {
esp_err_t ret = base_driver->post_attach(esp_netif, driver_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Post-attach callback of driver(%p) failed with %d", driver_handle, ret);
return ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED;
}{...}
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_set_driver_config(esp_netif_t *esp_netif,
const esp_netif_driver_ifconfig_t *driver_config)
{
if (esp_netif == NULL || driver_config == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
esp_netif->driver_handle = driver_config->handle;
esp_netif->driver_transmit = driver_config->transmit;
esp_netif->driver_transmit_wrap = driver_config->transmit_wrap;
esp_netif->driver_free_rx_buffer = driver_config->driver_free_rx_buffer;
return ESP_OK;
}{ ... }
#if CONFIG_LWIP_IPV4
static esp_err_t esp_netif_reset_ip_info(esp_netif_t *esp_netif)
{
ip4_addr_set_zero(&(esp_netif->ip_info->ip));
ip4_addr_set_zero(&(esp_netif->ip_info->gw));
ip4_addr_set_zero(&(esp_netif->ip_info->netmask));
return ESP_OK;
}{ ... }
/* ... */#endif
esp_err_t esp_netif_set_mac_api(esp_netif_api_msg_t *msg)
{
uint8_t *mac = msg->data;
esp_netif_t* esp_netif = msg->esp_netif;
memcpy(esp_netif->mac, mac, NETIF_MAX_HWADDR_LEN);
memcpy(esp_netif->lwip_netif->hwaddr, mac, NETIF_MAX_HWADDR_LEN);
return ESP_OK;
}{ ... }
esp_err_t esp_netif_set_mac(esp_netif_t *esp_netif, uint8_t mac[])
{
if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
return ESP_ERR_NOT_SUPPORTED;
}{...}
return esp_netif_lwip_ipc_call(esp_netif_set_mac_api, esp_netif, mac);
}{ ... }
esp_err_t esp_netif_get_mac(esp_netif_t *esp_netif, uint8_t mac[])
{
if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
return ESP_ERR_NOT_SUPPORTED;
}{...}
if (esp_netif_is_netif_up(esp_netif)) {
memcpy(mac, esp_netif->lwip_netif->hwaddr, NETIF_MAX_HWADDR_LEN);
return ESP_OK;
}{...}
memcpy(mac, esp_netif->mac, NETIF_MAX_HWADDR_LEN);
return ESP_OK;
}{ ... }
#if ESP_DHCPS
static void esp_netif_dhcps_cb(void* arg, uint8_t ip[4], uint8_t mac[6])
{
esp_netif_t *esp_netif = arg;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
ip_event_ap_staipassigned_t evt = { .esp_netif = esp_netif };
memcpy((char *)&evt.ip.addr, (char *)ip, sizeof(evt.ip.addr));
memcpy((char *)&evt.mac, mac, sizeof(evt.mac));
ESP_LOGI(TAG, "DHCP server assigned IP to a client, IP is: " IPSTR, IP2STR(&evt.ip));
ESP_LOGD(TAG, "Client's MAC: %x:%x:%x:%x:%x:%x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
int ret = esp_event_post(IP_EVENT, IP_EVENT_AP_STAIPASSIGNED, &evt, sizeof(evt), 0);
if (ESP_OK != ret) {
ESP_LOGE(TAG, "dhcps cb: failed to post IP_EVENT_AP_STAIPASSIGNED (%x)", ret);
}{...}
}{ ... }
/* ... */#endif
static esp_err_t esp_netif_config_sanity_check(const esp_netif_t * esp_netif)
{
if (esp_netif == NULL) {
ESP_LOGE(TAG, "Cannot start esp_netif: esp_netif must not be null");
return ESP_ERR_INVALID_STATE;
}{...}
if ((!(esp_netif->flags & ESP_NETIF_FLAG_IS_BRIDGE) && (esp_netif->driver_transmit == NULL ||
esp_netif->driver_handle == NULL || esp_netif->lwip_input_fn == NULL)) ||
esp_netif->lwip_init_fn == NULL) {
ESP_LOGE(TAG, "Cannot start esp_netif: Missing mandatory configuration:\n"
"esp_netif->driver_transmit: %p, esp_netif->driver_handle:%p, "
"esp_netif->lwip_input_fn: %p, esp_netif->lwip_init_fn:%p",
esp_netif->driver_transmit, esp_netif->driver_handle,
esp_netif->lwip_input_fn, esp_netif->lwip_init_fn);
return ESP_ERR_INVALID_STATE;
}{...}
return ESP_OK;
}{ ... }
static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg)
{
esp_netif_t * esp_netif = msg->esp_netif;
ESP_LOGD(TAG, "%s %p", __func__, esp_netif);
if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
#if CONFIG_PPP_SUPPORT
return esp_netif_start_ppp(esp_netif);
#endif
}{...}
ESP_ERROR_CHECK(esp_netif_config_sanity_check(esp_netif));
ESP_ERROR_CHECK(esp_netif_lwip_add(esp_netif));
#if ESP_IPV6_AUTOCONFIG
esp_netif->lwip_netif->ip6_autoconfig_enabled = (esp_netif->flags & ESP_NETIF_FLAG_IPV6_AUTOCONFIG_ENABLED) ? 1 : 0;
#endif
if (esp_netif->flags&ESP_NETIF_FLAG_GARP) {
#if ESP_GRATUITOUS_ARP
netif_set_garp_flag(esp_netif->lwip_netif);
#else
ESP_LOGW(TAG,"CONFIG_LWIP_ESP_GRATUITOUS_ARP not enabled, but esp-netif configured with ESP_NETIF_FLAG_GARP");
#endif
}{...}
struct netif *p_netif = esp_netif->lwip_netif;
if (esp_netif->flags&ESP_NETIF_FLAG_AUTOUP) {
ESP_LOGD(TAG, "%s Setting the lwip netif%p UP", __func__, p_netif);
netif_set_up(p_netif);
netif_set_link_up(p_netif);
}{...}
if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
#if ESP_DHCPS
if (esp_netif->dhcps_status == ESP_NETIF_DHCP_INIT) {
if (p_netif != NULL && netif_is_up(p_netif)) {
esp_netif_ip_info_t *default_ip = esp_netif->ip_info;
ip4_addr_t lwip_ip;
ip4_addr_t lwip_netmask;
memcpy(&lwip_ip, &default_ip->ip, sizeof(struct ip4_addr));
memcpy(&lwip_netmask, &default_ip->netmask, sizeof(struct ip4_addr));
dhcps_set_new_lease_cb(esp_netif->dhcps, esp_netif_dhcps_cb, esp_netif);
dhcps_set_option_info(esp_netif->dhcps, SUBNET_MASK, (void*)&lwip_netmask, sizeof(lwip_netmask));
if (dhcps_start(esp_netif->dhcps, p_netif, lwip_ip) != ERR_OK) {
ESP_LOGE(TAG, "DHCP server cannot be started");
esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
return ESP_ERR_ESP_NETIF_DHCPS_START_FAILED;
}{...}
esp_netif->dhcps_status = ESP_NETIF_DHCP_STARTED;
ESP_LOGI(TAG, "DHCP server started on interface %s with IP: " IPSTR, esp_netif->if_key, IP2STR(&lwip_ip));
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
return ESP_OK;
}{...} else {
ESP_LOGD(TAG, "DHCP server re init");
esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
return ESP_OK;
}{...}
}{...} else if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STARTED) {
ESP_LOGD(TAG, "DHCP server already started");
return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
}{...}
return ESP_OK;/* ... */
#else
LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
#endif
}{...}
#ifndef CONFIG_LWIP_IPV4
else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
LOG_NETIF_DISABLED_AND_DO("IPv4's DHCP Client", return ESP_ERR_NOT_SUPPORTED);
}{...}
#endif/* ... */
if (!((esp_netif->flags & ESP_NETIF_DHCP_CLIENT) && esp_netif->dhcpc_status != ESP_NETIF_DHCP_STOPPED)) {
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_start(esp_netif_t *esp_netif)
{
return esp_netif_lwip_ipc_call(esp_netif_start_api, esp_netif, NULL);
}{ ... }
static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
#if CONFIG_PPP_SUPPORT
esp_err_t ret = esp_netif_stop_ppp(esp_netif->related_data);
if (ret == ESP_OK) {
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);
}{...}
return ret;/* ... */
#endif
}{...}
struct netif *lwip_netif = esp_netif->lwip_netif;
if (lwip_netif == NULL) {
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
if (!netif_is_up(lwip_netif)) {
esp_netif_lwip_remove(esp_netif);
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
#if ESP_DHCPS
if (dhcps_stop(esp_netif->dhcps, lwip_netif) != ERR_OK ||
esp_netif->dhcps_status != ESP_NETIF_DHCP_STOPPED) {
esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
}{...}
#else/* ... */
LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
#endif
}{...} else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
#if CONFIG_LWIP_IPV4
dhcp_release(lwip_netif);
dhcp_stop(lwip_netif);
dhcp_cleanup(lwip_netif);
esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
esp_netif_reset_ip_info(esp_netif);/* ... */
#else
LOG_NETIF_DISABLED_AND_DO("IPv4's DHCP Client", return ESP_ERR_NOT_SUPPORTED);
#endif
}{...}
netif_set_down(lwip_netif);
esp_netif_lwip_remove(esp_netif);
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);
return ESP_OK;
}{ ... }
esp_err_t esp_netif_stop(esp_netif_t *esp_netif)
{
return esp_netif_lwip_ipc_call(esp_netif_stop_api, esp_netif, NULL);
}{ ... }
void esp_netif_netstack_buf_ref(void *pbuf)
{
pbuf_ref(pbuf);
}{ ... }
void esp_netif_netstack_buf_free(void *pbuf)
{
pbuf_free(pbuf);
}{ ... }
void esp_netif_free_rx_buffer(void *h, void* buffer)
{
esp_netif_t *esp_netif = h;
esp_netif->driver_free_rx_buffer(esp_netif->driver_handle, buffer);
}{ ... }
#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC
static esp_err_t esp_netif_tx_rx_event_api(esp_netif_api_msg_t *msg)
{
bool enable = (bool)msg->data;
esp_netif_t *esp_netif = msg->esp_netif;
if (esp_netif == NULL) {
ESP_LOGE(TAG, "Invalid esp_netif");
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
esp_netif->tx_rx_events_enabled = enable;
return ESP_OK;
}{ ... }
/* ... */#endif
esp_err_t esp_netif_tx_rx_event_enable(esp_netif_t *esp_netif)
{
#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC
return esp_netif_lwip_ipc_call(esp_netif_tx_rx_event_api, esp_netif, (void*)true );
#else
return ESP_FAIL;
#endif
}{ ... }
esp_err_t esp_netif_tx_rx_event_disable(esp_netif_t *esp_netif)
{
#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC
return esp_netif_lwip_ipc_call(esp_netif_tx_rx_event_api, esp_netif, (void*)false );
#else
return ESP_FAIL;
#endif
}{ ... }
esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len)
{
#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC
if (unlikely(esp_netif->tx_rx_events_enabled)) {
ip_event_tx_rx_t evt = {
.esp_netif = esp_netif,
.len = len,
.dir = ESP_NETIF_TX,
}{...};
esp_event_post(IP_EVENT, IP_EVENT_TX_RX, &evt, sizeof(evt), 0);
}{...}
#endif/* ... */
return (esp_netif->driver_transmit)(esp_netif->driver_handle, data, len);
}{ ... }
esp_err_t esp_netif_transmit_wrap(esp_netif_t *esp_netif, void *data, size_t len, void *pbuf)
{
#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC
if (unlikely(esp_netif->tx_rx_events_enabled)) {
ip_event_tx_rx_t evt = {
.esp_netif = esp_netif,
.len = len,
.dir = ESP_NETIF_TX,
}{...};
esp_event_post(IP_EVENT, IP_EVENT_TX_RX, &evt, sizeof(evt), 0);
}{...}
#endif/* ... */
return (esp_netif->driver_transmit_wrap)(esp_netif->driver_handle, data, len, pbuf);
}{ ... }
esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb)
{
#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC
if (unlikely(esp_netif->tx_rx_events_enabled)) {
ip_event_tx_rx_t evt = {
.esp_netif = esp_netif,
.len = len,
.dir = ESP_NETIF_RX,
}{...};
esp_event_post(IP_EVENT, IP_EVENT_TX_RX, &evt, sizeof(evt), 0);
}{...}
#endif/* ... */
#ifdef CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS
return esp_netif->lwip_input_fn(esp_netif->netif_handle, buffer, len, eb);
#else
esp_netif->lwip_input_fn(esp_netif->netif_handle, buffer, len, eb);
return ESP_OK;/* ... */
#endif
}{ ... }
#if CONFIG_LWIP_IPV4
static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif);
static void esp_netif_internal_dhcpc_cb(struct netif *netif)
{
esp_netif_t *esp_netif;
ESP_LOGD(TAG, "%s lwip-netif:%p", __func__, netif);
if (netif == NULL || (esp_netif = lwip_get_esp_netif(netif)) == NULL) {
return;
}{...}
esp_netif_ip_info_t *ip_info = esp_netif->ip_info;
esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info_old;
if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY4) ) {
if ( (!ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), (&ip_info->ip)) ||
!ip4_addr_cmp(ip_2_ip4(&netif->netmask), (&ip_info->netmask)) ||
!ip4_addr_cmp(ip_2_ip4(&netif->gw), (&ip_info->gw)))
|| (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif))) {
ip_event_got_ip_t evt = {
.esp_netif = esp_netif,
.ip_changed = false,
}{...};
ip_event_t evt_id = esp_netif_get_event_id(esp_netif, ESP_NETIF_IP_EVENT_GOT_IP);
int ret;
ip4_addr_set(&ip_info->ip, ip_2_ip4(&netif->ip_addr));
ip4_addr_set(&ip_info->netmask, ip_2_ip4(&netif->netmask));
ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw));
if (memcmp(ip_info, ip_info_old, sizeof(esp_netif_ip_info_t))) {
evt.ip_changed = true;
}{...}
esp_netif_update_default_netif(esp_netif, ESP_NETIF_GOT_IP);
memcpy(&evt.ip_info, ip_info, sizeof(esp_netif_ip_info_t));
memcpy(ip_info_old, ip_info, sizeof(esp_netif_ip_info_t));
ESP_LOGD(TAG, "if%p ip changed=%d", esp_netif, evt.ip_changed);
ret = esp_event_post(IP_EVENT, evt_id, &evt, sizeof(evt), 0);
if (ESP_OK != ret) {
ESP_LOGE(TAG, "dhcpc cb: failed to post got ip event (%x)", ret);
}{...}
#ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP
dhcp_ip_addr_store(netif);
#endif
}{...} else {
ESP_LOGD(TAG, "if%p ip unchanged", esp_netif);
}{...}
}{...} else {
if (!ip4_addr_cmp(&ip_info->ip, IP4_ADDR_ANY4)) {
esp_netif_start_ip_lost_timer(esp_netif);
}{...}
}{...}
}{ ... }
static void esp_netif_ip_lost_timer(void *arg)
{
esp_netif_t *esp_netif = esp_netif_is_active(arg);
if (esp_netif == NULL) {
ESP_LOGD(TAG, "%s esp_netif=%p not active any more", __func__, arg);
return;
}{...}
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
esp_netif->timer_running = false;
struct netif *netif = esp_netif->lwip_netif;
if ( (!netif) || (netif && ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY4))) {
ip_event_got_ip_t evt = {
.esp_netif = esp_netif,
}{...};
int ret;
esp_netif_update_default_netif(esp_netif, ESP_NETIF_LOST_IP);
ESP_LOGD(TAG, "if%p ip lost tmr: raise ip lost event", esp_netif);
memset(esp_netif->ip_info_old, 0, sizeof(esp_netif_ip_info_t));
if (esp_netif->lost_ip_event) {
ret = esp_event_post(IP_EVENT, esp_netif->lost_ip_event,
&evt, sizeof(evt), 0);
if (ESP_OK != ret) {
ESP_LOGE(TAG, "ip lost timer: failed to post lost ip event (%x)", ret);
}{...}
}{...}
}{...} else {
ESP_LOGD(TAG, "if%p ip lost tmr: no need raise ip lost event", esp_netif);
}{...}
}{ ... }
static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif)
{
esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info;
struct netif *netif = esp_netif->lwip_netif;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif->timer_running) {
ESP_LOGD(TAG, "if%p start ip lost tmr: already started", esp_netif);
return ESP_OK;
}{...}
if ( netif && (CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL > 0)) {
esp_netif->timer_running = true;
sys_timeout(CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL * 1000, esp_netif_ip_lost_timer, (void *)esp_netif);
ESP_LOGD(TAG, "if%p start ip lost tmr: interval=%d", esp_netif, CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL);
return ESP_OK;
}{...}
ESP_LOGD(TAG, "if%p start ip lost tmr: no need start because netif=%p interval=%d ip=%" PRIx32,
esp_netif, netif, (CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL), ip_info_old->ip.addr);
return ESP_OK;
}{ ... }
static esp_err_t esp_netif_dhcpc_stop_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif == NULL) {
ESP_LOGE(TAG, "dhcp client stop called with NULL api");
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL) {
dhcp_stop(p_netif);
esp_netif_reset_ip_info(esp_netif);
esp_netif_start_ip_lost_timer(esp_netif);
}{...} else {
ESP_LOGD(TAG, "dhcp client if not ready");
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
}{...} else if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STOPPED) {
ESP_LOGD(TAG, "dhcp client already stopped");
return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
}{...}
ESP_LOGD(TAG, "dhcp client stop successfully");
esp_netif->dhcpc_status = ESP_NETIF_DHCP_STOPPED;
#ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP
dhcp_ip_addr_erase(esp_netif->lwip_netif);
#endif
return ESP_OK;
}{ ... }
esp_err_t esp_netif_dhcpc_stop(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_stop_api, esp_netif, NULL)
static void dns_clear_servers(bool keep_fallback)
{
u8_t numdns = 0;
for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) {
if (keep_fallback && numdns == DNS_FALLBACK_SERVER_INDEX) {
continue;
}{...}
dns_setserver(numdns, NULL);
}{...}
}{ ... }
static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (!esp_netif) {
return ESP_ERR_INVALID_ARG;
}{...}
if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
ESP_LOGD(TAG, "dhcp client already started");
return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
}{...}
struct netif *p_netif = esp_netif->lwip_netif;
esp_netif_reset_ip_info(esp_netif);
#if LWIP_DNS
dns_clear_servers(true);
#endif
if (p_netif != NULL) {
if (netif_is_up(p_netif)) {
ip_addr_set_zero(&p_netif->ip_addr);
ip_addr_set_zero(&p_netif->netmask);
ip_addr_set_zero(&p_netif->gw);
esp_netif_start_ip_lost_timer(esp_netif);
}{...} else {
ESP_LOGD(TAG, "dhcp client re init");
esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
return ESP_OK;
}{...}
ESP_LOGD(TAG, "starting dhcp client");
if (dhcp_start(p_netif) != ERR_OK) {
ESP_LOGE(TAG, "dhcp client start failed");
return ESP_ERR_ESP_NETIF_DHCPC_START_FAILED;
}{...}
esp_netif->dhcpc_status = ESP_NETIF_DHCP_STARTED;
return ESP_OK;
}{...} else {
ESP_LOGD(TAG, "dhcp client re init");
esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
return ESP_OK;
}{...}
}{ ... }
esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_start_api, esp_netif, NULL)/* ... */
#endif
#if ESP_DHCPS
esp_err_t esp_netif_dhcps_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
{
if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
return ESP_ERR_INVALID_ARG;
}{...}
*status = esp_netif->dhcps_status;
return ESP_OK;
}{ ... }
/* ... */#endif
esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
{
if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_SERVER) || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
return ESP_ERR_INVALID_ARG;
}{...}
*status = esp_netif->dhcpc_status;
return ESP_OK;
}{ ... }
#if ESP_DHCPS
static esp_err_t esp_netif_dhcps_start_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (!esp_netif) {
return ESP_ERR_INVALID_ARG;
}{...}
if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STARTED) {
ESP_LOGD(TAG, "dhcp server already started");
return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
}{...}
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && netif_is_up(p_netif)) {
esp_netif_ip_info_t *default_ip = esp_netif->ip_info;
ip4_addr_t lwip_ip;
ip4_addr_t lwip_netmask;
memcpy(&lwip_ip, &default_ip->ip, sizeof(struct ip4_addr));
memcpy(&lwip_netmask, &default_ip->netmask, sizeof(struct ip4_addr));
dhcps_set_new_lease_cb(esp_netif->dhcps, esp_netif_dhcps_cb, esp_netif);
dhcps_set_option_info(esp_netif->dhcps, SUBNET_MASK, (void*)&lwip_netmask, sizeof(lwip_netmask));
if (dhcps_start(esp_netif->dhcps, p_netif, lwip_ip) != ERR_OK) {
ESP_LOGE(TAG, "DHCP server cannot be started");
esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
return ESP_ERR_ESP_NETIF_DHCPS_START_FAILED;
}{...}
esp_netif->dhcps_status = ESP_NETIF_DHCP_STARTED;
ESP_LOGD(TAG, "DHCP server started successfully");
return ESP_OK;
}{...} else {
ESP_LOGD(TAG, "dhcp server re init");
esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
return ESP_OK;
}{...}
}{ ... }
esp_err_t esp_netif_dhcps_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcps_start_api, esp_netif, NULL)
static esp_err_t esp_netif_dhcps_stop_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (!esp_netif) {
return ESP_ERR_INVALID_ARG;
}{...}
struct netif *p_netif = esp_netif->lwip_netif;
if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STARTED) {
if (dhcps_stop(esp_netif->dhcps, p_netif) != ERR_OK) {
ESP_LOGD(TAG, "dhcp server if not ready");
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
}{...} else if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STOPPED) {
ESP_LOGD(TAG, "dhcp server already stopped");
return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
}{...}
ESP_LOGD(TAG, "dhcp server stop successfully");
esp_netif->dhcps_status = ESP_NETIF_DHCP_STOPPED;
return ESP_OK;
}{ ... }
esp_err_t esp_netif_dhcps_stop(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcps_stop_api, esp_netif, NULL)/* ... */
#endif
static esp_err_t esp_netif_set_hostname_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
const char *hostname = msg->data;
ESP_LOGD(TAG, "%s esp_netif:%p hostname %s", __func__, esp_netif, hostname);
if (!esp_netif) {
return ESP_ERR_INVALID_ARG;
}{...}
#if LWIP_NETIF_HOSTNAME
struct netif *p_netif = esp_netif->lwip_netif;
if (strlen(hostname) > ESP_NETIF_HOSTNAME_MAX_SIZE) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
if (p_netif != NULL) {
if (esp_netif->hostname) {
free(esp_netif->hostname);
}{...}
esp_netif->hostname = strdup(hostname);
if (esp_netif->hostname == NULL) {
p_netif->hostname = CONFIG_LWIP_LOCAL_HOSTNAME;
return ESP_ERR_NO_MEM;
}{...}
p_netif->hostname = esp_netif->hostname;
return ESP_OK;
}{...} else {
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
/* ... */#else
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
#endif
}{ ... }
esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_hostname_api, esp_netif, hostname)
esp_err_t esp_netif_get_hostname(esp_netif_t *esp_netif, const char **hostname)
{
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (!esp_netif || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
return ESP_ERR_INVALID_ARG;
}{...}
#if LWIP_NETIF_HOSTNAME
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && p_netif->hostname != NULL) {
*hostname = p_netif->hostname;
return ESP_OK;
}{...} else {
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
/* ... */#else
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
#endif
}{ ... }
static esp_err_t esp_netif_up_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (!esp_netif) {
return ESP_ERR_INVALID_STATE;
}{...}
struct netif *lwip_netif = esp_netif->lwip_netif;
#if CONFIG_LWIP_IPV4
netif_set_addr(lwip_netif, (ip4_addr_t*)&esp_netif->ip_info->ip, (ip4_addr_t*)&esp_netif->ip_info->netmask, (ip4_addr_t*)&esp_netif->ip_info->gw);/* ... */
#endif
netif_set_up(lwip_netif);
netif_set_link_up(lwip_netif);
if (!((esp_netif->flags & ESP_NETIF_DHCP_CLIENT) && esp_netif->dhcpc_status != ESP_NETIF_DHCP_STOPPED)) {
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_up(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK(esp_netif_up_api, esp_netif, NULL)
static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (!esp_netif) {
return ESP_ERR_INVALID_STATE;
}{...}
struct netif *lwip_netif = esp_netif->lwip_netif;
if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT && esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
#if CONFIG_LWIP_IPV4
dhcp_stop(esp_netif->lwip_netif);
esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
esp_netif_reset_ip_info(esp_netif);/* ... */
#endif
}{...}
#if CONFIG_LWIP_IPV6
#if ESP_MLDV6_REPORT
if (esp_netif->flags & ESP_NETIF_FLAG_MLDV6_REPORT) {
netif_unset_mldv6_flag(esp_netif);
}{...}
#endif/* ... */
for(int8_t i = 0 ;i < LWIP_IPV6_NUM_ADDRESSES ;i++) {
netif_ip6_addr_set(lwip_netif, i, IP6_ADDR_ANY6);
netif_ip6_addr_set_valid_life(lwip_netif, i, 0);
netif_ip6_addr_set_pref_life(lwip_netif, i, 0);
netif_ip6_addr_set_state(lwip_netif, i, IP6_ADDR_INVALID);
}{...}
#endif/* ... */
#if CONFIG_LWIP_IPV4
netif_set_addr(lwip_netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
#endif
netif_set_down(lwip_netif);
netif_set_link_down(lwip_netif);
if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
#if CONFIG_LWIP_IPV4
esp_netif_start_ip_lost_timer(esp_netif);
#endif
}{...}
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);
return ESP_OK;
}{ ... }
esp_err_t esp_netif_down(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK(esp_netif_down_api, esp_netif, NULL)
bool esp_netif_is_netif_up(esp_netif_t *esp_netif)
{
ESP_LOGV(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif != NULL && esp_netif->lwip_netif != NULL) {
if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
return netif_is_link_up(esp_netif->lwip_netif);
}{...}
return netif_is_up(esp_netif->lwip_netif);
}{...} else {
return false;
}{...}
}{ ... }
#if CONFIG_LWIP_IPV4
esp_err_t esp_netif_get_old_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
{
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif == NULL || ip_info == NULL) {
return ESP_ERR_INVALID_ARG;
}{...}
memcpy(ip_info, esp_netif->ip_info_old, sizeof(esp_netif_ip_info_t));
return ESP_OK;
}{ ... }
esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
{
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif == NULL || ip_info == NULL) {
return ESP_ERR_INVALID_ARG;
}{...}
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && netif_is_up(p_netif)) {
ip4_addr_set(&ip_info->ip, ip_2_ip4(&p_netif->ip_addr));
ip4_addr_set(&ip_info->netmask, ip_2_ip4(&p_netif->netmask));
ip4_addr_set(&ip_info->gw, ip_2_ip4(&p_netif->gw));
return ESP_OK;
}{...}
memcpy(ip_info, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));
return ESP_OK;
}{ ... }
bool esp_netif_is_valid_static_ip(esp_netif_ip_info_t *ip_info)
{
if (!(ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask))) {
return true;
}{...}
return false;
}{ ... }
static esp_err_t esp_netif_set_ip_old_info_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
const esp_netif_ip_info_t *ip_info = msg->data;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif == NULL || ip_info == NULL) {
return ESP_ERR_INVALID_STATE;
}{...}
memcpy(msg->esp_netif->ip_info_old, msg->data, sizeof(esp_netif_ip_info_t));
return ESP_OK;
}{ ... }
esp_err_t esp_netif_set_old_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_ip_old_info_api, esp_netif, ip_info)
static esp_err_t esp_netif_set_ip_info_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
const esp_netif_ip_info_t *ip_info = msg->data;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif == NULL || ip_info == NULL) {
return ESP_ERR_INVALID_STATE;
}{...}
if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
if (esp_netif->dhcps_status != ESP_NETIF_DHCP_STOPPED) {
return ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED;
}{...}
}{...} else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
if (esp_netif->dhcpc_status != ESP_NETIF_DHCP_STOPPED) {
return ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED;
}{...}
#if LWIP_DNS
dns_clear_servers(true);
#endif
}{...}
ip4_addr_copy(esp_netif->ip_info->ip, ip_info->ip);
ip4_addr_copy(esp_netif->ip_info->gw, ip_info->gw);
ip4_addr_copy(esp_netif->ip_info->netmask, ip_info->netmask);
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && netif_is_up(p_netif)) {
netif_set_addr(p_netif, (ip4_addr_t*)&ip_info->ip, (ip4_addr_t*)&ip_info->netmask, (ip4_addr_t*)&ip_info->gw);
if (ESP_NETIF_FLAG_EVENT_IP_MODIFIED & esp_netif->flags) {
if (!ip4_addr_isany_val(ip_info->ip)) {
ip_event_t evt_id = esp_netif->get_ip_event;
ip_event_got_ip_t evt = { .esp_netif = esp_netif, .ip_changed = false};
int ret;
if (memcmp(ip_info, esp_netif->ip_info_old, sizeof(esp_netif_ip_info_t))) {
evt.ip_changed = true;
}{...}
esp_netif_update_default_netif(esp_netif, ESP_NETIF_GOT_IP);
memcpy(&evt.ip_info, ip_info, sizeof(esp_netif_ip_info_t));
memcpy(esp_netif->ip_info_old, ip_info, sizeof(esp_netif_ip_info_t));
ret = esp_event_post(IP_EVENT, evt_id, &evt, sizeof(evt), 0);
if (ESP_OK != ret) {
ESP_LOGE(TAG, "set ip info: failed to post got ip event (%x)", ret);
}{...}
ESP_LOGD(TAG, "if%p netif set static ip: ip changed=%d", esp_netif, evt.ip_changed);
}{...}
}{...}
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_set_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_ip_info_api, esp_netif, ip_info)/* ... */
#endif
struct array_mac_ip_t {
int num;
esp_netif_pair_mac_ip_t *mac_ip_pair;
}{ ... };
#if CONFIG_LWIP_DHCPS
static esp_err_t esp_netif_dhcps_get_clients_by_mac_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *netif = msg->esp_netif;
struct array_mac_ip_t *mac_ip_list = msg->data;
for (int i = 0; i < mac_ip_list->num; i++) {
dhcp_search_ip_on_mac(netif->dhcps, mac_ip_list->mac_ip_pair[i].mac, (ip4_addr_t*)&mac_ip_list->mac_ip_pair[i].ip);
}{...}
return ESP_OK;
}{ ... }
/* ... */#endif
esp_err_t esp_netif_dhcps_get_clients_by_mac(esp_netif_t *esp_netif, int num, esp_netif_pair_mac_ip_t *mac_ip_pair)
{
#if CONFIG_LWIP_DHCPS
if (esp_netif == NULL || esp_netif->dhcps == NULL || num < 0 || mac_ip_pair == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
struct array_mac_ip_t array_mac_ip = { num, mac_ip_pair };
return esp_netif_lwip_ipc_call(esp_netif_dhcps_get_clients_by_mac_api, esp_netif, (void *)&array_mac_ip);/* ... */
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}{ ... }
static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
esp_netif_dns_param_t *dns_param = msg->data;
esp_netif_dns_type_t type = dns_param->dns_type;
esp_netif_dns_info_t *dns = dns_param->dns_info;
ESP_LOGD(TAG, "esp_netif_set_dns_info: if=%p type=%d dns=%" PRIx32, esp_netif, type, dns->ip.u_addr.ip4.addr);
ip_addr_t lwip_ip = {};
ESPIP_TO_IP(&dns->ip, &lwip_ip);
if (esp_netif && esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
#if ESP_DHCPS
if (type != ESP_NETIF_DNS_MAIN) {
ESP_LOGD(TAG, "set dns invalid type");
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...} else {
dhcps_dns_setserver(esp_netif->dhcps, &lwip_ip);
}{...}
#else/* ... */
LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
#endif
}{...} else {
#ifdef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF
if (esp_netif) {
store_dnsserver_info(esp_netif->lwip_netif, type, &lwip_ip);
}{...}
if (esp_netif == s_last_default_esp_netif ||
esp_netif == NULL) {
dns_setserver(type, &lwip_ip);
}{...}
#else/* ... */
dns_setserver(type, &lwip_ip);
#endif
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_set_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns)
{
#ifndef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF
if (esp_netif == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
#endif/* ... */
if (dns == NULL) {
ESP_LOGD(TAG, "set dns null dns");
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
if (ESP_IP_IS_ANY(dns->ip)) {
ESP_LOGD(TAG, "set dns invalid dns");
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
esp_netif_dns_param_t dns_param = {
.dns_type = type,
.dns_info = dns
}{...};
return esp_netif_lwip_ipc_call(esp_netif_set_dns_info_api, esp_netif, (void *)&dns_param);
}{ ... }
static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
esp_netif_dns_param_t *dns_param = msg->data;
esp_netif_dns_type_t type = dns_param->dns_type;
esp_netif_dns_info_t *dns = dns_param->dns_info;
ESP_LOGD(TAG, "esp_netif_get_dns_info: esp_netif=%p type=%d", esp_netif, type);
if (esp_netif && esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
#if ESP_DHCPS
ip4_addr_t dns_ip;
dhcps_dns_getserver(esp_netif->dhcps, &dns_ip);
memcpy(&dns->ip.u_addr.ip4, &dns_ip, sizeof(ip4_addr_t));
dns->ip.type = ESP_IPADDR_TYPE_V4;/* ... */
#else
LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
#endif
}{...} else {
const ip_addr_t* dns_ip = NULL;
#ifdef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF
if (esp_netif == NULL) {
dns_ip = dns_getserver(type);
}{...} else {
dns_ip = &esp_netif->dns[type];
}{...}
#else/* ... */
dns_ip = dns_getserver(type);
#endif
if(dns_ip != NULL) {
IP_TO_ESPIP(dns_ip, &dns->ip);
}{...}
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_get_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns)
{
#ifndef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF
if (esp_netif == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
#endif/* ... */
if (dns == NULL) {
ESP_LOGE(TAG, "%s: dns_info cannot be NULL", __func__);
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
esp_netif_dns_param_t dns_param = {
.dns_type = type,
.dns_info = dns
}{...};
return esp_netif_lwip_ipc_call(esp_netif_get_dns_info_api, esp_netif, (void *)&dns_param);
}{ ... }
#if CONFIG_LWIP_IPV6
#ifdef CONFIG_LWIP_MLDV6_TMR_INTERVAL
static void netif_send_mldv6(void *arg)
{
esp_netif_t *esp_netif = arg;
esp_netif->mldv6_report_timer_started = false;
if (!netif_is_up(esp_netif->lwip_netif)) {
return;
}{...}
mld6_report_groups(esp_netif->lwip_netif);
esp_netif->mldv6_report_timer_started = true;
sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, esp_netif);
}{ ... }
static void netif_set_mldv6_flag(esp_netif_t *esp_netif)
{
if (!netif_is_up(esp_netif->lwip_netif) || esp_netif->mldv6_report_timer_started) {
return;
}{...}
esp_netif->mldv6_report_timer_started = true;
sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, esp_netif);
}{ ... }
static void netif_unset_mldv6_flag(esp_netif_t *esp_netif)
{
if (esp_netif->mldv6_report_timer_started) {
esp_netif->mldv6_report_timer_started = false;
sys_untimeout(netif_send_mldv6, esp_netif);
}{...}
}{ ... }
/* ... */#endif
esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr)
{
ip6_addr_t* lwip_ip6_info = (ip6_addr_t*)ip6_addr;
if (ip6_addr_isglobal(lwip_ip6_info)) {
return ESP_IP6_ADDR_IS_GLOBAL;
}{...} else if (ip6_addr_islinklocal(lwip_ip6_info)) {
return ESP_IP6_ADDR_IS_LINK_LOCAL;
}{...} else if (ip6_addr_issitelocal(lwip_ip6_info)) {
return ESP_IP6_ADDR_IS_SITE_LOCAL;
}{...} else if (ip6_addr_isuniquelocal(lwip_ip6_info)) {
return ESP_IP6_ADDR_IS_UNIQUE_LOCAL;
}{...} else if (ip6_addr_isipv4mappedipv6(lwip_ip6_info)) {
return ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6;
}{...}
return ESP_IP6_ADDR_IS_UNKNOWN;
}{ ... }
static void esp_netif_internal_nd6_cb(struct netif *netif, uint8_t ip_index)
{
esp_netif_t *esp_netif;
ESP_LOGD(TAG, "%s lwip-netif:%p", __func__, netif);
if (netif == NULL || (esp_netif = lwip_get_esp_netif(netif)) == NULL) {
return;
}{...}
esp_netif_ip6_info_t ip6_info;
ip6_addr_t lwip_ip6_info;
ip_event_got_ip6_t evt = { .esp_netif = esp_netif, .ip_index = ip_index };
ip6_addr_set(&lwip_ip6_info, ip_2_ip6(&netif->ip6_addr[ip_index]));
#if LWIP_IPV6_SCOPES
memcpy(&ip6_info.ip, &lwip_ip6_info, sizeof(esp_ip6_addr_t));
#else
memcpy(&ip6_info.ip, &lwip_ip6_info, sizeof(ip6_addr_t));
ip6_info.ip.zone = 0; /* ... */
#endif
if (esp_netif->flags&ESP_NETIF_FLAG_MLDV6_REPORT) {
#if ESP_MLDV6_REPORT
netif_set_mldv6_flag(esp_netif);
#else
ESP_LOGW(TAG,"CONFIG_LWIP_ESP_MLDV6_REPORT not enabled, but esp-netif configured with ESP_NETIF_FLAG_MLDV6_REPORT");
#endif
}{...}
esp_netif_update_default_netif(esp_netif, ESP_NETIF_GOT_IP);
memcpy(&evt.ip6_info, &ip6_info, sizeof(esp_netif_ip6_info_t));
int ret = esp_event_post(IP_EVENT, IP_EVENT_GOT_IP6, &evt, sizeof(evt), 0);
if (ESP_OK != ret) {
ESP_LOGE(TAG, "nd6 cb: failed to post IP_EVENT_GOT_IP6 (%x)", ret);
}{...}
}{ ... }
static esp_err_t esp_netif_create_ip6_linklocal_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && netif_is_up(p_netif)) {
netif_create_ip6_linklocal_address(p_netif, 1);
return ESP_OK;
}{...} else {
return ESP_FAIL;
}{...}
}{ ... }
esp_err_t esp_netif_create_ip6_linklocal(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_create_ip6_linklocal_api, esp_netif, NULL)
esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
{
ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
if (esp_netif == NULL || if_ip6 == NULL || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && netif_is_up(p_netif) && ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, 0))) {
memcpy(if_ip6, &p_netif->ip6_addr[0], sizeof(ip6_addr_t));
}{...} else {
return ESP_FAIL;
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_get_ip6_global(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
{
ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
if (esp_netif == NULL || if_ip6 == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
int i;
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && netif_is_up(p_netif)) {
for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, i)) &&
ip6_addr_isglobal(netif_ip6_addr(p_netif, i))) {
memcpy(if_ip6, &p_netif->ip6_addr[i], sizeof(ip6_addr_t));
return ESP_OK;
}{...}
}{...}
}{...}
return ESP_FAIL;
}{ ... }
int esp_netif_get_all_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[])
{
ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
if (esp_netif == NULL || if_ip6 == NULL) {
return 0;
}{...}
int addr_count = 0;
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && netif_is_up(p_netif)) {
for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isvalid(netif_ip6_addr_state(p_netif, i)) && !ip_addr_cmp(&p_netif->ip6_addr[i], IP6_ADDR_ANY)) {
memcpy(&if_ip6[addr_count++], &p_netif->ip6_addr[i], sizeof(ip6_addr_t));
}{...}
}{...}
}{...}
return addr_count;
}{ ... }
int esp_netif_get_all_preferred_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[])
{
ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
if (esp_netif == NULL || if_ip6 == NULL) {
return 0;
}{...}
int addr_count = 0;
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && netif_is_up(p_netif)) {
for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, i)) && !ip_addr_cmp(&p_netif->ip6_addr[i], IP6_ADDR_ANY)) {
memcpy(&if_ip6[addr_count++], &p_netif->ip6_addr[i], sizeof(ip6_addr_t));
}{...}
}{...}
}{...}
return addr_count;
}{ ... }
#endif/* ... */
esp_netif_flags_t esp_netif_get_flags(esp_netif_t *esp_netif)
{
return esp_netif->flags;
}{ ... }
const char *esp_netif_get_ifkey(esp_netif_t *esp_netif)
{
return esp_netif->if_key;
}{ ... }
const char *esp_netif_get_desc(esp_netif_t *esp_netif)
{
return esp_netif->if_desc;
}{ ... }
int esp_netif_get_route_prio(esp_netif_t *esp_netif)
{
if (esp_netif == NULL) {
return -1;
}{...}
return esp_netif->route_prio;
}{ ... }
int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t event_type)
{
switch(event_type) {
case ESP_NETIF_IP_EVENT_GOT_IP:
return esp_netif->get_ip_event;...
case ESP_NETIF_IP_EVENT_LOST_IP:
return esp_netif->lost_ip_event;...
default:
return -1;...
}{...}
}{ ... }
struct dhcp_params {
esp_netif_dhcp_option_mode_t op;
esp_netif_dhcp_option_id_t id;
void *val;
uint32_t len;
}{ ... };
#if ESP_DHCPS
esp_err_t esp_netif_dhcps_option_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
struct dhcp_params *opt = msg->data;
void *opt_info = dhcps_option_info(esp_netif->dhcps, opt->id, opt->len);
esp_netif_dhcp_status_t dhcps_status = esp_netif->dhcps_status;
if (opt_info == NULL || opt->val == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
if (opt->op == ESP_NETIF_OP_GET) {
if (dhcps_status == ESP_NETIF_DHCP_STOPPED) {
return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
}{...}
switch (opt->id) {
case IP_ADDRESS_LEASE_TIME: {
*(uint32_t *)opt->val = *(uint32_t *)opt_info;
break;
}{...}
... case ESP_NETIF_SUBNET_MASK:
case REQUESTED_IP_ADDRESS: {
memcpy(opt->val, opt_info, opt->len);
break;
}{...}
... case ROUTER_SOLICITATION_ADDRESS: {
if ((*(uint8_t *)opt_info) & OFFER_ROUTER) {
*(uint8_t *)opt->val = 1;
}{...} else {
*(uint8_t *)opt->val = 0;
}{...}
break;
}{...}
... case DOMAIN_NAME_SERVER: {
if ((*(uint8_t *)opt_info) & OFFER_DNS) {
*(uint8_t *)opt->val = 1;
}{...} else {
*(uint8_t *)opt->val = 0;
}{...}
break;
}{...}
... default:
break;...
}{...}
}{...} else if (opt->op == ESP_NETIF_OP_SET) {
if (dhcps_status == ESP_NETIF_DHCP_STARTED) {
return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
}{...}
switch (opt->id) {
case IP_ADDRESS_LEASE_TIME: {
if (*(uint32_t *)opt->val != 0) {
*(uint32_t *)opt_info = *(uint32_t *)opt->val;
}{...} else {
*(uint32_t *)opt_info = DHCPS_LEASE_TIME_DEF;
}{...}
break;
}{...}
... case ESP_NETIF_SUBNET_MASK: {
esp_netif_ip_info_t *default_ip = esp_netif->ip_info;
ip4_addr_t *config_netmask = (ip4_addr_t *)opt->val;
if (!memcmp(&default_ip->netmask, config_netmask, sizeof(struct ip4_addr))) {
ESP_LOGE(TAG, "Please use esp_netif_set_ip_info interface to configure subnet mask");
/* ... */
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
memcpy(opt_info, opt->val, opt->len);
break;
}{...}
... case REQUESTED_IP_ADDRESS: {
esp_netif_ip_info_t info;
uint32_t server_ip = 0;
uint32_t start_ip = 0;
uint32_t end_ip = 0;
uint32_t range_start_ip = 0;
uint32_t range_end_ip = 0;
dhcps_lease_t *poll = opt->val;
if (poll->enable) {
memset(&info, 0x00, sizeof(esp_netif_ip_info_t));
esp_netif_get_ip_info(esp_netif, &info);
server_ip = htonl(info.ip.addr);
range_start_ip = server_ip & htonl(info.netmask.addr);
range_end_ip = range_start_ip | ~htonl(info.netmask.addr);
if (server_ip == range_start_ip || server_ip == range_end_ip) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
start_ip = htonl(poll->start_ip.addr);
end_ip = htonl(poll->end_ip.addr);
if ((server_ip >= start_ip) && (server_ip <= end_ip)) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
if (start_ip <= range_start_ip || start_ip >= range_end_ip) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
if (end_ip <= range_start_ip || end_ip >= range_end_ip) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
if ((end_ip - start_ip + 1 > DHCPS_MAX_LEASE) || (start_ip >= end_ip)) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
}{...}
memcpy(opt_info, opt->val, opt->len);
break;
}{...}
... case ROUTER_SOLICITATION_ADDRESS: {
if (*(uint8_t *)opt->val) {
*(uint8_t *)opt_info |= OFFER_ROUTER;
}{...} else {
*(uint8_t *)opt_info &= ((~OFFER_ROUTER) & 0xFF);
}{...}
break;
}{...}
... case DOMAIN_NAME_SERVER: {
if (*(uint8_t *)opt->val) {
*(uint8_t *)opt_info |= OFFER_DNS;
}{...} else {
*(uint8_t *)opt_info &= ((~OFFER_DNS) & 0xFF);
}{...}
break;
}{...}
... case ESP_NETIF_CAPTIVEPORTAL_URI: {
opt_info = (char *)opt->val;
break;
}{...}
...
default:
break;...
}{...}
dhcps_set_option_info(esp_netif->dhcps, opt->id, opt_info, opt->len);
}{...} else {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val,
uint32_t opt_len)
{
if (esp_netif == NULL || esp_netif->dhcps == NULL) {
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
struct dhcp_params opts = { .op = opt_op, .id = opt_id, .len = opt_len, .val = opt_val };
return esp_netif_lwip_ipc_call(esp_netif_dhcps_option_api, esp_netif, &opts);
}{ ... }
#endif/* ... */
#if CONFIG_LWIP_IPV4
esp_err_t esp_netif_dhcpc_option_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
struct dhcp_params *opt = msg->data;
struct dhcp *dhcp = netif_dhcp_data(esp_netif->lwip_netif);
if (dhcp == NULL || opt->val == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
if (opt->op == ESP_NETIF_OP_GET) {
if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STOPPED) {
return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
}{...}
switch (opt->id) {
case ESP_NETIF_IP_REQUEST_RETRY_TIME:
if (opt->len == sizeof(dhcp->tries)) {
*(uint8_t *)opt->val = dhcp->tries;
}{...}
break;
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER...
case ESP_NETIF_VENDOR_SPECIFIC_INFO:
return dhcp_get_vendor_specific_information(opt->len, opt->val);/* ... */
#endif
default:
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;...
}{...}
}{...} else if (opt->op == ESP_NETIF_OP_SET) {
if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
}{...}
switch (opt->id) {
case ESP_NETIF_IP_REQUEST_RETRY_TIME:
if (opt->len == sizeof(dhcp->tries)) {
dhcp->tries = *(uint8_t *)opt->val;
}{...}
break;
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER...
case ESP_NETIF_VENDOR_CLASS_IDENTIFIER:
return dhcp_set_vendor_class_identifier(opt->len, opt->val);/* ... */
#endif
default:
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;...
}{...}
}{...} else {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_dhcpc_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val,
uint32_t opt_len)
{
if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
}{...}
struct dhcp_params opts = { .op = opt_op, .id = opt_id, .len = opt_len, .val = opt_val };
return esp_netif_lwip_ipc_call(esp_netif_dhcpc_option_api, esp_netif, &opts);
}{ ... }
/* ... */#endif
int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif)
{
if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
return -1;
}{...}
return netif_get_index(esp_netif->lwip_netif);
}{ ... }
esp_err_t esp_netif_get_netif_impl_name_api(esp_netif_api_msg_t *msg)
{
struct netif* netif = msg->esp_netif->lwip_netif;
netif_index_to_name(netif_get_index(netif), msg->data);
return ESP_OK;
}{ ... }
esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char* name)
{
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}{...}
return esp_netif_lwip_ipc_call(esp_netif_get_netif_impl_name_api, esp_netif, name);
}{ ... }
#if IP_NAPT
static esp_err_t esp_netif_napt_control_api(esp_netif_api_msg_t *msg)
{
bool enable = (bool)msg->data;
esp_netif_t *esp_netif = msg->esp_netif;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (!netif_is_up(esp_netif->lwip_netif)) {
return ESP_FAIL;
}{...}
if (enable) {
esp_netif_t *netif = esp_netif_next_unsafe(NULL);
while (netif) {
if (netif != esp_netif && netif->lwip_netif->napt == 1) {
ip_napt_enable_netif(netif->lwip_netif, 0);
ESP_LOGW(TAG, "napt disabled on esp_netif:%p", esp_netif);
}{...}
netif = esp_netif_next_unsafe(netif);
}{...}
int ret = ip_napt_enable_netif(esp_netif->lwip_netif, 1);
if (ret == 0) {
return ESP_FAIL;
}{...}
return ESP_OK;
}{...} else {
ip_napt_enable_netif(esp_netif->lwip_netif, 0);
ESP_LOGD(TAG, "napt disabled on esp_netif:%p", esp_netif);
return ESP_OK;
}{...}
}{...}
/* ... */#endif
esp_err_t esp_netif_napt_enable(esp_netif_t *esp_netif)
{
#if !IP_NAPT
return ESP_ERR_NOT_SUPPORTED;
#else
return esp_netif_lwip_ipc_call(esp_netif_napt_control_api, esp_netif, (void*)true );
#endif
}{ ... }
typedef struct {
u8_t authtype;
const char *user;
const char *passwd;
}{ ... } set_auth_msg_t;
static esp_err_t esp_netif_ppp_set_auth_api(esp_netif_api_msg_t *msg)
{
set_auth_msg_t *params = msg->data;
return esp_netif_ppp_set_auth_internal(msg->esp_netif, params->authtype, params->user, params->passwd);
}{ ... }
esp_err_t esp_netif_ppp_set_auth(esp_netif_t *esp_netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd)
{
set_auth_msg_t msg = { .authtype = authtype, .user = user, .passwd = passwd };
return esp_netif_lwip_ipc_call(esp_netif_ppp_set_auth_api, esp_netif, &msg);
}{ ... }
esp_err_t esp_netif_napt_disable(esp_netif_t *esp_netif)
{
#if !IP_NAPT
return ESP_ERR_NOT_SUPPORTED;
#else
return esp_netif_lwip_ipc_call(esp_netif_napt_control_api, esp_netif, (void*)false );
#endif
}{ ... }
#if MIB2_STATS
static esp_err_t esp_netif_set_link_speed_api(esp_netif_api_msg_t *msg)
{
uint32_t speed = *((uint32_t*)msg->data);
esp_err_t error = ESP_OK;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
NETIF_INIT_SNMP(msg->esp_netif->lwip_netif, snmp_ifType_ethernet_csmacd, speed);
LWIP_UNUSED_ARG(speed);
return error;
}{...}
esp_err_t esp_netif_set_link_speed(esp_netif_t *esp_netif, uint32_t speed)
_RUN_IN_LWIP_TASK(esp_netif_set_link_speed_api, esp_netif, &speed)/* ... */
#else
esp_err_t esp_netif_set_link_speed(esp_netif_t *esp_netif, uint32_t speed)
{
return ESP_OK;
}{ ... }
/* ... */#endif
#if CONFIG_LWIP_IPV6
static esp_err_t esp_netif_join_ip6_multicast_group_api(esp_netif_api_msg_t *msg)
{
esp_ip6_addr_t *addr = (esp_ip6_addr_t *)msg->data;
esp_err_t error = ESP_OK;
ip6_addr_t ip6addr;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
memcpy(ip6addr.addr, addr->addr, sizeof(ip6addr.addr));
#if LWIP_IPV6_SCOPES
ip6addr.zone = 0;
#endif
if (mld6_joingroup_netif(msg->esp_netif->lwip_netif, &ip6addr) != ERR_OK) {
error = ESP_ERR_ESP_NETIF_MLD6_FAILED;
ESP_LOGE(TAG, "failed to join ip6 multicast group");
}{...}
return error;
}{ ... }
esp_err_t esp_netif_join_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
_RUN_IN_LWIP_TASK(esp_netif_join_ip6_multicast_group_api, esp_netif, addr)
static esp_err_t esp_netif_leave_ip6_multicast_group_api(esp_netif_api_msg_t *msg)
{
esp_ip6_addr_t *addr = (esp_ip6_addr_t *)msg->data;
ip6_addr_t ip6addr;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
memcpy(ip6addr.addr, addr->addr, sizeof(ip6addr.addr));
#if LWIP_IPV6_SCOPES
ip6addr.zone = 0;
#endif
ESP_RETURN_ON_FALSE(mld6_leavegroup_netif(msg->esp_netif->lwip_netif, &ip6addr) == ERR_OK,
ESP_ERR_ESP_NETIF_MLD6_FAILED, TAG, "Failed to leave ip6 multicast group");
return ESP_OK;
}{ ... }
esp_err_t esp_netif_leave_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
_RUN_IN_LWIP_TASK(esp_netif_leave_ip6_multicast_group_api, esp_netif, addr)
static esp_err_t esp_netif_add_ip6_address_api(esp_netif_api_msg_t *msg)
{
ip_event_add_ip6_t *addr = (ip_event_add_ip6_t *)msg->data;
ip6_addr_t ip6addr;
esp_err_t error = ESP_OK;
int8_t index = -1;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
memcpy(ip6addr.addr, addr->addr.addr, sizeof(ip6addr.addr));
#if LWIP_IPV6_SCOPES
ip6addr.zone = 0;
#endif
err_t err = netif_add_ip6_address(msg->esp_netif->lwip_netif, &ip6addr, &index);
ESP_RETURN_ON_FALSE(err == ERR_OK && index >= 0, ESP_ERR_ESP_NETIF_IP6_ADDR_FAILED, TAG,
"Failed to add ip6 address");
esp_netif_update_default_netif(msg->esp_netif, ESP_NETIF_GOT_IP);
netif_ip6_addr_set_state(msg->esp_netif->lwip_netif, index,
addr->preferred ? IP6_ADDR_PREFERRED : IP6_ADDR_DEPRECATED);
ip_event_got_ip6_t evt = {.esp_netif = msg->esp_netif, .ip_index = index};
evt.ip6_info.ip = addr->addr;
ESP_RETURN_ON_ERROR(esp_event_post(IP_EVENT, IP_EVENT_GOT_IP6, &evt, sizeof(evt), 0), TAG,
"Failed to post IP_EVENT_GOT_IP6");
return error;
}{ ... }
static esp_err_t esp_netif_add_ip6_address_priv(esp_netif_t *esp_netif, const ip_event_add_ip6_t *addr)
_RUN_IN_LWIP_TASK(esp_netif_add_ip6_address_api, esp_netif, addr)
esp_err_t esp_netif_add_ip6_address(esp_netif_t *esp_netif, const esp_ip6_addr_t addr, bool preferred)
{
const ip_event_add_ip6_t addr_evt = {.addr = addr, .preferred = preferred};
return esp_netif_add_ip6_address_priv(esp_netif, &addr_evt);
}{ ... }
static esp_err_t esp_netif_remove_ip6_address_api(esp_netif_api_msg_t *msg)
{
esp_ip6_addr_t *addr = (esp_ip6_addr_t *)msg->data;
ip6_addr_t ip6addr;
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
memcpy(ip6addr.addr, addr->addr, sizeof(ip6addr.addr));
#if LWIP_IPV6_SCOPES
ip6addr.zone = 0;
#endif
int8_t index = netif_get_ip6_addr_match(msg->esp_netif->lwip_netif, &ip6addr);
if (index != -1) {
netif_ip6_addr_set_state(msg->esp_netif->lwip_netif, index, IP6_ADDR_INVALID);
}{...}
return ESP_OK;
}{ ... }
esp_err_t esp_netif_remove_ip6_address(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
_RUN_IN_LWIP_TASK(esp_netif_remove_ip6_address_api, esp_netif, addr)
/* ... */
#endif