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;
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, "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);
262 len = strlen(ussd_string) - 1;
264 strncpy(str, ussd_string, len);
266 dbg("USSD String - %s len = %d", str, strlen(str));
268 if ((dcs_str = g_slist_nth_data(tokens, 2))) {
270 dbg("USSD dcs %d", dcs);
276 status = SS_USSD_NO_ACTION_REQUIRE;
280 status = SS_USSD_ACTION_REQUIRE;
284 status = SS_USSD_TERMINATED_BY_NET;
288 status = SS_USSD_OTHER_CLIENT;
292 status = SS_USSD_NOT_SUPPORT;
296 status = SS_USSD_TIME_OUT;
300 dbg("unsupported m : %d", m);
301 status = SS_USSD_MAX;
305 switch (tcore_util_get_cbs_coding_scheme(dcs)) {
306 case TCORE_DCS_TYPE_7_BIT:
307 case TCORE_DCS_TYPE_UNSPECIFIED:
308 // ussd_str = tcore_util_unpack_gsm7bit(str, strlen(str));
311 case TCORE_DCS_TYPE_UCS2:
312 case TCORE_DCS_TYPE_8_BIT:
313 if ((str != NULL) && (strlen(str) > 0)) {
314 ussd_str = g_new0(char, strlen(str) + 1);
315 if (ussd_str != NULL) {
316 memcpy(ussd_str, str, strlen(str));
317 ussd_str[strlen(str)] = '\0';
323 dbg("[ error ] unknown dcs type. ussd_session : %x", ussd_session);
326 enum telephony_ss_ussd_type type;
328 tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
330 dbg("[ error ] ur : (0)");
334 type = (enum telephony_ss_ussd_type) tcore_ss_ussd_get_session_type(ussd_session);
335 dbg("ussd type - %d", type);
337 _ss_ussd_response(ur, ussd_str, type, status);
343 case SS_USSD_NO_ACTION_REQUIRE:
344 case SS_USSD_ACTION_REQUIRE:
345 case SS_USSD_OTHER_CLIENT:
346 case SS_USSD_NOT_SUPPORT:
347 case SS_USSD_TIME_OUT:
351 enum telephony_ss_ussd_type type;
353 tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
355 dbg("[ error ] ur : (0)");
358 type = (enum telephony_ss_ussd_type) tcore_ss_ussd_get_session_type(ussd_session);
359 dbg("ussd type - %d", type);
360 _ss_ussd_response(ur, (const char *) ussd_str, type, status);
364 tcore_ss_ussd_create_session(o, TCORE_SS_USSD_TYPE_NETWORK_INITIATED, 0, 0);
365 _ss_ussd_notification(plugin, (const char *) ussd_str, status);
373 case SS_USSD_TERMINATED_BY_NET:
377 tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
379 tcore_user_request_unref(ur);
381 tcore_ss_ussd_destroy_session(ussd_session);
392 tcore_at_tok_free(tokens);
399 static gboolean on_notification_ss_info(CoreObject *o, const void *data, void *user_data)
401 TcorePlugin *plugin = 0;
403 char *cmd = 0, *number = 0, *pos;
404 int code1 = -1, code2 = -1, index = 0, ton = 0;
405 char *str_code1, *str_code2, *str_ton, *str_index;
406 GSList *tokens = NULL;
408 gboolean cssu = FALSE, cssi = FALSE;
409 GSList *lines = NULL;
411 dbg("function enter");
413 plugin = tcore_object_ref_plugin(o);
414 co = tcore_plugin_ref_core_object(plugin, "call");
416 dbg("[ error ] plugin_ref_core_object : call");
420 lines = (GSList *) data;
421 if (1 != g_slist_length(lines)) {
422 dbg("unsolicited msg but multiple line");
426 cmd = (char *) (lines->data);
427 pos = strchr(cmd, ':');
429 dbg("[ error ] not valid SS- notification ");
432 buf = calloc(pos - cmd + 2, 1);
433 memcpy(buf, cmd, pos - cmd);
434 dbg("buf is %s", buf);
436 if (!strcmp(buf, "+CSSU")) {
437 dbg("SS - +CSSU indication");
439 } else if (!strcmp(buf, "+CSSI")) {
440 dbg("SS - +CSSI indication");
445 // handle %CSSU notification
447 tokens = tcore_at_tok_new(cmd);
449 str_code2 = g_slist_nth_data(tokens, 0);
451 dbg("Code2 is missing from %CSSU indiaction");
453 code2 = atoi(str_code2);
454 // parse [ <index>, <number> <type>]
455 if ((str_index = g_slist_nth_data(tokens, 1))) {
456 index = atoi(str_index);
459 if ((resp = g_slist_nth_data(tokens, 2))) {
460 // Strike off double quotes
461 number = util_removeQuotes(resp);
462 str_ton = g_slist_nth_data(tokens, 3);
470 dbg("CSSU - code2 = %d index = %d number = %s type = %d", code2, index, number, ton);
472 case 0: // this is a forwarded call (MT call setup)
473 tcore_call_information_mt_forwarded_call(co, number);
476 case 2: // call has been put on hold (during a voice call)
477 tcore_call_information_held(co, number);
480 case 3: // call has been retrieved (during a voice call)
481 tcore_call_information_active(co, number);
484 case 4: // multiparty call entered (during a voice call)
485 tcore_call_information_joined(co, number);
488 case 5: // call on hold has been released
489 tcore_call_information_released_on_hold(co, number);
492 case 6: // forward check SS message received (can be received whenever)
493 tcore_call_information_cf_check_ss_message(co, number);
496 case 7: // call is being connected (alerting) with the remote party in alerting state in explicit call transfer operation (during a voice call)
497 tcore_call_information_transfer_alert(co, number);
500 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)
501 tcore_call_information_transfered(co, number);
504 case 9: // this is a deflected call (MT call setup):
505 tcore_call_information_mt_deflected_call(co, number);
509 dbg("CSSU - unsupported code2 : %d", code2);
513 // handle %CSSI notification
516 tokens = tcore_at_tok_new(cmd);
518 str_code1 = g_slist_nth_data(tokens, 0);
520 dbg("Code1 is missing from %CSSI indiaction");
522 code1 = atoi(str_code1);
524 if ((str_index = g_slist_nth_data(tokens, 1))) {
525 index = atoi(str_index);
529 dbg("CSSI - code1 - %d index - %d ", code1, index);
532 case 0: // Unconditional CF is active
533 tcore_call_information_mo_cfu(co);
536 case 1: // some of the conditional call forwarding are active
537 tcore_call_information_mo_cfc(co);
540 case 2: // outgoing call is forwarded
541 tcore_call_information_mo_forwarded(co);
544 case 3: // this call is waiting
545 tcore_call_information_mo_waiting(co);
548 case 5: // outgoing call is barred
549 tcore_call_information_mo_barred_outgoing(co);
552 case 6: // incoming call is barred
553 tcore_call_information_mo_barred_incoming(co);
556 case 7: // CLIR suppression rejected
557 tcore_call_information_mo_clir_suppression_reject(co);
560 case 8: // outgoing call is deflected
561 tcore_call_information_mo_deflected(co);
565 dbg("unsupported cmd : %d", code1);
571 tcore_at_tok_free(tokens);
577 static void on_confirmation_ss_message_send(TcorePending *p, gboolean result, void *user_data)
581 if (result == FALSE) {
589 static void on_response_ss_barring_set(TcorePending *p, int data_len, const void *data, void *user_data)
591 struct ss_confirm_info *info = 0;
592 enum telephony_ss_class class;
595 struct tresp_ss_general resp;
596 UserRequest *ur_dup = 0;
597 GSList *tokens = NULL;
600 const TcoreATResponse *response;
602 dbg("function enter");
604 o = tcore_pending_ref_core_object(p);
605 ur = tcore_pending_ref_user_request(p);
607 info = (struct ss_confirm_info *) user_data;
610 if (response->success > 0) {
612 resp.err = TCORE_RETURN_SUCCESS;
614 dbg("RESPONSE NOT OK");
615 line = (const char *) response->final_response;
616 tokens = tcore_at_tok_new(line);
618 if (g_slist_length(tokens) < 1) {
619 dbg("err cause not specified or string corrupted");
620 resp.err = TCORE_RETURN_3GPP_ERROR;
622 err = atoi(g_slist_nth_data(tokens, 0));
623 // TODO: CMEE error mapping is required.
624 resp.err = TCORE_RETURN_3GPP_ERROR;
626 tcore_at_tok_free(tokens);
629 dbg("on_response_ss_barring_set - rsp.err : %d, ur : %x flavor_type = %d", resp.err, ur, info->flavor_type);
630 dbg("[ check ] class : 0x%x", info->class);
632 if (response->success > 0) {
633 if (info->class == SS_CLASS_VOICE) {
634 class = SS_CLASS_ALL_TELE_BEARER;
637 ur_dup = tcore_user_request_ref(ur);
639 if (info->flavor_type == SS_BARR_MODE_AB || info->flavor_type == SS_BARR_MODE_AOB) {
640 _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAOC, info->resp);
641 } else if (info->flavor_type == SS_BARR_MODE_AIB) {
642 _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAIC, info->resp);
644 _ss_barring_get(o, ur_dup, class, info->flavor_type, info->resp);
648 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
650 dbg("[ error ] ur is 0");
655 static void on_response_ss_barring_change_pwd(TcorePending *p, int data_len, const void *data, void *user_data)
657 const TcoreATResponse *response = data;
658 struct ss_confirm_info *info = 0;
660 struct tresp_ss_general resp;
662 GSList *tokens = NULL;
665 dbg("function enter");
666 ur = tcore_pending_ref_user_request(p);
667 info = (struct ss_confirm_info *) user_data;
669 if (response->success > 0) {
671 resp.err = TCORE_RETURN_SUCCESS;
673 dbg("RESPONSE NOT OK");
675 line = (const char *) response->final_response;
676 tokens = tcore_at_tok_new(line);
678 if (g_slist_length(tokens) < 1) {
679 dbg("err cause not specified or string corrupted");
680 resp.err = TCORE_RETURN_3GPP_ERROR;
682 err = atoi(g_slist_nth_data(tokens, 0));
683 // TODO: CMEE error mapping is required.
684 resp.err = TCORE_RETURN_3GPP_ERROR;
686 tcore_at_tok_free(tokens);
689 dbg("on_response_ss_barring_change_pwd: rsp.err : %d, usr : %x", resp.err, ur);
691 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
693 dbg("[ error ] ur is 0");
699 static void on_response_ss_forwarding_set(TcorePending *p, int data_len, const void *data, void *user_data)
702 UserRequest *ur = 0, *dup_ur = 0;
703 struct ss_confirm_info *info = 0;
704 struct tresp_ss_general resp;
705 GSList *tokens = NULL;
708 const TcoreATResponse *response;
710 dbg("function enter");
713 o = tcore_pending_ref_core_object(p);
714 ur = tcore_pending_ref_user_request(p);
716 info = (struct ss_confirm_info *) user_data;
718 if (response->success > 0) {
720 resp.err = TCORE_RETURN_SUCCESS;
722 dbg("RESPONSE NOT OK");
724 line = (const char *) response->final_response;
725 tokens = tcore_at_tok_new(line);
727 if (g_slist_length(tokens) < 1) {
728 dbg("err cause not specified or string corrupted");
729 resp.err = TCORE_RETURN_3GPP_ERROR;
731 err = atoi(g_slist_nth_data(tokens, 0));
732 // / TODO: CMEE error mapping is required.
733 resp.err = TCORE_RETURN_3GPP_ERROR;
736 tcore_at_tok_free(tokens);
739 dbg("[ check ] class : 0x%x", info->class);
740 dbg("[ check ] flavor_type : 0x%x", info->flavor_type);
742 dbg("on_response_ss_forwarding_set - rsp.err : %d, ur : %x", resp.err, ur);
744 if (response->success > 0) {
745 if (info->flavor_type == SS_CF_MODE_CF_ALL ||
746 info->flavor_type == SS_CF_MODE_CFC) {
748 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
750 dbg("[ error ] ur is 0");
753 dup_ur = tcore_user_request_ref(ur);
754 _ss_forwarding_get(o, dup_ur, info->class, info->flavor_type, info->resp);
758 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
760 dbg("[ error ] ur is 0");
766 static void on_response_ss_waiting_set(TcorePending *p, int data_len, const void *data, void *user_data)
768 CoreObject *core_obj = 0;
770 UserRequest *ur_dup = 0;
771 struct ss_confirm_info *info = 0;
772 struct tresp_ss_general resp;
773 GSList *tokens = NULL;
776 const TcoreATResponse *response;
778 dbg("function enter");
780 core_obj = tcore_pending_ref_core_object(p);
781 ur = tcore_pending_ref_user_request(p);
783 info = (struct ss_confirm_info *) user_data;
785 if (response->success > 0) {
787 resp.err = TCORE_RETURN_SUCCESS;
789 dbg("RESPONSE NOT OK");
791 line = (const char *) response->final_response;
792 tokens = tcore_at_tok_new(line);
794 if (g_slist_length(tokens) < 1) {
795 dbg("err cause not specified or string corrupted");
796 resp.err = TCORE_RETURN_3GPP_ERROR;
798 err = atoi(g_slist_nth_data(tokens, 0));
799 // / TODO: CMEE error mapping is required.
800 resp.err = TCORE_RETURN_3GPP_ERROR;
802 tcore_at_tok_free(tokens);
805 dbg("on_response_ss_waiting_set - rsp.err : %d, ur : %x, class : %d", resp.err, ur, info->class);
807 if (resp.err == TCORE_RETURN_SUCCESS) {
808 ur_dup = tcore_user_request_ref(ur);
809 dbg("Get waiting call status");
810 _ss_waiting_get(core_obj, ur_dup, info->class, info->resp);
813 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
815 dbg("[ error ] ur is 0");
822 static void on_confirmation_ss_ussd(TcorePending *p, int data_len, const void *data, void *user_data)
824 CoreObject *core_obj = 0;
825 struct ss_confirm_info *info = 0;
826 struct tresp_ss_ussd resp;
827 UserRequest *ur = NULL, *ussd_ur = NULL;
828 GSList *tokens = NULL;
831 UssdSession *ussd_s = NULL;
832 enum tcore_ss_ussd_type type = TCORE_SS_USSD_TYPE_MAX;
833 const TcoreATResponse *response;
835 dbg("function enter");
837 ur = tcore_pending_ref_user_request(p);
838 info = (struct ss_confirm_info *) user_data;
840 memset(resp.str, 0x00, MAX_SS_USSD_LEN);
842 core_obj = tcore_pending_ref_core_object(p);
843 ussd_s = tcore_ss_ussd_get_session(core_obj);
846 type = tcore_ss_ussd_get_session_type(ussd_s);
848 dbg("[ error ] ussd_s : (0)");
850 resp.type = (enum telephony_ss_ussd_type) type;
851 resp.status = SS_USSD_MAX; // hardcoded value.
853 if (response->success > 0) {
855 resp.err = TCORE_RETURN_SUCCESS;
857 dbg("RESPONSE NOT OK");
859 line = (const char *) response->final_response;
860 tokens = tcore_at_tok_new(line);
862 if (g_slist_length(tokens) < 1) {
863 dbg("err cause not specified or string corrupted");
864 resp.err = TCORE_RETURN_3GPP_ERROR;
866 err = atoi(g_slist_nth_data(tokens, 0));
867 // TODO: CMEE error mapping is required.
868 resp.err = TCORE_RETURN_3GPP_ERROR;
870 tcore_at_tok_free(tokens);
873 dbg("on_confirmation_ss_ussd - rsp.err : %d, ur : %x", resp.err, ur);
875 if (response->success > 0) {
876 if (type == TCORE_SS_USSD_TYPE_USER_INITIATED) {
877 dbg("ussd type %d", resp.type);
880 tcore_ss_ussd_get_session_data(ussd_s, (void **) &ussd_ur);
882 tcore_user_request_free(ussd_ur);
888 tcore_ss_ussd_destroy_session(ussd_s);
891 if (UssdResp == FALSE) { // to avoid sending multiple response to application.
892 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_ussd), &resp);
896 dbg("[ error ] ur : (0)");
901 static void on_response_ss_barring_get(TcorePending *p, int data_len, const void *data, void *user_data)
904 int status = 0, classx = 0, err = 0;
906 struct ss_confirm_info *info = 0;
907 struct tresp_ss_barring resp;
908 int countRecords = 0, countValidRecords = 0;
909 GSList *tokens = NULL;
913 const TcoreATResponse *response;
915 dbg("function enter");
918 ur = tcore_pending_ref_user_request(p);
919 info = (struct ss_confirm_info *) user_data;
921 if (response->lines) {
922 respdata = (GSList *) response->lines;
923 countRecords = g_slist_length(respdata);
924 dbg("total records : %d", countRecords);
927 dbg("no active status - return to user")
929 resp.record_num = countRecords;
931 if (resp.record_num > 0) {
932 resp.record = g_new0(struct barring_info, resp.record_num);
933 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
934 line = (const char *) (respdata->data);
935 tokens = tcore_at_tok_new(line);
938 stat = g_slist_nth_data(tokens, 0);
940 dbg("Stat is missing");
946 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
948 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
950 dbg("call barring status - %d", status);
953 classx_str = g_slist_nth_data(tokens, 1);
956 dbg("class error. classx not exist - set to requested one : %d", info->class);
957 switch (info->class) {
958 case SS_CLASS_ALL_TELE:
966 case SS_CLASS_ALL_DATA_TELE:
978 case SS_CLASS_ALL_CS_SYNC:
984 dbg("unsupported class %d. set to default : 7", info->class);
988 classx = atoi(classx_str);
989 dbg("call barring classx - %d", classx);
994 resp.record[countValidRecords].class = SS_CLASS_VOICE;
998 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1002 resp.record[countValidRecords].class = SS_CLASS_FAX;
1006 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1010 resp.record[countValidRecords].class = SS_CLASS_SMS;
1014 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1018 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1022 dbg("unspoorted class : [%d]\n", classx);
1026 resp.record[countValidRecords].mode = (enum telephony_ss_barring_mode) (info->flavor_type);
1027 countValidRecords++;
1028 tcore_at_tok_free(tokens);
1032 dbg("invalid field found. coutinue");
1033 tcore_at_tok_free(tokens);
1037 dbg("valid count :%d", countValidRecords);
1038 resp.record_num = countValidRecords;
1039 resp.err = TCORE_RETURN_SUCCESS;
1041 dbg("no active status - return to user")
1044 if (response->success > 0) {
1046 resp.err = TCORE_RETURN_SUCCESS;
1048 dbg("RESPONSE NOT OK");
1049 resp.err = TCORE_RETURN_FAILURE;
1051 line = (const char *) response->final_response;
1052 tokens = tcore_at_tok_new(line);
1054 if (g_slist_length(tokens) < 1) {
1055 dbg("err cause not specified or string corrupted");
1056 resp.err = TCORE_RETURN_3GPP_ERROR;
1058 err = atoi(g_slist_nth_data(tokens, 0));
1059 // TODO: CMEE error mapping is required.
1060 resp.err = TCORE_RETURN_3GPP_ERROR;
1062 tcore_at_tok_free(tokens);
1065 dbg("on_response_ss_barring_get- rsp.err : %d, ur : %x", resp.err, ur);
1068 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
1070 dbg("[ error ] ur is 0");
1073 g_free(resp.record);
1080 static void on_response_ss_forwarding_get(TcorePending *p, int data_len, const void *data, void *user_data)
1082 UserRequest *ur = 0;
1083 int classx = 0, err = 0, time = 0;
1085 struct ss_confirm_info *info = 0;
1086 struct tresp_ss_forwarding resp;
1087 int countRecords = 0, countValidRecords = 0;
1089 GSList *respdata = NULL, *tokens = NULL;
1091 char *classx_str, *status, *ton, *time_str;
1092 const TcoreATResponse *response;
1094 dbg("function enter");
1097 ur = tcore_pending_ref_user_request(p);
1098 info = (struct ss_confirm_info *) user_data;
1099 if (response->lines) {
1100 respdata = (GSList *) response->lines;
1101 countRecords = g_slist_length(respdata);
1102 dbg("total records : %d", countRecords);
1105 dbg("no active status - return to user")
1107 resp.record_num = countRecords;
1109 if (resp.record_num > 0) {
1110 resp.record = g_new0(struct forwarding_info, resp.record_num);
1112 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1113 line = (const char *) (respdata->data);
1114 tokens = tcore_at_tok_new(line);
1117 status = g_slist_nth_data(tokens, 0);
1119 dbg("start line error. skip this line");
1122 if (atoi(status) == 1) {
1123 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1125 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1130 classx_str = g_slist_nth_data(tokens, 1);
1132 dbg("class error. skip this line");
1135 switch (atoi(classx_str)) {
1137 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1141 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1145 resp.record[countValidRecords].class = SS_CLASS_FAX;
1149 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1153 resp.record[countValidRecords].class = SS_CLASS_SMS;
1157 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1161 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1165 dbg("unspoorted class : [%d]\n", classx);
1171 // parse <numer> <type>
1172 num = g_slist_nth_data(tokens, 2);
1174 dbg("number - %s", num);
1175 memcpy((resp.record[countValidRecords].number), num, strlen(num));
1176 resp.record[countValidRecords].number_present = TRUE;
1178 ton = g_slist_nth_data(tokens, 3);
1180 resp.record[countValidRecords].number_type = atoi(ton);
1181 dbg("number type - %d", resp.record[countValidRecords].number_type);
1185 // skip <subaddr> <satype>
1187 time_str = g_slist_nth_data(tokens, 6);
1189 time = atoi(time_str);
1190 resp.record[countValidRecords].time = (enum telephony_ss_forwarding_no_reply_time) time;
1191 dbg("time - %d", time);
1194 resp.record[countValidRecords].mode = (enum telephony_ss_forwarding_mode) (info->flavor_type);
1195 dbg("flavor_type - %d", (enum telephony_ss_forwarding_mode) (info->flavor_type));
1197 countValidRecords++;
1198 tcore_at_tok_free(tokens);
1201 dbg("invalid field found. coutinue");
1202 tcore_at_tok_free(tokens);
1205 dbg("valid count :%d", countValidRecords);
1206 resp.record_num = countValidRecords;
1207 resp.err = TCORE_RETURN_SUCCESS;
1209 dbg("no active status - return to user")
1212 if (response->success > 0) {
1214 resp.err = TCORE_RETURN_SUCCESS;
1216 dbg("RESPONSE NOT OK");
1217 line = (const char *) response->final_response;
1218 tokens = tcore_at_tok_new(line);
1220 if (g_slist_length(tokens) < 1) {
1221 dbg("err cause not specified or string corrupted");
1222 resp.err = TCORE_RETURN_3GPP_ERROR;
1224 err = atoi(g_slist_nth_data(tokens, 0));
1225 /* TODO: CMEE error mapping is required. */
1226 resp.err = TCORE_RETURN_3GPP_ERROR;
1228 tcore_at_tok_free(tokens);
1231 dbg("on_response_ss_forwarding_get- rsp.err : %d, ur : %x", resp.err, ur);
1233 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
1235 dbg("[ error ] ur is 0");
1238 g_free(resp.record);
1244 static void on_response_ss_waiting_get(TcorePending *p, int data_len, const void *data, void *user_data)
1246 UserRequest *ur = 0;
1247 GSList *respdata, *tokens = NULL;
1248 int classx = 0, err = 0;
1249 struct ss_confirm_info *info = 0;
1250 struct tresp_ss_waiting resp;
1251 int countRecords = 0, countValidRecords = 0;
1253 char *classx_str, *status;
1254 const TcoreATResponse *response;
1256 dbg("function enter")
1258 ur = tcore_pending_ref_user_request(p);
1259 info = (struct ss_confirm_info *) user_data;
1261 if (response->lines) {
1262 respdata = (GSList *) response->lines;
1263 countRecords = g_slist_length(respdata);
1264 dbg("total records : %d", countRecords);
1267 dbg("no active status - return to user")
1269 resp.record_num = countRecords;
1271 if (resp.record_num > 0) {
1272 resp.record = g_new0(struct waiting_info, resp.record_num);
1274 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1275 line = (const char *) (respdata->data);
1276 tokens = tcore_at_tok_new(line);
1279 status = g_slist_nth_data(tokens, 0);
1281 dbg("Missing stat in responce ");
1284 if (atoi(status) == 1) {
1285 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1287 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1290 dbg("status = %d", resp.record[countValidRecords].status);
1293 classx_str = g_slist_nth_data(tokens, 1);
1295 dbg("error - class is missing");
1298 switch (atoi(classx_str)) {
1300 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1304 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1308 resp.record[countValidRecords].class = SS_CLASS_FAX;
1312 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1316 resp.record[countValidRecords].class = SS_CLASS_SMS;
1320 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1324 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1328 dbg("unspoorted class : [%d]\n", classx);
1332 dbg("class info %d", resp.record[countValidRecords].class);
1335 countValidRecords++;
1336 tcore_at_tok_free(tokens);
1339 dbg("invalid field found. coutinue");
1340 tcore_at_tok_free(tokens);
1344 dbg("valid count :%d", countValidRecords);
1345 resp.record_num = countValidRecords;
1346 resp.err = TCORE_RETURN_SUCCESS;
1348 dbg("no active status - return to user")
1351 if (response->success > 0) {
1353 resp.err = TCORE_RETURN_SUCCESS;
1355 dbg("RESPONSE NOT OK");
1356 line = (const char *) response->final_response;
1357 tokens = tcore_at_tok_new(line);
1359 if (g_slist_length(tokens) < 1) {
1360 dbg("err cause not specified or string corrupted");
1361 resp.err = TCORE_RETURN_3GPP_ERROR;
1363 err = atoi(g_slist_nth_data(tokens, 0));
1364 // TODO: CMEE error mapping is required.
1365 resp.err = TCORE_RETURN_3GPP_ERROR;
1367 tcore_at_tok_free(tokens);
1370 dbg("on_response_ss_waiting_get - rsp.err : %d, ur : %x", resp.err, ur);
1372 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
1374 dbg("[ error ] ur is 0");
1377 g_free(resp.record);
1384 static void on_response_ss_cli_get(TcorePending *p, int data_len, const void *data, void *user_data)
1386 UserRequest *ur = 0;
1387 struct tresp_ss_cli resp;
1388 enum telephony_ss_cli_type *p_type = NULL;
1389 char *line = NULL, *status;
1392 GSList *tokens = NULL;
1393 const TcoreATResponse *response;
1395 dbg("function enter")
1397 ur = tcore_pending_ref_user_request(p);
1398 p_type = (enum telephony_ss_cli_type *) (user_data);
1400 if (response->success > 0) {
1401 line = (char *) (((GSList *) response->lines)->data);
1402 tokens = tcore_at_tok_new(line);
1404 if (*p_type == SS_CLI_TYPE_CLIR) {
1406 dbg("CLI type is CLIR")
1408 status = g_slist_nth_data(tokens, 0);
1411 dbg("Call line identification adjustment missing <n>");
1413 cli_adj = atoi(status);
1414 dbg("CLIR response value of <n> - %d", cli_adj);
1418 status = g_slist_nth_data(tokens, 1);
1420 dbg("status is missing<m>");
1422 stat = atoi(status);
1423 dbg("CLIR response value of <m> - %d", stat);
1425 if (stat == 1 || stat == 3) {
1428 resp.status = FALSE;
1430 } else if (cli_adj == 1) {
1433 resp.status = FALSE;
1435 dbg("resp.status - %d", resp.status);
1437 tcore_at_tok_free(tokens);
1440 status = g_slist_nth_data(tokens, 0);
1442 dbg("Stat is missing");
1444 stat = atoi(status);
1448 resp.status = FALSE;
1450 dbg("resp.status - %d", resp.status);
1452 tcore_at_tok_free(tokens);
1456 if (response->success > 0) {
1458 resp.err = TCORE_RETURN_SUCCESS;
1460 dbg("RESPONSE NOT OK");
1462 line = (char *) response->final_response;
1463 tokens = tcore_at_tok_new(line);
1465 if (g_slist_length(tokens) < 1) {
1466 dbg("err cause not specified or string corrupted");
1467 resp.err = TCORE_RETURN_3GPP_ERROR;
1469 err = atoi(g_slist_nth_data(tokens, 0));
1470 // TODO: CMEE error mapping is required.
1471 resp.err = TCORE_RETURN_3GPP_ERROR;
1473 tcore_at_tok_free(tokens);
1476 resp.type = *p_type;
1477 dbg("check - resp.type = %d ", resp.type);
1479 tcore_user_request_send_response(ur, TRESP_SS_CLI_GET_STATUS, sizeof(struct tresp_ss_cli), &resp);
1481 dbg("[ error ] ur : (0)");
1486 static struct tcore_ss_operations ss_ops = {
1487 .barring_activate = s_ss_barring_activate,
1488 .barring_deactivate = s_ss_barring_deactivate,
1489 .barring_change_password = s_ss_barring_change_password,
1490 .barring_get_status = s_ss_barring_get_status,
1491 .forwarding_activate = s_ss_forwarding_activate,
1492 .forwarding_deactivate = s_ss_forwarding_deactivate,
1493 .forwarding_register = s_ss_forwarding_register,
1494 .forwarding_deregister = s_ss_forwarding_deregister,
1495 .forwarding_get_status = s_ss_forwarding_get_status,
1496 .waiting_activate = s_ss_waiting_activate,
1497 .waiting_deactivate = s_ss_waiting_deactivate,
1498 .waiting_get_status = s_ss_waiting_get_status,
1499 .cli_activate = s_ss_cli_activate,
1500 .cli_deactivate = s_ss_cli_deactivate,
1501 .cli_get_status = s_ss_cli_get_status,
1502 .send_ussd = s_ss_send_ussd,
1503 .set_aoc = s_ss_set_aoc,
1504 .get_aoc = s_ss_get_aoc,
1508 static TReturn _ss_barring_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1510 struct treq_ss_barring *barring = 0;
1511 struct ss_confirm_info *user_data = 0;
1512 char *cmd_str = NULL;
1514 TcorePending *pending = NULL;
1515 TcoreATRequest *req;
1516 char passwd[MAX_SS_BARRING_PASSWORD_LEN + 1];
1519 char *facility = NULL;
1520 gboolean ret = FALSE;
1522 dbg("function enter");
1523 barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1526 case SS_OPCO_ACTIVATE:
1530 case SS_OPCO_DEACTIVATE:
1535 dbg("unsupported opco : %d", op);
1536 return TCORE_RETURN_FAILURE;
1538 dbg("opco - %d", opco);
1540 switch (barring->mode) {
1541 case SS_BARR_MODE_BAOC:
1545 case SS_BARR_MODE_BOIC:
1549 case SS_BARR_MODE_BOIC_NOT_HC:
1553 case SS_BARR_MODE_BAIC:
1557 case SS_BARR_MODE_BIC_ROAM:
1561 case SS_BARR_MODE_AB:
1565 case SS_BARR_MODE_AOB:
1569 case SS_BARR_MODE_AIB:
1573 case SS_BARR_MODE_BIC_NOT_SIM:
1576 dbg("unspported mode %d", barring->mode);
1577 return TCORE_RETURN_FAILURE;
1580 dbg("facility - %s", facility);
1582 switch (barring->class) {
1583 case SS_CLASS_ALL_TELE:
1587 case SS_CLASS_VOICE:
1591 case SS_CLASS_ALL_DATA_TELE:
1603 case SS_CLASS_ALL_CS_SYNC:
1609 dbg("unsupported class %d. set to default : 7", barring->class);
1613 dbg("classx - %d", classx);
1615 // null-ended pwd handling added - unexpected 0x11 value observed in req string
1616 memcpy(passwd, barring->password, MAX_SS_BARRING_PASSWORD_LEN);
1617 passwd[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1618 dbg("passwd - %s", passwd);
1620 hal = tcore_object_get_hal(o);
1621 pending = tcore_pending_new(o, 0);
1623 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d", facility, opco, passwd, classx);
1624 dbg("request command : %s", cmd_str);
1626 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1627 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1629 tcore_pending_set_request_data(pending, 0, req);
1631 user_data = g_new0(struct ss_confirm_info, 1);
1632 if (op == SS_OPCO_ACTIVATE) {
1633 user_data->resp = TRESP_SS_BARRING_ACTIVATE;
1634 } else if (op == SS_OPCO_DEACTIVATE) {
1635 user_data->resp = TRESP_SS_BARRING_DEACTIVATE;
1637 dbg("[ error ] wrong ss opco (0x%x)", op);
1638 return TCORE_RETURN_FAILURE;
1640 user_data->flavor_type = (int) (barring->mode);
1641 user_data->class = barring->class;
1643 ret = _ss_request_message(pending, o, ur, on_response_ss_barring_set, user_data);
1647 dbg("AT request sent failed ")
1648 return TCORE_RETURN_FAILURE;
1650 return TCORE_RETURN_SUCCESS;
1653 static TReturn _ss_barring_get(CoreObject *o,
1655 enum telephony_ss_class class,
1656 enum telephony_ss_barring_mode mode,
1657 enum tcore_response_command resp)
1659 struct ss_confirm_info *user_data = 0;
1660 gboolean ret = FALSE;
1661 char *cmd_str = NULL;
1663 char *facility = NULL;
1665 TcorePending *pending = NULL;
1666 TcoreATRequest *req;
1668 dbg("function enter");
1670 // query status - opco is fixed to 2
1674 case SS_BARR_MODE_BAOC:
1678 case SS_BARR_MODE_BOIC:
1682 case SS_BARR_MODE_BOIC_NOT_HC:
1686 case SS_BARR_MODE_BAIC:
1690 case SS_BARR_MODE_BIC_ROAM:
1694 case SS_BARR_MODE_AB:
1698 case SS_BARR_MODE_AOB:
1702 case SS_BARR_MODE_AIB:
1706 case SS_BARR_MODE_BIC_NOT_SIM:
1708 dbg("unspported mode %d", mode);
1709 return TCORE_RETURN_FAILURE;
1712 dbg("facility - %s", facility);
1715 case SS_CLASS_ALL_TELE:
1719 case SS_CLASS_VOICE:
1723 case SS_CLASS_ALL_DATA_TELE:
1735 case SS_CLASS_ALL_CS_SYNC:
1741 dbg("unsupported class %d. set to default : 7", class);
1744 dbg("class - %d", classx);
1747 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d", facility, opco);
1749 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d", facility, opco, classx);
1751 dbg("request command : %s", cmd_str);
1753 hal = tcore_object_get_hal(o);
1754 pending = tcore_pending_new(o, 0);
1755 req = tcore_at_request_new(cmd_str, "+CLCK", TCORE_AT_MULTILINE);
1756 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1758 tcore_pending_set_request_data(pending, 0, req);
1760 user_data = g_new0(struct ss_confirm_info, 1);
1761 user_data->resp = resp;
1762 user_data->flavor_type = (int) (mode);
1763 user_data->class = class;
1765 ret = _ss_request_message(pending, o, ur, on_response_ss_barring_get, user_data);
1769 dbg("AT request sent failed ")
1770 return TCORE_RETURN_FAILURE;
1773 return TCORE_RETURN_SUCCESS;
1776 static TReturn s_ss_barring_activate(CoreObject *o, UserRequest *ur)
1778 return _ss_barring_set(o, ur, SS_OPCO_ACTIVATE);
1781 static TReturn s_ss_barring_deactivate(CoreObject *o, UserRequest *ur)
1783 return _ss_barring_set(o, ur, SS_OPCO_DEACTIVATE);
1786 static TReturn s_ss_barring_change_password(CoreObject *o, UserRequest *ur)
1789 TcorePending *pending = NULL;
1790 TcoreATRequest *req;
1791 struct treq_ss_barring_change_password *barring = 0;
1792 struct ss_confirm_info *user_data = 0;
1793 char *cmd_str = NULL;
1794 gboolean ret = FALSE;
1796 dbg("function enter");
1797 barring = (struct treq_ss_barring_change_password *) tcore_user_request_ref_data(ur, 0);
1799 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB", barring->password_old, barring->password_new);
1800 dbg("request command : %s", cmd_str);
1802 hal = tcore_object_get_hal(o);
1803 pending = tcore_pending_new(o, 0);
1804 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1805 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1807 tcore_pending_set_request_data(pending, 0, req);
1809 user_data = g_new0(struct ss_confirm_info, 1);
1810 user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
1812 ret = _ss_request_message(pending, o, ur, on_response_ss_barring_change_pwd, user_data);
1815 dbg("AT request sent failed ")
1816 return TCORE_RETURN_FAILURE;
1818 return TCORE_RETURN_SUCCESS;
1821 static TReturn s_ss_barring_get_status(CoreObject *o, UserRequest *ur)
1823 struct treq_ss_barring *barring = 0;
1824 barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1826 return _ss_barring_get(o, ur, barring->class, barring->mode, TRESP_SS_BARRING_GET_STATUS);
1829 static TReturn _ss_forwarding_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1831 struct treq_ss_forwarding *forwarding = 0;
1832 struct ss_confirm_info *user_data = 0;
1833 gboolean ret = FALSE;
1835 char *cmd_str = NULL;
1836 char *tmp_str = NULL;
1837 int reason = 0, mode = 0, num_type = 0, classx = 0, time = 0;
1838 gboolean valid_num = FALSE;
1840 TcorePending *pending = NULL;
1841 TcoreATRequest *req;
1843 dbg("_ss_forwarding_set with opco %d ", op);
1845 forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
1846 switch (forwarding->mode) {
1847 case SS_CF_MODE_CFU:
1851 case SS_CF_MODE_CFB:
1855 case SS_CF_MODE_CFNRy:
1859 case SS_CF_MODE_CFNRc:
1863 case SS_CF_MODE_CF_ALL:
1867 case SS_CF_MODE_CFC:
1872 dbg("unsupported reason : %d");
1873 return TCORE_RETURN_FAILURE;
1877 dbg("reason = %d", reason);
1879 case SS_OPCO_DEACTIVATE:
1883 case SS_OPCO_ACTIVATE:
1896 dbg("unsupported opco : %d", op);
1897 return TCORE_RETURN_FAILURE;
1900 dbg("mode = %d", mode);
1903 switch (forwarding->class) {
1904 case SS_CLASS_ALL_TELE:
1908 case SS_CLASS_VOICE:
1912 case SS_CLASS_ALL_DATA_TELE:
1924 case SS_CLASS_ALL_CS_SYNC:
1930 dbg("unsupported class %d. set to default : 7", forwarding->class);
1933 dbg("classx = %d", classx);
1936 len = strlen(forwarding->number);
1939 if (forwarding->number[0] == '+')
1940 num_type = ((NUM_TYPE_INTERNATIONAL << 4) | NUM_PLAN_ISDN);
1944 dbg("number = %s", forwarding->number);
1946 user_data = g_new0(struct ss_confirm_info, 1);
1950 user_data->resp = TRESP_SS_FORWARDING_REGISTER;
1954 user_data->resp = TRESP_SS_FORWARDING_DEREGISTER;
1957 case SS_OPCO_ACTIVATE:
1958 user_data->resp = TRESP_SS_FORWARDING_ACTIVATE;
1961 case SS_OPCO_DEACTIVATE:
1962 user_data->resp = TRESP_SS_FORWARDING_DEACTIVATE;
1966 dbg("[ error ] unknown op (0x%x)", op);
1970 if (forwarding->number[0] == '+')
1975 if (op == SS_OPCO_REG)
1976 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,\"%s\",%d,%d", reason, mode, forwarding->number, num_type, classx);
1977 else // other opcode does not need num field
1978 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
1980 if (forwarding->mode == SS_CF_MODE_CFNRy) {
1981 // add time info to 'no reply' case
1982 time = (int) (forwarding->time);
1983 cmd_str = g_strdup_printf("%s,,,%d", tmp_str, time);
1985 cmd_str = g_strdup_printf("%s", tmp_str);
1988 dbg("request command : %s", cmd_str);
1989 hal = tcore_object_get_hal(o);
1990 pending = tcore_pending_new(o, 0);
1991 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1992 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1994 tcore_pending_set_request_data(pending, 0, req);
1996 user_data->flavor_type = forwarding->mode;
1997 user_data->class = forwarding->class;
1999 ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_set, user_data);
2005 dbg("AT request sent failed ")
2006 return TCORE_RETURN_FAILURE;
2009 return TCORE_RETURN_SUCCESS;
2012 static TReturn _ss_forwarding_get(CoreObject *o,
2014 enum telephony_ss_class class,
2015 enum telephony_ss_forwarding_mode type,
2016 enum tcore_response_command resp)
2018 struct ss_confirm_info *user_data = 0;
2019 gboolean ret = FALSE;
2020 char *cmd_str = NULL;
2021 int reason = 0, mode = 0, classx = 0;
2023 TcorePending *pending = NULL;
2024 TcoreATRequest *req;
2026 dbg("function enter");
2029 case SS_CF_MODE_CFU:
2033 case SS_CF_MODE_CFB:
2037 case SS_CF_MODE_CFNRy:
2041 case SS_CF_MODE_CFNRc:
2045 case SS_CF_MODE_CF_ALL:
2049 case SS_CF_MODE_CFC:
2054 dbg("unsupported reason : %d");
2057 dbg("reason = %d", reason);
2060 case SS_CLASS_ALL_TELE:
2064 case SS_CLASS_VOICE:
2068 case SS_CLASS_ALL_DATA_TELE:
2080 case SS_CLASS_ALL_CS_SYNC:
2086 dbg("unsupported class %d. set to default : 7", class);
2090 dbg("classx = %d", classx);
2092 // query status - mode set to 2
2094 user_data = g_new0(struct ss_confirm_info, 1);
2095 user_data->resp = resp;
2096 user_data->class = class;
2097 user_data->flavor_type = type;
2100 cmd_str = g_strdup_printf("AT+CCFC=%d,%d", reason, mode);
2102 cmd_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2104 dbg("request command : %s", cmd_str);
2106 hal = tcore_object_get_hal(o);
2107 pending = tcore_pending_new(o, 0);
2108 req = tcore_at_request_new(cmd_str, "+CCFC", TCORE_AT_MULTILINE);
2109 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2111 tcore_pending_set_request_data(pending, 0, req);
2113 ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_get, user_data);
2117 dbg("AT request sent failed ")
2118 return TCORE_RETURN_FAILURE;
2121 return TCORE_RETURN_SUCCESS;
2124 static TReturn s_ss_forwarding_activate(CoreObject *o, UserRequest *ur)
2126 return _ss_forwarding_set(o, ur, SS_OPCO_ACTIVATE);
2129 static TReturn s_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur)
2131 return _ss_forwarding_set(o, ur, SS_OPCO_DEACTIVATE);
2134 static TReturn s_ss_forwarding_register(CoreObject *o, UserRequest *ur)
2136 return _ss_forwarding_set(o, ur, SS_OPCO_REG);
2139 static TReturn s_ss_forwarding_deregister(CoreObject *o, UserRequest *ur)
2141 return _ss_forwarding_set(o, ur, SS_OPCO_DEREG);
2144 static TReturn s_ss_forwarding_get_status(CoreObject *o, UserRequest *ur)
2146 struct treq_ss_forwarding *forwarding = 0;
2147 forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
2149 return _ss_forwarding_get(o, ur, forwarding->class, forwarding->mode, TRESP_SS_FORWARDING_GET_STATUS);
2153 static TReturn _ss_waiting_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode opco)
2155 struct treq_ss_waiting *waiting = 0;
2156 struct ss_confirm_info *user_data = 0;
2157 gboolean ret = FALSE;
2158 int mode = 0, classx = 0;
2161 TcorePending *pending = NULL;
2162 TcoreATRequest *req;
2164 dbg("function enter ");
2165 waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2166 user_data = g_new0(struct ss_confirm_info, 1);
2168 if (opco == SS_OPCO_ACTIVATE) {
2169 user_data->resp = TRESP_SS_WAITING_ACTIVATE;
2171 } else if (opco == SS_OPCO_DEACTIVATE) {
2172 user_data->resp = TRESP_SS_WAITING_DEACTIVATE;
2173 mode = 0; // disable
2175 dbg("[ error ] unknown ss mode (0x%x)", opco);
2177 switch (waiting->class) {
2178 case SS_CLASS_ALL_TELE:
2182 case SS_CLASS_VOICE:
2186 case SS_CLASS_ALL_DATA_TELE:
2200 dbg("unsupported class %d. set to default : 1", waiting->class);
2203 dbg("mode = %d classxx- %d", mode, classx);
2205 user_data->class = waiting->class;
2206 user_data->flavor_type = (int) opco;
2208 cmd_str = g_strdup_printf("AT+CCWA=1,%d,%d", mode, classx); // always enable +CCWA: unsolicited cmd
2209 dbg("request command : %s", cmd_str);
2211 hal = tcore_object_get_hal(o);
2212 pending = tcore_pending_new(o, 0);
2213 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2214 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2216 tcore_pending_set_request_data(pending, 0, req);
2218 ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_set, user_data);
2221 dbg("AT request sent failed ")
2222 return TCORE_RETURN_FAILURE;
2224 return TCORE_RETURN_SUCCESS;
2227 static TReturn _ss_waiting_get(CoreObject *o,
2229 enum telephony_ss_class class,
2230 enum tcore_response_command resp)
2232 struct ss_confirm_info *user_data = 0;
2233 gboolean ret = FALSE;
2234 int classx; // mode,
2237 TcorePending *pending = NULL;
2238 TcoreATRequest *req;
2240 dbg("function enter")
2242 case SS_CLASS_ALL_TELE:
2246 case SS_CLASS_VOICE:
2250 case SS_CLASS_ALL_DATA_TELE:
2264 dbg("unsupported class %d. set to default : 7", class);
2267 dbg("classx - %d", classx);
2269 dbg("allocating user data");
2270 user_data = g_new0(struct ss_confirm_info, 1);
2271 user_data->resp = resp;
2272 user_data->class = class;
2274 cmd_str = g_strdup_printf("AT+CCWA=1,2,%d", classx); // always enable +CCWA: unsolicited cmd , mode is fixed to 2(query status)
2275 dbg("request cmd : %s", cmd_str);
2277 hal = tcore_object_get_hal(o);
2278 pending = tcore_pending_new(o, 0);
2279 req = tcore_at_request_new(cmd_str, "+CCWA", TCORE_AT_MULTILINE);
2280 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2282 tcore_pending_set_request_data(pending, 0, req);
2284 ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_get, user_data);
2287 dbg("AT request sent failed ")
2288 return TCORE_RETURN_FAILURE;
2290 return TCORE_RETURN_SUCCESS;
2293 static TReturn s_ss_waiting_activate(CoreObject *o, UserRequest *ur)
2295 return _ss_waiting_set(o, ur, SS_OPCO_ACTIVATE);
2298 static TReturn s_ss_waiting_deactivate(CoreObject *o, UserRequest *ur)
2300 return _ss_waiting_set(o, ur, SS_OPCO_DEACTIVATE);
2303 static TReturn s_ss_waiting_get_status(CoreObject *o, UserRequest *ur)
2305 struct treq_ss_waiting *waiting = 0;
2306 waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2308 return _ss_waiting_get(o, ur, waiting->class, TRESP_SS_WAITING_GET_STATUS);
2311 static TReturn s_ss_cli_activate(CoreObject *o, UserRequest *ur)
2313 return TCORE_RETURN_SUCCESS;
2316 static TReturn s_ss_cli_deactivate(CoreObject *o, UserRequest *ur)
2318 return TCORE_RETURN_SUCCESS;
2321 static TReturn s_ss_cli_get_status(CoreObject *o, UserRequest *ur)
2323 struct treq_ss_cli *cli = 0;
2324 gboolean ret = FALSE;
2325 char *cmd_prefix = NULL, *rsp_prefix = NULL, *cmd_str = NULL;
2326 enum telephony_ss_cli_type *user_data = 0;
2328 TcorePending *pending = NULL;
2329 TcoreATRequest *req;
2331 cli = (struct treq_ss_cli *) tcore_user_request_ref_data(ur, 0);
2332 switch (cli->type) {
2333 case SS_CLI_TYPE_CLIP:
2334 cmd_prefix = "+CLIP";
2335 rsp_prefix = "+CLIP";
2338 case SS_CLI_TYPE_CLIR:
2339 cmd_prefix = "+CLIR";
2340 rsp_prefix = "+CLIR";
2343 case SS_CLI_TYPE_COLP:
2344 cmd_prefix = "+COLP";
2345 rsp_prefix = "+COLP";
2348 case SS_CLI_TYPE_COLR:
2349 cmd_prefix = "+COLR";
2350 rsp_prefix = "+COLR";
2353 case SS_CLI_TYPE_CNAP:
2354 cmd_prefix = "+CNAP";
2355 rsp_prefix = "+CNAP";
2358 case SS_CLI_TYPE_CDIP:
2360 dbg("unsupported cli_type : %d", cli->type);
2361 return TCORE_RETURN_FAILURE;
2364 dbg("cmd_prefix : %s", cmd_prefix);
2366 cmd_str = g_strdup_printf("AT%s?", cmd_prefix);
2367 dbg("request cmd : %s", cmd_str);
2369 user_data = g_new0(enum telephony_ss_cli_type, 1);
2370 *user_data = cli->type;
2372 hal = tcore_object_get_hal(o);
2373 pending = tcore_pending_new(o, 0);
2375 req = tcore_at_request_new(cmd_str, rsp_prefix, TCORE_AT_SINGLELINE);
2376 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2377 tcore_pending_set_request_data(pending, 0, req);
2379 ret = _ss_request_message(pending, o, ur, on_response_ss_cli_get, user_data);
2382 dbg("AT request sent failed ")
2383 return TCORE_RETURN_FAILURE;
2385 return TCORE_RETURN_SUCCESS;
2388 static TReturn s_ss_send_ussd(CoreObject *o, UserRequest *ur)
2390 UssdSession *ussd_s = 0;
2391 struct treq_ss_ussd *ussd = 0;
2392 struct ss_confirm_info *user_data = 0;
2393 gboolean ret = FALSE;
2396 TcorePending *pending = NULL;
2397 TcoreATRequest *req;
2399 dbg("function enter");
2400 ussd = (struct treq_ss_ussd *) tcore_user_request_ref_data(ur, 0);
2401 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
2402 dbg("request command : %s", cmd_str);
2404 user_data = g_new0(struct ss_confirm_info, 1);
2405 user_data->resp = TRESP_SS_SEND_USSD;
2406 ussd_s = tcore_ss_ussd_get_session(o);
2408 dbg("USSD session does not exist");
2409 tcore_ss_ussd_create_session(o, (enum tcore_ss_ussd_type) ussd->type, (void *) tcore_user_request_ref(ur), 0);
2411 if (ussd->type == SS_USSD_TYPE_USER_INITIATED) {
2412 dbg("[ error ] ussd session is already exist");
2414 return TCORE_RETURN_FAILURE;
2417 tcore_ss_ussd_set_session_type(ussd_s, (enum tcore_ss_ussd_type) ussd->type);
2420 hal = tcore_object_get_hal(o);
2421 pending = tcore_pending_new(o, 0);
2422 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2423 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2425 tcore_pending_set_request_data(pending, 0, req);
2427 ret = _ss_request_message(pending, o, ur, on_confirmation_ss_ussd, user_data);
2431 dbg("AT request sent failed ")
2432 return TCORE_RETURN_FAILURE;
2434 return TCORE_RETURN_SUCCESS;
2437 static TReturn s_ss_set_aoc(CoreObject *o, UserRequest *ur)
2439 dbg("[ error ] unsupported function");
2440 return TCORE_RETURN_SUCCESS;
2443 static TReturn s_ss_get_aoc(CoreObject *o, UserRequest *ur)
2445 dbg("[ error ] unsupported function");
2446 return TCORE_RETURN_SUCCESS;
2450 static struct tcore_call_control_operations call_ops = {
2451 .answer_hold_and_accept = s_ss_manage_call_2_send,
2452 .answer_replace = s_ss_manage_call_1_send,
2453 .answer_reject = s_ss_manage_call_0_send,
2454 .end_specific = s_ss_manage_call_1x_send,
2455 .end_all_active = s_ss_manage_call_1_send,
2456 .end_all_held = s_ss_manage_call_0_send,
2457 .active = s_ss_manage_call_2_send,
2458 .hold = s_ss_manage_call_2_send,
2459 .swap = s_ss_manage_call_2_send,
2460 .join = s_ss_manage_call_3_send,
2461 .split = s_ss_manage_call_2x_send,
2462 .transfer = s_ss_manage_call_4_send,
2463 .deflect = s_ss_manage_call_4dn_send,
2466 static TReturn s_ss_manage_call_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
2468 TcorePending *pending = NULL;
2469 TcoreATRequest *req;
2470 gboolean ret = FALSE;
2472 pending = tcore_pending_new(o, 0);
2473 req = tcore_at_request_new(cmd, NULL, TCORE_AT_NO_RESULT);
2474 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2475 tcore_pending_set_request_data(pending, 0, req);
2477 ret = _ss_request_message(pending, o, ur, (TcorePendingResponseCallback) cb, user_data);
2479 dbg("AT request sent failed ")
2480 return TCORE_RETURN_FAILURE;
2482 return TCORE_RETURN_SUCCESS;
2485 static TReturn s_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2487 char *cmd_str = NULL;
2488 gboolean ret = FALSE;
2490 dbg("function enter");
2491 cmd_str = g_strdup_printf("%s", "AT+CHLD=0");
2492 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2494 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2499 static TReturn s_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2501 char *cmd_str = NULL;
2502 gboolean ret = FALSE;
2504 dbg("function enter");
2505 cmd_str = g_strdup_printf("%s", "AT+CHLD=1");
2506 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2508 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2513 static TReturn s_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2515 char *cmd_str = NULL;
2516 gboolean ret = FALSE;
2518 dbg("function enter");
2519 cmd_str = g_strdup_printf("%s%d", "AT+CHLD=1", id);
2520 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2522 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2527 static TReturn s_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2529 char *cmd_str = NULL;
2530 gboolean ret = FALSE;
2532 dbg("function enter");
2533 cmd_str = g_strdup_printf("%s", "AT+CHLD=2");
2534 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2536 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2541 static TReturn s_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2543 char *cmd_str = NULL;
2544 gboolean ret = FALSE;
2546 dbg("function enter");
2547 cmd_str = g_strdup_printf("%s%d", "AT+CHLD=2", id);
2548 dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2550 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2555 static TReturn s_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2557 char *cmd_str = NULL;
2558 gboolean ret = FALSE;
2560 dbg("function enter");
2561 cmd_str = g_strdup_printf("%s", "AT+CHLD=3");
2563 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2569 static TReturn s_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2571 char *cmd_str = NULL;
2572 gboolean ret = FALSE;
2574 dbg("function enter");
2575 cmd_str = g_strdup_printf("%s", "AT+CHLD=4");
2577 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2582 static TReturn s_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data)
2584 char *cmd_str = NULL;
2585 gboolean ret = FALSE;
2587 dbg("function enter");
2588 cmd_str = g_strdup_printf("%s%s", "AT+CHLD=4", number);
2590 ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2596 gboolean s_ss_init(TcorePlugin *p, TcoreHal *h)
2598 CoreObject *so = 0, *co = 0;
2599 struct property_call_info *data = 0;
2601 so = tcore_ss_new(p, "ss", &ss_ops, h);
2603 dbg("[ error ] ss_new()");
2607 co = tcore_plugin_ref_core_object(p, "call");
2609 dbg("[ error ] plugin_ref_core_object");
2613 tcore_call_control_set_operations(co, &call_ops);
2615 tcore_object_add_callback(so, "+CSSU", on_notification_ss_info, 0);
2616 tcore_object_add_callback(so, "+CSSI", on_notification_ss_info, 0);
2617 tcore_object_add_callback(so, "+CUSD", on_notification_ss_ussd, 0);
2619 data = calloc(sizeof(struct property_call_info *), 1);
2620 tcore_plugin_link_property(p, "SS", data);
2625 void s_ss_exit(TcorePlugin *p)
2628 struct property_network_info *data;
2630 o = tcore_plugin_ref_core_object(p, "ss");
2632 data = tcore_plugin_ref_property(p, "SS");