summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/atcmd.c227
-rw-r--r--src/atcmd.h8
-rw-r--r--src/global.h7
-rw-r--r--src/pdu_decode.c878
-rw-r--r--src/pdu_encode.c780
-rw-r--r--src/phonebook.c2
-rw-r--r--src/sms_delete.c4
-rw-r--r--src/sms_list.c20
-rw-r--r--src/sms_send.c74
-rw-r--r--src/utils.c16
10 files changed, 1057 insertions, 959 deletions
diff --git a/src/atcmd.c b/src/atcmd.c
index b988a57..d17c03f 100644
--- a/src/atcmd.c
+++ b/src/atcmd.c
@@ -873,17 +873,17 @@ int atcmd_plus_cpms_read(int fd, struct data_store *read_store,
char *token;
int tmp;
int i;
- int data_stores_size;
+ int data_stores_size;
struct data_store *store;
- struct data_store *data_stores[] = {read_store, send_store, new_store};
+ struct data_store *data_stores[] = {read_store, send_store, new_store};
- if (isCdmaTypeModel()) {
- data_stores_size = 2;
- }
- else {
- data_stores_size = 3;
- }
+ if (is_telit_3gpp2_format()) {
+ data_stores_size = 2;
+ }
+ else {
+ data_stores_size = 3;
+ }
atcmd_writeline(fd, "AT+CPMS?");
tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CPMS: ");
@@ -944,7 +944,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=?");
@@ -1006,14 +1006,14 @@ int atcmd_plus_cpms_write(int fd, const char *read_name,
char buf[ATCMD_LINE_SIZE];
int tmp;
- 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);
- }
+ if (is_telit_3gpp2_format()) {
+ 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");
@@ -1224,15 +1224,15 @@ int atcmd_plus_gmm_read(int fd)
int tmp;
atcmd_writeline(fd, "AT+GMM");
- //Swallow extra "\r\n"
- tmp = atcmd_readline(fd, buf, sizeof(buf));
+ //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));
+ //Read model string
+ tmp = atcmd_readline(fd, buf, sizeof(buf));
if (tmp <= 0) {
log_debug("expected model but it was not received");
return -1;
@@ -1300,7 +1300,7 @@ int atcmd_plus_gmi_read(int fd)
return 0;
}
-/* ICCID needed for LNA3 to determine carrier */
+/* ICCID needed to detect Verizon on multi-carrier radios */
int atcmd_plus_iccid_read(int fd)
{
char buf[ATCMD_LINE_SIZE];
@@ -1313,7 +1313,7 @@ int atcmd_plus_iccid_read(int fd)
if (is_telit_model()) {
command = "AT#CCID";
if (strstr(Global.core.model, "FN980")) {
- command = "AT+ICCID";
+ command = "AT+ICCID";
}
} else if (is_quectel_model()) {
command = "AT+QCCID";
@@ -1323,18 +1323,18 @@ int atcmd_plus_iccid_read(int fd)
}
atcmd_writeline(fd, command);
- //Swallow extra "\r\n"
- tmp = atcmd_readline(fd, buf, sizeof(buf));
+ //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 iccid string
- tmp = atcmd_readline(fd, buf, sizeof(buf));
+ //Read iccid string
+ tmp = atcmd_readline(fd, buf, sizeof(buf));
if (tmp <= 0) {
log_debug("expected ICCID but it was not received");
- /* Currently only LNA3 models will need the ICCID */
+ /* Currently only LNA3 models will need the ICCID */
return -1;
}
@@ -1342,12 +1342,12 @@ int atcmd_plus_iccid_read(int fd)
log_debug("buf=%s for %d", buf,strlen(buf));
token = atcmd_value_tok(&save);
if (!token) {
- log_debug("atcmd_value_tok model");
+ log_debug("atcmd_value_tok iccid");
return -1;
} else {
log_debug("token is %s",token);
}
- tmp_buf = strrchr(token,' ');
+ tmp_buf = strrchr(token,' ');
if (tmp_buf) {
token = ++tmp_buf;
log_debug("Found blank, incrementing tmp");
@@ -1371,6 +1371,65 @@ int atcmd_plus_iccid_read(int fd)
return 0;
}
+/* IMSI needed to detect Verizon when the ICCID is unrecognized */
+int atcmd_plus_imsi_read(int fd)
+{
+ char buf[ATCMD_LINE_SIZE];
+ char *save;
+ char *token;
+ int tmp;
+ char *tmp_buf;
+ char* command = "AT+CIMI";
+
+ atcmd_writeline(fd, command);
+ //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 imsi string
+ tmp = atcmd_readline(fd, buf, sizeof(buf));
+ if (tmp <= 0) {
+ log_debug("expected IMSI but it was not received");
+ /* Currently only LNA7/LNA7D/L4G1 models will need the IMSI */
+ return -1;
+ }
+
+ save = buf;
+ log_debug("buf=%s for %d", buf,strlen(buf));
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("atcmd_value_tok imsi");
+ return -1;
+ } else {
+ log_debug("token is %s",token);
+ }
+ tmp_buf = strrchr(token,' ');
+ if (tmp_buf) {
+ token = ++tmp_buf;
+ log_debug("Found blank, incrementing tmp");
+ } else {
+ tmp_buf = strrchr(token,'\t');
+ log_debug("Found tab, incrementing tmp");
+ if(tmp_buf)
+ token = ++tmp_buf;
+ }
+ log_debug("token[0]=%2.2x token[1]=%2.2x",token[0],token[1]);
+ strncpy(Global.core.imsi, token, IMSI_LEN);
+
+ log_debug("imsi: %s", Global.core.imsi);
+
+ 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;
@@ -1421,19 +1480,25 @@ static int sms_atcmd_init(int fd)
tmp = atcmd_plus_gmm_read(fd);
if (tmp < 0) {
- log_error("failed to read radio model");
+ log_error("failed to read radio model");
return -1;
}
tmp = atcmd_plus_gmi_read(fd);
if (tmp < 0) {
- log_error("failed to read radio manufacturer");
+ log_error("failed to read radio manufacturer");
+ return -1;
+ }
+
+ tmp = atcmd_plus_iccid_read(fd);
+ if (tmp < 0) {
+ log_error("failed to read SIM ICCID");
return -1;
}
- tmp = atcmd_plus_iccid_read(fd);
+ tmp = atcmd_plus_imsi_read(fd);
if (tmp < 0) {
- log_error("failed to read SIM ICCID");
+ log_error("failed to read SIM IMSI");
return -1;
}
@@ -1446,22 +1511,22 @@ 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);
- free(Global.core.pb_store);
- Global.core.msg_store_read = strdup("ME");
- Global.core.msg_store_send = strdup("ME");
- Global.core.pb_store = strdup("ME");
- }
+ 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);
+ free(Global.core.pb_store);
+ Global.core.msg_store_read = strdup("ME");
+ Global.core.msg_store_send = strdup("ME");
+ Global.core.pb_store = 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, Global.core.model);
if (Global.core.msg_store_read && Global.core.msg_store_send &&
- Global.core.msg_store_new) {
+ Global.core.msg_store_new) {
if (!msg_store_choice(&read_store, Global.core.msg_store_read)) {
log_error("message storage location %s is not a choice",
@@ -1474,8 +1539,8 @@ static int sms_atcmd_init(int fd)
return -1;
}
- //Doesn't apply to CDMA type radios
- if (!isCdmaTypeModel() && !msg_store_choice(&new_store, Global.core.msg_store_new)) {
+ //Doesn't apply to CDMA type radios
+ if (!is_telit_3gpp2_format() && !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;
@@ -1543,45 +1608,71 @@ int sms_device_open(void)
return fd;
}
-int is_vzw_lte(void)
+/* Detect Telit LTE radios that use the 3GPP2 SMS format for Verizon */
+int is_telit_lte_vzw_3gpp2_format(void)
{
- if (!strcmp(Global.core.model, "LE910-NA1")) {
- log_debug("Found LE910-NA1");
- /* Verizon Wireless SIM */
- if (strncmp(Global.core.iccid,"891480",6) == 0) {
- log_debug("Found VZW SIM");
- return 1;
- }
- }
-
- return (!strncmp(Global.core.model, "LE910-SVG", MODEL_LEN) ||
- !strncmp(Global.core.model, "LE910-SV1", MODEL_LEN));
+ if (!strcmp(Global.core.model, "LE910-NA1")) {
+ log_debug("Found LE910-NA1");
+ /* Verizon Wireless SIM */
+ if (strncmp(Global.core.iccid,"891480",6) == 0) {
+ log_debug("Found VZW SIM");
+ return 1;
+ }
+ }
+
+ return (!strncmp(Global.core.model, "LE910-SVG", MODEL_LEN) ||
+ !strncmp(Global.core.model, "LE910-SV1", MODEL_LEN));
}
-/* Detect LNA7/L4G1 radio with Verizon SIM */
-int is_quectel_dual_sms_format(void)
+/* Detect LNA7/LNA7D/L4G1 radios with Verizon SIM that support both 3GPP and 3GPP2 */
+int is_quectel_dual_format(void)
{
if (!strncmp(Global.core.model, "EG95", MODEL_LEN) ||
!strncmp(Global.core.model, "EG25", MODEL_LEN))
{
log_debug("Found Quectel radio with dual SMS format support");
- /* Verizon Wireless SIM */
+
+ /* Verizon Wireless SIM ICCID */
if (strncmp(Global.core.iccid,"891480",6) == 0) {
- log_debug("Found VZW SIM");
+ log_debug("Found VZW SIM by ICCID");
return 1;
}
+
+ /* Extract PLMN ID - the first 5 or 6 digits of IMSI.
+ Assume 6 digits for Verizon.
+ NOTE: Other carriers may use shorter codes */
+ char plmn_id_str[PLMN_ID_SIZE_VZW] = {0};
+ strncpy(plmn_id_str, Global.core.imsi, PLMN_ID_LEN_VZW);
+
+ /* Parse as integer for easier comparison */
+ int plmn_id_num = atoi(plmn_id_str);
+
+ /* Verizon Wireless SIM MCC/MNC */
+ switch (plmn_id_num) {
+ case 310590:
+ case 310890:
+ case 311270:
+ case 311480:
+ case 312770:
+ log_debug("Found VZW SIM by IMSI");
+ return 1;
+ default:
+ /* ignore, not Verizon */
+ break;
+ };
}
return 0;
}
-int isCdmaTypeModel()
+/* Detect Telit LTE and CDMA radios that use the 3GPP2 SMS format for Verizon */
+int is_telit_3gpp2_format()
{
- /* Test for possible dual firmware model */
- if (is_vzw_lte())
- return 1;
+ /* Test for possible dual firmware model */
+ if (is_telit_lte_vzw_3gpp2_format())
+ return 1;
- return (!strncmp(Global.core.model, "DE910-DUAL", MODEL_LEN) ||
- !strncmp(Global.core.model, "CE910-DUAL", MODEL_LEN));
+ return (!strncmp(Global.core.model, "DE910-DUAL", MODEL_LEN) ||
+ !strncmp(Global.core.model, "CE910-DUAL", MODEL_LEN));
}
int is_telit_model()
diff --git a/src/atcmd.h b/src/atcmd.h
index 28bc384..bbab2d7 100644
--- a/src/atcmd.h
+++ b/src/atcmd.h
@@ -72,7 +72,7 @@ int atcmd_plus_cmgd_write(int fd, int index);
int atcmd_plus_qcfg_write(int fd, int sms_format);
-int isCdmaTypeModel();
+int is_telit_3gpp2_format();
#define STORE_NAME_LEN 2
#define STORE_NAME_SIZE (STORE_NAME_LEN + 1)
@@ -117,12 +117,14 @@ int atcmd_plus_cpbr_test(int fd, struct phonebook_store *store);
int atcmd_plus_gmm_read(int fd);
int atcmd_plus_gmi_read(int fd);
+int atcmd_plus_iccid_read(int fd);
+int atcmd_plus_imsi_read(int fd);
int atcmd_init(int fd, int read_timeout);
int sms_device_close(int fd);
int sms_device_open(void);
-int is_vzw_lte(void);
-int is_quectel_dual_sms_format(void);
+int is_telit_lte_vzw_3gpp2_format(void);
+int is_quectel_dual_format(void);
int is_telit_model(void);
int is_quectel_model(void);
diff --git a/src/global.h b/src/global.h
index a6073dd..4b83cb5 100644
--- a/src/global.h
+++ b/src/global.h
@@ -14,6 +14,10 @@
#define ICCID_LEN 23
#define ICCID_SIZE (ICCID_LEN + 1)
+#define IMSI_LEN 15
+#define IMSI_SIZE (IMSI_LEN + 1)
+#define PLMN_ID_LEN_VZW 6
+#define PLMN_ID_SIZE_VZW (PLMN_ID_LEN_VZW + 1)
#define MODEL_LEN 1023
#define MODEL_SIZE (MODEL_LEN + 1)
#define MANUFACTURER_LEN 1023
@@ -37,7 +41,8 @@ struct global_core {
char *msg_store_new;
char *pb_store;
char model[MODEL_SIZE];
- char iccid[ICCID_SIZE]; /* Needed for LNA3/Verizon */
+ char iccid[ICCID_SIZE]; /* Needed for Verizon 3GPP2 SMS format detection */
+ char imsi[IMSI_SIZE]; /* Needed for Verizon 3GPP2 SMS format detection */
char manufacturer[MANUFACTURER_SIZE]; /* Needed to pick proper manufacturer-specific commands */
char *editor;
diff --git a/src/pdu_decode.c b/src/pdu_decode.c
index 9c0ced5..9014162 100644
--- a/src/pdu_decode.c
+++ b/src/pdu_decode.c
@@ -37,134 +37,134 @@
#define DECODE_FAIL(cond, name, ret) \
do { \
- if (cond) { \
- log_error("decode failed at %s", name); \
- return ret; \
- } \
+ if (cond) { \
+ log_error("decode failed at %s", name); \
+ return ret; \
+ } \
} while (0)
int pdu_decode_timestamp(const char *pdu_str, struct tm *tm)
{
- char buf[PDU_TIMESTAMP_SIZE + 3];
- char *cp;
- int off_upper;
- int off_lower;
- int off;
+ char buf[PDU_TIMESTAMP_SIZE + 3];
+ char *cp;
+ int off_upper;
+ int off_lower;
+ int off;
- STRLEN_CHECK(pdu_str, PDU_TIMESTAMP_LEN, -1);
+ STRLEN_CHECK(pdu_str, PDU_TIMESTAMP_LEN, -1);
- memset(tm, 0, sizeof(*tm));
- memset(buf, 0, sizeof(buf));
+ memset(tm, 0, sizeof(*tm));
+ memset(buf, 0, sizeof(buf));
- strncpy(buf, pdu_str, PDU_TIMESTAMP_LEN);
- nibble_swap(buf, PDU_TIMESTAMP_LEN);
- strunpad(buf, 'F');
+ strncpy(buf, pdu_str, PDU_TIMESTAMP_LEN);
+ nibble_swap(buf, PDU_TIMESTAMP_LEN);
+ strunpad(buf, 'F');
- off_upper = hex_nibble_scan(buf + GMT_OFFSET_IDX, 1);
- off_lower = hex_nibble_scan(buf + GMT_OFFSET_IDX + 1, 1);
+ off_upper = hex_nibble_scan(buf + GMT_OFFSET_IDX, 1);
+ off_lower = hex_nibble_scan(buf + GMT_OFFSET_IDX + 1, 1);
- if (off_upper & BIT(3)) {
- off_upper &= ~BIT(3);
- buf[GMT_OFFSET_IDX] = '-';
- } else {
- buf[GMT_OFFSET_IDX] = '+';
- }
+ if (off_upper & BIT(3)) {
+ off_upper &= ~BIT(3);
+ buf[GMT_OFFSET_IDX] = '-';
+ } else {
+ buf[GMT_OFFSET_IDX] = '+';
+ }
- off = (off_upper * 10 + off_lower) * 15;
+ off = (off_upper * 10 + off_lower) * 15;
- snprintf(buf + GMT_OFFSET_IDX + 1, 5, "%02d%02d", off / 60, off % 60);
+ snprintf(buf + GMT_OFFSET_IDX + 1, 5, "%02d%02d", off / 60, off % 60);
- cp = (char *) strptime(buf, "%y%m%d%H%M%S%z", tm);
- if (!cp || *cp) {
- log_error("timestamp could not be converted to tm");
- return -1;
- }
+ cp = (char *) strptime(buf, "%y%m%d%H%M%S%z", tm);
+ if (!cp || *cp) {
+ log_error("timestamp could not be converted to tm");
+ return -1;
+ }
- return PDU_TIMESTAMP_LEN;
+ return PDU_TIMESTAMP_LEN;
}
int pdu_decode_cdma_timestamp(const char *pdu_str, struct tm *tm)
{
- char buf[PDU_CDMA_TIMESTAMP_LEN + 1];
- char *cp;
+ char buf[PDU_CDMA_TIMESTAMP_LEN + 1];
+ char *cp;
- STRLEN_CHECK(pdu_str, PDU_CDMA_TIMESTAMP_LEN, -1);
+ STRLEN_CHECK(pdu_str, PDU_CDMA_TIMESTAMP_LEN, -1);
- memset(tm, 0, sizeof(*tm));
- memset(buf, 0, sizeof(buf));
+ memset(tm, 0, sizeof(*tm));
+ memset(buf, 0, sizeof(buf));
- strncpy(buf, pdu_str, PDU_CDMA_TIMESTAMP_LEN);
+ strncpy(buf, pdu_str, PDU_CDMA_TIMESTAMP_LEN);
- cp = (char *) strptime(buf, "%y%m%d%H%M%S", tm);
- if (!cp || *cp) {
- log_error("timestamp could not be converted to tm");
- return -1;
- }
+ cp = (char *) strptime(buf, "%y%m%d%H%M%S", tm);
+ if (!cp || *cp) {
+ log_error("timestamp could not be converted to tm");
+ return -1;
+ }
- return PDU_CDMA_TIMESTAMP_LEN;
+ return PDU_CDMA_TIMESTAMP_LEN;
}
int pdu_decode_addr(const char *pdu_str, struct pdu_addr *addr, int smsc)
{
- const char *begin = pdu_str;
- int addr_len;
- int tmp;
-
- memset(addr, 0, sizeof(*addr));
-
- STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
-
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "addr-len", -1);
- pdu_str += HEX_BYTE_LEN;
- addr->len = tmp;
-
- addr_len = addr->len;
- if (smsc) {
- if (!addr_len) {
- goto done;
- }
- addr_len = addr_len * HEX_BYTE_LEN - HEX_BYTE_LEN;
- } else {
- if (addr_len & 1) {
- addr_len++;
- }
- }
-
- STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
-
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "addr-type", -1);
- pdu_str += HEX_BYTE_LEN;
- addr->type = tmp;
-
- if (addr_len < 0 || addr_len >= sizeof(addr->addr)) {
- log_error("invalid length: 0x%02X", addr_len);
- return -1;
- }
-
- log_debug("addr-len [transformed]: 0x%02X", addr_len);
- log_debug("addr-type: 0x%02X", addr->type);
-
- STRLEN_CHECK(pdu_str, addr_len, -1);
-
- strncpy(addr->addr, pdu_str, addr_len);
-
- nibble_swap(addr->addr, addr_len);
- strunpad(addr->addr, 'F');
- if(addr->type == 0x91) {//91 indicates international format of the phone number
- memmove(&addr->addr[1],addr->addr,addr_len);
- addr->addr[0]='+';
- };
- pdu_str += addr_len;
+ const char *begin = pdu_str;
+ int addr_len;
+ int tmp;
+
+ memset(addr, 0, sizeof(*addr));
+
+ STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
+
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "addr-len", -1);
+ pdu_str += HEX_BYTE_LEN;
+ addr->len = tmp;
+
+ addr_len = addr->len;
+ if (smsc) {
+ if (!addr_len) {
+ goto done;
+ }
+ addr_len = addr_len * HEX_BYTE_LEN - HEX_BYTE_LEN;
+ } else {
+ if (addr_len & 1) {
+ addr_len++;
+ }
+ }
+
+ STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
+
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "addr-type", -1);
+ pdu_str += HEX_BYTE_LEN;
+ addr->type = tmp;
+
+ if (addr_len < 0 || addr_len >= sizeof(addr->addr)) {
+ log_error("invalid length: 0x%02X", addr_len);
+ return -1;
+ }
+
+ log_debug("addr-len [transformed]: 0x%02X", addr_len);
+ log_debug("addr-type: 0x%02X", addr->type);
+
+ STRLEN_CHECK(pdu_str, addr_len, -1);
+
+ strncpy(addr->addr, pdu_str, addr_len);
+
+ nibble_swap(addr->addr, addr_len);
+ strunpad(addr->addr, 'F');
+ if (addr->type == 0x91) {//91 indicates international format of the phone number
+ memmove(&addr->addr[1],addr->addr,addr_len);
+ addr->addr[0]='+';
+ };
+ pdu_str += addr_len;
done:
- log_debug("addr: %s", addr->addr);
- log_debug("addr-len: 0x%02X", addr->len);
+ log_debug("addr: %s", addr->addr);
+ log_debug("addr-len: 0x%02X", addr->len);
- return pdu_str - begin;
+ return pdu_str - begin;
}
@@ -178,400 +178,400 @@ shiftl(buf[octet_idx(n) - 1], cycledown(n, 8)) & 0x7F
int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octets)
{
- const char *begin = pdu_str;
- int tmp;
- uint8_t octets[PDU_OCTETS_MAX + 1];
- int user_data_start_index = 0;
- int i;
-
- STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
-
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "user-data-len", -1);
- pdu_str += HEX_BYTE_LEN;
- pdu->user_data_len = tmp;
-
- if (pdu->data_coding.general.unused) {
- log_error("data coding group 0x%02X not implemented",
- pdu->data_coding.data_coding & 0xF0);
- return -1;
- }
-
-
- if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT ||
- pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT2 )
- {
- log_debug("data coding alphabet is default (7-bit)");
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI) {
- log_debug("data coding alphabet is default (7-bit) multi-part");
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
- log_debug("data coding alphabet is CDMA default (7-bit)");
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_EIGHT) {
- log_debug("data coding alphabet is eight");
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_EIGHT) {
- log_debug("data coding alphabet is CDMA eight");
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_TE) {
- log_debug("data coding alphabet is TE specific 7-bit");
- } else {
- log_debug("data coding alphabet 0x%02X not implemented",
- pdu->data_coding.general.alphabet);
- return -1;
- }
-
- // -----------------------------------------------------------------------------
- // VERIFY DATA LENGTH AND GET NUMBER OF OCTETS (ACTUAL DATA BYTES IN PDU STRING)
- // -----------------------------------------------------------------------------
- if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) ||
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT2) ||
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI)||
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_TE)) {
- if (pdu->user_data_len > PDU_UD_7BIT_MAX) {
- log_warning("pdu contains invalid user-data-len: 0x%02X",
- pdu->user_data_len);
- pdu->user_data_len = PDU_UD_7BIT_MAX;
- }
-
- //GSM 7-bit data (septets) length is encoded in PDU as number of septets
- // (which is same as user_data_len), but octets is needed for decoding loop
- *nr_octets = octets_from_septets(pdu->user_data_len);
-
- // CDMA 7-BIT ENCODING
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
- if (is_vzw_lte()) {
- // LE910-SVG stores data length as # of septets
- log_debug("counting PDU length byte as number of septets (LE910-SVG/LE910-SV1/LE910-NA1/VZW)");
- *nr_octets = octets_from_septets(pdu->user_data_len);
- }
- else {
- // Other CDMA radios store data length as # of octets
- // NOTE: CE910 send PDU needs # of septets but receive PDU is in # of octets
- log_debug("counting PDU length byte as number of octets");
- *nr_octets = pdu->user_data_len;
- pdu->user_data_len = septets_from_octets(pdu->user_data_len);
- }
-
-
- if (pdu->user_data_len > PDU_UD_7BIT_MAX) {
- log_warning("pdu contains invalid user-data-len: 0x%02X", pdu->user_data_len);
- pdu->user_data_len = PDU_UD_7BIT_MAX;
- }
-
- // GSM & CDMA 8-BIT ENCODING
- } else if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_EIGHT) ||
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_EIGHT)) {
- if (pdu->user_data_len > PDU_UD_8BIT_MAX) {
- log_warning("pdu contains invalid user-data-len: 0x%02X",
- pdu->user_data_len);
- pdu->user_data_len = PDU_UD_8BIT_MAX;
- }
-
- //Original data is octets (all 8 bits could contain data)
- //Therefore, octets = user_data_len
- *nr_octets = pdu->user_data_len;
- }
-
- STRLEN_CHECK(pdu_str, *nr_octets * 2, -1);
-
- log_debug("nr_octets: 0x%02X (encoded data length)", *nr_octets);
- log_debug("user-data-len: 0x%02X (decoded data length)", pdu->user_data_len);
-
- //Copy user data from pdu string into octets
- for (i = 0; i < *nr_octets; i++) {
- octets[i] = hex_byte_decode(pdu_str);
- pdu_str += HEX_BYTE_LEN;
- }
-
-
- // ---------------------------------------------------------
- // DECODE USER DATA (IF NEEDED) AND COPY INTO pdu->user_data
- // ---------------------------------------------------------
- // GSM 7-BIT & LVW2 7-BIT MULTI-PART
- if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) ||
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT2) ||
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI)||
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_TE)) {
- // Keep UDH for concatenated SMS ONLY.
- // Otherwise it is impossible to process correctly concatenated SMS.
- i = 0;
- if (pdu->type.user_data_header ||
- // For LVW3, LNA3 and LVW2 - Save header ONLY when it's actually a multi-part message.
- // Multi-part messages should use Teleservice ID 4101 (0x1005) in LVW2 7-BIT MULTI-PART format.
- // See 3GPP2 X.S0004-550-E for details on Teleservice ID.
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI
- && pdu->teleservice_id == PDU_TELE_ID_CDMA_WEMT)) {
- for (i = 0; i <= octets[0]; ++i) {
- pdu->user_data[i] = octets[i];
- }
- i = octets[0] + 1; // Set message text start after UDH.
- // Process octets padding for 7-bit encoding.
- if (0 != (i * 8) % 7) {
- pdu->user_data[i] = 0; // set padding data to 0;
- i++;
- }
- }
-
- user_data_start_index = i;
- for (; i < pdu->user_data_len; i++) {
- pdu->user_data[i] = decode_septet_from_octet(octets, i);
- log_debug("DECODE: i: %d octet: 0x%02X --> data: 0x%02X", i, octets[i], pdu->user_data[i]);
- }
- pdu->user_data[i] = '\0';
-
- // CDMA 7-BIT
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
- // Keep UDH for concatenated SMS.
- // Otherwise it is impossible to process correctly concatenated SMS.
- i = 0;
- if (pdu->type.user_data_header) {
- for (i = 0; i <= octets[0]; ++i) {
- pdu->user_data[i] = octets[i];
- }
- i = octets[0] + 1; // Set message text start after UDH.
- // Process octets padding for 7-bit encoding.
- if (0 != (i * 8) % 7) {
- pdu->user_data[i] = 0; // set padding data to 0;
- i++;
- }
- }
-
- for (; i < pdu->user_data_len; i++) {
- pdu->user_data[i] = decode_cdma_septet_from_octet(octets, i);
- log_debug("DECODE: i: %d octet: 0x%02X --> data: 0x%02X", i, octets[i], pdu->user_data[i]);
- }
-
- //Remove padded byte for data length of 7 characters if not LE910-SVG
- if (!is_vzw_lte() && (pdu->user_data[i-1] == 0)) {
- log_debug("Removing padded char");
- i--;
- pdu->user_data_len--;
- }
- pdu->user_data[i] = '\0';
-
- // ALL 8-BIT ENCODING
- } else {
- for (i = 0; i < pdu->user_data_len; i++) {
- pdu->user_data[i] = octets[i];
- }
- pdu->user_data[i] = '\0';
- }
-
-
- // ---------------------------------------------------------------------
- // FOR GSM 7-BIT ENCODING ONLY, DECODE FROM GSM ALPHABET TO IRA ALPHABET
- // (includes LVW2 multi-part)
- // ---------------------------------------------------------------------
- if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) ||
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT2) ||
- (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI)) {
- int read = user_data_start_index;
- int store = user_data_start_index;
-
- log_debug("Converting from GSM character set to IRA");
- for (; read < pdu->user_data_len; read++) {
- if (pdu->user_data[read] == 0x1B) {
- //Character from the extended set using the escape char (27)
- read++;
- log_debug("GSM before: 0x1B%02X | IRA after: 0x%02X", pdu->user_data[read], strExtendedTable[pdu->user_data[read]]);
- pdu->user_data[store] = strExtendedTable[pdu->user_data[read]];
- }
- else {
- log_debug("GSM before: 0x%02X | IRA after: 0x%02X", pdu->user_data[read], strGSMTable[pdu->user_data[read]]);
- pdu->user_data[store] = strGSMTable[pdu->user_data[read]];
- }
- store++;
- }
- //Update lengths
- pdu->user_data_len -= read - store;
- pdu_str -= (read - store) * HEX_BYTE_LEN;
- }
-
- return pdu_str - begin;
+ const char *begin = pdu_str;
+ int tmp;
+ uint8_t octets[PDU_OCTETS_MAX + 1];
+ int user_data_start_index = 0;
+ int i;
+
+ STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
+
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "user-data-len", -1);
+ pdu_str += HEX_BYTE_LEN;
+ pdu->user_data_len = tmp;
+
+ if (pdu->data_coding.general.unused) {
+ log_error("data coding group 0x%02X not implemented",
+ pdu->data_coding.data_coding & 0xF0);
+ return -1;
+ }
+
+
+ if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT ||
+ pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT2 )
+ {
+ log_debug("data coding alphabet is default (7-bit)");
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI) {
+ log_debug("data coding alphabet is default (7-bit) multi-part");
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
+ log_debug("data coding alphabet is CDMA default (7-bit)");
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_EIGHT) {
+ log_debug("data coding alphabet is eight");
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_EIGHT) {
+ log_debug("data coding alphabet is CDMA eight");
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_TE) {
+ log_debug("data coding alphabet is TE specific 7-bit");
+ } else {
+ log_debug("data coding alphabet 0x%02X not implemented",
+ pdu->data_coding.general.alphabet);
+ return -1;
+ }
+
+ // -----------------------------------------------------------------------------
+ // VERIFY DATA LENGTH AND GET NUMBER OF OCTETS (ACTUAL DATA BYTES IN PDU STRING)
+ // -----------------------------------------------------------------------------
+ if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) ||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT2) ||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI)||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_TE)) {
+ if (pdu->user_data_len > PDU_UD_7BIT_MAX) {
+ log_warning("pdu contains invalid user-data-len: 0x%02X",
+ pdu->user_data_len);
+ pdu->user_data_len = PDU_UD_7BIT_MAX;
+ }
+
+ //GSM 7-bit data (septets) length is encoded in PDU as number of septets
+ // (which is same as user_data_len), but octets is needed for decoding loop
+ *nr_octets = octets_from_septets(pdu->user_data_len);
+
+ // CDMA 7-BIT ENCODING
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
+ if (is_telit_lte_vzw_3gpp2_format()) {
+ // LE910-SVG stores data length as # of septets
+ log_debug("counting PDU length byte as number of septets (LE910-SVG/LE910-SV1/LE910-NA1/VZW)");
+ *nr_octets = octets_from_septets(pdu->user_data_len);
+ }
+ else {
+ // Other CDMA radios store data length as # of octets
+ // NOTE: CE910 send PDU needs # of septets but receive PDU is in # of octets
+ log_debug("counting PDU length byte as number of octets");
+ *nr_octets = pdu->user_data_len;
+ pdu->user_data_len = septets_from_octets(pdu->user_data_len);
+ }
+
+
+ if (pdu->user_data_len > PDU_UD_7BIT_MAX) {
+ log_warning("pdu contains invalid user-data-len: 0x%02X", pdu->user_data_len);
+ pdu->user_data_len = PDU_UD_7BIT_MAX;
+ }
+
+ // GSM & CDMA 8-BIT ENCODING
+ } else if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_EIGHT) ||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_EIGHT)) {
+ if (pdu->user_data_len > PDU_UD_8BIT_MAX) {
+ log_warning("pdu contains invalid user-data-len: 0x%02X",
+ pdu->user_data_len);
+ pdu->user_data_len = PDU_UD_8BIT_MAX;
+ }
+
+ //Original data is octets (all 8 bits could contain data)
+ //Therefore, octets = user_data_len
+ *nr_octets = pdu->user_data_len;
+ }
+
+ STRLEN_CHECK(pdu_str, *nr_octets * 2, -1);
+
+ log_debug("nr_octets: 0x%02X (encoded data length)", *nr_octets);
+ log_debug("user-data-len: 0x%02X (decoded data length)", pdu->user_data_len);
+
+ //Copy user data from pdu string into octets
+ for (i = 0; i < *nr_octets; i++) {
+ octets[i] = hex_byte_decode(pdu_str);
+ pdu_str += HEX_BYTE_LEN;
+ }
+
+
+ // ---------------------------------------------------------
+ // DECODE USER DATA (IF NEEDED) AND COPY INTO pdu->user_data
+ // ---------------------------------------------------------
+ // GSM 7-BIT & LVW2 7-BIT MULTI-PART
+ if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) ||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT2) ||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI)||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_TE)) {
+ // Keep UDH for concatenated SMS ONLY.
+ // Otherwise it is impossible to process correctly concatenated SMS.
+ i = 0;
+ if (pdu->type.user_data_header ||
+ // For LVW3, LNA3 and LVW2 - Save header ONLY when it's actually a multi-part message.
+ // Multi-part messages should use Teleservice ID 4101 (0x1005) in LVW2 7-BIT MULTI-PART format.
+ // See 3GPP2 X.S0004-550-E for details on Teleservice ID.
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI
+ && pdu->teleservice_id == PDU_TELE_ID_CDMA_WEMT)) {
+ for (i = 0; i <= octets[0]; ++i) {
+ pdu->user_data[i] = octets[i];
+ }
+ i = octets[0] + 1; // Set message text start after UDH.
+ // Process octets padding for 7-bit encoding.
+ if (0 != (i * 8) % 7) {
+ pdu->user_data[i] = 0; // set padding data to 0;
+ i++;
+ }
+ }
+
+ user_data_start_index = i;
+ for (; i < pdu->user_data_len; i++) {
+ pdu->user_data[i] = decode_septet_from_octet(octets, i);
+ log_debug("DECODE: i: %d octet: 0x%02X --> data: 0x%02X", i, octets[i], pdu->user_data[i]);
+ }
+ pdu->user_data[i] = '\0';
+
+ // CDMA 7-BIT
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
+ // Keep UDH for concatenated SMS.
+ // Otherwise it is impossible to process correctly concatenated SMS.
+ i = 0;
+ if (pdu->type.user_data_header) {
+ for (i = 0; i <= octets[0]; ++i) {
+ pdu->user_data[i] = octets[i];
+ }
+ i = octets[0] + 1; // Set message text start after UDH.
+ // Process octets padding for 7-bit encoding.
+ if (0 != (i * 8) % 7) {
+ pdu->user_data[i] = 0; // set padding data to 0;
+ i++;
+ }
+ }
+
+ for (; i < pdu->user_data_len; i++) {
+ pdu->user_data[i] = decode_cdma_septet_from_octet(octets, i);
+ log_debug("DECODE: i: %d octet: 0x%02X --> data: 0x%02X", i, octets[i], pdu->user_data[i]);
+ }
+
+ //Remove padded byte for data length of 7 characters if not LE910-SVG
+ if (!is_telit_lte_vzw_3gpp2_format() && (pdu->user_data[i-1] == 0)) {
+ log_debug("Removing padded char");
+ i--;
+ pdu->user_data_len--;
+ }
+ pdu->user_data[i] = '\0';
+
+ // ALL 8-BIT ENCODING
+ } else {
+ for (i = 0; i < pdu->user_data_len; i++) {
+ pdu->user_data[i] = octets[i];
+ }
+ pdu->user_data[i] = '\0';
+ }
+
+
+ // ---------------------------------------------------------------------
+ // FOR GSM 7-BIT ENCODING ONLY, DECODE FROM GSM ALPHABET TO IRA ALPHABET
+ // (includes LVW2 multi-part)
+ // ---------------------------------------------------------------------
+ if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) ||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT2) ||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI)) {
+ int read = user_data_start_index;
+ int store = user_data_start_index;
+
+ log_debug("Converting from GSM character set to IRA");
+ for (; read < pdu->user_data_len; read++) {
+ if (pdu->user_data[read] == 0x1B) {
+ //Character from the extended set using the escape char (27)
+ read++;
+ log_debug("GSM before: 0x1B%02X | IRA after: 0x%02X", pdu->user_data[read], strExtendedTable[pdu->user_data[read]]);
+ pdu->user_data[store] = strExtendedTable[pdu->user_data[read]];
+ }
+ else {
+ log_debug("GSM before: 0x%02X | IRA after: 0x%02X", pdu->user_data[read], strGSMTable[pdu->user_data[read]]);
+ pdu->user_data[store] = strGSMTable[pdu->user_data[read]];
+ }
+ store++;
+ }
+ //Update lengths
+ pdu->user_data_len -= read - store;
+ pdu_str -= (read - store) * HEX_BYTE_LEN;
+ }
+
+ return pdu_str - begin;
}
int pdu_decode(const char *pdu_str, struct pdu_info *pdu)
{
- const char *begin = pdu_str;
- const char *msg_begin;
- int tmp;
- int nr_octets;
+ const char *begin = pdu_str;
+ const char *msg_begin;
+ int tmp;
+ int nr_octets;
- memset(pdu, 0, sizeof(*pdu));
+ memset(pdu, 0, sizeof(*pdu));
- tmp = pdu_decode_addr(pdu_str, &pdu->smsc_addr, 1);
- DECODE_FAIL(tmp < 0, "smsc-addr", -1);
- pdu_str += tmp;
+ tmp = pdu_decode_addr(pdu_str, &pdu->smsc_addr, 1);
+ DECODE_FAIL(tmp < 0, "smsc-addr", -1);
+ pdu_str += tmp;
- msg_begin = pdu_str;
+ msg_begin = pdu_str;
- log_debug("smsc-addr: %s", pdu->smsc_addr.addr);
- log_debug("smsc-addr-type: 0x%02X", pdu->smsc_addr.type);
- log_debug("smsc-addr-len: 0x%02X", pdu->smsc_addr.len);
+ log_debug("smsc-addr: %s", pdu->smsc_addr.addr);
+ log_debug("smsc-addr-type: 0x%02X", pdu->smsc_addr.type);
+ log_debug("smsc-addr-len: 0x%02X", pdu->smsc_addr.len);
- STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
+ STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "type", -1);
- pdu_str += HEX_BYTE_LEN;
- pdu->type.type = tmp;
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "type", -1);
+ pdu_str += HEX_BYTE_LEN;
+ pdu->type.type = tmp;
- log_debug("type: 0x%02X", pdu->type.type);
+ log_debug("type: 0x%02X", pdu->type.type);
- if (pdu->type.msg_type == PDU_MTI_SUBMIT ||
- pdu->type.msg_type == PDU_MTI_REPORT) {
- STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
+ if (pdu->type.msg_type == PDU_MTI_SUBMIT ||
+ pdu->type.msg_type == PDU_MTI_REPORT) {
+ STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "msg-reference", -1);
- pdu_str += HEX_BYTE_LEN;
- pdu->msg_reference = tmp;
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "msg-reference", -1);
+ pdu_str += HEX_BYTE_LEN;
+ pdu->msg_reference = tmp;
- log_debug("msg-reference: 0x%02X", pdu->msg_reference);
- }
+ log_debug("msg-reference: 0x%02X", pdu->msg_reference);
+ }
- tmp = pdu_decode_addr(pdu_str, &pdu->addr, 0);
- DECODE_FAIL(tmp < 0, "addr", -1);
- pdu_str += tmp;
+ tmp = pdu_decode_addr(pdu_str, &pdu->addr, 0);
+ DECODE_FAIL(tmp < 0, "addr", -1);
+ pdu_str += tmp;
- log_debug("addr: %s", pdu->addr.addr);
- log_debug("addr-type: 0x%02X", pdu->addr.type);
- log_debug("addr-len: 0x%02X", pdu->addr.len);
+ log_debug("addr: %s", pdu->addr.addr);
+ log_debug("addr-type: 0x%02X", pdu->addr.type);
+ log_debug("addr-len: 0x%02X", pdu->addr.len);
- switch (pdu->type.msg_type) {
- case PDU_MTI_REPORT:
- tmp = pdu_decode_timestamp(pdu_str, &pdu->timestamp);
- DECODE_FAIL(tmp < 0, "report-timestamp", -1);
- pdu_str += tmp;
+ switch (pdu->type.msg_type) {
+ case PDU_MTI_REPORT:
+ tmp = pdu_decode_timestamp(pdu_str, &pdu->timestamp);
+ DECODE_FAIL(tmp < 0, "report-timestamp", -1);
+ pdu_str += tmp;
- break;
- case PDU_MTI_DELIVER:
- case PDU_MTI_SUBMIT:
- STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
+ break;
+ case PDU_MTI_DELIVER:
+ case PDU_MTI_SUBMIT:
+ STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "protocol-id", -1);
- pdu_str += HEX_BYTE_LEN;
- pdu->protocol_id = tmp;
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "protocol-id", -1);
+ pdu_str += HEX_BYTE_LEN;
+ pdu->protocol_id = tmp;
- log_debug("protocol-id: 0x%02X", pdu->protocol_id);
+ log_debug("protocol-id: 0x%02X", pdu->protocol_id);
- STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
+ STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "data-coding-scheme", -1);
- pdu_str += HEX_BYTE_LEN;
- pdu->data_coding.data_coding = tmp;
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "data-coding-scheme", -1);
+ pdu_str += HEX_BYTE_LEN;
+ pdu->data_coding.data_coding = tmp;
- log_debug("data-coding-scheme: 0x%02X", pdu->data_coding.data_coding);
+ log_debug("data-coding-scheme: 0x%02X", pdu->data_coding.data_coding);
- if (pdu->type.msg_type == PDU_MTI_SUBMIT) {
- log_debug("validity-period-format: 0x%02X",
- pdu->type.validity_period_format);
- switch (pdu->type.validity_period_format) {
- case PDU_VPF_RELATIVE:
- STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
+ if (pdu->type.msg_type == PDU_MTI_SUBMIT) {
+ log_debug("validity-period-format: 0x%02X",
+ pdu->type.validity_period_format);
+ switch (pdu->type.validity_period_format) {
+ case PDU_VPF_RELATIVE:
+ STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "validity-period", -1);
- pdu_str += HEX_BYTE_LEN;
- pdu->validity_period = tmp;
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "validity-period", -1);
+ pdu_str += HEX_BYTE_LEN;
+ pdu->validity_period = tmp;
- log_debug("validity-period: 0x%02X", pdu->validity_period);
+ log_debug("validity-period: 0x%02X", pdu->validity_period);
- break;
+ break;
- case PDU_VPF_ENHANCED:
- log_warning("PDU_VPF_ENHANCED? Falling through to absolute");
- case PDU_VPF_ABSOUTE:
- tmp = pdu_decode_timestamp(pdu_str, &pdu->timestamp);
- DECODE_FAIL(tmp < 0, "validity-period-timestamp", -1);
- pdu_str += tmp;
+ case PDU_VPF_ENHANCED:
+ log_warning("PDU_VPF_ENHANCED? Falling through to absolute");
+ case PDU_VPF_ABSOUTE:
+ tmp = pdu_decode_timestamp(pdu_str, &pdu->timestamp);
+ DECODE_FAIL(tmp < 0, "validity-period-timestamp", -1);
+ pdu_str += tmp;
- return -1;
+ return -1;
- case PDU_VPF_NOT_PRESENT:
- default:
- break;
- }
- } else if (pdu->type.msg_type == PDU_MTI_DELIVER) {
- tmp = pdu_decode_timestamp(pdu_str, &pdu->timestamp);
- DECODE_FAIL(tmp < 0, "delivery-timestamp", -1);
- pdu_str += tmp;
- }
+ case PDU_VPF_NOT_PRESENT:
+ default:
+ break;
+ }
+ } else if (pdu->type.msg_type == PDU_MTI_DELIVER) {
+ tmp = pdu_decode_timestamp(pdu_str, &pdu->timestamp);
+ DECODE_FAIL(tmp < 0, "delivery-timestamp", -1);
+ pdu_str += tmp;
+ }
- tmp = pdu_decode_user_data(pdu_str, pdu, &nr_octets);
- DECODE_FAIL(tmp < 0, "user-data", -1);
- pdu_str += tmp;
- }
+ tmp = pdu_decode_user_data(pdu_str, pdu, &nr_octets);
+ DECODE_FAIL(tmp < 0, "user-data", -1);
+ pdu_str += tmp;
+ }
- pdu->msg_len = (pdu_str - msg_begin) / 2;
+ pdu->msg_len = (pdu_str - msg_begin) / 2;
- log_debug("msg_len: %d", pdu->msg_len);
+ log_debug("msg_len: %d", pdu->msg_len);
- return pdu_str - begin;
+ return pdu_str - begin;
}
int pdu_decode_cdma(const char *pdu_str, struct pdu_info *pdu)
{
- const char *begin = pdu_str;
- const char *msg_begin;
- int tmp;
- int nr_octets;
+ const char *begin = pdu_str;
+ const char *msg_begin;
+ int tmp;
+ int nr_octets;
- memset(pdu, 0, sizeof(*pdu));
+ memset(pdu, 0, sizeof(*pdu));
- //Destination address
- tmp = pdu_decode_addr(pdu_str, &pdu->addr, 1);
- DECODE_FAIL(tmp < 0, "addr", -1);
- pdu_str += tmp;
+ //Destination address
+ tmp = pdu_decode_addr(pdu_str, &pdu->addr, 1);
+ DECODE_FAIL(tmp < 0, "addr", -1);
+ pdu_str += tmp;
- msg_begin = pdu_str;
+ msg_begin = pdu_str;
- STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
+ STRLEN_CHECK(pdu_str, HEX_BYTE_LEN, -1);
- //Timestamp
- tmp = pdu_decode_cdma_timestamp(pdu_str, &pdu->timestamp);
- DECODE_FAIL(tmp < 0, "timestamp", -1);
- pdu_str += tmp;
+ //Timestamp
+ tmp = pdu_decode_cdma_timestamp(pdu_str, &pdu->timestamp);
+ DECODE_FAIL(tmp < 0, "timestamp", -1);
+ pdu_str += tmp;
- //Teleservice ID
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "tele-id-1", -1);
- pdu_str += HEX_BYTE_LEN;
- log_debug("tele-id-1: 0x%02X", tmp);
+ //Teleservice ID
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "tele-id-1", -1);
+ pdu_str += HEX_BYTE_LEN;
+ log_debug("tele-id-1: 0x%02X", tmp);
- pdu->teleservice_id = 0;
- pdu->teleservice_id |= (tmp << 8); // save upper byte of the Teleservice ID
+ pdu->teleservice_id = 0;
+ pdu->teleservice_id |= (tmp << 8); // save upper byte of the Teleservice ID
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "tele-id-2", -1);
- pdu_str += HEX_BYTE_LEN;
- log_debug("tele-id-2: 0x%02X", tmp);
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "tele-id-2", -1);
+ pdu_str += HEX_BYTE_LEN;
+ log_debug("tele-id-2: 0x%02X", tmp);
- pdu->teleservice_id |= (tmp); // save lower byte of the Teleservice ID
- log_debug("tele-id: 0x%04X", pdu->teleservice_id);
+ pdu->teleservice_id |= (tmp); // save lower byte of the Teleservice ID
+ log_debug("tele-id: 0x%04X", pdu->teleservice_id);
- //Priority
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "priority", -1);
- pdu_str += HEX_BYTE_LEN;
- log_debug("priority: 0x%02X", tmp);
+ //Priority
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "priority", -1);
+ pdu_str += HEX_BYTE_LEN;
+ log_debug("priority: 0x%02X", tmp);
- //Data coding scheme
- tmp = hex_byte_decode(pdu_str);
- DECODE_FAIL(tmp < 0, "data-coding-scheme", -1);
- pdu_str += HEX_BYTE_LEN;
- pdu->data_coding.data_coding = tmp;
- log_debug("data-coding-scheme: 0x%02X", pdu->data_coding.data_coding);
+ //Data coding scheme
+ tmp = hex_byte_decode(pdu_str);
+ DECODE_FAIL(tmp < 0, "data-coding-scheme", -1);
+ pdu_str += HEX_BYTE_LEN;
+ pdu->data_coding.data_coding = tmp;
+ log_debug("data-coding-scheme: 0x%02X", pdu->data_coding.data_coding);
- //User Data
- tmp = pdu_decode_user_data(pdu_str, pdu, &nr_octets);
- DECODE_FAIL(tmp < 0, "user-data", -1);
- pdu_str += tmp;
+ //User Data
+ tmp = pdu_decode_user_data(pdu_str, pdu, &nr_octets);
+ DECODE_FAIL(tmp < 0, "user-data", -1);
+ pdu_str += tmp;
- pdu->msg_len = 6 + nr_octets;
+ pdu->msg_len = 6 + nr_octets;
- log_debug("msg_len: %d", pdu->msg_len);
+ log_debug("msg_len: %d", pdu->msg_len);
- return pdu_str - begin;
+ return pdu_str - begin;
}
diff --git a/src/pdu_encode.c b/src/pdu_encode.c
index f8d6160..34028a9 100644
--- a/src/pdu_encode.c
+++ b/src/pdu_encode.c
@@ -33,119 +33,119 @@
#define ENCODE_FAIL(cond, name, ret) \
do { \
- if (cond) { \
- log_error("encode failed at %s", name); \
- return ret; \
- } \
+ if (cond) { \
+ log_error("encode failed at %s", name); \
+ return ret; \
+ } \
} while (0)
#define CEIL(X) ((X-(int)(X)) > 0 ? (int)(X+1) : (int)(X))
int pdu_encode_timestamp(char *pdu_str, size_t len, struct tm *tm)
{
- int tmp;
- int off_upper;
- int off_lower;
- int off;
- int negative;
+ int tmp;
+ int off_upper;
+ int off_lower;
+ int off;
+ int negative;
- if (len < PDU_TIMESTAMP_SIZE) {
- log_error("buffer is not large enough to hold a timestamp");
- return -1;
- }
+ if (len < PDU_TIMESTAMP_SIZE) {
+ log_error("buffer is not large enough to hold a timestamp");
+ return -1;
+ }
- tmp = strftime(pdu_str, PDU_TIMESTAMP_SIZE, "%y%m%d%H%M%S", tm);
- ENCODE_FAIL(tmp != GMT_OFFSET_IDX, "timestamp", -1);
+ tmp = strftime(pdu_str, PDU_TIMESTAMP_SIZE, "%y%m%d%H%M%S", tm);
+ ENCODE_FAIL(tmp != GMT_OFFSET_IDX, "timestamp", -1);
- off = tm->tm_gmtoff;
- if (off < 0) {
- off = -off;
- negative = 1;
- }
- off = off / 60 / 15;
+ off = tm->tm_gmtoff;
+ if (off < 0) {
+ off = -off;
+ negative = 1;
+ }
+ off = off / 60 / 15;
- off_upper = off / 10;
- off_lower = off % 10;
+ off_upper = off / 10;
+ off_lower = off % 10;
- if (negative) {
- off_upper |= BIT(3);
- }
+ if (negative) {
+ off_upper |= BIT(3);
+ }
- snprintf(pdu_str + GMT_OFFSET_IDX, 2, "%X", off_upper & 0xF);
- snprintf(pdu_str + GMT_OFFSET_IDX + 1, 2, "%X", off_lower & 0xF);
+ snprintf(pdu_str + GMT_OFFSET_IDX, 2, "%X", off_upper & 0xF);
+ snprintf(pdu_str + GMT_OFFSET_IDX + 1, 2, "%X", off_lower & 0xF);
- strpad(pdu_str, PDU_TIMESTAMP_LEN, 'F');
- nibble_swap(pdu_str, PDU_TIMESTAMP_LEN);
+ strpad(pdu_str, PDU_TIMESTAMP_LEN, 'F');
+ nibble_swap(pdu_str, PDU_TIMESTAMP_LEN);
- log_debug("encode_timestamp: %s", pdu_str);
+ log_debug("encode_timestamp: %s", pdu_str);
- return PDU_TIMESTAMP_LEN;
+ return PDU_TIMESTAMP_LEN;
}
int pdu_encode_addr(char *pdu_str, size_t len, struct pdu_addr *addr, int smsc)
{
- char *begin = pdu_str;
- int addr_len;
- int tmp;
-
- if (isCdmaTypeModel()) {
- //CDMA length is # of bytes including address type
- //Ex: Type: 80 #: 9132074666 --> 80 19 23 70 64 66 => 6 bytes
- addr_len = 1; //1 byte for address type
- addr_len += CEIL(strlen(addr->addr) / 2); //Number of hex bytes
- }
- else {
- //GSM length is # of digits in converted number
- //Ex: Type: 81 #: 9132074666 --> 1923706466 => 10 digits
- addr_len = strlen(addr->addr);
- }
-
- if (smsc) {
- if (addr_len) {
- if (addr_len & 1) {
- addr_len++;
- }
- addr_len = addr_len / HEX_BYTE_LEN + 1;
- }
- }
-
- log_debug("addr-len [transformed]: 0x%02X", addr_len);
- addr->len = addr_len;
-
- tmp = hex_byte_encode(pdu_str, len, addr_len);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "addr-len", -1);
- pdu_str += tmp;
- len -= tmp;
-
- if (smsc && !addr_len) {
- log_debug("smsc addr is empty");
- goto done;
- }
-
- tmp = hex_byte_encode(pdu_str, len, addr->type);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "addr-type", -1);
- pdu_str += tmp;
- len -= tmp;
-
- addr_len = strlen(addr->addr);
- if (addr_len & 1) {
- addr_len++;
- }
-
- if (len < addr_len + 1) {
- log_error("buffer is not large enough to hold the addr");
- return -1;
- }
-
- strcpy(pdu_str, addr->addr);
- strpad(pdu_str, addr_len, 'F');
- nibble_swap(pdu_str, addr_len);
- len -= addr_len;
- pdu_str += addr_len;
+ char *begin = pdu_str;
+ int addr_len;
+ int tmp;
+
+ if (is_telit_3gpp2_format()) {
+ //CDMA length is # of bytes including address type
+ //Ex: Type: 80 #: 9132074666 --> 80 19 23 70 64 66 => 6 bytes
+ addr_len = 1; //1 byte for address type
+ addr_len += CEIL(strlen(addr->addr) / 2); //Number of hex bytes
+ }
+ else {
+ //GSM length is # of digits in converted number
+ //Ex: Type: 81 #: 9132074666 --> 1923706466 => 10 digits
+ addr_len = strlen(addr->addr);
+ }
+
+ if (smsc) {
+ if (addr_len) {
+ if (addr_len & 1) {
+ addr_len++;
+ }
+ addr_len = addr_len / HEX_BYTE_LEN + 1;
+ }
+ }
+
+ log_debug("addr-len [transformed]: 0x%02X", addr_len);
+ addr->len = addr_len;
+
+ tmp = hex_byte_encode(pdu_str, len, addr_len);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "addr-len", -1);
+ pdu_str += tmp;
+ len -= tmp;
+
+ if (smsc && !addr_len) {
+ log_debug("smsc addr is empty");
+ goto done;
+ }
+
+ tmp = hex_byte_encode(pdu_str, len, addr->type);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "addr-type", -1);
+ pdu_str += tmp;
+ len -= tmp;
+
+ addr_len = strlen(addr->addr);
+ if (addr_len & 1) {
+ addr_len++;
+ }
+
+ if (len < addr_len + 1) {
+ log_error("buffer is not large enough to hold the addr");
+ return -1;
+ }
+
+ strcpy(pdu_str, addr->addr);
+ strpad(pdu_str, addr_len, 'F');
+ nibble_swap(pdu_str, addr_len);
+ len -= addr_len;
+ pdu_str += addr_len;
done:
- return pdu_str - begin;
+ return pdu_str - begin;
}
@@ -159,312 +159,312 @@ shiftl(buf[septet_idx(n)], cycleup(n, 7) + 1) | shiftr(buf[septet_idx(n) + 1], c
int pdu_encode_user_data(char *pdu_str, size_t len, struct pdu_info *pdu, int *nr_octets)
{
- char *begin = pdu_str;
- int tmp;
- uint8_t octets[PDU_OCTETS_MAX];
- int i;
-
- if (pdu->data_coding.general.unused) {
- log_error("data coding group 0x%02X not implemented",
- pdu->data_coding.data_coding & 0xF0);
- return -1;
- }
-
- if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) {
- log_debug("data coding alphabet is default (7-bit)");
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
- log_debug("data coding alphabet is CDMA default (7-bit)");
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_EIGHT) {
- log_debug("data coding alphabet is eight");
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_EIGHT) {
- log_debug("data coding alphabet is CDMA eight");
- } else {
- log_debug("data coding alphabet 0x%02X not implemented",
- pdu->data_coding.general.alphabet);
- return -1;
- }
-
-
- // ---------------------------------------------------------------------
- // FOR GSM 7-BIT ENCODING ONLY, ENCODE FROM IRA ALPHABET TO GSM ALPHABET
- // ---------------------------------------------------------------------
- if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) {
- int read = 0;
- int store = 0;
- char initial_user_data[PDU_UD_7BIT_MAX];
-
- for (read = 0; read < pdu->user_data_len; read++) {
- initial_user_data[read] = pdu->user_data[read];
- }
- initial_user_data[read] = 0;
-
- log_debug("Converting from IRA character set to GSM");
- for (read = 0; read < pdu->user_data_len; read++) {
- int GSMchar = indexOfChar(strGSMTable, GSM_TABLE_SIZE, initial_user_data[read]);
-
- if (GSMchar >= 0) {
- log_debug("IRA before: 0x%02X | GSM after: 0x%02X", initial_user_data[read], GSMchar);
- pdu->user_data[store] = GSMchar;
- }
- else {
- //Check in extended table
- GSMchar = indexOfChar(strExtendedTable, GSM_TABLE_SIZE, initial_user_data[read]);
-
- if (GSMchar >= 0) {
- log_debug("IRA before: 0x%02X | GSM after: 0x1B%02X", initial_user_data[read], GSMchar);
- pdu->user_data[store] = 0x1B;
- store++;
- pdu->user_data[store] = GSMchar;
- }
- else {
- log_debug("IRA before: 0x%02X | Translation not found - no change", initial_user_data[read]);
- pdu->user_data[store] = initial_user_data[read];
- }
- }
-
- store++;
- }
-
- //Update lengths
- pdu->user_data_len += store - read;
- }
-
-
- // ------------------------------
- // ENCODE USER DATA INTO PDU DATA
- // ------------------------------
- // GSM 7-BIT ENCODING
- if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) {
- if (pdu->user_data_len > PDU_UD_7BIT_MAX) {
- log_error("string exceeds 7-bit data max length");
- return -1;
- }
-
- *nr_octets = octets_from_septets(pdu->user_data_len);
- for (i = 0; i < *nr_octets; i++) {
- octets[i] = encode_octet(pdu->user_data, i);
- log_debug("ENCODE: i: %d data: 0x%02X --> octet: 0x%02X", i, pdu->user_data[i], octets[i]);
- }
-
- // CDMA 7-BIT ENCODING
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
- if (pdu->user_data_len > PDU_UD_7BIT_MAX) {
- log_error("string exceeds 7-bit data max length");
- return -1;
- }
-
- *nr_octets = octets_from_septets(pdu->user_data_len);
- for (i = 0; i < *nr_octets; i++) {
- octets[i] = encode_cdma_octet(pdu->user_data, i);
- log_debug("ENCODE: i: %d data: 0x%02X --> octet: 0x%02X", i, pdu->user_data[i], octets[i]);
- }
-
- // ALL 8-BIT ENCODING
- } else {
- if (pdu->user_data_len > PDU_UD_8BIT_MAX) {
- log_error("string exceeds 8-bit data max length");
- return -1;
- }
-
- *nr_octets = pdu->user_data_len;
- for (i = 0; i < pdu->user_data_len; i++) {
- octets[i] = pdu->user_data[i];
- }
- }
-
- if (len < *nr_octets * 2 + HEX_BYTE_LEN + 1) {
- log_error("buffer is not large enough to hold user-data");
- return -1;
- }
-
- if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) &&
- !strcmp(Global.core.model, "DE910-DUAL")) {
- // user_data_len is stored as number of encoded octets
- log_debug("putting nr_octets into PDU as data length (DE910-DUAL)");
- tmp = hex_byte_encode(pdu_str, len, *nr_octets);
- }
- else {
- // user_data_len is stored as number of septets
- log_debug("putting user_data_len into PDU as data length");
- tmp = hex_byte_encode(pdu_str, len, pdu->user_data_len);
- }
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "user-data-len", -1);
- pdu_str += tmp;
- len -= tmp;
-
- for (i = 0; i < *nr_octets; i++) {
- hex_byte_encode(pdu_str, len, octets[i]);
- pdu_str += HEX_BYTE_LEN;
- }
- len -= *nr_octets * 2;
- pdu_str[i] = '\0';
-
- log_debug("user-data-len: 0x%02X (before encoding)", pdu->user_data_len);
- log_debug("nr_octets: 0x%02X (after encoding)", *nr_octets);
-
- return pdu_str - begin;
+ char *begin = pdu_str;
+ int tmp;
+ uint8_t octets[PDU_OCTETS_MAX];
+ int i;
+
+ if (pdu->data_coding.general.unused) {
+ log_error("data coding group 0x%02X not implemented",
+ pdu->data_coding.data_coding & 0xF0);
+ return -1;
+ }
+
+ if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) {
+ log_debug("data coding alphabet is default (7-bit)");
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
+ log_debug("data coding alphabet is CDMA default (7-bit)");
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_EIGHT) {
+ log_debug("data coding alphabet is eight");
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_EIGHT) {
+ log_debug("data coding alphabet is CDMA eight");
+ } else {
+ log_debug("data coding alphabet 0x%02X not implemented",
+ pdu->data_coding.general.alphabet);
+ return -1;
+ }
+
+
+ // ---------------------------------------------------------------------
+ // FOR GSM 7-BIT ENCODING ONLY, ENCODE FROM IRA ALPHABET TO GSM ALPHABET
+ // ---------------------------------------------------------------------
+ if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) {
+ int read = 0;
+ int store = 0;
+ char initial_user_data[PDU_UD_7BIT_MAX];
+
+ for (read = 0; read < pdu->user_data_len; read++) {
+ initial_user_data[read] = pdu->user_data[read];
+ }
+ initial_user_data[read] = 0;
+
+ log_debug("Converting from IRA character set to GSM");
+ for (read = 0; read < pdu->user_data_len; read++) {
+ int GSMchar = indexOfChar(strGSMTable, GSM_TABLE_SIZE, initial_user_data[read]);
+
+ if (GSMchar >= 0) {
+ log_debug("IRA before: 0x%02X | GSM after: 0x%02X", initial_user_data[read], GSMchar);
+ pdu->user_data[store] = GSMchar;
+ }
+ else {
+ //Check in extended table
+ GSMchar = indexOfChar(strExtendedTable, GSM_TABLE_SIZE, initial_user_data[read]);
+
+ if (GSMchar >= 0) {
+ log_debug("IRA before: 0x%02X | GSM after: 0x1B%02X", initial_user_data[read], GSMchar);
+ pdu->user_data[store] = 0x1B;
+ store++;
+ pdu->user_data[store] = GSMchar;
+ }
+ else {
+ log_debug("IRA before: 0x%02X | Translation not found - no change", initial_user_data[read]);
+ pdu->user_data[store] = initial_user_data[read];
+ }
+ }
+
+ store++;
+ }
+
+ //Update lengths
+ pdu->user_data_len += store - read;
+ }
+
+
+ // ------------------------------
+ // ENCODE USER DATA INTO PDU DATA
+ // ------------------------------
+ // GSM 7-BIT ENCODING
+ if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) {
+ if (pdu->user_data_len > PDU_UD_7BIT_MAX) {
+ log_error("string exceeds 7-bit data max length");
+ return -1;
+ }
+
+ *nr_octets = octets_from_septets(pdu->user_data_len);
+ for (i = 0; i < *nr_octets; i++) {
+ octets[i] = encode_octet(pdu->user_data, i);
+ log_debug("ENCODE: i: %d data: 0x%02X --> octet: 0x%02X", i, pdu->user_data[i], octets[i]);
+ }
+
+ // CDMA 7-BIT ENCODING
+ } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) {
+ if (pdu->user_data_len > PDU_UD_7BIT_MAX) {
+ log_error("string exceeds 7-bit data max length");
+ return -1;
+ }
+
+ *nr_octets = octets_from_septets(pdu->user_data_len);
+ for (i = 0; i < *nr_octets; i++) {
+ octets[i] = encode_cdma_octet(pdu->user_data, i);
+ log_debug("ENCODE: i: %d data: 0x%02X --> octet: 0x%02X", i, pdu->user_data[i], octets[i]);
+ }
+
+ // ALL 8-BIT ENCODING
+ } else {
+ if (pdu->user_data_len > PDU_UD_8BIT_MAX) {
+ log_error("string exceeds 8-bit data max length");
+ return -1;
+ }
+
+ *nr_octets = pdu->user_data_len;
+ for (i = 0; i < pdu->user_data_len; i++) {
+ octets[i] = pdu->user_data[i];
+ }
+ }
+
+ if (len < *nr_octets * 2 + HEX_BYTE_LEN + 1) {
+ log_error("buffer is not large enough to hold user-data");
+ return -1;
+ }
+
+ if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT) &&
+ !strcmp(Global.core.model, "DE910-DUAL")) {
+ // user_data_len is stored as number of encoded octets
+ log_debug("putting nr_octets into PDU as data length (DE910-DUAL)");
+ tmp = hex_byte_encode(pdu_str, len, *nr_octets);
+ }
+ else {
+ // user_data_len is stored as number of septets
+ log_debug("putting user_data_len into PDU as data length");
+ tmp = hex_byte_encode(pdu_str, len, pdu->user_data_len);
+ }
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "user-data-len", -1);
+ pdu_str += tmp;
+ len -= tmp;
+
+ for (i = 0; i < *nr_octets; i++) {
+ hex_byte_encode(pdu_str, len, octets[i]);
+ pdu_str += HEX_BYTE_LEN;
+ }
+ len -= *nr_octets * 2;
+ pdu_str[i] = '\0';
+
+ log_debug("user-data-len: 0x%02X (before encoding)", pdu->user_data_len);
+ log_debug("nr_octets: 0x%02X (after encoding)", *nr_octets);
+
+ return pdu_str - begin;
}
int pdu_encode(char *pdu_str, size_t len, struct pdu_info *pdu)
{
- char *begin = pdu_str;
- char *msg_begin = pdu_str;
- int tmp;
- int nr_octets;
-
- tmp = pdu_encode_addr(pdu_str, len, &pdu->smsc_addr, 1);
- ENCODE_FAIL(tmp < 0, "smsc-addr", -1);
- len -= tmp;
- pdu_str += tmp;
-
- msg_begin = pdu_str;
-
- tmp = hex_byte_encode(pdu_str, len, pdu->type.type);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "type", -1);
- len -= tmp;
- pdu_str += tmp;
-
- if (pdu->type.msg_type == PDU_MTI_SUBMIT ||
- pdu->type.msg_type == PDU_MTI_REPORT) {
- tmp = hex_byte_encode(pdu_str, len, pdu->msg_reference);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "msg-reference", -1);
- len -= tmp;
- pdu_str += tmp;
- }
-
- tmp = pdu_encode_addr(pdu_str, len, &pdu->addr, 0);
- ENCODE_FAIL(tmp < 0, "addr", -1);
- len -= tmp;
- pdu_str += tmp;
-
- switch (pdu->type.msg_type) {
- case PDU_MTI_REPORT:
- tmp = pdu_encode_timestamp(pdu_str, len, &pdu->timestamp);
- ENCODE_FAIL(tmp < 0, "report-timestamp", -1);
- len -= tmp;
- pdu_str += tmp;
-
- break;
- case PDU_MTI_DELIVER:
- case PDU_MTI_SUBMIT:
- tmp = hex_byte_encode(pdu_str, len, pdu->protocol_id);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "protocol-id", -1);
- len -= tmp;
- pdu_str += tmp;
-
- tmp = hex_byte_encode(pdu_str, len, pdu->data_coding.data_coding);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "data-coding-scheme", -1);
- len -= tmp;
- pdu_str += tmp;
-
- if (pdu->type.msg_type == PDU_MTI_SUBMIT) {
- switch (pdu->type.validity_period_format) {
- case PDU_VPF_RELATIVE:
- tmp = hex_byte_encode(pdu_str, len, pdu->validity_period);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "validity-period", -1);
- len -= tmp;
- pdu_str += tmp;
-
- break;
-
- case PDU_VPF_ENHANCED:
- log_warning("PDU_VPF_ENHANCED? Falling through to absolute");
- case PDU_VPF_ABSOUTE:
- tmp = pdu_encode_timestamp(pdu_str, len, &pdu->timestamp);
- ENCODE_FAIL(tmp < 0, "validity-period-timestamp", -1);
- len -= tmp;
- pdu_str += tmp;
-
- break;
-
- case PDU_VPF_NOT_PRESENT:
- default:
- break;
- }
- } else if (pdu->type.msg_type == PDU_MTI_DELIVER) {
- tmp = pdu_encode_timestamp(pdu_str, len, &pdu->timestamp);
- ENCODE_FAIL(tmp < 0, "delivery-timestamp", -1);
- len -= tmp;
- pdu_str += tmp;
- }
-
- tmp = pdu_encode_user_data(pdu_str, len, pdu, &nr_octets);
- ENCODE_FAIL(tmp < 0, "user-data", -1);
- len -= tmp;
- pdu_str += tmp;
- }
-
- pdu->msg_len = (pdu_str - msg_begin) / 2;
- log_debug("msg-len: %d", pdu->msg_len);
-
- return pdu_str - begin;
+ char *begin = pdu_str;
+ char *msg_begin = pdu_str;
+ int tmp;
+ int nr_octets;
+
+ tmp = pdu_encode_addr(pdu_str, len, &pdu->smsc_addr, 1);
+ ENCODE_FAIL(tmp < 0, "smsc-addr", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+ msg_begin = pdu_str;
+
+ tmp = hex_byte_encode(pdu_str, len, pdu->type.type);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "type", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+ if (pdu->type.msg_type == PDU_MTI_SUBMIT ||
+ pdu->type.msg_type == PDU_MTI_REPORT) {
+ tmp = hex_byte_encode(pdu_str, len, pdu->msg_reference);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "msg-reference", -1);
+ len -= tmp;
+ pdu_str += tmp;
+ }
+
+ tmp = pdu_encode_addr(pdu_str, len, &pdu->addr, 0);
+ ENCODE_FAIL(tmp < 0, "addr", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+ switch (pdu->type.msg_type) {
+ case PDU_MTI_REPORT:
+ tmp = pdu_encode_timestamp(pdu_str, len, &pdu->timestamp);
+ ENCODE_FAIL(tmp < 0, "report-timestamp", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+ break;
+ case PDU_MTI_DELIVER:
+ case PDU_MTI_SUBMIT:
+ tmp = hex_byte_encode(pdu_str, len, pdu->protocol_id);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "protocol-id", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+ tmp = hex_byte_encode(pdu_str, len, pdu->data_coding.data_coding);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "data-coding-scheme", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+ if (pdu->type.msg_type == PDU_MTI_SUBMIT) {
+ switch (pdu->type.validity_period_format) {
+ case PDU_VPF_RELATIVE:
+ tmp = hex_byte_encode(pdu_str, len, pdu->validity_period);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "validity-period", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+ break;
+
+ case PDU_VPF_ENHANCED:
+ log_warning("PDU_VPF_ENHANCED? Falling through to absolute");
+ case PDU_VPF_ABSOUTE:
+ tmp = pdu_encode_timestamp(pdu_str, len, &pdu->timestamp);
+ ENCODE_FAIL(tmp < 0, "validity-period-timestamp", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+ break;
+
+ case PDU_VPF_NOT_PRESENT:
+ default:
+ break;
+ }
+ } else if (pdu->type.msg_type == PDU_MTI_DELIVER) {
+ tmp = pdu_encode_timestamp(pdu_str, len, &pdu->timestamp);
+ ENCODE_FAIL(tmp < 0, "delivery-timestamp", -1);
+ len -= tmp;
+ pdu_str += tmp;
+ }
+
+ tmp = pdu_encode_user_data(pdu_str, len, pdu, &nr_octets);
+ ENCODE_FAIL(tmp < 0, "user-data", -1);
+ len -= tmp;
+ pdu_str += tmp;
+ }
+
+ pdu->msg_len = (pdu_str - msg_begin) / 2;
+ log_debug("msg-len: %d", pdu->msg_len);
+
+ return pdu_str - begin;
}
int pdu_encode_cdma(char *pdu_str, size_t len, struct pdu_info *pdu)
{
- char *begin = pdu_str;
- char *msg_begin = pdu_str;
- int tmp;
- int nr_octets;
-
- //Set pdu encoding for CDMA
- pdu->data_coding.general.alphabet = PDU_ALPHABET_CDMA_DEFAULT;
-
- //Destination address
- tmp = pdu_encode_addr(pdu_str, len, &pdu->addr, 0);
- ENCODE_FAIL(tmp < 0, "addr", -1);
- len -= tmp;
- pdu_str += tmp;
-
- //Callback address (Always 00 because it's empty)
- tmp = hex_byte_encode(pdu_str, len, 0);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "callback-addr-len", -1);
- pdu_str += tmp;
- len -= tmp;
-
- //Teleservice ID (always 1002)
- tmp = hex_byte_encode(pdu_str, len, 16);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "tele-id-1", -1);
- pdu_str += tmp;
- len -= tmp;
- tmp = hex_byte_encode(pdu_str, len, 2);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "tele-id-2", -1);
- pdu_str += tmp;
- len -= tmp;
-
- //Priority (always 00 for normal)
- tmp = hex_byte_encode(pdu_str, len, 0);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "priority", -1);
- pdu_str += tmp;
- len -= tmp;
-
- switch (pdu->type.msg_type) {
- case PDU_MTI_REPORT:
- log_error("msg_type PDU_MTI_REPORT not supported!");
- return 0;
-
- case PDU_MTI_DELIVER:
- log_debug("msg_type: PDU_MTI_DELIVER");
- case PDU_MTI_SUBMIT:
- log_debug("msg_type: PDU_MTI_SUBMIT");
-
- //add data coding scheme
- tmp = hex_byte_encode(pdu_str, len, pdu->data_coding.data_coding);
- ENCODE_FAIL(tmp != HEX_BYTE_LEN, "data-coding-scheme", -1);
- len -= tmp;
- pdu_str += tmp;
-
-
- tmp = pdu_encode_user_data(pdu_str, len, pdu, &nr_octets);
- ENCODE_FAIL(tmp < 0, "user-data", -1);
- len -= tmp;
- pdu_str += tmp;
- }
-
- // pdu->msg_len = (pdu_str - msg_begin) / 2;
- pdu->msg_len = 6 + nr_octets;
- log_debug("msg-len: %d", pdu->msg_len);
-
- return pdu_str - begin;
+ char *begin = pdu_str;
+ char *msg_begin = pdu_str;
+ int tmp;
+ int nr_octets;
+
+ //Set pdu encoding for CDMA
+ pdu->data_coding.general.alphabet = PDU_ALPHABET_CDMA_DEFAULT;
+
+ //Destination address
+ tmp = pdu_encode_addr(pdu_str, len, &pdu->addr, 0);
+ ENCODE_FAIL(tmp < 0, "addr", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+ //Callback address (Always 00 because it's empty)
+ tmp = hex_byte_encode(pdu_str, len, 0);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "callback-addr-len", -1);
+ pdu_str += tmp;
+ len -= tmp;
+
+ //Teleservice ID (always 1002)
+ tmp = hex_byte_encode(pdu_str, len, 16);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "tele-id-1", -1);
+ pdu_str += tmp;
+ len -= tmp;
+ tmp = hex_byte_encode(pdu_str, len, 2);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "tele-id-2", -1);
+ pdu_str += tmp;
+ len -= tmp;
+
+ //Priority (always 00 for normal)
+ tmp = hex_byte_encode(pdu_str, len, 0);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "priority", -1);
+ pdu_str += tmp;
+ len -= tmp;
+
+ switch (pdu->type.msg_type) {
+ case PDU_MTI_REPORT:
+ log_error("msg_type PDU_MTI_REPORT not supported!");
+ return 0;
+
+ case PDU_MTI_DELIVER:
+ log_debug("msg_type: PDU_MTI_DELIVER");
+ case PDU_MTI_SUBMIT:
+ log_debug("msg_type: PDU_MTI_SUBMIT");
+
+ //add data coding scheme
+ tmp = hex_byte_encode(pdu_str, len, pdu->data_coding.data_coding);
+ ENCODE_FAIL(tmp != HEX_BYTE_LEN, "data-coding-scheme", -1);
+ len -= tmp;
+ pdu_str += tmp;
+
+
+ tmp = pdu_encode_user_data(pdu_str, len, pdu, &nr_octets);
+ ENCODE_FAIL(tmp < 0, "user-data", -1);
+ len -= tmp;
+ pdu_str += tmp;
+ }
+
+ // pdu->msg_len = (pdu_str - msg_begin) / 2;
+ pdu->msg_len = 6 + nr_octets;
+ log_debug("msg-len: %d", pdu->msg_len);
+
+ return pdu_str - begin;
}
diff --git a/src/phonebook.c b/src/phonebook.c
index fc29d61..3165235 100644
--- a/src/phonebook.c
+++ b/src/phonebook.c
@@ -290,7 +290,7 @@ int phonebook_list_get(int fd, struct phonebook_list_info *list_info)
atcmd_writeline(fd, "AT+CPBR=%d,%d",
list_info->store.index_min, list_info->store.index_max);
tmp = atcmd_response_foreach_line(fd, list_info_callback, list_info);
- //CE910 reports an error if empty. Don't report error in this case
+ //CE910 reports an error if empty. Don't report error in this case
if ((tmp < 0) && strcmp(Global.core.model, "CE910-DUAL")) {
log_error("listing failed");
phonebook_list_free(list_info);
diff --git a/src/sms_delete.c b/src/sms_delete.c
index 7bd50d0..e70ddc3 100644
--- a/src/sms_delete.c
+++ b/src/sms_delete.c
@@ -167,8 +167,8 @@ int sms_delete(int argc, char **argv)
return false;
}
- // LNA7/L4G1 with Verizon SIM SMS 3GPP, 3GPP2 WORKAROUND
- if (is_quectel_dual_sms_format()) {
+ // LNA7/LNA7D/L4G1 with Verizon SIM SMS 3GPP, 3GPP2 WORKAROUND
+ if (is_quectel_dual_format()) {
int tmp;
tmp = atcmd_plus_qcfg_write(fd, SMS_FORMAT_3GPP);
if (tmp == 0) {
diff --git a/src/sms_list.c b/src/sms_list.c
index 2c39aa8..7f246be 100644
--- a/src/sms_list.c
+++ b/src/sms_list.c
@@ -283,14 +283,14 @@ static int list_info_callback(char *buf, size_t len, void *data)
msg = list_entry(list_info->msg_list.prev, typeof(*msg), list);
if (msg->len > 0) {
- if (isCdmaTypeModel()) {
- log_debug("using CDMA pdu decoding");
- err = pdu_decode_cdma(buf, &msg->pdu);
- }
- else {
- log_debug("using GSM pdu decoding");
- err = pdu_decode(buf, &msg->pdu);
- }
+ if (is_telit_3gpp2_format()) {
+ log_debug("using CDMA pdu decoding");
+ err = pdu_decode_cdma(buf, &msg->pdu);
+ }
+ else {
+ log_debug("using GSM pdu decoding");
+ err = pdu_decode(buf, &msg->pdu);
+ }
if (err < 0) {
log_warning("pdu decode failed: %d", err);
}
@@ -499,8 +499,8 @@ int sms_list(int argc, char **argv)
return false;
}
- // LNA7 with Verizon SIM SMS 3GPP, 3GPP2 WORKAROUND
- if (is_quectel_dual_sms_format()) {
+ // LNA7/LNA7D/L4G1 with Verizon SIM SMS 3GPP, 3GPP2 WORKAROUND
+ if (is_quectel_dual_format()) {
int tmp;
tmp = atcmd_plus_qcfg_write(fd, SMS_FORMAT_3GPP);
if (tmp == 0) {
diff --git a/src/sms_send.c b/src/sms_send.c
index bc98cb4..a95a0ca 100644
--- a/src/sms_send.c
+++ b/src/sms_send.c
@@ -224,25 +224,25 @@ static int do_send(int fd, struct send_options *options, int argc, char **argv)
printf("preparing for send...\n");
}
- //LE910-SVG SMS SEND WORKAROUND
- if (is_vzw_lte()) {
- log_info("setting text mode for Verizon LTE");
- tmp = atcmd_plus_cmgf_write(fd, SMS_TEXT_MODE);
- if (tmp < 0) {
- log_error("failed to set text mode for sending with Verizon LTE.");
- return false;
- }
- }
+ //LE910-SVG SMS SEND WORKAROUND
+ if (is_telit_lte_vzw_3gpp2_format()) {
+ log_info("setting text mode for Verizon LTE");
+ tmp = atcmd_plus_cmgf_write(fd, SMS_TEXT_MODE);
+ if (tmp < 0) {
+ log_error("failed to set text mode for sending with Verizon LTE.");
+ return false;
+ }
+ }
if (options->cmgw_first) {
- if (isCdmaTypeModel()) {
+ if (is_telit_3gpp2_format()) {
log_debug("using CDMA pdu encoding for cmgw");
- tmp = pdu_encode_cdma(buf, sizeof(buf), &pdu);
- }
- else {
+ tmp = pdu_encode_cdma(buf, sizeof(buf), &pdu);
+ }
+ else {
log_debug("using GSM pdu encoding for cmgw");
- tmp = pdu_encode(buf, sizeof(buf), &pdu);
- }
+ tmp = pdu_encode(buf, sizeof(buf), &pdu);
+ }
if (tmp < 0) {
log_error("pdu encode failed");
return false;
@@ -252,13 +252,13 @@ static int do_send(int fd, struct send_options *options, int argc, char **argv)
printf("writing message to memory\n");
}
- //LE910-SVG SMS SEND WORKAROUND
- if (is_vzw_lte()) {
- mem_index = atcmd_plus_cmgw_write_text(fd, NULL, SMS_ADDR_UNSPEC, NULL, pdu.user_data, pdu.user_data_len);
- }
- else {
- mem_index = atcmd_plus_cmgw_write(fd, buf, pdu.msg_len);
- }
+ //LE910-SVG SMS SEND WORKAROUND
+ if (is_telit_lte_vzw_3gpp2_format()) {
+ mem_index = atcmd_plus_cmgw_write_text(fd, NULL, SMS_ADDR_UNSPEC, NULL, pdu.user_data, pdu.user_data_len);
+ }
+ else {
+ mem_index = atcmd_plus_cmgw_write(fd, buf, pdu.msg_len);
+ }
if (mem_index < 0) {
log_error("write message to memory failed");
return false;
@@ -298,27 +298,27 @@ static int do_send(int fd, struct send_options *options, int argc, char **argv)
continue;
}
} else {
- if (isCdmaTypeModel()) {
- log_debug("using CDMA pdu encoding for cmgs");
- tmp = pdu_encode_cdma(buf, sizeof(buf), &pdu);
- }
- else {
- log_debug("using GSM pdu encoding for cmgs");
- tmp = pdu_encode(buf, sizeof(buf), &pdu);
- }
+ if (is_telit_3gpp2_format()) {
+ log_debug("using CDMA pdu encoding for cmgs");
+ tmp = pdu_encode_cdma(buf, sizeof(buf), &pdu);
+ }
+ else {
+ log_debug("using GSM pdu encoding for cmgs");
+ tmp = pdu_encode(buf, sizeof(buf), &pdu);
+ }
if (tmp < 0) {
printf("sending message to %s failed\n", argv[i]);
failed++;
continue;
}
- //LE910-SVG SMS SEND WORKAROUND
- if (is_vzw_lte()) {
- tmp = atcmd_plus_cmgs_write_text(fd, pdu.addr.addr, pdu.user_data, pdu.user_data_len);
- }
- else {
- tmp = atcmd_plus_cmgs_write(fd, buf, pdu.msg_len);
- }
+ //LE910-SVG SMS SEND WORKAROUND
+ if (is_telit_lte_vzw_3gpp2_format()) {
+ tmp = atcmd_plus_cmgs_write_text(fd, pdu.addr.addr, pdu.user_data, pdu.user_data_len);
+ }
+ else {
+ tmp = atcmd_plus_cmgs_write(fd, buf, pdu.msg_len);
+ }
if (tmp < 0) {
printf("sending message to %s failed\n", argv[i]);
failed++;
diff --git a/src/utils.c b/src/utils.c
index 3a18487..37d0ac3 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -288,12 +288,12 @@ int device_unlock(int lock)
int indexOfChar(const char *array, int len, char character)
{
- int i;
-
- for (i = 0; i < len; i++) {
- if (array[i] == character) {
- return i;
- }
- }
- return -1;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (array[i] == character) {
+ return i;
+ }
+ }
+ return -1;
}