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,
75 TCORE_PENDING_PRIORITY_DEFAULT,
77 on_response_enable_sat, NULL,
78 on_send_imc_request, NULL,
82 return TCORE_HOOK_RETURN_CONTINUE;
85 static gboolean on_response_imc_sat_terminal_response_confirm
86 (CoreObject *co, const void *event_info, void *user_data)
92 static gboolean on_notification_imc_sat_proactive_command
93 (CoreObject *co, const void *event_info, void *user_data)
95 TelSatDecodedProactiveData decoded_data;
96 TelSatNotiProactiveData proactive_noti;
97 gint proactive_cmd_len = 0;
99 GSList *tokens = NULL;
101 gchar *hex_data = NULL;
103 gchar *record_data = NULL;
104 guint record_data_len;
106 gboolean decode_ret = FALSE;
110 tcore_check_return_value_assert(co != NULL, FALSE);
111 memset(&proactive_noti, 0x00, sizeof(TelSatNotiProactiveData));
112 memset(&decoded_data, 0x00, sizeof(TelSatDecodedProactiveData));
114 lines = (GSList *) event_info;
115 line = (gchar *) lines->data;
116 tokens = tcore_at_tok_new(line);
117 if (g_slist_length(tokens) != 1) {
118 err("Invalid message");
119 tcore_at_tok_free(tokens);
123 hex_data = (gchar *)g_slist_nth_data(tokens, 0);
124 dbg("SAT data: [%s] SAT data length: [%d]", hex_data, strlen(hex_data));
126 tmp = (gchar *)tcore_at_tok_extract((gchar *)hex_data);
127 tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
128 dbg("record_data: %x", record_data);
131 tcore_util_hex_dump(" ", strlen(hex_data) / 2, record_data);
132 proactive_cmd_len = strlen(record_data);
133 dbg("proactive_cmd_len = %d", proactive_cmd_len);
135 decode_ret = tcore_sat_decode_proactive_command((guchar *) record_data,
136 record_data_len, &decoded_data, &decode_err);
138 err("Proactive Command decoding failed");
139 tcore_at_tok_free(tokens);
143 tcore_free(record_data);
145 proactive_noti.cmd_number = decoded_data.cmd_num;
146 proactive_noti.cmd_type = decoded_data.cmd_type;
147 proactive_noti.decode_err_code = decode_err;
149 switch (decoded_data.cmd_type) {
150 case TEL_SAT_PROATV_CMD_DISPLAY_TEXT:
151 dbg("decoded command is display text!!");
152 memcpy(&proactive_noti.proactive_ind_data.display_text,
153 &decoded_data.data.display_text,
154 sizeof(TelSatDisplayTextTlv));
157 case TEL_SAT_PROATV_CMD_GET_INKEY:
158 dbg("decoded command is get inkey!!");
159 memcpy(&proactive_noti.proactive_ind_data.get_inkey,
160 &decoded_data.data.get_inkey,
161 sizeof(TelSatGetInkeyTlv));
164 case TEL_SAT_PROATV_CMD_GET_INPUT:
165 dbg("decoded command is get input!!");
166 memcpy(&proactive_noti.proactive_ind_data.get_input,
167 &decoded_data.data.get_input,
168 sizeof(TelSatGetInputTlv));
171 case TEL_SAT_PROATV_CMD_MORE_TIME:
172 dbg("decoded command is more time!!");
173 memcpy(&proactive_noti.proactive_ind_data.more_time,
174 &decoded_data.data.more_time,
175 sizeof(TelSatMoreTimeTlv));
178 case TEL_SAT_PROATV_CMD_PLAY_TONE:
179 dbg("decoded command is play tone!!");
180 memcpy(&proactive_noti.proactive_ind_data.play_tone,
181 &decoded_data.data.play_tone,
182 sizeof(TelSatPlayToneTlv));
185 case TEL_SAT_PROATV_CMD_SETUP_MENU:
186 dbg("decoded command is SETUP MENU!!");
187 memcpy(&proactive_noti.proactive_ind_data.setup_menu,
188 &decoded_data.data.setup_menu, sizeof(TelSatSetupMenuTlv));
191 case TEL_SAT_PROATV_CMD_SELECT_ITEM:
192 dbg("decoded command is select item!!");
193 memcpy(&proactive_noti.proactive_ind_data.select_item,
194 &decoded_data.data.select_item,
195 sizeof(TelSatSelectItemTlv));
198 case TEL_SAT_PROATV_CMD_SEND_SMS:
199 dbg("decoded command is send sms!!");
200 memcpy(&proactive_noti.proactive_ind_data.send_sms,
201 &decoded_data.data.send_sms,
202 sizeof(TelSatSendSmsTlv));
205 case TEL_SAT_PROATV_CMD_SEND_SS:
206 dbg("decoded command is send ss!!");
207 memcpy(&proactive_noti.proactive_ind_data.send_ss,
208 &decoded_data.data.send_ss,
209 sizeof(TelSatSendSsTlv));
212 case TEL_SAT_PROATV_CMD_SEND_USSD:
213 dbg("decoded command is send ussd!!");
214 memcpy(&proactive_noti.proactive_ind_data.send_ussd,
215 &decoded_data.data.send_ussd,
216 sizeof(TelSatSendUssdTlv));
219 case TEL_SAT_PROATV_CMD_SETUP_CALL:
220 dbg("decoded command is setup call!!");
221 memcpy(&proactive_noti.proactive_ind_data.setup_call,
222 &decoded_data.data.setup_call,
223 sizeof(TelSatSetupCallTlv));
226 case TEL_SAT_PROATV_CMD_REFRESH:
227 dbg("decoded command is refresh");
228 memcpy(&proactive_noti.proactive_ind_data.refresh,
229 &decoded_data.data.refresh, sizeof(TelSatRefreshTlv));
232 case TEL_SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
233 dbg("decoded command is provide local info");
234 memcpy(&proactive_noti.proactive_ind_data.provide_local_info,
235 &decoded_data.data.provide_local_info,
236 sizeof(TelSatProvideLocalInfoTlv));
239 case TEL_SAT_PROATV_CMD_SETUP_EVENT_LIST:
240 dbg("decoded command is setup event list!!");
241 memcpy(&proactive_noti.proactive_ind_data.setup_event_list,
242 &decoded_data.data.setup_event_list,
243 sizeof(TelSatSetupEventListTlv));
244 // setup_event_rsp_get(o, &decoded_data.data.setup_event_list);
247 case TEL_SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT:
248 dbg("decoded command is setup idle mode text");
249 memcpy(&proactive_noti.proactive_ind_data.setup_idle_mode_text,
250 &decoded_data.data.setup_idle_mode_text,
251 sizeof(TelSatSetupIdleModeTextTlv));
254 case TEL_SAT_PROATV_CMD_SEND_DTMF:
255 dbg("decoded command is send dtmf");
256 memcpy(&proactive_noti.proactive_ind_data.send_dtmf,
257 &decoded_data.data.send_dtmf,
258 sizeof(TelSatSendDtmfTlv));
261 case TEL_SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
262 dbg("decoded command is language notification");
263 memcpy(&proactive_noti.proactive_ind_data.language_notification,
264 &decoded_data.data.language_notification,
265 sizeof(TelSatLanguageNotificationTlv));
268 case TEL_SAT_PROATV_CMD_LAUNCH_BROWSER:
269 dbg("decoded command is launch browser");
270 memcpy(&proactive_noti.proactive_ind_data.launch_browser,
271 &decoded_data.data.launch_browser,
272 sizeof(TelSatLaunchBrowserTlv));
275 case TEL_SAT_PROATV_CMD_OPEN_CHANNEL:
276 dbg("decoded command is open channel!!");
277 memcpy(&proactive_noti.proactive_ind_data.open_channel,
278 &decoded_data.data.open_channel,
279 sizeof(TelSatOpenChannelTlv));
282 case TEL_SAT_PROATV_CMD_CLOSE_CHANNEL:
283 dbg("decoded command is close channel!!");
284 memcpy(&proactive_noti.proactive_ind_data.close_channel,
285 &decoded_data.data.close_channel,
286 sizeof(TelSatCloseChannelTlv));
289 case TEL_SAT_PROATV_CMD_RECEIVE_DATA:
290 dbg("decoded command is receive data!!");
291 memcpy(&proactive_noti.proactive_ind_data.receive_data,
292 &decoded_data.data.receive_data,
293 sizeof(TelSatReceiveChannelTlv));
296 case TEL_SAT_PROATV_CMD_SEND_DATA:
297 dbg("decoded command is send data!!");
298 memcpy(&proactive_noti.proactive_ind_data.send_data,
299 &decoded_data.data.send_data,
300 sizeof(TelSatSendChannelTlv));
303 case TEL_SAT_PROATV_CMD_GET_CHANNEL_STATUS:
304 dbg("decoded command is get channel status!!");
305 memcpy(&proactive_noti.proactive_ind_data.get_channel_status,
306 &decoded_data.data.get_channel_status,
307 sizeof(TelSatGetChannelStatusTlv));
311 dbg("invalid command:[%d]", decoded_data.cmd_type);
315 if (decoded_data.cmd_type == TEL_SAT_PROATV_CMD_REFRESH) {
317 dbg("Not suported Proactive command");
318 tcore_at_tok_free(tokens);
322 /* Send notification */
323 tcore_object_send_notification(co,
324 TCORE_NOTIFICATION_SAT_PROACTIVE_CMD,
325 sizeof(TelSatNotiProactiveData), &proactive_noti);
327 tcore_at_tok_free(tokens);
334 static void on_response_imc_sat_send_envelop_cmd(TcorePending *p,
335 guint data_len, const void *data, void *user_data)
337 const TcoreAtResponse *at_resp = data;
338 CoreObject *co = tcore_pending_ref_core_object(p);
339 ImcRespCbData *resp_cb_data = user_data;
340 TelSatEnvelopeResp envelop_resp;
341 TelSatResult result = TEL_SAT_RESULT_FAILURE;
342 GSList *tokens = NULL;
343 const gchar *line = NULL;
344 const gchar *env_res = NULL;
349 tcore_check_return_assert(co != NULL);
350 tcore_check_return_assert(resp_cb_data != NULL);
351 tcore_check_return_assert(resp_cb_data->cb != NULL);
353 if (at_resp && at_resp->success) {
354 result = TEL_SAT_RESULT_SUCCESS;
356 if (at_resp->lines) {
357 line = (const gchar *) at_resp->lines->data;
358 tokens = tcore_at_tok_new(line);
359 if (g_slist_length(tokens) < 1) {
360 err("invalid message");
361 tcore_at_tok_free(tokens);
365 env_res = g_slist_nth_data(tokens, 0);
366 envelop_resp = TEL_SAT_ENVELOPE_SUCCESS;
367 dbg("RESPONSE tokens present");
368 if (NULL != g_slist_nth_data(tokens, 1)) {
369 sw2 = atoi(g_slist_nth_data(tokens, 1));
370 dbg("status word SW2:[%d]", sw2);
372 dbg("Response is processed completely and sending session end notification");
373 /* Send Session End notification */
374 tcore_object_send_notification(co,
375 TCORE_NOTIFICATION_SAT_SESSION_END, 0, NULL);
380 envelop_resp = TEL_SAT_ENVELOPE_FAILED;
383 /* Invoke callback */
384 if (resp_cb_data->cb)
385 resp_cb_data->cb(co, (gint)result, &envelop_resp, resp_cb_data->cb_data);
387 imc_destroy_resp_cb_data(resp_cb_data);
388 tcore_at_tok_free(tokens);
392 static void on_response_imc_sat_send_terminal_response(TcorePending *p,
393 guint data_len, const void *data, void *user_data)
395 const TcoreAtResponse *at_resp = data;
396 CoreObject *co = tcore_pending_ref_core_object(p);
397 ImcRespCbData *resp_cb_data = user_data;
398 TelSatResult result = TEL_SAT_RESULT_FAILURE;
402 tcore_check_return_assert(co != NULL);
403 tcore_check_return_assert(resp_cb_data != NULL);
404 tcore_check_return_assert(resp_cb_data->cb != NULL);
406 if (at_resp && at_resp->success) {
407 result = TEL_SAT_RESULT_SUCCESS;
409 dbg(" at_resp->success = %d", at_resp->success);
410 /* Send Session End notification */
411 tcore_object_send_notification(co, TCORE_NOTIFICATION_SAT_SESSION_END, 0, NULL);
414 /* Invoke callback */
415 if (resp_cb_data->cb)
416 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
418 imc_destroy_resp_cb_data(resp_cb_data);
422 static void on_response_imc_sat_send_user_confirmation(TcorePending *p,
423 guint data_len, const void *data, void *user_data)
425 const TcoreAtResponse *at_resp = data;
426 CoreObject *co = tcore_pending_ref_core_object(p);
427 ImcRespCbData *resp_cb_data = user_data;
428 TelSatResult result = TEL_SAT_RESULT_FAILURE;
432 tcore_check_return_assert(co != NULL);
433 tcore_check_return_assert(resp_cb_data != NULL);
434 tcore_check_return_assert(resp_cb_data->cb != NULL);
436 if (at_resp && at_resp->success) {
438 result = TEL_SAT_RESULT_SUCCESS;
441 /* Invoke callback */
442 if (resp_cb_data->cb)
443 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
445 imc_destroy_resp_cb_data(resp_cb_data);
451 * Operation - Send Envelop Command
454 * AT-Command: AT+SATE
457 * Success: (Single line)
461 * +CME ERROR: <error>
463 static TelReturn imc_sat_send_envelope(CoreObject *co,
464 const TelSatRequestEnvelopCmdData *envelop_data,
465 TcoreObjectResponseCallback cb, void *cb_data)
468 gint envelope_cmd_len = 0;
469 gchar envelope_cmd[PROACTV_CMD_LEN];
471 gchar hex_string[PROACTV_CMD_LEN * 2];
472 gchar *buffer = NULL;
473 gboolean encode_ret = FALSE;
475 ImcRespCbData *resp_cb_data;
479 memset(&hex_string, 0x00, sizeof(hex_string));
482 encode_ret = tcore_sat_encode_envelop_cmd(envelop_data,
483 (gchar *)envelope_cmd, (gint *)&envelope_cmd_len);
485 err("Envelope Command encoding failed");
486 return TEL_RETURN_FAILURE;
489 dbg("envelope_cmd_len after encoding :[%d]", envelope_cmd_len);
490 if (envelope_cmd_len == 0) {
491 err("Envelope command length after encoding is NULL");
492 return TEL_RETURN_INVALID_PARAMETER;
495 for (count = 0; count < envelope_cmd_len; count++) {
496 dbg("envelope_cmd: %02x", (guchar)envelope_cmd[count]);
497 sprintf(buffer, "%02x", (guchar)envelope_cmd[count]);
500 dbg("hex_string: %s", hex_string);
503 at_cmd = g_strdup_printf("AT+SATE=\"%s\"", hex_string);
505 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
506 (void *)&envelop_data->sub_cmd, sizeof(TelSatEnvelopSubCmd));
508 /* Send Request to modem */
509 ret = tcore_at_prepare_and_send_request(co,
511 TCORE_AT_COMMAND_TYPE_SINGLELINE,
512 TCORE_PENDING_PRIORITY_DEFAULT,
514 on_response_imc_sat_send_envelop_cmd, resp_cb_data,
515 on_send_imc_request, NULL,
517 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Envelop Command");
526 * Operation - Send Terminal Response
529 * AT-Command: AT+SATR
532 * Success: (NO Result)
535 * +CME ERROR: <error>
537 static TelReturn imc_sat_send_terminal_response(CoreObject *co,
538 const TelSatRequestTerminalResponseData *terminal_rsp_data,
539 TcoreObjectResponseCallback cb, void *cb_data)
542 gint terminal_resp_len = 0;
543 gchar terminal_resp[PROACTV_CMD_LEN];
545 gchar *hex_string = NULL;
546 gboolean encode_ret = FALSE;
548 ImcRespCbData *resp_cb_data;
553 encode_ret = tcore_sat_encode_terminal_response(terminal_rsp_data,
554 (gchar *)terminal_resp, (gint *)&terminal_resp_len);
556 err("Envelope Command encoding failed");
557 return TEL_RETURN_FAILURE;
560 dbg("terminal_resp after encoding: %s", terminal_resp);
561 dbg("terminal_resp length after encoding:[%d]", strlen(terminal_resp));
562 if (terminal_resp_len == 0) {
563 err("Terminal Response length after encoding is NULL");
564 return TEL_RETURN_INVALID_PARAMETER;
566 hex_string = calloc((terminal_resp_len * 2) + 1, 1);
568 for (i = 0; i < terminal_resp_len * 2; i += 2) {
570 value = (terminal_resp[i / 2] & 0xf0) >> 4;
572 hex_string[i] = ((terminal_resp[i / 2] & 0xf0) >> 4) + '0';
574 hex_string[i] = ((terminal_resp[i / 2] & 0xf0) >> 4) + 'A' - 10;
576 value = terminal_resp[i / 2] & 0x0f;
578 hex_string[i + 1] = (terminal_resp[i / 2] & 0x0f) + '0';
580 hex_string[i + 1] = (terminal_resp[i / 2] & 0x0f) + 'A' - 10;
582 dbg("hex_string: %s", hex_string);
585 at_cmd = g_strdup_printf("AT+SATR=\"%s\"", hex_string);
587 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
589 /* Send Request to modem */
590 ret = tcore_at_prepare_and_send_request(co,
592 TCORE_AT_COMMAND_TYPE_NO_RESULT,
593 TCORE_PENDING_PRIORITY_DEFAULT,
595 on_response_imc_sat_send_terminal_response, resp_cb_data,
596 on_send_imc_request, NULL,
598 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Terminal Response");
607 * Operation - Send User Confirmation
610 * AT-Command: AT+SATD
613 * Success: (NO Result)
616 * +CME ERROR: <error>
618 static TelReturn imc_sat_send_user_confirmation(CoreObject *co,
619 const TelSatRequestUserConfirmationData *user_conf_data,
620 TcoreObjectResponseCallback cb, void *cb_data)
624 ImcRespCbData *resp_cb_data;
629 usr_conf = (guint)user_conf_data->user_conf;
630 dbg("User confirmation:[%d]", usr_conf);
633 at_cmd = g_strdup_printf("AT+SATD=%d", usr_conf);
635 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
637 /* Send Request to modem */
638 ret = tcore_at_prepare_and_send_request(co,
640 TCORE_AT_COMMAND_TYPE_NO_RESULT,
641 TCORE_PENDING_PRIORITY_DEFAULT,
643 on_response_imc_sat_send_user_confirmation, resp_cb_data,
644 on_send_imc_request, NULL,
646 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send User Confirmation");
656 static TcoreSatOps imc_sat_ops = {
657 .send_envelope = imc_sat_send_envelope,
658 .send_terminal_response = imc_sat_send_terminal_response,
659 .send_user_confirmation = imc_sat_send_user_confirmation
663 gboolean imc_sat_init(TcorePlugin *p, CoreObject *co)
668 tcore_sat_set_ops(co, &imc_sat_ops);
672 * At present keeping the same notification processing for
673 * both SATI and SATN command. But in future notification processing
674 * will be seperated for both command depending on SAT re-architecure.
676 tcore_object_add_callback(co, "+SATI",
677 on_notification_imc_sat_proactive_command, NULL);
678 tcore_object_add_callback(co, "+SATN",
679 on_notification_imc_sat_proactive_command, NULL);
680 tcore_object_add_callback(co, "+SATF",
681 on_response_imc_sat_terminal_response_confirm, NULL);
684 tcore_plugin_add_notification_hook(p,
685 TCORE_NOTIFICATION_SIM_STATUS, on_hook_imc_sim_status, co);
692 void imc_sat_exit(TcorePlugin *p, CoreObject *co)