From 9384d0da111bb23d01170ed8aa8bf4c69c0aa7b7 Mon Sep 17 00:00:00 2001 From: Nikos Ftylitakis Date: Mon, 6 Apr 2020 13:49:35 +0300 Subject: [PATCH 1/3] Adding support for AT commands that are longer than 124 bytes. --- esp32/lte/lteppp.c | 37 ++++++++++++++++++++++++------------- esp32/lte/lteppp.h | 4 +++- esp32/mods/modlte.c | 44 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 66 insertions(+), 19 deletions(-) diff --git a/esp32/lte/lteppp.c b/esp32/lte/lteppp.c index 43c46904a5..4230edd020 100644 --- a/esp32/lte/lteppp.c +++ b/esp32/lte/lteppp.c @@ -92,7 +92,7 @@ static bool lte_uart_break_evt = false; ******************************************************************************/ static void TASK_LTE (void *pvParameters); 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_exp(const char *cmd, uint32_t timeout, const char *expected_rsp, void* data_rem, size_t len, bool expect_continuation); 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); @@ -233,7 +233,9 @@ void lteppp_disconnect(void) { void lteppp_send_at_command (lte_task_cmd_data_t *cmd, lte_task_rsp_data_t *rsp) { xQueueSend(xCmdQueue, (void *)cmd, (TickType_t)portMAX_DELAY); - xQueueReceive(xRxQueue, rsp, (TickType_t)portMAX_DELAY); + + if(!cmd->expect_continuation) + 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) { @@ -526,8 +528,9 @@ 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), lte_task_cmd->dataLen); - xQueueSend(xRxQueue, (void *)lte_task_rsp, (TickType_t)portMAX_DELAY); + lteppp_send_at_cmd_exp(lte_task_cmd->data, lte_task_cmd->timeout, NULL, &(lte_task_rsp->data_remaining), lte_task_cmd->dataLen, lte_task_cmd->expect_continuation); + if(!lte_task_cmd->expect_continuation) + xQueueSend(xRxQueue, (void *)lte_task_rsp, (TickType_t)portMAX_DELAY); } else if(state == E_LTE_PPP && lte_uart_break_evt) { @@ -613,7 +616,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, size_t len) { +static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const char *expected_rsp, void* data_rem, size_t len, bool expect_continuation) { if(strstr(cmd, "Pycom_Dummy") != NULL) { @@ -654,22 +657,30 @@ static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const cha } #endif // flush the rx buffer first - uart_flush(LTE_UART_ID); + if(!expect_continuation || + (len >= 2 && cmd[0] == 'A' && cmd[1] == 'T')) // starts with AT + uart_flush(LTE_UART_ID); // uart_read_bytes(LTE_UART_ID, (uint8_t *)tmp_buf, sizeof(tmp_buf), 5 / portTICK_RATE_MS); // then send the command uart_write_bytes(LTE_UART_ID, cmd, cmd_len); - if (strcmp(cmd, "+++")) { - 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); - return lteppp_wait_at_rsp(expected_rsp, timeout, false, data_rem); + if(expect_continuation) + return true; + else { + if (strcmp(cmd, "+++")) { + 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); + + return lteppp_wait_at_rsp(expected_rsp, timeout, false, data_rem); + } } } static bool lteppp_send_at_cmd(const char *cmd, uint32_t timeout) { - return lteppp_send_at_cmd_exp (cmd, timeout, LTE_OK_RSP, NULL, strlen(cmd) ); + return lteppp_send_at_cmd_exp (cmd, timeout, LTE_OK_RSP, NULL, strlen(cmd), false); } static bool lteppp_check_sim_present(void) { diff --git a/esp32/lte/lteppp.h b/esp32/lte/lteppp.h index ace8c2c3de..c8e608dee3 100644 --- a/esp32/lte/lteppp.h +++ b/esp32/lte/lteppp.h @@ -19,6 +19,7 @@ #define LTE_CMD_QUEUE_SIZE_MAX (1) #define LTE_RSP_QUEUE_SIZE_MAX (1) #define LTE_AT_CMD_SIZE_MAX (128) +#define LTE_AT_CMD_DATA_SIZE_MAX (LTE_AT_CMD_SIZE_MAX - 4) #define LTE_AT_RSP_SIZE_MAX (LTE_UART_BUFFER_SIZE) #define LTE_OK_RSP "OK" @@ -71,8 +72,9 @@ typedef struct { #endif typedef struct { uint32_t timeout; - char data[LTE_AT_CMD_SIZE_MAX - 4]; + char data[LTE_AT_CMD_DATA_SIZE_MAX]; size_t dataLen; + bool expect_continuation; } lte_task_cmd_data_t; #pragma pack(1) typedef struct { diff --git a/esp32/mods/modlte.c b/esp32/mods/modlte.c index b3b39d7629..4ba1c8c70d 100644 --- a/esp32/mods/modlte.c +++ b/esp32/mods/modlte.c @@ -136,6 +136,7 @@ extern TaskHandle_t xLTETaskHndl; /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ +static bool lte_push_at_command_ext_cont (char *cmd_str, uint32_t timeout, const char *expected_rsp, size_t len, bool continuation); 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); @@ -192,14 +193,15 @@ static void lte_callback_handler(void* arg) } } -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}; +static bool lte_push_at_command_ext_cont (char *cmd_str, uint32_t timeout, const char *expected_rsp, size_t len, bool continuation) +{ + lte_task_cmd_data_t cmd = { .timeout = timeout, .dataLen = len, .expect_continuation = continuation}; memcpy(cmd.data, cmd_str, len); uint32_t start = mp_hal_ticks_ms(); if (lte_debug) printf("[AT] %u %s\n", start, cmd_str); lteppp_send_at_command(&cmd, &modlte_rsp); - if ((expected_rsp == NULL) || (strstr(modlte_rsp.data, expected_rsp) != NULL)) { + if (continuation || (expected_rsp == NULL) || (strstr(modlte_rsp.data, expected_rsp) != NULL)) { if (lte_debug) printf("[AT-OK] +%u %s\n", mp_hal_ticks_ms()-start, modlte_rsp.data); return true; @@ -209,6 +211,10 @@ static bool lte_push_at_command_ext(char *cmd_str, uint32_t timeout, const char return false; } +static bool lte_push_at_command_ext(char *cmd_str, uint32_t timeout, const char *expected_rsp, size_t len) { + return lte_push_at_command_ext_cont(cmd_str, timeout, expected_rsp, len, false); +} + static bool lte_push_at_command (char *cmd_str, uint32_t timeout) { return lte_push_at_command_ext(cmd_str, timeout, LTE_OK_RSP, strlen(cmd_str)); } @@ -1229,18 +1235,46 @@ STATIC mp_obj_t lte_send_at_cmd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_m lte_check_init(); lte_check_inppp(); STATIC const mp_arg_t allowed_args[] = { - { MP_QSTR_cmd, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_cmd, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_delay, MP_ARG_INT, {.u_int = 10000} } }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + uint32_t argLength = 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); if (args[0].u_obj == mp_const_none) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "the command must be specified!")); } + uint32_t timeout = LTE_RX_TIMEOUT_MAX_MS; 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); + char* command = (char *)(mp_obj_str_get_data(args[0].u_obj, &len)); + + if(argLength > 1) { + timeout = args[1].u_int; + } + + if(len <= LTE_AT_CMD_DATA_SIZE_MAX) + lte_push_at_command_ext_cont(command, timeout, NULL, len, false); + else { + size_t chunk_count = len / LTE_AT_CMD_DATA_SIZE_MAX; + size_t remaining_bytes = len % LTE_AT_CMD_DATA_SIZE_MAX; + + bool expect_continuation = false; + char* chunk_start = command; + for(size_t i=0; i Date: Mon, 13 Apr 2020 12:27:31 +0300 Subject: [PATCH 2/3] Fix bug when deciding if task response will be send in xRxQueue based on expect_continuation flag. --- esp32/lte/lteppp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esp32/lte/lteppp.c b/esp32/lte/lteppp.c index 4230edd020..c4b2681ff1 100644 --- a/esp32/lte/lteppp.c +++ b/esp32/lte/lteppp.c @@ -528,8 +528,9 @@ static void TASK_LTE (void *pvParameters) { xSemaphoreGive(xLTESem); state = lteppp_get_state(); if (xQueueReceive(xCmdQueue, lteppp_trx_buffer, 0)) { + bool expect_continuation = lte_task_cmd->expect_continuation; lteppp_send_at_cmd_exp(lte_task_cmd->data, lte_task_cmd->timeout, NULL, &(lte_task_rsp->data_remaining), lte_task_cmd->dataLen, lte_task_cmd->expect_continuation); - if(!lte_task_cmd->expect_continuation) + if(!expect_continuation) xQueueSend(xRxQueue, (void *)lte_task_rsp, (TickType_t)portMAX_DELAY); } else if(state == E_LTE_PPP && lte_uart_break_evt) From 12b7177229d577c1c835b8571a25b4008a5b024c Mon Sep 17 00:00:00 2001 From: Nikos Ftylitakis Date: Thu, 16 Jul 2020 11:13:20 +0300 Subject: [PATCH 3/3] Fixed changes recommended by @peter-pycom --- esp32/lte/lteppp.c | 10 +++++++--- esp32/mods/modlte.c | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/esp32/lte/lteppp.c b/esp32/lte/lteppp.c index c4b2681ff1..a774d25c08 100644 --- a/esp32/lte/lteppp.c +++ b/esp32/lte/lteppp.c @@ -658,17 +658,21 @@ static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const cha } #endif // flush the rx buffer first - if(!expect_continuation || - (len >= 2 && cmd[0] == 'A' && cmd[1] == 'T')) // starts with AT + if(!expect_continuation || (len >= 2 && cmd[0] == 'A' && cmd[1] == 'T')) // starts with AT + { uart_flush(LTE_UART_ID); + } // uart_read_bytes(LTE_UART_ID, (uint8_t *)tmp_buf, sizeof(tmp_buf), 5 / portTICK_RATE_MS); // then send the command uart_write_bytes(LTE_UART_ID, cmd, cmd_len); if(expect_continuation) + { return true; + } else { - if (strcmp(cmd, "+++")) { + if (strcmp(cmd, "+++")) + { uart_write_bytes(LTE_UART_ID, "\r", 1); } diff --git a/esp32/mods/modlte.c b/esp32/mods/modlte.c index 4ba1c8c70d..a52cfc0ced 100644 --- a/esp32/mods/modlte.c +++ b/esp32/mods/modlte.c @@ -1236,11 +1236,11 @@ 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_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_delay, MP_ARG_INT, {.u_int = 10000} } + { MP_QSTR_delay, MP_ARG_INT, {.u_int = LTE_RX_TIMEOUT_MAX_MS} } }; // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; uint32_t argLength = MP_ARRAY_SIZE(allowed_args); + mp_arg_val_t args[argLength]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); if (args[0].u_obj == mp_const_none) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "the command must be specified!"));