From 2e0cd20a1d3c6ddfaf0bb6dafc823955858334a9 Mon Sep 17 00:00:00 2001 From: danicampora Date: Mon, 19 Oct 2015 11:41:29 +0200 Subject: [PATCH] cc3200: Refactor network module to make the server a propper object. --- cc3200/mods/modnetwork.c | 137 ++++++++++++++++++++++++++-------- cc3200/mods/pybadc.c | 7 +- cc3200/qstrdefsport.h | 10 ++- cc3200/serverstask.c | 20 ++--- cc3200/serverstask.h | 9 ++- tests/wipy/wlan/server.py | 41 ++++++++++ tests/wipy/wlan/server.py.exp | 10 +++ 7 files changed, 181 insertions(+), 53 deletions(-) create mode 100644 tests/wipy/wlan/server.py create mode 100644 tests/wipy/wlan/server.py.exp diff --git a/cc3200/mods/modnetwork.c b/cc3200/mods/modnetwork.c index 3031c5e790..f4fe1b7a15 100644 --- a/cc3200/mods/modnetwork.c +++ b/cc3200/mods/modnetwork.c @@ -29,12 +29,28 @@ #include "py/mpstate.h" #include MICROPY_HAL_H +#include "py/obj.h" +#include "py/nlr.h" +#include "py/runtime.h" #include "modnetwork.h" #include "mpexception.h" #include "serverstask.h" #include "simplelink.h" +/****************************************************************************** + DEFINE TYPES + ******************************************************************************/ +typedef struct { + mp_obj_base_t base; +} network_server_obj_t; + +/****************************************************************************** + DECLARE PRIVATE DATA + ******************************************************************************/ +STATIC network_server_obj_t network_server_obj; +STATIC const mp_obj_type_t network_server_type; + /// \module network - network configuration /// /// This module provides network drivers and server configuration. @@ -43,48 +59,92 @@ void mod_network_init0(void) { } #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP) -STATIC mp_obj_t network_server_running(mp_uint_t n_args, const mp_obj_t *args) { - if (n_args > 0) { - // set - if (mp_obj_is_true(args[0])) { - servers_start(); - } else { - servers_stop(); - } - return mp_const_none; - } else { - // get - return mp_obj_new_bool(servers_are_enabled()); +STATIC mp_obj_t network_server_init_helper(mp_obj_t self, const mp_arg_val_t *args) { + const char *user = SERVERS_DEF_USER; + const char *pass = SERVERS_DEF_PASS; + if (args[0].u_obj != MP_OBJ_NULL) { + mp_obj_t *login; + mp_obj_get_array_fixed_n(args[0].u_obj, 2, &login); + user = mp_obj_str_get_str(login[0]); + pass = mp_obj_str_get_str(login[1]); } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_server_running_obj, 0, 1, network_server_running); -STATIC mp_obj_t network_server_login(mp_obj_t user, mp_obj_t pass) { - const char *_user = mp_obj_str_get_str(user); - const char *_pass = mp_obj_str_get_str(pass); - if (strlen(user) > SERVERS_USER_PASS_LEN_MAX || strlen(pass) > SERVERS_USER_PASS_LEN_MAX) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); + uint32_t timeout = SERVERS_DEF_TIMEOUT_MS / 1000; + if (args[1].u_obj != MP_OBJ_NULL) { + timeout = mp_obj_get_int(args[1].u_obj); } - servers_set_login ((char *)_user, (char *)_pass); + + // configure the new login + servers_set_login ((char *)user, (char *)pass); + + // configure the timeout + servers_set_timeout(timeout * 1000); + + // start the servers + servers_start(); + return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(network_server_login_obj, network_server_login); + +STATIC const mp_arg_t network_server_args[] = { + { MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_login, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, +}; +STATIC mp_obj_t network_server_new (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(network_server_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(args), network_server_args, args); + + // check the server id + if (args[0].u_obj != MP_OBJ_NULL) { + if (mp_obj_get_int(args[0].u_obj) != 0) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable)); + } + } + + // setup the object and initialize it + network_server_obj_t *self = &network_server_obj; + self->base.type = &network_server_type; + network_server_init_helper(self, &args[1]); + + return self; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_server_new_obj, 0, network_server_new); + +STATIC mp_obj_t network_server_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(network_server_args) - 1]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &network_server_args[1], args); + return network_server_init_helper(pos_args[0], args); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_server_init_obj, 1, network_server_init); // timeout value given in seconds STATIC mp_obj_t network_server_timeout(mp_uint_t n_args, const mp_obj_t *args) { - if (n_args > 0) { - uint32_t _timeout = mp_obj_get_int(args[0]); - if (!servers_set_timeout(_timeout * 1000)) { - // timeout is too low - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); - } + if (n_args > 1) { + uint32_t timeout = mp_obj_get_int(args[1]); + servers_set_timeout(timeout * 1000); return mp_const_none; } else { // get return mp_obj_new_int(servers_get_timeout() / 1000); } } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_server_timeout_obj, 0, 1, network_server_timeout); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_server_timeout_obj, 1, 2, network_server_timeout); + +STATIC mp_obj_t network_server_running(mp_obj_t self_in) { + // get + return mp_obj_new_bool(servers_are_enabled()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_server_running_obj, network_server_running); + +STATIC mp_obj_t network_server_deinit(mp_obj_t self_in) { + // simply stop the servers + servers_stop(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_server_deinit_obj, network_server_deinit); #endif STATIC const mp_map_elem_t mp_module_network_globals_table[] = { @@ -92,9 +152,7 @@ STATIC const mp_map_elem_t mp_module_network_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_WLAN), (mp_obj_t)&mod_network_nic_type_wlan }, #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP) - { MP_OBJ_NEW_QSTR(MP_QSTR_server_running), (mp_obj_t)&network_server_running_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_server_login), (mp_obj_t)&network_server_login_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_server_timeout), (mp_obj_t)&network_server_timeout_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_server), (mp_obj_t)&network_server_new_obj }, #endif }; @@ -105,3 +163,20 @@ const mp_obj_module_t mp_module_network = { .name = MP_QSTR_network, .globals = (mp_obj_dict_t*)&mp_module_network_globals, }; + +#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP) +STATIC const mp_map_elem_t network_server_locals_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&network_server_init_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&network_server_deinit_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_timeout), (mp_obj_t)&network_server_timeout_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_running), (mp_obj_t)&network_server_running_obj }, +}; + +STATIC MP_DEFINE_CONST_DICT(network_server_locals_dict, network_server_locals_dict_table); + +STATIC const mp_obj_type_t network_server_type = { + { &mp_type_type }, + .name = MP_QSTR_server, + .locals_dict = (mp_obj_t)&network_server_locals_dict, +}; +#endif diff --git a/cc3200/mods/pybadc.c b/cc3200/mods/pybadc.c index 97a0b82a35..2cb1cad088 100644 --- a/cc3200/mods/pybadc.c +++ b/cc3200/mods/pybadc.c @@ -195,7 +195,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_deinit_obj, adc_deinit); STATIC mp_obj_t adc_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC const mp_arg_t pyb_adc_channel_args[] = { - { MP_QSTR_id, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; @@ -204,12 +204,11 @@ STATIC mp_obj_t adc_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_adc_channel_args, args); uint ch_id; - if (args[0].u_obj != mp_const_none) { + if (args[0].u_obj != MP_OBJ_NULL) { ch_id = mp_obj_get_int(args[0].u_obj); if (ch_id >= PYB_ADC_NUM_CHANNELS) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_os_resource_not_avaliable)); - } - else if (args[1].u_obj != mp_const_none) { + } else if (args[1].u_obj != mp_const_none) { uint pin_ch_id = pin_find_peripheral_type (args[1].u_obj, PIN_FN_ADC, 0); if (ch_id != pin_ch_id) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h index 4e7e69d5f6..b42c69f811 100644 --- a/cc3200/qstrdefsport.h +++ b/cc3200/qstrdefsport.h @@ -278,16 +278,18 @@ Q(CERT_REQUIRED) // for network class Q(network) -Q(server_running) -Q(server_login) -Q(server_timeout) +Q(server) +Q(init) +Q(deinit) +Q(login) +Q(timeout) +Q(running) // for WLAN class Q(WLAN) Q(id) Q(init) Q(mode) -Q(key) Q(auth) Q(ssid) Q(bssid) diff --git a/cc3200/serverstask.c b/cc3200/serverstask.c index f39ccdbdfc..28a6fa5fd6 100644 --- a/cc3200/serverstask.c +++ b/cc3200/serverstask.c @@ -30,6 +30,7 @@ #include "py/mpconfig.h" #include MICROPY_HAL_H #include "py/misc.h" +#include "py/nlr.h" #include "serverstask.h" #include "simplelink.h" #include "debug.h" @@ -37,17 +38,9 @@ #include "ftp.h" #include "pybwdt.h" #include "modusocket.h" +#include "mpexception.h" -/****************************************************************************** - DECLARE PRIVATE DEFINITIONS - ******************************************************************************/ - -#define SERVERS_DEF_USER "micro" -#define SERVERS_DEF_PASS "python" -#define SERVERS_DEF_TIMEOUT_MS 300000 // 5 minutes -#define SERVERS_MIN_TIMEOUT_MS 5000 // 5 seconds - /****************************************************************************** DEFINE PRIVATE TYPES ******************************************************************************/ @@ -177,16 +170,19 @@ void servers_close_socket (int16_t *sd) { } void servers_set_login (char *user, char *pass) { + if (strlen(user) > SERVERS_USER_PASS_LEN_MAX || strlen(pass) > SERVERS_USER_PASS_LEN_MAX) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); + } memcpy(servers_user, user, SERVERS_USER_PASS_LEN_MAX); memcpy(servers_pass, pass, SERVERS_USER_PASS_LEN_MAX); } -bool servers_set_timeout (uint32_t timeout) { +void servers_set_timeout (uint32_t timeout) { if (timeout < SERVERS_MIN_TIMEOUT_MS) { - return false; + // timeout is too low + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); } servers_data.timeout = timeout; - return true; } uint32_t servers_get_timeout (void) { diff --git a/cc3200/serverstask.h b/cc3200/serverstask.h index 49309cf69a..1f4b8e32f6 100644 --- a/cc3200/serverstask.h +++ b/cc3200/serverstask.h @@ -36,10 +36,15 @@ #define SERVERS_SSID_LEN_MAX 16 #define SERVERS_KEY_LEN_MAX 16 -#define SERVERS_USER_PASS_LEN_MAX 16 +#define SERVERS_USER_PASS_LEN_MAX 32 #define SERVERS_CYCLE_TIME_MS 2 +#define SERVERS_DEF_USER "micro" +#define SERVERS_DEF_PASS "python" +#define SERVERS_DEF_TIMEOUT_MS 300000 // 5 minutes +#define SERVERS_MIN_TIMEOUT_MS 5000 // 5 seconds + /****************************************************************************** DEFINE TYPES ******************************************************************************/ @@ -61,7 +66,7 @@ extern bool servers_are_enabled (void); extern void servers_close_socket (int16_t *sd); extern void servers_set_login (char *user, char *pass); extern void server_sleep_sockets (void); -extern bool servers_set_timeout (uint32_t timeout); +extern void servers_set_timeout (uint32_t timeout); extern uint32_t servers_get_timeout (void); #endif /* SERVERSTASK_H_ */ diff --git a/tests/wipy/wlan/server.py b/tests/wipy/wlan/server.py new file mode 100644 index 0000000000..07dc26f504 --- /dev/null +++ b/tests/wipy/wlan/server.py @@ -0,0 +1,41 @@ +''' +network server test for the CC3200 based boards. +''' + +import os +import network + +mch = os.uname().machine +if not 'LaunchPad' in mch and not'WiPy' in mch: + raise Exception('Board not supported!') + +server = network.server() + +print(server.timeout() == 300) +print(server.running() == True) +server.deinit() +print(server.running() == False) + +server.init(login=('test-user', 'test-password'), timeout=60) +print(server.running() == True) +print(server.timeout() == 60) + +server.deinit() +print(server.running() == False) +server.init() +print(server.running() == True) + +try: + server.init(1) +except: + print('Exception') + +try: + server.init(0, login=('0000000000011111111111222222222222333333', 'abc')) +except: + print('Exception') + +try: + server.timeout(1) +except: + print('Exception') diff --git a/tests/wipy/wlan/server.py.exp b/tests/wipy/wlan/server.py.exp new file mode 100644 index 0000000000..a125ec934d --- /dev/null +++ b/tests/wipy/wlan/server.py.exp @@ -0,0 +1,10 @@ +True +True +True +True +True +True +True +Exception +Exception +Exception