summaryrefslogtreecommitdiff
path: root/src/pdu_decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdu_decode.c')
-rw-r--r--src/pdu_decode.c96
1 files changed, 57 insertions, 39 deletions
diff --git a/src/pdu_decode.c b/src/pdu_decode.c
index 459916c..27822f3 100644
--- a/src/pdu_decode.c
+++ b/src/pdu_decode.c
@@ -163,16 +163,14 @@ done:
return pdu_str - begin;
}
-#define octet_idx(n) octet_align(n)
-#define octet_cdma_idx(n) ((n+1) * 7 / 8)
-#define decode_septet(buf, n) \
+#define decode_septet_from_octet(buf, n) \
shiftl(bit_maskr(cycledown(n, 8)) & buf[octet_idx(n)], cycleup(n, 8)) | \
shiftr(bit_maskl(cycleup(n, 8), 8) & buf[octet_idx(n - 1)], cycledown(n - 1, 8))
-#define decode_septet_cdma(buf, n) \
-shiftr(buf[octet_cdma_idx(n)], cycleup(n, 8) + 1) | \
-shiftl(buf[octet_cdma_idx(n) - 1], cycledown(n, 8)) & 0x7F
+#define decode_cdma_septet_from_octet(buf, n) \
+shiftr(buf[octet_idx(n)], cycleup(n, 8) + 1) | \
+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)
{
@@ -195,19 +193,19 @@ int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octe
return -1;
}
- if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) {
- log_debug("data coding alphabet is default");
- 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;
- }
-
- *nr_octets = octet_align(pdu->user_data_len);
- } else if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI) {
- //GSM style 8 bit conversion but with UDH multi-part header (LE910-SVG)
- log_debug("data coding alphabet is nine");
+ // -----------------------------------------------------------------------------
+ // 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_DEFAULT_MULTI)) {
+ if (pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT_MULTI) {
+ //GSM style 7-bit encoding but with UDH multi-part header (LE910-SVG)
+ log_debug("data coding alphabet is nine");
+ } else {
+ //GSM 7-bit encoding
+ log_debug("data coding alphabet is default");
+ }
if (pdu->user_data_len > PDU_UD_7BIT_MAX) {
log_warning("pdu contains invalid user-data-len: 0x%02X",
@@ -215,31 +213,30 @@ int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octe
pdu->user_data_len = PDU_UD_7BIT_MAX;
}
- *nr_octets = octet_align(pdu->user_data_len);
+ //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) {
log_debug("data coding alphabet is cdma default");
- // Encoding 02 is 7 bit for LE910-SVG but 8 bit for other CDMA radios
+ // LE910-SVG stores data length as # of septets
if (!strcmp(Global.core.model, "LE910-SVG")) {
- 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;
- }
+ *nr_octets = octets_from_septets(pdu->user_data_len);
}
+ // Other CDMA radios store data length as # of octets
else {
- 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;
- }
+ *nr_octets = pdu->user_data_len;
+ pdu->user_data_len = septets_from_octets(pdu->user_data_len);
}
- if (!strcmp(Global.core.model, "LE910-SVG")) {
- *nr_octets = octet_align(pdu->user_data_len);
- }
- else {
- *nr_octets = pdu->user_data_len;
- pdu->user_data_len = octet_align_cdma(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)) {
log_debug("data coding alphabet is eight");
@@ -250,7 +247,11 @@ int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octe
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;
+
+ // UNSUPPORTED
} else {
log_debug("data coding alphabet 0x%02X not implemented",
pdu->data_coding.general.alphabet);
@@ -259,14 +260,20 @@ int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octe
STRLEN_CHECK(pdu_str, *nr_octets * 2, -1);
- log_debug("user-data-len: 0x%02X", pdu->user_data_len);
- log_debug("nr_octets: 0x%02X", *nr_octets);
+ 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_DEFAULT_MULTI)) {
// Keep UDH for concatenated SMS.
@@ -284,12 +291,15 @@ int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octe
i++;
}
}
+
user_data_start_index = i;
for (; i < pdu->user_data_len; i++) {
- pdu->user_data[i] = decode_septet(octets, 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.
@@ -305,10 +315,12 @@ int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octe
i++;
}
}
+
for (; i < pdu->user_data_len; i++) {
- pdu->user_data[i] = decode_septet_cdma(octets, 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 (strcmp(Global.core.model, "LE910-SVG") && (pdu->user_data[i-1] == 0)) {
log_debug("Removing padded char");
@@ -316,6 +328,8 @@ int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octe
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];
@@ -323,7 +337,11 @@ int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octe
pdu->user_data[i] = '\0';
}
- //Only for GSM 7-bit character set
+
+ // ---------------------------------------------------------------------
+ // 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_DEFAULT_MULTI)) {
int read = user_data_start_index;