59ef8c9a2ae75e45c4b04ff963d696917a0a5782
[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 = NULL;
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 = (enum telephony_ss_cli_type *) (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         g_free(user_data);
1539 }
1540
1541 static struct tcore_ss_operations ss_ops = {
1542         .barring_activate = imc_ss_barring_activate,
1543         .barring_deactivate = imc_ss_barring_deactivate,
1544         .barring_change_password = imc_ss_barring_change_password,
1545         .barring_get_status = imc_ss_barring_get_status,
1546         .forwarding_activate = imc_ss_forwarding_activate,
1547         .forwarding_deactivate = imc_ss_forwarding_deactivate,
1548         .forwarding_register = imc_ss_forwarding_register,
1549         .forwarding_deregister = imc_ss_forwarding_deregister,
1550         .forwarding_get_status = imc_ss_forwarding_get_status,
1551         .waiting_activate = imc_ss_waiting_activate,
1552         .waiting_deactivate = imc_ss_waiting_deactivate,
1553         .waiting_get_status = imc_ss_waiting_get_status,
1554         .cli_activate = imc_ss_cli_activate,
1555         .cli_deactivate = imc_ss_cli_deactivate,
1556         .cli_get_status = imc_ss_cli_get_status,
1557         .send_ussd = imc_ss_send_ussd,
1558         .set_aoc = imc_ss_set_aoc,
1559         .get_aoc = imc_ss_get_aoc,
1560 };
1561
1562
1563 static TReturn _ss_barring_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1564 {
1565         struct treq_ss_barring *barring = 0;
1566         struct ss_confirm_info *user_data = 0;
1567         char *cmd_str = NULL;
1568         TcorePending *pending = NULL;
1569         TcoreATRequest *req;
1570         char passwd[MAX_SS_BARRING_PASSWORD_LEN + 1];
1571         int opco;
1572         int classx;
1573         char *facility = NULL;
1574         gboolean ret = FALSE;
1575
1576         dbg("function enter");
1577         barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1578
1579         switch (op) {
1580         case SS_OPCO_ACTIVATE:
1581                 opco = 1;
1582         break;
1583
1584         case SS_OPCO_DEACTIVATE:
1585                 opco = 0;
1586         break;
1587
1588         default:
1589                 dbg("unsupported opco : %d", op);
1590                 return TCORE_RETURN_FAILURE;
1591         }
1592         dbg("opco - %d", opco);
1593
1594         switch (barring->mode) {
1595         case SS_BARR_MODE_BAOC:
1596                 facility = "AO";
1597         break;
1598
1599         case SS_BARR_MODE_BOIC:
1600                 facility = "OI";
1601         break;
1602
1603         case SS_BARR_MODE_BOIC_NOT_HC:
1604                 facility = "OX";
1605         break;
1606
1607         case SS_BARR_MODE_BAIC:
1608                 facility = "AI";
1609         break;
1610
1611         case SS_BARR_MODE_BIC_ROAM:
1612                 facility = "IR";
1613         break;
1614
1615         case SS_BARR_MODE_AB:
1616                 facility = "AB";
1617         break;
1618
1619         case SS_BARR_MODE_AOB:
1620                 facility = "AG";
1621         break;
1622
1623         case SS_BARR_MODE_AIB:
1624                 facility = "AC";
1625         break;
1626
1627         case SS_BARR_MODE_BIC_NOT_SIM:
1628         /* facility = "NS"; */
1629         default:
1630                 dbg("unspported mode %d", barring->mode);
1631                 return TCORE_RETURN_FAILURE;
1632         }
1633
1634         dbg("facility - %s", facility);
1635
1636         switch (barring->class) {
1637         case SS_CLASS_ALL_TELE:
1638                 classx = 7;
1639                 break;
1640
1641         case SS_CLASS_VOICE:
1642                 classx = 1;
1643                 break;
1644
1645         case SS_CLASS_ALL_DATA_TELE:
1646                 classx = 2;
1647                 break;
1648
1649         case SS_CLASS_FAX:
1650                 classx = 4;
1651                 break;
1652
1653         case SS_CLASS_SMS:
1654                 classx = 8;
1655                 break;
1656
1657         case SS_CLASS_ALL_CS_SYNC:
1658                 classx = 16;
1659                 break;
1660
1661         default:
1662                 classx = 7;
1663                 dbg("unsupported class %d. set to default : 7", barring->class);
1664                 break;
1665         }
1666
1667         dbg("classx - %d", classx);
1668
1669         user_data = g_new0(struct ss_confirm_info, 1);
1670         if (!user_data) {
1671                 dbg("[ error ] failed to allocate memory");
1672                 return TCORE_RETURN_ENOMEM;
1673         }
1674
1675         /* null-ended pwd handling added - unexpected  0x11 value observed in req string */
1676         memcpy(passwd, barring->password, MAX_SS_BARRING_PASSWORD_LEN);
1677         passwd[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1678         dbg("passwd - %s", passwd);
1679
1680         pending = tcore_pending_new(o, 0);
1681
1682         cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d", facility, opco, passwd, classx);
1683         dbg("request command : %s", cmd_str);
1684
1685         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1686         if (req == NULL) {
1687                 tcore_pending_free(pending);
1688                 g_free(cmd_str);
1689                 return TCORE_RETURN_FAILURE;
1690         }
1691         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1692
1693         tcore_pending_set_request_data(pending, 0, req);
1694
1695         if (op == SS_OPCO_ACTIVATE) {
1696                 user_data->resp = TRESP_SS_BARRING_ACTIVATE;
1697         } else if (op == SS_OPCO_DEACTIVATE) {
1698                 user_data->resp = TRESP_SS_BARRING_DEACTIVATE;
1699         } else {
1700                 dbg("[ error ] wrong ss opco (0x%x)", op);
1701                 if (user_data != NULL)
1702                         g_free(user_data);
1703
1704                 g_free(cmd_str);
1705                 tcore_pending_free(pending);
1706                 tcore_at_request_free(req);
1707                 return TCORE_RETURN_FAILURE;
1708         }
1709         user_data->flavor_type = (int) (barring->mode);
1710         user_data->class = barring->class;
1711
1712         ret = _ss_request_message(pending, o, ur, on_response_ss_barring_set, user_data);
1713         g_free(cmd_str);
1714
1715         if (!ret) {
1716                 dbg("AT request sent failed ");
1717                 if (user_data != NULL) {
1718                         g_free(user_data);
1719                         tcore_pending_free(pending);
1720                         tcore_at_request_free(req);
1721                 }
1722                 return TCORE_RETURN_FAILURE;
1723         }
1724         return TCORE_RETURN_SUCCESS;
1725 }
1726
1727 static TReturn _ss_barring_get(CoreObject *o,
1728                                                            UserRequest *ur,
1729                                                            enum telephony_ss_class class,
1730                                                            enum telephony_ss_barring_mode mode,
1731                                                            enum tcore_response_command resp)
1732 {
1733         struct ss_confirm_info *user_data = 0;
1734         gboolean ret = FALSE;
1735         char *cmd_str = NULL;
1736         int opco, classx;
1737         char *facility = NULL;
1738         TcorePending *pending = NULL;
1739         TcoreATRequest *req;
1740
1741         dbg("function enter");
1742
1743         /* query status - opco is fixed to 2 */
1744         opco = 2;
1745         /* barring mode */
1746         switch (mode) {
1747         case SS_BARR_MODE_BAOC:
1748                 facility = "AO";
1749                 break;
1750
1751         case SS_BARR_MODE_BOIC:
1752                 facility = "OI";
1753                 break;
1754
1755         case SS_BARR_MODE_BOIC_NOT_HC:
1756                 facility = "OX";
1757                 break;
1758
1759         case SS_BARR_MODE_BAIC:
1760                 facility = "AI";
1761                 break;
1762
1763         case SS_BARR_MODE_BIC_ROAM:
1764                 facility = "IR";
1765                 break;
1766
1767         case SS_BARR_MODE_AB:
1768         case SS_BARR_MODE_AOB:
1769         case SS_BARR_MODE_AIB:
1770         case SS_BARR_MODE_BIC_NOT_SIM:
1771         default:
1772                 dbg("unsupported mode %d", mode);
1773                 return TCORE_RETURN_FAILURE;
1774         }
1775
1776         dbg("facility - %s", facility);
1777
1778         switch (class) {
1779         case SS_CLASS_ALL_TELE:
1780                 classx = 7;
1781                 break;
1782
1783         case SS_CLASS_VOICE:
1784                 classx = 1;
1785                 break;
1786
1787         case SS_CLASS_ALL_DATA_TELE:
1788                 classx = 2;
1789                 break;
1790
1791         case SS_CLASS_FAX:
1792                 classx = 4;
1793                 break;
1794
1795         case SS_CLASS_SMS:
1796                 classx = 8;
1797                 break;
1798
1799         case SS_CLASS_ALL_CS_SYNC:
1800                 classx = 16;
1801                 break;
1802
1803         default:
1804                 classx = 7;
1805                 dbg("unsupported class %d. set to default : 7", class);
1806                 break;
1807         }
1808
1809         user_data = g_new0(struct ss_confirm_info, 1);
1810         if (!user_data) {
1811                 dbg("[ error ] failed to allocate memory");
1812                 return TCORE_RETURN_ENOMEM;
1813         }
1814
1815         dbg("class - %d", classx);
1816         if (classx == 7)
1817                 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d", facility, opco);
1818         else
1819                 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d", facility, opco, classx);
1820
1821         dbg("request command : %s", cmd_str);
1822
1823         pending = tcore_pending_new(o, 0);
1824         req = tcore_at_request_new(cmd_str, "+CLCK", TCORE_AT_MULTILINE);
1825         if (req == NULL) {
1826                 tcore_pending_free(pending);
1827                 g_free(cmd_str);
1828                 return TCORE_RETURN_FAILURE;
1829         }
1830         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1831
1832         tcore_pending_set_request_data(pending, 0, req);
1833
1834         user_data->resp = resp;
1835         user_data->flavor_type = (int) (mode);
1836         user_data->class = class;
1837
1838         ret = _ss_request_message(pending, o, ur, on_response_ss_barring_get, user_data);
1839         g_free(cmd_str);
1840
1841         if (!ret) {
1842                 dbg("AT request sent failed ");
1843                 if (user_data != NULL) {
1844                         g_free(user_data);
1845                         tcore_pending_free(pending);
1846                         tcore_at_request_free(req);
1847                 }
1848                 return TCORE_RETURN_FAILURE;
1849         }
1850
1851         return TCORE_RETURN_SUCCESS;
1852 }
1853
1854 static TReturn imc_ss_barring_activate(CoreObject *o, UserRequest *ur)
1855 {
1856         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
1857                 dbg("cp not ready/n");
1858                 return TCORE_RETURN_ENOSYS;
1859         }
1860         return _ss_barring_set(o, ur, SS_OPCO_ACTIVATE);
1861 }
1862
1863 static TReturn imc_ss_barring_deactivate(CoreObject *o, UserRequest *ur)
1864 {
1865         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
1866                 dbg("cp not ready/n");
1867                 return TCORE_RETURN_ENOSYS;
1868         }
1869         return _ss_barring_set(o, ur, SS_OPCO_DEACTIVATE);
1870 }
1871
1872 static TReturn imc_ss_barring_change_password(CoreObject *o, UserRequest *ur)
1873 {
1874         TcorePending *pending = NULL;
1875         TcoreATRequest *req;
1876         struct treq_ss_barring_change_password *barring = 0;
1877         struct ss_confirm_info *user_data = 0;
1878         char *cmd_str = NULL;
1879         gboolean ret = FALSE;
1880         char old_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1881         char new_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1882
1883         dbg("function enter");
1884
1885         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
1886                 dbg("cp not ready/n");
1887                 return TCORE_RETURN_ENOSYS;
1888         }
1889
1890         barring = (struct treq_ss_barring_change_password *) tcore_user_request_ref_data(ur, 0);
1891
1892         memcpy(old_password, barring->password_old, MAX_SS_BARRING_PASSWORD_LEN);
1893         old_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1894         memcpy(new_password, barring->password_new, MAX_SS_BARRING_PASSWORD_LEN);
1895         new_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1896
1897         user_data = g_new0(struct ss_confirm_info, 1);
1898         if (!user_data) {
1899                 dbg("[ error ] failed to allocate memory");
1900                 return TCORE_RETURN_ENOMEM;
1901         }
1902         user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
1903
1904         dbg("old passwd - %s new passwd- %s", old_password, new_password);
1905         cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB", old_password, new_password);
1906         dbg("request command : %s", cmd_str);
1907
1908         pending = tcore_pending_new(o, 0);
1909         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1910         if (req == NULL) {
1911                 tcore_pending_free(pending);
1912                 g_free(cmd_str);
1913                 return TCORE_RETURN_FAILURE;
1914         }
1915         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1916
1917         tcore_pending_set_request_data(pending, 0, req);
1918
1919         ret = _ss_request_message(pending, o, ur, on_response_ss_barring_change_pwd, user_data);
1920         g_free(cmd_str);
1921         if (!ret) {
1922                 dbg("AT request sent failed ");
1923                 if (user_data != NULL)
1924                         g_free(user_data);
1925
1926                 tcore_pending_free(pending);
1927                 tcore_at_request_free(req);
1928                 return TCORE_RETURN_FAILURE;
1929         }
1930         return TCORE_RETURN_SUCCESS;
1931 }
1932
1933 static TReturn imc_ss_barring_get_status(CoreObject *o, UserRequest *ur)
1934 {
1935         struct treq_ss_barring *barring = 0;
1936
1937         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
1938                 dbg("cp not ready/n");
1939                 return TCORE_RETURN_ENOSYS;
1940         }
1941         barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1942
1943         return _ss_barring_get(o, ur, barring->class, barring->mode, TRESP_SS_BARRING_GET_STATUS);
1944 }
1945
1946 static TReturn _ss_forwarding_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1947 {
1948         struct treq_ss_forwarding *forwarding = 0;
1949         struct ss_confirm_info *user_data = 0;
1950         gboolean ret = FALSE;
1951         int len = 0;
1952         char *cmd_str = NULL;
1953         char *tmp_str = NULL;
1954         int reason = 0, mode = 0, num_type = 0, classx = 0, time = 0;
1955         TcorePending *pending = NULL;
1956         TcoreATRequest *req;
1957
1958         dbg("_ss_forwarding_set with opco %d ", op);
1959
1960         forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
1961         switch (forwarding->mode) {
1962         case SS_CF_MODE_CFU:
1963                 reason = 0;
1964                 break;
1965
1966         case SS_CF_MODE_CFB:
1967                 reason = 1;
1968                 break;
1969
1970         case SS_CF_MODE_CFNRy:
1971                 reason = 2;
1972                 break;
1973
1974         case SS_CF_MODE_CFNRc:
1975                 reason = 3;
1976                 break;
1977
1978         case SS_CF_MODE_CF_ALL:
1979                 reason = 4;
1980                 break;
1981
1982         case SS_CF_MODE_CFC:
1983                 reason = 5;
1984                 break;
1985
1986         default:
1987                 dbg("unsupported reason : %d");
1988                 return TCORE_RETURN_FAILURE;
1989                 break;
1990         }
1991
1992         dbg("reason = %d", reason);
1993         switch (op) {
1994         case SS_OPCO_DEACTIVATE:
1995                 mode = 0;
1996                 break;
1997
1998         case SS_OPCO_ACTIVATE:
1999                 mode = 1;
2000                 break;
2001
2002         case SS_OPCO_REG:
2003                 mode = 3;
2004                 break;
2005
2006         case SS_OPCO_DEREG:
2007                 mode = 4;
2008                 break;
2009
2010         default:
2011                 dbg("unsupported opco : %d", op);
2012                 return TCORE_RETURN_FAILURE;
2013         }
2014
2015         dbg("mode = %d", mode);
2016
2017         /* class */
2018         switch (forwarding->class) {
2019         case SS_CLASS_ALL_TELE:
2020                 classx = 7;
2021                 break;
2022
2023         case SS_CLASS_VOICE:
2024                 classx = 1;
2025                 break;
2026
2027         case SS_CLASS_ALL_DATA_TELE:
2028                 classx = 2;
2029                 break;
2030
2031         case SS_CLASS_FAX:
2032                 classx = 4;
2033                 break;
2034
2035         case SS_CLASS_SMS:
2036                 classx = 8;
2037                 break;
2038
2039         case SS_CLASS_ALL_CS_SYNC:
2040                 classx = 16;
2041                 break;
2042
2043         default:
2044                 classx = 7;
2045                 dbg("unsupported class %d. set to default : 7", forwarding->class);
2046                 break;
2047         }
2048         dbg("classx = %d", classx);
2049
2050         /* number */
2051         len = strlen(forwarding->number);
2052         if (len > 0) {
2053                 if (forwarding->number[0] == '+')
2054                         num_type = ((NUM_TYPE_INTERNATIONAL << 4) | NUM_PLAN_ISDN);
2055                 else
2056                         num_type = 0;
2057         }
2058         dbg("number = %s", forwarding->number);
2059
2060         user_data = g_new0(struct ss_confirm_info, 1);
2061         if (!user_data) {
2062                 dbg("[ error ] failed to allocate memory");
2063                 return TCORE_RETURN_ENOMEM;
2064         }
2065
2066         switch (op) {
2067         case SS_OPCO_REG:
2068                 user_data->resp = TRESP_SS_FORWARDING_REGISTER;
2069                 break;
2070
2071         case SS_OPCO_DEREG:
2072                 user_data->resp = TRESP_SS_FORWARDING_DEREGISTER;
2073                 break;
2074
2075         case SS_OPCO_ACTIVATE:
2076                 user_data->resp = TRESP_SS_FORWARDING_ACTIVATE;
2077                 break;
2078
2079         case SS_OPCO_DEACTIVATE:
2080                 user_data->resp = TRESP_SS_FORWARDING_DEACTIVATE;
2081                 break;
2082
2083         default:
2084                 dbg("[ error ] unknown op (0x%x)", op);
2085                 break;
2086         }
2087
2088         if (forwarding->number[0] == '+')
2089                 num_type = 145;
2090         else
2091                 num_type = 129;
2092
2093         if (op == SS_OPCO_REG)
2094                 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,\"%s\",%d,%d", reason, mode, forwarding->number, num_type, classx);
2095         else /* other opcode does not need num field */
2096                 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2097
2098         if (forwarding->mode == SS_CF_MODE_CFNRy) {
2099                 /* add time info to 'no reply' case */
2100                 time = (int) (forwarding->time);
2101                 cmd_str = g_strdup_printf("%s,,,%d", tmp_str, time);
2102         } else {
2103                 cmd_str = g_strdup_printf("%s", tmp_str);
2104         }
2105
2106         dbg("request command : %s", cmd_str);
2107         pending = tcore_pending_new(o, 0);
2108         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2109         if (req == NULL) {
2110                 tcore_pending_free(pending);
2111                 g_free(cmd_str);
2112                 g_free(tmp_str);
2113                 return TCORE_RETURN_FAILURE;
2114         }
2115         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2116
2117         tcore_pending_set_request_data(pending, 0, req);
2118
2119         user_data->flavor_type = forwarding->mode;
2120         user_data->class = forwarding->class;
2121
2122         ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_set, user_data);
2123
2124         g_free(tmp_str);
2125         g_free(cmd_str);
2126
2127         if (!ret) {
2128                 dbg("AT request sent failed ");
2129                 if (user_data != NULL)
2130                         g_free(user_data);
2131
2132                 return TCORE_RETURN_FAILURE;
2133         }
2134
2135         return TCORE_RETURN_SUCCESS;
2136 }
2137
2138 static TReturn _ss_forwarding_get(CoreObject *o,
2139           UserRequest *ur,
2140           enum telephony_ss_class class,
2141           enum telephony_ss_forwarding_mode type,
2142           enum tcore_response_command resp)
2143 {
2144         struct ss_confirm_info *user_data = 0;
2145         gboolean ret = FALSE;
2146         char *cmd_str = NULL;
2147         int reason = 0, mode = 0, classx = 0;
2148         TcorePending *pending = NULL;
2149         TcoreATRequest *req;
2150
2151         dbg("function enter");
2152
2153         switch (type) {
2154         case SS_CF_MODE_CFU:
2155                 reason = 0;
2156         break;
2157
2158         case SS_CF_MODE_CFB:
2159                 reason = 1;
2160         break;
2161
2162         case SS_CF_MODE_CFNRy:
2163                 reason = 2;
2164         break;
2165
2166         case SS_CF_MODE_CFNRc:
2167                 reason = 3;
2168         break;
2169
2170         case SS_CF_MODE_CF_ALL:
2171                 reason = 4;
2172         break;
2173
2174         case SS_CF_MODE_CFC:
2175                 reason = 5;
2176         break;
2177
2178         default:
2179                 dbg("unsupported reason : %d");
2180         break;
2181         }
2182         dbg("reason  = %d", reason);
2183
2184         switch (class) {
2185         case SS_CLASS_ALL_TELE:
2186                 classx = 7;
2187         break;
2188
2189         case SS_CLASS_VOICE:
2190                 classx = 1;
2191         break;
2192
2193         case SS_CLASS_ALL_DATA_TELE:
2194                 classx = 2;
2195         break;
2196
2197         case SS_CLASS_FAX:
2198                 classx = 4;
2199         break;
2200
2201         case SS_CLASS_SMS:
2202                 classx = 8;
2203         break;
2204
2205         case SS_CLASS_ALL_CS_SYNC:
2206                 classx = 16;
2207         break;
2208
2209         default:
2210                 classx = 7;
2211                 dbg("unsupported class %d. set to default : 7", class);
2212         break;
2213         }
2214
2215         dbg("classx  = %d", classx);
2216
2217         /* query status - mode set to 2 */
2218         mode = 2;
2219         user_data = g_new0(struct ss_confirm_info, 1);
2220         if (!user_data) {
2221                 dbg("[ error ] failed to allocate memory");
2222                 return TCORE_RETURN_ENOMEM;
2223         }
2224         user_data->resp = resp;
2225         user_data->class = class;
2226         user_data->flavor_type = type;
2227
2228         if (classx == 7)
2229                 cmd_str = g_strdup_printf("AT+CCFC=%d,%d", reason, mode);
2230         else
2231                 cmd_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2232
2233         dbg("request command : %s", cmd_str);
2234
2235         pending = tcore_pending_new(o, 0);
2236         req = tcore_at_request_new(cmd_str, "+CCFC", TCORE_AT_MULTILINE);
2237         if (req == NULL) {
2238                 tcore_pending_free(pending);
2239                 g_free(cmd_str);
2240                 return TCORE_RETURN_FAILURE;
2241         }
2242         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2243
2244         tcore_pending_set_request_data(pending, 0, req);
2245
2246         ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_get, user_data);
2247         g_free(cmd_str);
2248
2249         if (!ret) {
2250                 dbg("AT request sent failed ");
2251                 if (user_data != NULL) {
2252                         g_free(user_data);
2253                         tcore_pending_free(pending);
2254                         tcore_at_request_free(req);
2255                 }
2256                 return TCORE_RETURN_FAILURE;
2257         }
2258
2259         return TCORE_RETURN_SUCCESS;
2260 }
2261
2262 static TReturn imc_ss_forwarding_activate(CoreObject *o, UserRequest *ur)
2263 {
2264         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2265                 dbg("cp not ready/n");
2266                 return TCORE_RETURN_ENOSYS;
2267         }
2268         return _ss_forwarding_set(o, ur, SS_OPCO_ACTIVATE);
2269 }
2270
2271 static TReturn imc_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur)
2272 {
2273         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2274                 dbg("cp not ready/n");
2275                 return TCORE_RETURN_ENOSYS;
2276         }
2277         return _ss_forwarding_set(o, ur, SS_OPCO_DEACTIVATE);
2278 }
2279
2280 static TReturn imc_ss_forwarding_register(CoreObject *o, UserRequest *ur)
2281 {
2282         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2283                 dbg("cp not ready/n");
2284                 return TCORE_RETURN_ENOSYS;
2285         }
2286         return _ss_forwarding_set(o, ur, SS_OPCO_REG);
2287 }
2288
2289 static TReturn imc_ss_forwarding_deregister(CoreObject *o, UserRequest *ur)
2290 {
2291         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2292                 dbg("cp not ready/n");
2293                 return TCORE_RETURN_ENOSYS;
2294         }
2295         return _ss_forwarding_set(o, ur, SS_OPCO_DEREG);
2296 }
2297
2298 static TReturn imc_ss_forwarding_get_status(CoreObject *o, UserRequest *ur)
2299 {
2300         struct treq_ss_forwarding *forwarding = 0;
2301
2302         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2303                 dbg("cp not ready/n");
2304                 return TCORE_RETURN_ENOSYS;
2305         }
2306
2307         forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
2308
2309         return _ss_forwarding_get(o, ur, forwarding->class, forwarding->mode, TRESP_SS_FORWARDING_GET_STATUS);
2310 }
2311
2312
2313 static TReturn _ss_waiting_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode opco)
2314 {
2315         struct treq_ss_waiting *waiting = 0;
2316         struct ss_confirm_info *user_data = 0;
2317         gboolean ret = FALSE;
2318         int mode = 0, classx = 0;
2319         char *cmd_str;
2320         TcorePending *pending = NULL;
2321         TcoreATRequest *req;
2322
2323         dbg("function enter ");
2324         waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2325         user_data = g_new0(struct ss_confirm_info, 1);
2326         if (!user_data) {
2327                 dbg("[ error ] failed to allocate memory");
2328                 return TCORE_RETURN_ENOMEM;
2329         }
2330
2331         if (opco == SS_OPCO_ACTIVATE) {
2332                 user_data->resp = TRESP_SS_WAITING_ACTIVATE;
2333                 mode = 1; /* enable */
2334         } else if (opco == SS_OPCO_DEACTIVATE) {
2335                 user_data->resp = TRESP_SS_WAITING_DEACTIVATE;
2336                 mode = 0; /* disable */
2337         } else
2338                 dbg("[ error ] unknown ss mode (0x%x)", opco);
2339
2340         switch (waiting->class) {
2341         case SS_CLASS_ALL_TELE:
2342                 classx = 7;
2343                 break;
2344
2345         case SS_CLASS_VOICE:
2346                 classx = 1;
2347                 break;
2348
2349         case SS_CLASS_ALL_DATA_TELE:
2350                 classx = 2;
2351                 break;
2352
2353         case SS_CLASS_FAX:
2354                 classx = 4;
2355                 break;
2356
2357         case SS_CLASS_SMS:
2358                 classx = 8;
2359                 break;
2360
2361         default:
2362                 classx = 1;
2363                 dbg("unsupported class %d. set to default : 1", waiting->class);
2364                 break;
2365         }
2366         dbg("mode = %d classxx- %d", mode, classx);
2367
2368         user_data->class = waiting->class;
2369         user_data->flavor_type = (int) opco;
2370
2371         cmd_str = g_strdup_printf("AT+CCWA=1,%d,%d", mode, classx); /* always enable +CCWA: unsolicited cmd */
2372         dbg("request command : %s", cmd_str);
2373
2374         pending = tcore_pending_new(o, 0);
2375         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2376         if (req == NULL) {
2377                 tcore_pending_free(pending);
2378                 g_free(cmd_str);
2379                 return TCORE_RETURN_FAILURE;
2380         }
2381         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2382
2383         tcore_pending_set_request_data(pending, 0, req);
2384
2385         ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_set, user_data);
2386         g_free(cmd_str);
2387         if (!ret) {
2388                 dbg("AT request sent failed ");
2389                 if (user_data != NULL) {
2390                         g_free(user_data);
2391                         tcore_pending_free(pending);
2392                         tcore_at_request_free(req);
2393                 }
2394                 return TCORE_RETURN_FAILURE;
2395         }
2396         return TCORE_RETURN_SUCCESS;
2397 }
2398
2399 static TReturn _ss_waiting_get(CoreObject *o,
2400            UserRequest *ur,
2401            enum telephony_ss_class class,
2402            enum tcore_response_command resp)
2403 {
2404         struct ss_confirm_info *user_data = 0;
2405         gboolean ret = FALSE;
2406         int classx; /* mode, */
2407         char *cmd_str;
2408         TcorePending *pending = NULL;
2409         TcoreATRequest *req;
2410
2411         dbg("function  enter");
2412         switch (class) {
2413         case SS_CLASS_ALL_TELE:
2414                 classx = 7;
2415         break;
2416
2417         case SS_CLASS_VOICE:
2418                 classx = 1;
2419         break;
2420
2421         case SS_CLASS_ALL_DATA_TELE:
2422                 classx = 2;
2423         break;
2424
2425         case SS_CLASS_FAX:
2426                 classx = 4;
2427         break;
2428
2429         case SS_CLASS_SMS:
2430                 classx = 8;
2431         break;
2432
2433         default:
2434                 classx = 7;
2435                 dbg("unsupported class %d. set to default : 7", class);
2436         break;
2437         }
2438         dbg("classx - %d", classx);
2439
2440         dbg("allocating user data");
2441         user_data = g_new0(struct ss_confirm_info, 1);
2442         if (!user_data) {
2443                 dbg("[ error ] failed to allocate memory");
2444                 return TCORE_RETURN_ENOMEM;
2445         }
2446         user_data->resp = resp;
2447         user_data->class = class;
2448
2449         cmd_str = g_strdup_printf("AT+CCWA=1,2,%d", classx); /* always enable +CCWA: unsolicited cmd , mode is fixed to 2(query status) */
2450         dbg("request cmd : %s", cmd_str);
2451
2452         pending = tcore_pending_new(o, 0);
2453         req = tcore_at_request_new(cmd_str, "+CCWA", TCORE_AT_MULTILINE);
2454         if (req == NULL) {
2455                 err("Request is NULL");
2456                 g_free(cmd_str);
2457                 tcore_pending_free(pending);
2458                 return TCORE_RETURN_EINVAL;
2459         }
2460         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2461
2462         tcore_pending_set_request_data(pending, 0, req);
2463
2464         ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_get, user_data);
2465         g_free(cmd_str);
2466         if (!ret) {
2467                 dbg("AT request sent failed ");
2468                 if (user_data != NULL) {
2469                         g_free(user_data);
2470                         tcore_pending_free(pending);
2471                         tcore_at_request_free(req);
2472                 }
2473                 return TCORE_RETURN_FAILURE;
2474         }
2475         return TCORE_RETURN_SUCCESS;
2476 }
2477
2478 static TReturn imc_ss_waiting_activate(CoreObject *o, UserRequest *ur)
2479 {
2480         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2481                 dbg("cp not ready/n");
2482                 return TCORE_RETURN_ENOSYS;
2483         }
2484         return _ss_waiting_set(o, ur, SS_OPCO_ACTIVATE);
2485 }
2486
2487 static TReturn imc_ss_waiting_deactivate(CoreObject *o, UserRequest *ur)
2488 {
2489         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2490                 dbg("cp not ready/n");
2491                 return TCORE_RETURN_ENOSYS;
2492         }
2493         return _ss_waiting_set(o, ur, SS_OPCO_DEACTIVATE);
2494 }
2495
2496 static TReturn imc_ss_waiting_get_status(CoreObject *o, UserRequest *ur)
2497 {
2498         struct treq_ss_waiting *waiting = 0;
2499
2500         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2501                 dbg("cp not ready/n");
2502                 return TCORE_RETURN_ENOSYS;
2503         }
2504         waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2505
2506         return _ss_waiting_get(o, ur, waiting->class, TRESP_SS_WAITING_GET_STATUS);
2507 }
2508
2509 static TReturn imc_ss_cli_activate(CoreObject *o, UserRequest *ur)
2510 {
2511         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2512                 dbg("cp not ready/n");
2513                 return TCORE_RETURN_ENOSYS;
2514         }
2515         return TCORE_RETURN_SUCCESS;
2516 }
2517
2518 static TReturn imc_ss_cli_deactivate(CoreObject *o, UserRequest *ur)
2519 {
2520         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2521                 dbg("cp not ready/n");
2522                 return TCORE_RETURN_ENOSYS;
2523         }
2524         return TCORE_RETURN_SUCCESS;
2525 }
2526
2527 static TReturn imc_ss_cli_get_status(CoreObject *o, UserRequest *ur)
2528 {
2529         struct treq_ss_cli *cli = 0;
2530         gboolean ret = FALSE;
2531         char *cmd_prefix = NULL, *rsp_prefix = NULL, *cmd_str = NULL;
2532         enum  telephony_ss_cli_type *user_data = 0;
2533         TcorePending *pending = NULL;
2534         TcoreATRequest *req;
2535
2536         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2537                 dbg("cp not ready/n");
2538                 return TCORE_RETURN_ENOSYS;
2539         }
2540
2541         cli = (struct treq_ss_cli *) tcore_user_request_ref_data(ur, 0);
2542         switch (cli->type) {
2543         case SS_CLI_TYPE_CLIP:
2544                 cmd_prefix = "+CLIP";
2545                 rsp_prefix = "+CLIP";
2546         break;
2547
2548         case SS_CLI_TYPE_CLIR:
2549                 cmd_prefix = "+CLIR";
2550                 rsp_prefix = "+CLIR";
2551         break;
2552
2553         case SS_CLI_TYPE_COLP:
2554                 cmd_prefix = "+COLP";
2555                 rsp_prefix = "+COLP";
2556         break;
2557
2558         case SS_CLI_TYPE_COLR:
2559                 cmd_prefix = "+COLR";
2560                 rsp_prefix = "+COLR";
2561         break;
2562
2563         case SS_CLI_TYPE_CNAP:
2564                 cmd_prefix = "+CNAP";
2565                 rsp_prefix = "+CNAP";
2566         break;
2567
2568         case SS_CLI_TYPE_CDIP:
2569         default:
2570                 dbg("unsupported cli_type : %d", cli->type);
2571                 return TCORE_RETURN_FAILURE;
2572         }
2573         dbg("cmd_prefix : %s", cmd_prefix);
2574
2575         cmd_str = g_strdup_printf("AT%s?", cmd_prefix);
2576         dbg("request cmd : %s", cmd_str);
2577
2578         user_data = g_new0(enum telephony_ss_cli_type, 1);
2579         if (!user_data) {
2580                 dbg("[ error ] failed to allocate memory");
2581                 g_free(cmd_str);
2582                 return TCORE_RETURN_ENOMEM;
2583         }
2584         *user_data = cli->type;
2585
2586         pending = tcore_pending_new(o, 0);
2587
2588         req = tcore_at_request_new(cmd_str, rsp_prefix, TCORE_AT_SINGLELINE);
2589         if (req == NULL) {
2590                 tcore_pending_free(pending);
2591                 g_free(cmd_str);
2592                 return TCORE_RETURN_FAILURE;
2593         }
2594         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2595         tcore_pending_set_request_data(pending, 0, req);
2596
2597         ret = _ss_request_message(pending, o, ur, on_response_ss_cli_get, user_data);
2598         g_free(cmd_str);
2599         if (!ret) {
2600                 dbg("AT request sent failed ");
2601                 if (user_data != NULL) {
2602                         g_free(user_data);
2603                         tcore_pending_free(pending);
2604                         tcore_at_request_free(req);
2605                 }
2606                 return TCORE_RETURN_FAILURE;
2607         }
2608         return TCORE_RETURN_SUCCESS;
2609 }
2610
2611 static TReturn imc_ss_send_ussd(CoreObject *o, UserRequest *ur)
2612 {
2613         UssdSession *ussd_s = 0;
2614         struct treq_ss_ussd *ussd = 0;
2615         struct ss_confirm_info *user_data = 0;
2616         gboolean ret = FALSE;
2617         char *cmd_str;
2618         TcorePending *pending = NULL;
2619         TcoreATRequest *req;
2620
2621         dbg("function enter");
2622
2623         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2624                 dbg("cp not ready/n");
2625                 return TCORE_RETURN_ENOSYS;
2626         }
2627
2628         ussd = (struct treq_ss_ussd *) tcore_user_request_ref_data(ur, 0);
2629
2630         user_data = g_new0(struct ss_confirm_info, 1);
2631         if (!user_data) {
2632                 dbg("[ error ] failed to allocate memory");
2633                 return TCORE_RETURN_ENOMEM;
2634         }
2635         user_data->resp = TRESP_SS_SEND_USSD;
2636         ussd_s = tcore_ss_ussd_get_session(o);
2637         if (!ussd_s) {
2638                 dbg("USSD session does not  exist");
2639                 tcore_ss_ussd_create_session(o, (enum tcore_ss_ussd_type) ussd->type, (void *) tcore_user_request_ref(ur), 0);
2640         } else {
2641                 if (ussd->type == SS_USSD_TYPE_USER_INITIATED) {
2642                         dbg("[ error ] ussd session is already exist");
2643                         g_free(user_data);
2644                         return TCORE_RETURN_FAILURE;
2645                 }
2646
2647                 tcore_ss_ussd_set_session_type(ussd_s, (enum tcore_ss_ussd_type) ussd->type);
2648         }
2649
2650         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 */
2651         dbg("request command : %s", cmd_str);
2652
2653         pending = tcore_pending_new(o, 0);
2654         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2655         if (req == NULL) {
2656                 tcore_pending_free(pending);
2657                 g_free(cmd_str);
2658                 return TCORE_RETURN_FAILURE;
2659         }
2660         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2661
2662         tcore_pending_set_request_data(pending, 0, req);
2663
2664         ret = _ss_request_message(pending, o, ur, on_confirmation_ss_ussd, user_data);
2665         g_free(cmd_str);
2666
2667         if (!ret) {
2668                 dbg("AT request sent failed ");
2669                 if (user_data != NULL) {
2670                         g_free(user_data);
2671                         tcore_pending_free(pending);
2672                         tcore_at_request_free(req);
2673                 }
2674                 return TCORE_RETURN_FAILURE;
2675         }
2676         return TCORE_RETURN_SUCCESS;
2677 }
2678
2679 static TReturn imc_ss_set_aoc(CoreObject *o, UserRequest *ur)
2680 {
2681         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2682                 dbg("cp not ready/n");
2683                 return TCORE_RETURN_ENOSYS;
2684         }
2685
2686         dbg("[ error ] unsupported function");
2687         return TCORE_RETURN_SUCCESS;
2688 }
2689
2690 static TReturn imc_ss_get_aoc(CoreObject *o, UserRequest *ur)
2691 {
2692         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2693                 dbg("cp not ready/n");
2694                 return TCORE_RETURN_ENOSYS;
2695         }
2696
2697         dbg("[ error ] unsupported function");
2698         return TCORE_RETURN_SUCCESS;
2699 }
2700
2701
2702 static struct tcore_call_control_operations call_ops = {
2703         .answer_hold_and_accept = imc_ss_manage_call_2_send,
2704         .answer_replace = imc_ss_manage_call_1_send,
2705         .answer_reject = imc_ss_manage_call_0_send,
2706         .end_specific = imc_ss_manage_call_1x_send,
2707         .end_all_active = imc_ss_manage_call_1_send,
2708         .end_all_held = imc_ss_manage_call_0_send,
2709         .active = imc_ss_manage_call_2_send,
2710         .hold = imc_ss_manage_call_2_send,
2711         .swap = imc_ss_manage_call_2_send,
2712         .join = imc_ss_manage_call_3_send,
2713         .split = imc_ss_manage_call_2x_send,
2714         .transfer = imc_ss_manage_call_4_send,
2715         .deflect = imc_ss_manage_call_4dn_send,
2716 };
2717
2718 static TReturn imc_ss_manage_call_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
2719 {
2720         TcorePending *pending = NULL;
2721         TcoreATRequest *req;
2722         gboolean ret = FALSE;
2723
2724         pending = tcore_pending_new(o, 0);
2725         req = tcore_at_request_new(cmd, NULL, TCORE_AT_NO_RESULT);
2726         if (req == NULL) {
2727                 tcore_pending_free(pending);
2728                 return TCORE_RETURN_FAILURE;
2729         }
2730         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2731         tcore_pending_set_request_data(pending, 0, req);
2732
2733         ret = _ss_request_message(pending, o, ur, (TcorePendingResponseCallback) cb, user_data);
2734         if (!ret) {
2735                 dbg("AT request sent failed ");
2736                 return TCORE_RETURN_FAILURE;
2737         }
2738         return TCORE_RETURN_SUCCESS;
2739 }
2740
2741 static TReturn imc_ss_manage_call_0_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=0");
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_1_send(CoreObject *o, UserRequest *ur, 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", "AT+CHLD=1");
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_1x_send(CoreObject *o, UserRequest *ur, const int id, 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%d", "AT+CHLD=1", id);
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_2_send(CoreObject *o, UserRequest *ur, 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", "AT+CHLD=2");
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_2x_send(CoreObject *o, UserRequest *ur, const int id, 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%d", "AT+CHLD=2", id);
2804         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2805
2806         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2807         g_free(cmd_str);
2808         return ret;
2809 }
2810
2811 static TReturn imc_ss_manage_call_3_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=3");
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
2825 static TReturn imc_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2826 {
2827         char *cmd_str = NULL;
2828         gboolean ret = FALSE;
2829
2830         dbg("function enter");
2831         cmd_str = g_strdup_printf("%s", "AT+CHLD=4");
2832
2833         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2834         g_free(cmd_str);
2835         return ret;
2836 }
2837
2838 static TReturn imc_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data)
2839 {
2840         char *cmd_str = NULL;
2841         gboolean ret = FALSE;
2842
2843         dbg("function enter");
2844         cmd_str = g_strdup_printf("%s%s", "AT+CHLD=4", number);
2845
2846         ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2847         g_free(cmd_str);
2848
2849         return ret;
2850 }
2851
2852 gboolean imc_ss_init(TcorePlugin *cp, CoreObject *co_ss)
2853 {
2854         CoreObject *co_call = NULL;
2855
2856         /* Set operations */
2857         tcore_ss_set_ops(co_ss, &ss_ops, TCORE_OPS_TYPE_CP);
2858
2859         co_call = tcore_plugin_ref_core_object(cp,
2860                                                 CORE_OBJECT_TYPE_CALL);
2861         if (co_call == NULL) {
2862                 err("Can't find CALL core object");
2863                 return FALSE;
2864         }
2865
2866         /* Set operations */
2867         tcore_call_control_set_operations(co_call, &call_ops);
2868
2869         tcore_object_add_callback(co_ss, "+CSSU", on_notification_ss_cssu_info, NULL);
2870         tcore_object_add_callback(co_ss, "+CSSI", on_notification_ss_cssi_info, NULL);
2871         tcore_object_add_callback(co_ss, "+CUSD", on_notification_ss_ussd, NULL);
2872
2873         return TRUE;
2874 }
2875
2876 void imc_ss_exit(TcorePlugin *cp, CoreObject *co_ss)
2877 {
2878         dbg("Exit");
2879
2880         tcore_object_del_callback(co_ss, "+CSSU", on_notification_ss_cssu_info);
2881         tcore_object_del_callback(co_ss, "+CSSI", on_notification_ss_cssi_info);
2882         tcore_object_del_callback(co_ss, "+CUSD", on_notification_ss_ussd);
2883 }