4
4
* The MIT License (MIT)
5
5
*
6
6
* Copyright (c) 2016 Nick Moore
7
+ * Based on esp8266/modnetwork.c which is Copyright (c) 2015 Paul Sokolovsky
8
+ * And the ESP IDF example code which is Public Domain / CC0
7
9
*
8
10
* Permission is hereby granted, free of charge, to any person obtaining a copy
9
11
* of this software and associated documentation files (the "Software"), to deal
32
34
#include "py/objlist.h"
33
35
#include "py/runtime.h"
34
36
#include "py/mphal.h"
37
+ #include "py/mperrno.h"
35
38
#include "netutils.h"
36
39
#include "esp_wifi.h"
37
40
#include "esp_wifi_types.h"
38
41
#include "esp_log.h"
39
42
#include "esp_event_loop.h"
40
43
#include "esp_log.h"
44
+ #include "lwip/dns.h"
45
+ #include "tcpip_adapter.h"
41
46
42
47
#define MODNETWORK_INCLUDE_CONSTANTS (1)
43
48
44
- char * wifi_error_messages (esp_err_t n ) {
45
- switch (n ) {
49
+ NORETURN void _esp_exceptions (esp_err_t e ) {
50
+ switch (e ) {
46
51
case ESP_ERR_WIFI_NOT_INIT :
47
- return "Wifi Not Initialized" ;
52
+ mp_raise_msg ( & mp_type_OSError , "Wifi Not Initialized" ) ;
48
53
case ESP_ERR_WIFI_NOT_START :
49
- return "Wifi Not Started" ;
54
+ mp_raise_msg ( & mp_type_OSError , "Wifi Not Started" ) ;
50
55
case ESP_ERR_WIFI_CONN :
51
- return "Wifi Internal Error" ;
56
+ mp_raise_msg ( & mp_type_OSError , "Wifi Internal Error" ) ;
52
57
case ESP_ERR_WIFI_SSID :
53
- return "Wifi SSID Invalid" ;
58
+ mp_raise_msg ( & mp_type_OSError , "Wifi SSID Invalid" ) ;
54
59
case ESP_ERR_WIFI_FAIL :
55
- return "Wifi Internal Failure" ;
60
+ mp_raise_msg ( & mp_type_OSError , "Wifi Internal Failure" ) ;
56
61
case ESP_ERR_WIFI_IF :
57
- return "Wifi Invalid Interface" ;
62
+ mp_raise_msg ( & mp_type_OSError , "Wifi Invalid Interface" ) ;
58
63
case ESP_ERR_WIFI_MAC :
59
- return "Wifi Invalid MAC Address" ;
64
+ mp_raise_msg ( & mp_type_OSError , "Wifi Invalid MAC Address" ) ;
60
65
case ESP_ERR_WIFI_ARG :
61
- return "Wifi Invalid Argument" ;
66
+ mp_raise_msg ( & mp_type_OSError , "Wifi Invalid Argument" ) ;
62
67
case ESP_ERR_WIFI_MODE :
63
- return "Wifi Invalid Mode" ;
68
+ mp_raise_msg ( & mp_type_OSError , "Wifi Invalid Mode" ) ;
64
69
case ESP_ERR_WIFI_PASSWORD :
65
- return "Wifi Invalid Password" ;
70
+ mp_raise_msg ( & mp_type_OSError , "Wifi Invalid Password" ) ;
66
71
case ESP_ERR_WIFI_NVS :
67
- return "Wifi Internal NVS Error" ;
72
+ mp_raise_msg (& mp_type_OSError , "Wifi Internal NVS Error" );
73
+ case ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS :
74
+ mp_raise_msg (& mp_type_OSError , "TCP/IP Invalid Parameters" );
75
+ case ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY :
76
+ mp_raise_msg (& mp_type_OSError , "TCP/IP IF Not Ready" );
77
+ case ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED :
78
+ mp_raise_msg (& mp_type_OSError , "TCP/IP DHCP Client Start Failed" );
68
79
case ESP_ERR_WIFI_TIMEOUT :
69
- return "Wifi Timeout" ;
80
+ mp_raise_OSError (MP_ETIMEDOUT );
81
+ case ESP_ERR_TCPIP_ADAPTER_NO_MEM :
70
82
case ESP_ERR_WIFI_NO_MEM :
71
- return "Wifi Out of Memory" ;
83
+ mp_raise_OSError ( MP_ENOMEM );
72
84
default :
73
- return "Wifi Unknown Error" ;
85
+ nlr_raise (mp_obj_new_exception_msg_varg (
86
+ & mp_type_RuntimeError , "Wifi Unknown Error 0x%04x" , e
87
+ ));
74
88
}
75
89
}
76
90
77
- #define ESP_EXCEPTIONS (x ) do { if (x != ESP_OK) nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, wifi_error_messages(x))); } while (0)
91
+ static inline void esp_exceptions (esp_err_t e ) {
92
+ if (e != ESP_OK ) _esp_exceptions (e );
93
+ }
94
+
95
+ #define ESP_EXCEPTIONS (x ) do { esp_exceptions(x); } while (0);
78
96
79
97
typedef struct _wlan_if_obj_t {
80
98
mp_obj_base_t base ;
@@ -101,21 +119,21 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) {
101
119
// This is a workaround as ESP32 WiFi libs don't currently
102
120
// auto-reassociate.
103
121
ESP_LOGI ("wifi" , "STA_DISCONNECTED" );
104
- esp_wifi_connect (); // XXX error handling
122
+ ESP_EXCEPTIONS ( esp_wifi_connect () );
105
123
break ;
106
124
default :
107
125
break ;
108
126
}
109
127
return ESP_OK ;
110
128
}
111
129
112
- void error_check (bool status , const char * msg ) {
130
+ /* void error_check(bool status, const char *msg) {
113
131
if (!status) {
114
132
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, msg));
115
133
}
116
134
}
117
135
118
- /* STATIC void require_if(mp_obj_t wlan_if, int if_no) {
136
+ STATIC void require_if(mp_obj_t wlan_if, int if_no) {
119
137
wlan_if_obj_t *self = MP_OBJ_TO_PTR(wlan_if);
120
138
if (self->if_id != if_no) {
121
139
error_check(false, if_no == WIFI_IF_STA ? "STA required" : "AP required");
@@ -129,7 +147,7 @@ STATIC mp_obj_t get_wlan(mp_uint_t n_args, const mp_obj_t *args) {
129
147
} else if (idx == WIFI_IF_AP ) {
130
148
return MP_OBJ_FROM_PTR (& wlan_ap_obj );
131
149
} else {
132
- nlr_raise ( mp_obj_new_exception_msg ( & mp_type_ValueError , "invalid WLAN interface identifier" ) );
150
+ mp_raise_msg ( & mp_type_ValueError , "invalid WLAN interface identifier" );
133
151
}
134
152
}
135
153
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (get_wlan_obj , 0 , 1 , get_wlan );
@@ -249,7 +267,50 @@ STATIC mp_obj_t esp_isconnected(mp_obj_t self_in) {
249
267
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (esp_isconnected_obj , esp_isconnected );
250
268
251
269
STATIC mp_obj_t esp_ifconfig (size_t n_args , const mp_obj_t * args ) {
252
- return mp_const_none ;
270
+ wlan_if_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
271
+ tcpip_adapter_ip_info_t info ;
272
+ ip_addr_t dns_addr ;
273
+ tcpip_adapter_get_ip_info (self -> if_id , & info );
274
+ if (n_args == 1 ) {
275
+ // get
276
+ dns_addr = dns_getserver (0 );
277
+ mp_obj_t tuple [4 ] = {
278
+ netutils_format_ipv4_addr ((uint8_t * )& info .ip , NETUTILS_BIG ),
279
+ netutils_format_ipv4_addr ((uint8_t * )& info .netmask , NETUTILS_BIG ),
280
+ netutils_format_ipv4_addr ((uint8_t * )& info .gw , NETUTILS_BIG ),
281
+ netutils_format_ipv4_addr ((uint8_t * )& dns_addr , NETUTILS_BIG ),
282
+ };
283
+ return mp_obj_new_tuple (4 , tuple );
284
+ } else {
285
+ // set
286
+ mp_obj_t * items ;
287
+ mp_obj_get_array_fixed_n (args [1 ], 4 , & items );
288
+ netutils_parse_ipv4_addr (items [0 ], (void * )& info .ip , NETUTILS_BIG );
289
+ if (mp_obj_is_integer (items [1 ])) {
290
+ // allow numeric netmask, i.e.:
291
+ // 24 -> 255.255.255.0
292
+ // 16 -> 255.255.0.0
293
+ // etc...
294
+ uint32_t * m = (uint32_t * )& info .netmask ;
295
+ * m = htonl (0xffffffff << (32 - mp_obj_get_int (items [1 ])));
296
+ } else {
297
+ netutils_parse_ipv4_addr (items [1 ], (void * )& info .netmask , NETUTILS_BIG );
298
+ }
299
+ netutils_parse_ipv4_addr (items [2 ], (void * )& info .gw , NETUTILS_BIG );
300
+ netutils_parse_ipv4_addr (items [3 ], (void * )& dns_addr , NETUTILS_BIG );
301
+ // To set a static IP we have to disable DHCP first
302
+ if (self -> if_id == WIFI_IF_STA ) {
303
+ esp_err_t e = tcpip_adapter_dhcpc_stop (WIFI_IF_STA );
304
+ if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED ) _esp_exceptions (e );
305
+ ESP_EXCEPTIONS (tcpip_adapter_set_ip_info (WIFI_IF_STA , & info ));
306
+ } else if (self -> if_id == WIFI_IF_AP ) {
307
+ esp_err_t e = tcpip_adapter_dhcps_stop (WIFI_IF_AP );
308
+ if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED ) _esp_exceptions (e );
309
+ ESP_EXCEPTIONS (tcpip_adapter_set_ip_info (WIFI_IF_AP , & info ));
310
+ ESP_EXCEPTIONS (tcpip_adapter_dhcps_start (WIFI_IF_AP ));
311
+ }
312
+ return mp_const_none ;
313
+ }
253
314
}
254
315
255
316
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (esp_ifconfig_obj , 1 , 2 , esp_ifconfig );
0 commit comments