4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
28 #include <core_object.h>
37 #include "imc_common.h"
39 #define PROACTV_CMD_LEN 256
41 static void on_response_enable_sat(TcorePending *p,
42 guint data_len, const void *data, void *user_data)
44 const TcoreAtResponse *at_resp = data;
46 if (at_resp && at_resp->success) {
47 dbg("Enable SAT (Proactive command) - [OK]");
50 err("Enable SAT (Proactive command) - [NOK]");
55 static TcoreHookReturn on_hook_imc_sim_status(TcorePlugin *plugin,
56 TcoreNotification command, guint data_len, void *data, void *user_data)
58 const TelSimCardStatus *sim_status = (TelSimCardStatus *)data;
59 CoreObject *co = (CoreObject *)user_data;
61 tcore_check_return_value(sim_status != NULL, TCORE_HOOK_RETURN_CONTINUE);
64 * If SIM is initialized -
67 dbg("SIM Status: [%d]", *sim_status);
68 if (*sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
69 dbg("SIM Initialized!!! Enable SAT");
71 /* Enable SAT - Send AT+CFUN=6 */
72 tcore_at_prepare_and_send_request(co,
74 TCORE_AT_COMMAND_TYPE_NO_RESULT,
76 on_response_enable_sat, NULL,
77 on_send_imc_request, NULL);
80 return TCORE_HOOK_RETURN_CONTINUE;
83 static gboolean on_response_imc_sat_terminal_response_confirm
84 (CoreObject *co, const void *event_info, void *user_data)
90 static gboolean on_notification_imc_sat_proactive_command
91 (CoreObject *co, const void *event_info, void *user_data)
93 TelSatDecodedProactiveData decoded_data;
94 TelSatNotiProactiveData proactive_noti;
95 gint proactive_cmd_len = 0;
97 GSList *tokens = NULL;
99 gchar *hex_data = NULL;
101 gchar *record_data = NULL;
102 guint record_data_len;
104 gboolean decode_ret = FALSE;
108 tcore_check_return_value_assert(co != NULL, FALSE);
109 memset(&proactive_noti, 0x00, sizeof(TelSatNotiProactiveData));
110 memset(&decoded_data, 0x00, sizeof(TelSatDecodedProactiveData));
112 lines = (GSList *) event_info;
113 line = (gchar *) lines->data;
114 tokens = tcore_at_tok_new(line);
115 if (g_slist_length(tokens) != 1) {
116 err("Invalid message");
117 tcore_at_tok_free(tokens);
121 hex_data = (gchar *)g_slist_nth_data(tokens, 0);
122 dbg("SAT data: [%s] SAT data length: [%d]", hex_data, strlen(hex_data));
124 tmp = (gchar *)tcore_at_tok_extract((gchar *)hex_data);
125 tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
126 dbg("record_data: %x", record_data);
129 tcore_util_hex_dump(" ", strlen(hex_data) / 2, record_data);
130 proactive_cmd_len = strlen(record_data);
131 dbg("proactive_cmd_len = %d", proactive_cmd_len);
133 decode_ret = tcore_sat_decode_proactive_command((guchar *) record_data,
134 record_data_len, &decoded_data, &decode_err);
136 err("Proactive Command decoding failed");
137 tcore_at_tok_free(tokens);
141 tcore_free(record_data);
143 proactive_noti.cmd_number = decoded_data.cmd_num;
144 proactive_noti.cmd_type = decoded_data.cmd_type;
145 proactive_noti.decode_err_code = decode_err;
147 switch (decoded_data.cmd_type) {
148 case TEL_SAT_PROATV_CMD_DISPLAY_TEXT:
149 dbg("decoded command is display text!!");
150 memcpy(&proactive_noti.proactive_ind_data.display_text,
151 &decoded_data.data.display_text,
152 sizeof(TelSatDisplayTextTlv));
155 case TEL_SAT_PROATV_CMD_GET_INKEY:
156 dbg("decoded command is get inkey!!");
157 memcpy(&proactive_noti.proactive_ind_data.get_inkey,
158 &decoded_data.data.get_inkey,
159 sizeof(TelSatGetInkeyTlv));
162 case TEL_SAT_PROATV_CMD_GET_INPUT:
163 dbg("decoded command is get input!!");
164 memcpy(&proactive_noti.proactive_ind_data.get_input,
165 &decoded_data.data.get_input,
166 sizeof(TelSatGetInputTlv));
169 case TEL_SAT_PROATV_CMD_MORE_TIME:
170 dbg("decoded command is more time!!");
171 memcpy(&proactive_noti.proactive_ind_data.more_time,
172 &decoded_data.data.more_time,
173 sizeof(TelSatMoreTimeTlv));
176 case TEL_SAT_PROATV_CMD_PLAY_TONE:
177 dbg("decoded command is play tone!!");
178 memcpy(&proactive_noti.proactive_ind_data.play_tone,
179 &decoded_data.data.play_tone,
180 sizeof(TelSatPlayToneTlv));
183 case TEL_SAT_PROATV_CMD_SETUP_MENU:
184 dbg("decoded command is SETUP MENU!!");
185 memcpy(&proactive_noti.proactive_ind_data.setup_menu,
186 &decoded_data.data.setup_menu, sizeof(TelSatSetupMenuTlv));
189 case TEL_SAT_PROATV_CMD_SELECT_ITEM:
190 dbg("decoded command is select item!!");
191 memcpy(&proactive_noti.proactive_ind_data.select_item,
192 &decoded_data.data.select_item,
193 sizeof(TelSatSelectItemTlv));
196 case TEL_SAT_PROATV_CMD_SEND_SMS:
197 dbg("decoded command is send sms!!");
198 memcpy(&proactive_noti.proactive_ind_data.send_sms,
199 &decoded_data.data.send_sms,
200 sizeof(TelSatSendSmsTlv));
203 case TEL_SAT_PROATV_CMD_SEND_SS:
204 dbg("decoded command is send ss!!");
205 memcpy(&proactive_noti.proactive_ind_data.send_ss,
206 &decoded_data.data.send_ss,
207 sizeof(TelSatSendSsTlv));
210 case TEL_SAT_PROATV_CMD_SEND_USSD:
211 dbg("decoded command is send ussd!!");
212 memcpy(&proactive_noti.proactive_ind_data.send_ussd,
213 &decoded_data.data.send_ussd,
214 sizeof(TelSatSendUssdTlv));
217 case TEL_SAT_PROATV_CMD_SETUP_CALL:
218 dbg("decoded command is setup call!!");
219 memcpy(&proactive_noti.proactive_ind_data.setup_call,
220 &decoded_data.data.setup_call,
221 sizeof(TelSatSetupCallTlv));
224 case TEL_SAT_PROATV_CMD_REFRESH:
225 dbg("decoded command is refresh");
226 memcpy(&proactive_noti.proactive_ind_data.refresh,
227 &decoded_data.data.refresh, sizeof(TelSatRefreshTlv));
230 case TEL_SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
231 dbg("decoded command is provide local info");
232 memcpy(&proactive_noti.proactive_ind_data.provide_local_info,
233 &decoded_data.data.provide_local_info,
234 sizeof(TelSatProvideLocalInfoTlv));
237 case TEL_SAT_PROATV_CMD_SETUP_EVENT_LIST:
238 dbg("decoded command is setup event list!!");
239 memcpy(&proactive_noti.proactive_ind_data.setup_event_list,
240 &decoded_data.data.setup_event_list,
241 sizeof(TelSatSetupEventListTlv));
242 // setup_event_rsp_get(o, &decoded_data.data.setup_event_list);
245 case TEL_SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT:
246 dbg("decoded command is setup idle mode text");
247 memcpy(&proactive_noti.proactive_ind_data.setup_idle_mode_text,
248 &decoded_data.data.setup_idle_mode_text,
249 sizeof(TelSatSetupIdleModeTextTlv));
252 case TEL_SAT_PROATV_CMD_SEND_DTMF:
253 dbg("decoded command is send dtmf");
254 memcpy(&proactive_noti.proactive_ind_data.send_dtmf,
255 &decoded_data.data.send_dtmf,
256 sizeof(TelSatSendDtmfTlv));
259 case TEL_SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
260 dbg("decoded command is language notification");
261 memcpy(&proactive_noti.proactive_ind_data.language_notification,
262 &decoded_data.data.language_notification,
263 sizeof(TelSatLanguageNotificationTlv));
266 case TEL_SAT_PROATV_CMD_LAUNCH_BROWSER:
267 dbg("decoded command is launch browser");
268 memcpy(&proactive_noti.proactive_ind_data.launch_browser,
269 &decoded_data.data.launch_browser,
270 sizeof(TelSatLaunchBrowserTlv));
273 case TEL_SAT_PROATV_CMD_OPEN_CHANNEL:
274 dbg("decoded command is open channel!!");
275 memcpy(&proactive_noti.proactive_ind_data.open_channel,
276 &decoded_data.data.open_channel,
277 sizeof(TelSatOpenChannelTlv));
280 case TEL_SAT_PROATV_CMD_CLOSE_CHANNEL:
281 dbg("decoded command is close channel!!");
282 memcpy(&proactive_noti.proactive_ind_data.close_channel,
283 &decoded_data.data.close_channel,
284 sizeof(TelSatCloseChannelTlv));
287 case TEL_SAT_PROATV_CMD_RECEIVE_DATA:
288 dbg("decoded command is receive data!!");
289 memcpy(&proactive_noti.proactive_ind_data.receive_data,
290 &decoded_data.data.receive_data,
291 sizeof(TelSatReceiveChannelTlv));
294 case TEL_SAT_PROATV_CMD_SEND_DATA:
295 dbg("decoded command is send data!!");
296 memcpy(&proactive_noti.proactive_ind_data.send_data,
297 &decoded_data.data.send_data,
298 sizeof(TelSatSendChannelTlv));
301 case TEL_SAT_PROATV_CMD_GET_CHANNEL_STATUS:
302 dbg("decoded command is get channel status!!");
303 memcpy(&proactive_noti.proactive_ind_data.get_channel_status,
304 &decoded_data.data.get_channel_status,
305 sizeof(TelSatGetChannelStatusTlv));
309 dbg("invalid command:[%d]", decoded_data.cmd_type);
313 if (decoded_data.cmd_type == TEL_SAT_PROATV_CMD_REFRESH) {
315 dbg("Not suported Proactive command");
316 tcore_at_tok_free(tokens);
320 /* Send notification */
321 tcore_object_send_notification(co,
322 TCORE_NOTIFICATION_SAT_PROACTIVE_CMD,
323 sizeof(TelSatNotiProactiveData), &proactive_noti);
325 tcore_at_tok_free(tokens);
332 static void on_response_imc_sat_send_envelop_cmd(TcorePending *p,
333 guint data_len, const void *data, void *user_data)
335 const TcoreAtResponse *at_resp = data;
336 CoreObject *co = tcore_pending_ref_core_object(p);
337 ImcRespCbData *resp_cb_data = user_data;
338 TelSatEnvelopeResp envelop_resp;
339 TelSatResult result = TEL_SAT_RESULT_FAILURE;
340 GSList *tokens = NULL;
341 const gchar *line = NULL;
342 const gchar *env_res = NULL;
347 tcore_check_return_assert(co != NULL);
348 tcore_check_return_assert(resp_cb_data != NULL);
349 tcore_check_return_assert(resp_cb_data->cb != NULL);
351 if (at_resp && at_resp->success) {
352 result = TEL_SAT_RESULT_SUCCESS;
354 if (at_resp->lines) {
355 line = (const gchar *) at_resp->lines->data;
356 tokens = tcore_at_tok_new(line);
357 if (g_slist_length(tokens) < 1) {
358 err("invalid message");
359 tcore_at_tok_free(tokens);
363 env_res = g_slist_nth_data(tokens, 0);
364 envelop_resp = TEL_SAT_ENVELOPE_SUCCESS;
365 dbg("RESPONSE tokens present");
366 if (NULL != g_slist_nth_data(tokens, 1)) {
367 sw2 = atoi(g_slist_nth_data(tokens, 1));
368 dbg("status word SW2:[%d]", sw2);
370 dbg("Response is processed completely and sending session end notification");
371 /* Send Session End notification */
372 tcore_object_send_notification(co,
373 TCORE_NOTIFICATION_SAT_SESSION_END, 0, NULL);
378 envelop_resp = TEL_SAT_ENVELOPE_FAILED;
381 /* Invoke callback */
382 if (resp_cb_data->cb)
383 resp_cb_data->cb(co, (gint)result, &envelop_resp, resp_cb_data->cb_data);
385 imc_destroy_resp_cb_data(resp_cb_data);
386 tcore_at_tok_free(tokens);
390 static void on_response_imc_sat_send_terminal_response(TcorePending *p,
391 guint data_len, const void *data, void *user_data)
393 const TcoreAtResponse *at_resp = data;
394 CoreObject *co = tcore_pending_ref_core_object(p);
395 ImcRespCbData *resp_cb_data = user_data;
396 TelSatResult result = TEL_SAT_RESULT_FAILURE;
400 tcore_check_return_assert(co != NULL);
401 tcore_check_return_assert(resp_cb_data != NULL);
402 tcore_check_return_assert(resp_cb_data->cb != NULL);
404 if (at_resp && at_resp->success) {
405 result = TEL_SAT_RESULT_SUCCESS;
407 dbg(" at_resp->success = %d", at_resp->success);
408 /* Send Session End notification */
409 tcore_object_send_notification(co, TCORE_NOTIFICATION_SAT_SESSION_END, 0, NULL);
412 /* Invoke callback */
413 if (resp_cb_data->cb)
414 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
416 imc_destroy_resp_cb_data(resp_cb_data);
420 static void on_response_imc_sat_send_user_confirmation(TcorePending *p,
421 guint data_len, const void *data, void *user_data)
423 const TcoreAtResponse *at_resp = data;
424 CoreObject *co = tcore_pending_ref_core_object(p);
425 ImcRespCbData *resp_cb_data = user_data;
426 TelSatResult result = TEL_SAT_RESULT_FAILURE;
430 tcore_check_return_assert(co != NULL);
431 tcore_check_return_assert(resp_cb_data != NULL);
432 tcore_check_return_assert(resp_cb_data->cb != NULL);
434 if (at_resp && at_resp->success) {
436 result = TEL_SAT_RESULT_SUCCESS;
439 /* Invoke callback */
440 if (resp_cb_data->cb)
441 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
443 imc_destroy_resp_cb_data(resp_cb_data);
449 * Operation - Send Envelop Command
452 * AT-Command: AT+SATE
455 * Success: (Single line)
459 * +CME ERROR: <error>
461 static TelReturn imc_sat_send_envelope(CoreObject *co,
462 const TelSatRequestEnvelopCmdData *envelop_data,
463 TcoreObjectResponseCallback cb, void *cb_data)
466 gint envelope_cmd_len = 0;
467 gchar envelope_cmd[PROACTV_CMD_LEN];
469 gchar hex_string[PROACTV_CMD_LEN * 2];
470 gchar *buffer = NULL;
471 gboolean encode_ret = FALSE;
473 ImcRespCbData *resp_cb_data;
477 memset(&hex_string, 0x00, sizeof(hex_string));
480 encode_ret = tcore_sat_encode_envelop_cmd(envelop_data,
481 (gchar *)envelope_cmd, (gint *)&envelope_cmd_len);
483 err("Envelope Command encoding failed");
484 return TEL_RETURN_FAILURE;
487 dbg("envelope_cmd_len after encoding :[%d]", envelope_cmd_len);
488 if (envelope_cmd_len == 0) {
489 err("Envelope command length after encoding is NULL");
490 return TEL_RETURN_INVALID_PARAMETER;
493 for (count = 0; count < envelope_cmd_len; count++) {
494 dbg("envelope_cmd: %02x", (guchar)envelope_cmd[count]);
495 sprintf(buffer, "%02x", (guchar)envelope_cmd[count]);
498 dbg("hex_string: %s", hex_string);
501 at_cmd = g_strdup_printf("AT+SATE=\"%s\"", hex_string);
503 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
504 (void *)&envelop_data->sub_cmd, sizeof(TelSatEnvelopSubCmd));
506 /* Send Request to modem */
507 ret = tcore_at_prepare_and_send_request(co,
509 TCORE_AT_COMMAND_TYPE_SINGLELINE,
511 on_response_imc_sat_send_envelop_cmd, resp_cb_data,
512 on_send_imc_request, NULL);
513 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Envelop Command");
522 * Operation - Send Terminal Response
525 * AT-Command: AT+SATR
528 * Success: (NO Result)
531 * +CME ERROR: <error>
533 static TelReturn imc_sat_send_terminal_response(CoreObject *co,
534 const TelSatRequestTerminalResponseData *terminal_rsp_data,
535 TcoreObjectResponseCallback cb, void *cb_data)
538 gint terminal_resp_len = 0;
539 gchar terminal_resp[PROACTV_CMD_LEN];
541 gchar *hex_string = NULL;
542 gboolean encode_ret = FALSE;
544 ImcRespCbData *resp_cb_data;
549 encode_ret = tcore_sat_encode_terminal_response(terminal_rsp_data,
550 (gchar *)terminal_resp, (gint *)&terminal_resp_len);
552 err("Envelope Command encoding failed");
553 return TEL_RETURN_FAILURE;
556 dbg("terminal_resp after encoding: %s", terminal_resp);
557 dbg("terminal_resp length after encoding:[%d]", strlen(terminal_resp));
558 if (terminal_resp_len == 0) {
559 err("Terminal Response length after encoding is NULL");
560 return TEL_RETURN_INVALID_PARAMETER;
562 hex_string = calloc((terminal_resp_len * 2) + 1, 1);
564 for (i = 0; i < terminal_resp_len * 2; i += 2) {
566 value = (terminal_resp[i / 2] & 0xf0) >> 4;
568 hex_string[i] = ((terminal_resp[i / 2] & 0xf0) >> 4) + '0';
570 hex_string[i] = ((terminal_resp[i / 2] & 0xf0) >> 4) + 'A' - 10;
572 value = terminal_resp[i / 2] & 0x0f;
574 hex_string[i + 1] = (terminal_resp[i / 2] & 0x0f) + '0';
576 hex_string[i + 1] = (terminal_resp[i / 2] & 0x0f) + 'A' - 10;
578 dbg("hex_string: %s", hex_string);
581 at_cmd = g_strdup_printf("AT+SATR=\"%s\"", hex_string);
583 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
585 /* Send Request to modem */
586 ret = tcore_at_prepare_and_send_request(co,
588 TCORE_AT_COMMAND_TYPE_NO_RESULT,
590 on_response_imc_sat_send_terminal_response, resp_cb_data,
591 on_send_imc_request, NULL);
592 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Terminal Response");
601 * Operation - Send User Confirmation
604 * AT-Command: AT+SATD
607 * Success: (NO Result)
610 * +CME ERROR: <error>
612 static TelReturn imc_sat_send_user_confirmation(CoreObject *co,
613 const TelSatRequestUserConfirmationData *user_conf_data,
614 TcoreObjectResponseCallback cb, void *cb_data)
618 ImcRespCbData *resp_cb_data;
623 usr_conf = (guint)user_conf_data->user_conf;
624 dbg("User confirmation:[%d]", usr_conf);
627 at_cmd = g_strdup_printf("AT+SATD=%d", usr_conf);
629 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
631 /* Send Request to modem */
632 ret = tcore_at_prepare_and_send_request(co,
634 TCORE_AT_COMMAND_TYPE_NO_RESULT,
636 on_response_imc_sat_send_user_confirmation, resp_cb_data,
637 on_send_imc_request, NULL);
638 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send User Confirmation");
648 static TcoreSatOps imc_sat_ops = {
649 .send_envelope = imc_sat_send_envelope,
650 .send_terminal_response = imc_sat_send_terminal_response,
651 .send_user_confirmation = imc_sat_send_user_confirmation
655 gboolean imc_sat_init(TcorePlugin *p, CoreObject *co)
660 tcore_sat_set_ops(co, &imc_sat_ops);
664 * At present keeping the same notification processing for
665 * both SATI and SATN command. But in future notification processing
666 * will be seperated for both command depending on SAT re-architecure.
668 tcore_object_add_callback(co, "+SATI",
669 on_notification_imc_sat_proactive_command, NULL);
670 tcore_object_add_callback(co, "+SATN",
671 on_notification_imc_sat_proactive_command, NULL);
672 tcore_object_add_callback(co, "+SATF",
673 on_response_imc_sat_terminal_response_confirm, NULL);
676 tcore_plugin_add_notification_hook(p,
677 TCORE_NOTIFICATION_SIM_STATUS, on_hook_imc_sim_status, co);
684 void imc_sat_exit(TcorePlugin *p, CoreObject *co)