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