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>
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 s_ss_barring_activate(CoreObject *o, UserRequest *ur);
73 static TReturn s_ss_barring_deactivate(CoreObject *o, UserRequest *ur);
74 static TReturn s_ss_barring_change_password(CoreObject *o, UserRequest *ur);
75 static TReturn s_ss_barring_get_status(CoreObject *o, UserRequest *ur);
77 static TReturn s_ss_forwarding_activate(CoreObject *o, UserRequest *ur);
78 static TReturn s_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur);
79 static TReturn s_ss_forwarding_register(CoreObject *o, UserRequest *ur);
80 static TReturn s_ss_forwarding_deregister(CoreObject *o, UserRequest *ur);
81 static TReturn s_ss_forwarding_get_status(CoreObject *o, UserRequest *ur);
83 static TReturn s_ss_waiting_activate(CoreObject *o, UserRequest *ur);
84 static TReturn s_ss_waiting_deactivate(CoreObject *o, UserRequest *ur);
85 static TReturn s_ss_waiting_get_status(CoreObject *o, UserRequest *ur);
87 static TReturn s_ss_cli_activate(CoreObject *o, UserRequest *ur);
88 static TReturn s_ss_cli_deactivate(CoreObject *o, UserRequest *ur);
89 static TReturn s_ss_cli_get_status(CoreObject *o, UserRequest *ur);
91 static TReturn s_ss_send_ussd(CoreObject *o, UserRequest *ur);
93 static TReturn s_ss_set_aoc(CoreObject *o, UserRequest *ur);
94 static TReturn s_ss_get_aoc(CoreObject *o, UserRequest *ur);
96 static TReturn s_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
97 static TReturn s_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
98 static TReturn s_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
99 static TReturn s_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
100 static TReturn s_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
101 static TReturn s_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
102 static TReturn s_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
103 static TReturn s_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;
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;
642 dbg("RESPONSE NOT OK");
644 line = (const char *) response->final_response;
645 tokens = tcore_at_tok_new(line);
647 if (g_slist_length(tokens) < 1) {
648 dbg("err cause not specified or string corrupted");
649 resp.err = SS_ERROR_SYSTEMFAILURE;
651 err = atoi(g_slist_nth_data(tokens, 0));
652 // TODO: CMEE error mapping is required.
653 resp.err = SS_ERROR_SYSTEMFAILURE;
655 tcore_at_tok_free(tokens);
658 dbg("on_response_ss_barring_set - rsp.err : %d, ur : %x flavor_type = %d", resp.err, ur, info->flavor_type);
659 dbg("[ check ] class : 0x%x", info->class);
661 if (response->success > 0) {
662 if (info->class == SS_CLASS_VOICE) {
663 class = SS_CLASS_ALL_TELE_BEARER;
666 ur_dup = tcore_user_request_ref(ur);
668 if (info->flavor_type == SS_BARR_MODE_AB || info->flavor_type == SS_BARR_MODE_AOB) {
669 _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAOC, info->resp);
670 } else if (info->flavor_type == SS_BARR_MODE_AIB) {
671 _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAIC, info->resp);
673 _ss_barring_get(o, ur_dup, class, info->flavor_type, info->resp);
677 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
679 dbg("[ error ] ur is 0");
685 static void on_response_ss_barring_change_pwd(TcorePending *p, int data_len, const void *data, void *user_data)
687 const TcoreATResponse *response = data;
688 struct ss_confirm_info *info = 0;
690 struct tresp_ss_barring resp;
692 GSList *tokens = NULL;
695 dbg("function enter");
696 ur = tcore_pending_ref_user_request(p);
697 info = (struct ss_confirm_info *) user_data;
699 if (response->success > 0) {
701 resp.err = SS_ERROR_NONE;
703 dbg("RESPONSE NOT OK");
705 line = (const char *) response->final_response;
706 tokens = tcore_at_tok_new(line);
708 if (g_slist_length(tokens) < 1) {
709 dbg("err cause not specified or string corrupted");
710 resp.err = SS_ERROR_SYSTEMFAILURE;
712 err = atoi(g_slist_nth_data(tokens, 0));
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_barring), &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 err = atoi(g_slist_nth_data(tokens, 0));
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 err = atoi(g_slist_nth_data(tokens, 0));
903 // TODO: CMEE error mapping is required.
904 resp.err = SS_ERROR_SYSTEMFAILURE;
906 tcore_at_tok_free(tokens);
909 dbg("on_confirmation_ss_ussd - rsp.err : %d, ur : %x", resp.err, ur);
911 if (response->success > 0) {
912 if (type == TCORE_SS_USSD_TYPE_USER_INITIATED) {
913 dbg("ussd type %d", resp.type);
916 tcore_ss_ussd_get_session_data(ussd_s, (void **) &ussd_ur);
918 tcore_user_request_free(ussd_ur);
924 tcore_ss_ussd_destroy_session(ussd_s);
927 if (UssdResp == FALSE) { // to avoid sending multiple response to application.
928 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_ussd), &resp);
932 dbg("[ error ] ur : (0)");
937 static void on_response_ss_barring_get(TcorePending *p, int data_len, const void *data, void *user_data)
940 int status = 0, classx = 0, err = 0;
942 struct ss_confirm_info *info = 0;
943 struct tresp_ss_barring resp;
944 int countRecords = 0, countValidRecords = 0;
945 GSList *tokens = NULL;
949 const TcoreATResponse *response;
951 dbg("function enter");
954 ur = tcore_pending_ref_user_request(p);
955 info = (struct ss_confirm_info *) user_data;
957 if (response->lines) {
958 respdata = (GSList *) response->lines;
959 countRecords = g_slist_length(respdata);
960 dbg("total records : %d", countRecords);
963 dbg("no active status - return to user");
965 resp.record_num = countRecords;
967 if (resp.record_num > 0) {
968 resp.record = g_new0(struct barring_info, resp.record_num);
969 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
970 line = (const char *) (respdata->data);
971 tokens = tcore_at_tok_new(line);
974 stat = g_slist_nth_data(tokens, 0);
976 dbg("Stat is missing");
982 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
984 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
986 dbg("call barring status - %d", status);
989 classx_str = g_slist_nth_data(tokens, 1);
992 dbg("class error. classx not exist - set to requested one : %d", info->class);
993 switch (info->class) {
994 case SS_CLASS_ALL_TELE:
1002 case SS_CLASS_ALL_DATA_TELE:
1014 case SS_CLASS_ALL_CS_SYNC:
1020 dbg("unsupported class %d. set to default : 7", info->class);
1024 classx = atoi(classx_str);
1025 dbg("call barring classx - %d", classx);
1030 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1034 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1038 resp.record[countValidRecords].class = SS_CLASS_FAX;
1042 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1046 resp.record[countValidRecords].class = SS_CLASS_SMS;
1050 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1054 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1058 dbg("unspoorted class : [%d]\n", classx);
1062 resp.record[countValidRecords].mode = (enum telephony_ss_barring_mode) (info->flavor_type);
1063 countValidRecords++;
1064 tcore_at_tok_free(tokens);
1068 dbg("invalid field found. coutinue");
1069 tcore_at_tok_free(tokens);
1073 dbg("valid count :%d", countValidRecords);
1074 resp.record_num = countValidRecords;
1075 resp.err = SS_ERROR_NONE;
1077 dbg("no active status - return to user");
1080 if (response->success > 0) {
1082 resp.err = SS_ERROR_NONE;
1084 dbg("RESPONSE NOT OK");
1085 resp.err = TCORE_RETURN_FAILURE;
1087 resp.record_num = 0;
1089 line = (const char *) response->final_response;
1090 tokens = tcore_at_tok_new(line);
1092 if (g_slist_length(tokens) < 1) {
1093 dbg("err cause not specified or string corrupted");
1094 resp.err = SS_ERROR_SYSTEMFAILURE;
1096 err = atoi(g_slist_nth_data(tokens, 0));
1097 // TODO: CMEE error mapping is required.
1098 resp.err = SS_ERROR_SYSTEMFAILURE;
1100 tcore_at_tok_free(tokens);
1103 dbg("on_response_ss_barring_get- rsp.err : %d, ur : %x", resp.err, ur);
1106 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
1108 dbg("[ error ] ur is 0");
1111 g_free(resp.record);
1118 static void on_response_ss_forwarding_get(TcorePending *p, int data_len, const void *data, void *user_data)
1120 UserRequest *ur = 0;
1121 int classx = 0, err = 0, time = 0;
1123 struct ss_confirm_info *info = 0;
1124 struct tresp_ss_forwarding resp;
1125 int countRecords = 0, countValidRecords = 0;
1127 GSList *respdata = NULL, *tokens = NULL;
1129 char *classx_str, *status, *ton, *time_str;
1130 const TcoreATResponse *response;
1132 dbg("function enter");
1135 ur = tcore_pending_ref_user_request(p);
1136 info = (struct ss_confirm_info *) user_data;
1137 if (response->lines) {
1138 respdata = (GSList *) response->lines;
1139 countRecords = g_slist_length(respdata);
1140 dbg("total records : %d", countRecords);
1143 dbg("no active status - return to user");
1145 resp.record_num = countRecords;
1147 if (resp.record_num > 0) {
1148 resp.record = g_new0(struct forwarding_info, resp.record_num);
1150 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1151 line = (const char *) (respdata->data);
1152 tokens = tcore_at_tok_new(line);
1155 status = g_slist_nth_data(tokens, 0);
1157 dbg("start line error. skip this line");
1160 if (atoi(status) == 1) {
1161 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1163 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1168 classx_str = g_slist_nth_data(tokens, 1);
1170 dbg("class error. skip this line");
1173 switch (atoi(classx_str)) {
1175 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1179 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1183 resp.record[countValidRecords].class = SS_CLASS_FAX;
1187 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1191 resp.record[countValidRecords].class = SS_CLASS_SMS;
1195 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1199 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1203 dbg("unspoorted class : [%d]\n", classx);
1209 // parse <numer> <type>
1210 num = g_slist_nth_data(tokens, 2);
1212 dbg("number - %s", num);
1213 memcpy((resp.record[countValidRecords].number), num, strlen(num));
1214 resp.record[countValidRecords].number_present = TRUE;
1216 ton = g_slist_nth_data(tokens, 3);
1218 resp.record[countValidRecords].number_type = atoi(ton);
1219 dbg("number type - %d", resp.record[countValidRecords].number_type);
1223 // skip <subaddr> <satype>
1225 time_str = g_slist_nth_data(tokens, 6);
1227 time = atoi(time_str);
1228 resp.record[countValidRecords].time = (enum telephony_ss_forwarding_no_reply_time) time;
1229 dbg("time - %d", time);
1232 resp.record[countValidRecords].mode = (enum telephony_ss_forwarding_mode) (info->flavor_type);
1233 dbg("flavor_type - %d", (enum telephony_ss_forwarding_mode) (info->flavor_type));
1235 countValidRecords++;
1236 tcore_at_tok_free(tokens);
1239 dbg("invalid field found. coutinue");
1240 tcore_at_tok_free(tokens);
1243 dbg("valid count :%d", countValidRecords);
1244 resp.record_num = countValidRecords;
1245 resp.err = SS_ERROR_NONE;
1247 dbg("no active status - return to user");
1250 if (response->success > 0) {
1252 resp.err = SS_ERROR_NONE;
1254 dbg("RESPONSE NOT OK");
1256 resp.record_num = 0;
1257 line = (const char *) response->final_response;
1258 tokens = tcore_at_tok_new(line);
1260 if (g_slist_length(tokens) < 1) {
1261 dbg("err cause not specified or string corrupted");
1262 resp.err = SS_ERROR_SYSTEMFAILURE;
1264 err = atoi(g_slist_nth_data(tokens, 0));
1265 /* TODO: CMEE error mapping is required. */
1266 resp.err = SS_ERROR_SYSTEMFAILURE;
1268 tcore_at_tok_free(tokens);
1271 dbg("on_response_ss_forwarding_get- rsp.err : %d, ur : %x", resp.err, ur);
1273 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
1275 dbg("[ error ] ur is 0");
1278 g_free(resp.record);
1284 static void on_response_ss_waiting_get(TcorePending *p, int data_len, const void *data, void *user_data)
1286 UserRequest *ur = 0;
1287 GSList *respdata, *tokens = NULL;
1288 int classx = 0, err = 0;
1289 struct ss_confirm_info *info = 0;
1290 struct tresp_ss_waiting resp;
1291 int countRecords = 0, countValidRecords = 0;
1293 char *classx_str, *status;
1294 const TcoreATResponse *response;
1296 dbg("function enter");
1298 ur = tcore_pending_ref_user_request(p);
1299 info = (struct ss_confirm_info *) user_data;
1301 if (response->lines) {
1302 respdata = (GSList *) response->lines;
1303 countRecords = g_slist_length(respdata);
1304 dbg("total records : %d", countRecords);
1307 dbg("no active status - return to user");
1309 resp.record_num = countRecords;
1312 if (resp.record_num > 0) {
1313 resp.record = g_new0(struct waiting_info, resp.record_num);
1315 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1316 line = (const char *) (respdata->data);
1317 tokens = tcore_at_tok_new(line);
1320 status = g_slist_nth_data(tokens, 0);
1322 dbg("Missing stat in responce ");
1325 if (atoi(status) == 1) {
1326 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1328 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1331 dbg("status = %d", resp.record[countValidRecords].status);
1334 classx_str = g_slist_nth_data(tokens, 1);
1336 dbg("error - class is missing");
1339 switch (atoi(classx_str)) {
1341 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1345 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1349 resp.record[countValidRecords].class = SS_CLASS_FAX;
1353 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1357 resp.record[countValidRecords].class = SS_CLASS_SMS;
1361 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1365 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1369 dbg("unspoorted class : [%d]\n", classx);
1373 dbg("class info %d", resp.record[countValidRecords].class);
1376 countValidRecords++;
1377 tcore_at_tok_free(tokens);
1380 dbg("invalid field found. coutinue");
1381 tcore_at_tok_free(tokens);
1385 dbg("valid count :%d", countValidRecords);
1386 resp.record_num = countValidRecords;
1387 resp.err = SS_ERROR_NONE;
1389 dbg("no active status - return to user");
1392 if (response->success > 0) {
1394 resp.err = SS_ERROR_NONE;
1396 dbg("RESPONSE NOT OK");
1398 resp.record_num = 0;
1399 line = (const char *) response->final_response;
1400 tokens = tcore_at_tok_new(line);
1402 if (g_slist_length(tokens) < 1) {
1403 dbg("err cause not specified or string corrupted");
1404 resp.err = SS_ERROR_SYSTEMFAILURE;
1406 err = atoi(g_slist_nth_data(tokens, 0));
1407 // TODO: CMEE error mapping is required.
1408 resp.err = SS_ERROR_SYSTEMFAILURE;
1410 tcore_at_tok_free(tokens);
1413 dbg("on_response_ss_waiting_get - rsp.err : %d, ur : %x", resp.err, ur);
1415 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
1417 dbg("[ error ] ur is 0");
1420 g_free(resp.record);
1427 static void on_response_ss_cli_get(TcorePending *p, int data_len, const void *data, void *user_data)
1429 UserRequest *ur = 0;
1430 struct tresp_ss_cli resp;
1431 enum telephony_ss_cli_type *p_type = NULL;
1432 char *line = NULL, *status;
1435 GSList *tokens = NULL;
1436 const TcoreATResponse *response;
1438 dbg("function enter");
1440 ur = tcore_pending_ref_user_request(p);
1441 p_type = (enum telephony_ss_cli_type *) (user_data);
1443 if (response->success > 0) {
1444 line = (char *) (((GSList *) response->lines)->data);
1445 tokens = tcore_at_tok_new(line);
1447 if (*p_type == SS_CLI_TYPE_CLIR) {
1449 dbg("CLI type is CLIR");
1451 status = g_slist_nth_data(tokens, 0);
1454 dbg("Call line identification adjustment missing <n>");
1456 cli_adj = atoi(status);
1457 dbg("CLIR response value of <n> - %d", cli_adj);
1461 status = g_slist_nth_data(tokens, 1);
1463 dbg("status is missing<m>");
1465 stat = atoi(status);
1466 dbg("CLIR response value of <m> - %d", stat);
1468 if (stat == 1 || stat == 3) {
1471 resp.status = FALSE;
1473 } else if (cli_adj == 1) {
1476 resp.status = FALSE;
1478 dbg("resp.status - %d", resp.status);
1480 tcore_at_tok_free(tokens);
1483 status = g_slist_nth_data(tokens, 0);
1485 dbg("Stat is missing");
1487 stat = atoi(status);
1491 resp.status = FALSE;
1493 dbg("resp.status - %d", resp.status);
1495 tcore_at_tok_free(tokens);
1499 if (response->success > 0) {
1501 resp.err = SS_ERROR_NONE;
1503 dbg("RESPONSE NOT OK");
1505 line = (char *) response->final_response;
1506 tokens = tcore_at_tok_new(line);
1508 if (g_slist_length(tokens) < 1) {
1509 dbg("err cause not specified or string corrupted");
1510 resp.err = SS_ERROR_SYSTEMFAILURE;
1512 err = atoi(g_slist_nth_data(tokens, 0));
1513 // TODO: CMEE error mapping is required.
1514 resp.err = SS_ERROR_SYSTEMFAILURE;
1516 tcore_at_tok_free(tokens);
1519 resp.type = *p_type;
1520 dbg("check - resp.type = %d ", resp.type);
1522 tcore_user_request_send_response(ur, TRESP_SS_CLI_GET_STATUS, sizeof(struct tresp_ss_cli), &resp);
1524 dbg("[ error ] ur : (0)");
1529 static struct tcore_ss_operations ss_ops = {
1530 .barring_activate = s_ss_barring_activate,
1531 .barring_deactivate = s_ss_barring_deactivate,
1532 .barring_change_password = s_ss_barring_change_password,
1533 .barring_get_status = s_ss_barring_get_status,
1534 .forwarding_activate = s_ss_forwarding_activate,
1535 .forwarding_deactivate = s_ss_forwarding_deactivate,
1536 .forwarding_register = s_ss_forwarding_register,
1537 .forwarding_deregister = s_ss_forwarding_deregister,
1538 .forwarding_get_status = s_ss_forwarding_get_status,
1539 .waiting_activate = s_ss_waiting_activate,
1540 .waiting_deactivate = s_ss_waiting_deactivate,
1541 .waiting_get_status = s_ss_waiting_get_status,
1542 .cli_activate = s_ss_cli_activate,
1543 .cli_deactivate = s_ss_cli_deactivate,
1544 .cli_get_status = s_ss_cli_get_status,
1545 .send_ussd = s_ss_send_ussd,
1546 .set_aoc = s_ss_set_aoc,
1547 .get_aoc = s_ss_get_aoc,
1551 static TReturn _ss_barring_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1553 struct treq_ss_barring *barring = 0;
1554 struct ss_confirm_info *user_data = 0;
1555 char *cmd_str = NULL;
1557 TcorePending *pending = NULL;
1558 TcoreATRequest *req;
1559 char passwd[MAX_SS_BARRING_PASSWORD_LEN + 1];
1562 char *facility = NULL;
1563 gboolean ret = FALSE;
1565 dbg("function enter");
1566 barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1569 case SS_OPCO_ACTIVATE:
1573 case SS_OPCO_DEACTIVATE:
1578 dbg("unsupported opco : %d", op);
1579 return TCORE_RETURN_FAILURE;
1581 dbg("opco - %d", opco);
1583 switch (barring->mode) {
1584 case SS_BARR_MODE_BAOC:
1588 case SS_BARR_MODE_BOIC:
1592 case SS_BARR_MODE_BOIC_NOT_HC:
1596 case SS_BARR_MODE_BAIC:
1600 case SS_BARR_MODE_BIC_ROAM:
1604 case SS_BARR_MODE_AB:
1608 case SS_BARR_MODE_AOB:
1612 case SS_BARR_MODE_AIB:
1616 case SS_BARR_MODE_BIC_NOT_SIM:
1619 dbg("unspported mode %d", barring->mode);
1620 return TCORE_RETURN_FAILURE;
1623 dbg("facility - %s", facility);
1625 switch (barring->class) {
1626 case SS_CLASS_ALL_TELE:
1630 case SS_CLASS_VOICE:
1634 case SS_CLASS_ALL_DATA_TELE:
1646 case SS_CLASS_ALL_CS_SYNC:
1652 dbg("unsupported class %d. set to default : 7", barring->class);
1656 dbg("classx - %d", classx);
1658 // null-ended pwd handling added - unexpected 0x11 value observed in req string
1659 memcpy(passwd, barring->password, MAX_SS_BARRING_PASSWORD_LEN);
1660 passwd[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1661 dbg("passwd - %s", passwd);
1663 hal = tcore_object_get_hal(o);
1664 pending = tcore_pending_new(o, 0);
1666 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d", facility, opco, passwd, classx);
1667 dbg("request command : %s", cmd_str);
1669 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1670 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1672 tcore_pending_set_request_data(pending, 0, req);
1674 user_data = g_new0(struct ss_confirm_info, 1);
1675 if (op == SS_OPCO_ACTIVATE) {
1676 user_data->resp = TRESP_SS_BARRING_ACTIVATE;
1677 } else if (op == SS_OPCO_DEACTIVATE) {
1678 user_data->resp = TRESP_SS_BARRING_DEACTIVATE;
1680 dbg("[ error ] wrong ss opco (0x%x)", op);
1681 if (user_data != NULL) {
1685 return TCORE_RETURN_FAILURE;
1687 user_data->flavor_type = (int) (barring->mode);
1688 user_data->class = barring->class;
1690 ret = _ss_request_message(pending, o, ur, on_response_ss_barring_set, user_data);
1694 dbg("AT request sent failed ");
1695 if (user_data != NULL) {
1698 return TCORE_RETURN_FAILURE;
1700 return TCORE_RETURN_SUCCESS;
1703 static TReturn _ss_barring_get(CoreObject *o,
1705 enum telephony_ss_class class,
1706 enum telephony_ss_barring_mode mode,
1707 enum tcore_response_command resp)
1709 struct ss_confirm_info *user_data = 0;
1710 gboolean ret = FALSE;
1711 char *cmd_str = NULL;
1713 char *facility = NULL;
1715 TcorePending *pending = NULL;
1716 TcoreATRequest *req;
1718 dbg("function enter");
1720 // query status - opco is fixed to 2
1724 case SS_BARR_MODE_BAOC:
1728 case SS_BARR_MODE_BOIC:
1732 case SS_BARR_MODE_BOIC_NOT_HC:
1736 case SS_BARR_MODE_BAIC:
1740 case SS_BARR_MODE_BIC_ROAM:
1744 case SS_BARR_MODE_AB:
1745 case SS_BARR_MODE_AOB:
1746 case SS_BARR_MODE_AIB:
1747 case SS_BARR_MODE_BIC_NOT_SIM:
1749 dbg("unsupported mode %d", mode);
1750 return TCORE_RETURN_FAILURE;
1753 dbg("facility - %s", facility);
1756 case SS_CLASS_ALL_TELE:
1760 case SS_CLASS_VOICE:
1764 case SS_CLASS_ALL_DATA_TELE:
1776 case SS_CLASS_ALL_CS_SYNC:
1782 dbg("unsupported class %d. set to default : 7", class);
1785 dbg("class - %d", classx);
1788 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d", facility, opco);
1790 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d", facility, opco, classx);
1792 dbg("request command : %s", cmd_str);
1794 hal = tcore_object_get_hal(o);
1795 pending = tcore_pending_new(o, 0);
1796 req = tcore_at_request_new(cmd_str, "+CLCK", TCORE_AT_MULTILINE);
1797 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1799 tcore_pending_set_request_data(pending, 0, req);
1801 user_data = g_new0(struct ss_confirm_info, 1);
1802 user_data->resp = resp;
1803 user_data->flavor_type = (int) (mode);
1804 user_data->class = class;
1806 ret = _ss_request_message(pending, o, ur, on_response_ss_barring_get, user_data);
1810 dbg("AT request sent failed ");
1811 if (user_data != NULL) {
1814 return TCORE_RETURN_FAILURE;
1817 return TCORE_RETURN_SUCCESS;
1820 static TReturn s_ss_barring_activate(CoreObject *o, UserRequest *ur)
1822 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1823 dbg("cp not ready/n");
1824 return TCORE_RETURN_ENOSYS;
1826 return _ss_barring_set(o, ur, SS_OPCO_ACTIVATE);
1829 static TReturn s_ss_barring_deactivate(CoreObject *o, UserRequest *ur)
1831 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1832 dbg("cp not ready/n");
1833 return TCORE_RETURN_ENOSYS;
1835 return _ss_barring_set(o, ur, SS_OPCO_DEACTIVATE);
1838 static TReturn s_ss_barring_change_password(CoreObject *o, UserRequest *ur)
1841 TcorePending *pending = NULL;
1842 TcoreATRequest *req;
1843 struct treq_ss_barring_change_password *barring = 0;
1844 struct ss_confirm_info *user_data = 0;
1845 char *cmd_str = NULL;
1846 gboolean ret = FALSE;
1847 char old_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1848 char new_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1850 dbg("function enter");
1852 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1853 dbg("cp not ready/n");
1854 return TCORE_RETURN_ENOSYS;
1857 barring = (struct treq_ss_barring_change_password *) tcore_user_request_ref_data(ur, 0);
1859 if (barring->password_old == NULL || barring->password_new == NULL) {
1860 dbg("[error]password is null");
1861 return TCORE_RETURN_FAILURE;
1863 memcpy(old_password, barring->password_old, MAX_SS_BARRING_PASSWORD_LEN);
1864 old_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1865 memcpy(new_password, barring->password_new, MAX_SS_BARRING_PASSWORD_LEN);
1866 new_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1868 dbg("old passwd - %s new passwd- %s", old_password, new_password);
1869 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB", old_password, new_password);
1870 dbg("request command : %s", cmd_str);
1872 hal = tcore_object_get_hal(o);
1873 pending = tcore_pending_new(o, 0);
1874 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1875 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1877 tcore_pending_set_request_data(pending, 0, req);
1879 user_data = g_new0(struct ss_confirm_info, 1);
1880 user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
1882 ret = _ss_request_message(pending, o, ur, on_response_ss_barring_change_pwd, user_data);
1885 dbg("AT request sent failed ");
1886 if (user_data != NULL) {
1889 return TCORE_RETURN_FAILURE;
1891 return TCORE_RETURN_SUCCESS;
1894 static TReturn s_ss_barring_get_status(CoreObject *o, UserRequest *ur)
1896 struct treq_ss_barring *barring = 0;
1898 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1899 dbg("cp not ready/n");
1900 return TCORE_RETURN_ENOSYS;
1902 barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1904 return _ss_barring_get(o, ur, barring->class, barring->mode, TRESP_SS_BARRING_GET_STATUS);
1907 static TReturn _ss_forwarding_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1909 struct treq_ss_forwarding *forwarding = 0;
1910 struct ss_confirm_info *user_data = 0;
1911 gboolean ret = FALSE;
1913 char *cmd_str = NULL;
1914 char *tmp_str = NULL;
1915 int reason = 0, mode = 0, num_type = 0, classx = 0, time = 0;
1916 gboolean valid_num = FALSE;
1918 TcorePending *pending = NULL;
1919 TcoreATRequest *req;
1921 dbg("_ss_forwarding_set with opco %d ", op);
1923 forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
1924 switch (forwarding->mode) {
1925 case SS_CF_MODE_CFU:
1929 case SS_CF_MODE_CFB:
1933 case SS_CF_MODE_CFNRy:
1937 case SS_CF_MODE_CFNRc:
1941 case SS_CF_MODE_CF_ALL:
1945 case SS_CF_MODE_CFC:
1950 dbg("unsupported reason : %d");
1951 return TCORE_RETURN_FAILURE;
1955 dbg("reason = %d", reason);
1957 case SS_OPCO_DEACTIVATE:
1961 case SS_OPCO_ACTIVATE:
1974 dbg("unsupported opco : %d", op);
1975 return TCORE_RETURN_FAILURE;
1978 dbg("mode = %d", mode);
1981 switch (forwarding->class) {
1982 case SS_CLASS_ALL_TELE:
1986 case SS_CLASS_VOICE:
1990 case SS_CLASS_ALL_DATA_TELE:
2002 case SS_CLASS_ALL_CS_SYNC:
2008 dbg("unsupported class %d. set to default : 7", forwarding->class);
2011 dbg("classx = %d", classx);
2014 len = strlen(forwarding->number);
2017 if (forwarding->number[0] == '+')
2018 num_type = ((NUM_TYPE_INTERNATIONAL << 4) | NUM_PLAN_ISDN);
2022 dbg("number = %s", forwarding->number);
2024 user_data = g_new0(struct ss_confirm_info, 1);
2028 user_data->resp = TRESP_SS_FORWARDING_REGISTER;
2032 user_data->resp = TRESP_SS_FORWARDING_DEREGISTER;
2035 case SS_OPCO_ACTIVATE:
2036 user_data->resp = TRESP_SS_FORWARDING_ACTIVATE;
2039 case SS_OPCO_DEACTIVATE:
2040 user_data->resp = TRESP_SS_FORWARDING_DEACTIVATE;
2044 dbg("[ error ] unknown op (0x%x)", op);
2048 if (forwarding->number[0] == '+')
2053 if (op == SS_OPCO_REG)
2054 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,\"%s\",%d,%d", reason, mode, forwarding->number, num_type, classx);
2055 else // other opcode does not need num field
2056 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2058 if (forwarding->mode == SS_CF_MODE_CFNRy) {
2059 // add time info to 'no reply' case
2060 time = (int) (forwarding->time);
2061 cmd_str = g_strdup_printf("%s,,,%d", tmp_str, time);
2063 cmd_str = g_strdup_printf("%s", tmp_str);
2066 dbg("request command : %s", cmd_str);
2067 hal = tcore_object_get_hal(o);
2068 pending = tcore_pending_new(o, 0);
2069 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2070 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2072 tcore_pending_set_request_data(pending, 0, req);
2074 user_data->flavor_type = forwarding->mode;
2075 user_data->class = forwarding->class;
2077 ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_set, user_data);
2083 dbg("AT request sent failed ");
2084 if (user_data != NULL) {
2087 return TCORE_RETURN_FAILURE;
2090 return TCORE_RETURN_SUCCESS;
2093 static TReturn _ss_forwarding_get(CoreObject *o,
2095 enum telephony_ss_class class,
2096 enum telephony_ss_forwarding_mode type,
2097 enum tcore_response_command resp)
2099 struct ss_confirm_info *user_data = 0;
2100 gboolean ret = FALSE;
2101 char *cmd_str = NULL;
2102 int reason = 0, mode = 0, classx = 0;
2104 TcorePending *pending = NULL;
2105 TcoreATRequest *req;
2107 dbg("function enter");
2110 case SS_CF_MODE_CFU:
2114 case SS_CF_MODE_CFB:
2118 case SS_CF_MODE_CFNRy:
2122 case SS_CF_MODE_CFNRc:
2126 case SS_CF_MODE_CF_ALL:
2130 case SS_CF_MODE_CFC:
2135 dbg("unsupported reason : %d");
2138 dbg("reason = %d", reason);
2141 case SS_CLASS_ALL_TELE:
2145 case SS_CLASS_VOICE:
2149 case SS_CLASS_ALL_DATA_TELE:
2161 case SS_CLASS_ALL_CS_SYNC:
2167 dbg("unsupported class %d. set to default : 7", class);
2171 dbg("classx = %d", classx);
2173 // query status - mode set to 2
2175 user_data = g_new0(struct ss_confirm_info, 1);
2176 user_data->resp = resp;
2177 user_data->class = class;
2178 user_data->flavor_type = type;
2181 cmd_str = g_strdup_printf("AT+CCFC=%d,%d", reason, mode);
2183 cmd_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2185 dbg("request command : %s", cmd_str);
2187 hal = tcore_object_get_hal(o);
2188 pending = tcore_pending_new(o, 0);
2189 req = tcore_at_request_new(cmd_str, "+CCFC", TCORE_AT_MULTILINE);
2190 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2192 tcore_pending_set_request_data(pending, 0, req);
2194 ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_get, user_data);
2198 dbg("AT request sent failed ");
2199 if (user_data != NULL) {
2202 return TCORE_RETURN_FAILURE;
2205 return TCORE_RETURN_SUCCESS;
2208 static TReturn s_ss_forwarding_activate(CoreObject *o, UserRequest *ur)
2210 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2211 dbg("cp not ready/n");
2212 return TCORE_RETURN_ENOSYS;
2214 return _ss_forwarding_set(o, ur, SS_OPCO_ACTIVATE);
2217 static TReturn s_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur)
2219 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2220 dbg("cp not ready/n");
2221 return TCORE_RETURN_ENOSYS;
2223 return _ss_forwarding_set(o, ur, SS_OPCO_DEACTIVATE);
2226 static TReturn s_ss_forwarding_register(CoreObject *o, UserRequest *ur)
2228 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2229 dbg("cp not ready/n");
2230 return TCORE_RETURN_ENOSYS;
2232 return _ss_forwarding_set(o, ur, SS_OPCO_REG);
2235 static TReturn s_ss_forwarding_deregister(CoreObject *o, UserRequest *ur)
2237 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2238 dbg("cp not ready/n");
2239 return TCORE_RETURN_ENOSYS;
2241 return _ss_forwarding_set(o, ur, SS_OPCO_DEREG);
2244 static TReturn s_ss_forwarding_get_status(CoreObject *o, UserRequest *ur)
2246 struct treq_ss_forwarding *forwarding = 0;
2248 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2249 dbg("cp not ready/n");
2250 return TCORE_RETURN_ENOSYS;
2253 forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
2255 return _ss_forwarding_get(o, ur, forwarding->class, forwarding->mode, TRESP_SS_FORWARDING_GET_STATUS);
2259 static TReturn _ss_waiting_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode opco)
2261 struct treq_ss_waiting *waiting = 0;
2262 struct ss_confirm_info *user_data = 0;
2263 gboolean ret = FALSE;
2264 int mode = 0, classx = 0;
2267 TcorePending *pending = NULL;
2268 TcoreATRequest *req;
2270 dbg("function enter ");
2271 waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2272 user_data = g_new0(struct ss_confirm_info, 1);
2274 if (opco == SS_OPCO_ACTIVATE) {
2275 user_data->resp = TRESP_SS_WAITING_ACTIVATE;
2277 } else if (opco == SS_OPCO_DEACTIVATE) {
2278 user_data->resp = TRESP_SS_WAITING_DEACTIVATE;
2279 mode = 0; // disable
2281 dbg("[ error ] unknown ss mode (0x%x)", opco);
2283 switch (waiting->class) {
2284 case SS_CLASS_ALL_TELE:
2288 case SS_CLASS_VOICE:
2292 case SS_CLASS_ALL_DATA_TELE:
2306 dbg("unsupported class %d. set to default : 1", waiting->class);
2309 dbg("mode = %d classxx- %d", mode, classx);
2311 user_data->class = waiting->class;
2312 user_data->flavor_type = (int) opco;
2314 cmd_str = g_strdup_printf("AT+CCWA=1,%d,%d", mode, classx); // always enable +CCWA: unsolicited cmd
2315 dbg("request command : %s", cmd_str);
2317 hal = tcore_object_get_hal(o);
2318 pending = tcore_pending_new(o, 0);
2319 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2320 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2322 tcore_pending_set_request_data(pending, 0, req);
2324 ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_set, user_data);
2327 dbg("AT request sent failed ");
2328 if (user_data != NULL) {
2331 return TCORE_RETURN_FAILURE;
2333 return TCORE_RETURN_SUCCESS;
2336 static TReturn _ss_waiting_get(CoreObject *o,
2338 enum telephony_ss_class class,
2339 enum tcore_response_command resp)
2341 struct ss_confirm_info *user_data = 0;
2342 gboolean ret = FALSE;
2343 int classx; // mode,
2346 TcorePending *pending = NULL;
2347 TcoreATRequest *req;
2349 dbg("function enter");
2351 case SS_CLASS_ALL_TELE:
2355 case SS_CLASS_VOICE:
2359 case SS_CLASS_ALL_DATA_TELE:
2373 dbg("unsupported class %d. set to default : 7", class);
2376 dbg("classx - %d", classx);
2378 dbg("allocating user data");
2379 user_data = g_new0(struct ss_confirm_info, 1);
2380 user_data->resp = resp;
2381 user_data->class = class;
2383 cmd_str = g_strdup_printf("AT+CCWA=1,2,%d", classx); // always enable +CCWA: unsolicited cmd , mode is fixed to 2(query status)
2384 dbg("request cmd : %s", cmd_str);
2386 hal = tcore_object_get_hal(o);
2387 pending = tcore_pending_new(o, 0);
2388 req = tcore_at_request_new(cmd_str, "+CCWA", TCORE_AT_MULTILINE);
2389 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2391 tcore_pending_set_request_data(pending, 0, req);
2393 ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_get, user_data);
2396 dbg("AT request sent failed ");
2397 if (user_data != NULL) {
2400 return TCORE_RETURN_FAILURE;
2402 return TCORE_RETURN_SUCCESS;
2405 static TReturn s_ss_waiting_activate(CoreObject *o, UserRequest *ur)
2407 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2408 dbg("cp not ready/n");
2409 return TCORE_RETURN_ENOSYS;
2411 return _ss_waiting_set(o, ur, SS_OPCO_ACTIVATE);
2414 static TReturn s_ss_waiting_deactivate(CoreObject *o, UserRequest *ur)
2416 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2417 dbg("cp not ready/n");
2418 return TCORE_RETURN_ENOSYS;
2420 return _ss_waiting_set(o, ur, SS_OPCO_DEACTIVATE);
2423 static TReturn s_ss_waiting_get_status(CoreObject *o, UserRequest *ur)
2425 struct treq_ss_waiting *waiting = 0;
2427 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2428 dbg("cp not ready/n");
2429 return TCORE_RETURN_ENOSYS;
2431 waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2433 return _ss_waiting_get(o, ur, waiting->class, TRESP_SS_WAITING_GET_STATUS);
2436 static TReturn s_ss_cli_activate(CoreObject *o, UserRequest *ur)
2438 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2439 dbg("cp not ready/n");
2440 return TCORE_RETURN_ENOSYS;
2442 return TCORE_RETURN_SUCCESS;
2445 static TReturn s_ss_cli_deactivate(CoreObject *o, UserRequest *ur)
2447 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2448 dbg("cp not ready/n");
2449 return TCORE_RETURN_ENOSYS;
2451 return TCORE_RETURN_SUCCESS;
2454 static TReturn s_ss_cli_get_status(CoreObject *o, UserRequest *ur)
2456 struct treq_ss_cli *cli = 0;
2457 gboolean ret = FALSE;
2458 char *cmd_prefix = NULL, *rsp_prefix = NULL, *cmd_str = NULL;
2459 enum telephony_ss_cli_type *user_data = 0;
2461 TcorePending *pending = NULL;
2462 TcoreATRequest *req;
2464 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2465 dbg("cp not ready/n");
2466 return TCORE_RETURN_ENOSYS;
2469 cli = (struct treq_ss_cli *) tcore_user_request_ref_data(ur, 0);
2470 switch (cli->type) {
2471 case SS_CLI_TYPE_CLIP:
2472 cmd_prefix = "+CLIP";
2473 rsp_prefix = "+CLIP";
2476 case SS_CLI_TYPE_CLIR:
2477 cmd_prefix = "+CLIR";
2478 rsp_prefix = "+CLIR";
2481 case SS_CLI_TYPE_COLP:
2482 cmd_prefix = "+COLP";
2483 rsp_prefix = "+COLP";
2486 case SS_CLI_TYPE_COLR:
2487 cmd_prefix = "+COLR";
2488 rsp_prefix = "+COLR";
2491 case SS_CLI_TYPE_CNAP:
2492 cmd_prefix = "+CNAP";
2493 rsp_prefix = "+CNAP";
2496 case SS_CLI_TYPE_CDIP:
2498 dbg("unsupported cli_type : %d", cli->type);
2499 return TCORE_RETURN_FAILURE;
2502 dbg("cmd_prefix : %s", cmd_prefix);
2504 cmd_str = g_strdup_printf("AT%s?", cmd_prefix);
2505 dbg("request cmd : %s", cmd_str);
2507 user_data = g_new0(enum telephony_ss_cli_type, 1);
2508 *user_data = cli->type;
2510 hal = tcore_object_get_hal(o);
2511 pending = tcore_pending_new(o, 0);
2513 req = tcore_at_request_new(cmd_str, rsp_prefix, TCORE_AT_SINGLELINE);
2514 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2515 tcore_pending_set_request_data(pending, 0, req);
2517 ret = _ss_request_message(pending, o, ur, on_response_ss_cli_get, user_data);
2520 dbg("AT request sent failed ");
2521 if (user_data != NULL) {
2524 return TCORE_RETURN_FAILURE;
2526 return TCORE_RETURN_SUCCESS;
2529 static TReturn s_ss_send_ussd(CoreObject *o, UserRequest *ur)
2531 UssdSession *ussd_s = 0;
2532 struct treq_ss_ussd *ussd = 0;
2533 struct ss_confirm_info *user_data = 0;
2534 gboolean ret = FALSE;
2537 TcorePending *pending = NULL;
2538 TcoreATRequest *req;
2540 dbg("function enter");
2542 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2543 dbg("cp not ready/n");
2544 return TCORE_RETURN_ENOSYS;
2547 ussd = (struct treq_ss_ussd *) tcore_user_request_ref_data(ur, 0);
2548 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
2549 dbg("request command : %s", cmd_str);
2551 user_data = g_new0(struct ss_confirm_info, 1);
2552 user_data->resp = TRESP_SS_SEND_USSD;
2553 ussd_s = tcore_ss_ussd_get_session(o);
2555 dbg("USSD session does not exist");
2556 tcore_ss_ussd_create_session(o, (enum tcore_ss_ussd_type) ussd->type, (void *) tcore_user_request_ref(ur), 0);
2558 if (ussd->type == SS_USSD_TYPE_USER_INITIATED) {
2559 dbg("[ error ] ussd session is already exist");
2561 return TCORE_RETURN_FAILURE;
2564 tcore_ss_ussd_set_session_type(ussd_s, (enum tcore_ss_ussd_type) ussd->type);
2567 hal = tcore_object_get_hal(o);
2568 pending = tcore_pending_new(o, 0);
2569 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2570 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2572 tcore_pending_set_request_data(pending, 0, req);
2574 ret = _ss_request_message(pending, o, ur, on_confirmation_ss_ussd, user_data);
2578 dbg("AT request sent failed ");
2579 if (user_data != NULL) {
2582 return TCORE_RETURN_FAILURE;
2584 return TCORE_RETURN_SUCCESS;
2587 static TReturn s_ss_set_aoc(CoreObject *o, UserRequest *ur)
2589 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2590 dbg("cp not ready/n");
2591 return TCORE_RETURN_ENOSYS;
2594 dbg("[ error ] unsupported function");
2595 return TCORE_RETURN_SUCCESS;
2598 static TReturn s_ss_get_aoc(CoreObject *o, UserRequest *ur)
2600 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2601 dbg("cp not ready/n");
2602 return TCORE_RETURN_ENOSYS;
2605 dbg("[ error ] unsupported function");
2606 return TCORE_RETURN_SUCCESS;
2610 static struct tcore_call_control_operations call_ops = {
2611 .answer_hold_and_accept = s_ss_manage_call_2_send,
2612 .answer_replace = s_ss_manage_call_1_send,
2613 .answer_reject = s_ss_manage_call_0_send,
2614 .end_specific = s_ss_manage_call_1x_send,
2615 .end_all_active = s_ss_manage_call_1_send,
2616 .end_all_held = s_ss_manage_call_0_send,
2617 .active = s_ss_manage_call_2_send,
2618 .hold = s_ss_manage_call_2_send,
2619 .swap = s_ss_manage_call_2_send,
2620 .join = s_ss_manage_call_3_send,
2621 .split = s_ss_manage_call_2x_send,
2622 .transfer = s_ss_manage_call_4_send,
2623 .deflect = s_ss_manage_call_4dn_send,
2626 static TReturn s_ss_manage_call_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
2628 TcorePending *pending = NULL;
2629 TcoreATRequest *req;
2630 gboolean ret = FALSE;
2632 pending = tcore_pending_new(o, 0);
2633 req = tcore_at_request_new(cmd, NULL, TCORE_AT_NO_RESULT);
2634 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2635 tcore_pending_set_request_data(pending, 0, req);
2637 ret = _ss_request_message(pending, o, ur, (TcorePendingResponseCallback) cb, user_data);
2639 dbg("AT request sent failed ");
2640 return TCORE_RETURN_FAILURE;
2642 return TCORE_RETURN_SUCCESS;
2645 static TReturn s_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2647 char *cmd_str = NULL;
2648 gboolean ret = FALSE;
2650 dbg("function enter");
2651 cmd_str = g_strdup_printf("%s", "AT+CHLD=0");
2652 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2654 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2659 static TReturn s_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2661 char *cmd_str = NULL;
2662 gboolean ret = FALSE;
2664 dbg("function enter");
2665 cmd_str = g_strdup_printf("%s", "AT+CHLD=1");
2666 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2668 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2673 static TReturn s_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2675 char *cmd_str = NULL;
2676 gboolean ret = FALSE;
2678 dbg("function enter");
2679 cmd_str = g_strdup_printf("%s%d", "AT+CHLD=1", id);
2680 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2682 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2687 static TReturn s_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2689 char *cmd_str = NULL;
2690 gboolean ret = FALSE;
2692 dbg("function enter");
2693 cmd_str = g_strdup_printf("%s", "AT+CHLD=2");
2694 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2696 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2701 static TReturn s_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2703 char *cmd_str = NULL;
2704 gboolean ret = FALSE;
2706 dbg("function enter");
2707 cmd_str = g_strdup_printf("%s%d", "AT+CHLD=2", id);
2708 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2710 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2715 static TReturn s_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2717 char *cmd_str = NULL;
2718 gboolean ret = FALSE;
2720 dbg("function enter");
2721 cmd_str = g_strdup_printf("%s", "AT+CHLD=3");
2723 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2729 static TReturn s_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2731 char *cmd_str = NULL;
2732 gboolean ret = FALSE;
2734 dbg("function enter");
2735 cmd_str = g_strdup_printf("%s", "AT+CHLD=4");
2737 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2742 static TReturn s_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data)
2744 char *cmd_str = NULL;
2745 gboolean ret = FALSE;
2747 dbg("function enter");
2748 cmd_str = g_strdup_printf("%s%s", "AT+CHLD=4", number);
2750 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2756 gboolean s_ss_init(TcorePlugin *cp, CoreObject *co_ss)
2758 CoreObject *co_call = NULL;
2760 tcore_ss_override_ops(co_ss, &ss_ops);
2763 co_call = tcore_plugin_ref_core_object(cp,
2764 CORE_OBJECT_TYPE_CALL);
2765 if (co_call == NULL) {
2766 err("Can't find CALL core object");
2770 tcore_call_override_ops(co_call, NULL, &call_ops);
2772 tcore_object_override_callback(co_ss, "+CSSU", on_notification_ss_info, NULL);
2773 tcore_object_override_callback(co_ss, "+CSSI", on_notification_ss_info, NULL);
2774 tcore_object_override_callback(co_ss, "+CUSD", on_notification_ss_ussd, NULL);
2779 void s_ss_exit(TcorePlugin *cp, CoreObject *co_ss)