summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--stmhal/Makefile2
-rw-r--r--stmhal/main.c5
-rw-r--r--stmhal/modcc3k.c211
-rw-r--r--stmhal/modnetwork.c141
-rw-r--r--stmhal/modnetwork.h54
-rw-r--r--stmhal/modusocket.c149
-rw-r--r--stmhal/modwiznet5k.c228
-rw-r--r--stmhal/mpconfigport.h21
-rw-r--r--stmhal/portmodules.h1
-rw-r--r--stmhal/qstrdefsport.h34
10 files changed, 531 insertions, 315 deletions
diff --git a/stmhal/Makefile b/stmhal/Makefile
index f14a881c5b..ba844d97cc 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -103,6 +103,8 @@ SRC_C = \
modstm.c \
modtime.c \
modselect.c \
+ modusocket.c \
+ modnetwork.c \
import.c \
lexerfatfs.c \
extint.c \
diff --git a/stmhal/main.c b/stmhal/main.c
index 84ce6353a4..20db6ca4a3 100644
--- a/stmhal/main.c
+++ b/stmhal/main.c
@@ -64,11 +64,10 @@
#include "dac.h"
#include "pybwlan.h"
#include "pybstdio.h"
+#include "modnetwork.h"
void SystemClock_Config(void);
-int errno;
-
static FATFS fatfs0;
#if MICROPY_HW_HAS_SDCARD
static FATFS fatfs1;
@@ -510,6 +509,8 @@ soft_reset:
pyb_wlan_start();
#endif
+ mod_network_init();
+
// At this point everything is fully configured and initialised.
// Run the main script from the current directory.
diff --git a/stmhal/modcc3k.c b/stmhal/modcc3k.c
index dda8d06f67..71b29fb86d 100644
--- a/stmhal/modcc3k.c
+++ b/stmhal/modcc3k.c
@@ -44,8 +44,10 @@
#include "qstr.h"
#include "obj.h"
#include "objtuple.h"
+#include "objlist.h"
#include "stream.h"
#include "runtime.h"
+#include "modnetwork.h"
#include "pin.h"
#include "genhdr/pins.h"
#include "spi.h"
@@ -61,10 +63,9 @@
#include "netapp.h"
#include "patch_prog.h"
-STATIC const mp_obj_type_t cc3k_type;
-STATIC const mp_obj_type_t cc3k_socket_type;
+int errno; // for cc3000 driver
-STATIC mp_obj_t cc3k_socket_new(mp_uint_t family, mp_uint_t type, mp_uint_t protocol);
+STATIC mp_obj_t cc3k_socket_new(mp_uint_t family, mp_uint_t type, mp_uint_t protocol, int *_errno);
STATIC volatile uint32_t fd_closed_state = 0;
STATIC volatile bool wlan_connected = false;
@@ -102,6 +103,42 @@ STATIC void cc3k_callback(long event_type, char *data, unsigned char length) {
}
}
+STATIC mp_obj_t cc3k_socket(mp_obj_t nic, int domain, int type, int fileno, int *_errno) {
+ switch (domain) {
+ case MOD_NETWORK_AF_INET: domain = AF_INET; break;
+ case MOD_NETWORK_AF_INET6: domain = AF_INET6; break;
+ default: *_errno = EAFNOSUPPORT; return MP_OBJ_NULL;
+ }
+
+ switch (type) {
+ case MOD_NETWORK_SOCK_STREAM: type = SOCK_STREAM; break;
+ case MOD_NETWORK_SOCK_DGRAM: type = SOCK_DGRAM; break;
+ case MOD_NETWORK_SOCK_RAW: type = SOCK_RAW; break;
+ default: *_errno = EINVAL; return MP_OBJ_NULL;
+ }
+
+ return cc3k_socket_new(domain, type, 0, _errno);
+}
+
+STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) {
+ uint32_t ip;
+ if (gethostbyname((char*)name, len, &ip) < 0) {
+ return errno;
+ }
+
+ if (ip == 0) {
+ // unknown host
+ return ENOENT;
+ }
+
+ out_ip[0] = ip >> 24;
+ out_ip[1] = ip >> 16;
+ out_ip[2] = ip >> 8;
+ out_ip[3] = ip;
+
+ return 0;
+}
+
/******************************************************************************/
// Micro Python bindings; CC3k class
@@ -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
HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE);
cc3k_obj_t *cc3k = m_new_obj(cc3k_obj_t);
- cc3k->base.type = &cc3k_type;
+ cc3k->base.type = (mp_obj_type_t*)&mod_network_nic_type_cc3k;
+
+ // register with network module
+ mod_network_register_nic(cc3k);
return cc3k;
}
-STATIC mp_obj_t cc3k_connect(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- int ssid_len =0;
- const char *ssid = NULL;
- const char *bssid = NULL;
-
- int key_len =0;
- int sec = WLAN_SEC_UNSEC;
- const char *key = NULL;
-
- mp_map_elem_t *kw_key, *kw_sec, *kw_bssid;
+/// \method connect(ssid, key=None, *, security=WPA2, bssid=None)
+STATIC mp_obj_t cc3k_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_key, MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = WLAN_SEC_WPA2} },
+ { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
- ssid = mp_obj_str_get_str(args[1]);
- ssid_len = strlen(ssid);
+ // parse args
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- // get KW args
- kw_key = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("key")), MP_MAP_LOOKUP);
- kw_sec = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("sec")), MP_MAP_LOOKUP);
- kw_bssid = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("bssid")), MP_MAP_LOOKUP);
+ // get ssid
+ mp_uint_t ssid_len;
+ const char *ssid = mp_obj_str_get_data(args[0].u_obj, &ssid_len);
// get key and sec
- if (kw_key && kw_sec) {
- key = mp_obj_str_get_str(kw_key->value);
- key_len = strlen(key);
-
- sec = mp_obj_get_int(kw_sec->value);
- if (!(WLAN_SEC_UNSEC < sec && sec <= WLAN_SEC_WPA2)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid security mode"));
- }
+ mp_uint_t key_len = 0;
+ const char *key = NULL;
+ mp_uint_t sec = WLAN_SEC_UNSEC;
+ if (args[1].u_obj != mp_const_none) {
+ key = mp_obj_str_get_data(args[1].u_obj, &key_len);
+ sec = args[2].u_int;
}
// get bssid
- if (kw_bssid != NULL) {
- bssid = mp_obj_str_get_str(kw_bssid->value);
+ const char *bssid = NULL;
+ if (args[3].u_obj != mp_const_none) {
+ bssid = mp_obj_str_get_str(args[3].u_obj);
}
// connect to AP
- if (wlan_connect(sec, (char*) ssid, ssid_len, (uint8_t*)bssid, (uint8_t*)key, key_len) != 0) {
+ if (wlan_connect(sec, (char*)ssid, ssid_len, (uint8_t*)bssid, (uint8_t*)key, key_len) != 0) {
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));
}
return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(cc3k_connect_obj, 2, cc3k_connect);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(cc3k_connect_obj, 1, cc3k_connect);
STATIC mp_obj_t cc3k_disconnect(mp_obj_t self_in) {
int ret = wlan_disconnect();
@@ -259,49 +296,6 @@ STATIC mp_obj_t cc3k_patch_program(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(cc3k_patch_program_obj, cc3k_patch_program);
-/// \method socket(family=AF_INET, type=SOCK_STREAM, fileno=-1)
-/// Create a socket.
-STATIC const mp_arg_t cc3k_socket_args[] = {
- { MP_QSTR_family, MP_ARG_INT, {.u_int = AF_INET} },
- { MP_QSTR_type, MP_ARG_INT, {.u_int = SOCK_STREAM} },
-};
-#define PYB_CC3K_SOCKET_NUM_ARGS MP_ARRAY_SIZE(cc3k_socket_args)
-STATIC mp_obj_t cc3k_socket(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- // parse args
- mp_arg_val_t vals[PYB_CC3K_SOCKET_NUM_ARGS];
- mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_CC3K_SOCKET_NUM_ARGS, cc3k_socket_args, vals);
-
- return cc3k_socket_new(vals[0].u_int, vals[1].u_int, 0);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(cc3k_socket_obj, 1, cc3k_socket);
-
-STATIC mp_obj_t cc3k_gethostbyname(mp_obj_t self_in, mp_obj_t hostname) {
- mp_uint_t len;
- const char *host = mp_obj_str_get_data(hostname, &len);
- uint32_t ip;
-
- if (gethostbyname((char*)host, len, &ip) < 0) {
- // TODO raise appropriate exception
- printf("gethostbyname failed\n");
- return mp_const_none;
- }
-
- if (ip == 0) {
- // unknown host
- // TODO CPython raises: socket.gaierror: [Errno -2] Name or service not known
- printf("Name or service not known\n");
- return mp_const_none;
- }
-
- // turn the ip address into a string (could use inet_ntop, but this here is much more efficient)
- VSTR_FIXED(ip_str, 16);
- vstr_printf(&ip_str, "%u.%u.%u.%u", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
- mp_obj_t ret = mp_obj_new_str(ip_str.buf, ip_str.len, false);
-
- return ret;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(cc3k_gethostbyname_obj, cc3k_gethostbyname);
-
STATIC const mp_map_elem_t cc3k_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&cc3k_connect_obj },
{ 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[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_patch_version), (mp_obj_t)&cc3k_patch_version_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_patch_program), (mp_obj_t)&cc3k_patch_program_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&cc3k_socket_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_gethostbyname), (mp_obj_t)&cc3k_gethostbyname_obj },
-
// class constants
-
{ MP_OBJ_NEW_QSTR(MP_QSTR_WEP), MP_OBJ_NEW_SMALL_INT(WLAN_SEC_WEP) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_WPA), MP_OBJ_NEW_SMALL_INT(WLAN_SEC_WPA) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_WPA2), MP_OBJ_NEW_SMALL_INT(WLAN_SEC_WPA2) },
-
- { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(AF_INET) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET6), MP_OBJ_NEW_SMALL_INT(AF_INET6) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(SOCK_STREAM) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(SOCK_DGRAM) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_RAW), MP_OBJ_NEW_SMALL_INT(SOCK_RAW) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IP), MP_OBJ_NEW_SMALL_INT(IPPROTO_IP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_ICMP), MP_OBJ_NEW_SMALL_INT(IPPROTO_ICMP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IPV4), MP_OBJ_NEW_SMALL_INT(IPPROTO_IPV4) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_TCP), MP_OBJ_NEW_SMALL_INT(IPPROTO_TCP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_UDP), MP_OBJ_NEW_SMALL_INT(IPPROTO_UDP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IPV6), MP_OBJ_NEW_SMALL_INT(IPPROTO_IPV6) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_RAW), MP_OBJ_NEW_SMALL_INT(IPPROTO_RAW) },
};
STATIC MP_DEFINE_CONST_DICT(cc3k_locals_dict, cc3k_locals_dict_table);
-STATIC const mp_obj_type_t cc3k_type = {
- { &mp_type_type },
- .name = MP_QSTR_CC3k,
- //.print = cc3k_print,
- .make_new = cc3k_make_new,
- .locals_dict = (mp_obj_t)&cc3k_locals_dict,
+const mod_network_nic_type_t mod_network_nic_type_cc3k = {
+ .base = {
+ { &mp_type_type },
+ .name = MP_QSTR_CC3k,
+ //.print = cc3k_print,
+ .make_new = cc3k_make_new,
+ .locals_dict = (mp_obj_t)&cc3k_locals_dict,
+ },
+ .socket = cc3k_socket,
+ .gethostbyname = cc3k_gethostbyname,
};
/******************************************************************************/
@@ -355,7 +336,9 @@ typedef struct _cc3k_socket_obj_t {
int fd;
} cc3k_socket_obj_t;
-STATIC mp_obj_t cc3k_socket_new(mp_uint_t family, mp_uint_t type, mp_uint_t protocol) {
+STATIC const mp_obj_type_t cc3k_socket_type;
+
+STATIC mp_obj_t cc3k_socket_new(mp_uint_t family, mp_uint_t type, mp_uint_t protocol, int *_errno) {
// create socket object
cc3k_socket_obj_t *s = m_new_obj_with_finaliser(cc3k_socket_obj_t);
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
s->fd = socket(family, type, protocol);
if (s->fd < 0) {
m_del_obj(cc3k_socket_obj_t, s);
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "socket failed"));
+ *_errno = errno;
+ return MP_OBJ_NULL;
}
// clear socket state
@@ -667,33 +651,6 @@ STATIC const mp_obj_type_t cc3k_socket_type = {
{ &mp_type_type },
.name = MP_QSTR_socket,
.print = cc3k_socket_print,
- .getiter = NULL,
- .iternext = NULL,
.stream_p = &cc3k_socket_stream_p,
.locals_dict = (mp_obj_t)&cc3k_socket_locals_dict,
};
-
-/******************************************************************************/
-// Micro Python bindings; CC3k module
-
-STATIC const mp_map_elem_t mp_module_cc3k_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_cc3k) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_CC3k), (mp_obj_t)&cc3k_type },
-};
-
-STATIC const mp_obj_dict_t mp_module_cc3k_globals = {
- .base = {&mp_type_dict},
- .map = {
- .all_keys_are_qstrs = 1,
- .table_is_fixed_array = 1,
- .used = MP_ARRAY_SIZE(mp_module_cc3k_globals_table),
- .alloc = MP_ARRAY_SIZE(mp_module_cc3k_globals_table),
- .table = (mp_map_elem_t*)mp_module_cc3k_globals_table,
- },
-};
-
-const mp_obj_module_t mp_module_cc3k = {
- .base = { &mp_type_module },
- .name = MP_QSTR_cc3k,
- .globals = (mp_obj_dict_t*)&mp_module_cc3k_globals,
-};
diff --git a/stmhal/modnetwork.c b/stmhal/modnetwork.c
new file mode 100644
index 0000000000..a0cd24de6b
--- /dev/null
+++ b/stmhal/modnetwork.c
@@ -0,0 +1,141 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include "stm32f4xx_hal.h"
+
+#include "mpconfig.h"
+#include "nlr.h"
+#include "misc.h"
+#include "qstr.h"
+#include "obj.h"
+#include "objlist.h"
+#include "runtime.h"
+#include "modnetwork.h"
+
+mp_obj_list_t mod_network_nic_list;
+
+void mod_network_init(void) {
+ mp_obj_list_init(&mod_network_nic_list, 0);
+}
+
+void mod_network_register_nic(mp_obj_t nic) {
+ for (mp_uint_t i = 0; i < mod_network_nic_list.len; i++) {
+ if (mod_network_nic_list.items[i] == nic) {
+ // nic already registered
+ return;
+ }
+ }
+ // nic not registered so add to list
+ mp_obj_list_append(&mod_network_nic_list, nic);
+}
+
+STATIC mp_obj_t network_route(void) {
+ return &mod_network_nic_list;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route);
+
+STATIC const mp_map_elem_t mp_module_network_globals_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_network) },
+
+ #if MICROPY_PY_WIZNET5K
+ { MP_OBJ_NEW_QSTR(MP_QSTR_WIZnet5k), (mp_obj_t)&mod_network_nic_type_wiznet5k },
+ #endif
+ #if MICROPY_PY_CC3K
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CC3k), (mp_obj_t)&mod_network_nic_type_cc3k },
+ #endif
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_route), (mp_obj_t)&network_route_obj },
+};
+
+STATIC const mp_obj_dict_t mp_module_network_globals = {
+ .base = {&mp_type_dict},
+ .map = {
+ .all_keys_are_qstrs = 1,
+ .table_is_fixed_array = 1,
+ .used = MP_ARRAY_SIZE(mp_module_network_globals_table),
+ .alloc = MP_ARRAY_SIZE(mp_module_network_globals_table),
+ .table = (mp_map_elem_t*)mp_module_network_globals_table,
+ },
+};
+
+const mp_obj_module_t mp_module_network = {
+ .base = { &mp_type_module },
+ .name = MP_QSTR_network,
+ .globals = (mp_obj_dict_t*)&mp_module_network_globals,
+};
+
+/******************************************************************************/
+// Miscellaneous helpers
+
+void mod_network_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip) {
+ const char *addr_str = mp_obj_str_get_str(addr_in);
+ const char *s = addr_str;
+ for (mp_uint_t i = 0;; i++) {
+ mp_uint_t val = 0;
+ for (; *s && *s != '.'; s++) {
+ val = val * 10 + *s - '0';
+ }
+ out_ip[i] = val;
+ if (i == 3 && *s == '\0') {
+ return;
+ } else if (i < 3 && *s == '.') {
+ s++;
+ } else {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid IP address"));
+ }
+ }
+}
+
+// Takes an address of the form ('192.168.0.1', 8080), returns the port and
+// puts IP in out_ip (which must take at least IPADDR_BUF_SIZE bytes).
+mp_uint_t mod_network_parse_inet_addr(mp_obj_t addr_in, uint8_t *out_ip) {
+ mp_obj_t *addr_items;
+ mp_obj_get_array_fixed_n(addr_in, 2, &addr_items);
+ mod_network_parse_ipv4_addr(addr_items[0], out_ip);
+ return mp_obj_get_int(addr_items[1]);
+}
+
+// Takes an array with a raw IPv4 address and returns something like '192.168.0.1'.
+mp_obj_t mod_network_format_ipv4_addr(uint8_t *ip) {
+ char ip_str[16];
+ mp_uint_t ip_len = snprintf(ip_str, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
+ return mp_obj_new_str(ip_str, ip_len, false);
+}
+
+// Takes an array with a raw IP address, and a port, and returns a net-address
+// tuple such as ('192.168.0.1', 8080).
+mp_obj_t mod_network_format_inet_addr(uint8_t *ip, mp_uint_t port) {
+ mp_obj_t tuple[2] = {
+ tuple[0] = mod_network_format_ipv4_addr(ip),
+ tuple[1] = mp_obj_new_int(port),
+ };
+ return mp_obj_new_tuple(2, tuple);
+}
diff --git a/stmhal/modnetwork.h b/stmhal/modnetwork.h
new file mode 100644
index 0000000000..ed31a602f2
--- /dev/null
+++ b/stmhal/modnetwork.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#define MOD_NETWORK_IPADDR_BUF_SIZE (4)
+
+#define MOD_NETWORK_AF_INET (2)
+#define MOD_NETWORK_AF_INET6 (10)
+
+#define MOD_NETWORK_SOCK_STREAM (1)
+#define MOD_NETWORK_SOCK_DGRAM (2)
+#define MOD_NETWORK_SOCK_RAW (3)
+
+typedef struct _mod_network_nic_type_t {
+ mp_obj_type_t base;
+
+ // API for a generic NIC
+ mp_obj_t (*socket)(mp_obj_t nic, int domain, int type, int fileno, int *_errno);
+ int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out);
+} mod_network_nic_type_t;
+
+extern struct _mp_obj_list_t mod_network_nic_list;
+extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k;
+extern const mod_network_nic_type_t mod_network_nic_type_cc3k;
+
+void mod_network_init(void);
+void mod_network_register_nic(mp_obj_t nic);
+
+void mod_network_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip);
+mp_uint_t mod_network_parse_inet_addr(mp_obj_t addr_in, uint8_t *out_ip);
+mp_obj_t mod_network_format_ipv4_addr(uint8_t *ip);
+mp_obj_t mod_network_format_inet_addr(uint8_t *ip, mp_uint_t port);
diff --git a/stmhal/modusocket.c b/stmhal/modusocket.c
new file mode 100644
index 0000000000..6a544cb3e0
--- /dev/null
+++ b/stmhal/modusocket.c
@@ -0,0 +1,149 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include "stm32f4xx_hal.h"
+
+#include "mpconfig.h"
+#include "nlr.h"
+#include "misc.h"
+#include "qstr.h"
+#include "obj.h"
+#include "objtuple.h"
+#include "objlist.h"
+#include "runtime.h"
+#include "modnetwork.h"
+
+/// \module usocket
+
+/// \method socket(family=AF_INET, type=SOCK_STREAM, fileno=-1)
+/// Create a socket.
+STATIC mp_obj_t mod_usocket_socket(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_family, MP_ARG_INT, {.u_int = MOD_NETWORK_AF_INET} },
+ { MP_QSTR_type, MP_ARG_INT, {.u_int = MOD_NETWORK_SOCK_STREAM} },
+ { MP_QSTR_fileno, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
+ };
+
+ // parse args
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ // find a NIC that can create a socket and call it
+ for (mp_uint_t i = 0; i < mod_network_nic_list.len; i++) {
+ mp_obj_t nic = mod_network_nic_list.items[i];
+ mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
+ if (nic_type->socket != NULL) {
+ int _errno;
+ mp_obj_t obj = nic_type->socket(nic, args[0].u_int, args[1].u_int, args[2].u_int, &_errno);
+ if (obj == MP_OBJ_NULL) {
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+ } else {
+ return obj;
+ }
+ }
+ }
+
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC"));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_usocket_socket_obj, 0, mod_usocket_socket);
+
+/// \method getaddrinfo(host, port)
+STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
+ mp_uint_t hlen;
+ const char *host = mp_obj_str_get_data(host_in, &hlen);
+ mp_int_t port = mp_obj_get_int(port_in);
+
+ // find a NIC that can do a name lookup
+ for (mp_uint_t i = 0; i < mod_network_nic_list.len; i++) {
+ mp_obj_t nic = mod_network_nic_list.items[i];
+ mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
+ if (nic_type->gethostbyname != NULL) {
+ uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE];
+ int ret = nic_type->gethostbyname(nic, host, hlen, out_ip);
+ if (ret != 0) {
+ // TODO CPython raises: socket.gaierror: [Errno -2] Name or service not known
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ret)));
+ }
+ mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
+ tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET);
+ tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM);
+ tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
+ tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
+ tuple->items[4] = mod_network_format_inet_addr(out_ip, port);
+ return mp_obj_new_list(1, (mp_obj_t*)&tuple);
+ }
+ }
+
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC"));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo);
+
+STATIC const mp_map_elem_t mp_module_usocket_globals_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usocket) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mod_usocket_socket_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&mod_usocket_getaddrinfo_obj },
+
+ // class constants
+ { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET6), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET6) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_DGRAM) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_RAW), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_RAW) },
+
+ /*
+ { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IP), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_IP) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_ICMP), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_ICMP) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IPV4), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_IPV4) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_TCP), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_TCP) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_UDP), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_UDP) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IPV6), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_IPV6) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_RAW), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_RAW) },
+ */
+};
+
+STATIC const mp_obj_dict_t mp_module_usocket_globals = {
+ .base = {&mp_type_dict},
+ .map = {
+ .all_keys_are_qstrs = 1,
+ .table_is_fixed_array = 1,
+ .used = MP_ARRAY_SIZE(mp_module_usocket_globals_table),
+ .alloc = MP_ARRAY_SIZE(mp_module_usocket_globals_table),
+ .table = (mp_map_elem_t*)mp_module_usocket_globals_table,
+ },
+};
+
+const mp_obj_module_t mp_module_usocket = {
+ .base = { &mp_type_module },
+ .name = MP_QSTR_usocket,
+ .globals = (mp_obj_dict_t*)&mp_module_usocket_globals,
+};
diff --git a/stmhal/modwiznet5k.c b/stmhal/modwiznet5k.c
index 3996c29944..3a4b25c0f6 100644
--- a/stmhal/modwiznet5k.c
+++ b/stmhal/modwiznet5k.c
@@ -36,7 +36,9 @@
#include "misc.h"
#include "qstr.h"
#include "obj.h"
+#include "objlist.h"
#include "runtime.h"
+#include "modnetwork.h"
#include "pin.h"
#include "genhdr/pins.h"
#include "spi.h"
@@ -64,17 +66,14 @@
#define IPADDR_BUF_SIZE (4)
-STATIC const mp_obj_type_t wiznet5k_type;
-STATIC const mp_obj_type_t wiznet5k_socket_type;
-
STATIC mp_obj_t wiznet5k_socket_new(uint8_t sn, mp_uint_t type);
typedef struct _wiznet5k_obj_t {
mp_obj_base_t base;
mp_uint_t cris_state;
+ SPI_HandleTypeDef *spi;
const pin_obj_t *cs;
const pin_obj_t *rst;
- SPI_HandleTypeDef *spi;
uint8_t socket_used;
} wiznet5k_obj_t;
@@ -106,9 +105,6 @@ STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) {
(void)status;
}
-/******************************************************************************/
-// Miscellaneous helpers
-
// Check the return value from Wiz socket calls:
// - on error (<0) an exception is raised
// - SOCK_OK or SOCK_BUSY does nothing
@@ -120,51 +116,50 @@ STATIC void check_sock_return_value(int8_t ret) {
}
}
-STATIC void parse_ip_addr(mp_obj_t addr_in, uint8_t *out_ip) {
- const char *addr_str = mp_obj_str_get_str(addr_in);
- const char *s = addr_str;
- for (mp_uint_t i = 0;; i++) {
- mp_uint_t val = 0;
- for (; *s && *s != '.'; s++) {
- val = val * 10 + *s - '0';
+STATIC mp_obj_t wiznet5k_socket(mp_obj_t self_in, int domain, int type, int fileno, int *_errno) {
+ if (domain != MOD_NETWORK_AF_INET) {
+ *_errno = EAFNOSUPPORT;
+ return MP_OBJ_NULL;
+ }
+
+ switch (type) {
+ case MOD_NETWORK_SOCK_STREAM: type = Sn_MR_TCP; break;
+ case MOD_NETWORK_SOCK_DGRAM: type = Sn_MR_UDP; break;
+ default: *_errno = EINVAL; return MP_OBJ_NULL;
+ }
+
+ if (fileno < 0) {
+ // get first unused socket number
+ for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) {
+ if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) {
+ fileno = sn;
+ break;
+ }
}
- out_ip[i] = val;
- if (i == 3 && *s == '\0') {
- return;
- } else if (i < 3 && *s == '.') {
- s++;
- } else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid IP address"));
+ if (fileno < 0) {
+ // too many open sockets
+ *_errno = EMFILE;
+ return MP_OBJ_NULL;
}
}
-}
-
-// Takes an address of the form ('192.168.0.1', 8080), returns the port and
-// puts IP in out_ip (which must take at least IPADDR_BUF_SIZE bytes).
-STATIC mp_uint_t parse_net_addr(mp_obj_t addr_in, uint8_t *out_ip) {
- mp_obj_t *addr_items;
- mp_obj_get_array_fixed_n(addr_in, 2, &addr_items);
- parse_ip_addr(addr_items[0], out_ip);
- return mp_obj_get_int(addr_items[1]);
-}
-// Takes an array with a raw IP address and returns something like '192.168.0.1'.
-STATIC mp_obj_t format_ip_addr(uint8_t *ip) {
- char ip_str[16];
- mp_uint_t ip_len = snprintf(ip_str, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
- return mp_obj_new_str(ip_str, ip_len, false);
+ return wiznet5k_socket_new(fileno, type);
}
-// Takes an array with a raw IP address, and a port, and returns a net-address
-// tuple such as ('192.168.0.1', 8080).
-STATIC mp_obj_t format_net_addr(uint8_t *ip, mp_uint_t port) {
- mp_obj_t tuple[2] = {
- tuple[0] = format_ip_addr(ip),
- tuple[1] = mp_obj_new_int(port),
- };
- return mp_obj_new_tuple(2, tuple);
+STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) {
+ uint8_t dns_ip[IPADDR_BUF_SIZE] = {8, 8, 8, 8};
+ uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE);
+ DNS_init(0, buf);
+ mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip);
+ m_del(uint8_t, buf, MAX_DNS_BUF_SIZE);
+ if (ret == 1) {
+ // success
+ return 0;
+ } else {
+ // failure
+ return ENOENT;
+ }
}
-
/******************************************************************************/
// Micro Python bindings
@@ -174,18 +169,18 @@ STATIC void wiznet5k_print(void (*print)(void *env, const char *fmt, ...), void
print(env, "WIZnet5k()");
}
-/// \classmethod \constructor()
+/// \classmethod \constructor(spi, pin_cs, pin_rst)
/// Create and return a WIZnet5k object.
STATIC mp_obj_t wiznet5k_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
// check arguments
- mp_arg_check_num(n_args, n_kw, 0, 0, false);
+ mp_arg_check_num(n_args, n_kw, 3, 3, false);
// init the wiznet5k object
- wiznet5k_obj.base.type = &wiznet5k_type;
+ wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k;
wiznet5k_obj.cris_state = 0;
- wiznet5k_obj.cs = &pin_B12; // Y5
- wiznet5k_obj.rst = &pin_B9; // Y4
- wiznet5k_obj.spi = &SPIHandle2; // Y-skin
+ wiznet5k_obj.spi = spi_get_handle(args[0]);
+ wiznet5k_obj.cs = pin_find(args[1]);
+ wiznet5k_obj.rst = pin_find(args[2]);
wiznet5k_obj.socket_used = 0;
/*!< SPI configuration */
@@ -200,7 +195,7 @@ STATIC mp_obj_t wiznet5k_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
SPIHandle2.Init.TIMode = SPI_TIMODE_DISABLED;
SPIHandle2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
SPIHandle2.Init.CRCPolynomial = 7; // unused
- spi_init(wiznet5k_obj.spi);
+ spi_init(wiznet5k_obj.spi, false);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
@@ -238,6 +233,9 @@ STATIC mp_obj_t wiznet5k_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
};
ctlnetwork(CN_SET_NETINFO, (void*)&netinfo);
+ // register with network module
+ mod_network_register_nic(&wiznet5k_obj);
+
// return wiznet5k object
return &wiznet5k_obj;
}
@@ -275,98 +273,43 @@ STATIC mp_obj_t wiznet5k_ipaddr(mp_uint_t n_args, const mp_obj_t *args) {
if (n_args == 1) {
// get
mp_obj_t tuple[4] = {
- format_ip_addr(netinfo.ip),
- format_ip_addr(netinfo.sn),
- format_ip_addr(netinfo.gw),
- format_ip_addr(netinfo.dns),
+ mod_network_format_ipv4_addr(netinfo.ip),
+ mod_network_format_ipv4_addr(netinfo.sn),
+ mod_network_format_ipv4_addr(netinfo.gw),
+ mod_network_format_ipv4_addr(netinfo.dns),
};
return mp_obj_new_tuple(4, tuple);
} else {
// set
mp_obj_t *items;
mp_obj_get_array_fixed_n(args[1], 4, &items);
- parse_ip_addr(items[0], netinfo.ip);
- parse_ip_addr(items[1], netinfo.sn);
- parse_ip_addr(items[2], netinfo.gw);
- parse_ip_addr(items[3], netinfo.dns);
+ mod_network_parse_ipv4_addr(items[0], netinfo.ip);
+ mod_network_parse_ipv4_addr(items[1], netinfo.sn);
+ mod_network_parse_ipv4_addr(items[2], netinfo.gw);
+ mod_network_parse_ipv4_addr(items[3], netinfo.dns);
ctlnetwork(CN_SET_NETINFO, &netinfo);
return mp_const_none;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ipaddr_obj, 1, 2, wiznet5k_ipaddr);
-/// \method socket(family=AF_INET, type=SOCK_STREAM, fileno=-1)
-/// Create a socket.
-STATIC const mp_arg_t wiznet5k_socket_args[] = {
- { MP_QSTR_family, MP_ARG_INT, {.u_int = 0} }, // ignored, only AF_INET supported
- { MP_QSTR_type, MP_ARG_INT, {.u_int = Sn_MR_TCP} }, // SOCK_STREAM or SOCK_DGRAM
- { MP_QSTR_fileno, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
-};
-#define PYB_WIZNET5K_SOCKET_NUM_ARGS MP_ARRAY_SIZE(wiznet5k_socket_args)
-
-STATIC mp_obj_t wiznet5k_socket(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- // parse args
- mp_arg_val_t vals[PYB_WIZNET5K_SOCKET_NUM_ARGS];
- mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_WIZNET5K_SOCKET_NUM_ARGS, wiznet5k_socket_args, vals);
-
- if (vals[2].u_int < 0) {
- // get first unused socket number
- for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) {
- if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) {
- vals[2].u_int = sn;
- break;
- }
- }
- if (vals[2].u_int < 0) {
- // too many open sockets
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EMFILE)));
- }
- }
-
- return wiznet5k_socket_new(vals[2].u_int, vals[1].u_int);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wiznet5k_socket_obj, 1, wiznet5k_socket);
-
-/// \method gethostbyname(name)
-/// Use DNS to lookup a host name. Returns an IP address.
-STATIC mp_obj_t wiznet5k_gethostbyname(mp_obj_t self_in, mp_obj_t name_in) {
- uint8_t dns_ip[IPADDR_BUF_SIZE] = {8, 8, 8, 8};
- const char *name = mp_obj_str_get_str(name_in);
- uint8_t out_ip[IPADDR_BUF_SIZE];
- uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE);
- DNS_init(0, buf);
- mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip);
- m_del(uint8_t, buf, MAX_DNS_BUF_SIZE);
- if (ret == 1) {
- // success
- return format_ip_addr(out_ip);
- } else {
- // failure
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "DNS error %d", ret));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(wiznet5k_gethostbyname_obj, wiznet5k_gethostbyname);
-
STATIC const mp_map_elem_t wiznet5k_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_regs), (mp_obj_t)&wiznet5k_regs_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ipaddr), (mp_obj_t)&wiznet5k_ipaddr_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&wiznet5k_socket_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_gethostbyname), (mp_obj_t)&wiznet5k_gethostbyname_obj },
-
- // class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(0) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(Sn_MR_TCP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(Sn_MR_UDP) },
};
STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table);
-STATIC const mp_obj_type_t wiznet5k_type = {
- { &mp_type_type },
- .name = MP_QSTR_WIZnet5k,
- .print = wiznet5k_print,
- .make_new = wiznet5k_make_new,
- .locals_dict = (mp_obj_t)&wiznet5k_locals_dict,
+const mod_network_nic_type_t mod_network_nic_type_wiznet5k = {
+ .base = {
+ { &mp_type_type },
+ .name = MP_QSTR_WIZnet5k,
+ .print = wiznet5k_print,
+ .make_new = wiznet5k_make_new,
+ .locals_dict = (mp_obj_t)&wiznet5k_locals_dict,
+ },
+ .socket = wiznet5k_socket,
+ .gethostbyname = wiznet5k_gethostbyname,
};
/******************************************************************************/
@@ -378,6 +321,8 @@ typedef struct _wiznet5k_socket_obj_t {
uint8_t type;
} wiznet5k_socket_obj_t;
+STATIC const mp_obj_type_t wiznet5k_socket_type;
+
STATIC mp_obj_t wiznet5k_socket_new(uint8_t sn, mp_uint_t type) {
wiznet5k_socket_obj_t *s = m_new_obj(wiznet5k_socket_obj_t);
s->base.type = &wiznet5k_socket_type;
@@ -404,7 +349,7 @@ STATIC mp_obj_t wiznet5k_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
wiznet5k_socket_obj_t *self = self_in;
uint8_t ip[IPADDR_BUF_SIZE];
- mp_uint_t port = parse_net_addr(addr_in, ip);
+ mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip);
// open the socket in server mode
mp_int_t ret = socket(self->sn, self->type, port, 0);
@@ -441,7 +386,7 @@ STATIC mp_obj_t wiznet5k_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
// now connect
uint8_t ip[IPADDR_BUF_SIZE];
- mp_uint_t port = parse_net_addr(addr_in, ip);
+ mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip);
ret = connect(self->sn, ip, port);
check_sock_return_value(ret);
@@ -484,7 +429,7 @@ STATIC mp_obj_t wiznet5k_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_ob
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ);
uint8_t ip[IPADDR_BUF_SIZE];
- mp_uint_t port = parse_net_addr(addr_in, ip);
+ mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip);
mp_int_t ret = sendto(self->sn, bufinfo.buf, bufinfo.len, ip, port);
check_sock_return_value(ret);
return mp_obj_new_int(ret);
@@ -501,7 +446,7 @@ STATIC mp_obj_t wiznet5k_socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
check_sock_return_value(ret);
mp_obj_t tuple[2] = {
mp_obj_new_bytes(buf, ret),
- format_net_addr(ip, port),
+ mod_network_format_inet_addr(ip, port),
};
return mp_obj_new_tuple(2, tuple);
}
@@ -528,28 +473,3 @@ STATIC const mp_obj_type_t wiznet5k_socket_type = {
.print = wiznet5k_socket_print,
.locals_dict = (mp_obj_t)&wiznet5k_socket_locals_dict,
};
-
-/******************************************************************************/
-// Micro Python bindings; WIZnet5x00 module
-
-STATIC const mp_map_elem_t mp_module_wiznet5k_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_wiznet5k) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_WIZnet5k), (mp_obj_t)&wiznet5k_type },
-};
-
-STATIC const mp_obj_dict_t mp_module_wiznet5k_globals = {
- .base = {&mp_type_dict},
- .map = {
- .all_keys_are_qstrs = 1,
- .table_is_fixed_array = 1,
- .used = MP_ARRAY_SIZE(mp_module_wiznet5k_globals_table),
- .alloc = MP_ARRAY_SIZE(mp_module_wiznet5k_globals_table),
- .table = (mp_map_elem_t*)mp_module_wiznet5k_globals_table,
- },
-};
-
-const mp_obj_module_t mp_module_wiznet5k = {
- .base = { &mp_type_module },
- .name = MP_QSTR_wiznet5k,
- .globals = (mp_obj_dict_t*)&mp_module_wiznet5k_globals,
-};
diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h
index 8fe2f21027..e9b76414ad 100644
--- a/stmhal/mpconfigport.h
+++ b/stmhal/mpconfigport.h
@@ -77,20 +77,8 @@ extern const struct _mp_obj_module_t pyb_module;
extern const struct _mp_obj_module_t stm_module;
extern const struct _mp_obj_module_t time_module;
extern const struct _mp_obj_module_t mp_module_select;
-
-#if MICROPY_PY_WIZNET5K
-extern const struct _mp_obj_module_t mp_module_wiznet5k;
-#define MICROPY_PY_WIZNET5K_DEF { MP_OBJ_NEW_QSTR(MP_QSTR_wiznet5k), (mp_obj_t)&mp_module_wiznet5k },
-#else
-#define MICROPY_PY_WIZNET5K_DEF
-#endif
-
-#if MICROPY_PY_CC3K
-extern const struct _mp_obj_module_t mp_module_cc3k;
-#define MICROPY_PY_CC3K_DEF { MP_OBJ_NEW_QSTR(MP_QSTR_cc3k), (mp_obj_t)&mp_module_cc3k },
-#else
-#define MICROPY_PY_CC3K_DEF
-#endif
+extern const struct _mp_obj_module_t mp_module_usocket;
+extern const struct _mp_obj_module_t mp_module_network;
#define MICROPY_PORT_BUILTIN_MODULES \
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, \
@@ -98,8 +86,9 @@ extern const struct _mp_obj_module_t mp_module_cc3k;
{ MP_OBJ_NEW_QSTR(MP_QSTR_stm), (mp_obj_t)&stm_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_select), (mp_obj_t)&mp_module_select }, \
- MICROPY_PY_WIZNET5K_DEF \
- MICROPY_PY_CC3K_DEF \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_usocket }, \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mp_module_usocket }, \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&mp_module_network }, \
// extra constants
#define MICROPY_PORT_CONSTANTS \
diff --git a/stmhal/portmodules.h b/stmhal/portmodules.h
index d71f74e73c..ebeaae796d 100644
--- a/stmhal/portmodules.h
+++ b/stmhal/portmodules.h
@@ -29,6 +29,7 @@ extern const mp_obj_module_t pyb_module;
extern const mp_obj_module_t stm_module;
extern const mp_obj_module_t time_module;
extern const mp_obj_module_t mp_module_select;
+extern const mp_obj_module_t mp_module_usocket;
// additional helper functions exported by the modules
diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h
index 674b8f3f8b..d0d8c113b8 100644
--- a/stmhal/qstrdefsport.h
+++ b/stmhal/qstrdefsport.h
@@ -320,6 +320,20 @@ Q(pixel)
Q(text)
Q(show)
+// for usocket module
+Q(usocket)
+Q(socket)
+Q(getaddrinfo)
+Q(AF_INET)
+Q(AF_INET6)
+Q(SOCK_STREAM)
+Q(SOCK_DGRAM)
+Q(SOCK_RAW)
+
+// for network module
+Q(network)
+Q(route)
+
// for WIZnet5k class
#if MICROPY_PY_WIZNET5K
Q(wiznet5k)
@@ -356,25 +370,13 @@ Q(is_connected)
Q(ifconfig)
Q(patch_version)
Q(patch_program)
-Q(socket)
-Q(family)
-Q(type)
-Q(gethostbyname)
Q(WEP)
Q(WPA)
Q(WPA2)
-Q(AF_INET)
-Q(AF_INET6)
-Q(SOCK_STREAM)
-Q(SOCK_DGRAM)
-Q(SOCK_RAW)
-Q(IPPROTO_IP)
-Q(IPPROTO_ICMP)
-Q(IPPROTO_IPV4)
-Q(IPPROTO_TCP)
-Q(IPPROTO_UDP)
-Q(IPPROTO_IPV6)
-Q(IPPROTO_RAW)
+Q(ssid)
+Q(key)
+Q(security)
+Q(bssid)
Q(send)
Q(recv)
Q(bind)