4444#include "qstr.h"
4545#include "obj.h"
4646#include "objtuple.h"
47+ #include "objlist.h"
4748#include "stream.h"
4849#include "runtime.h"
50+ #include "modnetwork.h"
4951#include "pin.h"
5052#include "genhdr/pins.h"
5153#include "spi.h"
6163#include "netapp.h"
6264#include "patch_prog.h"
6365
64- STATIC const mp_obj_type_t cc3k_type ;
65- STATIC const mp_obj_type_t cc3k_socket_type ;
66+ int errno ; // for cc3000 driver
6667
67- STATIC mp_obj_t cc3k_socket_new (mp_uint_t family , mp_uint_t type , mp_uint_t protocol );
68+ STATIC mp_obj_t cc3k_socket_new (mp_uint_t family , mp_uint_t type , mp_uint_t protocol , int * _errno );
6869
6970STATIC volatile uint32_t fd_closed_state = 0 ;
7071STATIC volatile bool wlan_connected = false;
@@ -102,6 +103,42 @@ STATIC void cc3k_callback(long event_type, char *data, unsigned char length) {
102103 }
103104}
104105
106+ STATIC mp_obj_t cc3k_socket (mp_obj_t nic , int domain , int type , int fileno , int * _errno ) {
107+ switch (domain ) {
108+ case MOD_NETWORK_AF_INET : domain = AF_INET ; break ;
109+ case MOD_NETWORK_AF_INET6 : domain = AF_INET6 ; break ;
110+ default : * _errno = EAFNOSUPPORT ; return MP_OBJ_NULL ;
111+ }
112+
113+ switch (type ) {
114+ case MOD_NETWORK_SOCK_STREAM : type = SOCK_STREAM ; break ;
115+ case MOD_NETWORK_SOCK_DGRAM : type = SOCK_DGRAM ; break ;
116+ case MOD_NETWORK_SOCK_RAW : type = SOCK_RAW ; break ;
117+ default : * _errno = EINVAL ; return MP_OBJ_NULL ;
118+ }
119+
120+ return cc3k_socket_new (domain , type , 0 , _errno );
121+ }
122+
123+ STATIC int cc3k_gethostbyname (mp_obj_t nic , const char * name , mp_uint_t len , uint8_t * out_ip ) {
124+ uint32_t ip ;
125+ if (gethostbyname ((char * )name , len , & ip ) < 0 ) {
126+ return errno ;
127+ }
128+
129+ if (ip == 0 ) {
130+ // unknown host
131+ return ENOENT ;
132+ }
133+
134+ out_ip [0 ] = ip >> 24 ;
135+ out_ip [1 ] = ip >> 16 ;
136+ out_ip [2 ] = ip >> 8 ;
137+ out_ip [3 ] = ip ;
138+
139+ return 0 ;
140+ }
141+
105142/******************************************************************************/
106143// Micro Python bindings; CC3k class
107144
@@ -148,54 +185,54 @@ STATIC mp_obj_t cc3k_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw
148185 HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE );
149186
150187 cc3k_obj_t * cc3k = m_new_obj (cc3k_obj_t );
151- cc3k -> base .type = & cc3k_type ;
188+ cc3k -> base .type = (mp_obj_type_t * )& mod_network_nic_type_cc3k ;
189+
190+ // register with network module
191+ mod_network_register_nic (cc3k );
152192
153193 return cc3k ;
154194}
155195
156- STATIC mp_obj_t cc3k_connect (mp_uint_t n_args , const mp_obj_t * args , mp_map_t * kw_args ) {
157- int ssid_len = 0 ;
158- const char * ssid = NULL ;
159- const char * bssid = NULL ;
160-
161- int key_len = 0 ;
162- int sec = WLAN_SEC_UNSEC ;
163- const char * key = NULL ;
164-
165- mp_map_elem_t * kw_key , * kw_sec , * kw_bssid ;
196+ /// \method connect(ssid, key=None, *, security=WPA2, bssid=None)
197+ STATIC mp_obj_t cc3k_connect (mp_uint_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
198+ static const mp_arg_t allowed_args [] = {
199+ { MP_QSTR_ssid , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
200+ { MP_QSTR_key , MP_ARG_OBJ , {.u_obj = mp_const_none } },
201+ { MP_QSTR_security , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = WLAN_SEC_WPA2 } },
202+ { MP_QSTR_bssid , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
203+ };
166204
167- ssid = mp_obj_str_get_str (args [1 ]);
168- ssid_len = strlen (ssid );
205+ // parse args
206+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
207+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
169208
170- // get KW args
171- kw_key = mp_map_lookup (kw_args , MP_OBJ_NEW_QSTR (qstr_from_str ("key" )), MP_MAP_LOOKUP );
172- kw_sec = mp_map_lookup (kw_args , MP_OBJ_NEW_QSTR (qstr_from_str ("sec" )), MP_MAP_LOOKUP );
173- kw_bssid = mp_map_lookup (kw_args , MP_OBJ_NEW_QSTR (qstr_from_str ("bssid" )), MP_MAP_LOOKUP );
209+ // get ssid
210+ mp_uint_t ssid_len ;
211+ const char * ssid = mp_obj_str_get_data (args [0 ].u_obj , & ssid_len );
174212
175213 // get key and sec
176- if (kw_key && kw_sec ) {
177- key = mp_obj_str_get_str (kw_key -> value );
178- key_len = strlen (key );
179-
180- sec = mp_obj_get_int (kw_sec -> value );
181- if (!(WLAN_SEC_UNSEC < sec && sec <= WLAN_SEC_WPA2 )) {
182- nlr_raise (mp_obj_new_exception_msg (& mp_type_ValueError , "invalid security mode" ));
183- }
214+ mp_uint_t key_len = 0 ;
215+ const char * key = NULL ;
216+ mp_uint_t sec = WLAN_SEC_UNSEC ;
217+ if (args [1 ].u_obj != mp_const_none ) {
218+ key = mp_obj_str_get_data (args [1 ].u_obj , & key_len );
219+ sec = args [2 ].u_int ;
184220 }
185221
186222 // get bssid
187- if (kw_bssid != NULL ) {
188- bssid = mp_obj_str_get_str (kw_bssid -> value );
223+ const char * bssid = NULL ;
224+ if (args [3 ].u_obj != mp_const_none ) {
225+ bssid = mp_obj_str_get_str (args [3 ].u_obj );
189226 }
190227
191228 // connect to AP
192- if (wlan_connect (sec , (char * ) ssid , ssid_len , (uint8_t * )bssid , (uint8_t * )key , key_len ) != 0 ) {
229+ if (wlan_connect (sec , (char * )ssid , ssid_len , (uint8_t * )bssid , (uint8_t * )key , key_len ) != 0 ) {
193230 nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_OSError , "could not connect to ssid=%s, sec=%d, key=%s\n" , ssid , sec , key ));
194231 }
195232
196233 return mp_const_none ;
197234}
198- STATIC MP_DEFINE_CONST_FUN_OBJ_KW (cc3k_connect_obj , 2 , cc3k_connect );
235+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (cc3k_connect_obj , 1 , cc3k_connect );
199236
200237STATIC mp_obj_t cc3k_disconnect (mp_obj_t self_in ) {
201238 int ret = wlan_disconnect ();
@@ -259,49 +296,6 @@ STATIC mp_obj_t cc3k_patch_program(mp_obj_t self_in) {
259296}
260297STATIC MP_DEFINE_CONST_FUN_OBJ_1 (cc3k_patch_program_obj , cc3k_patch_program );
261298
262- /// \method socket(family=AF_INET, type=SOCK_STREAM, fileno=-1)
263- /// Create a socket.
264- STATIC const mp_arg_t cc3k_socket_args [] = {
265- { MP_QSTR_family , MP_ARG_INT , {.u_int = AF_INET } },
266- { MP_QSTR_type , MP_ARG_INT , {.u_int = SOCK_STREAM } },
267- };
268- #define PYB_CC3K_SOCKET_NUM_ARGS MP_ARRAY_SIZE(cc3k_socket_args)
269- STATIC mp_obj_t cc3k_socket (mp_uint_t n_args , const mp_obj_t * args , mp_map_t * kw_args ) {
270- // parse args
271- mp_arg_val_t vals [PYB_CC3K_SOCKET_NUM_ARGS ];
272- mp_arg_parse_all (n_args - 1 , args + 1 , kw_args , PYB_CC3K_SOCKET_NUM_ARGS , cc3k_socket_args , vals );
273-
274- return cc3k_socket_new (vals [0 ].u_int , vals [1 ].u_int , 0 );
275- }
276- STATIC MP_DEFINE_CONST_FUN_OBJ_KW (cc3k_socket_obj , 1 , cc3k_socket );
277-
278- STATIC mp_obj_t cc3k_gethostbyname (mp_obj_t self_in , mp_obj_t hostname ) {
279- mp_uint_t len ;
280- const char * host = mp_obj_str_get_data (hostname , & len );
281- uint32_t ip ;
282-
283- if (gethostbyname ((char * )host , len , & ip ) < 0 ) {
284- // TODO raise appropriate exception
285- printf ("gethostbyname failed\n" );
286- return mp_const_none ;
287- }
288-
289- if (ip == 0 ) {
290- // unknown host
291- // TODO CPython raises: socket.gaierror: [Errno -2] Name or service not known
292- printf ("Name or service not known\n" );
293- return mp_const_none ;
294- }
295-
296- // turn the ip address into a string (could use inet_ntop, but this here is much more efficient)
297- VSTR_FIXED (ip_str , 16 );
298- vstr_printf (& ip_str , "%u.%u.%u.%u" , (ip >> 24 ) & 0xff , (ip >> 16 ) & 0xff , (ip >> 8 ) & 0xff , ip & 0xff );
299- mp_obj_t ret = mp_obj_new_str (ip_str .buf , ip_str .len , false);
300-
301- return ret ;
302- }
303- STATIC MP_DEFINE_CONST_FUN_OBJ_2 (cc3k_gethostbyname_obj , cc3k_gethostbyname );
304-
305299STATIC const mp_map_elem_t cc3k_locals_dict_table [] = {
306300 { MP_OBJ_NEW_QSTR (MP_QSTR_connect ), (mp_obj_t )& cc3k_connect_obj },
307301 { MP_OBJ_NEW_QSTR (MP_QSTR_disconnect ), (mp_obj_t )& cc3k_disconnect_obj },
@@ -310,37 +304,24 @@ STATIC const mp_map_elem_t cc3k_locals_dict_table[] = {
310304 { MP_OBJ_NEW_QSTR (MP_QSTR_patch_version ), (mp_obj_t )& cc3k_patch_version_obj },
311305 { MP_OBJ_NEW_QSTR (MP_QSTR_patch_program ), (mp_obj_t )& cc3k_patch_program_obj },
312306
313- { MP_OBJ_NEW_QSTR (MP_QSTR_socket ), (mp_obj_t )& cc3k_socket_obj },
314- { MP_OBJ_NEW_QSTR (MP_QSTR_gethostbyname ), (mp_obj_t )& cc3k_gethostbyname_obj },
315-
316307 // class constants
317-
318308 { MP_OBJ_NEW_QSTR (MP_QSTR_WEP ), MP_OBJ_NEW_SMALL_INT (WLAN_SEC_WEP ) },
319309 { MP_OBJ_NEW_QSTR (MP_QSTR_WPA ), MP_OBJ_NEW_SMALL_INT (WLAN_SEC_WPA ) },
320310 { MP_OBJ_NEW_QSTR (MP_QSTR_WPA2 ), MP_OBJ_NEW_SMALL_INT (WLAN_SEC_WPA2 ) },
321-
322- { MP_OBJ_NEW_QSTR (MP_QSTR_AF_INET ), MP_OBJ_NEW_SMALL_INT (AF_INET ) },
323- { MP_OBJ_NEW_QSTR (MP_QSTR_AF_INET6 ), MP_OBJ_NEW_SMALL_INT (AF_INET6 ) },
324- { MP_OBJ_NEW_QSTR (MP_QSTR_SOCK_STREAM ), MP_OBJ_NEW_SMALL_INT (SOCK_STREAM ) },
325- { MP_OBJ_NEW_QSTR (MP_QSTR_SOCK_DGRAM ), MP_OBJ_NEW_SMALL_INT (SOCK_DGRAM ) },
326- { MP_OBJ_NEW_QSTR (MP_QSTR_SOCK_RAW ), MP_OBJ_NEW_SMALL_INT (SOCK_RAW ) },
327- { MP_OBJ_NEW_QSTR (MP_QSTR_IPPROTO_IP ), MP_OBJ_NEW_SMALL_INT (IPPROTO_IP ) },
328- { MP_OBJ_NEW_QSTR (MP_QSTR_IPPROTO_ICMP ), MP_OBJ_NEW_SMALL_INT (IPPROTO_ICMP ) },
329- { MP_OBJ_NEW_QSTR (MP_QSTR_IPPROTO_IPV4 ), MP_OBJ_NEW_SMALL_INT (IPPROTO_IPV4 ) },
330- { MP_OBJ_NEW_QSTR (MP_QSTR_IPPROTO_TCP ), MP_OBJ_NEW_SMALL_INT (IPPROTO_TCP ) },
331- { MP_OBJ_NEW_QSTR (MP_QSTR_IPPROTO_UDP ), MP_OBJ_NEW_SMALL_INT (IPPROTO_UDP ) },
332- { MP_OBJ_NEW_QSTR (MP_QSTR_IPPROTO_IPV6 ), MP_OBJ_NEW_SMALL_INT (IPPROTO_IPV6 ) },
333- { MP_OBJ_NEW_QSTR (MP_QSTR_IPPROTO_RAW ), MP_OBJ_NEW_SMALL_INT (IPPROTO_RAW ) },
334311};
335312
336313STATIC MP_DEFINE_CONST_DICT (cc3k_locals_dict , cc3k_locals_dict_table );
337314
338- STATIC const mp_obj_type_t cc3k_type = {
339- { & mp_type_type },
340- .name = MP_QSTR_CC3k ,
341- //.print = cc3k_print,
342- .make_new = cc3k_make_new ,
343- .locals_dict = (mp_obj_t )& cc3k_locals_dict ,
315+ const mod_network_nic_type_t mod_network_nic_type_cc3k = {
316+ .base = {
317+ { & mp_type_type },
318+ .name = MP_QSTR_CC3k ,
319+ //.print = cc3k_print,
320+ .make_new = cc3k_make_new ,
321+ .locals_dict = (mp_obj_t )& cc3k_locals_dict ,
322+ },
323+ .socket = cc3k_socket ,
324+ .gethostbyname = cc3k_gethostbyname ,
344325};
345326
346327/******************************************************************************/
@@ -355,7 +336,9 @@ typedef struct _cc3k_socket_obj_t {
355336 int fd ;
356337} cc3k_socket_obj_t ;
357338
358- STATIC mp_obj_t cc3k_socket_new (mp_uint_t family , mp_uint_t type , mp_uint_t protocol ) {
339+ STATIC const mp_obj_type_t cc3k_socket_type ;
340+
341+ STATIC mp_obj_t cc3k_socket_new (mp_uint_t family , mp_uint_t type , mp_uint_t protocol , int * _errno ) {
359342 // create socket object
360343 cc3k_socket_obj_t * s = m_new_obj_with_finaliser (cc3k_socket_obj_t );
361344 s -> base .type = (mp_obj_t )& cc3k_socket_type ;
@@ -364,7 +347,8 @@ STATIC mp_obj_t cc3k_socket_new(mp_uint_t family, mp_uint_t type, mp_uint_t prot
364347 s -> fd = socket (family , type , protocol );
365348 if (s -> fd < 0 ) {
366349 m_del_obj (cc3k_socket_obj_t , s );
367- nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "socket failed" ));
350+ * _errno = errno ;
351+ return MP_OBJ_NULL ;
368352 }
369353
370354 // clear socket state
@@ -667,33 +651,6 @@ STATIC const mp_obj_type_t cc3k_socket_type = {
667651 { & mp_type_type },
668652 .name = MP_QSTR_socket ,
669653 .print = cc3k_socket_print ,
670- .getiter = NULL ,
671- .iternext = NULL ,
672654 .stream_p = & cc3k_socket_stream_p ,
673655 .locals_dict = (mp_obj_t )& cc3k_socket_locals_dict ,
674656};
675-
676- /******************************************************************************/
677- // Micro Python bindings; CC3k module
678-
679- STATIC const mp_map_elem_t mp_module_cc3k_globals_table [] = {
680- { MP_OBJ_NEW_QSTR (MP_QSTR___name__ ), MP_OBJ_NEW_QSTR (MP_QSTR_cc3k ) },
681- { MP_OBJ_NEW_QSTR (MP_QSTR_CC3k ), (mp_obj_t )& cc3k_type },
682- };
683-
684- STATIC const mp_obj_dict_t mp_module_cc3k_globals = {
685- .base = {& mp_type_dict },
686- .map = {
687- .all_keys_are_qstrs = 1 ,
688- .table_is_fixed_array = 1 ,
689- .used = MP_ARRAY_SIZE (mp_module_cc3k_globals_table ),
690- .alloc = MP_ARRAY_SIZE (mp_module_cc3k_globals_table ),
691- .table = (mp_map_elem_t * )mp_module_cc3k_globals_table ,
692- },
693- };
694-
695- const mp_obj_module_t mp_module_cc3k = {
696- .base = { & mp_type_module },
697- .name = MP_QSTR_cc3k ,
698- .globals = (mp_obj_dict_t * )& mp_module_cc3k_globals ,
699- };
0 commit comments