From be01eb8a87f1582b1c15ec4e09a9a66770da87c5 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Mon, 26 Oct 2015 14:58:43 -0500 Subject: feat: sms support for CE910-DUAL, DE910-DUAL, LE910-SVG - PDU is used for everything except LE910-SVG sending - a bug in radio requires radio reboot to send more than 1 PDU sms --- src/atcmd.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 167 insertions(+), 10 deletions(-) (limited to 'src/atcmd.c') diff --git a/src/atcmd.c b/src/atcmd.c index aad15e9..578554f 100644 --- a/src/atcmd.c +++ b/src/atcmd.c @@ -674,6 +674,51 @@ int atcmd_plus_cmgw_write(int fd, const char *msg, size_t msg_len) return mem_index; } +int atcmd_plus_cmgw_write_text(int fd, const char *addr, int addr_type, + const char *status, const char *msg, size_t msg_len) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + int mem_index; + + atcmd_printf(fd, "AT+CMGW"); + if (addr) { + atcmd_printf(fd, "=\"%s\"", addr); + if (addr_type != SMS_ADDR_UNSPEC) { + atcmd_printf(fd, ",%d", addr_type); + if (status) { + atcmd_printf(fd, ",\"%s\"", status); + } + } + } + atcmd_write_str(fd, ATCMD_EOL); + + tmp = atcmd_read_until(fd, buf, sizeof(buf), "> "); + if (tmp <= 0) { + log_debug("expected > start sequence but it was not received"); + return -1; + } + + tmp = atcmd_write(fd, msg, strlen(msg)); + tmp = atcmd_write_str(fd, CONTROL_Z_STR); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CMGW: "); + if (tmp <= 0) { + log_debug("expected +CMGW: but it was not received"); + return -1; + } + + mem_index = atoi(buf + strlen("+CMGW: ")); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return mem_index; +} + int atcmd_plus_cmgs_write(int fd, const char *msg, size_t msg_len) { char buf[ATCMD_LINE_SIZE]; @@ -706,6 +751,38 @@ int atcmd_plus_cmgs_write(int fd, const char *msg, size_t msg_len) return msg_ref; } +int atcmd_plus_cmgs_write_text(int fd, const char *addr, const char *msg, size_t msg_len) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + int msg_ref; + + atcmd_writeline(fd, "AT+CMGS=\"%s\"", addr); + tmp = atcmd_read_until(fd, buf, sizeof(buf), "> "); + if (tmp <= 0) { + log_debug("expected > start sequence but it was not received"); + return -1; + } + + tmp = atcmd_write(fd, msg, strlen(msg)); + tmp = atcmd_write_str(fd, CONTROL_Z_STR); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CMGS: "); + if (tmp <= 0) { + log_debug("expected +CMGS: but it was not received"); + return -1; + } + msg_ref = atoi(buf + strlen("+CMGS: ")); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return msg_ref; +} + int atcmd_plus_cmss_write(int fd, int index, const char *addr, int addr_type) { char buf[ATCMD_LINE_SIZE]; @@ -774,16 +851,24 @@ int atcmd_response_foreach_line(int fd, atcmd_response_callback_t call, void *pr } int atcmd_plus_cpms_read(int fd, struct data_store *read_store, - struct data_store *send_store, struct data_store *new_store) + struct data_store *send_store, struct data_store *new_store, const char *model) { char buf[ATCMD_LINE_SIZE]; char *save; char *token; int tmp; int i; + int data_stores_size; - struct data_store *data_stores[] = {read_store, send_store, new_store}; struct data_store *store; + struct data_store *data_stores[] = {read_store, send_store, new_store}; + + if (isCdmaTypeModel()) { + data_stores_size = 2; + } + else { + data_stores_size = 3; + } atcmd_writeline(fd, "AT+CPMS?"); tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CPMS: "); @@ -799,7 +884,7 @@ int atcmd_plus_cpms_read(int fd, struct data_store *read_store, return -1; } - for (i = 0; i < ARRAY_SIZE(data_stores); i++) { + for (i = 0; i < data_stores_size; i++) { store = data_stores[i]; token = atcmd_value_tok(&save); @@ -844,7 +929,7 @@ int atcmd_plus_cpms_test(int fd, struct store_locations *read_loc, int tmp; int i, j; - struct store_locations *locations[] = {read_loc, send_loc, new_loc}; + struct store_locations *locations[] = {read_loc, send_loc, new_loc}; struct store_locations *loc; atcmd_writeline(fd, "AT+CPMS=?"); @@ -901,13 +986,19 @@ int atcmd_plus_cpms_test(int fd, struct store_locations *read_loc, } int atcmd_plus_cpms_write(int fd, const char *read_name, - const char *send_name, const char *new_name) + const char *send_name, const char *new_name, const char *model) { char buf[ATCMD_LINE_SIZE]; int tmp; - atcmd_writeline(fd, "AT+CPMS=\"%s\",\"%s\",\"%s\"", - read_name, send_name, new_name); + if (isCdmaTypeModel()) { + atcmd_writeline(fd, "AT+CPMS=\"%s\",\"%s\"", read_name, send_name); + } + else + { + atcmd_writeline(fd, "AT+CPMS=\"%s\",\"%s\",\"%s\"", + read_name, send_name, new_name); + } tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); if (tmp <= 0) { log_debug("expected OK but it was not received"); @@ -1110,6 +1201,48 @@ int atcmd_plus_cpbr_test(int fd, struct phonebook_store *store) return 0; } +int atcmd_plus_gmm_read(int fd) +{ + char buf[ATCMD_LINE_SIZE]; + char *save; + char *token; + int tmp; + + atcmd_writeline(fd, "AT+GMM"); + //Swallow extra "\r\n" + tmp = atcmd_readline(fd, buf, sizeof(buf)); + if (tmp <= 0) { + log_debug("expected \\r\\n but it was not received"); + return -1; + } + + //Read model string + tmp = atcmd_readline(fd, buf, sizeof(buf)); + if (tmp <= 0) { + log_debug("expected model but it was not received"); + return -1; + } + + save = buf; + token = atcmd_value_tok(&save); + if (!token) { + log_debug("atcmd_value_tok model"); + return -1; + } + free(Global.core.model); + Global.core.model = strdup(token); + + log_debug("model: %s", Global.core.model); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + int atcmd_init(int fd, int read_timeout) { int tmp; @@ -1158,6 +1291,12 @@ static int sms_atcmd_init(int fd) return -1; } + tmp = atcmd_plus_gmm_read(fd); + if (tmp < 0) { + log_error("failed to read radio model"); + return -1; + } + tmp = atcmd_plus_cmgf_write(fd, SMS_PDU_MODE); if (tmp < 0) { return -1; @@ -1167,10 +1306,18 @@ static int sms_atcmd_init(int fd) memset(&send_store, 0, sizeof(send_store)); memset(&new_store, 0, sizeof(new_store)); + if (!strcmp(Global.core.model, "CE910-DUAL") || !strcmp(Global.core.model, "DE910-DUAL")) { + log_info("Changing message storage locations to ME for CE/DE910-DUAL"); + free(Global.core.msg_store_read); + free(Global.core.msg_store_send); + Global.core.msg_store_read = strdup("ME"); + Global.core.msg_store_send = strdup("ME"); + } + atcmd_plus_cpms_test(fd, &read_store.choices, &send_store.choices, &new_store.choices); atcmd_plus_cpms_read(fd, &read_store.selected, - &send_store.selected, &new_store.selected); + &send_store.selected, &new_store.selected, Global.core.model); if (Global.core.msg_store_read && Global.core.msg_store_send && Global.core.msg_store_new) { @@ -1184,14 +1331,16 @@ static int sms_atcmd_init(int fd) Global.core.msg_store_send); return -1; } - if (!msg_store_choice(&new_store, Global.core.msg_store_new)) { + + //Doesn't apply to CDMA type radios + if (!isCdmaTypeModel() && !msg_store_choice(&new_store, Global.core.msg_store_new)) { log_error("message storage location %s is not a choice", Global.core.msg_store_new); return -1; } tmp = atcmd_plus_cpms_write(fd, Global.core.msg_store_read, - Global.core.msg_store_send, Global.core.msg_store_new); + Global.core.msg_store_send, Global.core.msg_store_new, Global.core.model); if (tmp < 0) { return -1; } @@ -1255,3 +1404,11 @@ int sms_device_open(void) return fd; } + +int isCdmaTypeModel() +{ + return (!strcmp(Global.core.model, "LE910-SVG") || + !strcmp(Global.core.model, "DE910-DUAL") || + !strcmp(Global.core.model, "CE910-DUAL")); +} + -- cgit v1.2.3