diff --git a/examples/protocols/pppos_client/components/modem/CMakeLists.txt b/examples/protocols/pppos_client/components/modem/CMakeLists.txt index 50fa1a4b7b..bd6af3b747 100644 --- a/examples/protocols/pppos_client/components/modem/CMakeLists.txt +++ b/examples/protocols/pppos_client/components/modem/CMakeLists.txt @@ -8,5 +8,4 @@ set(srcs "src/esp_modem.c" idf_component_register(SRCS "${srcs}" INCLUDE_DIRS include - PRIV_INCLUDE_DIRS private_include REQUIRES driver) diff --git a/examples/protocols/pppos_client/components/modem/component.mk b/examples/protocols/pppos_client/components/modem/component.mk index d3afe77680..33f4c6039d 100644 --- a/examples/protocols/pppos_client/components/modem/component.mk +++ b/examples/protocols/pppos_client/components/modem/component.mk @@ -1,3 +1,2 @@ COMPONENT_ADD_INCLUDEDIRS := include -COMPONENT_PRIV_INCLUDEDIRS := private_include COMPONENT_SRCDIRS := src diff --git a/examples/protocols/pppos_client/components/modem/include/esp_modem_dce.h b/examples/protocols/pppos_client/components/modem/include/esp_modem_dce.h index 6a88de0c36..3da9d0aea1 100644 --- a/examples/protocols/pppos_client/components/modem/include/esp_modem_dce.h +++ b/examples/protocols/pppos_client/components/modem/include/esp_modem_dce.h @@ -23,6 +23,7 @@ extern "C" { typedef struct modem_dce modem_dce_t; typedef struct modem_dte modem_dte_t; +typedef struct esp_modem_dce esp_modem_dce_t; /** * @brief Result Code from DCE @@ -96,6 +97,15 @@ struct modem_dce { esp_err_t (*deinit)(modem_dce_t *dce); /*!< Deinitialize */ }; +/** + * @brief ESP Modem with private resource + * + */ + struct esp_modem_dce { + void *priv_resource; /*!< Private resource */ + modem_dce_t parent; /*!< DCE parent class */ + }; + #ifdef __cplusplus } #endif diff --git a/examples/protocols/pppos_client/components/modem/include/esp_modem_dce_service.h b/examples/protocols/pppos_client/components/modem/include/esp_modem_dce_service.h index 9b9a3a6c4d..447dc8a6ae 100644 --- a/examples/protocols/pppos_client/components/modem/include/esp_modem_dce_service.h +++ b/examples/protocols/pppos_client/components/modem/include/esp_modem_dce_service.h @@ -61,6 +61,94 @@ static inline void strip_cr_lf_tail(char *str, uint32_t len) */ esp_err_t esp_modem_dce_handle_response_default(modem_dce_t *dce, const char *line); +/** + * @brief Handle response from AT+CSQ (Get signal quality) + * + * @param dce Modem DCE object + * @param line line string + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_handle_csq(modem_dce_t *dce, const char *line); + +/** + * @brief Handle response from AT+CBC (Get battery status) + * + * @param dce Modem DCE object + * @param line line string + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_handle_cbc(modem_dce_t *dce, const char *line); + +/** + * @brief Handle response from +++ (Set Working Mode) + * + * @param dce Modem DCE object + * @param line line string + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_handle_exit_data_mode(modem_dce_t *dce, const char *line); + +/** + * @brief Handle response from ATD*99# (Set Working Mode) + * + * @param dce Modem DCE object + * @param line line string + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_handle_atd_ppp(modem_dce_t *dce, const char *line); + +/** + * @brief Handle response from AT+CGMM (Get DCE module name) + * + * @param dce Modem DCE object + * @param line line string + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_handle_cgmm(modem_dce_t *dce, const char *line); + +/** + * @brief Handle response from AT+CGSN (Get DCE module IMEI number) + * + * @param dce Modem DCE object + * @param line line string + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_handle_cgsn(modem_dce_t *dce, const char *line); + +/** + * @brief Handle response from AT+CIMI (Get DCE module IMSI number) + * + * @param dce Modem DCE object + * @param line line string + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_handle_cimi(modem_dce_t *dce, const char *line); + +/** + * @brief Handle response from AT+COPS? (Get Operator's name) + * + * @param dce Modem DCE object + * @param line line string + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_handle_cops(modem_dce_t *dce, const char *line); + /** * @brief Syncronization * @@ -72,7 +160,7 @@ esp_err_t esp_modem_dce_handle_response_default(modem_dce_t *dce, const char *li esp_err_t esp_modem_dce_sync(modem_dce_t *dce); /** - * @brief Enable or not echo mode of DCE + * @brief Enable or not echo mode of DCE (V.25TER specification) * * @param dce Modem DCE object * @param on true to enable echo mode, false to disable echo mode @@ -93,7 +181,7 @@ esp_err_t esp_modem_dce_echo(modem_dce_t *dce, bool on); esp_err_t esp_modem_dce_store_profile(modem_dce_t *dce); /** - * @brief Set flow control mode of DCE in data mode + * @brief Set flow control mode of DCE in data mode (V.25TER specification) * * @param dce Modem DCE object * @param flow_ctrl flow control mode @@ -104,7 +192,7 @@ esp_err_t esp_modem_dce_store_profile(modem_dce_t *dce); esp_err_t esp_modem_dce_set_flow_ctrl(modem_dce_t *dce, modem_flow_ctrl_t flow_ctrl); /** - * @brief Define PDP context + * @brief Define PDP context (GPRS) * * @param dce Modem DCE object * @param cid PDP context identifier @@ -117,7 +205,72 @@ esp_err_t esp_modem_dce_set_flow_ctrl(modem_dce_t *dce, modem_flow_ctrl_t flow_c esp_err_t esp_modem_dce_define_pdp_context(modem_dce_t *dce, uint32_t cid, const char *type, const char *apn); /** - * @brief Hang up + * @brief Get signal quality (3GPP TS 27.007 specification) + * + * @param dce Modem DCE object + * @param rssi received signal strength indication + * @param ber bit error ratio + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_get_signal_quality(modem_dce_t *dce, uint32_t *rssi, uint32_t *ber); + +/** + * @brief Get battery status (3GPP TS 27.007 specification) + * + * @param dce Modem DCE object + * @param bcs Battery charge status + * @param bcl Battery connection level + * @param voltage Battery voltage + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_get_battery_status(modem_dce_t *dce, uint32_t *bcs, uint32_t *bcl, uint32_t *voltage); + +/** + * @brief Get DCE module name (3GPP TS 27.007 specification) + * + * @param dce Modem DCE object + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_get_module_name(modem_dce_t *dce); + +/** + * @brief Get DCE module IMEI number (3GPP TS 27.007 specification) + * + * @param dce Modem DCE object + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_get_imei_number(modem_dce_t *dce); + +/** + * @brief Get DCE module IMSI number (3GPP TS 27.007 specification) + * + * @param dce Modem DCE object + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_get_imsi_number(modem_dce_t *dce); + +/** + * @brief Get Operator's name (3GPP TS 27.007 specification) + * + * @param dce Modem DCE object + * @return esp_err_t + * - ESP_OK on success + * - ESP_FAIL on error + */ +esp_err_t esp_modem_dce_get_operator_name(modem_dce_t *dce); + +/** + * @brief Hang up (V.25TER specification) * * @param dce Modem DCE object * @return esp_err_t diff --git a/examples/protocols/pppos_client/components/modem/private_include/bg96_private.h b/examples/protocols/pppos_client/components/modem/private_include/bg96_private.h deleted file mode 100644 index 6b245fc8fd..0000000000 --- a/examples/protocols/pppos_client/components/modem/private_include/bg96_private.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#pragma once - -/** - * @brief Macro defined for error checking - * - */ -#define DCE_CHECK(a, str, goto_tag, ...) \ - do \ - { \ - if (!(a)) \ - { \ - ESP_LOGE(DCE_TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - goto goto_tag; \ - } \ - } while (0) - -/** - * @brief BG96 Modem - * - */ -typedef struct { - void *priv_resource; /*!< Private resource */ - modem_dce_t parent; /*!< DCE parent class */ -} bg96_modem_dce_t; diff --git a/examples/protocols/pppos_client/components/modem/src/bg96.c b/examples/protocols/pppos_client/components/modem/src/bg96.c index da5c202d6a..af8e16a754 100644 --- a/examples/protocols/pppos_client/components/modem/src/bg96.c +++ b/examples/protocols/pppos_client/components/modem/src/bg96.c @@ -14,188 +14,26 @@ #include #include #include "esp_log.h" +#include "esp_modem_dce_service.h" #include "bg96.h" -#include "bg96_private.h" #define MODEM_RESULT_CODE_POWERDOWN "POWERED DOWN" static const char *DCE_TAG = "bg96"; /** - * @brief Handle response from AT+CSQ + * @brief Macro defined for error checking + * */ -static esp_err_t bg96_handle_csq(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - bg96_modem_dce_t *bg96_dce = __containerof(dce, bg96_modem_dce_t, parent); - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else if (!strncmp(line, "+CSQ", strlen("+CSQ"))) { - /* store value of rssi and ber */ - uint32_t **csq = bg96_dce->priv_resource; - /* +CSQ: , */ - sscanf(line, "%*s%d,%d", csq[0], csq[1]); - err = ESP_OK; - } - return err; -} - -/** - * @brief Handle response from AT+CBC - */ -static esp_err_t bg96_handle_cbc(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - bg96_modem_dce_t *bg96_dce = __containerof(dce, bg96_modem_dce_t, parent); - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else if (!strncmp(line, "+CBC", strlen("+CBC"))) { - /* store value of bcs, bcl, voltage */ - uint32_t **cbc = bg96_dce->priv_resource; - /* +CBC: ,, */ - sscanf(line, "%*s%d,%d,%d", cbc[0], cbc[1], cbc[2]); - err = ESP_OK; - } - return err; -} - -/** - * @brief Handle response from +++ - */ -static esp_err_t bg96_handle_exit_data_mode(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_NO_CARRIER)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } - return err; -} - -/** - * @brief Handle response from ATD*99# - */ -static esp_err_t bg96_handle_atd_ppp(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_CONNECT)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } - return err; -} - -/** - * @brief Handle response from AT+CGMM - */ -static esp_err_t bg96_handle_cgmm(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else { - int len = snprintf(dce->name, MODEM_MAX_NAME_LENGTH, "%s", line); - if (len > 2) { - /* Strip "\r\n" */ - strip_cr_lf_tail(dce->name, len); - err = ESP_OK; - } - } - return err; -} - -/** - * @brief Handle response from AT+CGSN - */ -static esp_err_t bg96_handle_cgsn(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else { - int len = snprintf(dce->imei, MODEM_IMEI_LENGTH + 1, "%s", line); - if (len > 2) { - /* Strip "\r\n" */ - strip_cr_lf_tail(dce->imei, len); - err = ESP_OK; - } - } - return err; -} - -/** - * @brief Handle response from AT+CIMI - */ -static esp_err_t bg96_handle_cimi(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else { - int len = snprintf(dce->imsi, MODEM_IMSI_LENGTH + 1, "%s", line); - if (len > 2) { - /* Strip "\r\n" */ - strip_cr_lf_tail(dce->imsi, len); - err = ESP_OK; - } - } - return err; -} - -/** - * @brief Handle response from AT+COPS? - */ -static esp_err_t bg96_handle_cops(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else if (!strncmp(line, "+COPS", strlen("+COPS"))) { - /* there might be some random spaces in operator's name, we can not use sscanf to parse the result */ - /* strtok will break the string, we need to create a copy */ - size_t len = strlen(line); - char *line_copy = malloc(len + 1); - strcpy(line_copy, line); - /* +COPS: [, [, [, ]]] */ - char *str_ptr = NULL; - char *p[5]; - uint8_t i = 0; - /* strtok will broke string by replacing delimiter with '\0' */ - p[i] = strtok_r(line_copy, ",", &str_ptr); - while (p[i]) { - p[++i] = strtok_r(NULL, ",", &str_ptr); - } - if (i >= 3) { - int len = snprintf(dce->oper, MODEM_MAX_OPERATOR_LENGTH, "%s", p[2]); - if (len > 2) { - /* Strip "\r\n" */ - strip_cr_lf_tail(dce->oper, len); - err = ESP_OK; - } - } - if (i >= 4) { - dce->act = (uint8_t)strtol(p[3], NULL, 0); - } - free(line_copy); - } - return err; -} +#define DCE_CHECK(a, str, goto_tag, ...) \ + do \ + { \ + if (!(a)) \ + { \ + ESP_LOGE(DCE_TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + goto goto_tag; \ + } \ + } while (0) /** * @brief Handle response from AT+QPOWD=1 @@ -211,57 +49,6 @@ static esp_err_t bg96_handle_power_down(modem_dce_t *dce, const char *line) return err; } -/** - * @brief Get signal quality - * - * @param dce Modem DCE object - * @param rssi received signal strength indication - * @param ber bit error ratio - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t bg96_get_signal_quality(modem_dce_t *dce, uint32_t *rssi, uint32_t *ber) -{ - modem_dte_t *dte = dce->dte; - bg96_modem_dce_t *bg96_dce = __containerof(dce, bg96_modem_dce_t, parent); - uint32_t *resource[2] = {rssi, ber}; - bg96_dce->priv_resource = resource; - dce->handle_line = bg96_handle_csq; - DCE_CHECK(dte->send_cmd(dte, "AT+CSQ\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "inquire signal quality failed", err); - ESP_LOGD(DCE_TAG, "inquire signal quality ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - -/** - * @brief Get battery status - * - * @param dce Modem DCE object - * @param bcs Battery charge status - * @param bcl Battery connection level - * @param voltage Battery voltage - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t bg96_get_battery_status(modem_dce_t *dce, uint32_t *bcs, uint32_t *bcl, uint32_t *voltage) -{ - modem_dte_t *dte = dce->dte; - bg96_modem_dce_t *bg96_dce = __containerof(dce, bg96_modem_dce_t, parent); - uint32_t *resource[3] = {bcs, bcl, voltage}; - bg96_dce->priv_resource = resource; - dce->handle_line = bg96_handle_cbc; - DCE_CHECK(dte->send_cmd(dte, "AT+CBC\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "inquire battery status failed", err); - ESP_LOGD(DCE_TAG, "inquire battery status ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - /** * @brief Set Working Mode * @@ -277,7 +64,7 @@ static esp_err_t bg96_set_working_mode(modem_dce_t *dce, modem_mode_t mode) switch (mode) { case MODEM_COMMAND_MODE: vTaskDelay(pdMS_TO_TICKS(1000)); // spec: 1s delay for the modem to recognize the escape sequence - dce->handle_line = bg96_handle_exit_data_mode; + dce->handle_line = esp_modem_dce_handle_exit_data_mode; if (dte->send_cmd(dte, "+++", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) != ESP_OK) { // "+++" Could fail if we are already in the command mode. // in that case we ignore the timeout and re-sync the modem @@ -292,13 +79,13 @@ static esp_err_t bg96_set_working_mode(modem_dce_t *dce, modem_mode_t mode) dce->mode = MODEM_COMMAND_MODE; break; case MODEM_PPP_MODE: - dce->handle_line = bg96_handle_atd_ppp; + dce->handle_line = esp_modem_dce_handle_atd_ppp; DCE_CHECK(dte->send_cmd(dte, "ATD*99***1#\r", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) == ESP_OK, "send command failed", err); if (dce->state != MODEM_STATE_SUCCESS) { // Initiate PPP mode could fail, if we've already "dialed" the data call before. // in that case we retry with "ATO" to just resume the data mode ESP_LOGD(DCE_TAG, "enter ppp mode failed, retry with ATO"); - dce->handle_line = bg96_handle_atd_ppp; + dce->handle_line = esp_modem_dce_handle_atd_ppp; DCE_CHECK(dte->send_cmd(dte, "ATO\r", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) == ESP_OK, "send command failed", err); DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter ppp mode failed", err); } @@ -335,87 +122,6 @@ err: return ESP_FAIL; } -/** - * @brief Get DCE module name - * - * @param bg96_dce bg96 object - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t bg96_get_module_name(bg96_modem_dce_t *bg96_dce) -{ - modem_dte_t *dte = bg96_dce->parent.dte; - bg96_dce->parent.handle_line = bg96_handle_cgmm; - DCE_CHECK(dte->send_cmd(dte, "AT+CGMM\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(bg96_dce->parent.state == MODEM_STATE_SUCCESS, "get module name failed", err); - ESP_LOGD(DCE_TAG, "get module name ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - -/** - * @brief Get DCE module IMEI number - * - * @param bg96_dce bg96 object - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t bg96_get_imei_number(bg96_modem_dce_t *bg96_dce) -{ - modem_dte_t *dte = bg96_dce->parent.dte; - bg96_dce->parent.handle_line = bg96_handle_cgsn; - DCE_CHECK(dte->send_cmd(dte, "AT+CGSN\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(bg96_dce->parent.state == MODEM_STATE_SUCCESS, "get imei number failed", err); - ESP_LOGD(DCE_TAG, "get imei number ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - -/** - * @brief Get DCE module IMSI number - * - * @param bg96_dce bg96 object - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t bg96_get_imsi_number(bg96_modem_dce_t *bg96_dce) -{ - modem_dte_t *dte = bg96_dce->parent.dte; - bg96_dce->parent.handle_line = bg96_handle_cimi; - DCE_CHECK(dte->send_cmd(dte, "AT+CIMI\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(bg96_dce->parent.state == MODEM_STATE_SUCCESS, "get imsi number failed", err); - ESP_LOGD(DCE_TAG, "get imsi number ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - -/** - * @brief Get Operator's name - * - * @param dce Modem DCE object - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t bg96_get_operator_name(modem_dce_t *dce) -{ - modem_dte_t *dte = dce->dte; - bg96_modem_dce_t *bg96_dce = __containerof(dce, bg96_modem_dce_t, parent); - bg96_dce->parent.handle_line = bg96_handle_cops; - DCE_CHECK(dte->send_cmd(dte, "AT+COPS?\r", MODEM_COMMAND_TIMEOUT_OPERATOR) == ESP_OK, "send command failed", err); - DCE_CHECK(bg96_dce->parent.state == MODEM_STATE_SUCCESS, "get network operator failed", err); - ESP_LOGD(DCE_TAG, "get network operator ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - /** * @brief Deinitialize BG96 object * @@ -426,52 +132,52 @@ err: */ static esp_err_t bg96_deinit(modem_dce_t *dce) { - bg96_modem_dce_t *bg96_dce = __containerof(dce, bg96_modem_dce_t, parent); + esp_modem_dce_t *esp_modem_dce = __containerof(dce, esp_modem_dce_t, parent); if (dce->dte) { dce->dte->dce = NULL; } - free(bg96_dce); + free(esp_modem_dce); return ESP_OK; } modem_dce_t *bg96_init(modem_dte_t *dte) { DCE_CHECK(dte, "DCE should bind with a DTE", err); - /* malloc memory for bg96_dce object */ - bg96_modem_dce_t *bg96_dce = calloc(1, sizeof(bg96_modem_dce_t)); - DCE_CHECK(bg96_dce, "calloc bg96_dce failed", err); + /* malloc memory for esp_modem_dce object */ + esp_modem_dce_t *esp_modem_dce = calloc(1, sizeof(esp_modem_dce_t)); + DCE_CHECK(esp_modem_dce, "calloc bg96_dce failed", err); /* Bind DTE with DCE */ - bg96_dce->parent.dte = dte; - dte->dce = &(bg96_dce->parent); + esp_modem_dce->parent.dte = dte; + dte->dce = &(esp_modem_dce->parent); /* Bind methods */ - bg96_dce->parent.handle_line = NULL; - bg96_dce->parent.sync = esp_modem_dce_sync; - bg96_dce->parent.echo_mode = esp_modem_dce_echo; - bg96_dce->parent.store_profile = esp_modem_dce_store_profile; - bg96_dce->parent.set_flow_ctrl = esp_modem_dce_set_flow_ctrl; - bg96_dce->parent.define_pdp_context = esp_modem_dce_define_pdp_context; - bg96_dce->parent.hang_up = esp_modem_dce_hang_up; - bg96_dce->parent.get_signal_quality = bg96_get_signal_quality; - bg96_dce->parent.get_battery_status = bg96_get_battery_status; - bg96_dce->parent.get_operator_name = bg96_get_operator_name; - bg96_dce->parent.set_working_mode = bg96_set_working_mode; - bg96_dce->parent.power_down = bg96_power_down; - bg96_dce->parent.deinit = bg96_deinit; + esp_modem_dce->parent.handle_line = NULL; + esp_modem_dce->parent.sync = esp_modem_dce_sync; + esp_modem_dce->parent.echo_mode = esp_modem_dce_echo; + esp_modem_dce->parent.store_profile = esp_modem_dce_store_profile; + esp_modem_dce->parent.set_flow_ctrl = esp_modem_dce_set_flow_ctrl; + esp_modem_dce->parent.define_pdp_context = esp_modem_dce_define_pdp_context; + esp_modem_dce->parent.hang_up = esp_modem_dce_hang_up; + esp_modem_dce->parent.get_signal_quality = esp_modem_dce_get_signal_quality; + esp_modem_dce->parent.get_battery_status = esp_modem_dce_get_battery_status; + esp_modem_dce->parent.get_operator_name = esp_modem_dce_get_operator_name; + esp_modem_dce->parent.set_working_mode = bg96_set_working_mode; + esp_modem_dce->parent.power_down = bg96_power_down; + esp_modem_dce->parent.deinit = bg96_deinit; /* Sync between DTE and DCE */ - DCE_CHECK(esp_modem_dce_sync(&(bg96_dce->parent)) == ESP_OK, "sync failed", err_io); + DCE_CHECK(esp_modem_dce_sync(&(esp_modem_dce->parent)) == ESP_OK, "sync failed", err_io); /* Close echo */ - DCE_CHECK(esp_modem_dce_echo(&(bg96_dce->parent), false) == ESP_OK, "close echo mode failed", err_io); + DCE_CHECK(esp_modem_dce_echo(&(esp_modem_dce->parent), false) == ESP_OK, "close echo mode failed", err_io); /* Get Module name */ - DCE_CHECK(bg96_get_module_name(bg96_dce) == ESP_OK, "get module name failed", err_io); + DCE_CHECK(esp_modem_dce_get_module_name(&(esp_modem_dce->parent)) == ESP_OK, "get module name failed", err_io); /* Get IMEI number */ - DCE_CHECK(bg96_get_imei_number(bg96_dce) == ESP_OK, "get imei failed", err_io); + DCE_CHECK(esp_modem_dce_get_imei_number(&(esp_modem_dce->parent)) == ESP_OK, "get imei failed", err_io); /* Get IMSI number */ - DCE_CHECK(bg96_get_imsi_number(bg96_dce) == ESP_OK, "get imsi failed", err_io); + DCE_CHECK(esp_modem_dce_get_imsi_number(&(esp_modem_dce->parent)) == ESP_OK, "get imsi failed", err_io); /* Get operator name */ - DCE_CHECK(bg96_get_operator_name(&(bg96_dce->parent)) == ESP_OK, "get operator name failed", err_io); - return &(bg96_dce->parent); + DCE_CHECK(esp_modem_dce_get_operator_name(&(esp_modem_dce->parent)) == ESP_OK, "get operator name failed", err_io); + return &(esp_modem_dce->parent); err_io: - free(bg96_dce); + free(esp_modem_dce); err: return NULL; } diff --git a/examples/protocols/pppos_client/components/modem/src/esp_modem.c b/examples/protocols/pppos_client/components/modem/src/esp_modem.c index 3aba38e6e5..fa7a5f2ed3 100644 --- a/examples/protocols/pppos_client/components/modem/src/esp_modem.c +++ b/examples/protocols/pppos_client/components/modem/src/esp_modem.c @@ -87,7 +87,6 @@ esp_err_t esp_modem_set_rx_cb(modem_dte_t *dte, esp_modem_on_receive receive_cb, return ESP_OK; } - /** * @brief Handle one line in DTE * @@ -330,8 +329,6 @@ err: return -1; } - - /** * @brief Send data and wait for prompt from DCE * @@ -446,8 +443,6 @@ static esp_err_t esp_modem_dte_deinit(modem_dte_t *dte) return ESP_OK; } - - modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config) { esp_err_t res; diff --git a/examples/protocols/pppos_client/components/modem/src/esp_modem_dce_service.c b/examples/protocols/pppos_client/components/modem/src/esp_modem_dce_service.c index 4b73534cf3..5753c18f36 100644 --- a/examples/protocols/pppos_client/components/modem/src/esp_modem_dce_service.c +++ b/examples/protocols/pppos_client/components/modem/src/esp_modem_dce_service.c @@ -15,11 +15,12 @@ #include "esp_log.h" #include "esp_modem_dce_service.h" +static const char *DCE_TAG = "dce_service"; + /** * @brief Macro defined for error checking * */ -static const char *DCE_TAG = "dce_service"; #define DCE_CHECK(a, str, goto_tag, ...) \ do \ { \ @@ -41,6 +42,158 @@ esp_err_t esp_modem_dce_handle_response_default(modem_dce_t *dce, const char *li return err; } +esp_err_t esp_modem_dce_handle_csq(modem_dce_t *dce, const char *line) +{ + esp_err_t err = ESP_FAIL; + esp_modem_dce_t *esp_dce = __containerof(dce, esp_modem_dce_t, parent); + if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); + } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); + } else if (!strncmp(line, "+CSQ", strlen("+CSQ"))) { + /* store value of rssi and ber */ + uint32_t **csq = esp_dce->priv_resource; + /* +CSQ: , */ + sscanf(line, "%*s%d,%d", csq[0], csq[1]); + err = ESP_OK; + } + return err; +} + +esp_err_t esp_modem_dce_handle_cbc(modem_dce_t *dce, const char *line) +{ + esp_err_t err = ESP_FAIL; + esp_modem_dce_t *esp_dce = __containerof(dce, esp_modem_dce_t, parent); + if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); + } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); + } else if (!strncmp(line, "+CBC", strlen("+CBC"))) { + /* store value of bcs, bcl, voltage */ + uint32_t **cbc = esp_dce->priv_resource; + /* +CBC: ,, */ + sscanf(line, "%*s%d,%d,%d", cbc[0], cbc[1], cbc[2]); + err = ESP_OK; + } + return err; +} + +esp_err_t esp_modem_dce_handle_exit_data_mode(modem_dce_t *dce, const char *line) +{ + esp_err_t err = ESP_FAIL; + if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); + } else if (strstr(line, MODEM_RESULT_CODE_NO_CARRIER)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); + } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); + } + return err; +} + +esp_err_t esp_modem_dce_handle_atd_ppp(modem_dce_t *dce, const char *line) +{ + esp_err_t err = ESP_FAIL; + if (strstr(line, MODEM_RESULT_CODE_CONNECT)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); + } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); + } + return err; +} + +esp_err_t esp_modem_dce_handle_cgmm(modem_dce_t *dce, const char *line) +{ + esp_err_t err = ESP_FAIL; + if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); + } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); + } else { + int len = snprintf(dce->name, MODEM_MAX_NAME_LENGTH, "%s", line); + if (len > 2) { + /* Strip "\r\n" */ + strip_cr_lf_tail(dce->name, len); + err = ESP_OK; + } + } + return err; +} + +esp_err_t esp_modem_dce_handle_cgsn(modem_dce_t *dce, const char *line) +{ + esp_err_t err = ESP_FAIL; + if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); + } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); + } else { + int len = snprintf(dce->imei, MODEM_IMEI_LENGTH + 1, "%s", line); + if (len > 2) { + /* Strip "\r\n" */ + strip_cr_lf_tail(dce->imei, len); + err = ESP_OK; + } + } + return err; +} + +esp_err_t esp_modem_dce_handle_cimi(modem_dce_t *dce, const char *line) +{ + esp_err_t err = ESP_FAIL; + if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); + } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); + } else { + int len = snprintf(dce->imsi, MODEM_IMSI_LENGTH + 1, "%s", line); + if (len > 2) { + /* Strip "\r\n" */ + strip_cr_lf_tail(dce->imsi, len); + err = ESP_OK; + } + } + return err; +} + +esp_err_t esp_modem_dce_handle_cops(modem_dce_t *dce, const char *line) +{ + esp_err_t err = ESP_FAIL; + if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); + } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { + err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); + } else if (!strncmp(line, "+COPS", strlen("+COPS"))) { + /* there might be some random spaces in operator's name, we can not use sscanf to parse the result */ + /* strtok will break the string, we need to create a copy */ + size_t len = strlen(line); + char *line_copy = malloc(len + 1); + strcpy(line_copy, line); + /* +COPS: [, [, [, ]]] */ + char *str_ptr = NULL; + char *p[5]; + uint8_t i = 0; + /* strtok will broke string by replacing delimiter with '\0' */ + p[i] = strtok_r(line_copy, ",", &str_ptr); + while (p[i]) { + p[++i] = strtok_r(NULL, ",", &str_ptr); + } + if (i >= 3) { + int len = snprintf(dce->oper, MODEM_MAX_OPERATOR_LENGTH, "%s", p[2]); + if (len > 2) { + /* Strip "\r\n" */ + strip_cr_lf_tail(dce->oper, len); + err = ESP_OK; + } + } + if (i >= 4) { + dce->act = (uint8_t)strtol(p[3], NULL, 0); + } + free(line_copy); + } + return err; +} + esp_err_t esp_modem_dce_sync(modem_dce_t *dce) { modem_dte_t *dte = dce->dte; @@ -113,6 +266,84 @@ err: return ESP_FAIL; } +esp_err_t esp_modem_dce_get_signal_quality(modem_dce_t *dce, uint32_t *rssi, uint32_t *ber) +{ + modem_dte_t *dte = dce->dte; + esp_modem_dce_t *esp_dce = __containerof(dce, esp_modem_dce_t, parent); + uint32_t *resource[2] = {rssi, ber}; + esp_dce->priv_resource = resource; + dce->handle_line = esp_modem_dce_handle_csq; + DCE_CHECK(dte->send_cmd(dte, "AT+CSQ\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); + DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "inquire signal quality failed", err); + ESP_LOGD(DCE_TAG, "inquire signal quality ok"); + return ESP_OK; +err: + return ESP_FAIL; +} + +esp_err_t esp_modem_dce_get_battery_status(modem_dce_t *dce, uint32_t *bcs, uint32_t *bcl, uint32_t *voltage) +{ + modem_dte_t *dte = dce->dte; + esp_modem_dce_t *esp_dce = __containerof(dce, esp_modem_dce_t, parent); + uint32_t *resource[3] = {bcs, bcl, voltage}; + esp_dce->priv_resource = resource; + dce->handle_line = esp_modem_dce_handle_cbc; + DCE_CHECK(dte->send_cmd(dte, "AT+CBC\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); + DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "inquire battery status failed", err); + ESP_LOGD(DCE_TAG, "inquire battery status ok"); + return ESP_OK; +err: + return ESP_FAIL; +} + +esp_err_t esp_modem_dce_get_module_name(modem_dce_t *dce) +{ + modem_dte_t *dte = dce->dte; + dce->handle_line = esp_modem_dce_handle_cgmm; + DCE_CHECK(dte->send_cmd(dte, "AT+CGMM\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); + DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "get module name failed", err); + ESP_LOGD(DCE_TAG, "get module name ok"); + return ESP_OK; +err: + return ESP_FAIL; +} + +esp_err_t esp_modem_dce_get_imei_number(modem_dce_t *dce) +{ + modem_dte_t *dte = dce->dte; + dce->handle_line = esp_modem_dce_handle_cgsn; + DCE_CHECK(dte->send_cmd(dte, "AT+CGSN\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); + DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "get imei number failed", err); + ESP_LOGD(DCE_TAG, "get imei number ok"); + return ESP_OK; +err: + return ESP_FAIL; +} + +esp_err_t esp_modem_dce_get_imsi_number(modem_dce_t *dce) +{ + modem_dte_t *dte = dce->dte; + dce->handle_line = esp_modem_dce_handle_cimi; + DCE_CHECK(dte->send_cmd(dte, "AT+CIMI\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); + DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "get imsi number failed", err); + ESP_LOGD(DCE_TAG, "get imsi number ok"); + return ESP_OK; +err: + return ESP_FAIL; +} + +esp_err_t esp_modem_dce_get_operator_name(modem_dce_t *dce) +{ + modem_dte_t *dte = dce->dte; + dce->handle_line = esp_modem_dce_handle_cops; + DCE_CHECK(dte->send_cmd(dte, "AT+COPS?\r", MODEM_COMMAND_TIMEOUT_OPERATOR) == ESP_OK, "send command failed", err); + DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "get network operator failed", err); + ESP_LOGD(DCE_TAG, "get network operator ok"); + return ESP_OK; +err: + return ESP_FAIL; +} + esp_err_t esp_modem_dce_hang_up(modem_dce_t *dce) { modem_dte_t *dte = dce->dte; diff --git a/examples/protocols/pppos_client/components/modem/src/sim7600.c b/examples/protocols/pppos_client/components/modem/src/sim7600.c index 1c678d3348..3ec3b3fff4 100644 --- a/examples/protocols/pppos_client/components/modem/src/sim7600.c +++ b/examples/protocols/pppos_client/components/modem/src/sim7600.c @@ -14,8 +14,8 @@ #include #include #include "esp_log.h" +#include "esp_modem_dce_service.h" #include "bg96.h" -#include "bg96_private.h" /** * @brief This module supports SIM7600 module, which has a very similar interface @@ -24,20 +24,34 @@ */ static const char *DCE_TAG = "sim7600"; +/** + * @brief Macro defined for error checking + * + */ +#define DCE_CHECK(a, str, goto_tag, ...) \ + do \ + { \ + if (!(a)) \ + { \ + ESP_LOGE(DCE_TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + goto goto_tag; \ + } \ + } while (0) + /** * @brief Handle response from AT+CBC */ static esp_err_t sim7600_handle_cbc(modem_dce_t *dce, const char *line) { esp_err_t err = ESP_FAIL; - bg96_modem_dce_t *bg96_dce = __containerof(dce, bg96_modem_dce_t, parent); + esp_modem_dce_t *esp_modem_dce = __containerof(dce, esp_modem_dce_t, parent); if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); } else if (!strncmp(line, "+CBC", strlen("+CBC"))) { /* store value of bcs, bcl, voltage */ - int32_t **cbc = bg96_dce->priv_resource; + int32_t **cbc = esp_modem_dce->priv_resource; int32_t volts = 0, fraction = 0; /* +CBC: V*/ sscanf(line, "+CBC: %d.%dV", &volts, &fraction); @@ -82,9 +96,9 @@ static esp_err_t sim7600_handle_cpof(modem_dce_t *dce, const char *line) static esp_err_t sim7600_get_battery_status(modem_dce_t *dce, uint32_t *bcs, uint32_t *bcl, uint32_t *voltage) { modem_dte_t *dte = dce->dte; - bg96_modem_dce_t *bg96_dce = __containerof(dce, bg96_modem_dce_t, parent); + esp_modem_dce_t *esp_modem_dce = __containerof(dce, esp_modem_dce_t, parent); uint32_t *resource[3] = {bcs, bcl, voltage}; - bg96_dce->priv_resource = resource; + esp_modem_dce->priv_resource = resource; dce->handle_line = sim7600_handle_cbc; DCE_CHECK(dte->send_cmd(dte, "AT+CBC\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "inquire battery status failed", err); diff --git a/examples/protocols/pppos_client/components/modem/src/sim800.c b/examples/protocols/pppos_client/components/modem/src/sim800.c index 177a288e88..d0a80c6f52 100644 --- a/examples/protocols/pppos_client/components/modem/src/sim800.c +++ b/examples/protocols/pppos_client/components/modem/src/sim800.c @@ -19,11 +19,12 @@ #define MODEM_RESULT_CODE_POWERDOWN "POWER DOWN" +static const char *DCE_TAG = "sim800"; + /** * @brief Macro defined for error checking * */ -static const char *DCE_TAG = "sim800"; #define DCE_CHECK(a, str, goto_tag, ...) \ do \ { \ @@ -34,191 +35,6 @@ static const char *DCE_TAG = "sim800"; } \ } while (0) -/** - * @brief SIM800 Modem - * - */ -typedef struct { - void *priv_resource; /*!< Private resource */ - modem_dce_t parent; /*!< DCE parent class */ -} sim800_modem_dce_t; - -/** - * @brief Handle response from AT+CSQ - */ -static esp_err_t sim800_handle_csq(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - sim800_modem_dce_t *sim800_dce = __containerof(dce, sim800_modem_dce_t, parent); - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else if (!strncmp(line, "+CSQ", strlen("+CSQ"))) { - /* store value of rssi and ber */ - uint32_t **csq = sim800_dce->priv_resource; - /* +CSQ: , */ - sscanf(line, "%*s%d,%d", csq[0], csq[1]); - err = ESP_OK; - } - return err; -} - -/** - * @brief Handle response from AT+CBC - */ -static esp_err_t sim800_handle_cbc(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - sim800_modem_dce_t *sim800_dce = __containerof(dce, sim800_modem_dce_t, parent); - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else if (!strncmp(line, "+CBC", strlen("+CBC"))) { - /* store value of bcs, bcl, voltage */ - uint32_t **cbc = sim800_dce->priv_resource; - /* +CBC: ,, */ - sscanf(line, "%*s%d,%d,%d", cbc[0], cbc[1], cbc[2]); - err = ESP_OK; - } - return err; -} - -/** - * @brief Handle response from +++ - */ -static esp_err_t sim800_handle_exit_data_mode(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_NO_CARRIER)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } - return err; -} - -/** - * @brief Handle response from ATD*99# - */ -static esp_err_t sim800_handle_atd_ppp(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_CONNECT)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } - return err; -} - -/** - * @brief Handle response from AT+CGMM - */ -static esp_err_t sim800_handle_cgmm(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else { - int len = snprintf(dce->name, MODEM_MAX_NAME_LENGTH, "%s", line); - if (len > 2) { - /* Strip "\r\n" */ - strip_cr_lf_tail(dce->name, len); - err = ESP_OK; - } - } - return err; -} - -/** - * @brief Handle response from AT+CGSN - */ -static esp_err_t sim800_handle_cgsn(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else { - int len = snprintf(dce->imei, MODEM_IMEI_LENGTH + 1, "%s", line); - if (len > 2) { - /* Strip "\r\n" */ - strip_cr_lf_tail(dce->imei, len); - err = ESP_OK; - } - } - return err; -} - -/** - * @brief Handle response from AT+CIMI - */ -static esp_err_t sim800_handle_cimi(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else { - int len = snprintf(dce->imsi, MODEM_IMSI_LENGTH + 1, "%s", line); - if (len > 2) { - /* Strip "\r\n" */ - strip_cr_lf_tail(dce->imsi, len); - err = ESP_OK; - } - } - return err; -} - -/** - * @brief Handle response from AT+COPS? - */ -static esp_err_t sim800_handle_cops(modem_dce_t *dce, const char *line) -{ - esp_err_t err = ESP_FAIL; - if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS); - } else if (strstr(line, MODEM_RESULT_CODE_ERROR)) { - err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL); - } else if (!strncmp(line, "+COPS", strlen("+COPS"))) { - /* there might be some random spaces in operator's name, we can not use sscanf to parse the result */ - /* strtok will break the string, we need to create a copy */ - size_t len = strlen(line); - char *line_copy = malloc(len + 1); - strcpy(line_copy, line); - /* +COPS: [, [, [, ]]] */ - char *str_ptr = NULL; - char *p[5]; - uint8_t i = 0; - /* strtok will broke string by replacing delimiter with '\0' */ - p[i] = strtok_r(line_copy, ",", &str_ptr); - while (p[i]) { - p[++i] = strtok_r(NULL, ",", &str_ptr); - } - if (i >= 3) { - int len = snprintf(dce->oper, MODEM_MAX_OPERATOR_LENGTH, "%s", p[2]); - if (len > 2) { - /* Strip "\r\n" */ - strip_cr_lf_tail(dce->oper, len); - err = ESP_OK; - } - } - if (i >= 4) { - dce->act = (uint8_t)strtol(p[3], NULL, 0); - } - free(line_copy); - } - return err; -} - /** * @brief Handle response from AT+CPOWD=1 */ @@ -231,110 +47,6 @@ static esp_err_t sim800_handle_power_down(modem_dce_t *dce, const char *line) return err; } -/** - * @brief Get signal quality - * - * @param dce Modem DCE object - * @param rssi received signal strength indication - * @param ber bit error ratio - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t sim800_get_signal_quality(modem_dce_t *dce, uint32_t *rssi, uint32_t *ber) -{ - modem_dte_t *dte = dce->dte; - sim800_modem_dce_t *sim800_dce = __containerof(dce, sim800_modem_dce_t, parent); - uint32_t *resource[2] = {rssi, ber}; - sim800_dce->priv_resource = resource; - dce->handle_line = sim800_handle_csq; - DCE_CHECK(dte->send_cmd(dte, "AT+CSQ\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "inquire signal quality failed", err); - ESP_LOGD(DCE_TAG, "inquire signal quality ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - -/** - * @brief Get battery status - * - * @param dce Modem DCE object - * @param bcs Battery charge status - * @param bcl Battery connection level - * @param voltage Battery voltage - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t sim800_get_battery_status(modem_dce_t *dce, uint32_t *bcs, uint32_t *bcl, uint32_t *voltage) -{ - modem_dte_t *dte = dce->dte; - sim800_modem_dce_t *sim800_dce = __containerof(dce, sim800_modem_dce_t, parent); - uint32_t *resource[3] = {bcs, bcl, voltage}; - sim800_dce->priv_resource = resource; - dce->handle_line = sim800_handle_cbc; - DCE_CHECK(dte->send_cmd(dte, "AT+CBC\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "inquire battery status failed", err); - ESP_LOGD(DCE_TAG, "inquire battery status ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - -/** - * @brief Set Working Mode - * - * @param dce Modem DCE object - * @param mode woking mode - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t sim800_set_working_mode(modem_dce_t *dce, modem_mode_t mode) -{ - modem_dte_t *dte = dce->dte; - switch (mode) { - case MODEM_COMMAND_MODE: - dce->handle_line = sim800_handle_exit_data_mode; - vTaskDelay(pdMS_TO_TICKS(1000)); // spec: 1s delay for the modem to recognize the escape sequence - if (dte->send_cmd(dte, "+++", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) != ESP_OK) { - // "+++" Could fail if we are already in the command mode. - // in that case we ignore the timeout and re-sync the modem - ESP_LOGI(DCE_TAG, "Sending \"+++\" command failed"); - dce->handle_line = esp_modem_dce_handle_response_default; - DCE_CHECK(dte->send_cmd(dte, "AT\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "sync failed", err); - } else { - DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter command mode failed", err); - } - ESP_LOGD(DCE_TAG, "enter command mode ok"); - dce->mode = MODEM_COMMAND_MODE; - break; - case MODEM_PPP_MODE: - dce->handle_line = sim800_handle_atd_ppp; - DCE_CHECK(dte->send_cmd(dte, "ATD*99#\r", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) == ESP_OK, "send command failed", err); - if (dce->state != MODEM_STATE_SUCCESS) { - // Initiate PPP mode could fail, if we've already "dialed" the data call before. - // in that case we retry with "ATO" to just resume the data mode - ESP_LOGD(DCE_TAG, "enter ppp mode failed, retry with ATO"); - dce->handle_line = sim800_handle_atd_ppp; - DCE_CHECK(dte->send_cmd(dte, "ATO\r", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) == ESP_OK, "send command failed", err); - DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter ppp mode failed", err); - } - ESP_LOGD(DCE_TAG, "enter ppp mode ok"); - dce->mode = MODEM_PPP_MODE; - break; - default: - ESP_LOGW(DCE_TAG, "unsupported working mode: %d", mode); - goto err; - break; - } - return ESP_OK; -err: - return ESP_FAIL; -} - /** * @brief Power down * @@ -356,81 +68,53 @@ err: } /** - * @brief Get DCE module name - * - * @param sim800_dce sim800 object - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t sim800_get_module_name(sim800_modem_dce_t *sim800_dce) -{ - modem_dte_t *dte = sim800_dce->parent.dte; - sim800_dce->parent.handle_line = sim800_handle_cgmm; - DCE_CHECK(dte->send_cmd(dte, "AT+CGMM\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(sim800_dce->parent.state == MODEM_STATE_SUCCESS, "get module name failed", err); - ESP_LOGD(DCE_TAG, "get module name ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - -/** - * @brief Get DCE module IMEI number - * - * @param sim800_dce sim800 object - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t sim800_get_imei_number(sim800_modem_dce_t *sim800_dce) -{ - modem_dte_t *dte = sim800_dce->parent.dte; - sim800_dce->parent.handle_line = sim800_handle_cgsn; - DCE_CHECK(dte->send_cmd(dte, "AT+CGSN\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(sim800_dce->parent.state == MODEM_STATE_SUCCESS, "get imei number failed", err); - ESP_LOGD(DCE_TAG, "get imei number ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - -/** - * @brief Get DCE module IMSI number - * - * @param sim800_dce sim800 object - * @return esp_err_t - * - ESP_OK on success - * - ESP_FAIL on error - */ -static esp_err_t sim800_get_imsi_number(sim800_modem_dce_t *sim800_dce) -{ - modem_dte_t *dte = sim800_dce->parent.dte; - sim800_dce->parent.handle_line = sim800_handle_cimi; - DCE_CHECK(dte->send_cmd(dte, "AT+CIMI\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); - DCE_CHECK(sim800_dce->parent.state == MODEM_STATE_SUCCESS, "get imsi number failed", err); - ESP_LOGD(DCE_TAG, "get imsi number ok"); - return ESP_OK; -err: - return ESP_FAIL; -} - -/** - * @brief Get Operator's name + * @brief Set Working Mode * * @param dce Modem DCE object + * @param mode woking mode * @return esp_err_t * - ESP_OK on success * - ESP_FAIL on error */ -static esp_err_t sim800_get_operator_name(modem_dce_t *dce) +static esp_err_t sim800_set_working_mode(modem_dce_t *dce, modem_mode_t mode) { modem_dte_t *dte = dce->dte; - sim800_modem_dce_t *sim800_dce = __containerof(dce, sim800_modem_dce_t, parent); - sim800_dce->parent.handle_line = sim800_handle_cops; - DCE_CHECK(dte->send_cmd(dte, "AT+COPS?\r", MODEM_COMMAND_TIMEOUT_OPERATOR) == ESP_OK, "send command failed", err); - DCE_CHECK(sim800_dce->parent.state == MODEM_STATE_SUCCESS, "get network operator failed", err); - ESP_LOGD(DCE_TAG, "get network operator ok"); + switch (mode) { + case MODEM_COMMAND_MODE: + dce->handle_line = esp_modem_dce_handle_exit_data_mode; + vTaskDelay(pdMS_TO_TICKS(1000)); // spec: 1s delay for the modem to recognize the escape sequence + if (dte->send_cmd(dte, "+++", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) != ESP_OK) { + // "+++" Could fail if we are already in the command mode. + // in that case we ignore the timeout and re-sync the modem + ESP_LOGI(DCE_TAG, "Sending \"+++\" command failed"); + dce->handle_line = esp_modem_dce_handle_response_default; + DCE_CHECK(dte->send_cmd(dte, "AT\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err); + DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "sync failed", err); + } else { + DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter command mode failed", err); + } + ESP_LOGD(DCE_TAG, "enter command mode ok"); + dce->mode = MODEM_COMMAND_MODE; + break; + case MODEM_PPP_MODE: + dce->handle_line = esp_modem_dce_handle_atd_ppp; + DCE_CHECK(dte->send_cmd(dte, "ATD*99#\r", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) == ESP_OK, "send command failed", err); + if (dce->state != MODEM_STATE_SUCCESS) { + // Initiate PPP mode could fail, if we've already "dialed" the data call before. + // in that case we retry with "ATO" to just resume the data mode + ESP_LOGD(DCE_TAG, "enter ppp mode failed, retry with ATO"); + dce->handle_line = esp_modem_dce_handle_atd_ppp; + DCE_CHECK(dte->send_cmd(dte, "ATO\r", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) == ESP_OK, "send command failed", err); + DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter ppp mode failed", err); + } + ESP_LOGD(DCE_TAG, "enter ppp mode ok"); + dce->mode = MODEM_PPP_MODE; + break; + default: + ESP_LOGW(DCE_TAG, "unsupported working mode: %d", mode); + goto err; + break; + } return ESP_OK; err: return ESP_FAIL; @@ -446,52 +130,52 @@ err: */ static esp_err_t sim800_deinit(modem_dce_t *dce) { - sim800_modem_dce_t *sim800_dce = __containerof(dce, sim800_modem_dce_t, parent); + esp_modem_dce_t *esp_modem_dce = __containerof(dce, esp_modem_dce_t, parent); if (dce->dte) { dce->dte->dce = NULL; } - free(sim800_dce); + free(esp_modem_dce); return ESP_OK; } modem_dce_t *sim800_init(modem_dte_t *dte) { DCE_CHECK(dte, "DCE should bind with a DTE", err); - /* malloc memory for sim800_dce object */ - sim800_modem_dce_t *sim800_dce = calloc(1, sizeof(sim800_modem_dce_t)); - DCE_CHECK(sim800_dce, "calloc sim800_dce failed", err); + /* malloc memory for esp_modem_dce object */ + esp_modem_dce_t *esp_modem_dce = calloc(1, sizeof(esp_modem_dce_t)); + DCE_CHECK(esp_modem_dce, "calloc esp_modem_dce_t failed", err); /* Bind DTE with DCE */ - sim800_dce->parent.dte = dte; - dte->dce = &(sim800_dce->parent); + esp_modem_dce->parent.dte = dte; + dte->dce = &(esp_modem_dce->parent); /* Bind methods */ - sim800_dce->parent.handle_line = NULL; - sim800_dce->parent.sync = esp_modem_dce_sync; - sim800_dce->parent.echo_mode = esp_modem_dce_echo; - sim800_dce->parent.store_profile = esp_modem_dce_store_profile; - sim800_dce->parent.set_flow_ctrl = esp_modem_dce_set_flow_ctrl; - sim800_dce->parent.define_pdp_context = esp_modem_dce_define_pdp_context; - sim800_dce->parent.hang_up = esp_modem_dce_hang_up; - sim800_dce->parent.get_signal_quality = sim800_get_signal_quality; - sim800_dce->parent.get_battery_status = sim800_get_battery_status; - sim800_dce->parent.get_operator_name = sim800_get_operator_name; - sim800_dce->parent.set_working_mode = sim800_set_working_mode; - sim800_dce->parent.power_down = sim800_power_down; - sim800_dce->parent.deinit = sim800_deinit; + esp_modem_dce->parent.handle_line = NULL; + esp_modem_dce->parent.sync = esp_modem_dce_sync; + esp_modem_dce->parent.echo_mode = esp_modem_dce_echo; + esp_modem_dce->parent.store_profile = esp_modem_dce_store_profile; + esp_modem_dce->parent.set_flow_ctrl = esp_modem_dce_set_flow_ctrl; + esp_modem_dce->parent.define_pdp_context = esp_modem_dce_define_pdp_context; + esp_modem_dce->parent.hang_up = esp_modem_dce_hang_up; + esp_modem_dce->parent.get_signal_quality = esp_modem_dce_get_signal_quality; + esp_modem_dce->parent.get_battery_status = esp_modem_dce_get_battery_status; + esp_modem_dce->parent.get_operator_name = esp_modem_dce_get_operator_name; + esp_modem_dce->parent.set_working_mode = sim800_set_working_mode; + esp_modem_dce->parent.power_down = sim800_power_down; + esp_modem_dce->parent.deinit = sim800_deinit; /* Sync between DTE and DCE */ - DCE_CHECK(esp_modem_dce_sync(&(sim800_dce->parent)) == ESP_OK, "sync failed", err_io); + DCE_CHECK(esp_modem_dce_sync(&(esp_modem_dce->parent)) == ESP_OK, "sync failed", err_io); /* Close echo */ - DCE_CHECK(esp_modem_dce_echo(&(sim800_dce->parent), false) == ESP_OK, "close echo mode failed", err_io); + DCE_CHECK(esp_modem_dce_echo(&(esp_modem_dce->parent), false) == ESP_OK, "close echo mode failed", err_io); /* Get Module name */ - DCE_CHECK(sim800_get_module_name(sim800_dce) == ESP_OK, "get module name failed", err_io); + DCE_CHECK(esp_modem_dce_get_module_name(&(esp_modem_dce->parent)) == ESP_OK, "get module name failed", err_io); /* Get IMEI number */ - DCE_CHECK(sim800_get_imei_number(sim800_dce) == ESP_OK, "get imei failed", err_io); + DCE_CHECK(esp_modem_dce_get_imei_number(&(esp_modem_dce->parent)) == ESP_OK, "get imei failed", err_io); /* Get IMSI number */ - DCE_CHECK(sim800_get_imsi_number(sim800_dce) == ESP_OK, "get imsi failed", err_io); + DCE_CHECK(esp_modem_dce_get_imsi_number(&(esp_modem_dce->parent)) == ESP_OK, "get imsi failed", err_io); /* Get operator name */ - DCE_CHECK(sim800_get_operator_name(&(sim800_dce->parent)) == ESP_OK, "get operator name failed", err_io); - return &(sim800_dce->parent); + DCE_CHECK(esp_modem_dce_get_operator_name(&(esp_modem_dce->parent)) == ESP_OK, "get operator name failed", err_io); + return &(esp_modem_dce->parent); err_io: - free(sim800_dce); + free(esp_modem_dce); err: return NULL; }