4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: sharanayya mathapati <sharan.m@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
29 #include <core_object.h>
34 #include <user_request.h>
39 #include "imc_common.h"
42 #define NUM_TYPE_INTERNATIONAL 0x01
43 #define NUM_PLAN_ISDN 0x01
45 // To avoid sending multiple response to application
46 static gboolean UssdResp = FALSE;
48 enum telephony_ss_opcode {
49 SS_OPCO_REG = 0x01, /* 0x01 : Registration */
50 SS_OPCO_DEREG, /* 0x02 : De-registration(erase) */
51 SS_OPCO_ACTIVATE, /* 0x03 : Activation */
52 SS_OPCO_DEACTIVATE, /* 0x04 : De-activation */
56 struct ss_confirm_info {
57 enum telephony_ss_class class;
59 enum tcore_response_command resp;
64 static gboolean _ss_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
66 static TReturn _ss_barring_get(CoreObject *o, UserRequest *ur, enum telephony_ss_class class, enum telephony_ss_barring_mode type, enum tcore_response_command resp);
68 static TReturn _ss_forwarding_get(CoreObject *o, UserRequest *ur, enum telephony_ss_class class, enum telephony_ss_forwarding_mode type, enum tcore_response_command resp);
70 static TReturn _ss_waiting_get(CoreObject *o, UserRequest *ur, enum telephony_ss_class class, enum tcore_response_command resp);
72 static TReturn imc_ss_barring_activate(CoreObject *o, UserRequest *ur);
73 static TReturn imc_ss_barring_deactivate(CoreObject *o, UserRequest *ur);
74 static TReturn imc_ss_barring_change_password(CoreObject *o, UserRequest *ur);
75 static TReturn imc_ss_barring_get_status(CoreObject *o, UserRequest *ur);
77 static TReturn imc_ss_forwarding_activate(CoreObject *o, UserRequest *ur);
78 static TReturn imc_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur);
79 static TReturn imc_ss_forwarding_register(CoreObject *o, UserRequest *ur);
80 static TReturn imc_ss_forwarding_deregister(CoreObject *o, UserRequest *ur);
81 static TReturn imc_ss_forwarding_get_status(CoreObject *o, UserRequest *ur);
83 static TReturn imc_ss_waiting_activate(CoreObject *o, UserRequest *ur);
84 static TReturn imc_ss_waiting_deactivate(CoreObject *o, UserRequest *ur);
85 static TReturn imc_ss_waiting_get_status(CoreObject *o, UserRequest *ur);
87 static TReturn imc_ss_cli_activate(CoreObject *o, UserRequest *ur);
88 static TReturn imc_ss_cli_deactivate(CoreObject *o, UserRequest *ur);
89 static TReturn imc_ss_cli_get_status(CoreObject *o, UserRequest *ur);
91 static TReturn imc_ss_send_ussd(CoreObject *o, UserRequest *ur);
93 static TReturn imc_ss_set_aoc(CoreObject *o, UserRequest *ur);
94 static TReturn imc_ss_get_aoc(CoreObject *o, UserRequest *ur);
96 static TReturn imc_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
97 static TReturn imc_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
98 static TReturn imc_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
99 static TReturn imc_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
100 static TReturn imc_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
101 static TReturn imc_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
102 static TReturn imc_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
103 static TReturn imc_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data);
105 static void on_confirmation_ss_message_send(TcorePending *p, gboolean result, void *user_data);
107 static void _ss_ussd_response(UserRequest *ur, const char *ussd_str, enum telephony_ss_ussd_type type, enum telephony_ss_ussd_status status);
108 static void _ss_ussd_notification(TcorePlugin *p, const char *ussd_str, enum telephony_ss_ussd_status status);
110 static gboolean on_notification_ss_info(CoreObject *o, const void *data, void *user_data);
111 static gboolean on_notification_ss_ussd(CoreObject *o, const void *data, void *user_data);
114 static gboolean _ss_request_message(TcorePending *pending,
120 TcoreHal *hal = NULL;
125 tcore_pending_set_response_callback(pending, on_resp, user_data);
127 tcore_pending_set_send_callback(pending, on_confirmation_ss_message_send, NULL);
129 tcore_pending_link_user_request(pending, ur);
131 err("User Request is NULL, is this internal request??");
134 hal = tcore_object_get_hal(o);
136 // Send request to HAL
137 ret = tcore_hal_send_request(hal, pending);
138 if (TCORE_RETURN_SUCCESS != ret) {
139 err("Request send failed");
147 static void _ss_ussd_response(UserRequest *ur, const char *ussd_str, enum telephony_ss_ussd_type type, enum telephony_ss_ussd_status status)
149 struct tresp_ss_ussd resp;
153 memset(&resp, 0x0, sizeof(struct tresp_ss_ussd));
155 resp.status = status;
156 resp.err = SS_ERROR_NONE;
157 dbg("ussd_str = %s resp.type - %d resp.status - %d", ussd_str, resp.type, resp.status);
160 int len = strlen(ussd_str);
161 if (len < MAX_SS_USSD_LEN) {
162 memcpy(resp.str, ussd_str, len);
163 resp.str[len] = '\0';
165 memcpy(resp.str, ussd_str, MAX_SS_USSD_LEN);
166 resp.str[MAX_SS_USSD_LEN - 1] = '\0';
168 dbg("Response string: %s", resp.str);
170 dbg("USSD string is not present");
171 memset(resp.str, '\0', MAX_SS_USSD_LEN);
174 // Send response to TAPI
175 tcore_user_request_send_response(ur, TRESP_SS_SEND_USSD, sizeof(struct tresp_ss_ussd), &resp);
177 err("User request is NULL");
184 static void _ss_ussd_notification(TcorePlugin *p, const char *ussd_str, enum telephony_ss_ussd_status status)
186 CoreObject *core_obj = 0;
187 struct tnoti_ss_ussd noti;
189 dbg("function enter");
191 dbg("[ error ] p : (NULL)");
194 noti.status = status;
196 int len = strlen(ussd_str);
197 if (len < MAX_SS_USSD_LEN) {
198 memcpy(noti.str, ussd_str, len);
199 noti.str[len] = '\0';
201 memcpy(noti.str, ussd_str, MAX_SS_USSD_LEN);
202 noti.str[MAX_SS_USSD_LEN - 1] = '\0';
205 memset(noti.str, '\0', MAX_SS_USSD_LEN);
207 dbg("noti.str - %s", noti.str);
209 core_obj = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SS);
210 tcore_server_send_notification(tcore_plugin_ref_server(p),
213 sizeof(struct tnoti_ss_ussd),
217 static gboolean on_notification_ss_ussd(CoreObject *o, const void *data, void *user_data)
219 enum telephony_ss_ussd_status status;
220 UssdSession *ussd_session = 0;
221 char *ussd_str = 0, *cmd = 0;
222 TcorePlugin *plugin = 0;
224 char *ussdnoti = NULL, *str = NULL, *dcs_str = NULL;
225 GSList *tokens = NULL;
226 GSList *lines = NULL;
227 char *ussd_string = NULL;
230 plugin = tcore_object_ref_plugin(o);
231 ussd_session = tcore_ss_ussd_get_session(o);
233 dbg("function enter");
234 lines = (GSList *) data;
235 if (1 != g_slist_length(lines)) {
236 dbg("unsolicited msg but multiple line");
239 cmd = (char *) (lines->data);
241 tokens = tcore_at_tok_new(cmd);
244 ussdnoti = g_slist_nth_data(tokens, 0);
246 dbg("+CUSD<m> is missing from %CUSD Notification");
249 dbg("USSD status %d", m);
250 // parse [ <str>, <dcs>]
251 ussd_string = g_slist_nth_data(tokens, 1);
253 /* Strike off starting & ending quotes. 1 extra character for NULL termination */
254 str = malloc(strlen(ussd_string) - 1);
255 dbg("length of Ussd Stirng - %d", strlen(ussd_string));
257 memset(str, 0x00, strlen(ussd_string) - 1);
259 dbg("malloc failed");
260 if (NULL != tokens) {
261 tcore_at_tok_free(tokens);
265 len = strlen(ussd_string) - 1;
267 strncpy(str, ussd_string, len);
269 dbg("USSD String - %s len = %d", str, strlen(str));
271 if ((dcs_str = g_slist_nth_data(tokens, 2))) {
273 dbg("USSD dcs %d", dcs);
279 status = SS_USSD_NO_ACTION_REQUIRE;
283 status = SS_USSD_ACTION_REQUIRE;
287 status = SS_USSD_TERMINATED_BY_NET;
291 status = SS_USSD_OTHER_CLIENT;
295 status = SS_USSD_NOT_SUPPORT;
299 status = SS_USSD_TIME_OUT;
303 dbg("unsupported m : %d", m);
304 status = SS_USSD_MAX;
308 switch (tcore_util_get_cbs_coding_scheme(dcs)) {
309 case TCORE_DCS_TYPE_7_BIT:
310 case TCORE_DCS_TYPE_UNSPECIFIED:
311 // ussd_str = tcore_util_unpack_gsm7bit(str, strlen(str));
314 case TCORE_DCS_TYPE_UCS2:
315 case TCORE_DCS_TYPE_8_BIT:
316 if ((str != NULL) && (strlen(str) > 0)) {
317 ussd_str = g_new0(char, strlen(str) + 1);
318 if (ussd_str != NULL) {
319 memcpy(ussd_str, str, strlen(str));
320 ussd_str[strlen(str)] = '\0';
326 dbg("[ error ] unknown dcs type. ussd_session : %x", ussd_session);
329 enum telephony_ss_ussd_type type;
331 tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
333 dbg("[ error ] ur : (0)");
337 type = (enum telephony_ss_ussd_type) tcore_ss_ussd_get_session_type(ussd_session);
338 dbg("ussd type - %d", type);
340 _ss_ussd_response(ur, ussd_str, type, status);
344 if (NULL != tokens) {
345 tcore_at_tok_free(tokens);
355 case SS_USSD_NO_ACTION_REQUIRE:
356 case SS_USSD_ACTION_REQUIRE:
357 case SS_USSD_OTHER_CLIENT:
358 case SS_USSD_NOT_SUPPORT:
359 case SS_USSD_TIME_OUT:
363 enum telephony_ss_ussd_type type;
365 tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
367 dbg("[ error ] ur : (0)");
368 if (NULL != tokens) {
369 tcore_at_tok_free(tokens);
381 type = (enum telephony_ss_ussd_type) tcore_ss_ussd_get_session_type(ussd_session);
382 dbg("ussd type - %d", type);
383 _ss_ussd_response(ur, (const char *) ussd_str, type, status);
387 tcore_ss_ussd_create_session(o, TCORE_SS_USSD_TYPE_NETWORK_INITIATED, 0, 0);
388 _ss_ussd_notification(plugin, (const char *) ussd_str, status);
396 case SS_USSD_TERMINATED_BY_NET:
400 tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
402 tcore_user_request_unref(ur);
404 tcore_ss_ussd_destroy_session(ussd_session);
413 if (NULL != tokens) {
414 tcore_at_tok_free(tokens);
425 static gboolean on_notification_ss_info(CoreObject *o, const void *data, void *user_data)
427 TcorePlugin *plugin = 0;
429 char *cmd = 0, *number = 0, *pos;
430 int code1 = -1, code2 = -1, index = 0, ton = 0;
431 char *str_code1, *str_code2, *str_ton, *str_index;
432 GSList *tokens = NULL;
434 gboolean cssu = FALSE, cssi = FALSE;
435 GSList *lines = NULL;
437 dbg("function enter");
439 plugin = tcore_object_ref_plugin(o);
440 co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
442 dbg("[ error ] plugin_ref_core_object : call");
446 lines = (GSList *) data;
447 if (1 != g_slist_length(lines)) {
448 dbg("unsolicited msg but multiple line");
452 cmd = (char *) (lines->data);
453 pos = strchr(cmd, ':');
455 dbg("[ error ] not valid SS- notification ");
458 buf = calloc(pos - cmd + 2, 1);
459 memcpy(buf, cmd, pos - cmd);
460 dbg("buf is %s", buf);
462 if (!strcmp(buf, "+CSSU")) {
463 dbg("SS - +CSSU indication");
465 } else if (!strcmp(buf, "+CSSI")) {
466 dbg("SS - +CSSI indication");
471 // handle %CSSU notification
473 tokens = tcore_at_tok_new(cmd);
475 str_code2 = g_slist_nth_data(tokens, 0);
477 dbg("Code2 is missing from %CSSU indiaction");
479 code2 = atoi(str_code2);
480 // parse [ <index>, <number> <type>]
481 if ((str_index = g_slist_nth_data(tokens, 1))) {
482 index = atoi(str_index);
485 if ((resp = g_slist_nth_data(tokens, 2))) {
486 // Strike off double quotes
487 number = util_removeQuotes(resp);
488 str_ton = g_slist_nth_data(tokens, 3);
496 dbg("CSSU - code2 = %d index = %d number = %s type = %d", code2, index, number, ton);
498 case 0: // this is a forwarded call (MT call setup)
499 tcore_call_information_mt_forwarded_call(co, number);
502 case 2: // call has been put on hold (during a voice call)
503 tcore_call_information_held(co, number);
506 case 3: // call has been retrieved (during a voice call)
507 tcore_call_information_active(co, number);
510 case 4: // multiparty call entered (during a voice call)
511 tcore_call_information_joined(co, number);
514 case 5: // call on hold has been released
515 tcore_call_information_released_on_hold(co, number);
518 case 6: // forward check SS message received (can be received whenever)
519 tcore_call_information_cf_check_ss_message(co, number);
522 case 7: // call is being connected (alerting) with the remote party in alerting state in explicit call transfer operation (during a voice call)
523 tcore_call_information_transfer_alert(co, number);
526 case 8: // call has been connected with the other remote party in explicit call transfer operation (also number and subaddress parameters may be present) (during a voice call or MT call setup)
527 tcore_call_information_transfered(co, number);
530 case 9: // this is a deflected call (MT call setup):
531 tcore_call_information_mt_deflected_call(co, number);
535 dbg("CSSU - unsupported code2 : %d", code2);
539 // handle %CSSI notification
542 tokens = tcore_at_tok_new(cmd);
544 str_code1 = g_slist_nth_data(tokens, 0);
546 dbg("Code1 is missing from %CSSI indiaction");
548 code1 = atoi(str_code1);
550 if ((str_index = g_slist_nth_data(tokens, 1))) {
551 index = atoi(str_index);
555 dbg("CSSI - code1 - %d index - %d ", code1, index);
558 case 0: // Unconditional CF is active
559 tcore_call_information_mo_cfu(co);
562 case 1: // some of the conditional call forwarding are active
563 tcore_call_information_mo_cfc(co);
566 case 2: // outgoing call is forwarded
567 tcore_call_information_mo_forwarded(co);
570 case 3: // this call is waiting
571 tcore_call_information_mo_waiting(co);
574 case 5: // outgoing call is barred
575 tcore_call_information_mo_barred_outgoing(co);
578 case 6: // incoming call is barred
579 tcore_call_information_mo_barred_incoming(co);
582 case 7: // CLIR suppression rejected
583 tcore_call_information_mo_clir_suppression_reject(co);
586 case 8: // outgoing call is deflected
587 tcore_call_information_mo_deflected(co);
591 dbg("unsupported cmd : %d", code1);
596 if (NULL != tokens) {
597 tcore_at_tok_free(tokens);
604 static void on_confirmation_ss_message_send(TcorePending *p, gboolean result, void *user_data)
608 if (result == FALSE) {
616 static void on_response_ss_barring_set(TcorePending *p, int data_len, const void *data, void *user_data)
618 struct ss_confirm_info *info = 0;
619 enum telephony_ss_class class;
622 struct tresp_ss_barring resp = {0, };
623 UserRequest *ur_dup = 0;
624 GSList *tokens = NULL;
627 const TcoreATResponse *response;
629 dbg("function enter");
631 o = tcore_pending_ref_core_object(p);
632 ur = tcore_pending_ref_user_request(p);
634 info = (struct ss_confirm_info *)user_data;
637 if (response->success > 0) {
639 resp.err = SS_ERROR_NONE;
641 dbg("RESPONSE NOT OK");
642 line = (const char *)response->final_response;
643 tokens = tcore_at_tok_new(line);
645 if (g_slist_length(tokens) < 1) {
646 dbg("err cause not specified or string corrupted");
647 resp.err = SS_ERROR_SYSTEMFAILURE;
649 error = atoi(g_slist_nth_data(tokens, 0));
650 err("Error: [%d]", error);
651 /* TODO: CMEE error mapping is required. */
652 resp.err = SS_ERROR_SYSTEMFAILURE;
654 tcore_at_tok_free(tokens);
657 dbg("on_response_ss_barring_set - rsp.err : %d, ur : %x flavor_type = %d", resp.err, ur, info->flavor_type);
658 dbg("[ check ] class : 0x%x", info->class);
660 if (response->success > 0) {
661 if (info->class == SS_CLASS_VOICE) {
662 class = SS_CLASS_ALL_TELE_BEARER;
665 ur_dup = tcore_user_request_ref(ur);
667 if (info->flavor_type == SS_BARR_MODE_AB || info->flavor_type == SS_BARR_MODE_AOB) {
668 _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAOC, info->resp);
669 } else if (info->flavor_type == SS_BARR_MODE_AIB) {
670 _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAIC, info->resp);
672 _ss_barring_get(o, ur_dup, class, info->flavor_type, info->resp);
676 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
678 dbg("[ error ] ur is 0");
684 static void on_response_ss_barring_change_pwd(TcorePending *p, int data_len, const void *data, void *user_data)
686 const TcoreATResponse *response = data;
687 struct ss_confirm_info *info = 0;
689 struct tresp_ss_general resp;
691 GSList *tokens = NULL;
694 dbg("function enter");
695 ur = tcore_pending_ref_user_request(p);
696 info = (struct ss_confirm_info *) user_data;
698 if (response->success > 0) {
700 resp.err = SS_ERROR_NONE;
702 dbg("RESPONSE NOT OK");
704 line = (const char *) response->final_response;
705 tokens = tcore_at_tok_new(line);
707 if (g_slist_length(tokens) < 1) {
708 dbg("err cause not specified or string corrupted");
709 resp.err = SS_ERROR_SYSTEMFAILURE;
711 error = atoi(g_slist_nth_data(tokens, 0));
712 err("Error: [%d]", error);
713 // TODO: CMEE error mapping is required.
714 resp.err = SS_ERROR_SYSTEMFAILURE;
716 tcore_at_tok_free(tokens);
719 dbg("on_response_ss_barring_change_pwd: rsp.err : %d, usr : %x", resp.err, ur);
721 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
723 dbg("[ error ] ur is 0");
729 static void on_response_ss_forwarding_set(TcorePending *p, int data_len, const void *data, void *user_data)
732 UserRequest *ur = 0, *dup_ur = 0;
733 struct ss_confirm_info *info = 0;
734 struct tresp_ss_forwarding resp = {0,};
735 GSList *tokens = NULL;
738 const TcoreATResponse *response;
740 dbg("function enter");
743 o = tcore_pending_ref_core_object(p);
744 ur = tcore_pending_ref_user_request(p);
746 info = (struct ss_confirm_info *) user_data;
748 if (response->success > 0) {
750 resp.err = SS_ERROR_NONE;
752 dbg("RESPONSE NOT OK");
755 line = (const char *) response->final_response;
756 tokens = tcore_at_tok_new(line);
758 if (g_slist_length(tokens) < 1) {
759 dbg("Error cause not specified or string corrupted");
760 resp.err = SS_ERROR_SYSTEMFAILURE;
762 error = atoi(g_slist_nth_data(tokens, 0));
763 err("Error: [%d]", error);
764 // / TODO: CMEE error mapping is required.
765 resp.err = SS_ERROR_SYSTEMFAILURE;
768 tcore_at_tok_free(tokens);
771 dbg("[ check ] class : 0x%x", info->class);
772 dbg("[ check ] flavor_type : 0x%x", info->flavor_type);
774 dbg("on_response_ss_forwarding_set - rsp.err : %d, ur : %x", resp.err, ur);
776 if (response->success > 0) {
777 if (info->flavor_type == SS_CF_MODE_CF_ALL ||
778 info->flavor_type == SS_CF_MODE_CFC) {
780 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
782 dbg("[ error ] ur is 0");
785 dup_ur = tcore_user_request_ref(ur);
786 _ss_forwarding_get(o, dup_ur, info->class, info->flavor_type, info->resp);
790 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
792 dbg("[ error ] ur is 0");
798 static void on_response_ss_waiting_set(TcorePending *p, int data_len, const void *data, void *user_data)
800 CoreObject *core_obj = 0;
802 UserRequest *ur_dup = 0;
803 struct ss_confirm_info *info = 0;
804 struct tresp_ss_waiting resp = {0,};
805 GSList *tokens = NULL;
808 const TcoreATResponse *response;
810 dbg("function enter");
812 core_obj = tcore_pending_ref_core_object(p);
813 ur = tcore_pending_ref_user_request(p);
815 info = (struct ss_confirm_info *)user_data;
817 if (response->success > 0) {
819 resp.err = SS_ERROR_NONE;
821 dbg("RESPONSE NOT OK");
824 line = (const char *) response->final_response;
825 tokens = tcore_at_tok_new(line);
827 if (g_slist_length(tokens) < 1) {
828 dbg("Error cause not specified or string corrupted");
829 resp.err = SS_ERROR_SYSTEMFAILURE;
831 error = atoi(g_slist_nth_data(tokens, 0));
832 err("Error: [%d]", error);
833 /* TODO: CMEE error mapping is required. */
834 resp.err = SS_ERROR_SYSTEMFAILURE;
838 tcore_at_tok_free(tokens);
841 dbg("Call Waiting - Error: [%d], UR: [0x%x] class: [0x%2x]", resp.err, ur, info->class);
842 if (resp.err == SS_ERROR_NONE) {
843 ur_dup = tcore_user_request_ref(ur);
845 dbg("Get Call Waiting status");
846 _ss_waiting_get(core_obj, ur_dup, info->class, info->resp);
849 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
851 err("User request is NULL");
858 static void on_confirmation_ss_ussd(TcorePending *p, int data_len, const void *data, void *user_data)
860 CoreObject *core_obj = 0;
861 struct ss_confirm_info *info = 0;
862 struct tresp_ss_ussd resp;
863 UserRequest *ur = NULL, *ussd_ur = NULL;
864 GSList *tokens = NULL;
867 UssdSession *ussd_s = NULL;
868 enum tcore_ss_ussd_type type = TCORE_SS_USSD_TYPE_MAX;
869 const TcoreATResponse *response;
871 dbg("function enter");
873 ur = tcore_pending_ref_user_request(p);
874 info = (struct ss_confirm_info *) user_data;
876 memset(resp.str, 0x00, MAX_SS_USSD_LEN);
878 core_obj = tcore_pending_ref_core_object(p);
879 ussd_s = tcore_ss_ussd_get_session(core_obj);
882 type = tcore_ss_ussd_get_session_type(ussd_s);
884 dbg("[ error ] ussd_s : (0)");
886 resp.type = (enum telephony_ss_ussd_type) type;
887 resp.status = SS_USSD_MAX; // hardcoded value.
889 if (response->success > 0) {
891 resp.err = SS_ERROR_NONE;
893 dbg("RESPONSE NOT OK");
895 line = (const char *) response->final_response;
896 tokens = tcore_at_tok_new(line);
898 if (g_slist_length(tokens) < 1) {
899 dbg("err cause not specified or string corrupted");
900 resp.err = SS_ERROR_SYSTEMFAILURE;
902 error = atoi(g_slist_nth_data(tokens, 0));
903 err("Error: [%d]", error);
904 // TODO: CMEE error mapping is required.
905 resp.err = SS_ERROR_SYSTEMFAILURE;
907 tcore_at_tok_free(tokens);
910 dbg("on_confirmation_ss_ussd - rsp.err : %d, ur : %x", resp.err, ur);
912 if (response->success > 0) {
913 if (type == TCORE_SS_USSD_TYPE_USER_INITIATED) {
914 dbg("ussd type %d", resp.type);
917 tcore_ss_ussd_get_session_data(ussd_s, (void **) &ussd_ur);
919 tcore_user_request_free(ussd_ur);
925 tcore_ss_ussd_destroy_session(ussd_s);
928 if (UssdResp == FALSE) { // to avoid sending multiple response to application.
929 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_ussd), &resp);
933 dbg("[ error ] ur : (0)");
938 static void on_response_ss_barring_get(TcorePending *p, int data_len, const void *data, void *user_data)
941 int status = 0, classx = 0, ss_err = 0;
943 struct ss_confirm_info *info = 0;
944 struct tresp_ss_barring resp;
945 int countRecords = 0, countValidRecords = 0;
946 GSList *tokens = NULL;
950 const TcoreATResponse *response;
952 dbg("function enter");
955 ur = tcore_pending_ref_user_request(p);
956 info = (struct ss_confirm_info *) user_data;
958 if (response->lines) {
959 respdata = (GSList *) response->lines;
960 countRecords = g_slist_length(respdata);
961 dbg("total records : %d", countRecords);
964 dbg("no active status - return to user");
966 resp.record_num = countRecords;
968 if (resp.record_num > 0) {
969 resp.record = g_new0(struct barring_info, resp.record_num);
970 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
971 line = (const char *) (respdata->data);
972 tokens = tcore_at_tok_new(line);
975 stat = g_slist_nth_data(tokens, 0);
977 dbg("Stat is missing");
983 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
985 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
987 dbg("call barring status - %d", status);
990 classx_str = g_slist_nth_data(tokens, 1);
993 dbg("class error. classx not exist - set to requested one : %d", info->class);
994 switch (info->class) {
995 case SS_CLASS_ALL_TELE:
1003 case SS_CLASS_ALL_DATA_TELE:
1015 case SS_CLASS_ALL_CS_SYNC:
1021 dbg("unsupported class %d. set to default : 7", info->class);
1025 classx = atoi(classx_str);
1026 dbg("call barring classx - %d", classx);
1031 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1035 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1039 resp.record[countValidRecords].class = SS_CLASS_FAX;
1043 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1047 resp.record[countValidRecords].class = SS_CLASS_SMS;
1051 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1055 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1059 dbg("unspoorted class : [%d]\n", classx);
1063 resp.record[countValidRecords].mode = (enum telephony_ss_barring_mode) (info->flavor_type);
1064 countValidRecords++;
1065 tcore_at_tok_free(tokens);
1069 dbg("invalid field found. coutinue");
1070 tcore_at_tok_free(tokens);
1074 dbg("valid count :%d", countValidRecords);
1075 resp.record_num = countValidRecords;
1076 resp.err = SS_ERROR_NONE;
1078 dbg("no active status - return to user");
1081 if (response->success > 0) {
1083 resp.err = SS_ERROR_NONE;
1085 dbg("RESPONSE NOT OK");
1086 resp.err = TCORE_RETURN_FAILURE;
1088 resp.record_num = 0;
1090 line = (const char *) response->final_response;
1091 tokens = tcore_at_tok_new(line);
1093 if (g_slist_length(tokens) < 1) {
1094 dbg("err cause not specified or string corrupted");
1095 resp.err = SS_ERROR_SYSTEMFAILURE;
1097 ss_err = atoi(g_slist_nth_data(tokens, 0));
1098 err("Error: [%d]", ss_err);
1099 // TODO: CMEE error mapping is required.
1100 resp.err = SS_ERROR_SYSTEMFAILURE;
1102 tcore_at_tok_free(tokens);
1105 dbg("on_response_ss_barring_get- rsp.err : %d, ur : %x", resp.err, ur);
1108 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
1110 dbg("[ error ] ur is 0");
1113 g_free(resp.record);
1120 static void on_response_ss_forwarding_get(TcorePending *p, int data_len, const void *data, void *user_data)
1122 UserRequest *ur = 0;
1123 int classx = 0, ss_err = 0, time = 0;
1125 struct ss_confirm_info *info = 0;
1126 struct tresp_ss_forwarding resp;
1127 int countRecords = 0, countValidRecords = 0;
1129 GSList *respdata = NULL, *tokens = NULL;
1131 char *classx_str, *status, *ton, *time_str;
1132 const TcoreATResponse *response;
1134 dbg("function enter");
1137 ur = tcore_pending_ref_user_request(p);
1138 info = (struct ss_confirm_info *) user_data;
1139 if (response->lines) {
1140 respdata = (GSList *) response->lines;
1141 countRecords = g_slist_length(respdata);
1142 dbg("total records : %d", countRecords);
1145 dbg("no active status - return to user");
1147 resp.record_num = countRecords;
1149 if (resp.record_num > 0) {
1150 resp.record = g_new0(struct forwarding_info, resp.record_num);
1152 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1153 line = (const char *) (respdata->data);
1154 tokens = tcore_at_tok_new(line);
1157 status = g_slist_nth_data(tokens, 0);
1159 dbg("start line error. skip this line");
1162 if (atoi(status) == 1) {
1163 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1165 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1170 classx_str = g_slist_nth_data(tokens, 1);
1172 dbg("class error. skip this line");
1175 switch (atoi(classx_str)) {
1177 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1181 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1185 resp.record[countValidRecords].class = SS_CLASS_FAX;
1189 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1193 resp.record[countValidRecords].class = SS_CLASS_SMS;
1197 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1201 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1205 dbg("unspoorted class : [%d]\n", classx);
1211 // parse <numer> <type>
1212 num = g_slist_nth_data(tokens, 2);
1214 dbg("number - %s", num);
1215 memcpy((resp.record[countValidRecords].number), num, strlen(num));
1216 resp.record[countValidRecords].number_present = TRUE;
1218 ton = g_slist_nth_data(tokens, 3);
1220 resp.record[countValidRecords].ton = atoi(ton);
1221 dbg("number type - %d", resp.record[countValidRecords].ton);
1225 // skip <subaddr> <satype>
1227 time_str = g_slist_nth_data(tokens, 6);
1229 time = atoi(time_str);
1230 resp.record[countValidRecords].time = (enum telephony_ss_forwarding_no_reply_time) time;
1231 dbg("time - %d", time);
1234 resp.record[countValidRecords].mode = (enum telephony_ss_forwarding_mode) (info->flavor_type);
1235 dbg("flavor_type - %d", (enum telephony_ss_forwarding_mode) (info->flavor_type));
1237 countValidRecords++;
1238 tcore_at_tok_free(tokens);
1241 dbg("invalid field found. coutinue");
1242 tcore_at_tok_free(tokens);
1245 dbg("valid count :%d", countValidRecords);
1246 resp.record_num = countValidRecords;
1247 resp.err = SS_ERROR_NONE;
1249 dbg("no active status - return to user");
1252 if (response->success > 0) {
1254 resp.err = SS_ERROR_NONE;
1256 dbg("RESPONSE NOT OK");
1258 resp.record_num = 0;
1259 line = (const char *) response->final_response;
1260 tokens = tcore_at_tok_new(line);
1262 if (g_slist_length(tokens) < 1) {
1263 dbg("err cause not specified or string corrupted");
1264 resp.err = SS_ERROR_SYSTEMFAILURE;
1266 ss_err = atoi(g_slist_nth_data(tokens, 0));
1267 err("Error: [%d]", ss_err);
1268 /* TODO: CMEE error mapping is required. */
1269 resp.err = SS_ERROR_SYSTEMFAILURE;
1271 tcore_at_tok_free(tokens);
1274 dbg("on_response_ss_forwarding_get- rsp.err : %d, ur : %x", resp.err, ur);
1276 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
1278 dbg("[ error ] ur is 0");
1281 g_free(resp.record);
1287 static void on_response_ss_waiting_get(TcorePending *p, int data_len, const void *data, void *user_data)
1289 UserRequest *ur = 0;
1290 GSList *respdata, *tokens = NULL;
1291 int classx = 0, ss_err = 0;
1292 struct ss_confirm_info *info = 0;
1293 struct tresp_ss_waiting resp;
1294 int countRecords = 0, countValidRecords = 0;
1296 char *classx_str, *status;
1297 const TcoreATResponse *response;
1299 dbg("function enter");
1301 ur = tcore_pending_ref_user_request(p);
1302 info = (struct ss_confirm_info *) user_data;
1304 if (response->lines) {
1305 respdata = (GSList *) response->lines;
1306 countRecords = g_slist_length(respdata);
1307 dbg("total records : %d", countRecords);
1310 dbg("no active status - return to user");
1312 resp.record_num = countRecords;
1315 if (resp.record_num > 0) {
1316 resp.record = g_new0(struct waiting_info, resp.record_num);
1318 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1319 line = (const char *) (respdata->data);
1320 tokens = tcore_at_tok_new(line);
1323 status = g_slist_nth_data(tokens, 0);
1325 dbg("Missing stat in responce ");
1328 if (atoi(status) == 1) {
1329 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1331 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1334 dbg("status = %d", resp.record[countValidRecords].status);
1337 classx_str = g_slist_nth_data(tokens, 1);
1339 dbg("error - class is missing");
1342 switch (atoi(classx_str)) {
1344 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1348 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1352 resp.record[countValidRecords].class = SS_CLASS_FAX;
1356 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1360 resp.record[countValidRecords].class = SS_CLASS_SMS;
1364 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1368 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1372 dbg("unspoorted class : [%d]\n", classx);
1376 dbg("class info %d", resp.record[countValidRecords].class);
1379 countValidRecords++;
1380 tcore_at_tok_free(tokens);
1383 dbg("invalid field found. coutinue");
1384 tcore_at_tok_free(tokens);
1388 dbg("valid count :%d", countValidRecords);
1389 resp.record_num = countValidRecords;
1390 resp.err = SS_ERROR_NONE;
1392 dbg("no active status - return to user");
1395 if (response->success > 0) {
1397 resp.err = SS_ERROR_NONE;
1399 dbg("RESPONSE NOT OK");
1401 resp.record_num = 0;
1402 line = (const char *) response->final_response;
1403 tokens = tcore_at_tok_new(line);
1405 if (g_slist_length(tokens) < 1) {
1406 dbg("err cause not specified or string corrupted");
1407 resp.err = SS_ERROR_SYSTEMFAILURE;
1409 ss_err = atoi(g_slist_nth_data(tokens, 0));
1410 err("Error: [%d]", ss_err);
1411 // TODO: CMEE error mapping is required.
1412 resp.err = SS_ERROR_SYSTEMFAILURE;
1414 tcore_at_tok_free(tokens);
1417 dbg("on_response_ss_waiting_get - rsp.err : %d, ur : %x", resp.err, ur);
1419 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
1421 dbg("[ error ] ur is 0");
1424 g_free(resp.record);
1431 static void on_response_ss_cli_get(TcorePending *p, int data_len, const void *data, void *user_data)
1433 UserRequest *ur = 0;
1434 struct tresp_ss_cli resp;
1435 enum telephony_ss_cli_type *p_type = NULL;
1436 char *line = NULL, *status;
1439 GSList *tokens = NULL;
1440 const TcoreATResponse *response;
1442 dbg("function enter");
1444 ur = tcore_pending_ref_user_request(p);
1445 p_type = (enum telephony_ss_cli_type *) (user_data);
1447 if (response->success > 0) {
1448 line = (char *) (((GSList *) response->lines)->data);
1449 tokens = tcore_at_tok_new(line);
1451 if (*p_type == SS_CLI_TYPE_CLIR) {
1453 dbg("CLI type is CLIR");
1455 status = g_slist_nth_data(tokens, 0);
1458 dbg("Call line identification adjustment missing <n>");
1460 cli_adj = atoi(status);
1461 dbg("CLIR response value of <n> - %d", cli_adj);
1465 status = g_slist_nth_data(tokens, 1);
1467 dbg("status is missing<m>");
1469 stat = atoi(status);
1470 dbg("CLIR response value of <m> - %d", stat);
1472 if (stat == 1 || stat == 3) {
1475 resp.status = FALSE;
1477 } else if (cli_adj == 1) {
1480 resp.status = FALSE;
1482 dbg("resp.status - %d", resp.status);
1484 tcore_at_tok_free(tokens);
1487 status = g_slist_nth_data(tokens, 0);
1489 dbg("Stat is missing");
1491 stat = atoi(status);
1495 resp.status = FALSE;
1497 dbg("resp.status - %d", resp.status);
1499 tcore_at_tok_free(tokens);
1503 if (response->success > 0) {
1505 resp.err = SS_ERROR_NONE;
1507 dbg("RESPONSE NOT OK");
1509 line = (char *) response->final_response;
1510 tokens = tcore_at_tok_new(line);
1512 if (g_slist_length(tokens) < 1) {
1513 dbg("err cause not specified or string corrupted");
1514 resp.err = SS_ERROR_SYSTEMFAILURE;
1516 error = atoi(g_slist_nth_data(tokens, 0));
1517 err("Error: [%d]", error);
1518 // TODO: CMEE error mapping is required.
1519 resp.err = SS_ERROR_SYSTEMFAILURE;
1521 tcore_at_tok_free(tokens);
1524 resp.type = *p_type;
1525 dbg("check - resp.type = %d ", resp.type);
1527 tcore_user_request_send_response(ur, TRESP_SS_CLI_GET_STATUS, sizeof(struct tresp_ss_cli), &resp);
1529 dbg("[ error ] ur : (0)");
1534 static struct tcore_ss_operations ss_ops = {
1535 .barring_activate = imc_ss_barring_activate,
1536 .barring_deactivate = imc_ss_barring_deactivate,
1537 .barring_change_password = imc_ss_barring_change_password,
1538 .barring_get_status = imc_ss_barring_get_status,
1539 .forwarding_activate = imc_ss_forwarding_activate,
1540 .forwarding_deactivate = imc_ss_forwarding_deactivate,
1541 .forwarding_register = imc_ss_forwarding_register,
1542 .forwarding_deregister = imc_ss_forwarding_deregister,
1543 .forwarding_get_status = imc_ss_forwarding_get_status,
1544 .waiting_activate = imc_ss_waiting_activate,
1545 .waiting_deactivate = imc_ss_waiting_deactivate,
1546 .waiting_get_status = imc_ss_waiting_get_status,
1547 .cli_activate = imc_ss_cli_activate,
1548 .cli_deactivate = imc_ss_cli_deactivate,
1549 .cli_get_status = imc_ss_cli_get_status,
1550 .send_ussd = imc_ss_send_ussd,
1551 .set_aoc = imc_ss_set_aoc,
1552 .get_aoc = imc_ss_get_aoc,
1556 static TReturn _ss_barring_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1558 struct treq_ss_barring *barring = 0;
1559 struct ss_confirm_info *user_data = 0;
1560 char *cmd_str = NULL;
1561 TcorePending *pending = NULL;
1562 TcoreATRequest *req;
1563 char passwd[MAX_SS_BARRING_PASSWORD_LEN + 1];
1566 char *facility = NULL;
1567 gboolean ret = FALSE;
1569 dbg("function enter");
1570 barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1573 case SS_OPCO_ACTIVATE:
1577 case SS_OPCO_DEACTIVATE:
1582 dbg("unsupported opco : %d", op);
1583 return TCORE_RETURN_FAILURE;
1585 dbg("opco - %d", opco);
1587 switch (barring->mode) {
1588 case SS_BARR_MODE_BAOC:
1592 case SS_BARR_MODE_BOIC:
1596 case SS_BARR_MODE_BOIC_NOT_HC:
1600 case SS_BARR_MODE_BAIC:
1604 case SS_BARR_MODE_BIC_ROAM:
1608 case SS_BARR_MODE_AB:
1612 case SS_BARR_MODE_AOB:
1616 case SS_BARR_MODE_AIB:
1620 case SS_BARR_MODE_BIC_NOT_SIM:
1623 dbg("unspported mode %d", barring->mode);
1624 return TCORE_RETURN_FAILURE;
1627 dbg("facility - %s", facility);
1629 switch (barring->class) {
1630 case SS_CLASS_ALL_TELE:
1634 case SS_CLASS_VOICE:
1638 case SS_CLASS_ALL_DATA_TELE:
1650 case SS_CLASS_ALL_CS_SYNC:
1656 dbg("unsupported class %d. set to default : 7", barring->class);
1660 dbg("classx - %d", classx);
1662 user_data = g_new0(struct ss_confirm_info, 1);
1664 dbg("[ error ] failed to allocate memory");
1665 return TCORE_RETURN_ENOMEM;
1668 // null-ended pwd handling added - unexpected 0x11 value observed in req string
1669 memcpy(passwd, barring->password, MAX_SS_BARRING_PASSWORD_LEN);
1670 passwd[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1671 dbg("passwd - %s", passwd);
1673 pending = tcore_pending_new(o, 0);
1675 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d", facility, opco, passwd, classx);
1676 dbg("request command : %s", cmd_str);
1678 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1679 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1681 tcore_pending_set_request_data(pending, 0, req);
1683 if (op == SS_OPCO_ACTIVATE) {
1684 user_data->resp = TRESP_SS_BARRING_ACTIVATE;
1685 } else if (op == SS_OPCO_DEACTIVATE) {
1686 user_data->resp = TRESP_SS_BARRING_DEACTIVATE;
1688 dbg("[ error ] wrong ss opco (0x%x)", op);
1689 if (user_data != NULL) {
1693 tcore_pending_free(pending);
1694 tcore_at_request_free(req);
1695 return TCORE_RETURN_FAILURE;
1697 user_data->flavor_type = (int) (barring->mode);
1698 user_data->class = barring->class;
1700 ret = _ss_request_message(pending, o, ur, on_response_ss_barring_set, user_data);
1704 dbg("AT request sent failed ");
1705 if (user_data != NULL) {
1707 tcore_pending_free(pending);
1708 tcore_at_request_free(req);
1710 return TCORE_RETURN_FAILURE;
1712 return TCORE_RETURN_SUCCESS;
1715 static TReturn _ss_barring_get(CoreObject *o,
1717 enum telephony_ss_class class,
1718 enum telephony_ss_barring_mode mode,
1719 enum tcore_response_command resp)
1721 struct ss_confirm_info *user_data = 0;
1722 gboolean ret = FALSE;
1723 char *cmd_str = NULL;
1725 char *facility = NULL;
1726 TcorePending *pending = NULL;
1727 TcoreATRequest *req;
1729 dbg("function enter");
1731 // query status - opco is fixed to 2
1735 case SS_BARR_MODE_BAOC:
1739 case SS_BARR_MODE_BOIC:
1743 case SS_BARR_MODE_BOIC_NOT_HC:
1747 case SS_BARR_MODE_BAIC:
1751 case SS_BARR_MODE_BIC_ROAM:
1755 case SS_BARR_MODE_AB:
1756 case SS_BARR_MODE_AOB:
1757 case SS_BARR_MODE_AIB:
1758 case SS_BARR_MODE_BIC_NOT_SIM:
1760 dbg("unsupported mode %d", mode);
1761 return TCORE_RETURN_FAILURE;
1764 dbg("facility - %s", facility);
1767 case SS_CLASS_ALL_TELE:
1771 case SS_CLASS_VOICE:
1775 case SS_CLASS_ALL_DATA_TELE:
1787 case SS_CLASS_ALL_CS_SYNC:
1793 dbg("unsupported class %d. set to default : 7", class);
1797 user_data = g_new0(struct ss_confirm_info, 1);
1799 dbg("[ error ] failed to allocate memory");
1800 return TCORE_RETURN_ENOMEM;
1803 dbg("class - %d", classx);
1805 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d", facility, opco);
1807 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d", facility, opco, classx);
1809 dbg("request command : %s", cmd_str);
1811 pending = tcore_pending_new(o, 0);
1812 req = tcore_at_request_new(cmd_str, "+CLCK", TCORE_AT_MULTILINE);
1813 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1815 tcore_pending_set_request_data(pending, 0, req);
1817 user_data->resp = resp;
1818 user_data->flavor_type = (int) (mode);
1819 user_data->class = class;
1821 ret = _ss_request_message(pending, o, ur, on_response_ss_barring_get, user_data);
1825 dbg("AT request sent failed ");
1826 if (user_data != NULL) {
1828 tcore_pending_free(pending);
1829 tcore_at_request_free(req);
1831 return TCORE_RETURN_FAILURE;
1834 return TCORE_RETURN_SUCCESS;
1837 static TReturn imc_ss_barring_activate(CoreObject *o, UserRequest *ur)
1839 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1840 dbg("cp not ready/n");
1841 return TCORE_RETURN_ENOSYS;
1843 return _ss_barring_set(o, ur, SS_OPCO_ACTIVATE);
1846 static TReturn imc_ss_barring_deactivate(CoreObject *o, UserRequest *ur)
1848 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1849 dbg("cp not ready/n");
1850 return TCORE_RETURN_ENOSYS;
1852 return _ss_barring_set(o, ur, SS_OPCO_DEACTIVATE);
1855 static TReturn imc_ss_barring_change_password(CoreObject *o, UserRequest *ur)
1857 TcorePending *pending = NULL;
1858 TcoreATRequest *req;
1859 struct treq_ss_barring_change_password *barring = 0;
1860 struct ss_confirm_info *user_data = 0;
1861 char *cmd_str = NULL;
1862 gboolean ret = FALSE;
1863 char old_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1864 char new_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1866 dbg("function enter");
1868 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1869 dbg("cp not ready/n");
1870 return TCORE_RETURN_ENOSYS;
1873 barring = (struct treq_ss_barring_change_password *) tcore_user_request_ref_data(ur, 0);
1875 if (barring->password_old == NULL || barring->password_new == NULL) {
1876 dbg("[error]password is null");
1877 return TCORE_RETURN_FAILURE;
1879 memcpy(old_password, barring->password_old, MAX_SS_BARRING_PASSWORD_LEN);
1880 old_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1881 memcpy(new_password, barring->password_new, MAX_SS_BARRING_PASSWORD_LEN);
1882 new_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1884 user_data = g_new0(struct ss_confirm_info, 1);
1886 dbg("[ error ] failed to allocate memory");
1887 return TCORE_RETURN_ENOMEM;
1889 user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
1891 dbg("old passwd - %s new passwd- %s", old_password, new_password);
1892 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB", old_password, new_password);
1893 dbg("request command : %s", cmd_str);
1895 pending = tcore_pending_new(o, 0);
1896 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1897 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1899 tcore_pending_set_request_data(pending, 0, req);
1901 ret = _ss_request_message(pending, o, ur, on_response_ss_barring_change_pwd, user_data);
1904 dbg("AT request sent failed ");
1905 if (user_data != NULL) {
1908 tcore_pending_free(pending);
1909 tcore_at_request_free(req);
1910 return TCORE_RETURN_FAILURE;
1912 return TCORE_RETURN_SUCCESS;
1915 static TReturn imc_ss_barring_get_status(CoreObject *o, UserRequest *ur)
1917 struct treq_ss_barring *barring = 0;
1919 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1920 dbg("cp not ready/n");
1921 return TCORE_RETURN_ENOSYS;
1923 barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1925 return _ss_barring_get(o, ur, barring->class, barring->mode, TRESP_SS_BARRING_GET_STATUS);
1928 static TReturn _ss_forwarding_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1930 struct treq_ss_forwarding *forwarding = 0;
1931 struct ss_confirm_info *user_data = 0;
1932 gboolean ret = FALSE;
1934 char *cmd_str = NULL;
1935 char *tmp_str = NULL;
1936 int reason = 0, mode = 0, num_type = 0, classx = 0, time = 0;
1937 TcorePending *pending = NULL;
1938 TcoreATRequest *req;
1940 dbg("_ss_forwarding_set with opco %d ", op);
1942 forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
1943 switch (forwarding->mode) {
1944 case SS_CF_MODE_CFU:
1948 case SS_CF_MODE_CFB:
1952 case SS_CF_MODE_CFNRy:
1956 case SS_CF_MODE_CFNRc:
1960 case SS_CF_MODE_CF_ALL:
1964 case SS_CF_MODE_CFC:
1969 dbg("unsupported reason : %d");
1970 return TCORE_RETURN_FAILURE;
1974 dbg("reason = %d", reason);
1976 case SS_OPCO_DEACTIVATE:
1980 case SS_OPCO_ACTIVATE:
1993 dbg("unsupported opco : %d", op);
1994 return TCORE_RETURN_FAILURE;
1997 dbg("mode = %d", mode);
2000 switch (forwarding->class) {
2001 case SS_CLASS_ALL_TELE:
2005 case SS_CLASS_VOICE:
2009 case SS_CLASS_ALL_DATA_TELE:
2021 case SS_CLASS_ALL_CS_SYNC:
2027 dbg("unsupported class %d. set to default : 7", forwarding->class);
2030 dbg("classx = %d", classx);
2033 len = strlen(forwarding->number);
2035 if (forwarding->number[0] == '+')
2036 num_type = ((NUM_TYPE_INTERNATIONAL << 4) | NUM_PLAN_ISDN);
2040 dbg("number = %s", forwarding->number);
2042 user_data = g_new0(struct ss_confirm_info, 1);
2044 dbg("[ error ] failed to allocate memory");
2045 return TCORE_RETURN_ENOMEM;
2050 user_data->resp = TRESP_SS_FORWARDING_REGISTER;
2054 user_data->resp = TRESP_SS_FORWARDING_DEREGISTER;
2057 case SS_OPCO_ACTIVATE:
2058 user_data->resp = TRESP_SS_FORWARDING_ACTIVATE;
2061 case SS_OPCO_DEACTIVATE:
2062 user_data->resp = TRESP_SS_FORWARDING_DEACTIVATE;
2066 dbg("[ error ] unknown op (0x%x)", op);
2070 if (forwarding->number[0] == '+')
2075 if (op == SS_OPCO_REG)
2076 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,\"%s\",%d,%d", reason, mode, forwarding->number, num_type, classx);
2077 else // other opcode does not need num field
2078 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2080 if (forwarding->mode == SS_CF_MODE_CFNRy) {
2081 // add time info to 'no reply' case
2082 time = (int) (forwarding->time);
2083 cmd_str = g_strdup_printf("%s,,,%d", tmp_str, time);
2085 cmd_str = g_strdup_printf("%s", tmp_str);
2088 dbg("request command : %s", cmd_str);
2089 pending = tcore_pending_new(o, 0);
2090 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2091 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2093 tcore_pending_set_request_data(pending, 0, req);
2095 user_data->flavor_type = forwarding->mode;
2096 user_data->class = forwarding->class;
2098 ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_set, user_data);
2104 dbg("AT request sent failed ");
2105 if (user_data != NULL) {
2108 return TCORE_RETURN_FAILURE;
2111 return TCORE_RETURN_SUCCESS;
2114 static TReturn _ss_forwarding_get(CoreObject *o,
2116 enum telephony_ss_class class,
2117 enum telephony_ss_forwarding_mode type,
2118 enum tcore_response_command resp)
2120 struct ss_confirm_info *user_data = 0;
2121 gboolean ret = FALSE;
2122 char *cmd_str = NULL;
2123 int reason = 0, mode = 0, classx = 0;
2124 TcorePending *pending = NULL;
2125 TcoreATRequest *req;
2127 dbg("function enter");
2130 case SS_CF_MODE_CFU:
2134 case SS_CF_MODE_CFB:
2138 case SS_CF_MODE_CFNRy:
2142 case SS_CF_MODE_CFNRc:
2146 case SS_CF_MODE_CF_ALL:
2150 case SS_CF_MODE_CFC:
2155 dbg("unsupported reason : %d");
2158 dbg("reason = %d", reason);
2161 case SS_CLASS_ALL_TELE:
2165 case SS_CLASS_VOICE:
2169 case SS_CLASS_ALL_DATA_TELE:
2181 case SS_CLASS_ALL_CS_SYNC:
2187 dbg("unsupported class %d. set to default : 7", class);
2191 dbg("classx = %d", classx);
2193 // query status - mode set to 2
2195 user_data = g_new0(struct ss_confirm_info, 1);
2197 dbg("[ error ] failed to allocate memory");
2198 return TCORE_RETURN_ENOMEM;
2200 user_data->resp = resp;
2201 user_data->class = class;
2202 user_data->flavor_type = type;
2205 cmd_str = g_strdup_printf("AT+CCFC=%d,%d", reason, mode);
2207 cmd_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2209 dbg("request command : %s", cmd_str);
2211 pending = tcore_pending_new(o, 0);
2212 req = tcore_at_request_new(cmd_str, "+CCFC", TCORE_AT_MULTILINE);
2213 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2215 tcore_pending_set_request_data(pending, 0, req);
2217 ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_get, user_data);
2221 dbg("AT request sent failed ");
2222 if (user_data != NULL) {
2224 tcore_pending_free(pending);
2225 tcore_at_request_free(req);
2227 return TCORE_RETURN_FAILURE;
2230 return TCORE_RETURN_SUCCESS;
2233 static TReturn imc_ss_forwarding_activate(CoreObject *o, UserRequest *ur)
2235 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2236 dbg("cp not ready/n");
2237 return TCORE_RETURN_ENOSYS;
2239 return _ss_forwarding_set(o, ur, SS_OPCO_ACTIVATE);
2242 static TReturn imc_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur)
2244 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2245 dbg("cp not ready/n");
2246 return TCORE_RETURN_ENOSYS;
2248 return _ss_forwarding_set(o, ur, SS_OPCO_DEACTIVATE);
2251 static TReturn imc_ss_forwarding_register(CoreObject *o, UserRequest *ur)
2253 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2254 dbg("cp not ready/n");
2255 return TCORE_RETURN_ENOSYS;
2257 return _ss_forwarding_set(o, ur, SS_OPCO_REG);
2260 static TReturn imc_ss_forwarding_deregister(CoreObject *o, UserRequest *ur)
2262 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2263 dbg("cp not ready/n");
2264 return TCORE_RETURN_ENOSYS;
2266 return _ss_forwarding_set(o, ur, SS_OPCO_DEREG);
2269 static TReturn imc_ss_forwarding_get_status(CoreObject *o, UserRequest *ur)
2271 struct treq_ss_forwarding *forwarding = 0;
2273 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2274 dbg("cp not ready/n");
2275 return TCORE_RETURN_ENOSYS;
2278 forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
2280 return _ss_forwarding_get(o, ur, forwarding->class, forwarding->mode, TRESP_SS_FORWARDING_GET_STATUS);
2284 static TReturn _ss_waiting_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode opco)
2286 struct treq_ss_waiting *waiting = 0;
2287 struct ss_confirm_info *user_data = 0;
2288 gboolean ret = FALSE;
2289 int mode = 0, classx = 0;
2291 TcorePending *pending = NULL;
2292 TcoreATRequest *req;
2294 dbg("function enter ");
2295 waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2296 user_data = g_new0(struct ss_confirm_info, 1);
2298 dbg("[ error ] failed to allocate memory");
2299 return TCORE_RETURN_ENOMEM;
2302 if (opco == SS_OPCO_ACTIVATE) {
2303 user_data->resp = TRESP_SS_WAITING_ACTIVATE;
2305 } else if (opco == SS_OPCO_DEACTIVATE) {
2306 user_data->resp = TRESP_SS_WAITING_DEACTIVATE;
2307 mode = 0; // disable
2309 dbg("[ error ] unknown ss mode (0x%x)", opco);
2311 switch (waiting->class) {
2312 case SS_CLASS_ALL_TELE:
2316 case SS_CLASS_VOICE:
2320 case SS_CLASS_ALL_DATA_TELE:
2334 dbg("unsupported class %d. set to default : 1", waiting->class);
2337 dbg("mode = %d classxx- %d", mode, classx);
2339 user_data->class = waiting->class;
2340 user_data->flavor_type = (int) opco;
2342 cmd_str = g_strdup_printf("AT+CCWA=1,%d,%d", mode, classx); // always enable +CCWA: unsolicited cmd
2343 dbg("request command : %s", cmd_str);
2345 pending = tcore_pending_new(o, 0);
2346 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2347 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2349 tcore_pending_set_request_data(pending, 0, req);
2351 ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_set, user_data);
2354 dbg("AT request sent failed ");
2355 if (user_data != NULL) {
2357 tcore_pending_free(pending);
2358 tcore_at_request_free(req);
2360 return TCORE_RETURN_FAILURE;
2362 return TCORE_RETURN_SUCCESS;
2365 static TReturn _ss_waiting_get(CoreObject *o,
2367 enum telephony_ss_class class,
2368 enum tcore_response_command resp)
2370 struct ss_confirm_info *user_data = 0;
2371 gboolean ret = FALSE;
2372 int classx; // mode,
2374 TcorePending *pending = NULL;
2375 TcoreATRequest *req;
2377 dbg("function enter");
2379 case SS_CLASS_ALL_TELE:
2383 case SS_CLASS_VOICE:
2387 case SS_CLASS_ALL_DATA_TELE:
2401 dbg("unsupported class %d. set to default : 7", class);
2404 dbg("classx - %d", classx);
2406 dbg("allocating user data");
2407 user_data = g_new0(struct ss_confirm_info, 1);
2409 dbg("[ error ] failed to allocate memory");
2410 return TCORE_RETURN_ENOMEM;
2412 user_data->resp = resp;
2413 user_data->class = class;
2415 cmd_str = g_strdup_printf("AT+CCWA=1,2,%d", classx); // always enable +CCWA: unsolicited cmd , mode is fixed to 2(query status)
2416 dbg("request cmd : %s", cmd_str);
2418 pending = tcore_pending_new(o, 0);
2419 req = tcore_at_request_new(cmd_str, "+CCWA", TCORE_AT_MULTILINE);
2420 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2422 tcore_pending_set_request_data(pending, 0, req);
2424 ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_get, user_data);
2427 dbg("AT request sent failed ");
2428 if (user_data != NULL) {
2430 tcore_pending_free(pending);
2431 tcore_at_request_free(req);
2433 return TCORE_RETURN_FAILURE;
2435 return TCORE_RETURN_SUCCESS;
2438 static TReturn imc_ss_waiting_activate(CoreObject *o, UserRequest *ur)
2440 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2441 dbg("cp not ready/n");
2442 return TCORE_RETURN_ENOSYS;
2444 return _ss_waiting_set(o, ur, SS_OPCO_ACTIVATE);
2447 static TReturn imc_ss_waiting_deactivate(CoreObject *o, UserRequest *ur)
2449 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2450 dbg("cp not ready/n");
2451 return TCORE_RETURN_ENOSYS;
2453 return _ss_waiting_set(o, ur, SS_OPCO_DEACTIVATE);
2456 static TReturn imc_ss_waiting_get_status(CoreObject *o, UserRequest *ur)
2458 struct treq_ss_waiting *waiting = 0;
2460 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2461 dbg("cp not ready/n");
2462 return TCORE_RETURN_ENOSYS;
2464 waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2466 return _ss_waiting_get(o, ur, waiting->class, TRESP_SS_WAITING_GET_STATUS);
2469 static TReturn imc_ss_cli_activate(CoreObject *o, UserRequest *ur)
2471 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2472 dbg("cp not ready/n");
2473 return TCORE_RETURN_ENOSYS;
2475 return TCORE_RETURN_SUCCESS;
2478 static TReturn imc_ss_cli_deactivate(CoreObject *o, UserRequest *ur)
2480 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2481 dbg("cp not ready/n");
2482 return TCORE_RETURN_ENOSYS;
2484 return TCORE_RETURN_SUCCESS;
2487 static TReturn imc_ss_cli_get_status(CoreObject *o, UserRequest *ur)
2489 struct treq_ss_cli *cli = 0;
2490 gboolean ret = FALSE;
2491 char *cmd_prefix = NULL, *rsp_prefix = NULL, *cmd_str = NULL;
2492 enum telephony_ss_cli_type *user_data = 0;
2493 TcorePending *pending = NULL;
2494 TcoreATRequest *req;
2496 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2497 dbg("cp not ready/n");
2498 return TCORE_RETURN_ENOSYS;
2501 cli = (struct treq_ss_cli *) tcore_user_request_ref_data(ur, 0);
2502 switch (cli->type) {
2503 case SS_CLI_TYPE_CLIP:
2504 cmd_prefix = "+CLIP";
2505 rsp_prefix = "+CLIP";
2508 case SS_CLI_TYPE_CLIR:
2509 cmd_prefix = "+CLIR";
2510 rsp_prefix = "+CLIR";
2513 case SS_CLI_TYPE_COLP:
2514 cmd_prefix = "+COLP";
2515 rsp_prefix = "+COLP";
2518 case SS_CLI_TYPE_COLR:
2519 cmd_prefix = "+COLR";
2520 rsp_prefix = "+COLR";
2523 case SS_CLI_TYPE_CNAP:
2524 cmd_prefix = "+CNAP";
2525 rsp_prefix = "+CNAP";
2528 case SS_CLI_TYPE_CDIP:
2530 dbg("unsupported cli_type : %d", cli->type);
2531 return TCORE_RETURN_FAILURE;
2534 dbg("cmd_prefix : %s", cmd_prefix);
2536 cmd_str = g_strdup_printf("AT%s?", cmd_prefix);
2537 dbg("request cmd : %s", cmd_str);
2539 user_data = g_new0(enum telephony_ss_cli_type, 1);
2541 dbg("[ error ] failed to allocate memory");
2543 return TCORE_RETURN_ENOMEM;
2545 *user_data = cli->type;
2547 pending = tcore_pending_new(o, 0);
2549 req = tcore_at_request_new(cmd_str, rsp_prefix, TCORE_AT_SINGLELINE);
2550 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2551 tcore_pending_set_request_data(pending, 0, req);
2553 ret = _ss_request_message(pending, o, ur, on_response_ss_cli_get, user_data);
2556 dbg("AT request sent failed ");
2557 if (user_data != NULL) {
2559 tcore_pending_free(pending);
2560 tcore_at_request_free(req);
2562 return TCORE_RETURN_FAILURE;
2564 return TCORE_RETURN_SUCCESS;
2567 static TReturn imc_ss_send_ussd(CoreObject *o, UserRequest *ur)
2569 UssdSession *ussd_s = 0;
2570 struct treq_ss_ussd *ussd = 0;
2571 struct ss_confirm_info *user_data = 0;
2572 gboolean ret = FALSE;
2574 TcorePending *pending = NULL;
2575 TcoreATRequest *req;
2577 dbg("function enter");
2579 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2580 dbg("cp not ready/n");
2581 return TCORE_RETURN_ENOSYS;
2584 ussd = (struct treq_ss_ussd *) tcore_user_request_ref_data(ur, 0);
2586 user_data = g_new0(struct ss_confirm_info, 1);
2588 user_data->resp = TRESP_SS_SEND_USSD;
2589 ussd_s = tcore_ss_ussd_get_session(o);
2591 dbg("USSD session does not exist");
2592 tcore_ss_ussd_create_session(o, (enum tcore_ss_ussd_type) ussd->type, (void *) tcore_user_request_ref(ur), 0);
2594 if (ussd->type == SS_USSD_TYPE_USER_INITIATED) {
2595 dbg("[ error ] ussd session is already exist");
2597 return TCORE_RETURN_FAILURE;
2600 tcore_ss_ussd_set_session_type(ussd_s, (enum tcore_ss_ussd_type) ussd->type);
2603 cmd_str = g_strdup_printf("AT+CUSD=1,\"%s\",%d", ussd->str, 0x0f); // always enable +CUSD: unsolicited cmd. set to dcs to 0x0f. only supports HEX type
2604 dbg("request command : %s", cmd_str);
2606 pending = tcore_pending_new(o, 0);
2607 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2608 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2610 tcore_pending_set_request_data(pending, 0, req);
2612 ret = _ss_request_message(pending, o, ur, on_confirmation_ss_ussd, user_data);
2616 dbg("AT request sent failed ");
2617 if (user_data != NULL) {
2619 tcore_pending_free(pending);
2620 tcore_at_request_free(req);
2622 return TCORE_RETURN_FAILURE;
2624 return TCORE_RETURN_SUCCESS;
2627 static TReturn imc_ss_set_aoc(CoreObject *o, UserRequest *ur)
2629 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2630 dbg("cp not ready/n");
2631 return TCORE_RETURN_ENOSYS;
2634 dbg("[ error ] unsupported function");
2635 return TCORE_RETURN_SUCCESS;
2638 static TReturn imc_ss_get_aoc(CoreObject *o, UserRequest *ur)
2640 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2641 dbg("cp not ready/n");
2642 return TCORE_RETURN_ENOSYS;
2645 dbg("[ error ] unsupported function");
2646 return TCORE_RETURN_SUCCESS;
2650 static struct tcore_call_control_operations call_ops = {
2651 .answer_hold_and_accept = imc_ss_manage_call_2_send,
2652 .answer_replace = imc_ss_manage_call_1_send,
2653 .answer_reject = imc_ss_manage_call_0_send,
2654 .end_specific = imc_ss_manage_call_1x_send,
2655 .end_all_active = imc_ss_manage_call_1_send,
2656 .end_all_held = imc_ss_manage_call_0_send,
2657 .active = imc_ss_manage_call_2_send,
2658 .hold = imc_ss_manage_call_2_send,
2659 .swap = imc_ss_manage_call_2_send,
2660 .join = imc_ss_manage_call_3_send,
2661 .split = imc_ss_manage_call_2x_send,
2662 .transfer = imc_ss_manage_call_4_send,
2663 .deflect = imc_ss_manage_call_4dn_send,
2666 static TReturn imc_ss_manage_call_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
2668 TcorePending *pending = NULL;
2669 TcoreATRequest *req;
2670 gboolean ret = FALSE;
2672 pending = tcore_pending_new(o, 0);
2673 req = tcore_at_request_new(cmd, NULL, TCORE_AT_NO_RESULT);
2674 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2675 tcore_pending_set_request_data(pending, 0, req);
2677 ret = _ss_request_message(pending, o, ur, (TcorePendingResponseCallback) cb, user_data);
2679 dbg("AT request sent failed ");
2680 return TCORE_RETURN_FAILURE;
2682 return TCORE_RETURN_SUCCESS;
2685 static TReturn imc_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2687 char *cmd_str = NULL;
2688 gboolean ret = FALSE;
2690 dbg("function enter");
2691 cmd_str = g_strdup_printf("%s", "AT+CHLD=0");
2692 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2694 ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2699 static TReturn imc_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2701 char *cmd_str = NULL;
2702 gboolean ret = FALSE;
2704 dbg("function enter");
2705 cmd_str = g_strdup_printf("%s", "AT+CHLD=1");
2706 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2708 ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2713 static TReturn imc_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2715 char *cmd_str = NULL;
2716 gboolean ret = FALSE;
2718 dbg("function enter");
2719 cmd_str = g_strdup_printf("%s%d", "AT+CHLD=1", id);
2720 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2722 ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2727 static TReturn imc_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2729 char *cmd_str = NULL;
2730 gboolean ret = FALSE;
2732 dbg("function enter");
2733 cmd_str = g_strdup_printf("%s", "AT+CHLD=2");
2734 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2736 ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2741 static TReturn imc_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2743 char *cmd_str = NULL;
2744 gboolean ret = FALSE;
2746 dbg("function enter");
2747 cmd_str = g_strdup_printf("%s%d", "AT+CHLD=2", id);
2748 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2750 ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2755 static TReturn imc_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2757 char *cmd_str = NULL;
2758 gboolean ret = FALSE;
2760 dbg("function enter");
2761 cmd_str = g_strdup_printf("%s", "AT+CHLD=3");
2763 ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2769 static TReturn imc_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2771 char *cmd_str = NULL;
2772 gboolean ret = FALSE;
2774 dbg("function enter");
2775 cmd_str = g_strdup_printf("%s", "AT+CHLD=4");
2777 ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2782 static TReturn imc_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data)
2784 char *cmd_str = NULL;
2785 gboolean ret = FALSE;
2787 dbg("function enter");
2788 cmd_str = g_strdup_printf("%s%s", "AT+CHLD=4", number);
2790 ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2796 gboolean imc_ss_init(TcorePlugin *cp, CoreObject *co_ss)
2798 CoreObject *co_call = NULL;
2800 /* Set operations */
2801 tcore_ss_set_ops(co_ss, &ss_ops);
2804 co_call = tcore_plugin_ref_core_object(cp,
2805 CORE_OBJECT_TYPE_CALL);
2806 if (co_call == NULL) {
2807 err("Can't find CALL core object");
2811 /* Set operations */
2812 tcore_call_control_set_operations(co_call, &call_ops);
2814 tcore_object_add_callback(co_ss, "+CSSU", on_notification_ss_info, NULL);
2815 tcore_object_add_callback(co_ss, "+CSSI", on_notification_ss_info, NULL);
2816 tcore_object_add_callback(co_ss, "+CUSD", on_notification_ss_ussd, NULL);
2821 void imc_ss_exit(TcorePlugin *cp, CoreObject *co_ss)