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