summaryrefslogtreecommitdiffstats
path: root/ss.c
diff options
context:
space:
mode:
authorAlexander Tarasikov <alexander.tarasikov@gmail.com>2012-07-13 16:04:37 +0400
committerAlexander Tarasikov <alexander.tarasikov@gmail.com>2012-07-13 16:04:37 +0400
commit98a8d340281ed71aaa0130accd0061d818d46199 (patch)
tree03a035ce573076a37cc543c0d8efc31a687f2dda /ss.c
parente88c9e5ac72a03c07b67f529248dceda1eefaa49 (diff)
downloadhardware_replicant_libsamsung-ril-98a8d340281ed71aaa0130accd0061d818d46199.tar.gz
hardware_replicant_libsamsung-ril-98a8d340281ed71aaa0130accd0061d818d46199.tar.bz2
hardware_replicant_libsamsung-ril-98a8d340281ed71aaa0130accd0061d818d46199.zip
Fix USSD encoding for all GSM7/UCS2/ASCII cases
This is a port of the DCS decoding function from the XDANDROID RIL. Now latin and unicode USSD notifications are correctly received. Verified by receiving cyrillic messages
Diffstat (limited to 'ss.c')
-rw-r--r--ss.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/ss.c b/ss.c
index 1cfff44..035c97a 100644
--- a/ss.c
+++ b/ss.c
@@ -168,10 +168,49 @@ void ipc2ril_ussd_state(struct ipc_ss_ussd *ussd, char *message[2])
}
}
+typedef enum {
+ SMS_CODING_SCHEME_UNKNOWN = 0,
+ SMS_CODING_SCHEME_GSM7,
+ SMS_CODING_SCHEME_UCS2
+} SmsCodingScheme;
+
+static SmsCodingScheme sms_get_coding_scheme(int dataCoding)
+{
+ switch (dataCoding >> 4) {
+ case 0x00:
+ case 0x02:
+ case 0x03:
+ return SMS_CODING_SCHEME_GSM7;
+ case 0x01:
+ if (dataCoding == 0x10)
+ return SMS_CODING_SCHEME_GSM7;
+ if (dataCoding == 0x11)
+ return SMS_CODING_SCHEME_UCS2;
+ break;
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ if (dataCoding & 0x20)
+ return SMS_CODING_SCHEME_UNKNOWN;
+ if (((dataCoding >> 2) & 3) == 0)
+ return SMS_CODING_SCHEME_GSM7;
+ if (((dataCoding >> 2) & 3) == 2)
+ return SMS_CODING_SCHEME_UCS2;
+ break;
+ case 0xF:
+ if (!(dataCoding & 4))
+ return SMS_CODING_SCHEME_GSM7;
+ break;
+ }
+ return SMS_CODING_SCHEME_UNKNOWN;
+}
+
void ipc_ss_ussd(struct ipc_message_info *info)
{
char *data_dec = NULL;
int data_dec_len = 0;
+ SmsCodingScheme codingScheme;
char *message[2];
@@ -187,8 +226,9 @@ void ipc_ss_ussd(struct ipc_message_info *info)
ril_state.ussd_state = ussd->state;
if(ussd->length > 0 && info->length > 0 && info->data != NULL) {
- switch(ussd->dcs) {
- case 0x0f:
+ codingScheme = sms_get_coding_scheme(ussd->dcs);
+ switch(codingScheme) {
+ case SMS_CODING_SCHEME_GSM7:
LOGD("USSD Rx encoding is GSM7");
data_dec_len = gsm72ascii(info->data
@@ -197,14 +237,14 @@ void ipc_ss_ussd(struct ipc_message_info *info)
message[1][data_dec_len] = '\0';
break;
- case 0x48:
- LOGD("USSD Rx encoding is UCS2", ussd->dcs);
+ case SMS_CODING_SCHEME_UCS2:
+ LOGD("USSD Rx encoding %x is UCS2", ussd->dcs);
data_dec_len = info->length - sizeof(struct ipc_ss_ussd);
message[1] = malloc(data_dec_len * 4 + 1);
int i, result = 0;
- char *ucs2 = info->data + sizeof(struct ipc_ss_ussd);
+ char *ucs2 = (char*)info->data + sizeof(struct ipc_ss_ussd);
for (i = 0; i < data_dec_len; i += 2) {
int c = (ucs2[i] << 8) | ucs2[1 + i];
result += utf8_write(message[1], result, c);