diff options
Diffstat (limited to 'src/pdu_decode.c')
-rw-r--r-- | src/pdu_decode.c | 96 |
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; |