Check if DNS is valid
[platform/core/telephony/tel-plugin-imc.git] / src / s_call.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 <user_request.h>
34 #include <server.h>
35 #include <at.h>
36
37 #include "s_common.h"
38 #include "s_call.h"
39
40
41 #define STATUS_INCOMING    4
42 #define STATUS_WAITING     5
43 #define STATUS_CONNECTED   7
44 #define COMMA              0X2c
45
46 static gboolean setsoundpath = FALSE;
47 static gboolean soundvolume = FALSE;
48
49 // End Cause field  - Call state end cause
50
51 typedef enum {
52         CALL_END_NO_CAUSE,
53
54         // These definitions are taken from GSM 04.08 Table 10.86
55
56         CC_CAUSE_UNASSIGNED_NUMBER,
57         CC_CAUSE_NO_ROUTE_TO_DEST,
58         CC_CAUSE_CHANNEL_UNACCEPTABLE,
59         CC_CAUSE_OPERATOR_DETERMINED_BARRING,
60         CC_CAUSE_NORMAL_CALL_CLEARING,
61         CC_CAUSE_USER_BUSY,
62         CC_CAUSE_NO_USER_RESPONDING,
63         CC_CAUSE_USER_ALERTING_NO_ANSWER,
64         CC_CAUSE_CALL_REJECTED,
65         CC_CAUSE_NUMBER_CHANGED,
66         CC_CAUSE_NON_SELECTED_USER_CLEARING,
67         CC_CAUSE_DESTINATION_OUT_OF_ORDER,
68         CC_CAUSE_INVALID_NUMBER_FORMAT,
69         CC_CAUSE_FACILITY_REJECTED,
70         CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY,
71         CC_CAUSE_NORMAL_UNSPECIFIED,
72         CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE,
73         CC_CAUSE_NETWORK_OUT_OF_ORDER,
74         CC_CAUSE_TEMPORARY_FAILURE,
75         CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION,
76         CC_CAUSE_ACCESS_INFORMATION_DISCARDED,
77         CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE,
78         CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED,
79         CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE,
80         CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED,
81         CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG,
82         CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED,
83         CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE,
84         CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE,
85         CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED,
86         CC_CAUSE_ACM_GEQ_ACMMAX,
87         CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED,
88         CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE,
89         CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED,
90         CC_CAUSE_INVALID_TRANSACTION_ID_VALUE,
91         CC_CAUSE_USER_NOT_MEMBER_OF_CUG,
92         CC_CAUSE_INCOMPATIBLE_DESTINATION,
93         CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION,
94         CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
95         CC_CAUSE_INVALID_MANDATORY_INFORMATION,
96         CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
97         CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE,
98         CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED,
99         CC_CAUSE_CONDITIONAL_IE_ERROR,
100         CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,
101         CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY,
102         CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
103         CC_CAUSE_INTERWORKING_UNSPECIFIED,
104         CC_CAUSE_END = 128,
105
106         // Reject causes
107         REJECT_CAUSE_IMSI_UNKNOWN_IN_HLR,
108         REJECT_CAUSE_ILLEGAL_MS,
109         REJECT_CAUSE_IMSI_UNKNOWN_IN_VLR,
110         REJECT_CAUSE_IMEI_NOT_ACCEPTED,
111         REJECT_CAUSE_ILLEGAL_ME,
112         REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED,
113         REJECT_CAUSE_GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,
114         REJECT_CAUSE_MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
115         REJECT_CAUSE_IMPLICITLY_DETACHED,
116         REJECT_CAUSE_PLMN_NOT_ALLOWED,
117         REJECT_CAUSE_LA_NOT_ALLOWED,
118         REJECT_CAUSE_NATIONAL_ROAMING_NOT_ALLOWED,
119         REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
120         REJECT_CAUSE_NO_SUITABLE_CELLS_IN_LA,
121         REJECT_CAUSE_MSC_TEMPORARILY_NOT_REACHABLE,
122         REJECT_CAUSE_NETWORK_FAILURE,
123         REJECT_CAUSE_MAC_FAILURE,
124         REJECT_CAUSE_SYNCH_FAILURE,
125         REJECT_CAUSE_CONGESTTION,
126         REJECT_CAUSE_GSM_AUTH_UNACCEPTED,
127         REJECT_CAUSE_SERVICE_OPTION_NOT_SUPPORTED,
128         REJECT_CAUSE_REQ_SERV_OPT_NOT_SUBSCRIBED,
129         REJECT_CAUSE_SERVICE_OPT__OUT_OF_ORDER,
130         REJECT_CAUSE_CALL_CANNOT_BE_IDENTIFIED,
131         REJECT_CAUSE_NO_PDP_CONTEXT_ACTIVATED,
132         REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MIN_VALUE,
133         REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MAX_VALUE,
134         REJECT_CAUSE_SEMANTICALLY_INCORRECT_MSG,
135         REJECT_CAUSE_INVALID_MANDATORY_INFO,
136         REJECT_CAUSE_MESSAGE_TYPE_NON_EXISTANT,
137         REJECT_CAUSE_MESSAGE_TYPE_NOT_COMP_PRT_ST,
138         REJECT_CAUSE_IE_NON_EXISTANT,
139         REJECT_CAUSE_MSG_NOT_COMPATIBLE_PROTOCOL_STATE,
140
141
142         // Connection Management establishment rejection cause
143         REJECT_CAUSE_REJ_UNSPECIFIED,
144
145         // AS reject causes
146         REJECT_CAUSE_AS_REJ_RR_REL_IND,
147         REJECT_CAUSE_AS_REJ_RR_RANDOM_ACCESS_FAILURE,
148         REJECT_CAUSE_AS_REJ_RRC_REL_IND,
149         REJECT_CAUSE_AS_REJ_RRC_CLOSE_SESSION_IND,
150         REJECT_CAUSE_AS_REJ_RRC_OPEN_SESSION_FAILURE,
151         REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL,
152         REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL_REDIAL_NOT_ALLOWED,
153         REJECT_CAUSE_AS_REJ_LOW_LEVEL_IMMED_RETRY,
154
155         // MM reject causes
156         REJECT_CAUSE_MM_REJ_INVALID_SIM,
157         REJECT_CAUSE_MM_REJ_NO_SERVICE,
158         REJECT_CAUSE_MM_REJ_TIMER_T3230_EXP,
159         REJECT_CAUSE_MM_REJ_NO_CELL_AVAILABLE,
160         REJECT_CAUSE_MM_REJ_WRONG_STATE,
161         REJECT_CAUSE_MM_REJ_ACCESS_CLASS_BLOCKED,
162         // Definitions for release ind causes between MM  and CNM
163         REJECT_CAUSE_ABORT_MSG_RECEIVED,
164         REJECT_CAUSE_OTHER_CAUSE,
165
166         // CNM reject causes
167         REJECT_CAUSE_CNM_REJ_TIMER_T303_EXP,
168         REJECT_CAUSE_CNM_REJ_NO_RESOURCES,
169         REJECT_CAUSE_CNM_MM_REL_PENDING,
170         REJECT_CAUSE_CNM_INVALID_USER_DATA,
171         CALL_END_CAUSE_MAX = 255
172 } call_end_cause_e_type;
173
174
175 struct clcc_call_t {
176         struct call_CLCC_info {
177                 int id;
178                 enum tcore_call_direction direction;
179                 enum tcore_call_status status;
180                 enum tcore_call_type type;
181                 int mpty;
182                 int num_len;
183                 int num_type;
184         }
185         info;
186         char number[90];
187 };
188
189 typedef struct {
190         int network_cause;
191         int tapi_cause;
192 } call_end_cause_info;
193
194 /**************************************************************************
195   *                                                     Local Function Prototypes
196   **************************************************************************/
197 /*************************              REQUESTS                ***************************/
198 static void _call_status_idle(TcorePlugin *p, CallObject *co);
199 static void _call_status_active(TcorePlugin *p, CallObject *co);
200 static void _call_status_dialing(TcorePlugin *p, CallObject *co);
201 static void _call_status_alert(TcorePlugin *p, CallObject *co);
202 static void _call_status_incoming(TcorePlugin *p, CallObject *co);
203 static void _call_status_waiting(TcorePlugin *p, CallObject *co);
204 static TReturn _call_list_get(CoreObject *o, gboolean *event_flag);
205 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur);
206
207 /*************************              CONFIRMATION            ***************************/
208 static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data);     // from Kernel
209 static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data);
210 static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data);
211 static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data);
212 static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data);
213
214 static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type);
215 static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type);
216 static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data);
217 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data);
218
219 /*************************              RESPONSES               ***************************/
220 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);
221
222 /*************************              NOTIIFICATIONS          ***************************/
223 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data);
224 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data);
225 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data);
226 static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data);
227 static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data);
228
229
230 /**************************************************************************
231   *                                                     Local Utility Function Prototypes
232   **************************************************************************/
233 static gboolean _call_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
234 static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status);
235 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call);
236
237 /**************************************************************************
238   *                                                     Local Function Definitions
239   **************************************************************************/
240
241 const call_end_cause_info call_end_cause_table[] =   // call end cause table to convert Netwotk cause to TAPI cause
242 {
243         { 1, CC_CAUSE_UNASSIGNED_NUMBER}, { 3, CC_CAUSE_NO_ROUTE_TO_DEST},
244         { 6, CC_CAUSE_CHANNEL_UNACCEPTABLE}, { 8, CC_CAUSE_OPERATOR_DETERMINED_BARRING},
245         { 16, CC_CAUSE_NORMAL_CALL_CLEARING}, { 17, CC_CAUSE_USER_BUSY},
246         { 18, CC_CAUSE_NO_USER_RESPONDING}, { 19, CC_CAUSE_USER_ALERTING_NO_ANSWER},
247         { 21, CC_CAUSE_CALL_REJECTED}, { 22, CC_CAUSE_NUMBER_CHANGED},
248         { 26, CC_CAUSE_NON_SELECTED_USER_CLEARING}, { 27, CC_CAUSE_DESTINATION_OUT_OF_ORDER},
249         { 28, CC_CAUSE_INVALID_NUMBER_FORMAT}, { 29, CC_CAUSE_FACILITY_REJECTED},
250         { 30, CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY}, { 31, CC_CAUSE_NORMAL_UNSPECIFIED},
251         { 34, CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE}, { 38, CC_CAUSE_NETWORK_OUT_OF_ORDER},
252         { 41, CC_CAUSE_TEMPORARY_FAILURE}, { 42, CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION},
253         { 43, CC_CAUSE_ACCESS_INFORMATION_DISCARDED}, { 44, CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE},
254         { 47, CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED}, { 49, CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE},
255         { 50, CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED}, { 55, CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG},
256         { 57, CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED}, { 58, CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE},
257         { 63, CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE}, { 65, CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED},
258         { 68, CC_CAUSE_ACM_GEQ_ACMMAX}, { 69, CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED},
259         { 70, CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE}, { 79, CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED},
260         { 81, CC_CAUSE_INVALID_TRANSACTION_ID_VALUE}, { 87, CC_CAUSE_USER_NOT_MEMBER_OF_CUG},
261         { 88, CC_CAUSE_INCOMPATIBLE_DESTINATION}, { 91, CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION},
262         { 95, CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE}, { 96, CC_CAUSE_INVALID_MANDATORY_INFORMATION},
263         { 97, CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT}, { 98, CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE},
264         { 99, CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED}, { 100, CC_CAUSE_CONDITIONAL_IE_ERROR},
265         { 101, CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE}, { 102, CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY},
266         { 111, CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED}, {127, CC_CAUSE_INTERWORKING_UNSPECIFIED},
267 };
268
269 static enum tcore_call_cli_mode _get_clir_status(char *num)
270 {
271         enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
272
273         dbg("Entry");
274
275         if (!strncmp(num, "*31#", 4)) {
276                 dbg("CLI mode restricted");
277                 return TCORE_CALL_CLI_MODE_RESTRICT;
278         }
279
280         if (!strncmp(num, "#31#", 4)) {
281                 dbg("CLI mode allowed");
282                 return TCORE_CALL_CLI_MODE_PRESENT;
283         }
284
285         err("Exit");
286         return clir;
287 }
288
289 static enum tcore_call_status _call_status(unsigned int status)
290 {
291         dbg("Entry");
292
293         switch (status) {
294         case 0:
295                 return TCORE_CALL_STATUS_ACTIVE;
296
297         case 1:
298                 return TCORE_CALL_STATUS_HELD;
299
300         case 2:
301                 return TCORE_CALL_STATUS_DIALING;
302
303         case 3:
304                 return TCORE_CALL_STATUS_ALERT;
305
306         case 4:
307                 return TCORE_CALL_STATUS_INCOMING;
308
309         case 5:
310                 return TCORE_CALL_STATUS_WAITING;
311
312         case 6:         // DISCONNECTED state  // FALL THROUGH
313         default:
314                 return TCORE_CALL_STATUS_IDLE;
315         }
316 }
317
318 static gboolean _call_is_in_mpty(int mpty)
319 {
320         dbg("Entry");
321
322         switch (mpty) {
323         case 0:
324                 return FALSE;
325
326         case 1:
327                 return TRUE;
328
329         default:
330                 break;
331         }
332
333         return FALSE;
334 }
335
336 static enum tcore_call_type call_type(int type)
337 {
338         dbg("Entry");
339
340         switch (type) {
341         case 0:
342                 return TCORE_CALL_TYPE_VOICE;
343
344         case 1:
345                 return TCORE_CALL_TYPE_VIDEO;
346
347         default:
348                 break;
349         }
350
351         return TCORE_CALL_TYPE_VOICE;
352 }
353
354 static int _compare_call_end_cause(int networkcause)
355 {
356         unsigned int count;
357
358         for (count = 0; count < sizeof(call_end_cause_table) / sizeof(call_end_cause_info); count++) {
359                 if (call_end_cause_table[count].network_cause == networkcause)
360                         return (call_end_cause_table[count].tapi_cause);
361         }
362         return CC_CAUSE_NORMAL_CALL_CLEARING;
363         dbg("Exit");
364 }
365
366 static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data)
367 {
368         dbg("Entry");
369
370         // TODO
371
372         return TRUE;
373 }
374
375 static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)
376 {
377         GSList *tokens = NULL;
378         GSList *lines = NULL;
379         const char *line = NULL;
380         char *stat;
381         int status;
382
383         dbg("Entry");
384
385         lines = (GSList *) data;
386         if (1 != g_slist_length(lines)) {
387                 err("Unsolicited message, BUT multiple lines present");
388                 goto OUT;
389         }
390
391         line = (char *) (lines->data);
392         tokens = tcore_at_tok_new(line);
393
394         stat = g_slist_nth_data(tokens, 1);
395         if (!stat) {
396                 dbg("Stat is missing from %XCALLSTAT indiaction");
397         } else {
398                 status = atoi(stat);
399
400                 switch (status) {
401                 case STATUS_INCOMING:
402                         dbg("calling on_notification_call_incoming");
403                         on_notification_call_incoming(o, line, user_data);
404                         break;
405
406                 case STATUS_WAITING:
407                         dbg("calling on_notification_call_waiting");
408                         on_notification_call_waiting(o, line, user_data);
409                         break;
410
411                 case STATUS_CONNECTED:     /*igonre Connected state. */
412                         dbg("Connected state");
413                         break;
414
415                 default:
416                         dbg("calling on_notification_call_status");
417                         on_notification_call_status(o, line, user_data);
418                         break;
419                 }
420         }
421
422         // Free tokens
423         tcore_at_tok_free(tokens);
424
425 OUT:
426         dbg("Exit");
427         return TRUE;
428 }
429
430 static gboolean _call_request_message(TcorePending *pending,
431                                                                           CoreObject *o,
432                                                                           UserRequest *ur,
433                                                                           void *on_resp,
434                                                                           void *user_data)
435 {
436         TcoreHal *hal = NULL;
437         TReturn ret;
438
439         dbg("Entry");
440
441         tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
442
443         if (on_resp) {
444                 tcore_pending_set_response_callback(pending, on_resp, user_data);
445         }
446         tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
447
448         if (ur) {
449                 tcore_pending_link_user_request(pending, ur);
450         } else {
451                 err("User Request is NULL, is this internal request??");
452         }
453
454         // HAL
455         hal = tcore_object_get_hal(o);
456         // Send request to HAL
457         ret = tcore_hal_send_request(hal, pending);
458         if (TCORE_RETURN_SUCCESS != ret) {
459                 err("Request send failed");
460                 return FALSE;
461         }
462
463         dbg("Exit");
464         return TRUE;
465 }
466
467 static void _call_status_idle(TcorePlugin *p, CallObject *co)
468 {
469         CoreObject *core_obj = NULL;
470         char *cmd_str = NULL;
471         TcorePending *pending = NULL;
472         TcoreATRequest *req = NULL;
473         gboolean ret = FALSE;
474         UserRequest *ur;
475
476         dbg("Entry");
477         core_obj = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
478         dbg("Call ID [%d], Call Status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));
479
480         if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_IDLE) {
481                 // get call end cause.
482                 cmd_str = g_strdup_printf("%s", "AT+XCEER");
483                 dbg("Request command string: %s", cmd_str);
484
485                 // Create new Pending request
486                 pending = tcore_pending_new(core_obj, 0);
487
488                 // Create new AT-Command request
489                 req = tcore_at_request_new(cmd_str, "+XCEER", TCORE_AT_SINGLELINE);
490                 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
491                 // Free command string
492                 g_free(cmd_str);
493
494                 // Set request data (AT command) to Pending request
495                 tcore_pending_set_request_data(pending, 0, req);
496
497                 ur = tcore_user_request_new(NULL, NULL);
498                 // Send request
499                 ret = _call_request_message(pending, core_obj, ur, _on_confirmation_call_end_cause, co);
500
501                 if (!ret) {
502                         err("Failed to send AT-Command request");
503                         // free only UserRequest.
504                         if (ur) {
505                                 tcore_user_request_free(ur);
506                                 ur = NULL;
507                         }
508                         return;
509                 }
510         } else {
511                 err("Call object was not free");
512                 tcore_call_object_free(core_obj, co);
513         }
514         dbg("Exit");
515         return;
516 }
517
518 static void _call_status_dialing(TcorePlugin *p, CallObject *co)
519 {
520         struct tnoti_call_status_dialing data;
521
522         dbg("Entry");
523
524         if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_DIALING) {
525                 data.type = tcore_call_object_get_type(co);
526                 dbg("data.type : [%d]", data.type);
527
528                 data.id = tcore_call_object_get_id(co);
529                 dbg("data.id : [%d]", data.id);
530
531                 // Set Status
532                 tcore_call_object_set_status(co, TCORE_CALL_STATUS_DIALING);
533
534                 // Send notification to TAPI
535                 tcore_server_send_notification(tcore_plugin_ref_server(p),
536                                                                            tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
537                                                                            TNOTI_CALL_STATUS_DIALING,
538                                                                            sizeof(struct tnoti_call_status_dialing),
539                                                                            (void *) &data);
540         }
541
542         dbg("Exit");
543         return;
544 }
545
546 static void _call_status_alert(TcorePlugin *p, CallObject *co)
547 {
548         struct tnoti_call_status_alert data;
549
550         dbg("Entry");
551
552         // Alerting has just 1 data 'CALL ID'
553         if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ALERT) {
554                 data.type = tcore_call_object_get_type(co);
555                 dbg("data.type : [%d]", data.type);
556
557                 data.id = tcore_call_object_get_id(co);
558                 dbg("data.id : [%d]", data.id);
559
560                 // Set Status
561                 tcore_call_object_set_status(co, TCORE_CALL_STATUS_ALERT);
562
563                 // Send notification to TAPI
564                 tcore_server_send_notification(tcore_plugin_ref_server(p),
565                                                                            tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
566                                                                            TNOTI_CALL_STATUS_ALERT,
567                                                                            sizeof(struct tnoti_call_status_alert),
568                                                                            (void *) &data);
569         }
570
571         dbg("Exit");
572         return;
573 }
574
575 static void _call_status_active(TcorePlugin *p, CallObject *co)
576 {
577         struct tnoti_call_status_active data;
578
579         dbg("Entry");
580
581         if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ACTIVE) {
582                 data.type = tcore_call_object_get_type(co);
583                 dbg("data.type : [%d]", data.type);
584
585                 data.id = tcore_call_object_get_id(co);
586                 dbg("data.id : [%d]", data.id);
587
588                 // Set Status
589                 tcore_call_object_set_status(co, TCORE_CALL_STATUS_ACTIVE);
590
591                 // Send notification to TAPI
592                 tcore_server_send_notification(tcore_plugin_ref_server(p),
593                                                                            tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
594                                                                            TNOTI_CALL_STATUS_ACTIVE,
595                                                                            sizeof(struct tnoti_call_status_active),
596                                                                            (void *) &data);
597         }
598
599         dbg("Exit");
600         return;
601 }
602
603 static void _call_status_held(TcorePlugin *p, CallObject *co)
604 {
605         struct tnoti_call_status_held data;
606
607         dbg("Entry");
608
609         if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_HELD) {
610                 data.type = tcore_call_object_get_type(co);
611                 dbg("data.type : [%d]", data.type);
612
613                 data.id = tcore_call_object_get_id(co);
614                 dbg("data.id : [%d]", data.id);
615
616                 // Set Status
617                 tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
618
619                 // Send notification to TAPI
620                 tcore_server_send_notification(tcore_plugin_ref_server(p),
621                                                                            tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
622                                                                            TNOTI_CALL_STATUS_HELD,
623                                                                            sizeof(struct tnoti_call_status_held),
624                                                                            (void *) &data);
625         }
626
627         dbg("Exit");
628         return;
629 }
630
631 static void _call_status_incoming(TcorePlugin *p, CallObject *co)
632 {
633         struct tnoti_call_status_incoming data;
634
635         dbg("Entry");
636
637         if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_INCOMING) {
638                 tcore_call_object_set_status(co, TCORE_CALL_STATUS_INCOMING);
639
640                 data.type = tcore_call_object_get_type(co);
641                 dbg("data.type : [%d]", data.type);
642
643                 data.id = tcore_call_object_get_id(co);
644                 dbg("data.id : [%d]", data.id);
645
646                 data.cli.mode = tcore_call_object_get_cli_mode(co);
647                 dbg("data.cli.mode : [%d]", data.cli.mode);
648
649                 tcore_call_object_get_number(co, data.cli.number);
650                 dbg("data.cli.number : [%s]", data.cli.number);
651
652                 data.cna.mode = tcore_call_object_get_cna_mode(co);
653                 dbg("data.cna.mode : [%d]", data.cna.mode);
654
655                 tcore_call_object_get_name(co, data.cna.name);
656                 dbg("data.cna.name : [%s]", data.cna.name);
657
658                 data.forward = FALSE; // this is tmp code
659
660                 data.active_line = tcore_call_object_get_active_line(co);
661                 dbg("data.active_line : [%d]", data.active_line);
662
663                 // Send notification to TAPI
664                 tcore_server_send_notification(tcore_plugin_ref_server(p),
665                                                                            tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
666                                                                            TNOTI_CALL_STATUS_INCOMING,
667                                                                            sizeof(struct tnoti_call_status_incoming),
668                                                                            (void *) &data);
669         }
670
671         dbg("Exit");
672         return;
673 }
674
675 static void _call_status_waiting(TcorePlugin *p, CallObject *co)
676 {
677         dbg("Entry");
678         _call_status_incoming(p, co);
679
680         dbg("Exit");
681         return;
682 }
683
684 static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status)
685 {
686         dbg("Entry");
687
688         dbg("Call Status is %d", status);
689         switch (status) {
690         case TCORE_CALL_STATUS_IDLE:
691                 _call_status_idle(p, co);
692                 break;
693
694         case TCORE_CALL_STATUS_ACTIVE:
695                 _call_status_active(p, co);
696                 break;
697
698         case TCORE_CALL_STATUS_HELD:
699                 _call_status_held(p, co);
700                 break;
701
702         case TCORE_CALL_STATUS_DIALING:
703                 _call_status_dialing(p, co);
704                 break;
705
706         case TCORE_CALL_STATUS_ALERT:
707                 _call_status_alert(p, co);
708                 break;
709
710         case TCORE_CALL_STATUS_INCOMING:
711                 _call_status_incoming(p, co);
712                 break;
713
714         case TCORE_CALL_STATUS_WAITING:
715                 _call_status_waiting(p, co);
716                 break;
717         }
718
719         dbg("Exit");
720         return;
721 }
722
723 static TReturn _call_list_get(CoreObject *o, gboolean *event_flag)
724 {
725         UserRequest *ur = NULL;
726         TcorePending *pending = NULL;
727         char *cmd_str = NULL;
728         TcoreATRequest *req = NULL;
729         gboolean ret = FALSE;
730
731         dbg("Entry");
732         if (!o) {
733                 err("Core Object is NULL");
734                 return TCORE_RETURN_FAILURE;
735         }
736
737         // Create new User Request
738         ur = tcore_user_request_new(NULL, NULL);
739
740         // Command string
741         cmd_str = g_strdup("AT+CLCC");
742
743         // Create new Pending Request
744         pending = tcore_pending_new(o, 0);
745         req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);
746
747         g_free(cmd_str);
748
749         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
750
751         tcore_pending_set_request_data(pending, 0, req);
752
753         ret = _call_request_message(pending, o, ur, on_response_call_list_get, event_flag);
754         if (!ret) {
755                 err("AT request (%s) sending failed", req->cmd);
756                 // free only UserRequest.
757                 if (ur) {
758                         tcore_user_request_free(ur);
759                         ur = NULL;
760                 }
761                 return TCORE_RETURN_FAILURE;
762         }
763
764         dbg("AT request sent success");
765         return TCORE_RETURN_SUCCESS;
766 }
767
768 // CONFIRMATION
769 static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data)
770 {
771         dbg("Entry");
772
773         if (result == FALSE) {  // Fail
774                 dbg("SEND FAIL");
775         } else {
776                 dbg("SEND OK");
777         }
778
779         dbg("Exit");
780         return;
781 }
782
783 static void call_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
784 {
785         TcoreATRequest *req = NULL;
786         TcoreHal *hal = NULL;
787         TcorePending *pending = NULL;
788         TReturn ret;
789
790         hal = tcore_object_get_hal(co);
791         dbg("hal: %p", hal);
792
793         pending = tcore_pending_new(co, 0);
794         if (!pending)
795                 dbg("Pending is NULL");
796         req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
797
798         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
799
800         tcore_pending_set_request_data(pending, 0, req);
801         tcore_pending_set_response_callback(pending, callback, NULL);
802         tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
803         ret = tcore_hal_send_request(hal, pending);
804 }
805
806 static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
807 {
808         UserRequest *ur = NULL;
809         GSList *tokens = NULL;
810         const char *line = NULL;
811         const TcoreATResponse *response = data;
812         struct tresp_call_dial resp;
813         enum telephony_call_error error;
814         dbg("Entry");
815
816         ur = tcore_pending_ref_user_request(p);
817         if (ur) {
818                 if (response->success > 0) {
819                         dbg("RESPONSE OK");
820                         resp.err = CALL_ERROR_NONE;
821                 } else {
822                         dbg("RESPONSE NOT OK");
823
824                         line = (const char *) response->final_response;
825                         tokens = tcore_at_tok_new(line);
826
827                         if (g_slist_length(tokens) < 1) {
828                                 err("Unspecified error cause OR string corrupted");
829                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
830                         } else {
831                                 error = atoi(g_slist_nth_data(tokens, 0));
832
833                                 // TODO: CMEE error mapping is required.
834                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
835                         }
836
837                         // Free tokens
838                         tcore_at_tok_free(tokens);
839                 }
840
841                 // Send Response to TAPI
842                 tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
843         } else {
844                 err("User Request is NULL");
845         }
846
847         dbg("Exit")
848         return;
849 }
850
851 static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)
852 {
853         UserRequest *ur = NULL;
854         GSList *tokens = NULL;
855         const char *line = NULL;
856         const TcoreATResponse *response = data;
857         struct tresp_call_answer resp;
858         enum telephony_call_error error;
859         dbg("Entry");
860
861         ur = tcore_pending_ref_user_request(p);
862         if (ur) {
863                 if (response->success > 0) {
864                         dbg("RESPONSE OK");
865                         resp.err = CALL_ERROR_NONE;
866                 } else {
867                         dbg("RESPONSE NOT OK");
868
869                         line = (const char *) response->final_response;
870                         tokens = tcore_at_tok_new(line);
871
872                         if (g_slist_length(tokens) < 1) {
873                                 err("Unspecified error cause OR string corrupted");
874                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
875                         } else {
876                                 error = atoi(g_slist_nth_data(tokens, 0));
877
878                                 // TODO: CMEE error mapping is required.
879                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
880                         }
881
882                         // Free tokens
883                         tcore_at_tok_free(tokens);
884                 }
885
886                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
887
888                 // Send Response to TAPI
889                 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
890         } else {
891                 err("User Request is NULL");
892         }
893
894         dbg("Exit");
895         return;
896 }
897
898
899 static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)
900 {
901         UserRequest *ur = NULL;
902         GSList *tokens = NULL;
903         const char *line = NULL;
904         const TcoreATResponse *response = data;
905         struct tresp_call_answer resp;
906         enum telephony_call_error error;
907
908         dbg("Entry");
909
910         ur = tcore_pending_ref_user_request(p);
911         if (ur) {
912                 if (response->success > 0) {
913                         dbg("RESPONSE OK");
914                         resp.err = CALL_ERROR_NONE;
915                 } else {
916                         dbg("RESPONSE NOT OK");
917                         line = (const char *) response->final_response;
918                         tokens = tcore_at_tok_new(line);
919
920                         if (g_slist_length(tokens) < 1) {
921                                 err("Unspecified error cause OR string corrupted");
922                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
923                         } else {
924                                 error = atoi(g_slist_nth_data(tokens, 0));
925                                 // TODO: CMEE error mapping is required.
926                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
927                         }
928
929                         // Free tokens
930                         tcore_at_tok_free(tokens);
931                 }
932
933                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
934
935                 // Send Response to TAPI
936                 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
937         } else {
938                 err("User Request is NULL");
939         }
940
941         dbg("Exit");
942         return;
943 }
944
945 static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)
946 {
947         UserRequest *ur = NULL;
948         GSList *tokens = NULL;
949         const char *line = NULL;
950         const TcoreATResponse *response = data;
951         struct tresp_call_answer resp;
952         enum telephony_call_error error;
953
954         dbg("Entry");
955         ur = tcore_pending_ref_user_request(p);
956         if (ur) {
957                 if (response->success > 0) {
958                         dbg("RESPONSE OK");
959                         resp.err = CALL_ERROR_NONE;
960                 } else {
961                         dbg("RESPONSE NOT OK");
962                         line = (const char *) response->final_response;
963                         tokens = tcore_at_tok_new(line);
964
965                         if (g_slist_length(tokens) < 1) {
966                                 err("Unspecified error cause OR string corrupted");
967                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
968                         } else {
969                                 error = atoi(g_slist_nth_data(tokens, 0));
970                                 // TODO: CMEE error mapping is required.
971                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
972                         }
973
974                         // Free tokens
975                         tcore_at_tok_free(tokens);
976                 }
977                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
978
979                 // Send Response to TAPI
980                 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
981         } else {
982                 dbg("User Request is NULL");
983         }
984
985         dbg("Exit");
986         return;
987 }
988
989 static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)
990 {
991         CoreObject *o = NULL;
992         UserRequest *ur = NULL;
993         GSList *tokens = NULL;
994         const char *line = NULL;
995         const TcoreATResponse *response = data;
996         struct tresp_call_answer resp;
997         enum telephony_call_error error;
998
999         dbg("Entry");
1000
1001         o = tcore_pending_ref_core_object(p);
1002         ur = tcore_pending_ref_user_request(p);
1003         resp.id = tcore_call_object_get_id((CallObject *) user_data);
1004
1005         if (ur) {
1006                 if (response->success > 0) {
1007                         dbg("RESPONSE OK");
1008                         resp.err = CALL_ERROR_NONE;
1009                 } else {
1010                         err("RESPONSE NOT OK");
1011                         line = (const char *) response->final_response;
1012                         tokens = tcore_at_tok_new(line);
1013
1014                         if (g_slist_length(tokens) < 1) {
1015                                 err("Unspecified error cause OR string corrupted");
1016                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1017                         } else {
1018                                 error = atoi(g_slist_nth_data(tokens, 0));
1019
1020                                 // TODO: CMEE error mapping is required.
1021                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1022                         }
1023
1024                         // Free tokens
1025                         tcore_at_tok_free(tokens);
1026                 }
1027
1028                 // Send response to TAPI
1029                 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
1030                 if (!resp.err) {
1031                         GSList *list = 0;
1032                         CallObject *co = NULL;
1033
1034                         // Active Call
1035                         list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
1036                         if (!list) {
1037                                 err("Can't find active Call");
1038                                 return;
1039                         }
1040
1041                         co = (CallObject *) list->data;
1042                         if (!co) {
1043                                 err("Can't get active Call object");
1044                                 return;
1045                         }
1046
1047                         // Set Call Status
1048                         tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
1049                         dbg("Call status is set to HELD");
1050                 }
1051         } else {
1052                 err("User Request is NULL");
1053         }
1054
1055         dbg("Exit");
1056         return;
1057 }
1058
1059 static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1060 {
1061         UserRequest *ur = NULL;
1062         struct tresp_call_end resp;
1063         GSList *tokens = NULL;
1064         const char *line = NULL;
1065         enum telephony_call_error error;
1066         const TcoreATResponse *response = data;
1067
1068         dbg("Entry");
1069         ur = tcore_pending_ref_user_request(p);
1070         if (ur) {
1071                 if (response->success > 0) {
1072                         dbg("RESPONSE OK");
1073                         resp.err = CALL_ERROR_NONE;
1074                 } else {
1075                         err("RESPONSE NOT OK");
1076
1077                         line = (const char *) response->final_response;
1078                         tokens = tcore_at_tok_new(line);
1079
1080                         if (g_slist_length(tokens) < 1) {
1081                                 err("Unspecified error cause OR string corrupted");
1082                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1083                         } else {
1084                                 error = atoi(g_slist_nth_data(tokens, 0));
1085
1086                                 // TODO: CMEE error mapping is required.
1087                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1088                         }
1089                         tcore_at_tok_free(tokens);
1090                 }
1091
1092                 resp.type = type;
1093                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1094                 dbg("resp.type = %d  resp.id= %d", resp.type, resp.id);
1095
1096                 // Send reponse to TAPI
1097                 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
1098         } else {
1099                 err("User Request is NULL");
1100         }
1101
1102         dbg("Exit");
1103         return;
1104 }
1105
1106 // RESPONSE
1107 static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)
1108 {
1109         // skip response handling - actual result will be handled in on_confirmation_call_release_all
1110         const TcoreATResponse *response = data;
1111
1112         dbg("Entry");
1113
1114         if (response->success > 0) {
1115                 dbg("RESPONSE OK");
1116         } else {
1117                 err("RESPONSE NOT OK");
1118         }
1119
1120         dbg("Exit");
1121         return;
1122 }
1123
1124
1125 static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)
1126 {
1127         dbg("Entry");
1128         _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);
1129
1130         return;
1131 }
1132
1133
1134 static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)
1135 {
1136         dbg("Entry");
1137         _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);
1138
1139         return;
1140 }
1141
1142 static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)
1143 {
1144         dbg("Entry");
1145         _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);
1146
1147         return;
1148 }
1149
1150 static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)
1151 {
1152         dbg("Entry");
1153         _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);
1154
1155         return;
1156 }
1157
1158 static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1159 {
1160         UserRequest *ur = NULL;
1161         GSList *tokens = NULL;
1162         const char *line = NULL;
1163         const TcoreATResponse *response = NULL;
1164         enum telephony_call_error error;
1165
1166         dbg("Entry");
1167         ur = tcore_pending_ref_user_request(p);
1168         response = (TcoreATResponse *) data;
1169         if (response->success > 0) {
1170                 dbg("RESPONSE OK");
1171                 error = CALL_ERROR_NONE;
1172         } else {
1173                 err("RESPONSE NOT OK");
1174
1175                 line = (const char *) response->final_response;
1176                 tokens = tcore_at_tok_new(line);
1177
1178                 if (g_slist_length(tokens) < 1) {
1179                         err("Unspecified error cause OR string corrupted");
1180                         error = CALL_ERROR_SERVICE_UNAVAIL;
1181                 } else {
1182                         error = atoi(g_slist_nth_data(tokens, 0));
1183
1184                         // TODO: CMEE error mapping is required.
1185                         error = CALL_ERROR_SERVICE_UNAVAIL;
1186                 }
1187
1188                 // Free tokens
1189                 tcore_at_tok_free(tokens);
1190         }
1191
1192         dbg("Response Call type -%d", type);
1193         switch (type) {
1194         case TRESP_CALL_HOLD:
1195         {
1196                 struct tresp_call_hold resp;
1197
1198                 resp.err = error;
1199                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1200                 dbg("call hold response");
1201                 // Send reponse to TAPI
1202                 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1203         }
1204         break;
1205
1206         case TRESP_CALL_ACTIVE:
1207         {
1208                 struct tresp_call_active resp;
1209
1210                 resp.err = error;
1211                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1212                 dbg("call active response");
1213                 // Send reponse to TAPI
1214                 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1215         }
1216         break;
1217
1218         case TRESP_CALL_JOIN:
1219         {
1220                 struct tresp_call_join resp;
1221
1222                 resp.err = error;
1223                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1224                 dbg("call join response");
1225
1226                 // Send reponse to TAPI
1227                 tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
1228         }
1229         break;
1230
1231         case TRESP_CALL_SPLIT:
1232         {
1233                 struct tresp_call_split resp;
1234
1235                 resp.err = error;
1236                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1237                 dbg("call split response");
1238                 // Send reponse to TAPI
1239                 tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
1240         }
1241         break;
1242
1243         case TRESP_CALL_DEFLECT:
1244         {
1245                 struct tresp_call_deflect resp;
1246
1247                 resp.err = error;
1248                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1249                 dbg("call deflect response");
1250                 // Send reponse to TAPI
1251                 tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
1252         }
1253
1254         break;
1255
1256         case TRESP_CALL_TRANSFER:
1257         {
1258                 struct tresp_call_transfer resp;
1259
1260                 resp.err = error;
1261                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1262                 dbg("call transfer response");
1263                 // Send reponse to TAPI
1264                 tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
1265         }
1266         break;
1267
1268         case TRESP_CALL_SEND_DTMF:
1269         {
1270                 struct tresp_call_dtmf resp;
1271
1272                 resp.err = error;
1273                 dbg("call dtmf response");
1274                 // Send reponse to TAPI
1275                 tcore_user_request_send_response(ur, TRESP_CALL_SEND_DTMF, sizeof(struct tresp_call_dtmf), &resp);
1276         }
1277         break;
1278
1279         default:
1280         {
1281                 dbg("type not supported");
1282                 return;
1283         }
1284         }
1285
1286         if ((type == TRESP_CALL_HOLD) || (type == TRESP_CALL_ACTIVE) || (type == TRESP_CALL_JOIN)
1287                 || (type == TRESP_CALL_SPLIT)) {
1288                 if (!error) {
1289                         CoreObject *core_obj = NULL;
1290                         gboolean *eflag = g_new0(gboolean, 1);
1291
1292                         core_obj = tcore_pending_ref_core_object(p);
1293                         *eflag = FALSE;
1294
1295                         dbg("Calling _call_list_get");
1296                         _call_list_get(core_obj, eflag);
1297                 }
1298         }
1299
1300         dbg("Exit");
1301         return;
1302 }
1303
1304 static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)
1305 {
1306         dbg("Entry");
1307         _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);
1308
1309         return;
1310 }
1311
1312 static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)
1313 {
1314         dbg("Entry");
1315         _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);
1316
1317         return;
1318 }
1319
1320 static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)
1321 {
1322         dbg("Entry");
1323         _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);
1324
1325         return;
1326 }
1327
1328 static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)
1329 {
1330         dbg("Entry");
1331         _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);
1332
1333         return;
1334 }
1335
1336 static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)
1337 {
1338         dbg("Entry");
1339         _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);
1340
1341         return;
1342 }
1343
1344 static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)
1345 {
1346         dbg("Entry");
1347         _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);
1348
1349         return;
1350 }
1351
1352 static void on_confirmation_call_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
1353 {
1354         dbg("Entry");
1355         _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SEND_DTMF);
1356
1357         return;
1358 }
1359
1360 static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data)
1361 {
1362         GSList *tokens = NULL;
1363         const char *line = NULL;
1364         const TcoreATResponse *response = data;
1365         enum telephony_call_error error;
1366
1367         dbg("Entry");
1368
1369         if (response->success > 0) {
1370                 dbg("RESPONSE OK");
1371                 error = CALL_ERROR_NONE;
1372         } else {
1373                 err("RESPONSE NOT OK");
1374                 line = (const char *) response->final_response;
1375                 tokens = tcore_at_tok_new(line);
1376                 if (g_slist_length(tokens) < 1) {
1377                         err("err cause not specified or string corrupted");
1378                         error = CALL_ERROR_SERVICE_UNAVAIL;
1379                 } else {
1380                         error = atoi(g_slist_nth_data(tokens, 0));
1381                         // TODO: CMEE error mapping is required.
1382                 }
1383
1384                 // Free tokens
1385                 tcore_at_tok_free(tokens);
1386         }
1387
1388         dbg("Set dtmf tone duration response - %d", error);
1389         return;
1390 }
1391
1392 static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
1393 {
1394         CoreObject *core_obj = NULL;
1395         UserRequest *ur = NULL;
1396         const TcoreATResponse *response = data;
1397         struct tresp_call_swap resp;
1398         GSList *tokens = NULL;
1399         const char *line = NULL;
1400
1401         dbg("Entry");
1402         core_obj = tcore_pending_ref_core_object(p);
1403         ur = tcore_pending_ref_user_request(p);
1404
1405         if (ur) {
1406                 if (response->success > 0) {
1407                         dbg("RESPONSE OK");
1408                         resp.err = CALL_ERROR_NONE;
1409                 } else {
1410                         err("RESPONSE NOT OK");
1411                         line = (const char *) response->final_response;
1412                         tokens = tcore_at_tok_new(line);
1413                         if (g_slist_length(tokens) < 1) {
1414                                 err("err cause not specified or string corrupted");
1415                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1416                         } else {
1417                                 resp.err = atoi(g_slist_nth_data(tokens, 0));
1418
1419                                 // TODO: CMEE error mapping is required.
1420                                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1421                         }
1422
1423                         // Free tokens
1424                         tcore_at_tok_free(tokens);
1425                 }
1426
1427                 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1428                 dbg("resp.id = %d", resp.id);
1429
1430                 // Send response to TAPI
1431                 tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
1432
1433                 if (!resp.err) {
1434                         GSList *active = NULL;
1435                         GSList *held = NULL;
1436                         CallObject *co = NULL;
1437                         gboolean *eflag = NULL;
1438
1439                         held = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_HELD);
1440                         if (!held) {
1441                                 err("Can't find held Call");
1442                                 return;
1443                         }
1444
1445                         active = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_ACTIVE);
1446                         if (!active) {
1447                                 dbg("Can't find active Call");
1448                                 return;
1449                         }
1450
1451                         while (held) {
1452                                 co = (CallObject *) held->data;
1453                                 if (!co) {
1454                                         err("Can't get held Call object");
1455                                         return;
1456                                 }
1457
1458                                 resp.id = tcore_call_object_get_id(co);
1459
1460                                 // Send response to TAPI
1461                                 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1462
1463                                 held = g_slist_next(held);
1464                         }
1465
1466                         while (active) {
1467                                 co = (CallObject *) active->data;
1468                                 if (!co) {
1469                                         err("[ error ] can't get active call object");
1470                                         return;
1471                                 }
1472
1473                                 resp.id = tcore_call_object_get_id(co);
1474
1475                                 // Send response to TAPI
1476                                 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1477                                 active = g_slist_next(active);
1478                         }
1479
1480                         eflag = g_new0(gboolean, 1);
1481                         *eflag = FALSE;
1482
1483                         dbg("calling _call_list_get");
1484                         _call_list_get(core_obj, eflag);
1485                 }
1486         } else {
1487                 err("User Request is NULL");
1488         }
1489
1490         dbg("Exit");
1491         return;
1492 }
1493
1494 static void on_confirmation_set_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1495 {
1496         const TcoreATResponse *resp = data;
1497         struct tnoti_call_sound_path *snd_path = user_data;
1498         TcorePlugin *plugin = tcore_pending_ref_plugin(p);
1499
1500         if (resp->success > 0) {
1501                 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
1502                                                                 tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL),
1503                                                                 TNOTI_CALL_SOUND_PATH,
1504                                                                 sizeof(struct tnoti_call_sound_path),
1505                                                                 (void *)snd_path);
1506         } else {
1507                 dbg("Error in set sound path");
1508         }
1509
1510         g_free(snd_path);
1511 }
1512
1513 static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1514 {
1515         UserRequest *ur = NULL;
1516         GSList *tokens = NULL;
1517         const char *line = NULL;
1518         const TcoreATResponse *response = data;
1519         char *resp_str = NULL;
1520         struct tresp_call_sound_set_path resp;
1521         gboolean error;
1522
1523         dbg("Entry");
1524         ur = tcore_pending_ref_user_request(p);
1525
1526         // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
1527         if (!response) {
1528                 err("Input data is NULL");
1529                 return;
1530         }
1531
1532         if (response->success > 0) {
1533                 dbg("RESPONSE OK");
1534
1535                 line = (const char *) (((GSList *) response->lines)->data);
1536                 tokens = tcore_at_tok_new(line);
1537
1538                 resp_str = g_slist_nth_data(tokens, 0);
1539                 if (!g_slist_nth_data(tokens, 0)) {
1540                         err("group_id is missing");
1541                         resp.err = TRUE;
1542                         goto OUT;
1543                 }
1544
1545                 if (!g_slist_nth_data(tokens, 1)) {
1546                         err(" function_id is missing");
1547                         resp.err = TRUE;
1548                         goto OUT;
1549                 }
1550
1551                 resp_str = g_slist_nth_data(tokens, 2);
1552
1553                 if (resp_str) {
1554                         error = atoi(resp_str);
1555                         if (0 == error) {
1556                                 dbg("Response is Success");
1557                                 resp.err = FALSE;
1558                         } else {
1559                                 resp.err = TRUE;
1560                         }
1561                 }
1562 OUT:
1563                 // Free tokens
1564                 tcore_at_tok_free(tokens);
1565         } else {
1566                 dbg("RESPONSE NOT OK");
1567
1568                 line = (const char *) response->final_response;
1569                 tokens = tcore_at_tok_new(line);
1570
1571                 if (g_slist_length(tokens) < 1) {
1572                         err("err cause not specified or string corrupted");
1573                         resp.err = TRUE;
1574                 } else {
1575                         error = atoi(g_slist_nth_data(tokens, 0));
1576
1577                         // TODO: CMEE error mapping is required.
1578                         resp.err = TRUE;
1579                 }
1580
1581                 // Free tokens
1582                 tcore_at_tok_free(tokens);
1583         }
1584
1585         if (ur) {
1586                 if ( resp.err ) {  // Send only failed notification . success notification send when destination device is set.
1587                         // Send notification to TAPI
1588                         tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1589                         setsoundpath = TRUE;
1590                 }
1591         } else {
1592                 err("User Request is NULL");
1593         }
1594
1595         dbg("Exit");
1596         return;
1597 }
1598
1599 static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1600 {
1601         UserRequest *ur = NULL;
1602         GSList *tokens = NULL;
1603         const char *line = NULL;
1604         char *resp_str = NULL;
1605         struct tresp_call_sound_set_path resp;
1606         const TcoreATResponse *response = data;
1607         gboolean error;
1608
1609         dbg("Entry");
1610
1611         ur = tcore_pending_ref_user_request(p);
1612         // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
1613
1614         if (!response) {
1615                 err("Input data is NULL");
1616                 return;
1617         }
1618
1619         if (ur) {
1620                 if (response->success > 0) {
1621                         dbg("RESPONSE OK");
1622
1623                         line = (const char *) (((GSList *) response->lines)->data);
1624                         tokens = tcore_at_tok_new(line);
1625
1626                         resp_str = g_slist_nth_data(tokens, 0);
1627                         if (!g_slist_nth_data(tokens, 0)) {
1628                                 dbg("group_id is missing");
1629                                 resp.err = TRUE;
1630                                 goto OUT;
1631                         }
1632
1633                         if (!g_slist_nth_data(tokens, 1)) {
1634                                 dbg("function_id is missing");
1635                                 resp.err = TRUE;
1636                                 goto OUT;
1637                         }
1638
1639                         resp_str = g_slist_nth_data(tokens, 2);
1640                         if (resp_str) {
1641                                 error = atoi(resp_str);
1642                                 if (0 == error) {
1643                                         dbg("Response is Success");
1644                                         resp.err = FALSE;
1645                                 } else {
1646                                         resp.err = TRUE;
1647                                 }
1648                         }
1649
1650 OUT:
1651                         // Free tokens
1652                         tcore_at_tok_free(tokens);
1653                 } else {
1654                         dbg("RESPONSE NOT OK");
1655
1656                         line = (const char *) response->final_response;
1657                         tokens = tcore_at_tok_new(line);
1658
1659                         if (g_slist_length(tokens) < 1) {
1660                                 err("err cause not specified or string corrupted");
1661                                 resp.err = TRUE;
1662                         } else {
1663                                 error = atoi(g_slist_nth_data(tokens, 0));
1664                                 // TODO: CMEE error mapping is required.
1665                                 resp.err = TRUE;
1666                         }
1667
1668                         // Free tokens
1669                         tcore_at_tok_free(tokens);
1670                 }
1671
1672                 if (setsoundpath == TRUE) {
1673                         setsoundpath = FALSE;
1674                 } else {
1675                         // Send response to TAPI
1676                         tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1677                 }
1678         } else {
1679                 dbg("User Request is NULL");
1680         }
1681
1682         dbg("Exit");
1683         return;
1684 }
1685
1686 static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1687 {
1688         UserRequest *ur = NULL;
1689         GSList *tokens = NULL;
1690         const char *line = NULL;
1691         const TcoreATResponse *response = data;
1692         char *resp_str = NULL;
1693         struct tresp_call_sound_set_volume_level resp;
1694         gboolean error;
1695
1696         ur = tcore_pending_ref_user_request(p);
1697         dbg("Entry");
1698         // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
1699         if (!response) {
1700                 err("Input data is NULL");
1701                 return;
1702         }
1703
1704         if (response->success > 0) {
1705                 dbg("RESPONSE OK");
1706
1707                 line = (const char *) (((GSList *) response->lines)->data);
1708                 tokens = tcore_at_tok_new(line);
1709
1710                 resp_str = g_slist_nth_data(tokens, 0);
1711                 if (!g_slist_nth_data(tokens, 0)) {
1712                         err("group_id is missing");
1713                         resp.err = TRUE;
1714                         goto OUT;
1715                 }
1716
1717                 if (!g_slist_nth_data(tokens, 1)) {
1718                         err("function_id is missing");
1719                         resp.err = TRUE;
1720                         goto OUT;
1721                 }
1722
1723                 resp_str = g_slist_nth_data(tokens, 2);
1724                 if (resp_str) {
1725                         error = atoi(resp_str);
1726
1727                         if (0 == error) {
1728                                 dbg("Response is Success ");
1729                                 resp.err = FALSE;
1730                         } else {
1731                                 resp.err = TRUE;
1732                         }
1733                 }
1734
1735 OUT:
1736                 // Free tokens
1737                 tcore_at_tok_free(tokens);
1738         } else {
1739                 dbg("RESPONSE NOT OK");
1740
1741                 line = (const char *) response->final_response;
1742                 tokens = tcore_at_tok_new(line);
1743
1744                 if (g_slist_length(tokens) < 1) {
1745                         err("err cause not specified or string corrupted");
1746                         resp.err = TRUE;
1747                 } else {
1748                         error = atoi(g_slist_nth_data(tokens, 0));
1749
1750                         // TODO: CMEE error mapping is required.
1751                         resp.err = TRUE;
1752                 }
1753
1754                 // Free tokens
1755                 tcore_at_tok_free(tokens);
1756         }
1757
1758         if (ur) {
1759                 if (resp.err && soundvolume == FALSE) {  // Send only failed notification . success notification send when destination device is set.
1760                         // Send reposne to TAPI
1761                         tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1762                         soundvolume = TRUE;
1763                 }
1764         } else {
1765                 err("User Request is NULL");
1766         }
1767
1768         dbg("Exit");
1769         return;
1770 }
1771
1772
1773 static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1774 {
1775         UserRequest *ur = NULL;
1776         GSList *tokens = NULL;
1777         const char *line = NULL;
1778         char *resp_str = NULL;
1779         const TcoreATResponse *response = data;
1780         struct tresp_call_sound_set_volume_level resp;
1781         gboolean error;
1782
1783         dbg("Entry");
1784
1785         ur = tcore_pending_ref_user_request(p);
1786
1787         // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
1788         if (!response) {
1789                 err("Input data is NULL");
1790                 return;
1791         }
1792
1793         if (ur) {
1794                 if (response->success > 0) {
1795                         dbg("RESPONSE OK");
1796                         line = (const char *) (((GSList *) response->lines)->data);
1797                         tokens = tcore_at_tok_new(line);
1798                         resp_str = g_slist_nth_data(tokens, 0);
1799
1800                         if (!g_slist_nth_data(tokens, 0)) {
1801                                 err("group_id is missing");
1802                                 resp.err = TRUE;
1803                                 goto OUT;
1804                         }
1805
1806                         if (!g_slist_nth_data(tokens, 1)) {
1807                                 err("function_id is missing");
1808                                 resp.err = TRUE;
1809                                 goto OUT;
1810                         }
1811
1812                         resp_str = g_slist_nth_data(tokens, 2);
1813
1814                         if (resp_str) {
1815                                 error = atoi(resp_str);
1816
1817                                 if (0 == error) {
1818                                         dbg("Response is Success");
1819                                         resp.err = FALSE;
1820                                 } else {
1821                                         resp.err = TRUE;
1822                                 }
1823                         }
1824
1825 OUT:
1826                         // Free tokens
1827                         tcore_at_tok_free(tokens);
1828                 } else {
1829                         dbg("RESPONSE NOT OK");
1830
1831                         line = (const char *) response->final_response;
1832                         tokens = tcore_at_tok_new(line);
1833
1834                         if (g_slist_length(tokens) < 1) {
1835                                 err("err cause not specified or string corrupted");
1836                                 resp.err = TRUE;
1837                         } else {
1838                                 error = atoi(g_slist_nth_data(tokens, 0));
1839
1840                                 // TODO: CMEE error mapping is required.
1841                                 resp.err = TRUE;
1842                         }
1843
1844                         tcore_at_tok_free(tokens);
1845                 }
1846
1847                 if (soundvolume == TRUE) {
1848                         soundvolume = FALSE;
1849                 } else {
1850                         // Send reposne to TAPI
1851                         tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1852                 }
1853         } else {
1854                 err("User Request is NULL");
1855         }
1856
1857         dbg("Exit");
1858         return;
1859 }
1860
1861
1862 static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
1863 {
1864         UserRequest *ur = NULL;
1865         GSList *tokens = NULL;
1866         const char *line = NULL;
1867         char *resp_str = NULL;
1868         struct tresp_call_mute resp;
1869         const TcoreATResponse *response = data;
1870         gboolean error;
1871
1872         dbg("Entry");
1873
1874         ur = tcore_pending_ref_user_request(p);
1875
1876         if (!response) {
1877                 err("Input data is NULL");
1878                 return;
1879         }
1880
1881         if (response->success > 0) {
1882                 dbg("RESPONSE OK");
1883
1884                 line = (const char *) (((GSList *) response->lines)->data);
1885                 tokens = tcore_at_tok_new(line);
1886                 resp_str = g_slist_nth_data(tokens, 0);
1887
1888                 if (!g_slist_nth_data(tokens, 0)) {
1889                         err("group_id is missing");
1890                         resp.err = TRUE;
1891                         goto OUT;
1892                 }
1893
1894                 if (!g_slist_nth_data(tokens, 1)) {
1895                         err(" function_id is missing");
1896                         resp.err = TRUE;
1897                         goto OUT;
1898                 }
1899
1900                 resp_str = g_slist_nth_data(tokens, 2);
1901
1902                 if (resp_str) {
1903                         error = atoi(resp_str);
1904                         if (0 == error) {
1905                                 dbg("Response is Success");
1906                                 resp.err = FALSE;
1907                         } else {
1908                                 resp.err = TRUE;
1909                         }
1910                 }
1911 OUT:
1912                 // Free tokens
1913                 tcore_at_tok_free(tokens);
1914         } else {
1915                 dbg("RESPONSE NOT OK");
1916
1917                 line = (const char *) response->final_response;
1918                 tokens = tcore_at_tok_new(line);
1919
1920                 if (g_slist_length(tokens) < 1) {
1921                         err("err cause not specified or string corrupted");
1922                         resp.err = TRUE;
1923                 } else {
1924                         error = atoi(g_slist_nth_data(tokens, 0));
1925
1926                         // TODO: CMEE error mapping is required.
1927                         resp.err = TRUE;
1928                 }
1929
1930                 // Free tokens
1931                 tcore_at_tok_free(tokens);
1932         }
1933
1934         if (ur) {
1935                 tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
1936         } else {
1937                 err("User Request is NULL");
1938         }
1939
1940         dbg("Exit");
1941         return;
1942 }
1943
1944 static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
1945 {
1946         const TcoreATResponse *response = NULL;
1947         struct tresp_call_unmute resp;
1948         GSList *tokens = NULL;
1949         const char *line = NULL;
1950         UserRequest *ur = NULL;
1951         char *resp_str = NULL;
1952         gboolean error;
1953
1954         dbg("Entry");
1955
1956         response = (TcoreATResponse *) data;
1957         ur = tcore_pending_ref_user_request(p);
1958
1959         if (!response) {
1960                 err("Input data is NULL");
1961                 return;
1962         }
1963
1964         if (response->success > 0) {
1965                 dbg("RESPONSE OK");
1966
1967                 line = (const char *) (((GSList *) response->lines)->data);
1968                 tokens = tcore_at_tok_new(line);
1969                 resp_str = g_slist_nth_data(tokens, 0);
1970
1971                 if (!g_slist_nth_data(tokens, 0)) {
1972                         err("group_id is missing");
1973                         resp.err = TRUE;
1974                         goto OUT;
1975                 }
1976
1977                 if (!g_slist_nth_data(tokens, 1)) {
1978                         err(" function_id is missing");
1979                         resp.err = TRUE;
1980                         goto OUT;
1981                 }
1982
1983                 resp_str = g_slist_nth_data(tokens, 2);
1984
1985                 if (resp_str) {
1986                         error = atoi(resp_str);
1987                         if (0 == error) {
1988                                 dbg("Response is Success");
1989                                 resp.err = FALSE;
1990                         } else {
1991                                 resp.err = TRUE;
1992                         }
1993                 }
1994 OUT:
1995                 // Free tokens
1996                 tcore_at_tok_free(tokens);
1997         } else {
1998                 dbg("RESPONSE NOT OK");
1999
2000                 line = (const char *) response->final_response;
2001                 tokens = tcore_at_tok_new(line);
2002
2003                 if (g_slist_length(tokens) < 1) {
2004                         err("err cause not specified or string corrupted");
2005                         resp.err = TRUE;
2006                 } else {
2007                         error = atoi(g_slist_nth_data(tokens, 0));
2008
2009                         // TODO: CMEE error mapping is required.
2010                         resp.err = TRUE;
2011                 }
2012
2013                 // Free tokens
2014                 tcore_at_tok_free(tokens);
2015         }
2016
2017         if (ur) {
2018                 tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
2019         } else {
2020                 err("User Request is NULL");
2021         }
2022
2023         dbg("Exit");
2024         return;
2025 }
2026
2027 // RESPONSE
2028 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
2029 {
2030         TcorePlugin *plugin = NULL;
2031         CoreObject *core_obj = NULL;
2032         CallObject *co = NULL;
2033         struct clcc_call_t *call_list = NULL;
2034         gboolean *event_flag = (gboolean *) user_data;
2035         const TcoreATResponse *response = data;
2036         GSList *resp_data = NULL;
2037         char *line = NULL;
2038
2039         int cllc_info = 0, countCalls = 0, countValidCalls = 0;
2040         int error = 0;
2041
2042         dbg("Entry");
2043
2044         plugin = tcore_pending_ref_plugin(p);
2045         core_obj = tcore_pending_ref_core_object(p);
2046
2047         if (response->success > 0) {
2048                 dbg("RESPONCE OK");
2049                 if (response->lines) {
2050                         resp_data = (GSList *) response->lines;
2051                         countCalls = g_slist_length(resp_data);
2052                         dbg("Total records : %d", countCalls);
2053                 }
2054
2055                 if (0 == countCalls) {
2056                         err("Call count is zero");
2057                         if (event_flag) {
2058                                 g_free(event_flag);
2059                                 event_flag = NULL;
2060                         }
2061                         return;
2062                 }
2063
2064                 call_list = g_new0(struct clcc_call_t, countCalls);
2065
2066                 for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
2067                         line = (char *) (resp_data->data);
2068
2069                         error = _callFromCLCCLine(line, call_list + countValidCalls);
2070                         if (0 != error) {
2071                                 continue;
2072                         }
2073
2074                         co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
2075                         if (!co) {
2076                                 co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
2077                                 if (!co) {
2078                                         err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
2079                                         continue;
2080                                 }
2081                         }
2082
2083                         // Call set parameters
2084                         tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
2085                         tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
2086                         tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
2087                         tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
2088                         tcore_call_object_set_active_line(co, 0);
2089
2090                         if (*event_flag) {
2091                                 dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
2092                                 _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
2093                         } else {
2094                                 // Set Status
2095                                 tcore_call_object_set_status(co, call_list[cllc_info].info.status);
2096
2097                                 dbg("Call id : (%d)", call_list[cllc_info].info.id);
2098                                 dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
2099                                 dbg("Call type : (%d)", call_list[cllc_info].info.type);
2100                                 dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
2101                                 dbg("Call number : (%s)", call_list[cllc_info].number);
2102                                 dbg("Call status : (%d)", call_list[cllc_info].info.status);
2103                         }
2104                 }
2105
2106                 // Free Call list
2107                 g_free(call_list);
2108         }
2109
2110         // Free User data
2111         if (event_flag) {
2112         g_free(event_flag);
2113                 event_flag = NULL;
2114         }
2115
2116         dbg("Exit");
2117         return;
2118 }
2119
2120 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
2121 {
2122         TcorePlugin *plugin = NULL;
2123         CoreObject *core_obj = NULL;
2124         CallObject *co = (CallObject *) user_data;
2125         const TcoreATResponse *response = data;
2126         const char *line = NULL;
2127         struct tnoti_call_status_idle call_status;
2128         GSList *tokens = NULL;
2129         char *resp_str;
2130         int error;
2131
2132         dbg("Entry");
2133         plugin = tcore_pending_ref_plugin(p);
2134         core_obj = tcore_pending_ref_core_object(p);
2135
2136         if (response->success > 0) {
2137                 dbg("RESPONSE OK");
2138                 line = (const char *) (((GSList *) response->lines)->data);
2139                 tokens = tcore_at_tok_new(line);
2140                 resp_str = g_slist_nth_data(tokens, 0);
2141                 if (!resp_str) {
2142                         err("call end cause - report value missing");
2143                 } else {
2144                         resp_str = g_slist_nth_data(tokens, 1);
2145                         if (!resp_str) {
2146                                 err("call end cause value missing");
2147                         }
2148                         error = atoi(resp_str);
2149                         dbg("call end cause - %d", error);
2150                         call_status.cause = _compare_call_end_cause(error);
2151                         dbg("TAPI call end cause - %d", call_status.cause);
2152                 }
2153
2154                 // Free tokens
2155                 tcore_at_tok_free(tokens);
2156         } else {
2157                 err("RESPONSE NOT OK");
2158                 line = (char *) response->final_response;
2159                 tokens = tcore_at_tok_new(line);
2160                 if (g_slist_length(tokens) < 1) {
2161                         err("err cause not specified or string corrupted");
2162                 } else {
2163                         err(" err cause  value: %d", atoi(g_slist_nth_data(tokens, 0)));
2164                 }
2165                 call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
2166                 // Free tokens
2167                 tcore_at_tok_free(tokens);
2168         }
2169
2170         call_status.type = tcore_call_object_get_type(co);
2171         dbg("data.type : [%d]", call_status.type);
2172
2173         call_status.id = tcore_call_object_get_id(co);
2174         dbg("data.id : [%d]", call_status.id);
2175
2176         // Set Status
2177         tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
2178
2179         // Send Notification to TAPI
2180         tcore_server_send_notification(tcore_plugin_ref_server(plugin),
2181                                                                    core_obj,
2182                                                                    TNOTI_CALL_STATUS_IDLE,
2183                                                                    sizeof(struct tnoti_call_status_idle),
2184                                                                    (void *) &call_status);
2185
2186         // Free Call object
2187         tcore_call_object_free(core_obj, co);
2188 }
2189
2190 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
2191 {
2192         // +CLCC: 1,0,2,0,0,"18005551212",145
2193         // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
2194         int state;
2195         int mode;
2196         int isMT;
2197         char *num = NULL;
2198         unsigned int num_type;
2199         GSList *tokens = NULL;
2200         char *resp = NULL;
2201
2202         dbg("Entry");
2203
2204         tokens = tcore_at_tok_new(line);
2205         // parse <id>
2206         resp = g_slist_nth_data(tokens, 0);
2207         if (!resp) {
2208                 err("InValid ID");
2209                 goto ERROR;
2210         }
2211         p_call->info.id = atoi(resp);
2212         dbg("id : [%d]\n", p_call->info.id);
2213
2214         // parse <dir>
2215         resp = g_slist_nth_data(tokens, 1);
2216         if (!resp) {
2217                 err("InValid Dir");
2218                 goto ERROR;
2219         }
2220         isMT = atoi(resp);
2221         if (0 == isMT) {
2222                 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
2223         } else {
2224                 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
2225         }
2226         dbg("Direction : [ %d ]\n", p_call->info.direction);
2227
2228         // parse <stat>
2229         resp = g_slist_nth_data(tokens, 2);
2230         if (!resp) {
2231                 err("InValid Stat");
2232                 goto ERROR;
2233         }
2234         state = atoi(resp);
2235         dbg("Call state : %d", state);
2236         switch (state) {
2237         case 0:     // active
2238                 p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
2239                 break;
2240
2241         case 1:
2242                 p_call->info.status = TCORE_CALL_STATUS_HELD;
2243                 break;
2244
2245         case 2:
2246                 p_call->info.status = TCORE_CALL_STATUS_DIALING;
2247                 break;
2248
2249         case 3:
2250                 p_call->info.status = TCORE_CALL_STATUS_ALERT;
2251                 break;
2252
2253         case 4:
2254                 p_call->info.status = TCORE_CALL_STATUS_INCOMING;
2255                 break;
2256
2257         case 5:
2258                 p_call->info.status = TCORE_CALL_STATUS_WAITING;
2259                 break;
2260         }
2261         dbg("Status : [%d]\n", p_call->info.status);
2262
2263         // parse <mode>
2264         resp = g_slist_nth_data(tokens, 3);
2265         if (!resp) {
2266                 err("InValid Mode");
2267                 goto ERROR;
2268         }
2269         mode = atoi(resp);
2270         switch (mode) {
2271         case 0:
2272                 p_call->info.type = TCORE_CALL_TYPE_VOICE;
2273                 break;
2274
2275         case 1:
2276                 p_call->info.type = TCORE_CALL_TYPE_VIDEO;
2277                 break;
2278
2279         default:        // only Voice/VT call is supported in CS. treat other unknown calls as error
2280                 dbg("invalid type : [%d]\n", mode);
2281                 goto ERROR;
2282         }
2283         dbg("Call type : [%d]\n", p_call->info.type);
2284
2285         // parse <mpty>
2286         resp = g_slist_nth_data(tokens, 4);
2287         if (!resp) {
2288                 err("InValid Mpty");
2289                 goto ERROR;
2290         }
2291
2292         p_call->info.mpty = atoi(resp);
2293         dbg("Mpty : [ %d ]\n", p_call->info.mpty);
2294
2295         // parse <num>
2296         resp = g_slist_nth_data(tokens, 5);
2297         dbg("Incoming number - %s and its len  - %d", resp, strlen(resp));
2298
2299         // tolerate null here
2300         if (!resp) {
2301                 err("Number is NULL");
2302                 goto ERROR;
2303         }
2304         // Strike off double quotes
2305         num = util_removeQuotes(resp);
2306         dbg("num  after removing quotes - %s", num);
2307
2308         p_call->info.num_len = strlen(resp);
2309         dbg("num_len : [0x%x]\n", p_call->info.num_len);
2310
2311         // parse <num type>
2312         resp = g_slist_nth_data(tokens, 6);
2313         if (!resp) {
2314                 dbg("InValid Num type");
2315                 goto ERROR;
2316         }
2317         p_call->info.num_type = atoi(resp);
2318         dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
2319
2320         // check number is international or national.
2321         num_type = ((p_call->info.num_type) >> 4) & 0x07;
2322         dbg("called party's type of number : [0x%x]\n", num_type);
2323
2324         if (num_type == 1 && num[0] != '+') {
2325                 // international number
2326                 p_call->number[0] = '+';
2327                 memcpy(&(p_call->number[1]), num, strlen(num));
2328         } else {
2329                 memcpy(&(p_call->number), num, strlen(num));
2330         }
2331         dbg("incoming number - %s", p_call->number);
2332
2333         g_free(num);
2334         num = NULL;
2335         // Free tokens
2336         tcore_at_tok_free(tokens);
2337
2338         dbg("Exit");
2339         return 0;
2340
2341 ERROR:
2342         err("Invalid CLCC line");
2343
2344         if (num) {
2345                 g_free(num);
2346                 num = NULL;
2347         }
2348
2349         // Free tokens
2350         tcore_at_tok_free(tokens);
2351         err("Exit");
2352         return -1;
2353 }
2354
2355 // NOTIFICATION
2356 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
2357 {
2358         GSList *tokens = NULL;
2359         const char *line = NULL;
2360         char *pId;
2361         int call_id;
2362         gboolean *eflag;
2363         GSList *pList = NULL;
2364         CallObject *co = NULL, *dupco = NULL;
2365
2366         dbg("function entrance");
2367         // check call with waiting status already exist
2368         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
2369
2370         if (pList != NULL) {
2371                 dbg("[error]Waiting call already exist. skip");
2372                 return;
2373         }
2374         // check call with incoming status already exist
2375         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2376
2377         if (pList != NULL) {
2378                 dbg("[error]incoming call already exist. skip");
2379                 return;
2380         }
2381         line = (char *) data;
2382         tokens = tcore_at_tok_new(line);
2383
2384         pId = g_slist_nth_data(tokens, 0);
2385         if (!pId) {
2386                 dbg("[error]:Call id is missing from +XCALLSTAT indication");
2387                 tcore_at_tok_free(tokens);
2388                 return;
2389         }
2390
2391         call_id = atoi(pId);
2392         dupco = tcore_call_object_find_by_id(o, call_id);
2393         if (dupco != NULL) {
2394                 dbg("co with same id already exist. skip");
2395                 tcore_at_tok_free(tokens);
2396                 return;
2397         }
2398         co = tcore_call_object_new(o, call_id);
2399         if (!co) {
2400                 dbg("[ error ] co is NULL");
2401                 tcore_at_tok_free(tokens);
2402                 return;
2403         }
2404
2405         tcore_at_tok_free(tokens);
2406
2407         eflag = g_new0(gboolean, 1);
2408         *eflag = TRUE;
2409         dbg("calling _call_list_get");
2410         _call_list_get(o, eflag);
2411 }
2412
2413 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
2414 {
2415         GSList *tokens = NULL;
2416         const char *line = NULL;
2417         char *pId;
2418         int call_id;
2419         gboolean *eflag;
2420         GSList *pList = NULL;
2421         CallObject *co = NULL, *dupco = NULL;
2422
2423         dbg("function entrance");
2424         // check call with incoming status already exist
2425         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2426
2427         if (pList != NULL) {
2428                 dbg("incoming call already exist. skip");
2429                 return;
2430         }
2431
2432         line = (char *) data;
2433         tokens = tcore_at_tok_new(line);
2434
2435         pId = g_slist_nth_data(tokens, 0);
2436         if (!pId) {
2437                 dbg("Error:Call id is missing from %XCALLSTAT indication");
2438                 tcore_at_tok_free(tokens);
2439                 return;
2440         }
2441
2442         call_id = atoi(pId);
2443
2444         dupco = tcore_call_object_find_by_id(o, call_id);
2445         if (dupco != NULL) {
2446                 dbg("co with same id already exist. skip");
2447                 tcore_at_tok_free(tokens);
2448                 return;
2449         }
2450
2451         co = tcore_call_object_new(o, call_id);
2452         if (!co) {
2453                 dbg("[ error ] co is NULL");
2454                 tcore_at_tok_free(tokens);
2455                 return;
2456         }
2457
2458         dbg("freeing  at token")
2459         tcore_at_tok_free(tokens);
2460
2461         eflag = g_new0(gboolean, 1);
2462         *eflag = TRUE;
2463
2464         dbg("calling  _call_list_get");
2465         _call_list_get(o, eflag);
2466 }
2467
2468 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
2469 {
2470         char *cmd = NULL;
2471         TcorePlugin *plugin = NULL;
2472         CallObject *co = NULL;
2473         int id = -1;
2474         int status = 0;
2475         int type = 0;
2476         char *stat = NULL;
2477         char *pCallId = NULL;
2478         GSList *tokens = NULL;
2479         gboolean *eflag = NULL;
2480         enum tcore_call_status co_status;
2481
2482         dbg("function entrance");
2483         plugin = tcore_object_ref_plugin(o);
2484         cmd = (char *) data;
2485         tokens = tcore_at_tok_new(cmd);
2486
2487         // parse <Call Id>
2488         pCallId = g_slist_nth_data(tokens, 0);
2489         if (!pCallId) {
2490                 dbg("CallId is missing from %XCALLSTAT indication");
2491                 tcore_at_tok_free(tokens);
2492                 return;
2493         } else {
2494                 id = atoi(pCallId);
2495                 dbg("call id = %d", id);
2496                 // parse <Stat>
2497                 if ((stat = g_slist_nth_data(tokens, 1))) {
2498                         status = atoi(stat);
2499                 }
2500                 dbg("call status = %d", status);
2501         }
2502
2503         tcore_at_tok_free(tokens);
2504         co_status = _call_status(status);
2505
2506         dbg("co_status = %d", co_status);
2507         switch (co_status) {
2508         case CALL_STATUS_ACTIVE:
2509         {
2510                 dbg("call(%d) status : [ ACTIVE ]", id);
2511                 co = tcore_call_object_find_by_id(o, id);
2512                 if (!co) {
2513                         dbg("co is NULL");
2514                         return;
2515                 }
2516                 _call_status_active(plugin, co);
2517         }
2518         break;
2519
2520         case CALL_STATUS_HELD:
2521                 dbg("call(%d) status : [ held ]", id);
2522                 break;
2523
2524         case CALL_STATUS_DIALING:
2525         {
2526                 dbg("call(%d) status : [ dialing ]", id);
2527                 co = tcore_call_object_find_by_id(o, id);
2528                 if (!co) {
2529                         co = tcore_call_object_new(o, id);
2530                         if (!co) {
2531                                 dbg("error : tcore_call_object_new [ id : %d ]", id);
2532                                 return;
2533                         }
2534                 }
2535
2536                 tcore_call_object_set_type(co, call_type(type));
2537                 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
2538                 _call_status_dialing(plugin, co);
2539         }
2540         break;
2541
2542         case CALL_STATUS_ALERT:
2543         {
2544                 dbg("call(%d) status : [ alert ]", id);
2545                 co = tcore_call_object_find_by_id(o, id);
2546                 if (!co) {
2547                         dbg("co is NULL");
2548                         return;
2549                 }
2550                 // Store dialed number information into Call object.
2551                 eflag = g_new0(gboolean, 1);
2552                 *eflag = TRUE;
2553                 dbg("calling _call_list_get");
2554                 _call_list_get(o, eflag);
2555         }
2556         break;
2557
2558         case CALL_STATUS_INCOMING:
2559         case CALL_STATUS_WAITING:
2560                 dbg("call(%d) status : [ incoming ]", id);
2561                 break;
2562
2563         case CALL_STATUS_IDLE:
2564         {
2565                 dbg("call(%d) status : [ release ]", id);
2566
2567                 co = tcore_call_object_find_by_id(o, id);
2568                 if (!co) {
2569                         dbg("co is NULL");
2570                         return;
2571                 }
2572
2573                 plugin = tcore_object_ref_plugin(o);
2574                 if (!plugin) {
2575                         dbg("plugin is NULL");
2576                         return;
2577                 }
2578                 _call_status_idle(plugin, co);
2579         }
2580         break;
2581
2582         default:
2583                 dbg("invalid call status", id);
2584                 break;
2585         }
2586 }
2587
2588 static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
2589 {
2590         struct treq_call_dial *data = 0;
2591         char *raw_str = NULL;
2592         char *cmd_str = NULL;
2593         const char *cclir;
2594         enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
2595         TcorePending *pending = NULL;
2596         TcoreATRequest *req;
2597         gboolean ret = FALSE;
2598
2599         dbg("function entrance");
2600
2601         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2602                 dbg("cp not ready/n");
2603                 return TCORE_RETURN_ENOSYS;
2604         }
2605
2606         data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
2607         if (data->type == CALL_TYPE_VIDEO) {
2608                 dbg("invalid call type")
2609                 return TCORE_RETURN_FAILURE;
2610         }
2611
2612         clir = _get_clir_status(data->number);
2613
2614         // Compose ATD Cmd string
2615         switch (clir) {
2616         case TCORE_CALL_CLI_MODE_PRESENT:
2617                 dbg("CALL_CLI_MODE_PRESENT");
2618                 cclir = "I";
2619                 break;  // invocation
2620
2621         case TCORE_CALL_CLI_MODE_RESTRICT:
2622                 dbg("CALL_CLI_MODE_RESTRICT");
2623                 cclir = "i";
2624                 break;  // suppression
2625
2626         case TCORE_CALL_CLI_MODE_DEFAULT:
2627         default:
2628                 cclir = "";
2629                 dbg("CALL_CLI_MODE_DEFAULT");
2630                 break;   // subscription default
2631         }
2632
2633         dbg("data->number = %s", data->number);
2634
2635         raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
2636         cmd_str = g_strdup_printf("%s", raw_str);
2637
2638         dbg("request command : %s", cmd_str);
2639
2640         pending = tcore_pending_new(o, 0);
2641         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2642         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2643
2644         tcore_pending_set_request_data(pending, 0, req);
2645         ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
2646
2647         g_free(raw_str);
2648         g_free(cmd_str);
2649
2650         if (!ret) {
2651                 dbg("AT request(%s) sent failed", req->cmd);
2652                 return TCORE_RETURN_FAILURE;
2653         }
2654
2655         dbg("AT request(%s) sent success", req->cmd);
2656
2657         return TCORE_RETURN_SUCCESS;
2658 }
2659
2660 static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
2661 {
2662         char *cmd_str = NULL;
2663         CallObject *co = NULL;
2664         struct treq_call_answer *data = 0;
2665         TcorePending *pending = NULL;
2666         TcoreATRequest *req;
2667         gboolean ret = FALSE;
2668
2669         dbg("function entrance");
2670
2671         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2672                 dbg("cp not ready/n");
2673                 return TCORE_RETURN_ENOSYS;
2674         }
2675
2676         data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
2677         co = tcore_call_object_find_by_id(o, data->id);
2678         if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
2679                 dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
2680
2681                 cmd_str = g_strdup_printf("%s", "ATA");
2682                 pending = tcore_pending_new(o, 0);
2683                 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2684                 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2685
2686                 tcore_pending_set_request_data(pending, 0, req);
2687                 ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
2688                 g_free(cmd_str);
2689
2690                 if (!ret) {
2691                         dbg("AT request(%s) sent failed", req->cmd);
2692                         return TCORE_RETURN_FAILURE;
2693                 }
2694         } else {
2695                 switch (data->type) {
2696                 case CALL_ANSWER_TYPE_REJECT:
2697                 {
2698                         dbg("call answer reject");
2699                         tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
2700                 }
2701                 break;
2702
2703                 case CALL_ANSWER_TYPE_REPLACE:
2704                 {
2705                         dbg("call answer replace");
2706                         tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
2707                 }
2708                 break;
2709
2710                 case CALL_ANSWER_TYPE_HOLD_ACCEPT:
2711                 {
2712                         dbg("call answer hold and accept");
2713                         tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
2714                 }
2715                 break;
2716
2717                 default:
2718                         dbg("[ error ] wrong answer type [ %d ]", data->type);
2719                         return TCORE_RETURN_FAILURE;
2720                 }
2721         }
2722
2723         return TCORE_RETURN_SUCCESS;
2724 }
2725
2726 static TReturn s_call_release(CoreObject *o, UserRequest *ur)
2727 {
2728         CallObject *co = NULL;
2729         struct treq_call_end *data = 0;
2730         UserRequest *ur_dup = NULL;
2731         char *chld0_cmd = NULL;
2732         char *chld1_cmd = NULL;
2733         TcorePending *pending = NULL, *pending1 = NULL;
2734         TcoreATRequest *req, *req1;
2735         gboolean ret = FALSE;
2736
2737         dbg("function entrance");
2738         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2739                 dbg("cp not ready/n");
2740                 return TCORE_RETURN_ENOSYS;
2741         }
2742         data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
2743         co = tcore_call_object_find_by_id(o, data->id);
2744
2745         dbg("type of release call = %d", data->type);
2746
2747         if (data->type == CALL_END_TYPE_ALL) {
2748                 // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
2749                 chld0_cmd = g_strdup("AT+CHLD=0");
2750                 chld1_cmd = g_strdup("AT+CHLD=1");
2751
2752                 pending = tcore_pending_new(o, 0);
2753                 req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
2754
2755                 dbg("input command is %s", chld0_cmd);
2756                 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2757
2758                 tcore_pending_set_request_data(pending, 0, req);
2759                 ur_dup = tcore_user_request_new(NULL, NULL);
2760                 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
2761                 g_free(chld0_cmd);
2762
2763                 if (!ret) {
2764                         dbg("AT request %s has failed ", req->cmd);
2765                         if (ur_dup) {
2766                                 tcore_user_request_free(ur_dup);
2767                                 ur_dup = NULL;
2768                         }
2769                         g_free(chld1_cmd);
2770                         return TCORE_RETURN_FAILURE;
2771                 }
2772
2773                 pending1 = tcore_pending_new(o, 0);
2774                 req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
2775
2776                 dbg("input command is %s", chld1_cmd);
2777                 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2778
2779                 tcore_pending_set_request_data(pending1, 0, req1);
2780                 ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
2781                 g_free(chld1_cmd);
2782
2783                 if (!ret) {
2784                         dbg("AT request %s has failed ", req->cmd);
2785                         return TCORE_RETURN_FAILURE;
2786                 }
2787         } else {
2788                 switch (data->type) {
2789                 case CALL_END_TYPE_DEFAULT:
2790                 {
2791                         int id = 0;
2792                         id = tcore_call_object_get_id(co);
2793
2794                         dbg("call end call id [%d]", id);
2795                         tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
2796                 }
2797                 break;
2798
2799                 case CALL_END_TYPE_ACTIVE_ALL:
2800                 {
2801                         dbg("call end all active");
2802                         tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
2803                 }
2804                 break;
2805
2806                 case CALL_END_TYPE_HOLD_ALL:
2807                 {
2808                         dbg("call end all held");
2809                         tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
2810                 }
2811                 break;
2812
2813                 default:
2814                         dbg("[ error ] wrong end type [ %d ]", data->type);
2815                         return TCORE_RETURN_FAILURE;
2816                 }
2817         }
2818
2819         return TCORE_RETURN_SUCCESS;
2820 }
2821
2822 static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
2823 {
2824         struct treq_call_hold *hold = 0;
2825         CallObject *co = NULL;
2826
2827         dbg("function entrance");
2828
2829         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2830                 dbg("cp not ready/n");
2831                 return TCORE_RETURN_ENOSYS;
2832         }
2833
2834         hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
2835         dbg("call id : [ %d ]", hold->id);
2836
2837         co = tcore_call_object_find_by_id(o, hold->id);
2838         tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
2839
2840         return TCORE_RETURN_SUCCESS;
2841 }
2842
2843 static TReturn s_call_active(CoreObject *o, UserRequest *ur)
2844 {
2845         struct treq_call_active *active = 0;
2846         CallObject *co = NULL;
2847
2848         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2849                 dbg("cp not ready/n");
2850                 return TCORE_RETURN_ENOSYS;
2851         }
2852
2853         active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
2854         dbg("call id : [ %d ]", active->id);
2855
2856         co = tcore_call_object_find_by_id(o, active->id);
2857         tcore_call_control_active(o, ur, on_confirmation_call_active, co);
2858
2859         return TCORE_RETURN_SUCCESS;
2860 }
2861
2862 static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
2863 {
2864         struct treq_call_swap *swap = NULL;
2865         CallObject *co = NULL;
2866
2867         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2868                 dbg("cp not ready/n");
2869                 return TCORE_RETURN_ENOSYS;
2870         }
2871
2872         swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
2873         dbg("call id : [ %d ]", swap->id);
2874
2875         co = tcore_call_object_find_by_id(o, swap->id);
2876         tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
2877
2878         return TCORE_RETURN_SUCCESS;
2879 }
2880
2881 static TReturn s_call_join(CoreObject *o, UserRequest *ur)
2882 {
2883         struct treq_call_join *join = 0;
2884         CallObject *co = NULL;
2885
2886         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2887                 dbg("cp not ready/n");
2888                 return TCORE_RETURN_ENOSYS;
2889         }
2890
2891         join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
2892         dbg("call id : [ %d ]", join->id);
2893
2894         co = tcore_call_object_find_by_id(o, join->id);
2895         tcore_call_control_join(o, ur, on_confirmation_call_join, co);
2896
2897         return TCORE_RETURN_SUCCESS;
2898 }
2899
2900 static TReturn s_call_split(CoreObject *o, UserRequest *ur)
2901 {
2902         struct treq_call_split *split = 0;
2903         CallObject *co = NULL;
2904
2905         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2906                 dbg("cp not ready/n");
2907                 return TCORE_RETURN_ENOSYS;
2908         }
2909
2910         split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
2911         co = tcore_call_object_find_by_id(o, split->id);
2912         dbg("call id : [ %d ]", split->id);
2913
2914         tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
2915
2916         return TCORE_RETURN_SUCCESS;
2917 }
2918
2919 static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
2920 {
2921         struct treq_call_deflect *deflect = 0;
2922         CallObject *co = NULL;
2923
2924         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2925                 dbg("cp not ready/n");
2926                 return TCORE_RETURN_ENOSYS;
2927         }
2928
2929         deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
2930         co = tcore_call_object_find_by_number(o, deflect->number);
2931         dbg("deflect number: [ %s ]", deflect->number);
2932
2933         tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
2934
2935         return TCORE_RETURN_SUCCESS;
2936 }
2937
2938 static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
2939 {
2940         struct treq_call_transfer *transfer = 0;
2941         CallObject *co = NULL;
2942
2943         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2944                 dbg("cp not ready/n");
2945                 return TCORE_RETURN_ENOSYS;
2946         }
2947
2948         transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
2949         dbg("call id : [ %d ]", transfer->id);
2950
2951         co = tcore_call_object_find_by_id(o, transfer->id);
2952         tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
2953
2954         return TCORE_RETURN_SUCCESS;
2955 }
2956
2957 static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
2958 {
2959         char *cmd_str = NULL;
2960         TcorePending *pending = NULL;
2961         TcoreATRequest *req;
2962         UserRequest *dup;
2963         gboolean ret = FALSE;
2964         struct treq_call_dtmf *dtmf = 0;
2965         char *dtmfstr = NULL, *tmp_dtmf = NULL;
2966         unsigned int dtmf_count;
2967
2968         dbg("Function enter");
2969
2970         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2971                 dbg("cp not ready/n");
2972                 return TCORE_RETURN_ENOSYS;
2973         }
2974
2975         dup = tcore_user_request_new(NULL, NULL);
2976         (void) _set_dtmf_tone_duration(o, dup);
2977
2978         dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
2979         dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1);    // DTMF digits + comma for each dtmf digit.
2980
2981         if (dtmfstr == NULL) {
2982                 dbg("Memory allocation failed");
2983                 return TCORE_RETURN_FAILURE;
2984         }
2985
2986         tmp_dtmf = dtmfstr;
2987
2988         for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
2989                 *tmp_dtmf = dtmf->digits[dtmf_count];
2990                 tmp_dtmf++;
2991
2992                 *tmp_dtmf = COMMA;
2993                 tmp_dtmf++;
2994         }
2995
2996         // last digit is having COMMA , overwrite it with '\0' .
2997         *(--tmp_dtmf) = '\0';
2998         dbg("Input DTMF string(%s)", dtmfstr);
2999
3000         // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
3001         cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
3002         dbg("request command : %s", cmd_str);
3003
3004         pending = tcore_pending_new(o, 0);
3005         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3006         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3007
3008         tcore_pending_set_request_data(pending, 0, req);
3009         ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
3010         g_free(dtmfstr);
3011         g_free(cmd_str);
3012
3013         if (!ret) {
3014                 dbg("AT request sent failed")
3015                 return TCORE_RETURN_FAILURE;
3016         }
3017
3018         return TCORE_RETURN_SUCCESS;
3019 }
3020
3021 static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
3022 {
3023         UserRequest *ur_dup = NULL;
3024         TcorePending *pending = NULL, *pending1 = NULL;
3025         TcoreATRequest *req, *req1;
3026         char *cmd_str = NULL, *cmd_str1 = NULL;
3027         int device_type = -1;
3028         struct treq_call_sound_set_path *sound_path = 0;
3029         gboolean ret = FALSE;
3030         TcorePlugin *plugin = tcore_object_ref_plugin(o);
3031         const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
3032
3033         dbg("function entrance");
3034
3035         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3036                 dbg("cp not ready/n");
3037                 return TCORE_RETURN_ENOSYS;
3038         }
3039         sound_path = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
3040         if (sound_path == NULL) {
3041                 dbg("invaling user request");
3042                 return TCORE_RETURN_FAILURE;
3043         }
3044         dbg("audio device type - 0x%x", sound_path->path);
3045         switch (sound_path->path) {
3046         case CALL_SOUND_PATH_HANDSET:
3047                 device_type = 1;
3048                 break;
3049
3050         case CALL_SOUND_PATH_HEADSET:
3051                 device_type = 2;
3052                 break;
3053
3054         case CALL_SOUND_PATH_HEADSET_3_5PI:
3055                 device_type = 3;
3056                 break;
3057
3058         case CALL_SOUND_PATH_SPEAKER:
3059                 device_type = 4;
3060                 break;
3061
3062         case CALL_SOUND_PATH_HANDFREE:
3063                 device_type = 5;
3064                 break;
3065
3066         case CALL_SOUND_PATH_HEADSET_HAC:
3067                 device_type = 6;
3068                 break;
3069
3070         case CALL_SOUND_PATH_BLUETOOTH:
3071         case CALL_SOUND_PATH_STEREO_BLUETOOTH:
3072                 device_type = 7;
3073                 break;
3074
3075         case CALL_SOUND_PATH_BT_NSEC_OFF:
3076         case CALL_SOUND_PATH_MIC1:
3077         case CALL_SOUND_PATH_MIC2:
3078         default:
3079                 dbg("unsupported device type");
3080                 return TCORE_RETURN_FAILURE;
3081         }
3082
3083         if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
3084                 struct tnoti_call_sound_path *tnoti_snd_path;
3085
3086                 tnoti_snd_path = g_try_new0(struct tnoti_call_sound_path, 1);
3087                 if (!tnoti_snd_path)
3088                         return TCORE_RETURN_ENOMEM;
3089
3090                 tnoti_snd_path->path = sound_path->path;
3091
3092                 /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
3093                 if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
3094                         call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,3,0,1,0,0,0,0,0,0,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
3095                         call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,2,0,1,0,0,0,0,0,0,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
3096                 }
3097                 else {
3098                         call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,3,0,1,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
3099                         call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,2,0,1,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
3100                 }
3101
3102                 /* Configure modem I2S2 and do the modem routing */
3103                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,4,0,0,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
3104                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,3,0,0,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
3105                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
3106                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
3107                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
3108                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
3109
3110                 /* amc enable */
3111                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
3112                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
3113                 /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
3114
3115                 pending = tcore_pending_new(o, 0);
3116                 req = tcore_at_request_new("AT+XDRV=40,6,0,2", "+XDRV", TCORE_AT_SINGLELINE);
3117                 dbg("XDRV req-cmd for source type  : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3118                 tcore_pending_set_request_data(pending, 0, req);
3119                 ur_dup = tcore_user_request_ref(ur);
3120                 ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, tnoti_snd_path);
3121
3122         } else {
3123
3124                 cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
3125                 pending = tcore_pending_new(o, 0);
3126                 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3127                 dbg("XDRV req-cmd for source type  : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3128                 tcore_pending_set_request_data(pending, 0, req);
3129                 ur_dup = tcore_user_request_ref(ur);
3130                 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
3131                 g_free(cmd_str);
3132
3133                 if (!ret) {
3134                         dbg("At request(%s) sent failed", req->cmd);
3135                         return TCORE_RETURN_FAILURE;
3136                 }
3137
3138                 cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
3139                 pending1 = tcore_pending_new(o, 0);
3140                 req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
3141                 dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
3142                 tcore_pending_set_request_data(pending1, 0, req1);
3143                 ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
3144                 g_free(cmd_str1);
3145
3146                 if (!ret) {
3147                         dbg("AT request %s has failed ", req1->cmd);
3148                         return TCORE_RETURN_FAILURE;
3149                 }
3150         }
3151
3152         return TCORE_RETURN_SUCCESS;
3153 }
3154
3155 static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
3156 {
3157         UserRequest *src_ur = NULL;
3158         UserRequest *dest_ur = NULL;
3159         TcorePending *src_pending = NULL;
3160         TcorePending *dest_pending = NULL;
3161         TcoreATRequest *src_req = NULL;
3162         TcoreATRequest *dest_req = NULL;
3163         char *cmd_str = NULL, *volume_level = NULL;
3164         gboolean ret = FALSE;
3165         struct treq_call_sound_set_volume_level *data = NULL;
3166
3167         dbg("Entry");
3168
3169         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3170                 dbg("cp not ready/n");
3171                 return TCORE_RETURN_ENOSYS;
3172         }
3173
3174         data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
3175
3176         // Hard-coded values for MIC & Speakers
3177         // Source volume
3178         dbg("Set Source volume");
3179
3180         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88");   // Source type
3181         dbg("Request command string: %s", cmd_str);
3182
3183         // Create new Pending request
3184         src_pending = tcore_pending_new(o, 0);
3185
3186         // Create new AT-Command request
3187         src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3188         dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3189
3190         // Free Command string
3191         g_free(cmd_str);
3192
3193         tcore_pending_set_request_data(src_pending, 0, src_req);
3194         src_ur = tcore_user_request_ref(ur);
3195
3196         // Send request
3197         ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3198         if (!ret) {
3199                 err("Failed to send AT-Command request");
3200                 return TCORE_RETURN_FAILURE;
3201         }
3202
3203         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88");   // Destination type
3204         dbg("Request command string: %s", cmd_str);
3205
3206         // Create new Pending request
3207         src_pending = tcore_pending_new(o, 0);
3208
3209         // Create new AT-Command request
3210         src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3211         dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3212
3213         // Free Command string
3214         g_free(cmd_str);
3215
3216         tcore_pending_set_request_data(src_pending, 0, src_req);
3217
3218         src_ur = tcore_user_request_ref(ur);
3219
3220         // Send request
3221         ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3222         if (!ret) {
3223                 err("Failed to send AT-Command request");
3224                 return TCORE_RETURN_FAILURE;
3225         }
3226
3227         // Destination volume
3228         dbg("Set Source volume");
3229
3230         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88");   // Source type
3231         dbg("Request command string: %s", cmd_str);
3232
3233         // Create new Pending request
3234         dest_pending = tcore_pending_new(o, 0);
3235
3236         // Create new AT-Command request
3237         dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3238         dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3239
3240         // Free Command string
3241         g_free(cmd_str);
3242
3243         tcore_pending_set_request_data(dest_pending, 0, dest_req);
3244         dest_ur = tcore_user_request_ref(ur);
3245
3246         // Send request
3247         ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3248         if (!ret) {
3249                 err("Failed to send AT-Command request");
3250                 return TCORE_RETURN_FAILURE;
3251         }
3252
3253         dbg("Input volume level - %d", data->volume);
3254         switch (data->volume) {
3255         case CALL_SOUND_MUTE:
3256                 volume_level = "0";
3257                 break;
3258
3259         case CALL_SOUND_VOLUME_LEVEL_1:
3260                 volume_level = "40";
3261                 break;
3262
3263         case CALL_SOUND_VOLUME_LEVEL_2:
3264                 volume_level = "46";
3265                 break;
3266
3267         case CALL_SOUND_VOLUME_LEVEL_3:
3268                 volume_level = "52";
3269                 break;
3270
3271         case CALL_SOUND_VOLUME_LEVEL_4:
3272                 volume_level = "58";
3273                 break;
3274
3275         case CALL_SOUND_VOLUME_LEVEL_5:
3276                 volume_level = "64";
3277                 break;
3278
3279         case CALL_SOUND_VOLUME_LEVEL_6:
3280                 volume_level = "70";
3281                 break;
3282
3283         case CALL_SOUND_VOLUME_LEVEL_7:
3284                 volume_level = "76";
3285                 break;
3286
3287         case CALL_SOUND_VOLUME_LEVEL_8:
3288                 volume_level = "82";
3289                 break;
3290
3291         case CALL_SOUND_VOLUME_LEVEL_9:
3292         default:
3293                 volume_level = "88";
3294                 break;
3295         }
3296         cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level);   // Destination type
3297         dbg("Request command string: %s", cmd_str);
3298
3299         // Create new Pending request
3300         dest_pending = tcore_pending_new(o, 0);
3301
3302         // Create new AT-Command request
3303         dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3304         dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3305
3306         // Free Command string
3307         g_free(cmd_str);
3308
3309         tcore_pending_set_request_data(dest_pending, 0, dest_req);
3310
3311         // Send request
3312         ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
3313         if (!ret) {
3314                 err("Failed to send AT-Command request");
3315                 return TCORE_RETURN_FAILURE;
3316         }
3317
3318         return TCORE_RETURN_SUCCESS;
3319 }
3320
3321
3322 static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
3323 {
3324         dbg("Entry");
3325
3326         dbg("Exit");
3327         return TCORE_RETURN_SUCCESS;
3328 }
3329
3330 static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
3331 {
3332         char *cmd_str = NULL;
3333         TcorePending *pending = NULL;
3334         TcoreATRequest *req = NULL;
3335         gboolean ret = FALSE;
3336
3337         dbg("Entry");
3338
3339         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3340                 dbg("cp not ready/n");
3341                 return TCORE_RETURN_ENOSYS;
3342         }
3343
3344         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
3345
3346         dbg("Request command string: %s", cmd_str);
3347
3348         // Create new Pending request
3349         pending = tcore_pending_new(o, 0);
3350
3351         // Create new AT-Command request
3352         req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3353         dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3354
3355         // Free command string
3356         g_free(cmd_str);
3357
3358         // Set request data (AT command) to Pending request
3359         tcore_pending_set_request_data(pending, 0, req);
3360
3361         // Send request
3362         ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
3363         if (!ret) {
3364                 err("Failed to send AT-Command request");
3365                 return TCORE_RETURN_FAILURE;
3366         }
3367
3368         dbg("Exit");
3369         return TCORE_RETURN_SUCCESS;
3370 }
3371
3372 static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
3373 {
3374         char *cmd_str = NULL;
3375         TcorePending *pending = NULL;
3376         TcoreATRequest *req = NULL;
3377         gboolean ret = FALSE;
3378
3379         dbg("Entry");
3380
3381         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3382                 dbg("cp not ready/n");
3383                 return TCORE_RETURN_ENOSYS;
3384         }
3385
3386         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
3387         dbg("Request command string: %s", cmd_str);
3388
3389         // Create new Pending request
3390         pending = tcore_pending_new(o, 0);
3391
3392         // Create new AT-Command request
3393         req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3394         dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3395
3396         // Free command string
3397         g_free(cmd_str);
3398
3399         // Set request data (AT command) to Pending request
3400         tcore_pending_set_request_data(pending, 0, req);
3401
3402         // Send request
3403         ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
3404         if (!ret) {
3405                 err("Failed to send AT-Command request");
3406                 return TCORE_RETURN_FAILURE;
3407         }
3408
3409         dbg("Exit");
3410         return TCORE_RETURN_SUCCESS;
3411 }
3412
3413
3414 static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
3415 {
3416         dbg("Entry");
3417
3418         dbg("Exit");
3419         return TCORE_RETURN_SUCCESS;
3420 }
3421
3422 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
3423 {
3424         char *cmd_str = NULL;
3425         TcorePending *pending = NULL;
3426         TcoreATRequest *req = NULL;
3427         gboolean ret = FALSE;
3428
3429         dbg("Entry");
3430
3431         cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where  n = (0 - 255) * 1/10 secs.
3432         dbg("Request command string: %s", cmd_str);
3433
3434         // Create new Pending request
3435         pending = tcore_pending_new(o, 0);
3436
3437         // Create new AT-Command request
3438         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3439         dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3440
3441         // Free command string */
3442         g_free(cmd_str);
3443
3444         // Set request data (AT command) to Pending request
3445         tcore_pending_set_request_data(pending, 0, req);
3446
3447         // Send request
3448         ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
3449         if (!ret) {
3450                 err("Failed to send AT-Command request");
3451                 if (ur) {
3452                         tcore_user_request_free(ur);
3453                         ur = NULL;
3454                 }
3455                 return TCORE_RETURN_FAILURE;
3456         }
3457
3458         dbg("Exit");
3459         return TCORE_RETURN_SUCCESS;
3460 }
3461
3462 // Call Operations
3463 static struct tcore_call_operations call_ops = {
3464         .dial = s_call_outgoing,
3465         .answer = s_call_answer,
3466         .end = s_call_release,
3467         .hold = s_call_hold,
3468         .active = s_call_active,
3469         .swap = s_call_swap,
3470         .join = s_call_join,
3471         .split = s_call_split,
3472         .deflect = s_call_deflect,
3473         .transfer = s_call_transfer,
3474         .send_dtmf = s_call_send_dtmf,
3475         .set_sound_path = s_call_set_sound_path,
3476         .set_sound_volume_level = s_call_set_sound_volume_level,
3477         .get_sound_volume_level = s_call_get_sound_volume_level,
3478         .mute = s_call_mute,
3479         .unmute = s_call_unmute,
3480         .get_mute_status = s_call_get_mute_status,
3481         .set_sound_recording = NULL,
3482         .set_sound_equalization = NULL,
3483         .set_sound_noise_reduction = NULL,
3484 };
3485
3486 gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call)
3487 {
3488         dbg("Entry");
3489
3490         tcore_call_override_ops(co_call, &call_ops, NULL);
3491
3492         /* Add Callbacks */
3493         tcore_object_override_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
3494         tcore_object_override_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
3495
3496         dbg("Exit");
3497
3498         return TRUE;
3499 }
3500
3501 void s_call_exit(TcorePlugin *cp, CoreObject *co_call)
3502 {
3503         dbg("Exit");
3504 }