diff --git a/esp_modem/include/esp_modem_recov_helper.h b/esp_modem/include/esp_modem_recov_helper.h index ec8c95388..b7bdccd8c 100644 --- a/esp_modem/include/esp_modem_recov_helper.h +++ b/esp_modem/include/esp_modem_recov_helper.h @@ -85,5 +85,3 @@ esp_modem_recov_resend_t *esp_modem_recov_resend_new(esp_modem_dce_t *dce, dce_c * */ esp_modem_recov_gpio_t *esp_modem_recov_gpio_new(int gpio_num, int inactive_level, int active_width_ms, int inactive_width_ms); - - diff --git a/esp_modem/src/esp_modem_dce.c b/esp_modem/src/esp_modem_dce.c index 1d1e27821..6253f057c 100644 --- a/esp_modem/src/esp_modem_dce.c +++ b/esp_modem/src/esp_modem_dce.c @@ -187,4 +187,4 @@ esp_err_t esp_modem_dce_default_start_up(esp_modem_dce_t *dce) return ESP_OK; err: return ESP_FAIL; -} \ No newline at end of file +} diff --git a/esp_modem/src/esp_modem_dce_command_lib.c b/esp_modem/src/esp_modem_dce_command_lib.c index c811124b8..581b5bacf 100644 --- a/esp_modem/src/esp_modem_dce_command_lib.c +++ b/esp_modem/src/esp_modem_dce_command_lib.c @@ -200,5 +200,3 @@ esp_err_t esp_modem_command_list_deinit(esp_modem_dce_t *dce) free(dce->dce_cmd_list); return ESP_OK; } - - diff --git a/esp_modem/src/esp_modem_dce_common_commands.c b/esp_modem/src/esp_modem_dce_common_commands.c index fa862d9bc..bc1f8b890 100644 --- a/esp_modem/src/esp_modem_dce_common_commands.c +++ b/esp_modem/src/esp_modem_dce_common_commands.c @@ -354,4 +354,4 @@ esp_err_t esp_modem_dce_set_baud_temp(esp_modem_dce_t *dce, void *param, void *r command[cmd_len+1] = '\0'; return esp_modem_dce_generic_command(dce, command, MODEM_COMMAND_TIMEOUT_DEFAULT, esp_modem_dce_handle_response_default, NULL); -} \ No newline at end of file +} diff --git a/esp_modem/src/esp_modem_dte.c b/esp_modem/src/esp_modem_dte.c index e61ea7175..28a4baae7 100644 --- a/esp_modem/src/esp_modem_dte.c +++ b/esp_modem/src/esp_modem_dte.c @@ -71,23 +71,28 @@ esp_err_t esp_modem_set_rx_cb(esp_modem_dte_t *dte, esp_modem_on_receive receive */ static esp_err_t esp_dte_handle_line(esp_modem_dte_internal_t *esp_dte) { + esp_err_t err = ESP_FAIL; esp_modem_dce_t *dce = esp_dte->parent.dce; ESP_MODEM_ERR_CHECK(dce, "DTE has not yet bind with DCE", err); const char *line = (const char *)(esp_dte->buffer); size_t len = strlen(line); /* Skip pure "\r\n" lines */ if (len > 2 && !is_only_cr_lf(line, len)) { - ESP_MODEM_ERR_CHECK(dce->handle_line, "no handler for line", err_handle); - ESP_LOGD(TAG, "%s: %s", __func__ , line); - ESP_MODEM_ERR_CHECK(dce->handle_line(dce, line) == ESP_OK, "handle line failed", err_handle); + if (dce->handle_line == NULL) { + /* Received an asynchronous line, but no handler waiting this this */ + ESP_LOGD(TAG, "No handler for line: %s", line); + err = ESP_OK; /* Not an error, just propagate the line to user handler */ + goto post_event_unknown; + } + ESP_MODEM_ERR_CHECK(dce->handle_line(dce, line) == ESP_OK, "handle line failed", err); } return ESP_OK; -err_handle: +post_event_unknown: /* Send ESP_MODEM_EVENT_UNKNOWN signal to event loop */ esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, ESP_MODEM_EVENT_UNKNOWN, (void *)line, strlen(line) + 1, pdMS_TO_TICKS(100)); err: - return ESP_FAIL; + return err; } /** @@ -99,6 +104,15 @@ static void esp_handle_uart_pattern(esp_modem_dte_internal_t *esp_dte) { int pos = uart_pattern_pop_pos(esp_dte->uart_port); int read_len = 0; + + if (esp_dte->parent.dce->mode == ESP_MODEM_PPP_MODE) { + ESP_LOGD(TAG, "Pattern event in PPP mode ignored"); + // Ignore potential pattern detection events in PPP mode + // Note 1: the interrupt is disabled, but some events might still be pending + // Note 2: checking the mode *after* uart_pattern_pop_pos() to consume the event + return; + } + if (pos != -1) { if (pos < esp_dte->line_buffer_size - 1) { /* read one line(include '\n') */ @@ -119,11 +133,12 @@ static void esp_handle_uart_pattern(esp_modem_dte_internal_t *esp_dte) } else { size_t length = 0; uart_get_buffered_data_len(esp_dte->uart_port, &length); - ESP_LOGW(TAG, "Pattern not found in the pattern queue, uart data length = %d", length); - length = MIN(esp_dte->line_buffer_size-1, length); - length = uart_read_bytes(esp_dte->uart_port, esp_dte->buffer, length, portMAX_DELAY); - ESP_LOG_BUFFER_HEXDUMP("esp-modem-dte: debug_data", esp_dte->buffer, length, ESP_LOG_DEBUG); - + if (length) { + ESP_LOGD(TAG, "Pattern not found in the pattern queue, uart data length = %d", length); + length = MIN(esp_dte->line_buffer_size-1, length); + length = uart_read_bytes(esp_dte->uart_port, esp_dte->buffer, length, portMAX_DELAY); + ESP_LOG_BUFFER_HEXDUMP("esp-modem-pattern: debug_data", esp_dte->buffer, length, ESP_LOG_DEBUG); + } uart_flush(esp_dte->uart_port); } } @@ -135,17 +150,12 @@ static void esp_handle_uart_pattern(esp_modem_dte_internal_t *esp_dte) */ static void esp_handle_uart_data(esp_modem_dte_internal_t *esp_dte) { - if (!esp_dte->parent.dce) { - // we could possibly get a data event before - // the DCE gets bound yet with the DTE, so just return - return; - } size_t length = 0; uart_get_buffered_data_len(esp_dte->uart_port, &length); - if (esp_dte->parent.dce->mode != ESP_MODEM_PPP_MODE) { + if (esp_dte->parent.dce->mode != ESP_MODEM_PPP_MODE && length) { // Check if matches the pattern to process the data as pattern - int pos = uart_pattern_pop_pos(esp_dte->uart_port); + int pos = uart_pattern_get_pos(esp_dte->uart_port); if (pos > -1) { esp_handle_uart_pattern(esp_dte); return; @@ -153,10 +163,24 @@ static void esp_handle_uart_data(esp_modem_dte_internal_t *esp_dte) // Read the data and process it using `handle_line` logic length = MIN(esp_dte->line_buffer_size-1, length); length = uart_read_bytes(esp_dte->uart_port, esp_dte->buffer, length, portMAX_DELAY); - ESP_LOG_BUFFER_HEXDUMP("esp-modem-dte: debug_data", esp_dte->buffer, length, ESP_LOG_DEBUG); esp_dte->buffer[length] = '\0'; + if (strchr((char*)esp_dte->buffer, '\n') == NULL) { + size_t max = esp_dte->line_buffer_size-1; + size_t bytes; + // if pattern not found in the data, + // continue reading as long as the modem is in MODEM_STATE_PROCESSING, checking for the pattern + while (length < max && esp_dte->buffer[length-1] != '\n' && + esp_dte->parent.dce->state == ESP_MODEM_STATE_PROCESSING) { + bytes = uart_read_bytes(esp_dte->uart_port, + esp_dte->buffer + length, 1, pdMS_TO_TICKS(100)); + length += bytes; + ESP_LOGV("esp-modem: debug_data", "Continuous read in non-data mode: length: %d char: %x", length, esp_dte->buffer[length-1]); + } + esp_dte->buffer[length] = '\0'; + } + ESP_LOG_BUFFER_HEXDUMP("esp-modem: debug_data", esp_dte->buffer, length, ESP_LOG_DEBUG); if (esp_dte->parent.dce->handle_line) { - // Send new line to handle if handler registered + /* Send new line to handle if handler registered */ esp_dte_handle_line(esp_dte); } return; @@ -185,7 +209,20 @@ static void uart_event_task_entry(void *param) } while (xEventGroupGetBits(esp_dte->process_group) & ESP_MODEM_START_BIT) { + /* Drive the event loop */ + esp_event_loop_run(esp_dte->event_loop_hdl, pdMS_TO_TICKS(0)); + + /* Process UART events */ if (xQueueReceive(esp_dte->event_queue, &event, pdMS_TO_TICKS(100))) { + if (esp_dte->parent.dce == NULL) { + ESP_LOGD(TAG, "Ignore UART event for DTE with no DCE attached"); + // No action on any uart event with null DCE. + // This might happen before DCE gets initialized and attached to running DTE, + // or after destroying the DCE when DTE is up and gets a data event. + uart_flush(esp_dte->uart_port); + continue; + } + switch (event.type) { case UART_DATA: esp_handle_uart_data(esp_dte); @@ -217,8 +254,6 @@ static void uart_event_task_entry(void *param) break; } } - /* Drive the event loop */ - esp_event_loop_run(esp_dte->event_loop_hdl, pdMS_TO_TICKS(0)); } vTaskDelete(NULL); } @@ -270,6 +305,10 @@ static int esp_modem_dte_send_data(esp_modem_dte_t *dte, const char *data, uint3 ESP_LOGD(TAG, "Not sending data in transition mode"); return -1; } + if (esp_dte->parent.dce->mode == ESP_MODEM_TRANSITION_MODE) { + ESP_LOGD(TAG, "Not sending data in transition mode"); + return -1; + } ESP_LOG_BUFFER_HEXDUMP("esp-modem-dte: ppp_output", data, length, ESP_LOG_VERBOSE); return uart_write_bytes(esp_dte->uart_port, data, length); @@ -502,4 +541,4 @@ esp_err_t esp_modem_dte_set_params(esp_modem_dte_t *dte, const esp_modem_dte_con { esp_modem_dte_internal_t *esp_dte = __containerof(dte, esp_modem_dte_internal_t, parent); return uart_set_baudrate(esp_dte->uart_port, config->baud_rate); -} \ No newline at end of file +}