2 * This file is part of samsung-ril.
4 * Copyright (C) 2012 Paul Kocialkowski <contact@oaulk.fr>
6 * samsung-ril is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * samsung-ril is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>.
21 #define LOG_TAG "RIL-SS"
22 #include <utils/Log.h>
24 #include "samsung-ril.h"
27 void ipc_ss_ussd_complete(struct ipc_message_info *info)
29 struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
32 rc = ipc_gen_phone_res_check(phone_res);
34 LOGE("There was an error, aborting USSD request");
36 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
37 ril_state.ussd_state = 0;
42 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, NULL, 0);
45 void ril_request_send_ussd(RIL_Token t, void *data, size_t datalen)
47 char *data_enc = NULL;
51 struct ipc_ss_ussd *ussd = NULL;
53 int message_size = 0xc0;
55 switch(ril_state.ussd_state) {
57 case IPC_SS_USSD_NO_ACTION_REQUIRE:
58 case IPC_SS_USSD_TERMINATED_BY_NET:
59 case IPC_SS_USSD_OTHER_CLIENT:
60 case IPC_SS_USSD_NOT_SUPPORT:
61 case IPC_SS_USSD_TIME_OUT:
62 LOGD("USSD Tx encoding is GSM7");
64 data_enc_len = ascii2gsm7(data, (unsigned char**)&data_enc, datalen);
65 if(data_enc_len > message_size) {
66 LOGE("USSD message size is too long, aborting");
67 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
74 message = malloc(message_size);
75 memset(message, 0, message_size);
77 ussd = (struct ipc_ss_ussd *) message;
78 ussd->state = IPC_SS_USSD_NO_ACTION_REQUIRE;
79 ussd->dcs = 0x0f; // GSM7 in that case
80 ussd->length = data_enc_len;
82 memcpy((void *) (message + sizeof(struct ipc_ss_ussd)), data_enc, data_enc_len);
87 case IPC_SS_USSD_ACTION_REQUIRE:
89 LOGD("USSD Tx encoding is ASCII");
91 data_enc_len = asprintf(&data_enc, "%s", (char*)data);
93 if(data_enc_len > message_size) {
94 LOGE("USSD message size is too long, aborting");
95 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
102 message = malloc(message_size);
103 memset(message, 0, message_size);
105 ussd = (struct ipc_ss_ussd *) message;
106 ussd->state = IPC_SS_USSD_ACTION_REQUIRE;
107 ussd->dcs = 0x0f; // ASCII in that case
108 ussd->length = data_enc_len;
110 memcpy((void *) (message + sizeof(struct ipc_ss_ussd)), data_enc, data_enc_len);
117 if(message == NULL) {
118 LOGE("USSD message is empty, aborting");
120 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
124 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_SS_USSD,
125 ipc_ss_ussd_complete);
127 ipc_fmt_send(IPC_SS_USSD, IPC_TYPE_EXEC, (void *) message, message_size, reqGetId(t));
130 void ril_request_cancel_ussd(RIL_Token t, void *data, size_t datalen)
132 struct ipc_ss_ussd ussd;
134 memset(&ussd, 0, sizeof(ussd));
136 ussd.state = IPC_SS_USSD_TERMINATED_BY_NET;
137 ril_state.ussd_state = IPC_SS_USSD_TERMINATED_BY_NET;
139 ipc_gen_phone_res_expect_to_complete(reqGetId(t), IPC_SS_USSD);
141 ipc_fmt_send(IPC_SS_USSD, IPC_TYPE_EXEC, (void *) &ussd, sizeof(ussd), reqGetId(t));
144 void ipc2ril_ussd_state(struct ipc_ss_ussd *ussd, char *message[2])
146 switch(ussd->state) {
147 case IPC_SS_USSD_NO_ACTION_REQUIRE:
148 asprintf(&message[0], "%d", 0);
150 case IPC_SS_USSD_ACTION_REQUIRE:
151 asprintf(&message[0], "%d", 1);
153 case IPC_SS_USSD_TERMINATED_BY_NET:
154 asprintf(&message[0], "%d", 2);
156 case IPC_SS_USSD_OTHER_CLIENT:
157 asprintf(&message[0], "%d", 3);
159 case IPC_SS_USSD_NOT_SUPPORT:
160 asprintf(&message[0], "%d", 4);
162 case IPC_SS_USSD_TIME_OUT:
163 asprintf(&message[0], "%d", 5);
168 void ipc_ss_ussd(struct ipc_message_info *info)
170 char *data_dec = NULL;
171 int data_dec_len = 0;
172 SmsCodingScheme codingScheme;
176 struct ipc_ss_ussd *ussd = NULL;
179 memset(message, 0, sizeof(message));
181 ussd = (struct ipc_ss_ussd *) info->data;
183 ipc2ril_ussd_state(ussd, message);
185 ril_state.ussd_state = ussd->state;
187 if(ussd->length > 0 && info->length > 0 && info->data != NULL) {
188 codingScheme = sms_get_coding_scheme(ussd->dcs);
189 switch(codingScheme) {
190 case SMS_CODING_SCHEME_GSM7:
191 LOGD("USSD Rx encoding is GSM7");
193 data_dec_len = gsm72ascii(info->data
194 + sizeof(struct ipc_ss_ussd), &data_dec, info->length - sizeof(struct ipc_ss_ussd));
195 asprintf(&message[1], "%s", data_dec);
196 message[1][data_dec_len] = '\0';
199 case SMS_CODING_SCHEME_UCS2:
200 LOGD("USSD Rx encoding %x is UCS2", ussd->dcs);
202 data_dec_len = info->length - sizeof(struct ipc_ss_ussd);
203 message[1] = malloc(data_dec_len * 4 + 1);
206 char *ucs2 = (char*)info->data + sizeof(struct ipc_ss_ussd);
207 for (i = 0; i < data_dec_len; i += 2) {
208 int c = (ucs2[i] << 8) | ucs2[1 + i];
209 result += utf8_write(message[1], result, c);
211 message[1][result] = '\0';
214 LOGD("USSD Rx encoding %x is unknown, assuming ASCII",
217 data_dec_len = info->length - sizeof(struct ipc_ss_ussd);
218 asprintf(&message[1], "%s", info->data + sizeof(struct ipc_ss_ussd));
219 message[1][data_dec_len] = '\0';
224 RIL_onUnsolicitedResponse(RIL_UNSOL_ON_USSD, message, sizeof(message));