Fix SVACE issue
[platform/core/telephony/tel-plugin-imc.git] / src / imc_ss.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: sharanayya mathapati <sharan.m@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  */
20
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <glib.h>
26
27 #include <tcore.h>
28 #include <hal.h>
29 #include <core_object.h>
30 #include <plugin.h>
31 #include <queue.h>
32 #include <co_call.h>
33 #include <co_ss.h>
34 #include <user_request.h>
35 #include <util.h>
36 #include <server.h>
37 #include <at.h>
38
39 #include "imc_common.h"
40 #include "imc_ss.h"
41
42 #define NUM_TYPE_INTERNATIONAL      0x01
43 #define NUM_PLAN_ISDN                   0x01
44
45 /* To avoid sending multiple response to application */
46 static gboolean UssdResp = FALSE;
47
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 */
53         SS_OPCO_MAX
54 };
55
56 struct ss_confirm_info {
57         enum telephony_ss_class class;
58         int flavor_type;
59         enum tcore_response_command resp;
60         void *data;
61         int data_len;
62 };
63
64 static gboolean _ss_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
65
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);
67
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);
69
70 static TReturn _ss_waiting_get(CoreObject *o, UserRequest *ur, enum telephony_ss_class class, enum tcore_response_command resp);
71
72 static TReturn imc_ss_barring_activate(CoreObject *o, UserRequest *ur);
73 static TReturn imc_ss_barring_deactivate(CoreObject *o, UserRequest *ur);
74 static TReturn imc_ss_barring_change_password(CoreObject *o, UserRequest *ur);
75 static TReturn imc_ss_barring_get_status(CoreObject *o, UserRequest *ur);
76
77 static TReturn imc_ss_forwarding_activate(CoreObject *o, UserRequest *ur);
78 static TReturn imc_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur);
79 static TReturn imc_ss_forwarding_register(CoreObject *o, UserRequest *ur);
80 static TReturn imc_ss_forwarding_deregister(CoreObject *o, UserRequest *ur);
81 static TReturn imc_ss_forwarding_get_status(CoreObject *o, UserRequest *ur);
82
83 static TReturn imc_ss_waiting_activate(CoreObject *o, UserRequest *ur);
84 static TReturn imc_ss_waiting_deactivate(CoreObject *o, UserRequest *ur);
85 static TReturn imc_ss_waiting_get_status(CoreObject *o, UserRequest *ur);
86
87 static TReturn imc_ss_cli_activate(CoreObject *o, UserRequest *ur);
88 static TReturn imc_ss_cli_deactivate(CoreObject *o, UserRequest *ur);
89 static TReturn imc_ss_cli_get_status(CoreObject *o, UserRequest *ur);
90
91 static TReturn imc_ss_send_ussd(CoreObject *o, UserRequest *ur);
92
93 static TReturn imc_ss_set_aoc(CoreObject *o, UserRequest *ur);
94 static TReturn imc_ss_get_aoc(CoreObject *o, UserRequest *ur);
95
96 static TReturn imc_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
97 static TReturn imc_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
98 static TReturn imc_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
99 static TReturn imc_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
100 static TReturn imc_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
101 static TReturn imc_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
102 static TReturn imc_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
103 static TReturn imc_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data);
104
105 static void on_confirmation_ss_message_send(TcorePending *p, gboolean result, void *user_data);
106
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);
109
110 static gboolean on_notification_ss_ussd(CoreObject *o, const void *data, void *user_data);
111
112
113 static gboolean _ss_request_message(TcorePending *pending,
114         CoreObject *o, UserRequest *ur,
115         void *on_resp, void *user_data)
116 {
117         TcoreHal *hal = NULL;
118         TReturn ret;
119         dbg("Entry");
120
121         if (on_resp)
122                 tcore_pending_set_response_callback(pending, on_resp, user_data);
123
124         tcore_pending_set_send_callback(pending, on_confirmation_ss_message_send, NULL);
125
126         if (ur)
127                 tcore_pending_link_user_request(pending, ur);
128         else
129                 err("User Request is NULL, is this internal request??");
130
131         hal = tcore_object_get_hal(o);
132
133         /* Send request to HAL */
134         ret = tcore_hal_send_request(hal, pending);
135         if (TCORE_RETURN_SUCCESS != ret) {
136                 err("Request send failed");
137                 return FALSE;
138         }
139
140         dbg("Exit");
141         return TRUE;
142 }
143
144 static void _ss_ussd_response(UserRequest *ur,
145         const char *ussd_str, enum telephony_ss_ussd_type type,
146         enum telephony_ss_ussd_status status)
147 {
148         struct tresp_ss_ussd resp;
149         dbg("Entry");
150
151         if (ur) {
152                 memset(&resp, 0x0, sizeof(struct tresp_ss_ussd));
153                 resp.type = type;
154                 resp.status = status;
155                 resp.err = SS_ERROR_NONE;
156                 dbg("ussd_str = %s resp.type - %d resp.status - %d", ussd_str, resp.type, resp.status);
157
158                 if (ussd_str) {
159                         int len = strlen(ussd_str);
160                         if (len < MAX_SS_USSD_LEN) {
161                                 memcpy(resp.str, ussd_str, len);
162                                 resp.str[len] = '\0';
163                         } else {
164                                 memcpy(resp.str, ussd_str, MAX_SS_USSD_LEN);
165                                 resp.str[MAX_SS_USSD_LEN - 1] = '\0';
166                         }
167                         dbg("Response string: %s", resp.str);
168                 } else {
169                         dbg("USSD string is not present");
170                         memset(resp.str, '\0', MAX_SS_USSD_LEN);
171                 }
172                 UssdResp = TRUE;
173
174                 /* Send response to TAPI */
175                 tcore_user_request_send_response(ur, TRESP_SS_SEND_USSD, sizeof(struct tresp_ss_ussd), &resp);
176         } else {
177                 err("User request is NULL");
178         }
179
180         dbg("Exit");
181         return;
182 }
183
184 static void _ss_ussd_notification(TcorePlugin *p, const char *ussd_str, enum telephony_ss_ussd_status status)
185 {
186         CoreObject *core_obj = 0;
187         struct tnoti_ss_ussd noti;
188
189         dbg("function enter");
190         if (!p) {
191                 dbg("[ error ] p : (NULL)");
192                 return;
193         }
194         noti.status = status;
195         if (ussd_str) {
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';
200                 } else {
201                         memcpy(noti.str, ussd_str, MAX_SS_USSD_LEN);
202                         noti.str[MAX_SS_USSD_LEN - 1] = '\0';
203                 }
204         } else {
205                 memset(noti.str, '\0', MAX_SS_USSD_LEN);
206         }
207         dbg("noti.str - %s", noti.str);
208
209         core_obj = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SS);
210         tcore_server_send_notification(tcore_plugin_ref_server(p),
211                                                                    core_obj,
212                                                                    TNOTI_SS_USSD,
213                                                                    sizeof(struct tnoti_ss_ussd),
214                                                                    (void *) &noti);
215 }
216
217 static gboolean on_notification_ss_ussd(CoreObject *o, const void *data, void *user_data)
218 {
219         enum telephony_ss_ussd_status status;
220         UssdSession *ussd_session = 0;
221         char *ussd_str = 0, *cmd = 0;
222         TcorePlugin *plugin = 0;
223         int m = -1, dcs = 0;
224         char *ussdnoti = NULL, *str = NULL, *dcs_str = NULL;
225         GSList *tokens = NULL;
226         GSList *lines = NULL;
227         char *ussd_string = NULL;
228         unsigned int len;
229
230         plugin = tcore_object_ref_plugin(o);
231         ussd_session = tcore_ss_ussd_get_session(o);
232
233         dbg("function enter");
234         lines = (GSList *) data;
235         if (1 != g_slist_length(lines)) {
236                 dbg("unsolicited msg but multiple line");
237                 return TRUE;
238         }
239
240         cmd = (char *)(lines->data);
241
242         /* parse ussd status */
243         tokens = tcore_at_tok_new(cmd);
244
245         /* parse <m> */
246         ussdnoti = g_slist_nth_data(tokens, 0);
247         if (!ussdnoti) {
248                 dbg("+CUSD<m> is missing from %CUSD Notification");
249         } else {
250                 m = atoi(ussdnoti);
251                 dbg("USSD status  %d", m);
252
253                 /* parse [ <str>, <dcs>] */
254                 ussd_string = g_slist_nth_data(tokens, 1);
255                 if (ussd_string) {
256                         /* Strike off starting & ending quotes. 1 extra character for NULL termination */
257                         str = malloc(strlen(ussd_string) - 1);
258                         dbg("length of Ussd Stirng - %d", strlen(ussd_string));
259                         if (str) {
260                                 memset(str, 0x00, strlen(ussd_string) - 1);
261                         } else {
262                                 dbg("malloc failed");
263                                 if (NULL != tokens)
264                                         tcore_at_tok_free(tokens);
265
266                                 return FALSE;
267                         }
268
269                         len = strlen(ussd_string) - 1;
270                         ++ussd_string;
271                         strncpy(str, ussd_string, len);
272
273                         dbg("USSD String - %s len = %d", str, strlen(str));
274                 }
275
276                 if ((dcs_str = g_slist_nth_data(tokens, 2))) {
277                         dcs = atoi(dcs_str);
278                         dbg("USSD dcs %d", dcs);
279                 }
280         }
281
282         switch (m) {
283         case 0:
284                 status = SS_USSD_NO_ACTION_REQUIRE;
285         break;
286
287         case 1:
288                 status = SS_USSD_ACTION_REQUIRE;
289         break;
290
291         case 2:
292                 status = SS_USSD_TERMINATED_BY_NET;
293         break;
294
295         case 3:
296                 status = SS_USSD_OTHER_CLIENT;
297         break;
298
299         case 4:
300                 status = SS_USSD_NOT_SUPPORT;
301         break;
302
303         case 5:
304                 status = SS_USSD_TIME_OUT;
305         break;
306
307         default:
308                 dbg("unsupported m : %d", m);
309                 status = SS_USSD_MAX;
310         break;
311         }
312
313         switch (tcore_util_get_cbs_coding_scheme(dcs)) {
314         case TCORE_DCS_TYPE_7_BIT:
315         case TCORE_DCS_TYPE_UNSPECIFIED:
316         /* ussd_str = tcore_util_unpack_gsm7bit(str, strlen(str)); */
317         /* break; */
318
319         case TCORE_DCS_TYPE_UCS2:
320         case TCORE_DCS_TYPE_8_BIT:
321                 if ((str != NULL) && (strlen(str) > 0)) {
322                         ussd_str = g_new0(char, strlen(str) + 1);
323                         if (ussd_str != NULL) {
324                                 memcpy(ussd_str, str, strlen(str));
325                                 ussd_str[strlen(str)] = '\0';
326                         }
327                 }
328         break;
329
330         default:
331                 dbg("[ error ] unknown dcs type. ussd_session : %x", ussd_session);
332                 if (ussd_session) {
333                         UserRequest *ur = 0;
334                         enum telephony_ss_ussd_type type;
335
336                         tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
337                         if (!ur) {
338                                 dbg("[ error ] ur : (0)");
339                                 goto CATCH;
340                         }
341
342                         type = (enum telephony_ss_ussd_type)tcore_ss_ussd_get_session_type(ussd_session);
343                         dbg("ussd type  - %d", type);
344
345                         _ss_ussd_response(ur, ussd_str, type, status);
346                 }
347
348 CATCH:
349                 if (NULL != tokens)
350                         tcore_at_tok_free(tokens);
351
352                 if (NULL != str)
353                         free(str);
354
355                 return FALSE;
356         }
357
358         switch (status) {
359         case SS_USSD_NO_ACTION_REQUIRE:
360         case SS_USSD_ACTION_REQUIRE:
361         case SS_USSD_OTHER_CLIENT:
362         case SS_USSD_NOT_SUPPORT:
363         case SS_USSD_TIME_OUT:
364                 if (ussd_session) {
365                         UserRequest *ur = 0;
366                         enum telephony_ss_ussd_type type;
367
368                         tcore_ss_ussd_get_session_data(ussd_session, (void **)&ur);
369                         if (!ur) {
370                                 dbg("[ error ] ur : (0)");
371                                 if (NULL != tokens)
372                                         tcore_at_tok_free(tokens);
373
374                                 if (NULL != str)
375                                         free(str);
376
377                                 if (ussd_str)
378                                         g_free(ussd_str);
379
380                                 return FALSE;
381                         }
382                         type = (enum telephony_ss_ussd_type)tcore_ss_ussd_get_session_type(ussd_session);
383                         dbg("ussd type  - %d", type);
384
385                         _ss_ussd_response(ur, (const char *)ussd_str, type, status);
386
387                         if (ussd_str)
388                                 g_free(ussd_str);
389                 } else {
390                         tcore_ss_ussd_create_session(o, TCORE_SS_USSD_TYPE_NETWORK_INITIATED, 0, 0);
391                         _ss_ussd_notification(plugin, (const char *)ussd_str, status);
392
393                         if (ussd_str)
394                                 g_free(ussd_str);
395                 }
396         break;
397
398         case SS_USSD_TERMINATED_BY_NET:
399                 if (ussd_session) {
400                         UserRequest *ur = 0;
401                         tcore_ss_ussd_get_session_data(ussd_session, (void **)&ur);
402                         if (ur)
403                                 tcore_user_request_unref(ur);
404
405                         tcore_ss_ussd_destroy_session(ussd_session);
406                 }
407         break;
408
409         default:
410         break;
411         }
412
413         if (NULL != tokens)
414                 tcore_at_tok_free(tokens);
415
416         if (NULL != str)
417                 free(str);
418
419         dbg("Exit");
420         return TRUE;
421 }
422
423 static gboolean on_notification_ss_cssu_info(CoreObject *co,
424         const void *event_data, void *user_data)
425 {
426         TcorePlugin *p = NULL;
427         CoreObject *o = NULL;
428         GSList *tokens = NULL;
429         enum tcore_notification_command command = TNOTI_UNKNOWN;
430         char *resp = NULL;
431         char *cmd = 0;
432         int index = 0;
433         int code2 = -1;
434         char *number = NULL;
435         int id = 1;     /* TODO: Need to check how to fetch Call id */
436
437         dbg("entry");
438
439         p = tcore_object_ref_plugin(co);
440         o = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
441         if (!o) {
442                 err(" Call CoreObject not found ");
443                 return FALSE;
444         }
445
446         if (1 != g_slist_length((GSList *) event_data)) {
447                 err("unsolicited msg but multiple line");
448                 return TRUE;
449         }
450         cmd = (char *) ((GSList *) event_data)->data;
451         info("ss notification message[%s]", cmd);
452
453         tokens = tcore_at_tok_new(cmd);
454
455         /* parse <code2> */
456         resp = g_slist_nth_data(tokens, 0);
457         if (NULL == resp) {
458                 err("Code2 is missing from +CSSU indication");
459                 tcore_at_tok_free(tokens);
460                 return TRUE;
461         }
462         code2 = atoi(resp);
463
464         /* parse [ <index>, <number> <type>] */
465         if ((resp = g_slist_nth_data(tokens, 1)))
466                 index = atoi(resp);
467
468         if ((resp = g_slist_nth_data(tokens, 2))) {
469                 /* Strike off double quotes */
470                 number = tcore_at_tok_extract(resp);
471         }
472
473         info("+CSSU: <code2> = %d <index> = %d ", code2, index);
474
475         /* <code2> - other values will be ignored */
476         switch (code2) {
477         case 0:
478                 command = TNOTI_CALL_INFO_FORWARDED_CALL;
479         break;
480
481         case 2:
482                 command = TNOTI_CALL_INFO_HELD;
483         break;
484
485         case 3:
486                 command = TNOTI_CALL_INFO_ACTIVE;
487         break;
488
489         case 4:
490                 command = TNOTI_CALL_INFO_JOINED;
491         break;
492
493         case 5:
494                 command = TNOTI_CALL_INFO_RELEASED_ON_HOLD;
495         break;
496
497         case 6:
498                 command = TNOTI_CALL_INFO_CF_CHECK_MESSAGE;
499         break;
500
501         case 7:
502                 command = TNOTI_CALL_INFO_TRANSFER_ALERT;
503         break;
504
505         case 8:
506                 command = TNOTI_CALL_INFO_TRANSFERED_CALL;
507         break;
508
509         case 9:
510                 command = TNOTI_CALL_INFO_DEFLECTED_CALL;
511         break;
512
513         default:
514                 err("Unsupported +CSSU notification : %d", code2);
515         break;
516         }
517
518         /* Send notification */
519         if (command != TNOTI_UNKNOWN) {
520                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
521                         o, command, sizeof(unsigned int), (void *)&id);
522         }
523         tcore_at_tok_free(tokens);
524         g_free(number);
525
526         return TRUE;
527 }
528
529 static gboolean on_notification_ss_cssi_info(CoreObject *co,
530         const void *event_data, void *user_data)
531 {
532         TcorePlugin *p = NULL;
533         CoreObject *o = NULL;
534         GSList *tokens = NULL;
535         enum tcore_notification_command command = TNOTI_UNKNOWN;
536         char *resp = NULL;
537         char *cmd = 0;
538         int index = 0;
539         int code1 = -1;
540         int id = 1;     /* TODO: Need to check how to fetch Call id */
541
542         dbg("entry");
543
544         p = tcore_object_ref_plugin(co);
545         o = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
546         if (!o) {
547                 err(" Call CoreObject not found ");
548                 return FALSE;
549         }
550
551         if (1 != g_slist_length((GSList *) event_data)) {
552                 err("unsolicited msg but multiple line");
553                 return TRUE;
554         }
555         cmd = (char *) ((GSList *) event_data)->data;
556         info("ss notification message[%s]", cmd);
557
558         tokens = tcore_at_tok_new(cmd);
559
560         /* parse <code1> */
561         resp = g_slist_nth_data(tokens, 0);
562         if (NULL == resp) {
563                 err("<code1> is missing from %CSSI indication");
564                 tcore_at_tok_free(tokens);
565                 return TRUE;
566         }
567         code1 = atoi(resp);
568
569         /* parse [ <index>] */
570         if ((resp = g_slist_nth_data(tokens, 1)))
571                 index = atoi(resp);
572
573         info("+CSSI: <code1> = %d <index> = %d ", code1, index);
574
575         /* <code1> - other values will be ignored */
576         switch (code1) {
577         case 0:
578                 command = TNOTI_CALL_INFO_FORWARD_UNCONDITIONAL;
579         break;
580
581         case 1:
582                 command = TNOTI_CALL_INFO_FORWARD_CONDITIONAL;
583         break;
584
585         case 2:
586                 command = TNOTI_CALL_INFO_FORWARDED;
587         break;
588
589         case 3:
590                 command = TNOTI_CALL_INFO_WAITING;
591         break;
592
593         case 5:
594                 command = TNOTI_CALL_INFO_BARRED_OUTGOING;
595         break;
596
597         case 6:
598                 command = TNOTI_CALL_INFO_BARRED_INCOMING;
599         break;
600
601         case 7:
602                 command = TNOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT;
603         break;
604
605         case 8:
606                 command  = TNOTI_CALL_INFO_DEFLECTED;
607         break;
608
609         default:
610                 dbg("Unsupported +CSSI notification : %d", code1);
611         break;
612         }
613
614         /* Send notification */
615         if (command != TNOTI_UNKNOWN) {
616                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
617                         o, command, sizeof(unsigned int), (void *)&id);
618         }
619         tcore_at_tok_free(tokens);
620
621         return TRUE;
622 }
623
624 static void on_confirmation_ss_message_send(TcorePending *p, gboolean result, void *user_data)
625 {
626         dbg("");
627
628         if (result == FALSE) {
629                 /* Fail */
630                 dbg("FAIL");
631         } else {
632                 dbg("SEND OK");
633         }
634 }
635
636 static void on_response_ss_barring_set(TcorePending *p, int data_len, const void *data, void *user_data)
637 {
638         struct ss_confirm_info *info = 0;
639         enum telephony_ss_class class;
640         CoreObject *o = 0;
641         UserRequest *ur;
642         struct tresp_ss_barring resp = {0, };
643         UserRequest *ur_dup = 0;
644         GSList *tokens = NULL;
645         const char *line;
646         int error;
647         const TcoreATResponse *response;
648
649         dbg("function enter");
650         response = data;
651         o = tcore_pending_ref_core_object(p);
652         ur = tcore_pending_ref_user_request(p);
653
654         info = (struct ss_confirm_info *)user_data;
655         class = info->class;
656
657         if (response->success > 0) {
658                 dbg("RESPONSE OK");
659                 resp.err = SS_ERROR_NONE;
660         } else {
661                 dbg("RESPONSE NOT OK");
662                 line = (const char *)response->final_response;
663                 tokens = tcore_at_tok_new(line);
664
665                 if (g_slist_length(tokens) < 1) {
666                         dbg("err cause not specified or string corrupted");
667                         resp.err = SS_ERROR_SYSTEMFAILURE;
668                 } else {
669                         error = atoi(g_slist_nth_data(tokens, 0));
670                         err("Error: [%d]", error);
671                         /* TODO: CMEE error mapping is required. */
672                         resp.err = SS_ERROR_SYSTEMFAILURE;
673                 }
674                 tcore_at_tok_free(tokens);
675         }
676
677         dbg("on_response_ss_barring_set - rsp.err : %d, ur : %x flavor_type = %d", resp.err, ur, info->flavor_type);
678         dbg("[ check ] class : 0x%x", info->class);
679
680         if (response->success > 0) {
681                 if (info->class == SS_CLASS_VOICE)
682                         class = SS_CLASS_ALL_TELE_BEARER;
683
684                 ur_dup = tcore_user_request_ref(ur);
685
686                 if (info->flavor_type == SS_BARR_MODE_AB || info->flavor_type == SS_BARR_MODE_AOB)
687                         _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAOC, info->resp);
688                 else if (info->flavor_type == SS_BARR_MODE_AIB)
689                         _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAIC, info->resp);
690                 else
691                         _ss_barring_get(o, ur_dup, class, info->flavor_type, info->resp);
692         } else {
693                 if (ur)
694                         tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
695                 else
696                         dbg("[ error ] ur is 0");
697         }
698         g_free(user_data);
699 }
700
701 static void on_response_ss_barring_change_pwd(TcorePending *p, int data_len, const void *data, void *user_data)
702 {
703         const TcoreATResponse *response = data;
704         struct ss_confirm_info *info = 0;
705         UserRequest *ur;
706         struct tresp_ss_general resp;
707         int error;
708         GSList *tokens = NULL;
709         const char *line;
710
711         dbg("function enter");
712         ur = tcore_pending_ref_user_request(p);
713         info = (struct ss_confirm_info *) user_data;
714
715         if (response->success > 0) {
716                 dbg("RESPONSE OK");
717                 resp.err = SS_ERROR_NONE;
718         } else {
719                 dbg("RESPONSE NOT OK");
720
721                 line = (const char *) response->final_response;
722                 tokens = tcore_at_tok_new(line);
723
724                 if (g_slist_length(tokens) < 1) {
725                         dbg("err cause not specified or string corrupted");
726                         resp.err = SS_ERROR_SYSTEMFAILURE;
727                 } else {
728                         error = atoi(g_slist_nth_data(tokens, 0));
729                         err("Error: [%d]", error);
730                         /* TODO: CMEE error mapping is required. */
731                         resp.err = SS_ERROR_SYSTEMFAILURE;
732                 }
733                 tcore_at_tok_free(tokens);
734         }
735
736         dbg("on_response_ss_barring_change_pwd: rsp.err : %d, usr : %x", resp.err, ur);
737         if (ur)
738                 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
739         else
740                 dbg("[ error ] ur is 0");
741
742         g_free(user_data);
743 }
744
745 static void on_response_ss_forwarding_set(TcorePending *p, int data_len, const void *data, void *user_data)
746 {
747         CoreObject *o = 0;
748         UserRequest *ur = 0, *dup_ur = 0;
749         struct ss_confirm_info *info = 0;
750         struct tresp_ss_forwarding resp = {0,};
751         GSList *tokens = NULL;
752         const char *line;
753         int error;
754         const TcoreATResponse *response;
755
756         dbg("function enter");
757
758         response = data;
759         o = tcore_pending_ref_core_object(p);
760         ur = tcore_pending_ref_user_request(p);
761
762         info = (struct ss_confirm_info *) user_data;
763
764         if (response->success > 0) {
765                 dbg("RESPONSE OK");
766                 resp.err = SS_ERROR_NONE;
767         } else {
768                 dbg("RESPONSE NOT OK");
769
770                 /* Extract Error */
771                 line = (const char *) response->final_response;
772                 tokens = tcore_at_tok_new(line);
773
774                 if (g_slist_length(tokens) < 1) {
775                         dbg("Error cause not specified or string corrupted");
776                         resp.err = SS_ERROR_SYSTEMFAILURE;
777                 } else {
778                         error = atoi(g_slist_nth_data(tokens, 0));
779                         err("Error: [%d]", error);
780                         /* / TODO: CMEE error mapping is required. */
781                         resp.err = SS_ERROR_SYSTEMFAILURE;
782                 }
783
784                 tcore_at_tok_free(tokens);
785         }
786
787         dbg("[ check ] class : 0x%x", info->class);
788         dbg("[ check ] flavor_type : 0x%x", info->flavor_type);
789
790         dbg("on_response_ss_forwarding_set - rsp.err : %d, ur : %x", resp.err, ur);
791
792         if (response->success > 0) {
793                 if (info->flavor_type == SS_CF_MODE_CF_ALL ||
794                                 info->flavor_type == SS_CF_MODE_CFC) {
795                         if (ur)
796                                 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
797                         else
798                                 dbg("[ error ] ur is 0");
799                 } else {
800                         dup_ur = tcore_user_request_ref(ur);
801                         _ss_forwarding_get(o, dup_ur, info->class, info->flavor_type, info->resp);
802                 }
803         } else {
804                 if (ur)
805                         tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
806                 else
807                         dbg("[ error ] ur is 0");
808         }
809         g_free(user_data);
810 }
811
812 static void on_response_ss_waiting_set(TcorePending *p, int data_len, const void *data, void *user_data)
813 {
814         CoreObject *core_obj = 0;
815         UserRequest *ur = 0;
816         UserRequest *ur_dup = 0;
817         struct ss_confirm_info *info = 0;
818         struct tresp_ss_waiting resp = {0,};
819         GSList *tokens = NULL;
820         const char *line;
821         int error;
822         const TcoreATResponse *response;
823
824         dbg("function enter");
825         response = data;
826         core_obj = tcore_pending_ref_core_object(p);
827         ur = tcore_pending_ref_user_request(p);
828
829         info = (struct ss_confirm_info *)user_data;
830
831         if (response->success > 0) {
832                 dbg("RESPONSE OK");
833                 resp.err = SS_ERROR_NONE;
834         } else {
835                 dbg("RESPONSE NOT OK");
836
837                 /* Extract Error */
838                 line = (const char *) response->final_response;
839                 tokens = tcore_at_tok_new(line);
840
841                 if (g_slist_length(tokens) < 1) {
842                         dbg("Error cause not specified or string corrupted");
843                         resp.err = SS_ERROR_SYSTEMFAILURE;
844                 } else {
845                         error = atoi(g_slist_nth_data(tokens, 0));
846                         err("Error: [%d]", error);
847                         /* TODO: CMEE error mapping is required. */
848                         resp.err = SS_ERROR_SYSTEMFAILURE;
849                 }
850
851                 /* Free tokens */
852                 tcore_at_tok_free(tokens);
853         }
854
855         dbg("Call Waiting - Error: [%d], UR: [0x%x] class: [0x%2x]", resp.err, ur, info->class);
856         if (resp.err == SS_ERROR_NONE) {
857                 ur_dup = tcore_user_request_ref(ur);
858
859                 dbg("Get Call Waiting status");
860                 _ss_waiting_get(core_obj, ur_dup, info->class, info->resp);
861         } else {
862                 if (ur)
863                         tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
864                 else
865                         err("User request is NULL");
866         }
867         g_free(user_data);
868 }
869
870
871 static void on_confirmation_ss_ussd(TcorePending *p, int data_len, const void *data, void *user_data)
872 {
873         CoreObject *core_obj = 0;
874         struct ss_confirm_info *info = 0;
875         struct tresp_ss_ussd resp;
876         UserRequest *ur = NULL, *ussd_ur = NULL;
877         GSList *tokens = NULL;
878         const char *line;
879         int error;
880         UssdSession *ussd_s = NULL;
881         enum tcore_ss_ussd_type type = TCORE_SS_USSD_TYPE_MAX;
882         const TcoreATResponse *response;
883
884         dbg("function enter");
885         response = data;
886         ur = tcore_pending_ref_user_request(p);
887         info = (struct ss_confirm_info *) user_data;
888
889         memset(resp.str, 0x00, MAX_SS_USSD_LEN);
890
891         core_obj = tcore_pending_ref_core_object(p);
892         ussd_s = tcore_ss_ussd_get_session(core_obj);
893
894         if (ussd_s)
895                 type = tcore_ss_ussd_get_session_type(ussd_s);
896         else
897                 dbg("[ error ] ussd_s : (0)");
898
899         resp.type = (enum telephony_ss_ussd_type) type;
900         resp.status = SS_USSD_MAX; /* hardcoded value. */
901
902         if (response->success > 0) {
903                 dbg("RESPONSE OK");
904                 resp.err = SS_ERROR_NONE;
905         } else {
906                 dbg("RESPONSE NOT OK");
907
908                 line = (const char *) response->final_response;
909                 tokens = tcore_at_tok_new(line);
910
911                 if (g_slist_length(tokens) < 1) {
912                         dbg("err cause not specified or string corrupted");
913                         resp.err = SS_ERROR_SYSTEMFAILURE;
914                 } else {
915                         error = atoi(g_slist_nth_data(tokens, 0));
916                         err("Error: [%d]", error);
917                         /* TODO: CMEE error mapping is required. */
918                         resp.err = SS_ERROR_SYSTEMFAILURE;
919                 }
920                 tcore_at_tok_free(tokens);
921         }
922
923         dbg("on_confirmation_ss_ussd - rsp.err : %d, ur : %x", resp.err, ur);
924
925         if (response->success > 0) {
926                 if (type == TCORE_SS_USSD_TYPE_USER_INITIATED) {
927                         dbg("ussd type %d", resp.type);
928
929                         if (ussd_s) {
930                                 tcore_ss_ussd_get_session_data(ussd_s, (void **) &ussd_ur);
931                                 if (ussd_ur)
932                                         tcore_user_request_free(ussd_ur);
933                         }
934                 }
935         }
936
937         if (ussd_s)
938                 tcore_ss_ussd_destroy_session(ussd_s);
939
940         if (ur) {
941                 if (UssdResp == FALSE) { /* to avoid sending multiple response to application. */
942                         tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_ussd), &resp);
943                 }
944                 UssdResp = FALSE;
945         } else
946                 dbg("[ error ] ur : (0)");
947
948         g_free(user_data);
949 }
950
951 static void on_response_ss_barring_get(TcorePending *p, int data_len, const void *data, void *user_data)
952 {
953         UserRequest *ur = 0;
954         int status = 0, classx = 0, ss_err = 0;
955         GSList *respdata;
956         struct ss_confirm_info *info = 0;
957         struct tresp_ss_barring resp;
958         int countRecords = 0, countValidRecords = 0;
959         GSList *tokens = NULL;
960         const char *line;
961         char *classx_str;
962         char *stat = NULL;
963         const TcoreATResponse *response;
964
965         dbg("function enter");
966
967         response = data;
968         ur = tcore_pending_ref_user_request(p);
969         info = (struct ss_confirm_info *) user_data;
970
971         if (response->lines) {
972                 respdata = (GSList *) response->lines;
973                 countRecords = g_slist_length(respdata);
974                 dbg("total records : %d", countRecords);
975         } else {
976                 countRecords = 0;
977                 dbg("no active status - return to user");
978         }
979         resp.record_num = countRecords;
980         resp.record = 0;
981         if (resp.record_num > 0) {
982                 resp.record = g_new0(struct barring_info, resp.record_num);
983                 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
984                         line = (const char *) (respdata->data);
985                         tokens = tcore_at_tok_new(line);
986
987                         /* parse <status> */
988                         stat = g_slist_nth_data(tokens, 0);
989                         if (!stat) {
990                                 dbg("Stat is missing");
991                                 goto error;
992                         }
993
994                         status = atoi(stat);
995                         if (status == 1)
996                                 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
997                         else
998                                 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
999
1000                         dbg("call barring status - %d", status);
1001
1002                         /* Parse <class> */
1003                         classx_str = g_slist_nth_data(tokens, 1);
1004
1005                         if (!classx_str) {
1006                                 dbg("class error. classx not exist - set to requested one : %d", info->class);
1007                                 switch (info->class) {
1008                                 case SS_CLASS_ALL_TELE:
1009                                         classx = 7;
1010                                 break;
1011
1012                                 case SS_CLASS_VOICE:
1013                                         classx = 1;
1014                                 break;
1015
1016                                 case SS_CLASS_ALL_DATA_TELE:
1017                                         classx = 2;
1018                                 break;
1019
1020                                 case SS_CLASS_FAX:
1021                                         classx = 4;
1022                                 break;
1023
1024                                 case SS_CLASS_SMS:
1025                                         classx = 8;
1026                                 break;
1027
1028                                 case SS_CLASS_ALL_CS_SYNC:
1029                                         classx = 16;
1030                                 break;
1031
1032                                 default:
1033                                         classx = 7;
1034                                         dbg("unsupported class %d. set to default : 7", info->class);
1035                                 break;
1036                                 }
1037                         } else {
1038                                 classx = atoi(classx_str);
1039                                 dbg("call barring classx - %d", classx);
1040                         }
1041
1042                         switch (classx) {
1043                         case 1:
1044                                 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1045                         break;
1046
1047                         case 2:
1048                                 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1049                         break;
1050
1051                         case 4:
1052                                 resp.record[countValidRecords].class = SS_CLASS_FAX;
1053                         break;
1054
1055                         case 7:
1056                                 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1057                         break;
1058
1059                         case 8:
1060                                 resp.record[countValidRecords].class = SS_CLASS_SMS;
1061                         break;
1062
1063                         case 16:
1064                                 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1065                         break;
1066
1067                         case 32:
1068                                 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1069                         break;
1070
1071                         default:
1072                                 dbg("unspoorted class : [%d]\n", classx);
1073                                 goto error;
1074                         }
1075                         resp.record[countValidRecords].mode = (enum telephony_ss_barring_mode) (info->flavor_type);
1076                         countValidRecords++;
1077                         tcore_at_tok_free(tokens);
1078                         continue;
1079
1080 error:
1081                         dbg("invalid field found. coutinue");
1082                         tcore_at_tok_free(tokens);
1083                         continue;
1084                 }
1085
1086                 dbg("valid count :%d", countValidRecords);
1087                 resp.record_num = countValidRecords;
1088                 resp.err = SS_ERROR_NONE;
1089         } else {
1090                 dbg("no active status - return to user");
1091         }
1092
1093         if (response->success > 0) {
1094                 dbg("RESPONSE OK");
1095                 resp.err = SS_ERROR_NONE;
1096         } else {
1097                 dbg("RESPONSE NOT OK");
1098                 resp.err = TCORE_RETURN_FAILURE;
1099                 resp.record = 0;
1100                 resp.record_num = 0;
1101
1102                 line = (const char *) response->final_response;
1103                 tokens = tcore_at_tok_new(line);
1104
1105                 if (g_slist_length(tokens) < 1) {
1106                         dbg("err cause not specified or string corrupted");
1107                         resp.err = SS_ERROR_SYSTEMFAILURE;
1108                 } else {
1109                         ss_err = atoi(g_slist_nth_data(tokens, 0));
1110                         err("Error: [%d]", ss_err);
1111                         /* TODO: CMEE error mapping is required. */
1112                         resp.err = SS_ERROR_SYSTEMFAILURE;
1113                 }
1114                 tcore_at_tok_free(tokens);
1115         }
1116
1117         dbg("on_response_ss_barring_get- rsp.err : %d, ur : %x", resp.err, ur);
1118
1119         if (ur)
1120                 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
1121         else
1122                 dbg("[ error ] ur is 0");
1123
1124         if (resp.record) {
1125                 g_free(resp.record);
1126                 resp.record = NULL;
1127         }
1128
1129         g_free(user_data);
1130 }
1131
1132 static void on_response_ss_forwarding_get(TcorePending *p, int data_len, const void *data, void *user_data)
1133 {
1134         UserRequest *ur = 0;
1135         int classx = 0, ss_err = 0, time = 0;
1136         char *num;
1137         struct ss_confirm_info *info = 0;
1138         struct tresp_ss_forwarding resp;
1139         int countRecords = 0, countValidRecords = 0;
1140
1141         GSList *respdata = NULL, *tokens = NULL;
1142         const char *line;
1143         char *classx_str, *status, *ton, *time_str;
1144         const TcoreATResponse *response;
1145
1146         dbg("function enter");
1147         response = data;
1148
1149         ur = tcore_pending_ref_user_request(p);
1150         info = (struct ss_confirm_info *) user_data;
1151         if (response->lines) {
1152                 respdata = (GSList *) response->lines;
1153                 countRecords = g_slist_length(respdata);
1154                 dbg("total records : %d", countRecords);
1155         } else {
1156                 countRecords = 0;
1157                 dbg("no active status - return to user");
1158         }
1159         resp.record_num = countRecords;
1160         resp.record = 0;
1161         if (resp.record_num > 0) {
1162                 resp.record = g_new0(struct forwarding_info, resp.record_num);
1163
1164                 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1165                         line = (const char *) (respdata->data);
1166                         tokens = tcore_at_tok_new(line);
1167
1168                         /* parse <status> */
1169                         status = g_slist_nth_data(tokens, 0);
1170                         if (!status) {
1171                                 dbg("start line error. skip this line");
1172                                 goto error;
1173                         } else {
1174                                 if (atoi(status) == 1)
1175                                         resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1176                                 else
1177                                         resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1178                         }
1179
1180                         /* Parse <class> */
1181                         classx_str = g_slist_nth_data(tokens, 1);
1182                         if (!classx_str) {
1183                                 dbg("class error. skip this line");
1184                                 goto error;
1185                         } else {
1186                                 switch (atoi(classx_str)) {
1187                                 case 1:
1188                                         resp.record[countValidRecords].class = SS_CLASS_VOICE;
1189                                 break;
1190
1191                                 case 2:
1192                                         resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1193                                 break;
1194
1195                                 case 4:
1196                                         resp.record[countValidRecords].class = SS_CLASS_FAX;
1197                                 break;
1198
1199                                 case 7:
1200                                         resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1201                                 break;
1202
1203                                 case 8:
1204                                         resp.record[countValidRecords].class = SS_CLASS_SMS;
1205                                 break;
1206
1207                                 case 16:
1208                                         resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1209                                 break;
1210
1211                                 case 32:
1212                                         resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1213                                 break;
1214
1215                                 default:
1216                                         dbg("unspoorted class : [%d]\n", classx);
1217                                         goto error;
1218                                 }
1219                         }
1220
1221                         /* parse  <numer> <type> */
1222                         num = g_slist_nth_data(tokens, 2);
1223                         if (num) {
1224                                 dbg("number  - %s", num);
1225                                 memcpy((resp.record[countValidRecords].number), num, strlen(num));
1226                                 resp.record[countValidRecords].number_present = TRUE;
1227
1228                                 ton = g_slist_nth_data(tokens, 3);
1229                                 if (ton) {
1230                                         resp.record[countValidRecords].ton = atoi(ton);
1231                                         dbg("number  type - %d", resp.record[countValidRecords].ton);
1232                                 }
1233                         }
1234
1235                         /* skip  <subaddr> <satype> */
1236                         /* parse  <time> */
1237                         time_str = g_slist_nth_data(tokens, 6);
1238                         if (time_str) {
1239                                 time = atoi(time_str);
1240                                 resp.record[countValidRecords].time = (enum telephony_ss_forwarding_no_reply_time) time;
1241                                 dbg("time  - %d", time);
1242                         }
1243
1244                         resp.record[countValidRecords].mode = (enum telephony_ss_forwarding_mode) (info->flavor_type);
1245                         dbg("flavor_type  - %d", (enum telephony_ss_forwarding_mode) (info->flavor_type));
1246
1247                         countValidRecords++;
1248                         tcore_at_tok_free(tokens);
1249                         continue;
1250 error:
1251                         dbg("invalid field found. coutinue");
1252                         tcore_at_tok_free(tokens);
1253                         continue;
1254                 }
1255                 dbg("valid count :%d", countValidRecords);
1256                 resp.record_num = countValidRecords;
1257                 resp.err = SS_ERROR_NONE;
1258         } else {
1259                 dbg("no active status - return to user");
1260         }
1261
1262         if (response->success > 0) {
1263                 dbg("RESPONSE OK");
1264                 resp.err = SS_ERROR_NONE;
1265         } else {
1266                 dbg("RESPONSE NOT OK");
1267                 resp.record = 0;
1268                 resp.record_num = 0;
1269                 line = (const char *) response->final_response;
1270                 tokens = tcore_at_tok_new(line);
1271
1272                 if (g_slist_length(tokens) < 1) {
1273                         dbg("err cause not specified or string corrupted");
1274                         resp.err = SS_ERROR_SYSTEMFAILURE;
1275                 } else {
1276                         ss_err = atoi(g_slist_nth_data(tokens, 0));
1277                         err("Error: [%d]", ss_err);
1278                         /* TODO: CMEE error mapping is required. */
1279                         resp.err = SS_ERROR_SYSTEMFAILURE;
1280                 }
1281                 tcore_at_tok_free(tokens);
1282         }
1283
1284         dbg("on_response_ss_forwarding_get- rsp.err : %d, ur : %x", resp.err, ur);
1285         if (ur)
1286                 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
1287         else
1288                 dbg("[ error ] ur is 0");
1289
1290         if (resp.record) {
1291                 g_free(resp.record);
1292                 resp.record = NULL;
1293         }
1294         g_free(user_data);
1295 }
1296
1297 static void on_response_ss_waiting_get(TcorePending *p, int data_len, const void *data, void *user_data)
1298 {
1299         UserRequest *ur = 0;
1300         GSList *respdata, *tokens = NULL;
1301         int classx = 0, ss_err = 0;
1302         struct ss_confirm_info *info = 0;
1303         struct tresp_ss_waiting resp;
1304         int countRecords = 0, countValidRecords = 0;
1305         const char *line;
1306         char *classx_str, *status;
1307         const TcoreATResponse *response;
1308
1309         dbg("function enter");
1310         response = data;
1311         ur = tcore_pending_ref_user_request(p);
1312         info = (struct ss_confirm_info *) user_data;
1313
1314         if (response->lines) {
1315                 respdata = (GSList *) response->lines;
1316                 countRecords = g_slist_length(respdata);
1317                 dbg("total records : %d", countRecords);
1318         } else {
1319                 countRecords = 0;
1320                 dbg("no active status - return to user");
1321         }
1322         resp.record_num = countRecords;
1323         resp.record = 0;
1324
1325         if (resp.record_num > 0) {
1326                 resp.record = g_new0(struct waiting_info, resp.record_num);
1327
1328                 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1329                         line = (const char *) (respdata->data);
1330                         tokens = tcore_at_tok_new(line);
1331
1332                         /* parse <status> */
1333                         status = g_slist_nth_data(tokens, 0);
1334                         if (!status) {
1335                                 dbg("Missing stat  in responce ");
1336                                 goto error;
1337                         } else {
1338                                 if (atoi(status) == 1)
1339                                         resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1340                                 else
1341                                         resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1342                         }
1343                         dbg("status = %d", resp.record[countValidRecords].status);
1344
1345                         /* Parse <class> */
1346                         classx_str = g_slist_nth_data(tokens, 1);
1347                         if (!classx_str) {
1348                                 dbg("error - class is missing");
1349                                 goto error;
1350                         } else {
1351                                 switch (atoi(classx_str)) {
1352                                 case 1:
1353                                         resp.record[countValidRecords].class = SS_CLASS_VOICE;
1354                                 break;
1355
1356                                 case 2:
1357                                         resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1358                                 break;
1359
1360                                 case 4:
1361                                         resp.record[countValidRecords].class = SS_CLASS_FAX;
1362                                 break;
1363
1364                                 case 7:
1365                                         resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1366                                 break;
1367
1368                                 case 8:
1369                                         resp.record[countValidRecords].class = SS_CLASS_SMS;
1370                                 break;
1371
1372                                 case 16:
1373                                         resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1374                                 break;
1375
1376                                 case 32:
1377                                         resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1378                                 break;
1379
1380                                 default:
1381                                         dbg("unspoorted class : [%d]\n", classx);
1382                                         goto error;
1383                                 }
1384                                 dbg("class info %d", resp.record[countValidRecords].class);
1385                         }
1386
1387                         countValidRecords++;
1388                         tcore_at_tok_free(tokens);
1389                         continue;
1390 error:
1391                         dbg("invalid field found. coutinue");
1392                         tcore_at_tok_free(tokens);
1393                         continue;
1394                 }
1395
1396                 dbg("valid count :%d", countValidRecords);
1397                 resp.record_num = countValidRecords;
1398                 resp.err = SS_ERROR_NONE;
1399         } else {
1400                 dbg("no active status - return to user");
1401         }
1402
1403         if (response->success > 0) {
1404                 dbg("RESPONSE OK");
1405                 resp.err = SS_ERROR_NONE;
1406         } else {
1407                 dbg("RESPONSE NOT OK");
1408                 resp.record = 0;
1409                 resp.record_num = 0;
1410                 line = (const char *) response->final_response;
1411                 tokens = tcore_at_tok_new(line);
1412
1413                 if (g_slist_length(tokens) < 1) {
1414                         dbg("err cause not specified or string corrupted");
1415                         resp.err = SS_ERROR_SYSTEMFAILURE;
1416                 } else {
1417                         ss_err = atoi(g_slist_nth_data(tokens, 0));
1418                         err("Error: [%d]", ss_err);
1419                         /* TODO: CMEE error mapping is required. */
1420                         resp.err = SS_ERROR_SYSTEMFAILURE;
1421                 }
1422                 tcore_at_tok_free(tokens);
1423         }
1424
1425         dbg("on_response_ss_waiting_get - rsp.err : %d, ur : %x", resp.err, ur);
1426         if (ur)
1427                 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
1428         else
1429                 dbg("[ error ] ur is 0");
1430
1431         if (resp.record) {
1432                 g_free(resp.record);
1433                 resp.record = NULL;
1434         }
1435         g_free(user_data);
1436 }
1437
1438
1439 static void on_response_ss_cli_get(TcorePending *p, int data_len, const void *data, void *user_data)
1440 {
1441         UserRequest *ur = 0;
1442         struct tresp_ss_cli resp;
1443         enum telephony_ss_cli_type p_type;
1444         char *line = NULL, *status;
1445         int error = FALSE;
1446         int cli_adj, stat = 0;
1447         GSList *tokens = NULL;
1448         const TcoreATResponse *response;
1449
1450         dbg("function enter");
1451         response = data;
1452         ur = tcore_pending_ref_user_request(p);
1453         p_type = GPOINTER_TO_INT(user_data);
1454
1455         if (response->success > 0) {
1456                 line = (char *) (((GSList *) response->lines)->data);
1457                 tokens = tcore_at_tok_new(line);
1458
1459                 if (p_type == SS_CLI_TYPE_CLIR) {
1460                         /* +CLIR: <n> <m> */
1461                         dbg("CLI type is CLIR");
1462                         /* parse <n> */
1463                         status = g_slist_nth_data(tokens, 0);
1464
1465                         if (!status) {
1466                                 dbg("Call line identification adjustment missing <n>");
1467                         } else {
1468                                 cli_adj = atoi(status);
1469                                 dbg("CLIR response value of <n> - %d", cli_adj);
1470
1471                                 if (cli_adj == 0) {
1472                                         /* parse <m> */
1473                                         status = g_slist_nth_data(tokens, 1);
1474                                         if (!status)
1475                                                 dbg("status is missing<m>");
1476                                         else
1477                                                 stat = atoi(status);
1478                                         dbg("CLIR response value of <m> - %d", stat);
1479
1480                                         if (stat == 1 || stat == 3)
1481                                                 resp.status = TRUE;
1482                                         else
1483                                                 resp.status = FALSE;
1484                                 } else if (cli_adj == 1) {
1485                                         resp.status = TRUE;
1486                                 } else {
1487                                         resp.status = FALSE;
1488                                 }
1489                                 dbg("resp.status -  %d", resp.status);
1490                         }
1491                         tcore_at_tok_free(tokens);
1492                 } else {
1493                         /* parse <n> */
1494                         status = g_slist_nth_data(tokens, 0);
1495                         if (!status) {
1496                                 dbg("Stat is missing");
1497                         } else {
1498                                 stat = atoi(status);
1499                                 if (stat == 1)
1500                                         resp.status = TRUE;
1501                                 else
1502                                         resp.status = FALSE;
1503
1504                                 dbg("resp.status -  %d", resp.status);
1505                         }
1506                         tcore_at_tok_free(tokens);
1507                 }
1508         }
1509
1510         if (response->success > 0) {
1511                 dbg("RESPONSE OK");
1512                 resp.err = SS_ERROR_NONE;
1513         } else {
1514                 dbg("RESPONSE NOT OK");
1515
1516                 line = (char *) response->final_response;
1517                 tokens = tcore_at_tok_new(line);
1518
1519                 if (g_slist_length(tokens) < 1) {
1520                         dbg("err cause not specified or string corrupted");
1521                         resp.err = SS_ERROR_SYSTEMFAILURE;
1522                 } else {
1523                         error = atoi(g_slist_nth_data(tokens, 0));
1524                         err("Error: [%d]", error);
1525                         /* TODO: CMEE error mapping is required. */
1526                         resp.err = SS_ERROR_SYSTEMFAILURE;
1527                 }
1528                 tcore_at_tok_free(tokens);
1529         }
1530
1531         resp.type = p_type;
1532         dbg("check - resp.type = %d ", resp.type);
1533         if (ur)
1534                 tcore_user_request_send_response(ur, TRESP_SS_CLI_GET_STATUS, sizeof(struct tresp_ss_cli), &resp);
1535         else
1536                 dbg("[ error ] ur : (0)");
1537 }
1538
1539 static struct tcore_ss_operations ss_ops = {
1540         .barring_activate = imc_ss_barring_activate,
1541         .barring_deactivate = imc_ss_barring_deactivate,
1542         .barring_change_password = imc_ss_barring_change_password,
1543         .barring_get_status = imc_ss_barring_get_status,
1544         .forwarding_activate = imc_ss_forwarding_activate,
1545         .forwarding_deactivate = imc_ss_forwarding_deactivate,
1546         .forwarding_register = imc_ss_forwarding_register,
1547         .forwarding_deregister = imc_ss_forwarding_deregister,
1548         .forwarding_get_status = imc_ss_forwarding_get_status,
1549         .waiting_activate = imc_ss_waiting_activate,
1550         .waiting_deactivate = imc_ss_waiting_deactivate,
1551         .waiting_get_status = imc_ss_waiting_get_status,
1552         .cli_activate = imc_ss_cli_activate,
1553         .cli_deactivate = imc_ss_cli_deactivate,
1554         .cli_get_status = imc_ss_cli_get_status,
1555         .send_ussd = imc_ss_send_ussd,
1556         .set_aoc = imc_ss_set_aoc,
1557         .get_aoc = imc_ss_get_aoc,
1558 };
1559
1560
1561 static TReturn _ss_barring_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1562 {
1563         struct treq_ss_barring *barring = 0;
1564         struct ss_confirm_info *user_data = 0;
1565         char *cmd_str = NULL;
1566         TcorePending *pending = NULL;
1567         TcoreATRequest *req;
1568         char passwd[MAX_SS_BARRING_PASSWORD_LEN + 1];
1569         int opco;
1570         int classx;
1571         char *facility = NULL;
1572         gboolean ret = FALSE;
1573
1574         dbg("function enter");
1575         barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1576
1577         switch (op) {
1578         case SS_OPCO_ACTIVATE:
1579                 opco = 1;
1580         break;
1581
1582         case SS_OPCO_DEACTIVATE:
1583                 opco = 0;
1584         break;
1585
1586         default:
1587                 dbg("unsupported opco : %d", op);
1588                 return TCORE_RETURN_FAILURE;
1589         }
1590         dbg("opco - %d", opco);
1591
1592         switch (barring->mode) {
1593         case SS_BARR_MODE_BAOC:
1594                 facility = "AO";
1595         break;
1596
1597         case SS_BARR_MODE_BOIC:
1598                 facility = "OI";
1599         break;
1600
1601         case SS_BARR_MODE_BOIC_NOT_HC:
1602                 facility = "OX";
1603         break;
1604
1605         case SS_BARR_MODE_BAIC:
1606                 facility = "AI";
1607         break;
1608
1609         case SS_BARR_MODE_BIC_ROAM:
1610                 facility = "IR";
1611         break;
1612
1613         case SS_BARR_MODE_AB:
1614                 facility = "AB";
1615         break;
1616
1617         case SS_BARR_MODE_AOB:
1618                 facility = "AG";
1619         break;
1620
1621         case SS_BARR_MODE_AIB:
1622                 facility = "AC";
1623         break;
1624
1625         case SS_BARR_MODE_BIC_NOT_SIM:
1626         /* facility = "NS"; */
1627         default:
1628                 dbg("unspported mode %d", barring->mode);
1629                 return TCORE_RETURN_FAILURE;
1630         }
1631
1632         dbg("facility - %s", facility);
1633
1634         switch (barring->class) {
1635         case SS_CLASS_ALL_TELE:
1636                 classx = 7;
1637                 break;
1638
1639         case SS_CLASS_VOICE:
1640                 classx = 1;
1641                 break;
1642
1643         case SS_CLASS_ALL_DATA_TELE:
1644                 classx = 2;
1645                 break;
1646
1647         case SS_CLASS_FAX:
1648                 classx = 4;
1649                 break;
1650
1651         case SS_CLASS_SMS:
1652                 classx = 8;
1653                 break;
1654
1655         case SS_CLASS_ALL_CS_SYNC:
1656                 classx = 16;
1657                 break;
1658
1659         default:
1660                 classx = 7;
1661                 dbg("unsupported class %d. set to default : 7", barring->class);
1662                 break;
1663         }
1664
1665         dbg("classx - %d", classx);
1666
1667         user_data = g_new0(struct ss_confirm_info, 1);
1668         if (!user_data) {
1669                 dbg("[ error ] failed to allocate memory");
1670                 return TCORE_RETURN_ENOMEM;
1671         }
1672
1673         /* null-ended pwd handling added - unexpected  0x11 value observed in req string */
1674         memcpy(passwd, barring->password, MAX_SS_BARRING_PASSWORD_LEN);
1675         passwd[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1676         dbg("passwd - %s", passwd);
1677
1678         pending = tcore_pending_new(o, 0);
1679
1680         cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d", facility, opco, passwd, classx);
1681         dbg("request command : %s", cmd_str);
1682
1683         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1684         if (req == NULL) {
1685                 tcore_pending_free(pending);
1686                 g_free(cmd_str);
1687                 return TCORE_RETURN_FAILURE;
1688         }
1689         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1690
1691         tcore_pending_set_request_data(pending, 0, req);
1692
1693         if (op == SS_OPCO_ACTIVATE) {
1694                 user_data->resp = TRESP_SS_BARRING_ACTIVATE;
1695         } else if (op == SS_OPCO_DEACTIVATE) {
1696                 user_data->resp = TRESP_SS_BARRING_DEACTIVATE;
1697         } else {
1698                 dbg("[ error ] wrong ss opco (0x%x)", op);
1699                 if (user_data != NULL)
1700                         g_free(user_data);
1701
1702                 g_free(cmd_str);
1703                 tcore_pending_free(pending);
1704                 tcore_at_request_free(req);
1705                 return TCORE_RETURN_FAILURE;
1706         }
1707         user_data->flavor_type = (int) (barring->mode);
1708         user_data->class = barring->class;
1709
1710         ret = _ss_request_message(pending, o, ur, on_response_ss_barring_set, user_data);
1711         g_free(cmd_str);
1712
1713         if (!ret) {
1714                 dbg("AT request sent failed ");
1715                 if (user_data != NULL) {
1716                         g_free(user_data);
1717                         tcore_pending_free(pending);
1718                         tcore_at_request_free(req);
1719                 }
1720                 return TCORE_RETURN_FAILURE;
1721         }
1722         return TCORE_RETURN_SUCCESS;
1723 }
1724
1725 static TReturn _ss_barring_get(CoreObject *o,
1726                                                            UserRequest *ur,
1727                                                            enum telephony_ss_class class,
1728                                                            enum telephony_ss_barring_mode mode,
1729                                                            enum tcore_response_command resp)
1730 {
1731         struct ss_confirm_info *user_data = 0;
1732         gboolean ret = FALSE;
1733         char *cmd_str = NULL;
1734         int opco, classx;
1735         char *facility = NULL;
1736         TcorePending *pending = NULL;
1737         TcoreATRequest *req;
1738
1739         dbg("function enter");
1740
1741         /* query status - opco is fixed to 2 */
1742         opco = 2;
1743         /* barring mode */
1744         switch (mode) {
1745         case SS_BARR_MODE_BAOC:
1746                 facility = "AO";
1747                 break;
1748
1749         case SS_BARR_MODE_BOIC:
1750                 facility = "OI";
1751                 break;
1752
1753         case SS_BARR_MODE_BOIC_NOT_HC:
1754                 facility = "OX";
1755                 break;
1756
1757         case SS_BARR_MODE_BAIC:
1758                 facility = "AI";
1759                 break;
1760
1761         case SS_BARR_MODE_BIC_ROAM:
1762                 facility = "IR";
1763                 break;
1764
1765         case SS_BARR_MODE_AB:
1766         case SS_BARR_MODE_AOB:
1767         case SS_BARR_MODE_AIB:
1768         case SS_BARR_MODE_BIC_NOT_SIM:
1769         default:
1770                 dbg("unsupported mode %d", mode);
1771                 return TCORE_RETURN_FAILURE;
1772         }
1773
1774         dbg("facility - %s", facility);
1775
1776         switch (class) {
1777         case SS_CLASS_ALL_TELE:
1778                 classx = 7;
1779                 break;
1780
1781         case SS_CLASS_VOICE:
1782                 classx = 1;
1783                 break;
1784
1785         case SS_CLASS_ALL_DATA_TELE:
1786                 classx = 2;
1787                 break;
1788
1789         case SS_CLASS_FAX:
1790                 classx = 4;
1791                 break;
1792
1793         case SS_CLASS_SMS:
1794                 classx = 8;
1795                 break;
1796
1797         case SS_CLASS_ALL_CS_SYNC:
1798                 classx = 16;
1799                 break;
1800
1801         default:
1802                 classx = 7;
1803                 dbg("unsupported class %d. set to default : 7", class);
1804                 break;
1805         }
1806
1807         user_data = g_new0(struct ss_confirm_info, 1);
1808         if (!user_data) {
1809                 dbg("[ error ] failed to allocate memory");
1810                 return TCORE_RETURN_ENOMEM;
1811         }
1812
1813         dbg("class - %d", classx);
1814         if (classx == 7)
1815                 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d", facility, opco);
1816         else
1817                 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d", facility, opco, classx);
1818
1819         dbg("request command : %s", cmd_str);
1820
1821         pending = tcore_pending_new(o, 0);
1822         req = tcore_at_request_new(cmd_str, "+CLCK", TCORE_AT_MULTILINE);
1823         if (req == NULL) {
1824                 tcore_pending_free(pending);
1825                 g_free(cmd_str);
1826                 return TCORE_RETURN_FAILURE;
1827         }
1828         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1829
1830         tcore_pending_set_request_data(pending, 0, req);
1831
1832         user_data->resp = resp;
1833         user_data->flavor_type = (int) (mode);
1834         user_data->class = class;
1835
1836         ret = _ss_request_message(pending, o, ur, on_response_ss_barring_get, user_data);
1837         g_free(cmd_str);
1838
1839         if (!ret) {
1840                 dbg("AT request sent failed ");
1841                 if (user_data != NULL) {
1842                         g_free(user_data);
1843                         tcore_pending_free(pending);
1844                         tcore_at_request_free(req);
1845                 }
1846                 return TCORE_RETURN_FAILURE;
1847         }
1848
1849         return TCORE_RETURN_SUCCESS;
1850 }
1851
1852 static TReturn imc_ss_barring_activate(CoreObject *o, UserRequest *ur)
1853 {
1854         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
1855                 dbg("cp not ready/n");
1856                 return TCORE_RETURN_ENOSYS;
1857         }
1858         return _ss_barring_set(o, ur, SS_OPCO_ACTIVATE);
1859 }
1860
1861 static TReturn imc_ss_barring_deactivate(CoreObject *o, UserRequest *ur)
1862 {
1863         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
1864                 dbg("cp not ready/n");
1865                 return TCORE_RETURN_ENOSYS;
1866         }
1867         return _ss_barring_set(o, ur, SS_OPCO_DEACTIVATE);
1868 }
1869
1870 static TReturn imc_ss_barring_change_password(CoreObject *o, UserRequest *ur)
1871 {
1872         TcorePending *pending = NULL;
1873         TcoreATRequest *req;
1874         struct treq_ss_barring_change_password *barring = 0;
1875         struct ss_confirm_info *user_data = 0;
1876         char *cmd_str = NULL;
1877         gboolean ret = FALSE;
1878         char old_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1879         char new_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1880
1881         dbg("function enter");
1882
1883         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
1884                 dbg("cp not ready/n");
1885                 return TCORE_RETURN_ENOSYS;
1886         }
1887
1888         barring = (struct treq_ss_barring_change_password *) tcore_user_request_ref_data(ur, 0);
1889
1890         memcpy(old_password, barring->password_old, MAX_SS_BARRING_PASSWORD_LEN);
1891         old_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1892         memcpy(new_password, barring->password_new, MAX_SS_BARRING_PASSWORD_LEN);
1893         new_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1894
1895         user_data = g_new0(struct ss_confirm_info, 1);
1896         if (!user_data) {
1897                 dbg("[ error ] failed to allocate memory");
1898                 return TCORE_RETURN_ENOMEM;
1899         }
1900         user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
1901
1902         dbg("old passwd - %s new passwd- %s", old_password, new_password);
1903         cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB", old_password, new_password);
1904         dbg("request command : %s", cmd_str);
1905
1906         pending = tcore_pending_new(o, 0);
1907         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1908         if (req == NULL) {
1909                 tcore_pending_free(pending);
1910                 g_free(cmd_str);
1911                 return TCORE_RETURN_FAILURE;
1912         }
1913         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1914
1915         tcore_pending_set_request_data(pending, 0, req);
1916
1917         ret = _ss_request_message(pending, o, ur, on_response_ss_barring_change_pwd, user_data);
1918         g_free(cmd_str);
1919         if (!ret) {
1920                 dbg("AT request sent failed ");
1921                 if (user_data != NULL)
1922                         g_free(user_data);
1923
1924                 tcore_pending_free(pending);
1925                 tcore_at_request_free(req);
1926                 return TCORE_RETURN_FAILURE;
1927         }
1928         return TCORE_RETURN_SUCCESS;
1929 }
1930
1931 static TReturn imc_ss_barring_get_status(CoreObject *o, UserRequest *ur)
1932 {
1933         struct treq_ss_barring *barring = 0;
1934
1935         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
1936                 dbg("cp not ready/n");
1937                 return TCORE_RETURN_ENOSYS;
1938         }
1939         barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1940
1941         return _ss_barring_get(o, ur, barring->class, barring->mode, TRESP_SS_BARRING_GET_STATUS);
1942 }
1943
1944 static TReturn _ss_forwarding_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1945 {
1946         struct treq_ss_forwarding *forwarding = 0;
1947         struct ss_confirm_info *user_data = 0;
1948         gboolean ret = FALSE;
1949         int len = 0;
1950         char *cmd_str = NULL;
1951         char *tmp_str = NULL;
1952         int reason = 0, mode = 0, num_type = 0, classx = 0, time = 0;
1953         TcorePending *pending = NULL;
1954         TcoreATRequest *req;
1955
1956         dbg("_ss_forwarding_set with opco %d ", op);
1957
1958         forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
1959         switch (forwarding->mode) {
1960         case SS_CF_MODE_CFU:
1961                 reason = 0;
1962                 break;
1963
1964         case SS_CF_MODE_CFB:
1965                 reason = 1;
1966                 break;
1967
1968         case SS_CF_MODE_CFNRy:
1969                 reason = 2;
1970                 break;
1971
1972         case SS_CF_MODE_CFNRc:
1973                 reason = 3;
1974                 break;
1975
1976         case SS_CF_MODE_CF_ALL:
1977                 reason = 4;
1978                 break;
1979
1980         case SS_CF_MODE_CFC:
1981                 reason = 5;
1982                 break;
1983
1984         default:
1985                 dbg("unsupported reason : %d");
1986                 return TCORE_RETURN_FAILURE;
1987                 break;
1988         }
1989
1990         dbg("reason = %d", reason);
1991         switch (op) {
1992         case SS_OPCO_DEACTIVATE:
1993                 mode = 0;
1994                 break;
1995
1996         case SS_OPCO_ACTIVATE:
1997                 mode = 1;
1998                 break;
1999
2000         case SS_OPCO_REG:
2001                 mode = 3;
2002                 break;
2003
2004         case SS_OPCO_DEREG:
2005                 mode = 4;
2006                 break;
2007
2008         default:
2009                 dbg("unsupported opco : %d", op);
2010                 return TCORE_RETURN_FAILURE;
2011         }
2012
2013         dbg("mode = %d", mode);
2014
2015         /* class */
2016         switch (forwarding->class) {
2017         case SS_CLASS_ALL_TELE:
2018                 classx = 7;
2019                 break;
2020
2021         case SS_CLASS_VOICE:
2022                 classx = 1;
2023                 break;
2024
2025         case SS_CLASS_ALL_DATA_TELE:
2026                 classx = 2;
2027                 break;
2028
2029         case SS_CLASS_FAX:
2030                 classx = 4;
2031                 break;
2032
2033         case SS_CLASS_SMS:
2034                 classx = 8;
2035                 break;
2036
2037         case SS_CLASS_ALL_CS_SYNC:
2038                 classx = 16;
2039                 break;
2040
2041         default:
2042                 classx = 7;
2043                 dbg("unsupported class %d. set to default : 7", forwarding->class);
2044                 break;
2045         }
2046         dbg("classx = %d", classx);
2047
2048         /* number */
2049         len = strlen(forwarding->number);
2050         if (len > 0) {
2051                 if (forwarding->number[0] == '+')
2052                         num_type = ((NUM_TYPE_INTERNATIONAL << 4) | NUM_PLAN_ISDN);
2053                 else
2054                         num_type = 0;
2055         }
2056         dbg("number = %s", forwarding->number);
2057
2058         user_data = g_new0(struct ss_confirm_info, 1);
2059         if (!user_data) {
2060                 dbg("[ error ] failed to allocate memory");
2061                 return TCORE_RETURN_ENOMEM;
2062         }
2063
2064         switch (op) {
2065         case SS_OPCO_REG:
2066                 user_data->resp = TRESP_SS_FORWARDING_REGISTER;
2067                 break;
2068
2069         case SS_OPCO_DEREG:
2070                 user_data->resp = TRESP_SS_FORWARDING_DEREGISTER;
2071                 break;
2072
2073         case SS_OPCO_ACTIVATE:
2074                 user_data->resp = TRESP_SS_FORWARDING_ACTIVATE;
2075                 break;
2076
2077         case SS_OPCO_DEACTIVATE:
2078                 user_data->resp = TRESP_SS_FORWARDING_DEACTIVATE;
2079                 break;
2080
2081         default:
2082                 dbg("[ error ] unknown op (0x%x)", op);
2083                 break;
2084         }
2085
2086         if (forwarding->number[0] == '+')
2087                 num_type = 145;
2088         else
2089                 num_type = 129;
2090
2091         if (op == SS_OPCO_REG)
2092                 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,\"%s\",%d,%d", reason, mode, forwarding->number, num_type, classx);
2093         else /* other opcode does not need num field */
2094                 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2095
2096         if (forwarding->mode == SS_CF_MODE_CFNRy) {
2097                 /* add time info to 'no reply' case */
2098                 time = (int) (forwarding->time);
2099                 cmd_str = g_strdup_printf("%s,,,%d", tmp_str, time);
2100         } else {
2101                 cmd_str = g_strdup_printf("%s", tmp_str);
2102         }
2103
2104         dbg("request command : %s", cmd_str);
2105         pending = tcore_pending_new(o, 0);
2106         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2107         if (req == NULL) {
2108                 tcore_pending_free(pending);
2109                 g_free(cmd_str);
2110                 g_free(tmp_str);
2111                 return TCORE_RETURN_FAILURE;
2112         }
2113         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2114
2115         tcore_pending_set_request_data(pending, 0, req);
2116
2117         user_data->flavor_type = forwarding->mode;
2118         user_data->class = forwarding->class;
2119
2120         ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_set, user_data);
2121
2122         g_free(tmp_str);
2123         g_free(cmd_str);
2124
2125         if (!ret) {
2126                 dbg("AT request sent failed ");
2127                 if (user_data != NULL)
2128                         g_free(user_data);
2129
2130                 return TCORE_RETURN_FAILURE;
2131         }
2132
2133         return TCORE_RETURN_SUCCESS;
2134 }
2135
2136 static TReturn _ss_forwarding_get(CoreObject *o,
2137           UserRequest *ur,
2138           enum telephony_ss_class class,
2139           enum telephony_ss_forwarding_mode type,
2140           enum tcore_response_command resp)
2141 {
2142         struct ss_confirm_info *user_data = 0;
2143         gboolean ret = FALSE;
2144         char *cmd_str = NULL;
2145         int reason = 0, mode = 0, classx = 0;
2146         TcorePending *pending = NULL;
2147         TcoreATRequest *req;
2148
2149         dbg("function enter");
2150
2151         switch (type) {
2152         case SS_CF_MODE_CFU:
2153                 reason = 0;
2154         break;
2155
2156         case SS_CF_MODE_CFB:
2157                 reason = 1;
2158         break;
2159
2160         case SS_CF_MODE_CFNRy:
2161                 reason = 2;
2162         break;
2163
2164         case SS_CF_MODE_CFNRc:
2165                 reason = 3;
2166         break;
2167
2168         case SS_CF_MODE_CF_ALL:
2169                 reason = 4;
2170         break;
2171
2172         case SS_CF_MODE_CFC:
2173                 reason = 5;
2174         break;
2175
2176         default:
2177                 dbg("unsupported reason : %d");
2178         break;
2179         }
2180         dbg("reason  = %d", reason);
2181
2182         switch (class) {
2183         case SS_CLASS_ALL_TELE:
2184                 classx = 7;
2185         break;
2186
2187         case SS_CLASS_VOICE:
2188                 classx = 1;
2189         break;
2190
2191         case SS_CLASS_ALL_DATA_TELE:
2192                 classx = 2;
2193         break;
2194
2195         case SS_CLASS_FAX:
2196                 classx = 4;
2197         break;
2198
2199         case SS_CLASS_SMS:
2200                 classx = 8;
2201         break;
2202
2203         case SS_CLASS_ALL_CS_SYNC:
2204                 classx = 16;
2205         break;
2206
2207         default:
2208                 classx = 7;
2209                 dbg("unsupported class %d. set to default : 7", class);
2210         break;
2211         }
2212
2213         dbg("classx  = %d", classx);
2214
2215         /* query status - mode set to 2 */
2216         mode = 2;
2217         user_data = g_new0(struct ss_confirm_info, 1);
2218         if (!user_data) {
2219                 dbg("[ error ] failed to allocate memory");
2220                 return TCORE_RETURN_ENOMEM;
2221         }
2222         user_data->resp = resp;
2223         user_data->class = class;
2224         user_data->flavor_type = type;
2225
2226         if (classx == 7)
2227                 cmd_str = g_strdup_printf("AT+CCFC=%d,%d", reason, mode);
2228         else
2229                 cmd_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2230
2231         dbg("request command : %s", cmd_str);
2232
2233         pending = tcore_pending_new(o, 0);
2234         req = tcore_at_request_new(cmd_str, "+CCFC", TCORE_AT_MULTILINE);
2235         if (req == NULL) {
2236                 tcore_pending_free(pending);
2237                 g_free(cmd_str);
2238                 return TCORE_RETURN_FAILURE;
2239         }
2240         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2241
2242         tcore_pending_set_request_data(pending, 0, req);
2243
2244         ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_get, user_data);
2245         g_free(cmd_str);
2246
2247         if (!ret) {
2248                 dbg("AT request sent failed ");
2249                 if (user_data != NULL) {
2250                         g_free(user_data);
2251                         tcore_pending_free(pending);
2252                         tcore_at_request_free(req);
2253                 }
2254                 return TCORE_RETURN_FAILURE;
2255         }
2256
2257         return TCORE_RETURN_SUCCESS;
2258 }
2259
2260 static TReturn imc_ss_forwarding_activate(CoreObject *o, UserRequest *ur)
2261 {
2262         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2263                 dbg("cp not ready/n");
2264                 return TCORE_RETURN_ENOSYS;
2265         }
2266         return _ss_forwarding_set(o, ur, SS_OPCO_ACTIVATE);
2267 }
2268
2269 static TReturn imc_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur)
2270 {
2271         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2272                 dbg("cp not ready/n");
2273                 return TCORE_RETURN_ENOSYS;
2274         }
2275         return _ss_forwarding_set(o, ur, SS_OPCO_DEACTIVATE);
2276 }
2277
2278 static TReturn imc_ss_forwarding_register(CoreObject *o, UserRequest *ur)
2279 {
2280         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2281                 dbg("cp not ready/n");
2282                 return TCORE_RETURN_ENOSYS;
2283         }
2284         return _ss_forwarding_set(o, ur, SS_OPCO_REG);
2285 }
2286
2287 static TReturn imc_ss_forwarding_deregister(CoreObject *o, UserRequest *ur)
2288 {
2289         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2290                 dbg("cp not ready/n");
2291                 return TCORE_RETURN_ENOSYS;
2292         }
2293         return _ss_forwarding_set(o, ur, SS_OPCO_DEREG);
2294 }
2295
2296 static TReturn imc_ss_forwarding_get_status(CoreObject *o, UserRequest *ur)
2297 {
2298         struct treq_ss_forwarding *forwarding = 0;
2299
2300         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2301                 dbg("cp not ready/n");
2302                 return TCORE_RETURN_ENOSYS;
2303         }
2304
2305         forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
2306
2307         return _ss_forwarding_get(o, ur, forwarding->class, forwarding->mode, TRESP_SS_FORWARDING_GET_STATUS);
2308 }
2309
2310
2311 static TReturn _ss_waiting_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode opco)
2312 {
2313         struct treq_ss_waiting *waiting = 0;
2314         struct ss_confirm_info *user_data = 0;
2315         gboolean ret = FALSE;
2316         int mode = 0, classx = 0;
2317         char *cmd_str;
2318         TcorePending *pending = NULL;
2319         TcoreATRequest *req;
2320
2321         dbg("function enter ");
2322         waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2323         user_data = g_new0(struct ss_confirm_info, 1);
2324         if (!user_data) {
2325                 dbg("[ error ] failed to allocate memory");
2326                 return TCORE_RETURN_ENOMEM;
2327         }
2328
2329         if (opco == SS_OPCO_ACTIVATE) {
2330                 user_data->resp = TRESP_SS_WAITING_ACTIVATE;
2331                 mode = 1; /* enable */
2332         } else if (opco == SS_OPCO_DEACTIVATE) {
2333                 user_data->resp = TRESP_SS_WAITING_DEACTIVATE;
2334                 mode = 0; /* disable */
2335         } else
2336                 dbg("[ error ] unknown ss mode (0x%x)", opco);
2337
2338         switch (waiting->class) {
2339         case SS_CLASS_ALL_TELE:
2340                 classx = 7;
2341                 break;
2342
2343         case SS_CLASS_VOICE:
2344                 classx = 1;
2345                 break;
2346
2347         case SS_CLASS_ALL_DATA_TELE:
2348                 classx = 2;
2349                 break;
2350
2351         case SS_CLASS_FAX:
2352                 classx = 4;
2353                 break;
2354
2355         case SS_CLASS_SMS:
2356                 classx = 8;
2357                 break;
2358
2359         default:
2360                 classx = 1;
2361                 dbg("unsupported class %d. set to default : 1", waiting->class);
2362                 break;
2363         }
2364         dbg("mode = %d classxx- %d", mode, classx);
2365
2366         user_data->class = waiting->class;
2367         user_data->flavor_type = (int) opco;
2368
2369         cmd_str = g_strdup_printf("AT+CCWA=1,%d,%d", mode, classx); /* always enable +CCWA: unsolicited cmd */
2370         dbg("request command : %s", cmd_str);
2371
2372         pending = tcore_pending_new(o, 0);
2373         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2374         if (req == NULL) {
2375                 tcore_pending_free(pending);
2376                 g_free(cmd_str);
2377                 return TCORE_RETURN_FAILURE;
2378         }
2379         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2380
2381         tcore_pending_set_request_data(pending, 0, req);
2382
2383         ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_set, user_data);
2384         g_free(cmd_str);
2385         if (!ret) {
2386                 dbg("AT request sent failed ");
2387                 if (user_data != NULL) {
2388                         g_free(user_data);
2389                         tcore_pending_free(pending);
2390                         tcore_at_request_free(req);
2391                 }
2392                 return TCORE_RETURN_FAILURE;
2393         }
2394         return TCORE_RETURN_SUCCESS;
2395 }
2396
2397 static TReturn _ss_waiting_get(CoreObject *o,
2398            UserRequest *ur,
2399            enum telephony_ss_class class,
2400            enum tcore_response_command resp)
2401 {
2402         struct ss_confirm_info *user_data = 0;
2403         gboolean ret = FALSE;
2404         int classx; /* mode, */
2405         char *cmd_str;
2406         TcorePending *pending = NULL;
2407         TcoreATRequest *req;
2408
2409         dbg("function  enter");
2410         switch (class) {
2411         case SS_CLASS_ALL_TELE:
2412                 classx = 7;
2413         break;
2414
2415         case SS_CLASS_VOICE:
2416                 classx = 1;
2417         break;
2418
2419         case SS_CLASS_ALL_DATA_TELE:
2420                 classx = 2;
2421         break;
2422
2423         case SS_CLASS_FAX:
2424                 classx = 4;
2425         break;
2426
2427         case SS_CLASS_SMS:
2428                 classx = 8;
2429         break;
2430
2431         default:
2432                 classx = 7;
2433                 dbg("unsupported class %d. set to default : 7", class);
2434         break;
2435         }
2436         dbg("classx - %d", classx);
2437
2438         dbg("allocating user data");
2439         user_data = g_new0(struct ss_confirm_info, 1);
2440         if (!user_data) {
2441                 dbg("[ error ] failed to allocate memory");
2442                 return TCORE_RETURN_ENOMEM;
2443         }
2444         user_data->resp = resp;
2445         user_data->class = class;
2446
2447         cmd_str = g_strdup_printf("AT+CCWA=1,2,%d", classx); /* always enable +CCWA: unsolicited cmd , mode is fixed to 2(query status) */
2448         dbg("request cmd : %s", cmd_str);
2449
2450         pending = tcore_pending_new(o, 0);
2451         req = tcore_at_request_new(cmd_str, "+CCWA", TCORE_AT_MULTILINE);
2452         if (req == NULL) {
2453                 err("Request is NULL");
2454                 g_free(cmd_str);
2455                 tcore_pending_free(pending);
2456                 return TCORE_RETURN_EINVAL;
2457         }
2458         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2459
2460         tcore_pending_set_request_data(pending, 0, req);
2461
2462         ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_get, user_data);
2463         g_free(cmd_str);
2464         if (!ret) {
2465                 dbg("AT request sent failed ");
2466                 if (user_data != NULL) {
2467                         g_free(user_data);
2468                         tcore_pending_free(pending);
2469                         tcore_at_request_free(req);
2470                 }
2471                 return TCORE_RETURN_FAILURE;
2472         }
2473         return TCORE_RETURN_SUCCESS;
2474 }
2475
2476 static TReturn imc_ss_waiting_activate(CoreObject *o, UserRequest *ur)
2477 {
2478         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2479                 dbg("cp not ready/n");
2480                 return TCORE_RETURN_ENOSYS;
2481         }
2482         return _ss_waiting_set(o, ur, SS_OPCO_ACTIVATE);
2483 }
2484
2485 static TReturn imc_ss_waiting_deactivate(CoreObject *o, UserRequest *ur)
2486 {
2487         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2488                 dbg("cp not ready/n");
2489                 return TCORE_RETURN_ENOSYS;
2490         }
2491         return _ss_waiting_set(o, ur, SS_OPCO_DEACTIVATE);
2492 }
2493
2494 static TReturn imc_ss_waiting_get_status(CoreObject *o, UserRequest *ur)
2495 {
2496         struct treq_ss_waiting *waiting = 0;
2497
2498         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2499                 dbg("cp not ready/n");
2500                 return TCORE_RETURN_ENOSYS;
2501         }
2502         waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2503
2504         return _ss_waiting_get(o, ur, waiting->class, TRESP_SS_WAITING_GET_STATUS);
2505 }
2506
2507 static TReturn imc_ss_cli_activate(CoreObject *o, UserRequest *ur)
2508 {
2509         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2510                 dbg("cp not ready/n");
2511                 return TCORE_RETURN_ENOSYS;
2512         }
2513         return TCORE_RETURN_SUCCESS;
2514 }
2515
2516 static TReturn imc_ss_cli_deactivate(CoreObject *o, UserRequest *ur)
2517 {
2518         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2519                 dbg("cp not ready/n");
2520                 return TCORE_RETURN_ENOSYS;
2521         }
2522         return TCORE_RETURN_SUCCESS;
2523 }
2524
2525 static TReturn imc_ss_cli_get_status(CoreObject *o, UserRequest *ur)
2526 {
2527         struct treq_ss_cli *cli = 0;
2528         gboolean ret = FALSE;
2529         char *cmd_prefix = NULL, *rsp_prefix = NULL, *cmd_str = NULL;
2530         TcorePending *pending = NULL;
2531         TcoreATRequest *req;
2532
2533         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2534                 dbg("cp not ready/n");
2535                 return TCORE_RETURN_ENOSYS;
2536         }
2537
2538         cli = (struct treq_ss_cli *) tcore_user_request_ref_data(ur, 0);
2539         switch (cli->type) {
2540         case SS_CLI_TYPE_CLIP:
2541                 cmd_prefix = "+CLIP";
2542                 rsp_prefix = "+CLIP";
2543         break;
2544
2545         case SS_CLI_TYPE_CLIR:
2546                 cmd_prefix = "+CLIR";
2547                 rsp_prefix = "+CLIR";
2548         break;
2549
2550         case SS_CLI_TYPE_COLP:
2551                 cmd_prefix = "+COLP";
2552                 rsp_prefix = "+COLP";
2553         break;
2554
2555         case SS_CLI_TYPE_COLR:
2556                 cmd_prefix = "+COLR";
2557                 rsp_prefix = "+COLR";
2558         break;
2559
2560         case SS_CLI_TYPE_CNAP:
2561                 cmd_prefix = "+CNAP";
2562                 rsp_prefix = "+CNAP";
2563         break;
2564
2565         case SS_CLI_TYPE_CDIP:
2566         default:
2567                 dbg("unsupported cli_type : %d", cli->type);
2568                 return TCORE_RETURN_FAILURE;
2569         }
2570         dbg("cmd_prefix : %s", cmd_prefix);
2571
2572         cmd_str = g_strdup_printf("AT%s?", cmd_prefix);
2573         dbg("request cmd : %s", cmd_str);
2574
2575         pending = tcore_pending_new(o, 0);
2576
2577         req = tcore_at_request_new(cmd_str, rsp_prefix, TCORE_AT_SINGLELINE);
2578         if (req == NULL) {
2579                 tcore_pending_free(pending);
2580                 g_free(cmd_str);
2581                 return TCORE_RETURN_FAILURE;
2582         }
2583         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2584         tcore_pending_set_request_data(pending, 0, req);
2585
2586         ret = _ss_request_message(pending, o, ur, on_response_ss_cli_get, GINT_TO_POINTER(cli->type));
2587         g_free(cmd_str);
2588         if (!ret) {
2589                 dbg("AT request sent failed ");
2590                 tcore_pending_free(pending);
2591                 tcore_at_request_free(req);
2592                 return TCORE_RETURN_FAILURE;
2593         }
2594         return TCORE_RETURN_SUCCESS;
2595 }
2596
2597 static TReturn imc_ss_send_ussd(CoreObject *o, UserRequest *ur)
2598 {
2599         UssdSession *ussd_s = 0;
2600         struct treq_ss_ussd *ussd = 0;
2601         struct ss_confirm_info *user_data = 0;
2602         gboolean ret = FALSE;
2603         char *cmd_str;
2604         TcorePending *pending = NULL;
2605         TcoreATRequest *req;
2606
2607         dbg("function enter");
2608
2609         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2610                 dbg("cp not ready/n");
2611                 return TCORE_RETURN_ENOSYS;
2612         }
2613
2614         ussd = (struct treq_ss_ussd *) tcore_user_request_ref_data(ur, 0);
2615
2616         user_data = g_new0(struct ss_confirm_info, 1);
2617         if (!user_data) {
2618                 dbg("[ error ] failed to allocate memory");
2619                 return TCORE_RETURN_ENOMEM;
2620         }
2621         user_data->resp = TRESP_SS_SEND_USSD;
2622         ussd_s = tcore_ss_ussd_get_session(o);
2623         if (!ussd_s) {
2624                 dbg("USSD session does not  exist");
2625                 tcore_ss_ussd_create_session(o, (enum tcore_ss_ussd_type) ussd->type, (void *) tcore_user_request_ref(ur), 0);
2626         } else {
2627                 if (ussd->type == SS_USSD_TYPE_USER_INITIATED) {
2628                         dbg("[ error ] ussd session is already exist");
2629                         g_free(user_data);
2630                         return TCORE_RETURN_FAILURE;
2631                 }
2632
2633                 tcore_ss_ussd_set_session_type(ussd_s, (enum tcore_ss_ussd_type) ussd->type);
2634         }
2635
2636         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 */
2637         dbg("request command : %s", cmd_str);
2638
2639         pending = tcore_pending_new(o, 0);
2640         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2641         if (req == NULL) {
2642                 tcore_pending_free(pending);
2643                 g_free(cmd_str);
2644                 return TCORE_RETURN_FAILURE;
2645         }
2646         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2647
2648         tcore_pending_set_request_data(pending, 0, req);
2649
2650         ret = _ss_request_message(pending, o, ur, on_confirmation_ss_ussd, user_data);
2651         g_free(cmd_str);
2652
2653         if (!ret) {
2654                 dbg("AT request sent failed ");
2655                 if (user_data != NULL) {
2656                         g_free(user_data);
2657                         tcore_pending_free(pending);
2658                         tcore_at_request_free(req);
2659                 }
2660                 return TCORE_RETURN_FAILURE;
2661         }
2662         return TCORE_RETURN_SUCCESS;
2663 }
2664
2665 static TReturn imc_ss_set_aoc(CoreObject *o, UserRequest *ur)
2666 {
2667         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2668                 dbg("cp not ready/n");
2669                 return TCORE_RETURN_ENOSYS;
2670         }
2671
2672         dbg("[ error ] unsupported function");
2673         return TCORE_RETURN_SUCCESS;
2674 }
2675
2676 static TReturn imc_ss_get_aoc(CoreObject *o, UserRequest *ur)
2677 {
2678         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2679                 dbg("cp not ready/n");
2680                 return TCORE_RETURN_ENOSYS;
2681         }
2682
2683         dbg("[ error ] unsupported function");
2684         return TCORE_RETURN_SUCCESS;
2685 }
2686
2687
2688 static struct tcore_call_control_operations call_ops = {
2689         .answer_hold_and_accept = imc_ss_manage_call_2_send,
2690         .answer_replace = imc_ss_manage_call_1_send,
2691         .answer_reject = imc_ss_manage_call_0_send,
2692         .end_specific = imc_ss_manage_call_1x_send,
2693         .end_all_active = imc_ss_manage_call_1_send,
2694         .end_all_held = imc_ss_manage_call_0_send,
2695         .active = imc_ss_manage_call_2_send,
2696         .hold = imc_ss_manage_call_2_send,
2697         .swap = imc_ss_manage_call_2_send,
2698         .join = imc_ss_manage_call_3_send,
2699         .split = imc_ss_manage_call_2x_send,
2700         .transfer = imc_ss_manage_call_4_send,
2701         .deflect = imc_ss_manage_call_4dn_send,
2702 };
2703
2704 static TReturn imc_ss_manage_call_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
2705 {
2706         TcorePending *pending = NULL;
2707         TcoreATRequest *req;
2708         gboolean ret = FALSE;
2709
2710         pending = tcore_pending_new(o, 0);
2711         req = tcore_at_request_new(cmd, NULL, TCORE_AT_NO_RESULT);
2712         if (req == NULL) {
2713                 tcore_pending_free(pending);
2714                 return TCORE_RETURN_FAILURE;
2715         }
2716         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2717         tcore_pending_set_request_data(pending, 0, req);
2718
2719         ret = _ss_request_message(pending, o, ur, (TcorePendingResponseCallback) cb, user_data);
2720         if (!ret) {
2721                 dbg("AT request sent failed ");
2722                 return TCORE_RETURN_FAILURE;
2723         }
2724         return TCORE_RETURN_SUCCESS;
2725 }
2726
2727 static TReturn imc_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2728 {
2729         char *cmd_str = NULL;
2730         gboolean ret = FALSE;
2731
2732         dbg("function enter");
2733         cmd_str = g_strdup_printf("%s", "AT+CHLD=0");
2734         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2735
2736         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2737         g_free(cmd_str);
2738         return ret;
2739 }
2740
2741 static TReturn imc_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2742 {
2743         char *cmd_str = NULL;
2744         gboolean ret = FALSE;
2745
2746         dbg("function enter");
2747         cmd_str = g_strdup_printf("%s", "AT+CHLD=1");
2748         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2749
2750         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2751         g_free(cmd_str);
2752         return ret;
2753 }
2754
2755 static TReturn imc_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2756 {
2757         char *cmd_str = NULL;
2758         gboolean ret = FALSE;
2759
2760         dbg("function enter");
2761         cmd_str = g_strdup_printf("%s%d", "AT+CHLD=1", id);
2762         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2763
2764         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2765         g_free(cmd_str);
2766         return ret;
2767 }
2768
2769 static TReturn imc_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2770 {
2771         char *cmd_str = NULL;
2772         gboolean ret = FALSE;
2773
2774         dbg("function enter");
2775         cmd_str = g_strdup_printf("%s", "AT+CHLD=2");
2776         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2777
2778         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2779         g_free(cmd_str);
2780         return ret;
2781 }
2782
2783 static TReturn imc_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2784 {
2785         char *cmd_str = NULL;
2786         gboolean ret = FALSE;
2787
2788         dbg("function enter");
2789         cmd_str = g_strdup_printf("%s%d", "AT+CHLD=2", id);
2790         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2791
2792         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2793         g_free(cmd_str);
2794         return ret;
2795 }
2796
2797 static TReturn imc_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2798 {
2799         char *cmd_str = NULL;
2800         gboolean ret = FALSE;
2801
2802         dbg("function enter");
2803         cmd_str = g_strdup_printf("%s", "AT+CHLD=3");
2804
2805         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2806         g_free(cmd_str);
2807         return ret;
2808 }
2809
2810
2811 static TReturn imc_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2812 {
2813         char *cmd_str = NULL;
2814         gboolean ret = FALSE;
2815
2816         dbg("function enter");
2817         cmd_str = g_strdup_printf("%s", "AT+CHLD=4");
2818
2819         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2820         g_free(cmd_str);
2821         return ret;
2822 }
2823
2824 static TReturn imc_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data)
2825 {
2826         char *cmd_str = NULL;
2827         gboolean ret = FALSE;
2828
2829         dbg("function enter");
2830         cmd_str = g_strdup_printf("%s%s", "AT+CHLD=4", number);
2831
2832         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2833         g_free(cmd_str);
2834
2835         return ret;
2836 }
2837
2838 gboolean imc_ss_init(TcorePlugin *cp, CoreObject *co_ss)
2839 {
2840         CoreObject *co_call = NULL;
2841
2842         /* Set operations */
2843         tcore_ss_set_ops(co_ss, &ss_ops, TCORE_OPS_TYPE_CP);
2844
2845         co_call = tcore_plugin_ref_core_object(cp,
2846                                                 CORE_OBJECT_TYPE_CALL);
2847         if (co_call == NULL) {
2848                 err("Can't find CALL core object");
2849                 return FALSE;
2850         }
2851
2852         /* Set operations */
2853         tcore_call_control_set_operations(co_call, &call_ops);
2854
2855         tcore_object_add_callback(co_ss, "+CSSU", on_notification_ss_cssu_info, NULL);
2856         tcore_object_add_callback(co_ss, "+CSSI", on_notification_ss_cssi_info, NULL);
2857         tcore_object_add_callback(co_ss, "+CUSD", on_notification_ss_ussd, NULL);
2858
2859         return TRUE;
2860 }
2861
2862 void imc_ss_exit(TcorePlugin *cp, CoreObject *co_ss)
2863 {
2864         dbg("Exit");
2865
2866         tcore_object_del_callback(co_ss, "+CSSU", on_notification_ss_cssu_info);
2867         tcore_object_del_callback(co_ss, "+CSSI", on_notification_ss_cssi_info);
2868         tcore_object_del_callback(co_ss, "+CUSD", on_notification_ss_ussd);
2869 }