s_sim: Extend XSIMSTATE parsing to get SMS service status
[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;
737         GSList *tokens = NULL;
738         const char *line;
739         int err;
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                 resp.record = 0;
754         } else {
755                 dbg("RESPONSE NOT OK");
756                 resp.record = 0;
757                 line = (const char *) response->final_response;
758                 tokens = tcore_at_tok_new(line);
759
760                 if (g_slist_length(tokens) < 1) {
761                         dbg("err cause not specified or string corrupted");
762                         resp.err = SS_ERROR_SYSTEMFAILURE;
763                 } else {
764                         err = atoi(g_slist_nth_data(tokens, 0));
765                         // / TODO: CMEE error mapping is required.
766                         resp.err = SS_ERROR_SYSTEMFAILURE;
767                 }
768
769                 tcore_at_tok_free(tokens);
770         }
771
772         dbg("[ check ] class : 0x%x", info->class);
773         dbg("[ check ] flavor_type : 0x%x", info->flavor_type);
774
775         dbg("on_response_ss_forwarding_set - rsp.err : %d, ur : %x", resp.err, ur);
776
777         if (response->success > 0) {
778                 if (info->flavor_type == SS_CF_MODE_CF_ALL ||
779                         info->flavor_type == SS_CF_MODE_CFC) {
780                         if (ur) {
781                                 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
782                         } else {
783                                 dbg("[ error ] ur is 0");
784                         }
785                 } else {
786                         dup_ur = tcore_user_request_ref(ur);
787                         _ss_forwarding_get(o, dup_ur, info->class, info->flavor_type, info->resp);
788                 }
789         } else {
790                 if (ur) {
791                         tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
792                 } else {
793                         dbg("[ error ] ur is 0");
794                 }
795         }
796         g_free(user_data);
797 }
798
799 static void on_response_ss_waiting_set(TcorePending *p, int data_len, const void *data, void *user_data)
800 {
801         CoreObject *core_obj = 0;
802         UserRequest *ur = 0;
803         UserRequest *ur_dup = 0;
804         struct ss_confirm_info *info = 0;
805         struct tresp_ss_waiting resp;
806         GSList *tokens = NULL;
807         const char *line;
808         int err;
809         const TcoreATResponse *response;
810
811         dbg("function enter");
812         response = data;
813         core_obj = tcore_pending_ref_core_object(p);
814         ur = tcore_pending_ref_user_request(p);
815
816         info = (struct ss_confirm_info *) user_data;
817
818         if (response->success > 0) {
819                 dbg("RESPONSE OK");
820                 resp.err = SS_ERROR_NONE;
821                 resp.record = 0;
822         } else {
823                 dbg("RESPONSE NOT OK");
824                 resp.record = 0;
825                 line = (const char *) response->final_response;
826                 tokens = tcore_at_tok_new(line);
827
828                 if (g_slist_length(tokens) < 1) {
829                         dbg("err cause not specified or string corrupted");
830                         resp.err = SS_ERROR_SYSTEMFAILURE;
831                 } else {
832                         err = atoi(g_slist_nth_data(tokens, 0));
833                         // / TODO: CMEE error mapping is required.
834                         resp.err = SS_ERROR_SYSTEMFAILURE;
835                 }
836                 tcore_at_tok_free(tokens);
837         }
838
839         dbg("on_response_ss_waiting_set - rsp.err : %d, ur : %x, class : %d", resp.err, ur, info->class);
840
841         if (resp.err == SS_ERROR_NONE) {
842                 ur_dup = tcore_user_request_ref(ur);
843                 dbg("Get waiting call status");
844                 _ss_waiting_get(core_obj, ur_dup, info->class, info->resp);
845         } else {
846                 if (ur) {
847                         tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
848                 } else {
849                         dbg("[ error ] ur is 0");
850                 }
851         }
852         g_free(user_data);
853 }
854
855
856 static void on_confirmation_ss_ussd(TcorePending *p, int data_len, const void *data, void *user_data)
857 {
858         CoreObject *core_obj = 0;
859         struct ss_confirm_info *info = 0;
860         struct tresp_ss_ussd resp;
861         UserRequest *ur = NULL, *ussd_ur = NULL;
862         GSList *tokens = NULL;
863         const char *line;
864         int err;
865         UssdSession *ussd_s = NULL;
866         enum tcore_ss_ussd_type type = TCORE_SS_USSD_TYPE_MAX;
867         const TcoreATResponse *response;
868
869         dbg("function enter");
870         response = data;
871         ur = tcore_pending_ref_user_request(p);
872         info = (struct ss_confirm_info *) user_data;
873
874         memset(resp.str, 0x00, MAX_SS_USSD_LEN);
875
876         core_obj = tcore_pending_ref_core_object(p);
877         ussd_s = tcore_ss_ussd_get_session(core_obj);
878
879         if (ussd_s)
880                 type = tcore_ss_ussd_get_session_type(ussd_s);
881         else
882                 dbg("[ error ] ussd_s : (0)");
883
884         resp.type = (enum telephony_ss_ussd_type) type;
885         resp.status = SS_USSD_MAX; // hardcoded value.
886
887         if (response->success > 0) {
888                 dbg("RESPONSE OK");
889                 resp.err = SS_ERROR_NONE;
890         } else {
891                 dbg("RESPONSE NOT OK");
892
893                 line = (const char *) response->final_response;
894                 tokens = tcore_at_tok_new(line);
895
896                 if (g_slist_length(tokens) < 1) {
897                         dbg("err cause not specified or string corrupted");
898                         resp.err = SS_ERROR_SYSTEMFAILURE;
899                 } else {
900                         err = atoi(g_slist_nth_data(tokens, 0));
901                         // TODO: CMEE error mapping is required.
902                         resp.err = SS_ERROR_SYSTEMFAILURE;
903                 }
904                 tcore_at_tok_free(tokens);
905         }
906
907         dbg("on_confirmation_ss_ussd - rsp.err : %d, ur : %x", resp.err, ur);
908
909         if (response->success > 0) {
910                 if (type == TCORE_SS_USSD_TYPE_USER_INITIATED) {
911                         dbg("ussd type %d", resp.type);
912
913                         if (ussd_s) {
914                                 tcore_ss_ussd_get_session_data(ussd_s, (void **) &ussd_ur);
915                                 if (ussd_ur)
916                                         tcore_user_request_free(ussd_ur);
917                         }
918                 }
919         }
920
921         if (ussd_s)
922                 tcore_ss_ussd_destroy_session(ussd_s);
923
924         if (ur) {
925                 if (UssdResp == FALSE) { // to avoid sending multiple response to application.
926                         tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_ussd), &resp);
927                 }
928                 UssdResp = FALSE;
929         } else
930                 dbg("[ error ] ur : (0)");
931
932         g_free(user_data);
933 }
934
935 static void on_response_ss_barring_get(TcorePending *p, int data_len, const void *data, void *user_data)
936 {
937         UserRequest *ur = 0;
938         int status = 0, classx = 0, err = 0;
939         GSList *respdata;
940         struct ss_confirm_info *info = 0;
941         struct tresp_ss_barring resp;
942         int countRecords = 0, countValidRecords = 0;
943         GSList *tokens = NULL;
944         const char *line;
945         char *classx_str;
946         char *stat = NULL;
947         const TcoreATResponse *response;
948
949         dbg("function enter");
950
951         response = data;
952         ur = tcore_pending_ref_user_request(p);
953         info = (struct ss_confirm_info *) user_data;
954
955         if (response->lines) {
956                 respdata = (GSList *) response->lines;
957                 countRecords = g_slist_length(respdata);
958                 dbg("total records : %d", countRecords);
959         } else {
960                 countRecords = 0;
961                 dbg("no active status - return to user")
962         }
963         resp.record_num = countRecords;
964         resp.record = 0;
965         if (resp.record_num > 0) {
966                 resp.record = g_new0(struct barring_info, resp.record_num);
967                 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
968                         line = (const char *) (respdata->data);
969                         tokens = tcore_at_tok_new(line);
970
971                         // parse <status>
972                         stat = g_slist_nth_data(tokens, 0);
973                         if (!stat) {
974                                 dbg("Stat is missing");
975                                 goto error;
976                         }
977
978                         status = atoi(stat);
979                         if (status == 1) {
980                                 resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
981                         } else {
982                                 resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
983                         }
984                         dbg("call barring status - %d", status);
985
986                         // Parse <class>
987                         classx_str = g_slist_nth_data(tokens, 1);
988
989                         if (!classx_str) {
990                                 dbg("class error. classx not exist - set to requested one : %d", info->class);
991                                 switch (info->class) {
992                                 case SS_CLASS_ALL_TELE:
993                                         classx = 7;
994                                         break;
995
996                                 case SS_CLASS_VOICE:
997                                         classx = 1;
998                                         break;
999
1000                                 case SS_CLASS_ALL_DATA_TELE:
1001                                         classx = 2;
1002                                         break;
1003
1004                                 case SS_CLASS_FAX:
1005                                         classx = 4;
1006                                         break;
1007
1008                                 case SS_CLASS_SMS:
1009                                         classx = 8;
1010                                         break;
1011
1012                                 case SS_CLASS_ALL_CS_SYNC:
1013                                         classx = 16;
1014                                         break;
1015
1016                                 default:
1017                                         classx = 7;
1018                                         dbg("unsupported class %d. set to default : 7", info->class);
1019                                         break;
1020                                 }
1021                         } else {
1022                                 classx = atoi(classx_str);
1023                                 dbg("call barring classx - %d", classx);
1024                         }
1025
1026                         switch (classx) {
1027                         case 1:
1028                                 resp.record[countValidRecords].class = SS_CLASS_VOICE;
1029                                 break;
1030
1031                         case 2:
1032                                 resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1033                                 break;
1034
1035                         case 4:
1036                                 resp.record[countValidRecords].class = SS_CLASS_FAX;
1037                                 break;
1038
1039                         case 7:
1040                                 resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1041                                 break;
1042
1043                         case 8:
1044                                 resp.record[countValidRecords].class = SS_CLASS_SMS;
1045                                 break;
1046
1047                         case 16:
1048                                 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1049                                 break;
1050
1051                         case 32:
1052                                 resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1053                                 break;
1054
1055                         default:
1056                                 dbg("unspoorted class : [%d]\n", classx);
1057                                 goto error;
1058                                 break;
1059                         }
1060                         resp.record[countValidRecords].mode = (enum telephony_ss_barring_mode) (info->flavor_type);
1061                         countValidRecords++;
1062                         tcore_at_tok_free(tokens);
1063                         continue;
1064
1065 error:
1066                         dbg("invalid field found. coutinue");
1067                         tcore_at_tok_free(tokens);
1068                         continue;
1069                 }
1070
1071                 dbg("valid count :%d", countValidRecords);
1072                 resp.record_num = countValidRecords;
1073                 resp.err = SS_ERROR_NONE;
1074         } else {
1075                 dbg("no active status - return to user")
1076         }
1077
1078         if (response->success > 0) {
1079                 dbg("RESPONSE OK");
1080                 resp.err = SS_ERROR_NONE;
1081         } else {
1082                 dbg("RESPONSE NOT OK");
1083                 resp.err = TCORE_RETURN_FAILURE;
1084                 resp.record = 0;
1085                 resp.record_num = 0;
1086
1087                 line = (const char *) response->final_response;
1088                 tokens = tcore_at_tok_new(line);
1089
1090                 if (g_slist_length(tokens) < 1) {
1091                         dbg("err cause not specified or string corrupted");
1092                         resp.err = SS_ERROR_SYSTEMFAILURE;
1093                 } else {
1094                         err = atoi(g_slist_nth_data(tokens, 0));
1095                         // TODO: CMEE error mapping is required.
1096                         resp.err = SS_ERROR_SYSTEMFAILURE;
1097                 }
1098                 tcore_at_tok_free(tokens);
1099         }
1100
1101         dbg("on_response_ss_barring_get- rsp.err : %d, ur : %x", resp.err, ur);
1102
1103         if (ur)
1104                 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
1105         else
1106                 dbg("[ error ] ur is 0");
1107
1108         if (resp.record) {
1109                 g_free(resp.record);
1110                 resp.record = NULL;
1111         }
1112
1113         g_free(user_data);
1114 }
1115
1116 static void on_response_ss_forwarding_get(TcorePending *p, int data_len, const void *data, void *user_data)
1117 {
1118         UserRequest *ur = 0;
1119         int classx = 0, err = 0, time = 0;
1120         char *num;
1121         struct ss_confirm_info *info = 0;
1122         struct tresp_ss_forwarding resp;
1123         int countRecords = 0, countValidRecords = 0;
1124
1125         GSList *respdata = NULL, *tokens = NULL;
1126         const char *line;
1127         char *classx_str, *status, *ton, *time_str;
1128         const TcoreATResponse *response;
1129
1130         dbg("function enter");
1131         response = data;
1132
1133         ur = tcore_pending_ref_user_request(p);
1134         info = (struct ss_confirm_info *) user_data;
1135         if (response->lines) {
1136                 respdata = (GSList *) response->lines;
1137                 countRecords = g_slist_length(respdata);
1138                 dbg("total records : %d", countRecords);
1139         } else {
1140                 countRecords = 0;
1141                 dbg("no active status - return to user")
1142         }
1143         resp.record_num = countRecords;
1144         resp.record = 0;
1145         if (resp.record_num > 0) {
1146                 resp.record = g_new0(struct forwarding_info, resp.record_num);
1147
1148                 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1149                         line = (const char *) (respdata->data);
1150                         tokens = tcore_at_tok_new(line);
1151
1152                         // parse <status>
1153                         status = g_slist_nth_data(tokens, 0);
1154                         if (!status) {
1155                                 dbg("start line error. skip this line");
1156                                 goto error;
1157                         } else {
1158                                 if (atoi(status) == 1) {
1159                                         resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1160                                 } else {
1161                                         resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1162                                 }
1163                         }
1164
1165                         // Parse <class>
1166                         classx_str = g_slist_nth_data(tokens, 1);
1167                         if (!classx_str) {
1168                                 dbg("class error. skip this line");
1169                                 goto error;
1170                         } else {
1171                                 switch (atoi(classx_str)) {
1172                                 case 1:
1173                                         resp.record[countValidRecords].class = SS_CLASS_VOICE;
1174                                         break;
1175
1176                                 case 2:
1177                                         resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1178                                         break;
1179
1180                                 case 4:
1181                                         resp.record[countValidRecords].class = SS_CLASS_FAX;
1182                                         break;
1183
1184                                 case 7:
1185                                         resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1186                                         break;
1187
1188                                 case 8:
1189                                         resp.record[countValidRecords].class = SS_CLASS_SMS;
1190                                         break;
1191
1192                                 case 16:
1193                                         resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1194                                         break;
1195
1196                                 case 32:
1197                                         resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1198                                         break;
1199
1200                                 default:
1201                                         dbg("unspoorted class : [%d]\n", classx);
1202                                         goto error;
1203                                         break;
1204                                 }
1205                         }
1206
1207                         // parse  <numer> <type>
1208                         num = g_slist_nth_data(tokens, 2);
1209                         if (num) {
1210                                 dbg("number  - %s", num);
1211                                 memcpy((resp.record[countValidRecords].number), num, strlen(num));
1212                                 resp.record[countValidRecords].number_present = TRUE;
1213
1214                                 ton = g_slist_nth_data(tokens, 3);
1215                                 if (ton) {
1216                                         resp.record[countValidRecords].number_type = atoi(ton);
1217                                         dbg("number  type - %d", resp.record[countValidRecords].number_type);
1218                                 }
1219                         }
1220
1221                         // skip  <subaddr> <satype>
1222                         // parse  <time>
1223                         time_str = g_slist_nth_data(tokens, 6);
1224                         if (time_str) {
1225                                 time = atoi(time_str);
1226                                 resp.record[countValidRecords].time = (enum telephony_ss_forwarding_no_reply_time) time;
1227                                 dbg("time  - %d", time);
1228                         }
1229
1230                         resp.record[countValidRecords].mode = (enum telephony_ss_forwarding_mode) (info->flavor_type);
1231                         dbg("flavor_type  - %d", (enum telephony_ss_forwarding_mode) (info->flavor_type));
1232
1233                         countValidRecords++;
1234                         tcore_at_tok_free(tokens);
1235                         continue;
1236 error:
1237                         dbg("invalid field found. coutinue");
1238                         tcore_at_tok_free(tokens);
1239                         continue;
1240                 }
1241                 dbg("valid count :%d", countValidRecords);
1242                 resp.record_num = countValidRecords;
1243                 resp.err = SS_ERROR_NONE;
1244         } else {
1245                 dbg("no active status - return to user")
1246         }
1247
1248         if (response->success > 0) {
1249                 dbg("RESPONSE OK");
1250                 resp.err = SS_ERROR_NONE;
1251         } else {
1252                 dbg("RESPONSE NOT OK");
1253                 resp.record = 0;
1254                 resp.record_num = 0;
1255                 line = (const char *) response->final_response;
1256                 tokens = tcore_at_tok_new(line);
1257
1258                 if (g_slist_length(tokens) < 1) {
1259                         dbg("err cause not specified or string corrupted");
1260                         resp.err = SS_ERROR_SYSTEMFAILURE;
1261                 } else {
1262                         err = atoi(g_slist_nth_data(tokens, 0));
1263                         /* TODO: CMEE error mapping is required. */
1264                         resp.err = SS_ERROR_SYSTEMFAILURE;
1265                 }
1266                 tcore_at_tok_free(tokens);
1267         }
1268
1269         dbg("on_response_ss_forwarding_get- rsp.err : %d, ur : %x", resp.err, ur);
1270         if (ur)
1271                 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
1272         else
1273                 dbg("[ error ] ur is 0");
1274
1275         if (resp.record) {
1276                 g_free(resp.record);
1277                 resp.record = NULL;
1278         }
1279         g_free(user_data);
1280 }
1281
1282 static void on_response_ss_waiting_get(TcorePending *p, int data_len, const void *data, void *user_data)
1283 {
1284         UserRequest *ur = 0;
1285         GSList *respdata, *tokens = NULL;
1286         int classx = 0, err = 0;
1287         struct ss_confirm_info *info = 0;
1288         struct tresp_ss_waiting resp;
1289         int countRecords = 0, countValidRecords = 0;
1290         const char *line;
1291         char *classx_str, *status;
1292         const TcoreATResponse *response;
1293
1294         dbg("function enter")
1295         response = data;
1296         ur = tcore_pending_ref_user_request(p);
1297         info = (struct ss_confirm_info *) user_data;
1298
1299         if (response->lines) {
1300                 respdata = (GSList *) response->lines;
1301                 countRecords = g_slist_length(respdata);
1302                 dbg("total records : %d", countRecords);
1303         } else {
1304                 countRecords = 0;
1305                 dbg("no active status - return to user")
1306         }
1307         resp.record_num = countRecords;
1308         resp.record = 0;
1309
1310         if (resp.record_num > 0) {
1311                 resp.record = g_new0(struct waiting_info, resp.record_num);
1312
1313                 for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
1314                         line = (const char *) (respdata->data);
1315                         tokens = tcore_at_tok_new(line);
1316
1317                         // parse <status>
1318                         status = g_slist_nth_data(tokens, 0);
1319                         if (!status) {
1320                                 dbg("Missing stat  in responce ");
1321                                 goto error;
1322                         } else {
1323                                 if (atoi(status) == 1) {
1324                                         resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
1325                                 } else {
1326                                         resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
1327                                 }
1328                         }
1329                         dbg("status = %d", resp.record[countValidRecords].status);
1330
1331                         // Parse <class>
1332                         classx_str = g_slist_nth_data(tokens, 1);
1333                         if (!classx_str) {
1334                                 dbg("error - class is missing");
1335                                 goto error;
1336                         } else {
1337                                 switch (atoi(classx_str)) {
1338                                 case 1:
1339                                         resp.record[countValidRecords].class = SS_CLASS_VOICE;
1340                                         break;
1341
1342                                 case 2:
1343                                         resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
1344                                         break;
1345
1346                                 case 4:
1347                                         resp.record[countValidRecords].class = SS_CLASS_FAX;
1348                                         break;
1349
1350                                 case 7:
1351                                         resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
1352                                         break;
1353
1354                                 case 8:
1355                                         resp.record[countValidRecords].class = SS_CLASS_SMS;
1356                                         break;
1357
1358                                 case 16:
1359                                         resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
1360                                         break;
1361
1362                                 case 32:
1363                                         resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
1364                                         break;
1365
1366                                 default:
1367                                         dbg("unspoorted class : [%d]\n", classx);
1368                                         goto error;
1369                                         break;
1370                                 }
1371                                 dbg("class info %d", resp.record[countValidRecords].class);
1372                         }
1373
1374                         countValidRecords++;
1375                         tcore_at_tok_free(tokens);
1376                         continue;
1377 error:
1378                         dbg("invalid field found. coutinue");
1379                         tcore_at_tok_free(tokens);
1380                         continue;
1381                 }
1382
1383                 dbg("valid count :%d", countValidRecords);
1384                 resp.record_num = countValidRecords;
1385                 resp.err = SS_ERROR_NONE;
1386         } else {
1387                 dbg("no active status - return to user")
1388         }
1389
1390         if (response->success > 0) {
1391                 dbg("RESPONSE OK");
1392                 resp.err = SS_ERROR_NONE;
1393         } else {
1394                 dbg("RESPONSE NOT OK");
1395                 resp.record = 0;
1396                 resp.record_num = 0;
1397                 line = (const char *) response->final_response;
1398                 tokens = tcore_at_tok_new(line);
1399
1400                 if (g_slist_length(tokens) < 1) {
1401                         dbg("err cause not specified or string corrupted");
1402                         resp.err = SS_ERROR_SYSTEMFAILURE;
1403                 } else {
1404                         err = atoi(g_slist_nth_data(tokens, 0));
1405                         // TODO: CMEE error mapping is required.
1406                         resp.err = SS_ERROR_SYSTEMFAILURE;
1407                 }
1408                 tcore_at_tok_free(tokens);
1409         }
1410
1411         dbg("on_response_ss_waiting_get - rsp.err : %d, ur : %x", resp.err, ur);
1412         if (ur)
1413                 tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
1414         else
1415                 dbg("[ error ] ur is 0");
1416
1417         if (resp.record) {
1418                 g_free(resp.record);
1419                 resp.record = NULL;
1420         }
1421         g_free(user_data);
1422 }
1423
1424
1425 static void on_response_ss_cli_get(TcorePending *p, int data_len, const void *data, void *user_data)
1426 {
1427         UserRequest *ur = 0;
1428         struct tresp_ss_cli resp;
1429         enum telephony_ss_cli_type *p_type = NULL;
1430         char *line = NULL, *status;
1431         int err = FALSE;
1432         int cli_adj, stat;
1433         GSList *tokens = NULL;
1434         const TcoreATResponse *response;
1435
1436         dbg("function enter")
1437         response = data;
1438         ur = tcore_pending_ref_user_request(p);
1439         p_type = (enum telephony_ss_cli_type *) (user_data);
1440
1441         if (response->success > 0) {
1442                 line = (char *) (((GSList *) response->lines)->data);
1443                 tokens = tcore_at_tok_new(line);
1444
1445                 if (*p_type == SS_CLI_TYPE_CLIR) {
1446                         // +CLIR: <n> <m>
1447                         dbg("CLI type is CLIR")
1448                         // parse <n>
1449                         status = g_slist_nth_data(tokens, 0);
1450
1451                         if (!status) {
1452                                 dbg("Call line identification adjustment missing <n>");
1453                         } else {
1454                                 cli_adj = atoi(status);
1455                                 dbg("CLIR response value of <n> - %d", cli_adj);
1456
1457                                 if (cli_adj == 0) {
1458                                         // parse <m>
1459                                         status = g_slist_nth_data(tokens, 1);
1460                                         if (!status) {
1461                                                 dbg("status is missing<m>");
1462                                         }
1463                                         stat = atoi(status);
1464                                         dbg("CLIR response value of <m> - %d", stat);
1465
1466                                         if (stat == 1 || stat == 3) {
1467                                                 resp.status = TRUE;
1468                                         } else {
1469                                                 resp.status = FALSE;
1470                                         }
1471                                 } else if (cli_adj == 1) {
1472                                         resp.status = TRUE;
1473                                 } else {
1474                                         resp.status = FALSE;
1475                                 }
1476                                 dbg("resp.status -  %d", resp.status);
1477                         }
1478                         tcore_at_tok_free(tokens);
1479                 } else {
1480                         // parse <n>
1481                         status = g_slist_nth_data(tokens, 0);
1482                         if (!status) {
1483                                 dbg("Stat is missing");
1484                         } else {
1485                                 stat = atoi(status);
1486                                 if (stat == 1)
1487                                         resp.status = TRUE;
1488                                 else
1489                                         resp.status = FALSE;
1490
1491                                 dbg("resp.status -  %d", resp.status);
1492                         }
1493                         tcore_at_tok_free(tokens);
1494                 }
1495         }
1496
1497         if (response->success > 0) {
1498                 dbg("RESPONSE OK");
1499                 resp.err = SS_ERROR_NONE;
1500         } else {
1501                 dbg("RESPONSE NOT OK");
1502
1503                 line = (char *) response->final_response;
1504                 tokens = tcore_at_tok_new(line);
1505
1506                 if (g_slist_length(tokens) < 1) {
1507                         dbg("err cause not specified or string corrupted");
1508                         resp.err = SS_ERROR_SYSTEMFAILURE;
1509                 } else {
1510                         err = atoi(g_slist_nth_data(tokens, 0));
1511                         // TODO: CMEE error mapping is required.
1512                         resp.err = SS_ERROR_SYSTEMFAILURE;
1513                 }
1514                 tcore_at_tok_free(tokens);
1515         }
1516
1517         resp.type = *p_type;
1518         dbg("check - resp.type = %d ", resp.type);
1519         if (ur)
1520                 tcore_user_request_send_response(ur, TRESP_SS_CLI_GET_STATUS, sizeof(struct tresp_ss_cli), &resp);
1521         else
1522                 dbg("[ error ] ur : (0)");
1523
1524         g_free(user_data);
1525 }
1526
1527 static struct tcore_ss_operations ss_ops = {
1528         .barring_activate = s_ss_barring_activate,
1529         .barring_deactivate = s_ss_barring_deactivate,
1530         .barring_change_password = s_ss_barring_change_password,
1531         .barring_get_status = s_ss_barring_get_status,
1532         .forwarding_activate = s_ss_forwarding_activate,
1533         .forwarding_deactivate = s_ss_forwarding_deactivate,
1534         .forwarding_register = s_ss_forwarding_register,
1535         .forwarding_deregister = s_ss_forwarding_deregister,
1536         .forwarding_get_status = s_ss_forwarding_get_status,
1537         .waiting_activate = s_ss_waiting_activate,
1538         .waiting_deactivate = s_ss_waiting_deactivate,
1539         .waiting_get_status = s_ss_waiting_get_status,
1540         .cli_activate = s_ss_cli_activate,
1541         .cli_deactivate = s_ss_cli_deactivate,
1542         .cli_get_status = s_ss_cli_get_status,
1543         .send_ussd = s_ss_send_ussd,
1544         .set_aoc = s_ss_set_aoc,
1545         .get_aoc = s_ss_get_aoc,
1546 };
1547
1548
1549 static TReturn _ss_barring_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1550 {
1551         struct treq_ss_barring *barring = 0;
1552         struct ss_confirm_info *user_data = 0;
1553         char *cmd_str = NULL;
1554         TcoreHal *hal;
1555         TcorePending *pending = NULL;
1556         TcoreATRequest *req;
1557         char passwd[MAX_SS_BARRING_PASSWORD_LEN + 1];
1558         int opco;
1559         int classx;
1560         char *facility = NULL;
1561         gboolean ret = FALSE;
1562
1563         dbg("function enter");
1564         barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1565
1566         switch (op) {
1567         case SS_OPCO_ACTIVATE:
1568                 opco = 1;
1569                 break;
1570
1571         case SS_OPCO_DEACTIVATE:
1572                 opco = 0;
1573                 break;
1574
1575         default:
1576                 dbg("unsupported opco : %d", op);
1577                 return TCORE_RETURN_FAILURE;
1578         }
1579         dbg("opco - %d", opco);
1580
1581         switch (barring->mode) {
1582         case SS_BARR_MODE_BAOC:
1583                 facility = "AO";
1584                 break;
1585
1586         case SS_BARR_MODE_BOIC:
1587                 facility = "OI";
1588                 break;
1589
1590         case SS_BARR_MODE_BOIC_NOT_HC:
1591                 facility = "OX";
1592                 break;
1593
1594         case SS_BARR_MODE_BAIC:
1595                 facility = "AI";
1596                 break;
1597
1598         case SS_BARR_MODE_BIC_ROAM:
1599                 facility = "IR";
1600                 break;
1601
1602         case SS_BARR_MODE_AB:
1603                 facility = "AB";
1604                 break;
1605
1606         case SS_BARR_MODE_AOB:
1607                 facility = "AG";
1608                 break;
1609
1610         case SS_BARR_MODE_AIB:
1611                 facility = "AC";
1612                 break;
1613
1614         case SS_BARR_MODE_BIC_NOT_SIM:
1615         // facility = "NS";
1616         default:
1617                 dbg("unspported mode %d", barring->mode);
1618                 return TCORE_RETURN_FAILURE;
1619         }
1620
1621         dbg("facility - %s", facility);
1622
1623         switch (barring->class) {
1624         case SS_CLASS_ALL_TELE:
1625                 classx = 7;
1626                 break;
1627
1628         case SS_CLASS_VOICE:
1629                 classx = 1;
1630                 break;
1631
1632         case SS_CLASS_ALL_DATA_TELE:
1633                 classx = 2;
1634                 break;
1635
1636         case SS_CLASS_FAX:
1637                 classx = 4;
1638                 break;
1639
1640         case SS_CLASS_SMS:
1641                 classx = 8;
1642                 break;
1643
1644         case SS_CLASS_ALL_CS_SYNC:
1645                 classx = 16;
1646                 break;
1647
1648         default:
1649                 classx = 7;
1650                 dbg("unsupported class %d. set to default : 7", barring->class);
1651                 break;
1652         }
1653
1654         dbg("classx - %d", classx);
1655
1656         // null-ended pwd handling added - unexpected  0x11 value observed in req string
1657         memcpy(passwd, barring->password, MAX_SS_BARRING_PASSWORD_LEN);
1658         passwd[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1659         dbg("passwd - %s", passwd);
1660
1661         hal = tcore_object_get_hal(o);
1662         pending = tcore_pending_new(o, 0);
1663
1664         cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d", facility, opco, passwd, classx);
1665         dbg("request command : %s", cmd_str);
1666
1667         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1668         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1669
1670         tcore_pending_set_request_data(pending, 0, req);
1671
1672         user_data = g_new0(struct ss_confirm_info, 1);
1673         if (op == SS_OPCO_ACTIVATE) {
1674                 user_data->resp = TRESP_SS_BARRING_ACTIVATE;
1675         } else if (op == SS_OPCO_DEACTIVATE) {
1676                 user_data->resp = TRESP_SS_BARRING_DEACTIVATE;
1677         } else {
1678                 dbg("[ error ] wrong ss opco (0x%x)", op);
1679                 if (user_data != NULL) {
1680                         g_free(user_data);
1681                 }
1682                 g_free(cmd_str);
1683                 return TCORE_RETURN_FAILURE;
1684         }
1685         user_data->flavor_type = (int) (barring->mode);
1686         user_data->class = barring->class;
1687
1688         ret = _ss_request_message(pending, o, ur, on_response_ss_barring_set, user_data);
1689         g_free(cmd_str);
1690
1691         if (!ret) {
1692                 dbg("AT request sent failed ")
1693                 if (user_data != NULL) {
1694                         g_free(user_data);
1695                 }
1696                 return TCORE_RETURN_FAILURE;
1697         }
1698         return TCORE_RETURN_SUCCESS;
1699 }
1700
1701 static TReturn _ss_barring_get(CoreObject *o,
1702                                                            UserRequest *ur,
1703                                                            enum telephony_ss_class class,
1704                                                            enum telephony_ss_barring_mode mode,
1705                                                            enum tcore_response_command resp)
1706 {
1707         struct ss_confirm_info *user_data = 0;
1708         gboolean ret = FALSE;
1709         char *cmd_str = NULL;
1710         int opco, classx;
1711         char *facility = NULL;
1712         TcoreHal *hal;
1713         TcorePending *pending = NULL;
1714         TcoreATRequest *req;
1715
1716         dbg("function enter");
1717
1718         // query status - opco is fixed to 2
1719         opco = 2;
1720         // barring mode
1721         switch (mode) {
1722         case SS_BARR_MODE_BAOC:
1723                 facility = "AO";
1724                 break;
1725
1726         case SS_BARR_MODE_BOIC:
1727                 facility = "OI";
1728                 break;
1729
1730         case SS_BARR_MODE_BOIC_NOT_HC:
1731                 facility = "OX";
1732                 break;
1733
1734         case SS_BARR_MODE_BAIC:
1735                 facility = "AI";
1736                 break;
1737
1738         case SS_BARR_MODE_BIC_ROAM:
1739                 facility = "IR";
1740                 break;
1741
1742         case SS_BARR_MODE_AB:
1743         case SS_BARR_MODE_AOB:
1744         case SS_BARR_MODE_AIB:
1745         case SS_BARR_MODE_BIC_NOT_SIM:
1746         default:
1747                 dbg("unsupported mode %d", mode);
1748                 return TCORE_RETURN_FAILURE;
1749         }
1750
1751         dbg("facility - %s", facility);
1752
1753         switch (class) {
1754         case SS_CLASS_ALL_TELE:
1755                 classx = 7;
1756                 break;
1757
1758         case SS_CLASS_VOICE:
1759                 classx = 1;
1760                 break;
1761
1762         case SS_CLASS_ALL_DATA_TELE:
1763                 classx = 2;
1764                 break;
1765
1766         case SS_CLASS_FAX:
1767                 classx = 4;
1768                 break;
1769
1770         case SS_CLASS_SMS:
1771                 classx = 8;
1772                 break;
1773
1774         case SS_CLASS_ALL_CS_SYNC:
1775                 classx = 16;
1776                 break;
1777
1778         default:
1779                 classx = 7;
1780                 dbg("unsupported class %d. set to default : 7", class);
1781                 break;
1782         }
1783         dbg("class - %d", classx);
1784
1785         if (classx == 7)
1786                 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d", facility, opco);
1787         else
1788                 cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d", facility, opco, classx);
1789
1790         dbg("request command : %s", cmd_str);
1791
1792         hal = tcore_object_get_hal(o);
1793         pending = tcore_pending_new(o, 0);
1794         req = tcore_at_request_new(cmd_str, "+CLCK", TCORE_AT_MULTILINE);
1795         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1796
1797         tcore_pending_set_request_data(pending, 0, req);
1798
1799         user_data = g_new0(struct ss_confirm_info, 1);
1800         user_data->resp = resp;
1801         user_data->flavor_type = (int) (mode);
1802         user_data->class = class;
1803
1804         ret = _ss_request_message(pending, o, ur, on_response_ss_barring_get, user_data);
1805         g_free(cmd_str);
1806
1807         if (!ret) {
1808                 dbg("AT request sent failed ")
1809                 if (user_data != NULL) {
1810                         g_free(user_data);
1811                 }
1812                 return TCORE_RETURN_FAILURE;
1813         }
1814
1815         return TCORE_RETURN_SUCCESS;
1816 }
1817
1818 static TReturn s_ss_barring_activate(CoreObject *o, UserRequest *ur)
1819 {
1820         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1821                 dbg("cp not ready/n");
1822                 return TCORE_RETURN_ENOSYS;
1823         }
1824         return _ss_barring_set(o, ur, SS_OPCO_ACTIVATE);
1825 }
1826
1827 static TReturn s_ss_barring_deactivate(CoreObject *o, UserRequest *ur)
1828 {
1829         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1830                 dbg("cp not ready/n");
1831                 return TCORE_RETURN_ENOSYS;
1832         }
1833         return _ss_barring_set(o, ur, SS_OPCO_DEACTIVATE);
1834 }
1835
1836 static TReturn s_ss_barring_change_password(CoreObject *o, UserRequest *ur)
1837 {
1838         TcoreHal *hal;
1839         TcorePending *pending = NULL;
1840         TcoreATRequest *req;
1841         struct treq_ss_barring_change_password *barring = 0;
1842         struct ss_confirm_info *user_data = 0;
1843         char *cmd_str = NULL;
1844         gboolean ret = FALSE;
1845         char old_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1846         char new_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
1847
1848         dbg("function enter");
1849
1850         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1851                 dbg("cp not ready/n");
1852                 return TCORE_RETURN_ENOSYS;
1853         }
1854
1855         barring = (struct treq_ss_barring_change_password *) tcore_user_request_ref_data(ur, 0);
1856
1857         if (barring->password_old == NULL || barring->password_new == NULL) {
1858                 dbg("[error]password is null");
1859                 return TCORE_RETURN_FAILURE;
1860         }
1861         memcpy(old_password, barring->password_old, MAX_SS_BARRING_PASSWORD_LEN);
1862         old_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1863         memcpy(new_password, barring->password_new, MAX_SS_BARRING_PASSWORD_LEN);
1864         new_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
1865
1866         dbg("old passwd - %s new passwd- %s", old_password, new_password);
1867         cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB", old_password, new_password);
1868         dbg("request command : %s", cmd_str);
1869
1870         hal = tcore_object_get_hal(o);
1871         pending = tcore_pending_new(o, 0);
1872         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1873         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1874
1875         tcore_pending_set_request_data(pending, 0, req);
1876
1877         user_data = g_new0(struct ss_confirm_info, 1);
1878         user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
1879
1880         ret = _ss_request_message(pending, o, ur, on_response_ss_barring_change_pwd, user_data);
1881         g_free(cmd_str);
1882         if (!ret) {
1883                 dbg("AT request sent failed ")
1884                 if (user_data != NULL) {
1885                         g_free(user_data);
1886                 }
1887                 return TCORE_RETURN_FAILURE;
1888         }
1889         return TCORE_RETURN_SUCCESS;
1890 }
1891
1892 static TReturn s_ss_barring_get_status(CoreObject *o, UserRequest *ur)
1893 {
1894         struct treq_ss_barring *barring = 0;
1895
1896         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
1897                 dbg("cp not ready/n");
1898                 return TCORE_RETURN_ENOSYS;
1899         }
1900         barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
1901
1902         return _ss_barring_get(o, ur, barring->class, barring->mode, TRESP_SS_BARRING_GET_STATUS);
1903 }
1904
1905 static TReturn _ss_forwarding_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
1906 {
1907         struct treq_ss_forwarding *forwarding = 0;
1908         struct ss_confirm_info *user_data = 0;
1909         gboolean ret = FALSE;
1910         int len = 0;
1911         char *cmd_str = NULL;
1912         char *tmp_str = NULL;
1913         int reason = 0, mode = 0, num_type = 0, classx = 0, time = 0;
1914         gboolean valid_num = FALSE;
1915         TcoreHal *hal;
1916         TcorePending *pending = NULL;
1917         TcoreATRequest *req;
1918
1919         dbg("_ss_forwarding_set with opco %d ", op);
1920
1921         forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
1922         switch (forwarding->mode) {
1923         case SS_CF_MODE_CFU:
1924                 reason = 0;
1925                 break;
1926
1927         case SS_CF_MODE_CFB:
1928                 reason = 1;
1929                 break;
1930
1931         case SS_CF_MODE_CFNRy:
1932                 reason = 2;
1933                 break;
1934
1935         case SS_CF_MODE_CFNRc:
1936                 reason = 3;
1937                 break;
1938
1939         case SS_CF_MODE_CF_ALL:
1940                 reason = 4;
1941                 break;
1942
1943         case SS_CF_MODE_CFC:
1944                 reason = 5;
1945                 break;
1946
1947         default:
1948                 dbg("unsupported reason : %d");
1949                 return TCORE_RETURN_FAILURE;
1950                 break;
1951         }
1952
1953         dbg("reason = %d", reason);
1954         switch (op) {
1955         case SS_OPCO_DEACTIVATE:
1956                 mode = 0;
1957                 break;
1958
1959         case SS_OPCO_ACTIVATE:
1960                 mode = 1;
1961                 break;
1962
1963         case SS_OPCO_REG:
1964                 mode = 3;
1965                 break;
1966
1967         case SS_OPCO_DEREG:
1968                 mode = 4;
1969                 break;
1970
1971         default:
1972                 dbg("unsupported opco : %d", op);
1973                 return TCORE_RETURN_FAILURE;
1974         }
1975
1976         dbg("mode = %d", mode);
1977
1978         // class
1979         switch (forwarding->class) {
1980         case SS_CLASS_ALL_TELE:
1981                 classx = 7;
1982                 break;
1983
1984         case SS_CLASS_VOICE:
1985                 classx = 1;
1986                 break;
1987
1988         case SS_CLASS_ALL_DATA_TELE:
1989                 classx = 2;
1990                 break;
1991
1992         case SS_CLASS_FAX:
1993                 classx = 4;
1994                 break;
1995
1996         case SS_CLASS_SMS:
1997                 classx = 8;
1998                 break;
1999
2000         case SS_CLASS_ALL_CS_SYNC:
2001                 classx = 16;
2002                 break;
2003
2004         default:
2005                 classx = 7;
2006                 dbg("unsupported class %d. set to default : 7", forwarding->class);
2007                 break;
2008         }
2009         dbg("classx = %d", classx);
2010
2011         // number
2012         len = strlen(forwarding->number);
2013         if (len > 0) {
2014                 valid_num = TRUE;
2015                 if (forwarding->number[0] == '+')
2016                         num_type = ((NUM_TYPE_INTERNATIONAL << 4) | NUM_PLAN_ISDN);
2017                 else
2018                         num_type = 0;
2019         }
2020         dbg("number = %s", forwarding->number);
2021
2022         user_data = g_new0(struct ss_confirm_info, 1);
2023
2024         switch (op) {
2025         case SS_OPCO_REG:
2026                 user_data->resp = TRESP_SS_FORWARDING_REGISTER;
2027                 break;
2028
2029         case SS_OPCO_DEREG:
2030                 user_data->resp = TRESP_SS_FORWARDING_DEREGISTER;
2031                 break;
2032
2033         case SS_OPCO_ACTIVATE:
2034                 user_data->resp = TRESP_SS_FORWARDING_ACTIVATE;
2035                 break;
2036
2037         case SS_OPCO_DEACTIVATE:
2038                 user_data->resp = TRESP_SS_FORWARDING_DEACTIVATE;
2039                 break;
2040
2041         default:
2042                 dbg("[ error ] unknown op (0x%x)", op);
2043                 break;
2044         }
2045
2046         if (forwarding->number[0] == '+')
2047                 num_type = 145;
2048         else
2049                 num_type = 129;
2050
2051         if (op == SS_OPCO_REG)
2052                 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,\"%s\",%d,%d", reason, mode, forwarding->number, num_type, classx);
2053         else // other opcode does not need num field
2054                 tmp_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2055
2056         if (forwarding->mode == SS_CF_MODE_CFNRy) {
2057                 // add time info to 'no reply' case
2058                 time = (int) (forwarding->time);
2059                 cmd_str = g_strdup_printf("%s,,,%d", tmp_str, time);
2060         } else {
2061                 cmd_str = g_strdup_printf("%s", tmp_str);
2062         }
2063
2064         dbg("request command : %s", cmd_str);
2065         hal = tcore_object_get_hal(o);
2066         pending = tcore_pending_new(o, 0);
2067         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2068         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2069
2070         tcore_pending_set_request_data(pending, 0, req);
2071
2072         user_data->flavor_type = forwarding->mode;
2073         user_data->class = forwarding->class;
2074
2075         ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_set, user_data);
2076
2077         g_free(tmp_str);
2078         g_free(cmd_str);
2079
2080         if (!ret) {
2081                 dbg("AT request sent failed ")
2082                 if (user_data != NULL) {
2083                         g_free(user_data);
2084                 }
2085                 return TCORE_RETURN_FAILURE;
2086         }
2087
2088         return TCORE_RETURN_SUCCESS;
2089 }
2090
2091 static TReturn _ss_forwarding_get(CoreObject *o,
2092                                                                   UserRequest *ur,
2093                                                                   enum telephony_ss_class class,
2094                                                                   enum telephony_ss_forwarding_mode type,
2095                                                                   enum tcore_response_command resp)
2096 {
2097         struct ss_confirm_info *user_data = 0;
2098         gboolean ret = FALSE;
2099         char *cmd_str = NULL;
2100         int reason = 0, mode = 0, classx = 0;
2101         TcoreHal *hal;
2102         TcorePending *pending = NULL;
2103         TcoreATRequest *req;
2104
2105         dbg("function enter");
2106
2107         switch (type) {
2108         case SS_CF_MODE_CFU:
2109                 reason = 0;
2110                 break;
2111
2112         case SS_CF_MODE_CFB:
2113                 reason = 1;
2114                 break;
2115
2116         case SS_CF_MODE_CFNRy:
2117                 reason = 2;
2118                 break;
2119
2120         case SS_CF_MODE_CFNRc:
2121                 reason = 3;
2122                 break;
2123
2124         case SS_CF_MODE_CF_ALL:
2125                 reason = 4;
2126                 break;
2127
2128         case SS_CF_MODE_CFC:
2129                 reason = 5;
2130                 break;
2131
2132         default:
2133                 dbg("unsupported reason : %d");
2134                 break;
2135         }
2136         dbg("reason  = %d", reason);
2137
2138         switch (class) {
2139         case SS_CLASS_ALL_TELE:
2140                 classx = 7;
2141                 break;
2142
2143         case SS_CLASS_VOICE:
2144                 classx = 1;
2145                 break;
2146
2147         case SS_CLASS_ALL_DATA_TELE:
2148                 classx = 2;
2149                 break;
2150
2151         case SS_CLASS_FAX:
2152                 classx = 4;
2153                 break;
2154
2155         case SS_CLASS_SMS:
2156                 classx = 8;
2157                 break;
2158
2159         case SS_CLASS_ALL_CS_SYNC:
2160                 classx = 16;
2161                 break;
2162
2163         default:
2164                 classx = 7;
2165                 dbg("unsupported class %d. set to default : 7", class);
2166                 break;
2167         }
2168
2169         dbg("classx  = %d", classx);
2170
2171         // query status - mode set to 2
2172         mode = 2;
2173         user_data = g_new0(struct ss_confirm_info, 1);
2174         user_data->resp = resp;
2175         user_data->class = class;
2176         user_data->flavor_type = type;
2177
2178         if (classx == 7)
2179                 cmd_str = g_strdup_printf("AT+CCFC=%d,%d", reason, mode);
2180         else
2181                 cmd_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
2182
2183         dbg("request command : %s", cmd_str);
2184
2185         hal = tcore_object_get_hal(o);
2186         pending = tcore_pending_new(o, 0);
2187         req = tcore_at_request_new(cmd_str, "+CCFC", TCORE_AT_MULTILINE);
2188         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2189
2190         tcore_pending_set_request_data(pending, 0, req);
2191
2192         ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_get, user_data);
2193         g_free(cmd_str);
2194
2195         if (!ret) {
2196                 dbg("AT request sent failed ")
2197                 if (user_data != NULL) {
2198                         g_free(user_data);
2199                 }
2200                 return TCORE_RETURN_FAILURE;
2201         }
2202
2203         return TCORE_RETURN_SUCCESS;
2204 }
2205
2206 static TReturn s_ss_forwarding_activate(CoreObject *o, UserRequest *ur)
2207 {
2208         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2209                 dbg("cp not ready/n");
2210                 return TCORE_RETURN_ENOSYS;
2211         }
2212         return _ss_forwarding_set(o, ur, SS_OPCO_ACTIVATE);
2213 }
2214
2215 static TReturn s_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur)
2216 {
2217         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2218                 dbg("cp not ready/n");
2219                 return TCORE_RETURN_ENOSYS;
2220         }
2221         return _ss_forwarding_set(o, ur, SS_OPCO_DEACTIVATE);
2222 }
2223
2224 static TReturn s_ss_forwarding_register(CoreObject *o, UserRequest *ur)
2225 {
2226         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2227                 dbg("cp not ready/n");
2228                 return TCORE_RETURN_ENOSYS;
2229         }
2230         return _ss_forwarding_set(o, ur, SS_OPCO_REG);
2231 }
2232
2233 static TReturn s_ss_forwarding_deregister(CoreObject *o, UserRequest *ur)
2234 {
2235         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2236                 dbg("cp not ready/n");
2237                 return TCORE_RETURN_ENOSYS;
2238         }
2239         return _ss_forwarding_set(o, ur, SS_OPCO_DEREG);
2240 }
2241
2242 static TReturn s_ss_forwarding_get_status(CoreObject *o, UserRequest *ur)
2243 {
2244         struct treq_ss_forwarding *forwarding = 0;
2245
2246         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2247                 dbg("cp not ready/n");
2248                 return TCORE_RETURN_ENOSYS;
2249         }
2250
2251         forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
2252
2253         return _ss_forwarding_get(o, ur, forwarding->class, forwarding->mode, TRESP_SS_FORWARDING_GET_STATUS);
2254 }
2255
2256
2257 static TReturn _ss_waiting_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode opco)
2258 {
2259         struct treq_ss_waiting *waiting = 0;
2260         struct ss_confirm_info *user_data = 0;
2261         gboolean ret = FALSE;
2262         int mode = 0, classx = 0;
2263         char *cmd_str;
2264         TcoreHal *hal;
2265         TcorePending *pending = NULL;
2266         TcoreATRequest *req;
2267
2268         dbg("function enter ");
2269         waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2270         user_data = g_new0(struct ss_confirm_info, 1);
2271
2272         if (opco == SS_OPCO_ACTIVATE) {
2273                 user_data->resp = TRESP_SS_WAITING_ACTIVATE;
2274                 mode = 1; // enable
2275         } else if (opco == SS_OPCO_DEACTIVATE) {
2276                 user_data->resp = TRESP_SS_WAITING_DEACTIVATE;
2277                 mode = 0; // disable
2278         } else
2279                 dbg("[ error ] unknown ss mode (0x%x)", opco);
2280
2281         switch (waiting->class) {
2282         case SS_CLASS_ALL_TELE:
2283                 classx = 7;
2284                 break;
2285
2286         case SS_CLASS_VOICE:
2287                 classx = 1;
2288                 break;
2289
2290         case SS_CLASS_ALL_DATA_TELE:
2291                 classx = 2;
2292                 break;
2293
2294         case SS_CLASS_FAX:
2295                 classx = 4;
2296                 break;
2297
2298         case SS_CLASS_SMS:
2299                 classx = 8;
2300                 break;
2301
2302         default:
2303                 classx = 1;
2304                 dbg("unsupported class %d. set to default : 1", waiting->class);
2305                 break;
2306         }
2307         dbg("mode = %d classxx- %d", mode, classx);
2308
2309         user_data->class = waiting->class;
2310         user_data->flavor_type = (int) opco;
2311
2312         cmd_str = g_strdup_printf("AT+CCWA=1,%d,%d", mode, classx); // always enable +CCWA: unsolicited cmd
2313         dbg("request command : %s", cmd_str);
2314
2315         hal = tcore_object_get_hal(o);
2316         pending = tcore_pending_new(o, 0);
2317         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2318         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2319
2320         tcore_pending_set_request_data(pending, 0, req);
2321
2322         ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_set, user_data);
2323         g_free(cmd_str);
2324         if (!ret) {
2325                 dbg("AT request sent failed ")
2326                 if (user_data != NULL) {
2327                         g_free(user_data);
2328                 }
2329                 return TCORE_RETURN_FAILURE;
2330         }
2331         return TCORE_RETURN_SUCCESS;
2332 }
2333
2334 static TReturn _ss_waiting_get(CoreObject *o,
2335                                                            UserRequest *ur,
2336                                                            enum telephony_ss_class class,
2337                                                            enum tcore_response_command resp)
2338 {
2339         struct ss_confirm_info *user_data = 0;
2340         gboolean ret = FALSE;
2341         int classx; // mode,
2342         char *cmd_str;
2343         TcoreHal *hal;
2344         TcorePending *pending = NULL;
2345         TcoreATRequest *req;
2346
2347         dbg("function  enter")
2348         switch (class) {
2349         case SS_CLASS_ALL_TELE:
2350                 classx = 7;
2351                 break;
2352
2353         case SS_CLASS_VOICE:
2354                 classx = 1;
2355                 break;
2356
2357         case SS_CLASS_ALL_DATA_TELE:
2358                 classx = 2;
2359                 break;
2360
2361         case SS_CLASS_FAX:
2362                 classx = 4;
2363                 break;
2364
2365         case SS_CLASS_SMS:
2366                 classx = 8;
2367                 break;
2368
2369         default:
2370                 classx = 7;
2371                 dbg("unsupported class %d. set to default : 7", class);
2372                 break;
2373         }
2374         dbg("classx - %d", classx);
2375
2376         dbg("allocating user data");
2377         user_data = g_new0(struct ss_confirm_info, 1);
2378         user_data->resp = resp;
2379         user_data->class = class;
2380
2381         cmd_str = g_strdup_printf("AT+CCWA=1,2,%d", classx); // always enable +CCWA: unsolicited cmd , mode is fixed to 2(query status)
2382         dbg("request cmd : %s", cmd_str);
2383
2384         hal = tcore_object_get_hal(o);
2385         pending = tcore_pending_new(o, 0);
2386         req = tcore_at_request_new(cmd_str, "+CCWA", TCORE_AT_MULTILINE);
2387         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2388
2389         tcore_pending_set_request_data(pending, 0, req);
2390
2391         ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_get, user_data);
2392         g_free(cmd_str);
2393         if (!ret) {
2394                 dbg("AT request sent failed ")
2395                 if (user_data != NULL) {
2396                         g_free(user_data);
2397                 }
2398                 return TCORE_RETURN_FAILURE;
2399         }
2400         return TCORE_RETURN_SUCCESS;
2401 }
2402
2403 static TReturn s_ss_waiting_activate(CoreObject *o, UserRequest *ur)
2404 {
2405         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2406                 dbg("cp not ready/n");
2407                 return TCORE_RETURN_ENOSYS;
2408         }
2409         return _ss_waiting_set(o, ur, SS_OPCO_ACTIVATE);
2410 }
2411
2412 static TReturn s_ss_waiting_deactivate(CoreObject *o, UserRequest *ur)
2413 {
2414         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2415                 dbg("cp not ready/n");
2416                 return TCORE_RETURN_ENOSYS;
2417         }
2418         return _ss_waiting_set(o, ur, SS_OPCO_DEACTIVATE);
2419 }
2420
2421 static TReturn s_ss_waiting_get_status(CoreObject *o, UserRequest *ur)
2422 {
2423         struct treq_ss_waiting *waiting = 0;
2424
2425         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2426                 dbg("cp not ready/n");
2427                 return TCORE_RETURN_ENOSYS;
2428         }
2429         waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
2430
2431         return _ss_waiting_get(o, ur, waiting->class, TRESP_SS_WAITING_GET_STATUS);
2432 }
2433
2434 static TReturn s_ss_cli_activate(CoreObject *o, UserRequest *ur)
2435 {
2436         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2437                 dbg("cp not ready/n");
2438                 return TCORE_RETURN_ENOSYS;
2439         }
2440         return TCORE_RETURN_SUCCESS;
2441 }
2442
2443 static TReturn s_ss_cli_deactivate(CoreObject *o, UserRequest *ur)
2444 {
2445         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2446                 dbg("cp not ready/n");
2447                 return TCORE_RETURN_ENOSYS;
2448         }
2449         return TCORE_RETURN_SUCCESS;
2450 }
2451
2452 static TReturn s_ss_cli_get_status(CoreObject *o, UserRequest *ur)
2453 {
2454         struct treq_ss_cli *cli = 0;
2455         gboolean ret = FALSE;
2456         char *cmd_prefix = NULL, *rsp_prefix = NULL, *cmd_str = NULL;
2457         enum  telephony_ss_cli_type *user_data = 0;
2458         TcoreHal *hal;
2459         TcorePending *pending = NULL;
2460         TcoreATRequest *req;
2461
2462         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2463                 dbg("cp not ready/n");
2464                 return TCORE_RETURN_ENOSYS;
2465         }
2466
2467         cli = (struct treq_ss_cli *) tcore_user_request_ref_data(ur, 0);
2468         switch (cli->type) {
2469         case SS_CLI_TYPE_CLIP:
2470                 cmd_prefix = "+CLIP";
2471                 rsp_prefix = "+CLIP";
2472                 break;
2473
2474         case SS_CLI_TYPE_CLIR:
2475                 cmd_prefix = "+CLIR";
2476                 rsp_prefix = "+CLIR";
2477                 break;
2478
2479         case SS_CLI_TYPE_COLP:
2480                 cmd_prefix = "+COLP";
2481                 rsp_prefix = "+COLP";
2482                 break;
2483
2484         case SS_CLI_TYPE_COLR:
2485                 cmd_prefix = "+COLR";
2486                 rsp_prefix = "+COLR";
2487                 break;
2488
2489         case SS_CLI_TYPE_CNAP:
2490                 cmd_prefix = "+CNAP";
2491                 rsp_prefix = "+CNAP";
2492                 break;
2493
2494         case SS_CLI_TYPE_CDIP:
2495         default:
2496                 dbg("unsupported cli_type : %d", cli->type);
2497                 return TCORE_RETURN_FAILURE;
2498                 break;
2499         }
2500         dbg("cmd_prefix : %s", cmd_prefix);
2501
2502         cmd_str = g_strdup_printf("AT%s?", cmd_prefix);
2503         dbg("request cmd : %s", cmd_str);
2504
2505         user_data = g_new0(enum telephony_ss_cli_type, 1);
2506         *user_data = cli->type;
2507
2508         hal = tcore_object_get_hal(o);
2509         pending = tcore_pending_new(o, 0);
2510
2511         req = tcore_at_request_new(cmd_str, rsp_prefix, TCORE_AT_SINGLELINE);
2512         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2513         tcore_pending_set_request_data(pending, 0, req);
2514
2515         ret = _ss_request_message(pending, o, ur, on_response_ss_cli_get, user_data);
2516         g_free(cmd_str);
2517         if (!ret) {
2518                 dbg("AT request sent failed ")
2519                 if (user_data != NULL) {
2520                         g_free(user_data);
2521                 }
2522                 return TCORE_RETURN_FAILURE;
2523         }
2524         return TCORE_RETURN_SUCCESS;
2525 }
2526
2527 static TReturn s_ss_send_ussd(CoreObject *o, UserRequest *ur)
2528 {
2529         UssdSession *ussd_s = 0;
2530         struct treq_ss_ussd *ussd = 0;
2531         struct ss_confirm_info *user_data = 0;
2532         gboolean ret = FALSE;
2533         char *cmd_str;
2534         TcoreHal *hal;
2535         TcorePending *pending = NULL;
2536         TcoreATRequest *req;
2537
2538         dbg("function enter");
2539
2540         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2541                 dbg("cp not ready/n");
2542                 return TCORE_RETURN_ENOSYS;
2543         }
2544
2545         ussd = (struct treq_ss_ussd *) tcore_user_request_ref_data(ur, 0);
2546         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
2547         dbg("request command : %s", cmd_str);
2548
2549         user_data = g_new0(struct ss_confirm_info, 1);
2550         user_data->resp = TRESP_SS_SEND_USSD;
2551         ussd_s = tcore_ss_ussd_get_session(o);
2552         if (!ussd_s) {
2553                 dbg("USSD session does not  exist");
2554                 tcore_ss_ussd_create_session(o, (enum tcore_ss_ussd_type) ussd->type, (void *) tcore_user_request_ref(ur), 0);
2555         } else {
2556                 if (ussd->type == SS_USSD_TYPE_USER_INITIATED) {
2557                         dbg("[ error ] ussd session is already exist");
2558                         g_free(user_data);
2559                         return TCORE_RETURN_FAILURE;
2560                 }
2561
2562                 tcore_ss_ussd_set_session_type(ussd_s, (enum tcore_ss_ussd_type) ussd->type);
2563         }
2564
2565         hal = tcore_object_get_hal(o);
2566         pending = tcore_pending_new(o, 0);
2567         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2568         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2569
2570         tcore_pending_set_request_data(pending, 0, req);
2571
2572         ret = _ss_request_message(pending, o, ur, on_confirmation_ss_ussd, user_data);
2573         g_free(cmd_str);
2574
2575         if (!ret) {
2576                 dbg("AT request sent failed ")
2577                 if (user_data != NULL) {
2578                         g_free(user_data);
2579                 }
2580                 return TCORE_RETURN_FAILURE;
2581         }
2582         return TCORE_RETURN_SUCCESS;
2583 }
2584
2585 static TReturn s_ss_set_aoc(CoreObject *o, UserRequest *ur)
2586 {
2587         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2588                 dbg("cp not ready/n");
2589                 return TCORE_RETURN_ENOSYS;
2590         }
2591
2592         dbg("[ error ] unsupported function");
2593         return TCORE_RETURN_SUCCESS;
2594 }
2595
2596 static TReturn s_ss_get_aoc(CoreObject *o, UserRequest *ur)
2597 {
2598         if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2599                 dbg("cp not ready/n");
2600                 return TCORE_RETURN_ENOSYS;
2601         }
2602
2603         dbg("[ error ] unsupported function");
2604         return TCORE_RETURN_SUCCESS;
2605 }
2606
2607
2608 static struct tcore_call_control_operations call_ops = {
2609         .answer_hold_and_accept = s_ss_manage_call_2_send,
2610         .answer_replace = s_ss_manage_call_1_send,
2611         .answer_reject = s_ss_manage_call_0_send,
2612         .end_specific = s_ss_manage_call_1x_send,
2613         .end_all_active = s_ss_manage_call_1_send,
2614         .end_all_held = s_ss_manage_call_0_send,
2615         .active = s_ss_manage_call_2_send,
2616         .hold = s_ss_manage_call_2_send,
2617         .swap = s_ss_manage_call_2_send,
2618         .join = s_ss_manage_call_3_send,
2619         .split = s_ss_manage_call_2x_send,
2620         .transfer = s_ss_manage_call_4_send,
2621         .deflect = s_ss_manage_call_4dn_send,
2622 };
2623
2624 static TReturn s_ss_manage_call_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
2625 {
2626         TcorePending *pending = NULL;
2627         TcoreATRequest *req;
2628         gboolean ret = FALSE;
2629
2630         pending = tcore_pending_new(o, 0);
2631         req = tcore_at_request_new(cmd, NULL, TCORE_AT_NO_RESULT);
2632         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2633         tcore_pending_set_request_data(pending, 0, req);
2634
2635         ret = _ss_request_message(pending, o, ur, (TcorePendingResponseCallback) cb, user_data);
2636         if (!ret) {
2637                 dbg("AT request sent failed ")
2638                 return TCORE_RETURN_FAILURE;
2639         }
2640         return TCORE_RETURN_SUCCESS;
2641 }
2642
2643 static TReturn s_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2644 {
2645         char *cmd_str = NULL;
2646         gboolean ret = FALSE;
2647
2648         dbg("function enter");
2649         cmd_str = g_strdup_printf("%s", "AT+CHLD=0");
2650         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2651
2652         ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2653         g_free(cmd_str);
2654         return ret;
2655 }
2656
2657 static TReturn s_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2658 {
2659         char *cmd_str = NULL;
2660         gboolean ret = FALSE;
2661
2662         dbg("function enter");
2663         cmd_str = g_strdup_printf("%s", "AT+CHLD=1");
2664         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2665
2666         ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2667         g_free(cmd_str);
2668         return ret;
2669 }
2670
2671 static TReturn s_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2672 {
2673         char *cmd_str = NULL;
2674         gboolean ret = FALSE;
2675
2676         dbg("function enter");
2677         cmd_str = g_strdup_printf("%s%d", "AT+CHLD=1", id);
2678         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2679
2680         ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2681         g_free(cmd_str);
2682         return ret;
2683 }
2684
2685 static TReturn s_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2686 {
2687         char *cmd_str = NULL;
2688         gboolean ret = FALSE;
2689
2690         dbg("function enter");
2691         cmd_str = g_strdup_printf("%s", "AT+CHLD=2");
2692         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2693
2694         ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2695         g_free(cmd_str);
2696         return ret;
2697 }
2698
2699 static TReturn s_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
2700 {
2701         char *cmd_str = NULL;
2702         gboolean ret = FALSE;
2703
2704         dbg("function enter");
2705         cmd_str = g_strdup_printf("%s%d", "AT+CHLD=2", id);
2706         dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
2707
2708         ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2709         g_free(cmd_str);
2710         return ret;
2711 }
2712
2713 static TReturn s_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2714 {
2715         char *cmd_str = NULL;
2716         gboolean ret = FALSE;
2717
2718         dbg("function enter");
2719         cmd_str = g_strdup_printf("%s", "AT+CHLD=3");
2720
2721         ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2722         g_free(cmd_str);
2723         return ret;
2724 }
2725
2726
2727 static TReturn s_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
2728 {
2729         char *cmd_str = NULL;
2730         gboolean ret = FALSE;
2731
2732         dbg("function enter");
2733         cmd_str = g_strdup_printf("%s", "AT+CHLD=4");
2734
2735         ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2736         g_free(cmd_str);
2737         return ret;
2738 }
2739
2740 static TReturn s_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data)
2741 {
2742         char *cmd_str = NULL;
2743         gboolean ret = FALSE;
2744
2745         dbg("function enter");
2746         cmd_str = g_strdup_printf("%s%s", "AT+CHLD=4", number);
2747
2748         ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
2749         g_free(cmd_str);
2750
2751         return ret;
2752 }
2753
2754 gboolean s_ss_init(TcorePlugin *cp, CoreObject *co_ss)
2755 {
2756         CoreObject *co_call = NULL;
2757
2758         tcore_ss_override_ops(co_ss, &ss_ops);
2759
2760
2761         co_call = tcore_plugin_ref_core_object(cp,
2762                                                 CORE_OBJECT_TYPE_CALL);
2763         if (co_call == NULL) {
2764                 err("Can't find CALL core object");
2765                 return FALSE;
2766         }
2767
2768         tcore_call_override_ops(co_call, NULL, &call_ops);
2769
2770         tcore_object_override_callback(co_ss, "+CSSU", on_notification_ss_info, NULL);
2771         tcore_object_override_callback(co_ss, "+CSSI", on_notification_ss_info, NULL);
2772         tcore_object_override_callback(co_ss, "+CUSD", on_notification_ss_ussd, NULL);
2773
2774         return TRUE;
2775 }
2776
2777 void s_ss_exit(TcorePlugin *cp, CoreObject *co_ss)
2778 {
2779         dbg("Exit");
2780 }