summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Bayer <bbayer@multitech.com>2015-11-16 09:59:15 -0600
committerBrandon Bayer <bbayer@multitech.com>2015-11-17 09:27:36 -0600
commitd8be565fc564cbd6e3beaddb3fc77b311abf2359 (patch)
tree5c6e960dee414104cd1e0ba227ac674bfc9cf7f1
parentf3b916f22265f3f173987e28d8fdc2c8a3502519 (diff)
downloadsms-utils-d8be565fc564cbd6e3beaddb3fc77b311abf2359.tar.gz
sms-utils-d8be565fc564cbd6e3beaddb3fc77b311abf2359.tar.bz2
sms-utils-d8be565fc564cbd6e3beaddb3fc77b311abf2359.zip
feat: implement IRA->GSM character set encoding & decoding0.0.10
This adds support for certain characters like @ $ ~ ^
-rw-r--r--configure.in2
-rw-r--r--src/pdu.c20
-rw-r--r--src/pdu.h4
-rw-r--r--src/pdu_decode.c25
-rw-r--r--src/pdu_encode.c45
-rw-r--r--src/utils.c13
-rw-r--r--src/utils.h2
7 files changed, 110 insertions, 1 deletions
diff --git a/configure.in b/configure.in
index 2c4b8ad..71f19ec 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
AC_INIT([src/sms_main.c])
-AM_INIT_AUTOMAKE([sms-utils], [0.0.9])
+AM_INIT_AUTOMAKE([sms-utils], [0.0.10])
AM_CONFIG_HEADER([config.h])
AC_PROG_CC
diff --git a/src/pdu.c b/src/pdu.c
index 2ceb7ae..07a976c 100644
--- a/src/pdu.c
+++ b/src/pdu.c
@@ -36,6 +36,26 @@
#include "pdu.h"
#include "sms_utils.h"
+// ` is not a conversion, just a untranslatable letter
+char strGSMTable[GSM_TABLE_SIZE] = {
+ '@','£','$','¥','è','é','ù','ì','ò','Ç','\n','Ø','ø','\r','Å','å',
+ 'Δ','_','Φ','Γ','Λ','Ω','Π','Ψ','Σ','Θ','Ξ','`','Æ','æ','ß','É',
+ ' ','!','\"','#','¤','%','&','\'','(',')','*','=',',','-','.','/',
+ '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?',
+ '¡','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
+ 'P','Q','R','S','T','U','V','W','X','Y','Z','Ä','Ö','Ñ','Ü','`',
+ '¿','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
+ 'p','q','r','s','t','u','v','w','x','y','z','ä','ö','ñ','ü','à'};
+char strExtendedTable[GSM_TABLE_SIZE] = {
+ '`','`','`','`','`','`','`','`','`','`','`','`','`','`','`','`',
+ '`','`','`','`','^','`','`','`','`','`','`','`','`','`','`','`',
+ '`','`','`','`','`','`','`','`','{','}','`','`','`','`','`','\\',
+ '`','`','`','`','`','`','`','`','`','`','`','`','[','~',']','`',
+ '|','`','`','`','`','`','`','`','`','`','`','`','`','`','`','`',
+ '`','`','`','`','`','`','`','`','`','`','`','`','`','`','`','`',
+ '`','`','`','`','`','€','`','`','`','`','`','`','`','`','`','`',
+ '`','`','`','`','`','`','`','`','`','`','`','`','`','`','`','`'};
+
int hex_nibble_scan(const char *buf, size_t len)
{
static const char digits[] = "0123456789ABCDEF";
diff --git a/src/pdu.h b/src/pdu.h
index 58f88e0..9dfddd4 100644
--- a/src/pdu.h
+++ b/src/pdu.h
@@ -25,6 +25,10 @@ extern char *strptime(const char *s, const char *format, struct tm *tm);
#define PDU_VPF_RELATIVE_2DAYS 0xA8
+#define GSM_TABLE_SIZE 128
+extern char strGSMTable[];
+extern char strExtendedTable[];
+
struct pdu_addr {
char addr[PDU_ADDR_SIZE];
uint8_t type;
diff --git a/src/pdu_decode.c b/src/pdu_decode.c
index 140fd14..934aef5 100644
--- a/src/pdu_decode.c
+++ b/src/pdu_decode.c
@@ -309,6 +309,31 @@ int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu, int *nr_octe
pdu->user_data[i] = '\0';
}
+ //Only for 7-bit character sets
+ if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) ||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_DEFAULT)) {
+ int read = 0;
+ int store = 0;
+
+ log_debug("Converting from GSM character set to IRA");
+ for (read = 0; 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;
}
diff --git a/src/pdu_encode.c b/src/pdu_encode.c
index 1bb7e4d..f0d8c96 100644
--- a/src/pdu_encode.c
+++ b/src/pdu_encode.c
@@ -182,6 +182,51 @@ int pdu_encode_user_data(char *pdu_str, size_t len, struct pdu_info *pdu, int *n
return -1;
}
+
+ //Convert to GSM character set, Only for 7-bit character sets
+ if ((pdu->data_coding.general.alphabet == PDU_ALPHABET_DEFAULT) ||
+ (pdu->data_coding.general.alphabet == PDU_ALPHABET_CDMA_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;
+ }
+
+
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");
diff --git a/src/utils.c b/src/utils.c
index a794f9b..8e7bed7 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -275,3 +275,16 @@ char *device_lock(const char *path)
return 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;
+}
+
diff --git a/src/utils.h b/src/utils.h
index 79b04ae..04a71b6 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -37,6 +37,8 @@ char *shell_path_expand(const char *path);
char *device_lock(const char *path);
+int indexOfChar(const char *array, int len, char character);
+
#define YAML_INDENT 2
#define indentf(n, format, args...) \