diff options
author | Alexander Tarasikov <alexander.tarasikov@gmail.com> | 2012-08-24 20:24:35 +0400 |
---|---|---|
committer | Alexander Tarasikov <alexander.tarasikov@gmail.com> | 2012-08-24 20:24:35 +0400 |
commit | 554a526381db5cda5dda5724e8fcbe94fca6f3d9 (patch) | |
tree | 3b79dec643be682d7ed1bd0edb4ab0a37feb9f7a | |
parent | ccf9b863a3f5b118b13c54f030ef7a77e672d758 (diff) | |
parent | c4d12a5c5bcb5fe29fb13e9afa23975af3fbb63b (diff) | |
download | hardware_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.mk | 14 | ||||
-rw-r--r-- | client.c | 2 | ||||
-rw-r--r-- | compat.h | 57 | ||||
-rw-r--r-- | misc.c | 44 | ||||
-rw-r--r-- | net.c | 29 | ||||
-rw-r--r-- | samsung-ril.c | 2 | ||||
-rw-r--r-- | samsung-ril.h | 2 | ||||
-rw-r--r-- | sec.c | 7 | ||||
-rw-r--r-- | sms.c | 6 | ||||
-rw-r--r-- | srs.c | 13 | ||||
-rw-r--r-- | ss.c | 35 | ||||
-rw-r--r-- | util.c | 81 | ||||
-rw-r--r-- | util.h | 9 |
13 files changed, 249 insertions, 52 deletions
@@ -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 @@ -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__ @@ -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); } @@ -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); @@ -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); } /** @@ -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); } @@ -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; @@ -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)); @@ -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; +} + @@ -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 |