Move commun methods in DCE and align few methods

Signed-off-by: Jonathan Dreyer <jonathan.dreyer@cleanenergie.ch>
Signed-off-by: Liu Han <liuhan@espressif.com>
This commit is contained in:
Jonathan Dreyer
2021-01-30 23:28:18 +01:00
committed by bot
parent dcb8857e72
commit ea1df995f8
4 changed files with 448 additions and 672 deletions

View File

@@ -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); esp_err_t esp_modem_dce_handle_response_default(modem_dce_t *dce, const char *line);
/**
* @brief Handle response from AT+CSQ
*
* @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
*
* @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 +++
*
* @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#
*
* @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
*
* @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
*
* @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
*
* @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?
*
* @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 * @brief Syncronization
* *
@@ -116,6 +204,71 @@ 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); esp_err_t esp_modem_dce_define_pdp_context(modem_dce_t *dce, uint32_t cid, const char *type, const char *apn);
/**
* @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
*/
esp_err_t esp_modem_dce_get_signal_quality(modem_dce_t *dce, uint32_t *rssi, uint32_t *ber);
/**
* @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
*/
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
*
* @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
*
* @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
*
* @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
*
* @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 * @brief Hang up
* *

View File

@@ -21,182 +21,6 @@
static const char *DCE_TAG = "bg96"; 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
*/
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;
}
/** /**
* @brief Handle response from AT+QPOWD=1 * @brief Handle response from AT+QPOWD=1
*/ */
@@ -211,57 +35,6 @@ static esp_err_t bg96_handle_power_down(modem_dce_t *dce, const char *line)
return err; 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 * @brief Set Working Mode
* *
@@ -277,7 +50,7 @@ static esp_err_t bg96_set_working_mode(modem_dce_t *dce, modem_mode_t mode)
switch (mode) { switch (mode) {
case MODEM_COMMAND_MODE: case MODEM_COMMAND_MODE:
vTaskDelay(pdMS_TO_TICKS(1000)); // spec: 1s delay for the modem to recognize the escape sequence 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) { if (dte->send_cmd(dte, "+++", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) != ESP_OK) {
// "+++" Could fail if we are already in the command mode. // "+++" Could fail if we are already in the command mode.
// in that case we ignore the timeout and re-sync the modem // in that case we ignore the timeout and re-sync the modem
@@ -292,13 +65,13 @@ static esp_err_t bg96_set_working_mode(modem_dce_t *dce, modem_mode_t mode)
dce->mode = MODEM_COMMAND_MODE; dce->mode = MODEM_COMMAND_MODE;
break; break;
case MODEM_PPP_MODE: 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); 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) { if (dce->state != MODEM_STATE_SUCCESS) {
// Initiate PPP mode could fail, if we've already "dialed" the data call before. // 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 // in that case we retry with "ATO" to just resume the data mode
ESP_LOGD(DCE_TAG, "enter ppp mode failed, retry with ATO"); 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(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); DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter ppp mode failed", err);
} }
@@ -335,87 +108,6 @@ err:
return ESP_FAIL; 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 * @brief Deinitialize BG96 object
* *
@@ -451,9 +143,9 @@ modem_dce_t *bg96_init(modem_dte_t *dte)
bg96_dce->parent.set_flow_ctrl = esp_modem_dce_set_flow_ctrl; 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.define_pdp_context = esp_modem_dce_define_pdp_context;
bg96_dce->parent.hang_up = esp_modem_dce_hang_up; bg96_dce->parent.hang_up = esp_modem_dce_hang_up;
bg96_dce->parent.get_signal_quality = bg96_get_signal_quality; bg96_dce->parent.get_signal_quality = esp_modem_dce_get_signal_quality;
bg96_dce->parent.get_battery_status = bg96_get_battery_status; bg96_dce->parent.get_battery_status = esp_modem_dce_get_battery_status;
bg96_dce->parent.get_operator_name = bg96_get_operator_name; bg96_dce->parent.get_operator_name = esp_modem_dce_get_operator_name;
bg96_dce->parent.set_working_mode = bg96_set_working_mode; bg96_dce->parent.set_working_mode = bg96_set_working_mode;
bg96_dce->parent.power_down = bg96_power_down; bg96_dce->parent.power_down = bg96_power_down;
bg96_dce->parent.deinit = bg96_deinit; bg96_dce->parent.deinit = bg96_deinit;
@@ -462,13 +154,13 @@ modem_dce_t *bg96_init(modem_dte_t *dte)
/* Close echo */ /* 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(&(bg96_dce->parent), false) == ESP_OK, "close echo mode failed", err_io);
/* Get Module name */ /* 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(&(bg96_dce->parent)) == ESP_OK, "get module name failed", err_io);
/* Get IMEI number */ /* 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(&(bg96_dce->parent)) == ESP_OK, "get imei failed", err_io);
/* Get IMSI number */ /* 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(&(bg96_dce->parent)) == ESP_OK, "get imsi failed", err_io);
/* Get operator name */ /* Get operator name */
DCE_CHECK(bg96_get_operator_name(&(bg96_dce->parent)) == ESP_OK, "get operator name failed", err_io); DCE_CHECK(esp_modem_dce_get_operator_name(&(bg96_dce->parent)) == ESP_OK, "get operator name failed", err_io);
return &(bg96_dce->parent); return &(bg96_dce->parent);
err_io: err_io:
free(bg96_dce); free(bg96_dce);

View File

@@ -30,6 +30,15 @@ static const char *DCE_TAG = "dce_service";
} \ } \
} while (0) } while (0)
/**
* @brief ESP Modem
*
*/
typedef struct {
void *priv_resource; /*!< Private resource */
modem_dce_t parent; /*!< DCE parent class */
} esp_modem_dce_t;
esp_err_t esp_modem_dce_handle_response_default(modem_dce_t *dce, const char *line) esp_err_t esp_modem_dce_handle_response_default(modem_dce_t *dce, const char *line)
{ {
esp_err_t err = ESP_FAIL; esp_err_t err = ESP_FAIL;
@@ -41,6 +50,158 @@ esp_err_t esp_modem_dce_handle_response_default(modem_dce_t *dce, const char *li
return err; 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) esp_err_t esp_modem_dce_sync(modem_dce_t *dce)
{ {
modem_dte_t *dte = dce->dte; modem_dte_t *dte = dce->dte;
@@ -113,6 +274,84 @@ err:
return ESP_FAIL; 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) esp_err_t esp_modem_dce_hang_up(modem_dce_t *dce)
{ {
modem_dte_t *dte = dce->dte; modem_dte_t *dte = dce->dte;

View File

@@ -43,182 +43,6 @@ typedef struct {
modem_dce_t parent; /*!< DCE parent class */ modem_dce_t parent; /*!< DCE parent class */
} sim800_modem_dce_t; } 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 * @brief Handle response from AT+CPOWD=1
*/ */
@@ -231,110 +55,6 @@ static esp_err_t sim800_handle_power_down(modem_dce_t *dce, const char *line)
return err; 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 * @brief Power down
* *
@@ -356,81 +76,53 @@ err:
} }
/** /**
* @brief Get DCE module name * @brief Set Working Mode
*
* @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 * @param dce Modem DCE object
* @param mode woking mode
* @return esp_err_t * @return esp_err_t
* - ESP_OK on success * - ESP_OK on success
* - ESP_FAIL on error * - 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; modem_dte_t *dte = dce->dte;
sim800_modem_dce_t *sim800_dce = __containerof(dce, sim800_modem_dce_t, parent); switch (mode) {
sim800_dce->parent.handle_line = sim800_handle_cops; case MODEM_COMMAND_MODE:
DCE_CHECK(dte->send_cmd(dte, "AT+COPS?\r", MODEM_COMMAND_TIMEOUT_OPERATOR) == ESP_OK, "send command failed", err); dce->handle_line = esp_modem_dce_handle_exit_data_mode;
DCE_CHECK(sim800_dce->parent.state == MODEM_STATE_SUCCESS, "get network operator failed", err); vTaskDelay(pdMS_TO_TICKS(1000)); // spec: 1s delay for the modem to recognize the escape sequence
ESP_LOGD(DCE_TAG, "get network operator ok"); 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; return ESP_OK;
err: err:
return ESP_FAIL; return ESP_FAIL;
@@ -471,9 +163,9 @@ modem_dce_t *sim800_init(modem_dte_t *dte)
sim800_dce->parent.set_flow_ctrl = esp_modem_dce_set_flow_ctrl; 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.define_pdp_context = esp_modem_dce_define_pdp_context;
sim800_dce->parent.hang_up = esp_modem_dce_hang_up; sim800_dce->parent.hang_up = esp_modem_dce_hang_up;
sim800_dce->parent.get_signal_quality = sim800_get_signal_quality; sim800_dce->parent.get_signal_quality = esp_modem_dce_get_signal_quality;
sim800_dce->parent.get_battery_status = sim800_get_battery_status; sim800_dce->parent.get_battery_status = esp_modem_dce_get_battery_status;
sim800_dce->parent.get_operator_name = sim800_get_operator_name; sim800_dce->parent.get_operator_name = esp_modem_dce_get_operator_name;
sim800_dce->parent.set_working_mode = sim800_set_working_mode; sim800_dce->parent.set_working_mode = sim800_set_working_mode;
sim800_dce->parent.power_down = sim800_power_down; sim800_dce->parent.power_down = sim800_power_down;
sim800_dce->parent.deinit = sim800_deinit; sim800_dce->parent.deinit = sim800_deinit;
@@ -482,13 +174,13 @@ modem_dce_t *sim800_init(modem_dte_t *dte)
/* Close echo */ /* 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(&(sim800_dce->parent), false) == ESP_OK, "close echo mode failed", err_io);
/* Get Module name */ /* 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(&(sim800_dce->parent)) == ESP_OK, "get module name failed", err_io);
/* Get IMEI number */ /* 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(&(sim800_dce->parent)) == ESP_OK, "get imei failed", err_io);
/* Get IMSI number */ /* 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(&(sim800_dce->parent)) == ESP_OK, "get imsi failed", err_io);
/* Get operator name */ /* Get operator name */
DCE_CHECK(sim800_get_operator_name(&(sim800_dce->parent)) == ESP_OK, "get operator name failed", err_io); DCE_CHECK(esp_modem_dce_get_operator_name(&(sim800_dce->parent)) == ESP_OK, "get operator name failed", err_io);
return &(sim800_dce->parent); return &(sim800_dce->parent);
err_io: err_io:
free(sim800_dce); free(sim800_dce);