summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Tarasikov <alexander.tarasikov@gmail.com>2012-08-24 20:24:35 +0400
committerAlexander Tarasikov <alexander.tarasikov@gmail.com>2012-08-24 20:24:35 +0400
commit554a526381db5cda5dda5724e8fcbe94fca6f3d9 (patch)
tree3b79dec643be682d7ed1bd0edb4ab0a37feb9f7a
parentccf9b863a3f5b118b13c54f030ef7a77e672d758 (diff)
parentc4d12a5c5bcb5fe29fb13e9afa23975af3fbb63b (diff)
downloadhardware_ril_samsung-ril-554a526381db5cda5dda5724e8fcbe94fca6f3d9.zip
hardware_ril_samsung-ril-554a526381db5cda5dda5724e8fcbe94fca6f3d9.tar.gz
hardware_ril_samsung-ril-554a526381db5cda5dda5724e8fcbe94fca6f3d9.tar.bz2
Merge remote-tracking branch 'ksys/master' into replicant-merge
Conflicts: gprs.c net.c
-rw-r--r--Android.mk14
-rw-r--r--client.c2
-rw-r--r--compat.h57
-rw-r--r--misc.c44
-rw-r--r--net.c29
-rw-r--r--samsung-ril.c2
-rw-r--r--samsung-ril.h2
-rw-r--r--sec.c7
-rw-r--r--sms.c6
-rw-r--r--srs.c13
-rw-r--r--ss.c35
-rw-r--r--util.c81
-rw-r--r--util.h9
13 files changed, 249 insertions, 52 deletions
diff --git a/Android.mk b/Android.mk
index 2b2cfbd..3badf11 100644
--- a/Android.mk
+++ b/Android.mk
@@ -41,7 +41,7 @@ LOCAL_SRC_FILES := \
rfs.c
LOCAL_SHARED_LIBRARIES := \
- libcutils libutils libril
+ libcutils libutils libril liblog
LOCAL_STATIC_LIBRARIES := libsamsung-ipc
@@ -58,6 +58,11 @@ ifeq ($(TARGET_DEVICE),galaxysmtd)
samsung-ipc_device := aries
endif
+ifeq ($(TARGET_DEVICE),galaxys2)
+ LOCAL_CFLAGS += -DDEVICE_IPC_V4
+ samsung-ipc_device := galaxys2
+endif
+
ifeq ($(TARGET_DEVICE),galaxytab)
LOCAL_CFLAGS += -DDEVICE_IPC_V4
samsung-ipc_device := aries
@@ -67,6 +72,11 @@ ifeq ($(TARGET_DEVICE),h1)
LOCAL_CFLAGS += -DDEVICE_H1
endif
+ifeq ($(TARGET_DEVICE),maguro)
+ LOCAL_CFLAGS += -DDEVICE_IPC_V4
+ samsung-ipc_device := maguro
+endif
+
LOCAL_C_INCLUDES := external/libsamsung-ipc/include
LOCAL_C_INCLUDES += hardware/ril/libsamsung-ipc/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
@@ -78,7 +88,7 @@ LOCAL_PRELINK_MODULE := false
ifeq (foo,foo)
# build shared library
LOCAL_SHARED_LIBRARIES += \
- libcutils libnetutils libutils
+ libcutils libnetutils libutils liblog
LOCAL_LDLIBS += -lpthread
LOCAL_CFLAGS += -DRIL_SHLIB
LOCAL_MODULE:= libsamsung-ril
diff --git a/client.c b/client.c
index 7f2b987..ee3e0bc 100644
--- a/client.c
+++ b/client.c
@@ -129,7 +129,7 @@ void *ril_client_thread(void *data)
return 0;
}
- client = (struct ipc_client *) data;
+ client = (struct ril_client *) data;
for(c = 5 ; c > 0 ; c--) {
client->state = RIL_CLIENT_READY;
diff --git a/compat.h b/compat.h
new file mode 100644
index 0000000..3eda9af
--- /dev/null
+++ b/compat.h
@@ -0,0 +1,57 @@
+/**
+ * This file is part of samsung-ril.
+ *
+ * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
+ * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr>
+ * Copyright (C) 2012 Alexander Tarasikov <alexander.tarasikov@gmail.com>
+ *
+ * samsung-ril is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * samsung-ril is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __COMPAT_H__
+#define __COMPAT_H__
+
+#include <telephony/ril.h>
+#include <utils/Log.h>
+
+#ifndef LOGE
+ #define LOGE ALOGE
+#endif
+
+#ifndef LOGI
+ #define LOGI ALOGI
+#endif
+
+#ifndef LOGD
+ #define LOGD ALOGD
+#endif
+
+#if RIL_VERSION >= 6
+ #define RIL_REQUEST_REGISTRATION_STATE RIL_REQUEST_VOICE_REGISTRATION_STATE
+ #define RIL_REQUEST_GPRS_REGISTRATION_STATE RIL_REQUEST_DATA_REGISTRATION_STATE
+ #define RIL_SignalStrength RIL_SignalStrength_v6
+ #define RIL_CardStatus RIL_CardStatus_v6
+ #define RIL_SIM_IO RIL_SIM_IO_v6
+ #define RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED
+ #define COMPAT_RADIO_STATE_ON RADIO_STATE_ON
+#else
+ #define COMPAT_RADIO_STATE_ON RADIO_STATE_SIM_READY
+#endif
+
+//set it to the maximum supported revision
+//we've not yet fully implemented version 7
+#define SAMSUNG_RIL_VERSION 6
+
+#endif //__COMPAT_H__
diff --git a/misc.c b/misc.c
index 2ef9e4f..b6d70bc 100644
--- a/misc.c
+++ b/misc.c
@@ -30,7 +30,8 @@ void ril_request_get_imei_send(RIL_Token t)
unsigned char data;
data = IPC_MISC_ME_SN_SERIAL_NUM;
- ipc_fmt_send(IPC_MISC_ME_SN, IPC_TYPE_GET, (unsigned char *) &data, sizeof(data), reqGetId(t));
+ ipc_fmt_send(IPC_MISC_ME_SN, IPC_TYPE_GET,
+ (unsigned char *) &data, sizeof(data), reqGetId(t));
}
void ril_request_get_imei(RIL_Token t)
@@ -44,7 +45,7 @@ void ril_request_get_imei(RIL_Token t)
ril_state.tokens.get_imei = t;
if(ril_state.tokens.get_imeisv) {
- LOGD("IMEISV token found: 0x%x", ril_state.tokens.get_imeisv);
+ LOGD("IMEISV token found: 0x%p", ril_state.tokens.get_imeisv);
if(ril_state.radio_state != RADIO_STATE_OFF) {
ril_request_get_imei_send(ril_state.tokens.get_imei);
@@ -67,7 +68,7 @@ void ril_request_get_imeisv(RIL_Token t)
ril_state.tokens.get_imeisv = t;
if(ril_state.tokens.get_imei) {
- LOGD("IMEI token found: 0x%x", ril_state.tokens.get_imei);
+ LOGD("IMEI token found: 0x%p", ril_state.tokens.get_imei);
if(ril_state.radio_state != RADIO_STATE_OFF) {
ril_request_get_imei_send(ril_state.tokens.get_imei);
@@ -88,7 +89,8 @@ void ipc_misc_me_sn_imei(RIL_Token t, void *data, int length)
imei_info = (struct ipc_misc_me_sn *) data;
if(ril_state.tokens.get_imei != t)
- LOGE("IMEI tokens mismatch (0x%x and 0x%x)", ril_state.tokens.get_imei, t);
+ LOGE("IMEI tokens mismatch (0x%p and 0x%p)",
+ ril_state.tokens.get_imei, t);
if(imei_info->length > 32)
return;
@@ -108,13 +110,15 @@ void ipc_misc_me_sn_imei(RIL_Token t, void *data, int length)
// IMEI
if(ril_state.tokens.get_imei) {
- RIL_onRequestComplete(ril_state.tokens.get_imei, RIL_E_SUCCESS, imei, sizeof(char *));
+ RIL_onRequestComplete(ril_state.tokens.get_imei,
+ RIL_E_SUCCESS, imei, sizeof(char *));
ril_state.tokens.get_imei = 0;
}
// IMEI SV
if(ril_state.tokens.get_imeisv) {
- RIL_onRequestComplete(ril_state.tokens.get_imeisv, RIL_E_SUCCESS, imeisv, sizeof(char *));
+ RIL_onRequestComplete(ril_state.tokens.get_imeisv,
+ RIL_E_SUCCESS, imeisv, sizeof(char *));
ril_state.tokens.get_imeisv = 0;
}
}
@@ -128,7 +132,8 @@ void ipc_misc_me_sn(struct ipc_message_info *info)
ipc_misc_me_sn_imei(reqGetToken(info->aseq), info->data, info->length);
break;
case IPC_MISC_ME_SN_SERIAL_NUM_SERIAL:
- LOGD("Got IPC_MISC_ME_SN_SERIAL_NUM_SERIAL: %s\n", me_sn_info->data);
+ LOGD("Got IPC_MISC_ME_SN_SERIAL_NUM_SERIAL: %s\n",
+ me_sn_info->data);
break;
}
}
@@ -147,18 +152,22 @@ void ril_request_baseband_version(RIL_Token t)
if(ril_state.radio_state != RADIO_STATE_OFF) {
data = 0xff;
- ipc_fmt_send(IPC_MISC_ME_VERSION, IPC_TYPE_GET, (unsigned char *) &data, sizeof(data), reqGetId(t));
+ ipc_fmt_send(IPC_MISC_ME_VERSION, IPC_TYPE_GET,
+ (unsigned char *) &data, sizeof(data), reqGetId(t));
}
}
void ipc_misc_me_version(struct ipc_message_info *info)
{
char sw_version[33];
- struct ipc_misc_me_version *version = (struct ipc_misc_me_version *) info->data;
+ struct ipc_misc_me_version *version =
+ (struct ipc_misc_me_version *) info->data;
RIL_Token t = reqGetToken(info->aseq);
if(ril_state.tokens.baseband_version != t)
- LOGE("Baseband tokens mismatch (0x%x and 0x%x)", ril_state.tokens.baseband_version, t);
+ LOGE("Baseband tokens mismatch (0x%p and 0x%p)",
+ ril_state.tokens.baseband_version, t);
+
memcpy(sw_version, version->sw_version, 32);
sw_version[32] = '\0';
@@ -195,7 +204,8 @@ void ipc_misc_me_imsi(struct ipc_message_info *info)
if(info->length < 1) {
LOGE("%s: zero data length", __FUNCTION__);
- RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ RIL_onRequestComplete(reqGetToken(info->aseq),
+ RIL_E_GENERIC_FAILURE, NULL, 0);
return;
}
@@ -203,7 +213,8 @@ void ipc_misc_me_imsi(struct ipc_message_info *info)
if(((int) info->length) < *imsi_length + 1) {
LOGE("%s: missing IMSI data", __FUNCTION__);
- RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ RIL_onRequestComplete(reqGetToken(info->aseq),
+ RIL_E_GENERIC_FAILURE, NULL, 0);
return;
}
@@ -212,7 +223,8 @@ void ipc_misc_me_imsi(struct ipc_message_info *info)
memcpy(imsi, ((unsigned char*) info->data) + 1, *imsi_length);
imsi[*imsi_length] = '\0';
- RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, imsi, *imsi_length+1);
+ RIL_onRequestComplete(reqGetToken(info->aseq),
+ RIL_E_SUCCESS, imsi, *imsi_length+1);
}
void ipc_misc_time_info(struct ipc_message_info *info)
@@ -221,7 +233,9 @@ void ipc_misc_time_info(struct ipc_message_info *info)
char str[128];
sprintf(str, "%02u/%02u/%02u,%02u:%02u:%02u+%02d,%02d",
- nitz->year, nitz->mon, nitz->day, nitz->hour, nitz->min, nitz->sec, nitz->tz, 0);
+ nitz->year, nitz->mon, nitz->day, nitz->hour,
+ nitz->min, nitz->sec, nitz->tz, 0);
- RIL_onUnsolicitedResponse(RIL_UNSOL_NITZ_TIME_RECEIVED, str, strlen(str) + 1);
+ RIL_onUnsolicitedResponse(RIL_UNSOL_NITZ_TIME_RECEIVED,
+ str, strlen(str) + 1);
}
diff --git a/net.c b/net.c
index eecdfc6..24b27e3 100644
--- a/net.c
+++ b/net.c
@@ -217,9 +217,9 @@ int ril_tokens_net_get_data_waiting(void)
void ril_tokens_net_state_dump(void)
{
LOGD("ril_tokens_net_state_dump:\n\
- \tril_state.tokens.registration_state = 0x%x\n\
- \tril_state.tokens.gprs_registration_state = 0x%x\n\
- \tril_state.tokens.operator = 0x%x\n", ril_state.tokens.registration_state, ril_state.tokens.gprs_registration_state, ril_state.tokens.operator);
+ \tril_state.tokens.registration_state = 0x%p\n\
+ \tril_state.tokens.gprs_registration_state = 0x%p\n\
+ \tril_state.tokens.operator = 0x%p\n", ril_state.tokens.registration_state, ril_state.tokens.gprs_registration_state, ril_state.tokens.operator);
}
void ril_plmn_split(char *plmn_data, char **plmn, unsigned int *mcc, unsigned int *mnc)
@@ -323,7 +323,7 @@ void ril_plmn_string(char *plmn_data, char *response[3])
void ril_request_operator(RIL_Token t)
{
char *response[3];
- int i;
+ size_t i;
// IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
@@ -388,7 +388,7 @@ void ipc_net_current_plmn(struct ipc_message_info *message)
struct ipc_net_current_plmn *plmndata = (struct ipc_net_current_plmn *) message->data;
char *response[3];
- int i;
+ size_t i;
switch(message->type) {
case IPC_TYPE_NOTI:
@@ -528,7 +528,7 @@ void ril_request_gprs_registration_state(RIL_Token t)
{
struct ipc_net_regist_get regist_req;
char *response[4];
- int i;
+ size_t i;
if(ril_state.tokens.gprs_registration_state == RIL_TOKEN_DATA_WAITING) {
LOGD("Got RILJ request for UNSOL data");
@@ -621,7 +621,7 @@ void ipc_net_regist_unsol(struct ipc_message_info *message)
void ipc_net_regist_sol(struct ipc_message_info *message)
{
char *response[4];
- int i;
+ size_t i;
struct ipc_net_regist *netinfo = (struct ipc_net_regist *) message->data;
RIL_Token t = reqGetToken(message->aseq);
@@ -798,11 +798,16 @@ void ipc_net_plmn_sel(struct ipc_message_info *info)
struct ipc_net_plmn_sel_get *plmn_sel;
int ril_mode;
- if (info->data != NULL && info->length >= sizeof(struct ipc_net_plmn_sel_get)) {
- plmn_sel = (struct ipc_net_plmn_sel_get *) info->data;
- ril_mode = ipc2ril_plmn_sel(plmn_sel->plmn_sel);
- RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &ril_mode, sizeof(int));
- }
+ if (!info)
+ return;
+
+ if (!info->data || info->length < sizeof(struct ipc_net_plmn_sel_get))
+ return;
+
+ plmn_sel = (struct ipc_net_plmn_sel_get *) info->data;
+ ril_mode = ipc2ril_plmn_sel(plmn_sel->plmn_sel);
+ RIL_onRequestComplete(reqGetToken(info->aseq),
+ RIL_E_SUCCESS, &ril_mode, sizeof(int));
}
void ipc_net_plmn_sel_complete(struct ipc_message_info *info)
diff --git a/samsung-ril.c b/samsung-ril.c
index cfd7f20..daa756a 100644
--- a/samsung-ril.c
+++ b/samsung-ril.c
@@ -541,7 +541,7 @@ void ril_state_lpm(void)
static const RIL_RadioFunctions ril_ops = {
- RIL_VERSION,
+ SAMSUNG_RIL_VERSION,
onRequest,
currentState,
onSupports,
diff --git a/samsung-ril.h b/samsung-ril.h
index 2b40c05..493fb43 100644
--- a/samsung-ril.h
+++ b/samsung-ril.h
@@ -27,6 +27,7 @@
#include <telephony/ril.h>
#include <radio.h>
+#include "compat.h"
#include "ipc.h"
#include "srs.h"
@@ -262,6 +263,7 @@ void ril_request_enter_sim_pin(RIL_Token t, void *data, size_t datalen);
void ril_request_change_sim_pin(RIL_Token t, void *data, size_t datalen);
void ril_request_enter_sim_puk(RIL_Token t, void *data, size_t datalen);
void ril_request_query_facility_lock(RIL_Token t, void *data, size_t datalen);
+void ipc_sec_phone_lock(struct ipc_message_info *info);
void ipc_sec_phone_lock_complete(struct ipc_message_info *info);
void ril_request_set_facility_lock(RIL_Token t, void *data, size_t datalen);
diff --git a/sec.c b/sec.c
index 46856ca..a6b24b6 100644
--- a/sec.c
+++ b/sec.c
@@ -83,12 +83,12 @@ void ril_state_update(SIM_Status status)
/* If power mode isn't at least normal, don't update RIL state */
if(ril_state.power_mode < POWER_MODE_NORMAL)
return;
-
+
ril_state.sim_status = status;
switch(status) {
case SIM_READY:
- radio_state = RADIO_STATE_SIM_READY;
+ radio_state = COMPAT_RADIO_STATE_ON;
break;
case SIM_NOT_READY:
radio_state = RADIO_STATE_SIM_NOT_READY;
@@ -107,6 +107,7 @@ void ril_state_update(SIM_Status status)
radio_state = RADIO_STATE_SIM_NOT_READY;
break;
}
+
ril_state.radio_state = radio_state;
@@ -191,7 +192,7 @@ void ipc2ril_card_status(struct ipc_sec_pin_status_response *pin_status, RIL_Car
void ril_tokens_pin_status_dump(void)
{
LOGD("ril_tokens_pin_status_dump:\n\
- \tril_state.tokens.pin_status = 0x%x\n", ril_state.tokens.pin_status);
+ \tril_state.tokens.pin_status = 0x%p\n", ril_state.tokens.pin_status);
}
/**
diff --git a/sms.c b/sms.c
index c594a3b..7a21ae3 100644
--- a/sms.c
+++ b/sms.c
@@ -229,7 +229,7 @@ void ril_request_sms_lock_release(void)
*/
void ril_request_send_sms(RIL_Token t, void *data, size_t datalen)
{
- const char **request = (char **) data;
+ char **request = (char **) data;
char *pdu = request[1];
int pdu_len = pdu != NULL ? strlen(pdu) : 0;
char *smsc = request[0];
@@ -372,7 +372,7 @@ void ril_request_send_sms_complete(RIL_Token t, char *pdu, char *smsc)
LOGD("data_len is 0x%x + 0x%x + 0x%x = 0x%x\n", pdu_dec_len, smsc_len, send_msg_len, data_len);
pdu_dec = malloc(pdu_dec_len);
- hex2bin(pdu, pdu_len, pdu_dec);
+ hex2bin(pdu, pdu_len, (unsigned char*)pdu_dec);
/* PDU operations */
int pdu_tp_da_index = 2;
@@ -697,7 +697,7 @@ void ipc_sms_deliver_report(struct ipc_message_info *info)
void ipc_sms_device_ready(struct ipc_message_info *info)
{
- if(ril_state.radio_state == RADIO_STATE_SIM_READY) {
+ if(ril_state.radio_state == COMPAT_RADIO_STATE_ON) {
ipc_fmt_send(IPC_SMS_DEVICE_READY, IPC_TYPE_SET, NULL, 0, info->aseq);
}
diff --git a/srs.c b/srs.c
index def0fc4..3c519ab 100644
--- a/srs.c
+++ b/srs.c
@@ -69,7 +69,8 @@ int srs_server_send_message(struct srs_server *srs_server, struct srs_message *m
memset(data, 0, header.length);
memcpy(data, &header, sizeof(header));
- memcpy((void *) (data + sizeof(header)), message->data, message->data_len);
+ memcpy((void *) ((char*)data + sizeof(header)),
+ message->data, message->data_len);
FD_ZERO(&fds);
FD_SET(srs_server->client_fd, &fds);
@@ -107,7 +108,7 @@ int srs_server_recv(struct srs_server *srs_server, struct srs_message *message)
int rc;
rc = read(srs_server->client_fd, raw_data, SRS_DATA_MAX_SIZE);
- if(rc < sizeof(struct srs_header)) {
+ if(rc < (int)sizeof(struct srs_header)) {
return -1;
}
@@ -117,7 +118,8 @@ int srs_server_recv(struct srs_server *srs_server, struct srs_message *message)
message->data_len = header->length - sizeof(struct srs_header);
message->data = malloc(message->data_len);
- memcpy(message->data, raw_data + sizeof(struct srs_header), message->data_len);
+ memcpy(message->data, (char*)raw_data + sizeof(struct srs_header),
+ message->data_len);
free(raw_data);
@@ -134,7 +136,8 @@ int srs_server_accept(struct srs_server *srs_server)
return 0;
}
- client_fd = accept(srs_server->server_fd, (struct sockaddr_un *) &client_addr, &client_addr_len);
+ client_fd = accept(srs_server->server_fd,
+ (struct sockaddr*) &client_addr, &client_addr_len);
if(client_fd > 0) {
srs_server->client_fd = client_fd;
@@ -169,7 +172,7 @@ int srs_server_open(struct srs_server *srs_server)
while(t < 5) {
unlink(SRS_SOCKET_NAME);
- server_fd = socket_local_server(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
+ server_fd = socket_local_server(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
if(server_fd > 0)
break;
diff --git a/ss.c b/ss.c
index 44a16cc..3201a21 100644
--- a/ss.c
+++ b/ss.c
@@ -61,9 +61,7 @@ void ril_request_send_ussd(RIL_Token t, void *data, size_t datalen)
case IPC_SS_USSD_TIME_OUT:
LOGD("USSD Tx encoding is GSM7");
- data_enc_len = ascii2gsm7(data, &data_enc, datalen);
- // message_size = data_enc_len + sizeof(struct ipc_ss_ussd);
-
+ data_enc_len = ascii2gsm7(data, (unsigned char**)&data_enc, datalen);
if(data_enc_len > message_size) {
LOGE("USSD message size is too long, aborting");
RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
@@ -90,8 +88,7 @@ void ril_request_send_ussd(RIL_Token t, void *data, size_t datalen)
default:
LOGD("USSD Tx encoding is ASCII");
- data_enc_len = asprintf(&data_enc, "%s", data);
- // message_size = data_enc_len + sizeof(struct ipc_ss_ussd);
+ data_enc_len = asprintf(&data_enc, "%s", (char*)data);
if(data_enc_len > message_size) {
LOGE("USSD message size is too long, aborting");
@@ -172,13 +169,14 @@ void ipc_ss_ussd(struct ipc_message_info *info)
{
char *data_dec = NULL;
int data_dec_len = 0;
+ SmsCodingScheme codingScheme;
char *message[2];
struct ipc_ss_ussd *ussd = NULL;
unsigned char state;
- memset(message, 0, sizeof(message) / sizeof(char *));
+ memset(message, 0, sizeof(message));
ussd = (struct ipc_ss_ussd *) info->data;
@@ -187,17 +185,34 @@ 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 + sizeof(struct ipc_ss_ussd), &data_dec, info->length - sizeof(struct ipc_ss_ussd));
+ data_dec_len = gsm72ascii(info->data
+ + sizeof(struct ipc_ss_ussd), &data_dec, info->length - sizeof(struct ipc_ss_ussd));
asprintf(&message[1], "%s", data_dec);
message[1][data_dec_len] = '\0';
break;
+ 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 = (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);
+ }
+ message[1][result] = '\0';
+ break;
default:
- LOGD("USSD Rx encoding is unknown, assuming ASCII");
+ LOGD("USSD Rx encoding %x is unknown, assuming ASCII",
+ ussd->dcs);
data_dec_len = info->length - sizeof(struct ipc_ss_ussd);
asprintf(&message[1], "%s", info->data + sizeof(struct ipc_ss_ussd));
diff --git a/util.c b/util.c
index 5f7b716..9c08c5a 100644
--- a/util.c
+++ b/util.c
@@ -20,9 +20,13 @@
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#define LOG_TAG "RIL-UTIL"
#include <utils/Log.h>
+#include "util.h"
+
+#include "samsung-ril.h"
/**
* Converts a hexidecimal string to binary
@@ -134,6 +138,9 @@ int ascii2gsm7(char *data, unsigned char **data_enc, int length)
enc_length = ((length * 7) - (length * 7) % 8) / 8;
enc_length += (length * 7) % 8 > 0 ? 1 : 0;
+ //FIXME: why does samsung does that?
+ enc_length++;
+
enc = malloc(enc_length);
memset(enc, 0, enc_length);
@@ -159,6 +166,10 @@ int ascii2gsm7(char *data, unsigned char **data_enc, int length)
}
*data_enc = enc;
+
+ //FIXME: what is going on here?
+ enc[enc_length - 2] |= 0x30;
+ enc[enc_length - 1] = 0x02;
return enc_length;
}
@@ -216,3 +227,73 @@ void hex_dump(void *data, int size)
LOGD("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
}
}
+
+/* writes the utf8 character encoded in v
+ * to the buffer utf8 at the specified offset
+ */
+int utf8_write(char *utf8, int offset, int v)
+{
+
+ int result;
+
+ if (v < 0x80) {
+ result = 1;
+ if (utf8)
+ utf8[offset] = (char)v;
+ } else if (v < 0x800) {
+ result = 2;
+ if (utf8) {
+ utf8[offset + 0] = (char)(0xc0 | (v >> 6));
+ utf8[offset + 1] = (char)(0x80 | (v & 0x3f));
+ }
+ } else if (v < 0x10000) {
+ result = 3;
+ if (utf8) {
+ utf8[offset + 0] = (char)(0xe0 | (v >> 12));
+ utf8[offset + 1] = (char)(0x80 | ((v >> 6) & 0x3f));
+ utf8[offset + 2] = (char)(0x80 | (v & 0x3f));
+ }
+ } else {
+ result = 4;
+ if (utf8) {
+ utf8[offset + 0] = (char)(0xf0 | ((v >> 18) & 0x7));
+ utf8[offset + 1] = (char)(0x80 | ((v >> 12) & 0x3f));
+ utf8[offset + 2] = (char)(0x80 | ((v >> 6) & 0x3f));
+ utf8[offset + 3] = (char)(0x80 | (v & 0x3f));
+ }
+ }
+ return result;
+}
+
+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;
+}
+
diff --git a/util.h b/util.h
index 6eedbbc..9d5e51b 100644
--- a/util.h
+++ b/util.h
@@ -26,5 +26,14 @@ void hex2bin(const char *data, int length, unsigned char *buf);
int gsm72ascii(unsigned char *data, char **data_dec, int length);
int ascii2gsm7(char *data, unsigned char **data_enc, int length);
void hex_dump(void *data, int size);
+int utf8_write(char *utf8, int offset, int v);
+
+typedef enum {
+ SMS_CODING_SCHEME_UNKNOWN = 0,
+ SMS_CODING_SCHEME_GSM7,
+ SMS_CODING_SCHEME_UCS2
+} SmsCodingScheme;
+
+SmsCodingScheme sms_get_coding_scheme(int dataCoding);
#endif