summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/modnetwork.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-11-29 13:48:45 +0000
committerDamien George <damien.p.george@gmail.com>2014-12-04 18:57:57 +0000
commit29a1ec1bd6680d1108408cc825935012af10d938 (patch)
tree32f04d97e4e22c2739b7bfa17fefa71ad73fdb56 /stmhal/modnetwork.c
parentd8f239263dbcc3ab54964421ef6c9755a6537f6e (diff)
downloadmicropython-29a1ec1bd6680d1108408cc825935012af10d938.tar.gz
micropython-29a1ec1bd6680d1108408cc825935012af10d938.zip
stmhal: Overhaul network drivers; has generic network protocol in C.
This patch overhauls the network driver interface. A generic NIC must provide a set of C-level functions to implement low-level socket control (eg socket, bind, connect, send, recv). Doing this, the network and usocket modules can then use such a NIC to implement proper socket control at the Python level. This patch also updates the CC3K and WIZNET5K drivers to conform to the new interface, and fixes some bugs in the drivers. They now work reasonably well.
Diffstat (limited to 'stmhal/modnetwork.c')
-rw-r--r--stmhal/modnetwork.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/stmhal/modnetwork.c b/stmhal/modnetwork.c
index fd3fee9284..e4d0fcdf9e 100644
--- a/stmhal/modnetwork.c
+++ b/stmhal/modnetwork.c
@@ -61,6 +61,18 @@ void mod_network_register_nic(mp_obj_t nic) {
mp_obj_list_append(&mod_network_nic_list, nic);
}
+mp_obj_t mod_network_find_nic(const uint8_t *ip) {
+ // find a NIC that is suited to given IP address
+ for (mp_uint_t i = 0; i < mod_network_nic_list.len; i++) {
+ mp_obj_t nic = mod_network_nic_list.items[i];
+ // TODO check IP suitability here
+ //mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
+ return nic;
+ }
+
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC"));
+}
+
STATIC mp_obj_t network_route(void) {
return &mod_network_nic_list;
}
@@ -70,10 +82,10 @@ 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 },
+ { 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 },
+ { 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 },
@@ -90,18 +102,32 @@ const mp_obj_module_t mp_module_network = {
/******************************************************************************/
// Miscellaneous helpers
+void mod_network_convert_ipv4_endianness(uint8_t *ip) {
+ uint8_t ip0 = ip[0]; ip[0] = ip[3]; ip[3] = ip0;
+ uint8_t ip1 = ip[1]; ip[1] = ip[2]; ip[2] = ip1;
+}
+
+// Takes an address of the form '192.168.0.1' and converts it to network format
+// in out_ip (big endian, so the 192 is the first byte).
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);
+ mp_uint_t addr_len;
+ const char *addr_str = mp_obj_str_get_data(addr_in, &addr_len);
+ if (addr_len == 0) {
+ // special case of no address given
+ memset(out_ip, 0, MOD_NETWORK_IPADDR_BUF_SIZE);
+ return;
+ }
const char *s = addr_str;
+ const char *s_top = addr_str + addr_len;
for (mp_uint_t i = 0;; i++) {
mp_uint_t val = 0;
- for (; *s && *s != '.'; s++) {
+ for (; s < s_top && *s != '.'; s++) {
val = val * 10 + *s - '0';
}
out_ip[i] = val;
- if (i == 3 && *s == '\0') {
+ if (i == 3 && s == s_top) {
return;
- } else if (i < 3 && *s == '.') {
+ } else if (i < 3 && s < s_top && *s == '.') {
s++;
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid IP address"));