Skip to content
This repository has been archived by the owner on Sep 16, 2024. It is now read-only.

Adding support for AT commands that are longer than 124 bytes. #429

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 28 additions & 12 deletions esp32/lte/lteppp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -526,8 +528,10 @@ 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);
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(!expect_continuation)
xQueueSend(xRxQueue, (void *)lte_task_rsp, (TickType_t)portMAX_DELAY);
}
else if(state == E_LTE_PPP && lte_uart_break_evt)
{
Expand Down Expand Up @@ -613,7 +617,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)
{
Expand Down Expand Up @@ -654,22 +658,34 @@ 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);
ftylitak marked this conversation as resolved.
Show resolved Hide resolved
}
// 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);

if(expect_continuation)
{
return true;
}
uart_wait_tx_done(LTE_UART_ID, LTE_TRX_WAIT_MS(cmd_len) / portTICK_RATE_MS);
vTaskDelay(2 / portTICK_RATE_MS);
else {
if (strcmp(cmd, "+++"))
{
uart_write_bytes(LTE_UART_ID, "\r", 1);
}

return lteppp_wait_at_rsp(expected_rsp, timeout, false, data_rem);
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) {
Expand Down
4 changes: 3 additions & 1 deletion esp32/lte/lteppp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down
46 changes: 40 additions & 6 deletions esp32/mods/modlte.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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));
}
Expand Down Expand Up @@ -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 = 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);
ftylitak marked this conversation as resolved.
Show resolved Hide resolved
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!"));
}
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<chunk_count; ++i) {
expect_continuation = (i < (chunk_count - 1)) || remaining_bytes;

lte_push_at_command_ext_cont(chunk_start, timeout, NULL, LTE_AT_CMD_DATA_SIZE_MAX, expect_continuation);

chunk_start += LTE_AT_CMD_DATA_SIZE_MAX;
}

if(remaining_bytes) {
lte_push_at_command_ext_cont(chunk_start, timeout, NULL, remaining_bytes, false);
}
}
}
else
{
Expand Down