Przeglądaj źródła

Merge branch 'feature/refactor_pppos_modem' into 'master'

pppos-client: Refactor modem component

Closes IDFGH-4671

See merge request espressif/esp-idf!12313
David Čermák 4 lat temu
rodzic
commit
138ab8a3af

+ 0 - 1
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)

+ 0 - 1
examples/protocols/pppos_client/components/modem/component.mk

@@ -1,3 +1,2 @@
 COMPONENT_ADD_INCLUDEDIRS := include
-COMPONENT_PRIV_INCLUDEDIRS := private_include
 COMPONENT_SRCDIRS := src

+ 10 - 0
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

+ 157 - 4
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

+ 0 - 37
examples/protocols/pppos_client/components/modem/private_include/bg96_private.h

@@ -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;

+ 43 - 337
examples/protocols/pppos_client/components/modem/src/bg96.c

@@ -14,188 +14,26 @@
 #include <stdlib.h>
 #include <string.h>
 #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
- */
-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: <rssi>,<ber> */
-        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: <bcs>,<bcl>,<voltage> */
-        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
+ * @brief Macro defined for error checking
+ *
  */
-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: <mode>[, <format>[, <oper>[, <Act>]]] */
-        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;
 }

+ 0 - 5
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;

+ 232 - 1
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: <rssi>,<ber> */
+        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: <bcs>,<bcl>,<voltage> */
+        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: <mode>[, <format>[, <oper>[, <Act>]]] */
+        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;

+ 19 - 5
examples/protocols/pppos_client/components/modem/src/sim7600.c

@@ -14,8 +14,8 @@
 #include <stdlib.h>
 #include <string.h>
 #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: <voltage in Volts> 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);

+ 40 - 356
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: <rssi>,<ber> */
-        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: <bcs>,<bcl>,<voltage> */
-        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: <mode>[, <format>[, <oper>[, <Act>]]] */
-        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
  */
@@ -232,51 +48,20 @@ static esp_err_t sim800_handle_power_down(modem_dce_t *dce, const char *line)
 }
 
 /**
- * @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
+ * @brief Power down
  *
- * @param dce Modem DCE object
- * @param bcs Battery charge status
- * @param bcl Battery connection level
- * @param voltage Battery voltage
+ * @param sim800_dce sim800 object
  * @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)
+static esp_err_t sim800_power_down(modem_dce_t *dce)
 {
     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");
+    dce->handle_line = sim800_handle_power_down;
+    DCE_CHECK(dte->send_cmd(dte, "AT+CPOWD=1\r", MODEM_COMMAND_TIMEOUT_POWEROFF) == ESP_OK, "send command failed", err);
+    DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "power down failed", err);
+    ESP_LOGD(DCE_TAG, "power down ok");
     return ESP_OK;
 err:
     return ESP_FAIL;
@@ -296,7 +81,7 @@ 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;
+        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.
@@ -312,13 +97,13 @@ static esp_err_t sim800_set_working_mode(modem_dce_t *dce, modem_mode_t mode)
         dce->mode = MODEM_COMMAND_MODE;
         break;
     case MODEM_PPP_MODE:
-        dce->handle_line = sim800_handle_atd_ppp;
+        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 = sim800_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,107 +120,6 @@ err:
     return ESP_FAIL;
 }
 
-/**
- * @brief Power down
- *
- * @param sim800_dce sim800 object
- * @return esp_err_t
- *      - ESP_OK on success
- *      - ESP_FAIL on error
- */
-static esp_err_t sim800_power_down(modem_dce_t *dce)
-{
-    modem_dte_t *dte = dce->dte;
-    dce->handle_line = sim800_handle_power_down;
-    DCE_CHECK(dte->send_cmd(dte, "AT+CPOWD=1\r", MODEM_COMMAND_TIMEOUT_POWEROFF) == ESP_OK, "send command failed", err);
-    DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "power down failed", err);
-    ESP_LOGD(DCE_TAG, "power down ok");
-    return ESP_OK;
-err:
-    return ESP_FAIL;
-}
-
-/**
- * @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
- *
- * @param dce Modem DCE object
- * @return esp_err_t
- *      - ESP_OK on success
- *      - ESP_FAIL on error
- */
-static esp_err_t sim800_get_operator_name(modem_dce_t *dce)
-{
-    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");
-    return ESP_OK;
-err:
-    return ESP_FAIL;
-}
-
 /**
  * @brief Deinitialize SIM800 object
  *
@@ -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;
 }