From 8b803a4429fe8524e85f710701091fdf1a8f29f4 Mon Sep 17 00:00:00 2001 From: robert Date: Mon, 7 Oct 2019 15:06:12 +0200 Subject: [PATCH 01/12] mods/pybadc.c: Fix the argument handling of bits=x for adc.init() Before, the only accepted argument & value for adc.init() was bits=12, and even that was discarded. With that change, the function meets the documentation and works as expected. --- esp32/mods/pybadc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esp32/mods/pybadc.c b/esp32/mods/pybadc.c index 9737119c56..29204cf03e 100644 --- a/esp32/mods/pybadc.c +++ b/esp32/mods/pybadc.c @@ -153,10 +153,12 @@ STATIC mp_obj_t adc_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *k mp_arg_val_t args[MP_ARRAY_SIZE(pyb_adc_init_args) - 1]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_adc_init_args[1], args); // check the number of bits - if (args[0].u_int != 12) { + if (args[0].u_int < 9 || args[0].u_int > 12) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); } - pyb_adc_init(pos_args[0]); + pyb_adc_obj_t *self = pos_args[0]; + self->width = args[0].u_int; + pyb_adc_init(self); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adc_init_obj, 1, adc_init); From f3b7732f78de58240369544b1223d73b81762b75 Mon Sep 17 00:00:00 2001 From: Christian Ehlers Date: Mon, 30 Sep 2019 22:28:38 +0200 Subject: [PATCH 02/12] Update modlte.c Improved SIM card detection, ICCID string parsing # Conflicts: # esp32/mods/modlte.c --- esp32/mods/modlte.c | 235 ++++++++++++++++++++++++++++++++------------ 1 file changed, 172 insertions(+), 63 deletions(-) diff --git a/esp32/mods/modlte.c b/esp32/mods/modlte.c index 123d8ff883..10e14ed358 100644 --- a/esp32/mods/modlte.c +++ b/esp32/mods/modlte.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017, Pycom Limited and its licensors. +* Copyright (c) 2019, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence @@ -30,7 +30,6 @@ #include "esp_system.h" #include "esp_spi_flash.h" #include "nvs_flash.h" -#include "esp_event.h" #include "esp_event_loop.h" #include "ff.h" @@ -41,7 +40,7 @@ #include "netutils.h" #include "modnetwork.h" #include "modusocket.h" -#include "pybioctl.h" +#include "py/stream.h" //#include "pybrtc.h" #include "serverstask.h" #include "mpexception.h" @@ -67,6 +66,7 @@ #include "pycom_config.h" #include "modmachine.h" +#include "mpirq.h" /****************************************************************************** DEFINE TYPES @@ -86,7 +86,7 @@ /****************************************************************************** DECLARE PRIVATE DATA ******************************************************************************/ -static lte_obj_t lte_obj = {.init = false}; +static lte_obj_t lte_obj = {.init = false, .trigger = LTE_TRIGGER_NONE, .events = 0, .handler = NULL, .handler_arg = NULL}; static lte_task_rsp_data_t modlte_rsp; uart_dev_t* uart_driver_0 = &UART0; uart_dev_t* uart_driver_lte = &UART2; @@ -103,6 +103,9 @@ extern TaskHandle_t mpTaskHandle; extern TaskHandle_t svTaskHandle; #if defined(FIPY) extern TaskHandle_t xLoRaTaskHndl; +#ifdef LORA_OPENTHREAD_ENABLED +extern TaskHandle_t xMeshTaskHndl; +#endif extern TaskHandle_t xSigfoxTaskHndl; #endif extern TaskHandle_t xLTETaskHndl; @@ -113,7 +116,7 @@ extern TaskHandle_t xLTETaskHndl; /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ -static bool lte_push_at_command_ext (char *cmd_str, uint32_t timeout, const char *expected_rsp); +static bool lte_push_at_command_ext (char *cmd_str, uint32_t timeout, const char *expected_rsp, size_t len); static bool lte_push_at_command (char *cmd_str, uint32_t timeout); static void lte_pause_ppp(void); static bool lte_check_attached(bool legacy); @@ -125,7 +128,8 @@ STATIC mp_obj_t lte_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t STATIC mp_obj_t lte_deinit(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); STATIC mp_obj_t lte_disconnect(mp_obj_t self_in); - +static void lte_set_default_inf(void); +static void lte_callback_handler(void* arg); /****************************************************************************** DEFINE PUBLIC FUNCTIONS ******************************************************************************/ @@ -139,29 +143,41 @@ void modlte_start_modem(void) vTaskDelay(100 / portTICK_PERIOD_MS); portYIELD(); } + +void modlte_urc_events(lte_events_t events) +{ + switch(events) + { + case LTE_EVENT_COVERAGE_LOST: + if ((lte_obj.trigger & LTE_TRIGGER_SIG_LOST)) { + lte_obj.events |= (uint32_t)LTE_TRIGGER_SIG_LOST; + } + mp_irq_queue_interrupt(lte_callback_handler, <e_obj); + break; + default: + break; + } +} //***************************************************************************** // DEFINE STATIC FUNCTIONS //***************************************************************************** -static bool lte_push_at_command_ext(char *cmd_str, uint32_t timeout, const char *expected_rsp) { - lte_task_cmd_data_t cmd = { .timeout = timeout }; - memcpy(cmd.data, cmd_str, strlen(cmd_str)); - //printf("[CMD] %s\n", cmd_str); - lteppp_send_at_command(&cmd, &modlte_rsp); - if (strstr(modlte_rsp.data, expected_rsp) != NULL) { - //printf("[OK] %s\n", modlte_rsp.data); - return true; +static void lte_callback_handler(void* arg) +{ + lte_obj_t *self = arg; + + if (self->handler && self->handler != mp_const_none) { + + mp_call_function_1(self->handler, self->handler_arg); } - //printf("[FAIL] %s\n", modlte_rsp.data); - return false; } -static bool lte_push_at_command_delay_ext (char *cmd_str, uint32_t timeout, const char *expected_rsp, TickType_t delay) { - lte_task_cmd_data_t cmd = { .timeout = timeout }; - memcpy(cmd.data, cmd_str, strlen(cmd_str)); +static bool lte_push_at_command_ext(char *cmd_str, uint32_t timeout, const char *expected_rsp, size_t len) { + lte_task_cmd_data_t cmd = { .timeout = timeout, .dataLen = len}; + memcpy(cmd.data, cmd_str, len); //printf("[CMD] %s\n", cmd_str); - lteppp_send_at_command_delay(&cmd, &modlte_rsp, delay); - if (strstr(modlte_rsp.data, expected_rsp) != NULL) { + lteppp_send_at_command(&cmd, &modlte_rsp); + if ((expected_rsp == NULL) || (strstr(modlte_rsp.data, expected_rsp) != NULL)) { //printf("[OK] %s\n", modlte_rsp.data); return true; } @@ -170,11 +186,7 @@ static bool lte_push_at_command_delay_ext (char *cmd_str, uint32_t timeout, cons } static bool lte_push_at_command (char *cmd_str, uint32_t timeout) { - return lte_push_at_command_ext(cmd_str, timeout, LTE_OK_RSP); -} - -static bool lte_push_at_command_delay (char *cmd_str, uint32_t timeout, TickType_t delay) { - return lte_push_at_command_delay_ext(cmd_str, timeout, LTE_OK_RSP, delay); + return lte_push_at_command_ext(cmd_str, timeout, LTE_OK_RSP, strlen(cmd_str)); } static void lte_pause_ppp(void) { @@ -232,8 +244,9 @@ static bool lte_check_attached(bool legacy) { attached = true; } } else { - if ((pos = strstr(modlte_rsp.data, "+CEREG: 2,1,")) || (pos = strstr(modlte_rsp.data, "+CEREG: 2,5,")) || (pos = strstr(modlte_rsp.data, "+CEREG: 2,4"))) { + if ((pos = strstr(modlte_rsp.data, "+CEREG: 2,1,")) || (pos = strstr(modlte_rsp.data, "+CEREG: 2,5,"))) { attached = true; + } else { if((pos = strstr(modlte_rsp.data, "+CEREG: 2,4"))) { lte_ue_is_out_of_coverage = true; @@ -242,7 +255,6 @@ static bool lte_check_attached(bool legacy) { { lte_ue_is_out_of_coverage = false; } - } else { attached = false; } } @@ -319,6 +331,11 @@ static void lte_check_init(void) { } } +static void lte_set_default_inf(void) +{ + lteppp_set_default_inf(); +} + static void lte_check_inppp(void) { if (lteppp_get_state() == E_LTE_PPP) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "LTE modem is in data state, cannot send AT commands")); @@ -326,16 +343,23 @@ static void lte_check_inppp(void) { } static bool lte_check_sim_present(void) { + lte_push_at_command("AT+CFUN?", LTE_RX_TIMEOUT_MIN_MS); + if (strstr(modlte_rsp.data, "+CFUN: 0")) { + lte_push_at_command("AT+CFUN=4", LTE_RX_TIMEOUT_MAX_MS); + mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); + } lte_push_at_command("AT+CPIN?", LTE_RX_TIMEOUT_MAX_MS); - if (strstr(modlte_rsp.data, "ERROR")) { - lte_push_at_command("AT+CPIN?", LTE_RX_TIMEOUT_MAX_MS); - if (strstr(modlte_rsp.data, "ERROR")) { - return false; - } else { - return true; - } + if (strstr(modlte_rsp.data, "READY")) { + return true; } else { - return true; + for (int n=0; n < 4; n++) { + mp_hal_delay_ms(1000); + lte_push_at_command("AT+CPIN?", LTE_RX_TIMEOUT_MAX_MS); + if (strstr(modlte_rsp.data, "READY")) { + return true; + } + } + return false; } } @@ -349,6 +373,9 @@ static void TASK_LTE_UPGRADE(void *pvParameters){ #if defined(FIPY) vTaskSuspend(xLoRaTaskHndl); vTaskSuspend(xSigfoxTaskHndl); +#ifdef LORA_OPENTHREAD_ENABLED + vTaskSuspend(xMeshTaskHndl); +#endif #endif vTaskSuspend(xLTETaskHndl); @@ -439,7 +466,8 @@ static mp_obj_t lte_init_helper(lte_obj_t *self, const mp_arg_val_t *args) { // configure the carrier lte_push_at_command("AT+SQNCTM?", LTE_RX_TIMEOUT_MAX_MS); - if (!strstr(modlte_rsp.data, carrier)) { + const char* detected_carrier = modlte_rsp.data; + if (!strstr(detected_carrier, carrier) && (args[0].u_obj != mp_const_none)) { sprintf(at_cmd, "AT+SQNCTM=\"%s\"", carrier); lte_push_at_command(at_cmd, LTE_RX_TIMEOUT_MAX_MS); lteppp_wait_at_rsp("+S", LTE_RX_TIMEOUT_MAX_MS, true, NULL); @@ -450,10 +478,12 @@ static mp_obj_t lte_init_helper(lte_obj_t *self, const mp_arg_val_t *args) { lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); } - - // at least enable access to the SIM + if (!strstr(detected_carrier, carrier) && (!strstr(detected_carrier, "standard"))) { + lte_obj.carrier = true; + } lte_push_at_command("AT+CFUN=4", LTE_RX_TIMEOUT_MAX_MS); lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); + lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); } lteppp_set_state(E_LTE_IDLE); @@ -610,8 +640,14 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t lte_check_attached(lte_legacyattach_flag); if (lteppp_get_state() < E_LTE_ATTACHING) { - - if (!lte_obj.carrier) { + const char *carrier = "standard"; + if (!lte_push_at_command("AT+SQNCTM?", LTE_RX_TIMEOUT_MAX_MS)) { + if (!lte_push_at_command("AT+SQNCTM?", LTE_RX_TIMEOUT_MAX_MS)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Modem did not respond!\n")); + } + } + if (strstr(modlte_rsp.data, carrier)) { + lte_obj.carrier = false; /* Get configured bands in modem */ lte_task_cmd_data_t cmd = { .timeout = LTE_RX_TIMEOUT_MAX_MS }; memcpy(cmd.data, "AT+SMDD", strlen("AT+SMDD")); @@ -619,6 +655,10 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t /* Dummy command for command response > Uart buff size */ memcpy(cmd.data, "Pycom_Dummy", strlen("Pycom_Dummy")); MP_THREAD_GIL_EXIT(); + if(strstr(modlte_rsp.data, "17 bands") != NULL) + { + is_hw_new_band_support = true; + } while(modlte_rsp.data_remaining) { if (!is_hw_new_band_support) { @@ -640,6 +680,7 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t lte_push_at_command("AT!=\"clearscanconfig\"", LTE_RX_TIMEOUT_MIN_MS); // Delay to ensure next addScan command is not discarded vTaskDelay(1000); + if (args[0].u_obj == mp_const_none) { lte_push_at_command("AT!=\"RRC::addScanBand band=3\"", LTE_RX_TIMEOUT_MIN_MS); lte_push_at_command("AT!=\"RRC::addScanBand band=4\"", LTE_RX_TIMEOUT_MIN_MS); @@ -660,7 +701,7 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t { case 5: case 8: - if(!is_hw_new_band_support) + if (!is_hw_new_band_support) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "band %d not supported by this board hardware!", band)); } @@ -682,7 +723,7 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "band %d not supported by current modem Firmware [%d], please upgrade!", band, version)); } - if(!is_hw_new_band_support) + if (!is_hw_new_band_support) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "band %d not supported by this board hardware!", band)); } @@ -728,6 +769,8 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "band %d not supported", band)); } } + } else { + lte_obj.carrier = true; } if (args[3].u_obj != mp_const_none) { lte_obj.cid = args[3].u_int; @@ -912,17 +955,18 @@ STATIC mp_obj_t lte_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t } if (lteppp_get_state() == E_LTE_ATTACHED || (args[1].u_bool && lteppp_get_state() == E_LTE_SUSPENDED)) { - if (args[1].u_bool || !lte_push_at_command_ext("ATO", LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP)) { + if (args[1].u_bool || !lte_push_at_command_ext("ATO", LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP, strlen("ATO") )) { char at_cmd[LTE_AT_CMD_SIZE_MAX - 4]; if (args[0].u_obj != mp_const_none) { lte_obj.cid = args[0].u_int; } sprintf(at_cmd, "AT+CGDATA=\"PPP\",%d", lte_obj.cid); // set the PPP state in advance, to avoid CEREG? to be sent right after PPP is entered - if (!lte_push_at_command_ext(at_cmd, LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP)) { + if (!lte_push_at_command_ext(at_cmd, LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP, strlen(at_cmd) )) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); } } + mod_network_register_nic(<e_obj); lteppp_connect(); lteppp_set_state(E_LTE_PPP); vTaskDelay(1000); @@ -961,7 +1005,7 @@ STATIC mp_obj_t lte_resume(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t lte_obj.cid = args[0].u_int; } - if (lte_push_at_command_ext("ATO", LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP)) { + if (lte_push_at_command_ext("ATO", LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP, strlen("ATO") )) { lteppp_connect(); lteppp_resume(); lteppp_set_state(E_LTE_PPP); @@ -997,6 +1041,7 @@ STATIC mp_obj_t lte_disconnect(mp_obj_t self_in) { } } lte_check_attached(lte_legacyattach_flag); + mod_network_deregister_nic(<e_obj); } return mp_const_none; } @@ -1031,7 +1076,6 @@ STATIC mp_obj_t lte_send_at_cmd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_m lte_check_inppp(); STATIC const mp_arg_t allowed_args[] = { { MP_QSTR_cmd, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_delay, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -1039,15 +1083,23 @@ STATIC mp_obj_t lte_send_at_cmd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_m if (args[0].u_obj == mp_const_none) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "the command must be specified!")); } - const char *cmd = mp_obj_str_get_str(args[0].u_obj); - lte_push_at_command_delay((char *)cmd, LTE_RX_TIMEOUT_MAX_MS, args[1].u_int); + if (MP_OBJ_IS_STR_OR_BYTES(args[0].u_obj)) + { + size_t len; + lte_push_at_command_ext((char *)(mp_obj_str_get_data(args[0].u_obj, &len)), LTE_RX_TIMEOUT_MAX_MS, NULL, len); + } + else + { + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments)); + } + vstr_t vstr; vstr_init(&vstr, 0); vstr_add_str(&vstr, modlte_rsp.data); MP_THREAD_GIL_EXIT(); while(modlte_rsp.data_remaining) { - lte_push_at_command_delay("Pycom_Dummy", LTE_RX_TIMEOUT_MAX_MS, args[1].u_int); + lte_push_at_command_ext("Pycom_Dummy", LTE_RX_TIMEOUT_MAX_MS, NULL, strlen("Pycom_Dummy") ); vstr_add_str(&vstr, modlte_rsp.data); } MP_THREAD_GIL_ENTER(); @@ -1106,19 +1158,25 @@ STATIC mp_obj_t lte_time(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_time_obj, lte_time); STATIC mp_obj_t lte_iccid(mp_obj_t self_in) { - lte_check_init(); - lte_check_inppp(); - char *pos; - vstr_t vstr; - vstr_init_len(&vstr, strlen("AT+SQNCCID?")); - strcpy(vstr.buf, "AT+SQNCCID?"); - lte_send_raw_at(MP_OBJ_NULL, mp_obj_new_str_from_vstr(&mp_type_str, &vstr)); - if ((pos = strstr(modlte_rsp.data, "SQNCCID:")) && (strlen(pos) > 25)) { - vstr_init_len(&vstr, 20); - memcpy(vstr.buf, &pos[10], 20); - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); - } - return mp_const_none; + lte_check_init(); + lte_check_inppp(); + if (lte_check_sim_present()) { + char *pos, *iccid; + vstr_t vstr; + vstr_init_len(&vstr, strlen("AT+SQNCCID?")); + strcpy(vstr.buf, "AT+SQNCCID?"); + lte_send_raw_at(MP_OBJ_NULL, mp_obj_new_str_from_vstr(&mp_type_str, &vstr)); + if ((pos = strstr(modlte_rsp.data, "SQNCCID:")) && (strlen(pos) > 25)) { + iccid = strchr(pos, '"')+1; + pos = strchr(iccid, '"'); + vstr_init_len(&vstr, strlen(iccid)-strlen(pos)); + memcpy(vstr.buf, iccid, strlen(iccid)-strlen(pos)); + return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + } + } else { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "SIM card not found!")); + } + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_iccid_obj, lte_iccid); @@ -1276,6 +1334,53 @@ STATIC mp_obj_t lte_reconnect_uart (void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(lte_reconnect_uart_obj, lte_reconnect_uart); +STATIC mp_obj_t lte_callback(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_trigger, MP_ARG_REQUIRED | MP_ARG_OBJ, }, + { MP_QSTR_handler, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_arg, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + // parse arguments + 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(args), allowed_args, args); + lte_obj_t *self = pos_args[0]; + + // enable the callback + if (args[0].u_obj != mp_const_none && args[1].u_obj != mp_const_none) + { + self->trigger = mp_obj_get_int(args[0].u_obj); + + self->handler = args[1].u_obj; + + if (args[2].u_obj == mp_const_none) { + self->handler_arg = self; + } else { + self->handler_arg = args[2].u_obj; + } + } + else + { // disable the callback + self->trigger = 0; + mp_irq_remove(self); + INTERRUPT_OBJ_CLEAN(self); + } + + mp_irq_add(self, args[1].u_obj); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(lte_callback_obj, 1, lte_callback); + +STATIC mp_obj_t lte_events(mp_obj_t self_in) { + lte_obj_t *self = self_in; + + int32_t events = self->events; + self->events = 0; + return mp_obj_new_int(events); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_events_obj, lte_events); + STATIC const mp_map_elem_t lte_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)<e_init_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)<e_deinit_obj }, @@ -1297,6 +1402,8 @@ STATIC const mp_map_elem_t lte_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_modem_upgrade_mode), (mp_obj_t)<e_upgrade_mode_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_reconnect_uart), (mp_obj_t)<e_reconnect_uart_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_ue_coverage), (mp_obj_t)<e_ue_coverage_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_lte_callback), (mp_obj_t)<e_callback_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_events), (mp_obj_t)<e_events_obj }, #ifdef LTE_DEBUG_BUFF { MP_OBJ_NEW_QSTR(MP_QSTR_debug_buff), (mp_obj_t)<e_debug_buff_obj }, #endif @@ -1304,6 +1411,7 @@ STATIC const mp_map_elem_t lte_locals_dict_table[] = { // class constants { MP_OBJ_NEW_QSTR(MP_QSTR_IP), MP_OBJ_NEW_QSTR(MP_QSTR_IP) }, { MP_OBJ_NEW_QSTR(MP_QSTR_IPV4V6), MP_OBJ_NEW_QSTR(MP_QSTR_IPV4V6) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EVENT_COVERAGE_LOSS), MP_OBJ_NEW_SMALL_INT(LTE_TRIGGER_SIG_LOST) }, }; STATIC MP_DEFINE_CONST_DICT(lte_locals_dict, lte_locals_dict_table); @@ -1331,4 +1439,5 @@ const mod_network_nic_type_t mod_network_nic_type_lte = { .n_ioctl = lwipsocket_socket_ioctl, .n_setupssl = lwipsocket_socket_setup_ssl, .inf_up = ltepp_is_ppp_conn_up, + .set_default_inf = lte_set_default_inf }; From 48f23f7d010c4af9702fa097f7f6e99f16edfc75 Mon Sep 17 00:00:00 2001 From: Christian Ehlers Date: Fri, 4 Oct 2019 19:44:12 +0200 Subject: [PATCH 03/12] Update sqnsupgrade.py Update sqnsupgrade to version 1.2.6 --- esp32/frozen/LTE/sqnsupgrade.py | 80 ++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/esp32/frozen/LTE/sqnsupgrade.py b/esp32/frozen/LTE/sqnsupgrade.py index b4887870ce..5331c053be 100644 --- a/esp32/frozen/LTE/sqnsupgrade.py +++ b/esp32/frozen/LTE/sqnsupgrade.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -VERSION = "1.2.5" +VERSION = "1.2.6" # Copyright (c) 2019, Pycom Limited. # @@ -339,7 +339,7 @@ def __get_wait_msg(self, load_fff=True): - def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_ffh=False, mirror=False, switch_ffh=False, bootrom=False, rgbled=0x050505, debug=False, pkgdebug=False, atneg=True, max_try=10, direct=True, atneg_only=False, info_only=False, expected_smod=None, verbose=False, load_fff=False, mtools=False): + def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_ffh=False, mirror=False, switch_ffh=False, bootrom=False, rgbled=0x050505, debug=False, pkgdebug=False, atneg=True, max_try=10, direct=True, atneg_only=False, info_only=False, expected_smod=None, verbose=False, load_fff=False, mtools=False, fc=False): self.__wait_msg = False mirror = True if atneg_only else mirror recover = True if atneg_only else load_ffh @@ -365,7 +365,7 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f external = True br = 115200 if recover and not direct else baudrate if debug: print('Setting baudrate to {}'.format(br)) - self.__serial = serial.Serial(port, br, bytesize=serial.EIGHTBITS, timeout=1 if info_only else 0.1) + self.__serial = serial.Serial(port, br, bytesize=serial.EIGHTBITS, timeout=1 if info_only else 0.1, rtscts=fc) self.__serial.reset_input_buffer() self.__serial.reset_output_buffer() @@ -408,7 +408,7 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f if blobsize < 128: print('Firmware file is too small!') reconnect_uart() - sys.exit(1) + return False if blobsize > 4194304: if load_fff: print("Firmware file is too big to load via FFF method. Using ON_THE_FLY") @@ -447,7 +447,7 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f if verbose: print('Sending AT+FSRDFILE="/fs/crashdump"') self.__serial.write(b'AT+FSRDFILE="/fs/crashdump"\r\n') - response = self.read_rsp(size=100) + response = self.read_rsp(size=1024) if verbose: print('AT+FSRDFILE="/fs/crashdump" returned {}'.format(response)) self.__serial.read() @@ -484,7 +484,7 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f else: print('Received ERROR from AT+SMSWBOOT=3,1! Aborting!') reconnect_uart() - sys.exit(1) + return False time.sleep(3) resp = self.__serial.read() if debug: print("Response after reset: {}".format(resp)) @@ -548,7 +548,10 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f response = self.read_rsp(size=4) if response != b'OK\r\n' and response != b'\r\nOK' and response != b'\nOK': raise OSError("Invalid answer '%s' from the device" % response) - blob.close() + try: + blob.close() + except: + pass self.__serial.read() elif recover and (not direct): @@ -571,7 +574,7 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f if not b'OK' in response: print('Failed to start STP mode!') reconnect_uart() - sys.exit(1) + return False else: print('AT auto-negotiation failed! Exiting.') return False @@ -582,13 +585,18 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f if not b'OK' in response: print('Failed to start STP mode!') reconnect_uart() - sys.exit(1) + return False try: if debug: if verbose: print('Starting STP code upload') - if stp.start(blob, blobsize, self.__serial, baudrate, AT=False, debug=debug, pkgdebug=pkgdebug): - blob.close() + start = stp.start(blob, blobsize, self.__serial, baudrate, AT=False, debug=debug, pkgdebug=pkgdebug) + if debug: print('start returned {} type {}'.format(start, type(start))) + if start == True: + try: + blob.close() + except: + pass self.__serial.read() if switch_ffh: if verbose: print('Bootrom updated successfully, switching to recovery mode') @@ -602,12 +610,19 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f if verbose: print('Code download done, returning to user mode') abort = recover else: - blob.close() - print('Code download failed, aborting!') + try: + blob.close() + except: + pass + print('Code download failed[1], aborting!') return False - except: - blob.close() - print('Code download failed, aborting!') + except Exception as ex: + try: + blob.close() + except: + pass + print('Exception: {}'.format(ex)) + print('Code download failed [2], aborting!') abort = True time.sleep(1.5) @@ -638,7 +653,7 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f if not self.wakeup_modem(baudrate, port, 100, 1, debug, self.__get_wait_msg(load_fff=load_fff)): print("Timeout while waiting for modem to finish updating!") reconnect_uart() - sys.exit(1) + return False start = time.time() while True: @@ -708,7 +723,7 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f else: print("Invalid response after upgrade... aborting.") reconnect_uart() - sys.exit(1) + return False self.__serial.write(b"AT\r\n") self.__serial.write(b"AT\r\n") @@ -819,7 +834,7 @@ def at_negotiation(self, baudrate, port, max_try, mirror, atneg_only, debug, tar self.__serial = UART(1, baudrate=target_baudrate, pins=self.__pins, timeout_chars=100) else: self.__serial = None - self.__serial = serial.Serial(port, target_baudrate, bytesize=serial.EIGHTBITS, timeout=0.1) + self.__serial = serial.Serial(port, target_baudrate, bytesize=serial.EIGHTBITS, timeout=0.1, rtscts=fc) self.__serial.reset_input_buffer() self.__serial.reset_output_buffer() self.__serial.flush() @@ -882,10 +897,11 @@ def upgrade(self, ffile, mfile=None, baudrate=921600, retry=False, resume=False, if success: if self.__run(file_path=ffile, resume=True if mfile is not None else resume, baudrate=baudrate, direct=False, debug=debug, pkgdebug=pkgdebug, verbose=verbose, load_fff=False if mfile else load_fff, mtools=mtools): if self.__check_br(verbose=verbose, debug=debug): - self.__run(bootrom=True, debug=debug, direct=False, pkgdebug=pkgdebug, verbose=verbose, load_fff=True) + success = self.__run(bootrom=True, debug=debug, direct=False, pkgdebug=pkgdebug, verbose=verbose, load_fff=True) self.success_message(verbose=verbose, debug=debug) else: print('Unable to load updater from {}'.format(mfile)) + return success def upgrade_uart(self, ffh_mode=False, mfile=None, retry=False, resume=False, color=0x050505, debug=False, pkgdebug=False, verbose=False, load_fff=True): success = False @@ -896,7 +912,7 @@ def upgrade_uart(self, ffh_mode=False, mfile=None, retry=False, resume=False, co if not success: print('Firmware does not support LTE.modem_upgrade_mode()!') reconnect_uart() - sys.exit(1) + return False print('Preparing modem for upgrade...') if not retry and ffh_mode: success = False @@ -923,16 +939,16 @@ def upgrade_uart(self, ffh_mode=False, mfile=None, retry=False, resume=False, co else: print('Unable to upgrade bootrom.') - def show_info(self, port=None, debug=False, verbose=False): - self.__run(port=port, debug=debug, info_only=True, verbose=verbose) + def show_info(self, port=None, debug=False, verbose=False, fc=False): + self.__run(port=port, debug=debug, info_only=True, verbose=verbose, fc=fc) - def upgrade_ext(self, port, ffile, mfile, resume=False, debug=False, pkgdebug=False, verbose=False, load_fff=True): + def upgrade_ext(self, port, ffile, mfile, resume=False, debug=False, pkgdebug=False, verbose=False, load_fff=True, fc=False): success = True if mfile is not None: success = False - success = self.__run(file_path=mfile, load_ffh=True, port=port, debug=debug, pkgdebug=pkgdebug, verbose=verbose) + success = self.__run(file_path=mfile, load_ffh=True, port=port, debug=debug, pkgdebug=pkgdebug, verbose=verbose, fc=fc) if success: - if self.__run(file_path=ffile, resume=True if mfile is not None else resume, direct=False, port=port, debug=debug, pkgdebug=pkgdebug, verbose=verbose, load_fff=load_fff): + if self.__run(file_path=ffile, resume=True if mfile is not None else resume, direct=False, port=port, debug=debug, pkgdebug=pkgdebug, verbose=verbose, load_fff=load_fff, fc=fc): self.success_message(port=port, verbose=verbose, debug=debug) else: print('Unable to load updater from {}'.format(mfile)) @@ -941,7 +957,7 @@ def detect_error(): print('Could not detect your modem!') print('Please try to power off your device and restart in safeboot mode.') reconnect_uart() - sys.exit(1) + return False def print_welcome(): print('<<< Welcome to the SQN3330 firmware updater [{}] >>>'.format(VERSION)) @@ -973,6 +989,7 @@ def run(ffile, mfile=None, baudrate=921600, verbose=False, debug=False, load_fff retry = False resume = False mtools = False + success = False sqnup = sqnsupgrade() if sqnup.check_files(ffile, mfile, debug): state = sqnup.detect_modem_state(debug=debug, hangup=hangup) @@ -984,15 +1001,16 @@ def run(ffile, mfile=None, baudrate=921600, verbose=False, debug=False, load_fff if mfile is None: print('Your modem is in recovery mode. Please specify updater.elf file') reconnect_uart() - sys.exit(1) + return False elif state == 4: resume = True elif state == 1: mtools = True elif state == -1: detect_error() - sqnup.upgrade(ffile=ffile, mfile=mfile, baudrate=baudrate, retry=retry, resume=resume, debug=debug, pkgdebug=False, verbose=verbose, load_fff=load_fff, mtools=mtools) + success = sqnup.upgrade(ffile=ffile, mfile=mfile, baudrate=baudrate, retry=retry, resume=resume, debug=debug, pkgdebug=False, verbose=verbose, load_fff=load_fff, mtools=mtools) reconnect_uart() + return success def uart(ffh_mode=False, mfile=None, color=0x050505, verbose=False, debug=False, hangup=True): print_welcome() @@ -1054,12 +1072,12 @@ def state(verbose=False, debug=False, retry=5, hangup=False): return sqnup.detect_modem_state(debug=debug, hangup=hangup, retry=retry) else: - def run(port, ffile, mfile=None, resume=False, debug=False, verbose=False, load_fff=True): + def run(port, ffile, mfile=None, resume=False, debug=False, verbose=False, load_fff=True, fc=False): print_welcome() sqnup = sqnsupgrade() if sqnup.check_files(ffile, mfile, debug): sqnup.upgrade_ext(port=port, ffile=ffile, mfile=mfile, resume=resume, debug=debug, pkgdebug=False, verbose=verbose, load_fff=load_fff) - def version(port, verbose=False, debug=False): + def version(port, verbose=False, debug=False, fc=False): sqnup = sqnsupgrade() sqnup.show_info(port=port, debug=debug, verbose=verbose) From 14f60f90955ab3a9305219f278d320d719cbc0f2 Mon Sep 17 00:00:00 2001 From: iwahdan88 Date: Wed, 25 Sep 2019 21:51:11 +0200 Subject: [PATCH 04/12] Fix crash caused by Lora intr firing before handler is registered by Lora init. --- esp32/mods/machpin.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/esp32/mods/machpin.c b/esp32/mods/machpin.c index 1b595378a5..7cb3bdb837 100644 --- a/esp32/mods/machpin.c +++ b/esp32/mods/machpin.c @@ -332,7 +332,10 @@ STATIC IRAM_ATTR void machpin_intr_process (void* arg) { #ifdef MICROPY_LPWAN_DIO_PIN // fast path for the LPWAN DIO interrupt if (gpio_intr_status & (1 << micropy_lpwan_dio_pin_num)) { - ((void(*)(void))((pin_obj_t *)micropy_lpwan_dio_pin)->handler)(); + if(((pin_obj_t *)micropy_lpwan_dio_pin)->handler != NULL) + { + ((void(*)(void))((pin_obj_t *)micropy_lpwan_dio_pin)->handler)(); + } // clear this bit from the interrupt status gpio_intr_status &= ~(1 << micropy_lpwan_dio_pin_num); From 62c6bbbd218e9aabac167e520cf43f58e134b42c Mon Sep 17 00:00:00 2001 From: iwahdan88 Date: Tue, 3 Sep 2019 21:09:39 +0200 Subject: [PATCH 05/12] [PYFW-358] Added modem URC handling and callback events for LTE class # Conflicts: # esp32/lte/lteppp.c --- esp32/lte/lteppp.c | 64 +++++++++++++++++++++++++++++++++++++++++---- esp32/main.c | 1 + esp32/mods/modlte.h | 14 ++++++++++ 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/esp32/lte/lteppp.c b/esp32/lte/lteppp.c index db3408ba83..82b0207906 100644 --- a/esp32/lte/lteppp.c +++ b/esp32/lte/lteppp.c @@ -49,6 +49,7 @@ typedef enum DECLARE EXPORTED DATA ******************************************************************************/ extern TaskHandle_t xLTETaskHndl; +extern TaskHandle_t xLTEUartEvtTaskHndl; SemaphoreHandle_t xLTE_modem_Conn_Sem; /****************************************************************************** DECLARE PRIVATE DATA @@ -78,11 +79,16 @@ static bool ltepp_ppp_conn_up = false; static ltepppconnstatus_t lteppp_connstatus = LTE_PPP_IDLE; +static QueueHandle_t uart0_queue; + +static bool lte_uart_break_evt = false; + /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ static void TASK_LTE (void *pvParameters); -static bool lteppp_send_at_cmd_exp(const char *cmd, uint32_t timeout, const char *expected_rsp, void* data_rem); +static void TASK_UART_EVT (void *pvParameters); +static bool lteppp_send_at_cmd_exp(const char *cmd, uint32_t timeout, const char *expected_rsp, void* data_rem, size_t len); static bool lteppp_send_at_cmd(const char *cmd, uint32_t timeout); static bool lteppp_check_sim_present(void); static void lteppp_status_cb (ppp_pcb *pcb, int err_code, void *ctx); @@ -113,7 +119,7 @@ void connect_lte_uart (void) { vTaskDelay(5 / portTICK_RATE_MS); // install the UART driver - uart_driver_install(LTE_UART_ID, LTE_UART_BUFFER_SIZE, LTE_UART_BUFFER_SIZE, 0, NULL, 0, NULL); + uart_driver_install(LTE_UART_ID, LTE_UART_BUFFER_SIZE, LTE_UART_BUFFER_SIZE, 1, &uart0_queue, 0, NULL); lteppp_uart_reg = &UART2; // disable the delay between transfers @@ -125,6 +131,7 @@ void connect_lte_uart (void) { uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_DISABLE, 0); uart_set_rts(LTE_UART_ID, false); + xTaskCreatePinnedToCore(TASK_UART_EVT, "LTE_UART_EVT", 2048 / sizeof(StackType_t), NULL, 12, &xLTEUartEvtTaskHndl, 1); } @@ -491,7 +498,7 @@ static void TASK_LTE (void *pvParameters) { lteppp_modem_conn_state = E_LTE_MODEM_CONNECTED; xSemaphoreGive(xLTESem); xSemaphoreGive(xLTE_modem_Conn_Sem); - + lte_state_t state; for (;;) { vTaskDelay(LTE_TASK_PERIOD_MS); xSemaphoreTake(xLTESem, portMAX_DELAY); @@ -502,11 +509,18 @@ static void TASK_LTE (void *pvParameters) { goto modem_init; } xSemaphoreGive(xLTESem); + state = lteppp_get_state(); if (xQueueReceive(xCmdQueue, lteppp_trx_buffer, 0)) { lteppp_send_at_cmd_exp(lte_task_cmd->data, lte_task_cmd->timeout, NULL, &(lte_task_rsp->data_remaining)); xQueueSend(xRxQueue, (void *)lte_task_rsp, (TickType_t)portMAX_DELAY); - } else { - lte_state_t state = lteppp_get_state(); + } + else if(state == E_LTE_PPP && lte_uart_break_evt) + { + lteppp_send_at_cmd("+++", LTE_PPP_BACK_OFF_TIME_MS); + lteppp_suspend(); + } + else + { if (state == E_LTE_PPP) { uint32_t rx_len; // check for IP connection @@ -543,6 +557,46 @@ static void TASK_LTE (void *pvParameters) { goto modem_init; } +static void TASK_UART_EVT (void *pvParameters) +{ + uart_event_t event; + uint8_t buff[50] = {0}; + for(;;) { + //Waiting for UART event. + if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { + + switch(event.type) + { + case UART_DATA: + if (lte_uart_break_evt) { + + uint32_t rx_len = uart_read_bytes(LTE_UART_ID, buff, LTE_UART_BUFFER_SIZE, + LTE_TRX_WAIT_MS(LTE_UART_BUFFER_SIZE) / portTICK_RATE_MS); + + if ((rx_len) && (strstr((const char *)buff, "OK") != NULL)) + { + if(strstr((const char *)buff, "+CEREG: 4") != NULL) + { + modlte_urc_events(LTE_EVENT_COVERAGE_LOST); + } + + lte_uart_break_evt = false; + } + } + break; + case UART_BREAK: + if (E_LTE_PPP == lteppp_get_state()) { + lte_uart_break_evt = true; + } + break; + default: + break; + } + } + } + vTaskDelete(NULL); +} + static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const char *expected_rsp, void* data_rem) { diff --git a/esp32/main.c b/esp32/main.c index 72326ae27b..63cd3763a5 100644 --- a/esp32/main.c +++ b/esp32/main.c @@ -64,6 +64,7 @@ TaskHandle_t xSigfoxTaskHndl; #endif #if defined(GPY) || defined (FIPY) TaskHandle_t xLTETaskHndl; +TaskHandle_t xLTEUartEvtTaskHndl; TaskHandle_t xLTEUpgradeTaskHndl; #endif diff --git a/esp32/mods/modlte.h b/esp32/mods/modlte.h index 494445613e..0d6c0677da 100644 --- a/esp32/mods/modlte.h +++ b/esp32/mods/modlte.h @@ -16,6 +16,9 @@ #define LTE_MAX_RX_SIZE 1024 +#define LTE_TRIGGER_NONE 0x00000000 +#define LTE_TRIGGER_SIG_LOST 0x00000001 + typedef struct _lte_obj_t { mp_obj_base_t base; uint32_t ip; @@ -23,13 +26,24 @@ typedef struct _lte_obj_t { uint8_t cid; bool init; bool carrier; + uint32_t trigger; + int32_t events; + mp_obj_t handler; + mp_obj_t handler_arg; } lte_obj_t; +typedef enum +{ + LTE_EVENT_COVERAGE_LOST = 0, + LTE_EVENT_MAX +}lte_events_t; + /****************************************************************************** DECLARE PUBLIC FUNCTIONS ******************************************************************************/ extern void modlte_init0(void); extern void modlte_start_modem(void); +extern void modlte_urc_events(lte_events_t events); #endif /* MODLTE_H_ */ \ No newline at end of file From c558e3d391d5d3f74b3d20d190a37007f4e25ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9za=20Husi?= Date: Wed, 4 Sep 2019 20:43:21 +0200 Subject: [PATCH 06/12] PYFW-360: Crash when Pybytes library retrying Activating device (#54) # Conflicts: # esp32/mods/modusocket.c --- esp32/mods/modusocket.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esp32/mods/modusocket.c b/esp32/mods/modusocket.c index 09a90eff72..4adf1b38ba 100644 --- a/esp32/mods/modusocket.c +++ b/esp32/mods/modusocket.c @@ -716,6 +716,9 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC")); } + //getaddrinfo() allocates memory, needs to be freed + freeaddrinfo(res); + } STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo); From e6f53912143d16da31d30cdf7387e1fe34acf674 Mon Sep 17 00:00:00 2001 From: iwahdan88 Date: Mon, 9 Sep 2019 00:00:31 +0200 Subject: [PATCH 07/12] [PYFW-358] Enabled URC break signal # Conflicts: # esp32/tools/makepkg.sh --- esp32/lte/lteppp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/esp32/lte/lteppp.c b/esp32/lte/lteppp.c index 82b0207906..9391b4eae1 100644 --- a/esp32/lte/lteppp.c +++ b/esp32/lte/lteppp.c @@ -493,7 +493,12 @@ static void TASK_LTE (void *pvParameters) { // enable airplane low power mode lteppp_send_at_cmd("AT!=\"setlpm airplane=1 enable=1\"", LTE_RX_TIMEOUT_MAX_MS); - + // enable Break Signal for URC on UART0 + lteppp_send_at_cmd("AT+SQNIBRCFG?", LTE_RX_TIMEOUT_MAX_MS); + if(strstr(lteppp_trx_buffer, "+SQNIBRCFG: 1,100")) + { + lteppp_send_at_cmd("AT+SQNIBRCFG=1,100", LTE_RX_TIMEOUT_MAX_MS); + } xSemaphoreTake(xLTESem, portMAX_DELAY); lteppp_modem_conn_state = E_LTE_MODEM_CONNECTED; xSemaphoreGive(xLTESem); From 193d9ab9f9a92d21c29367cd019c7f6d860b2169 Mon Sep 17 00:00:00 2001 From: iwahdan88 Date: Sun, 22 Sep 2019 00:00:22 +0200 Subject: [PATCH 08/12] Update lteppp to fix UART src CLK flag initialization --- esp32/lte/lteppp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/esp32/lte/lteppp.c b/esp32/lte/lteppp.c index 9391b4eae1..c32cb63370 100644 --- a/esp32/lte/lteppp.c +++ b/esp32/lte/lteppp.c @@ -108,6 +108,7 @@ void connect_lte_uart (void) { config.stop_bits = UART_STOP_BITS_1; config.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS; config.rx_flow_ctrl_thresh = 64; + config.use_ref_tick = false; uart_param_config(LTE_UART_ID, &config); // configure the UART pins @@ -118,6 +119,8 @@ void connect_lte_uart (void) { vTaskDelay(5 / portTICK_RATE_MS); + uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_DISABLE, 0); + // install the UART driver uart_driver_install(LTE_UART_ID, LTE_UART_BUFFER_SIZE, LTE_UART_BUFFER_SIZE, 1, &uart0_queue, 0, NULL); lteppp_uart_reg = &UART2; @@ -128,7 +131,6 @@ void connect_lte_uart (void) { // configure the rx timeout threshold lteppp_uart_reg->conf1.rx_tout_thrhd = 20 & UART_RX_TOUT_THRHD_V; - uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_DISABLE, 0); uart_set_rts(LTE_UART_ID, false); xTaskCreatePinnedToCore(TASK_UART_EVT, "LTE_UART_EVT", 2048 / sizeof(StackType_t), NULL, 12, &xLTEUartEvtTaskHndl, 1); @@ -406,8 +408,9 @@ static void TASK_LTE (void *pvParameters) { xSemaphoreTake(xLTESem, portMAX_DELAY); lteppp_modem_conn_state = E_LTE_MODEM_CONNECTING; xSemaphoreGive(xLTESem); - uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_CTS_RTS, 64); + uart_set_rts(LTE_UART_ID, true); vTaskDelay(500/portTICK_PERIOD_MS); + uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_CTS_RTS, 64); // exit PPP session if applicable if(lteppp_send_at_cmd("+++", LTE_PPP_BACK_OFF_TIME_MS)) { @@ -495,7 +498,7 @@ static void TASK_LTE (void *pvParameters) { lteppp_send_at_cmd("AT!=\"setlpm airplane=1 enable=1\"", LTE_RX_TIMEOUT_MAX_MS); // enable Break Signal for URC on UART0 lteppp_send_at_cmd("AT+SQNIBRCFG?", LTE_RX_TIMEOUT_MAX_MS); - if(strstr(lteppp_trx_buffer, "+SQNIBRCFG: 1,100")) + if(!strstr(lteppp_trx_buffer, "+SQNIBRCFG: 1,100")) { lteppp_send_at_cmd("AT+SQNIBRCFG=1,100", LTE_RX_TIMEOUT_MAX_MS); } From bf89c1e02e974b2e4f7fb673fe915f2ac63dc687 Mon Sep 17 00:00:00 2001 From: iwahdan88 Date: Mon, 22 Jul 2019 15:16:25 +0200 Subject: [PATCH 09/12] [PYFW-356] Update AT command apending with only '\r' --- esp32/lte/lteppp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp32/lte/lteppp.c b/esp32/lte/lteppp.c index c32cb63370..b26f512aa3 100644 --- a/esp32/lte/lteppp.c +++ b/esp32/lte/lteppp.c @@ -652,7 +652,7 @@ static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const cha // then send the command uart_write_bytes(LTE_UART_ID, cmd, cmd_len); if (strcmp(cmd, "+++")) { - uart_write_bytes(LTE_UART_ID, "\r\n", 2); + uart_write_bytes(LTE_UART_ID, "\r", 1); } uart_wait_tx_done(LTE_UART_ID, LTE_TRX_WAIT_MS(cmd_len) / portTICK_RATE_MS); vTaskDelay(2 / portTICK_RATE_MS); From 4a9bca034959758d64ce1455ef6c3a29b66fd42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9za=20Husi?= Date: Wed, 31 Jul 2019 15:18:22 +0200 Subject: [PATCH 10/12] PYFW-353: Socket timeout in recv operation is not working in case of ssl socket (#48) --- esp32/mods/lwipsocket.c | 54 +++++++++++++++++++++++++---------------- esp32/mods/modusocket.c | 6 +++-- esp32/mods/modussl.c | 2 -- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/esp32/mods/lwipsocket.c b/esp32/mods/lwipsocket.c index 2a3d7ceff2..ae3226620d 100644 --- a/esp32/mods/lwipsocket.c +++ b/esp32/mods/lwipsocket.c @@ -212,7 +212,11 @@ int lwipsocket_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len ret = 0; break; } - // blocking do nothing + // blocking and timed out, return with error + // mbedtls_net_recv_timeout() returned with timeout + else { + break; + } } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { // printf("Close notify received\n"); @@ -279,33 +283,41 @@ int lwipsocket_socket_setsockopt(mod_network_socket_obj_t *s, mp_uint_t level, m int lwipsocket_socket_settimeout(mod_network_socket_obj_t *s, mp_int_t timeout_ms, int *_errno) { int ret; - uint32_t option = lwip_fcntl_r(s->sock_base.u.sd, F_GETFL, 0); - if (timeout_ms <= 0) { - if (timeout_ms == 0) { - // set non-blocking mode - option |= O_NONBLOCK; + if (s->sock_base.is_ssl) { + mp_obj_ssl_socket_t *ss = (mp_obj_ssl_socket_t *)s; + // mbedtls_net_recv_timeout() API is registered with mbedtls_ssl_set_bio() so setting timeout on receive works + mbedtls_ssl_conf_read_timeout(&ss->conf, timeout_ms); + } + else { + uint32_t option = lwip_fcntl_r(s->sock_base.u.sd, F_GETFL, 0); + + if (timeout_ms <= 0) { + if (timeout_ms == 0) { + // set non-blocking mode + option |= O_NONBLOCK; + } else { + // set blocking mode + option &= ~O_NONBLOCK; + timeout_ms = UINT32_MAX; + } } else { // set blocking mode option &= ~O_NONBLOCK; - timeout_ms = UINT32_MAX; } - } else { - // set blocking mode - option &= ~O_NONBLOCK; - } - // set the timeout - struct timeval tv; - tv.tv_sec = timeout_ms / 1000; // seconds - tv.tv_usec = (timeout_ms % 1000) * 1000; // microseconds - ret = lwip_setsockopt_r(s->sock_base.u.sd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); - ret |= lwip_setsockopt_r(s->sock_base.u.sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - ret |= lwip_fcntl_r(s->sock_base.u.sd, F_SETFL, option); + // set the timeout + struct timeval tv; + tv.tv_sec = timeout_ms / 1000; // seconds + tv.tv_usec = (timeout_ms % 1000) * 1000; // microseconds + ret = lwip_setsockopt_r(s->sock_base.u.sd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + ret |= lwip_setsockopt_r(s->sock_base.u.sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + ret |= lwip_fcntl_r(s->sock_base.u.sd, F_SETFL, option); - if (ret != 0) { - *_errno = errno; - return -1; + if (ret != 0) { + *_errno = errno; + return -1; + } } s->sock_base.timeout = timeout_ms; diff --git a/esp32/mods/modusocket.c b/esp32/mods/modusocket.c index 4adf1b38ba..6409095e79 100644 --- a/esp32/mods/modusocket.c +++ b/esp32/mods/modusocket.c @@ -62,6 +62,8 @@ #include "lwip/dns.h" #include "lwip/netdb.h" +#include "mbedtls/ssl.h" + #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -376,7 +378,7 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { mp_int_t ret = self->sock_base.nic_type->n_recv(self, (byte*)vstr.buf, len, &_errno); MP_THREAD_GIL_ENTER(); if (ret < 0) { - if (_errno == MP_EAGAIN) { + if (_errno == MP_EAGAIN || _errno == MBEDTLS_ERR_SSL_TIMEOUT ) { if (self->sock_base.timeout > 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out")); } else { @@ -434,7 +436,7 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { mp_int_t ret = self->sock_base.nic_type->n_recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno); MP_THREAD_GIL_ENTER(); if (ret < 0) { - if (_errno == MP_EAGAIN && self->sock_base.timeout > 0) { + if ((_errno == MP_EAGAIN || _errno == MBEDTLS_ERR_SSL_TIMEOUT ) && self->sock_base.timeout > 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out")); } nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno))); diff --git a/esp32/mods/modussl.c b/esp32/mods/modussl.c index 304da6b2ba..4e4d4db697 100644 --- a/esp32/mods/modussl.c +++ b/esp32/mods/modussl.c @@ -144,8 +144,6 @@ static int32_t mod_ssl_setup_socket (mp_obj_ssl_socket_t *ssl_sock, const char * } } - mbedtls_ssl_conf_read_timeout(&ssl_sock->conf, 1000); - ssl_sock->context_fd.fd = ssl_sock->sock_base.u.sd; ssl_sock->sock_base.is_ssl = true; From 5f6d7b2a7a61438d17e59ce22b4d26b14e37926c Mon Sep 17 00:00:00 2001 From: iwahdan88 Date: Thu, 8 Aug 2019 18:17:37 +0200 Subject: [PATCH 11/12] [PYFW-356] support for sending bytes in lte.send_at_cmd() #close # Conflicts: # esp32/lte/lteppp.c # esp32/mods/modlte.c --- esp32/lte/lteppp.c | 14 ++++---------- esp32/lte/lteppp.h | 3 +-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/esp32/lte/lteppp.c b/esp32/lte/lteppp.c index b26f512aa3..6369046736 100644 --- a/esp32/lte/lteppp.c +++ b/esp32/lte/lteppp.c @@ -223,12 +223,6 @@ void lteppp_send_at_command (lte_task_cmd_data_t *cmd, lte_task_rsp_data_t *rsp) xQueueReceive(xRxQueue, rsp, (TickType_t)portMAX_DELAY); } -void lteppp_send_at_command_delay (lte_task_cmd_data_t *cmd, lte_task_rsp_data_t *rsp, TickType_t delay) { - xQueueSend(xCmdQueue, (void *)cmd, (TickType_t)portMAX_DELAY); - vTaskDelay(delay); - xQueueReceive(xRxQueue, rsp, (TickType_t)portMAX_DELAY); -} - bool lteppp_wait_at_rsp (const char *expected_rsp, uint32_t timeout, bool from_mp, void* data_rem) { uint32_t rx_len = 0; @@ -519,7 +513,7 @@ static void TASK_LTE (void *pvParameters) { xSemaphoreGive(xLTESem); state = lteppp_get_state(); if (xQueueReceive(xCmdQueue, lteppp_trx_buffer, 0)) { - lteppp_send_at_cmd_exp(lte_task_cmd->data, lte_task_cmd->timeout, NULL, &(lte_task_rsp->data_remaining)); + lteppp_send_at_cmd_exp(lte_task_cmd->data, lte_task_cmd->timeout, NULL, &(lte_task_rsp->data_remaining), lte_task_cmd->dataLen); xQueueSend(xRxQueue, (void *)lte_task_rsp, (TickType_t)portMAX_DELAY); } else if(state == E_LTE_PPP && lte_uart_break_evt) @@ -606,7 +600,7 @@ static void TASK_UART_EVT (void *pvParameters) } -static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const char *expected_rsp, void* data_rem) { +static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const char *expected_rsp, void* data_rem, size_t len) { if(strstr(cmd, "Pycom_Dummy") != NULL) { @@ -628,7 +622,7 @@ static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const cha } else { - uint32_t cmd_len = strlen(cmd); + size_t cmd_len = len; // char tmp_buf[128]; #ifdef LTE_DEBUG_BUFF if (lteppp_log.ptr < (LTE_LOG_BUFF_SIZE - strlen("[CMD]:") - cmd_len + 1)) @@ -662,7 +656,7 @@ static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const cha } static bool lteppp_send_at_cmd(const char *cmd, uint32_t timeout) { - return lteppp_send_at_cmd_exp (cmd, timeout, LTE_OK_RSP, NULL); + return lteppp_send_at_cmd_exp (cmd, timeout, LTE_OK_RSP, NULL, strlen(cmd) ); } static bool lteppp_check_sim_present(void) { diff --git a/esp32/lte/lteppp.h b/esp32/lte/lteppp.h index b0716ee5a3..268c7f44b4 100644 --- a/esp32/lte/lteppp.h +++ b/esp32/lte/lteppp.h @@ -72,6 +72,7 @@ typedef struct { typedef struct { uint32_t timeout; char data[LTE_AT_CMD_SIZE_MAX - 4]; + size_t dataLen; } lte_task_cmd_data_t; #pragma pack(1) typedef struct { @@ -111,8 +112,6 @@ extern void lteppp_deinit (void); extern void lteppp_send_at_command (lte_task_cmd_data_t *cmd, lte_task_rsp_data_t *rsp); -extern void lteppp_send_at_command_delay (lte_task_cmd_data_t *cmd, lte_task_rsp_data_t *rsp, TickType_t delay); - extern bool lteppp_wait_at_rsp (const char *expected_rsp, uint32_t timeout, bool from_mp, void* data_rem); lte_modem_conn_state_t lteppp_modem_state(void); From 45f0d8ea6167d72a9daec1df9baa3590ef9ce7b6 Mon Sep 17 00:00:00 2001 From: iwahdan88 Date: Fri, 8 Nov 2019 09:35:31 +0100 Subject: [PATCH 12/12] minor update to getadrinfo --- esp32/mods/modusocket.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/esp32/mods/modusocket.c b/esp32/mods/modusocket.c index 6409095e79..8fd4050467 100644 --- a/esp32/mods/modusocket.c +++ b/esp32/mods/modusocket.c @@ -718,9 +718,6 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC")); } - //getaddrinfo() allocates memory, needs to be freed - freeaddrinfo(res); - } STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo);