Replacing free with g_free based on changes in util_removeQuotes.
[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,
1495                                                 const void *data,
1496                                                 void *user_data)
1497 {
1498         const TcoreATResponse *resp = data;
1499         struct tnoti_call_sound_path *snd_path = user_data;
1500         struct tresp_call_sound_set_path resp_set_sound_path;
1501         UserRequest *ur = tcore_pending_ref_user_request(p);
1502         TcorePlugin *plugin = tcore_pending_ref_plugin(p);
1503         CoreObject *co_call;
1504
1505         if (ur == NULL) {
1506                 err("User Request is NULL");
1507                 g_free(user_data);
1508                 return;
1509         }
1510
1511         if (resp->success <= 0) {
1512
1513                 dbg("RESPONSE NOT OK");
1514                 resp_set_sound_path.err = TRUE;
1515
1516                 goto out;
1517         }
1518
1519         dbg("RESPONSE OK");
1520         resp_set_sound_path.err = FALSE;
1521
1522         co_call = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
1523
1524         /* Notify control plugin about sound path */
1525         tcore_server_send_notification(tcore_plugin_ref_server(plugin),
1526                                         co_call, TNOTI_CALL_SOUND_PATH,
1527                                         sizeof(struct tnoti_call_sound_path),
1528                                         snd_path);
1529
1530 out:
1531         /* Answer TAPI request */
1532         tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH,
1533                                 sizeof(resp_set_sound_path),
1534                                 &resp_set_sound_path);
1535
1536         g_free(user_data);
1537 }
1538
1539 static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1540 {
1541         UserRequest *ur = NULL;
1542         GSList *tokens = NULL;
1543         const char *line = NULL;
1544         const TcoreATResponse *response = data;
1545         char *resp_str = NULL;
1546         struct tresp_call_sound_set_path resp;
1547         gboolean error;
1548
1549         dbg("Entry");
1550         ur = tcore_pending_ref_user_request(p);
1551
1552         // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
1553         if (!response) {
1554                 err("Input data is NULL");
1555                 return;
1556         }
1557
1558         if (response->success > 0) {
1559                 dbg("RESPONSE OK");
1560
1561                 line = (const char *) (((GSList *) response->lines)->data);
1562                 tokens = tcore_at_tok_new(line);
1563
1564                 resp_str = g_slist_nth_data(tokens, 0);
1565                 if (!g_slist_nth_data(tokens, 0)) {
1566                         err("group_id is missing");
1567                         resp.err = TRUE;
1568                         goto OUT;
1569                 }
1570
1571                 if (!g_slist_nth_data(tokens, 1)) {
1572                         err(" function_id is missing");
1573                         resp.err = TRUE;
1574                         goto OUT;
1575                 }
1576
1577                 resp_str = g_slist_nth_data(tokens, 2);
1578
1579                 if (resp_str) {
1580                         error = atoi(resp_str);
1581                         if (0 == error) {
1582                                 dbg("Response is Success");
1583                                 resp.err = FALSE;
1584                         } else {
1585                                 resp.err = TRUE;
1586                         }
1587                 }
1588 OUT:
1589                 // Free tokens
1590                 tcore_at_tok_free(tokens);
1591         } else {
1592                 dbg("RESPONSE NOT OK");
1593
1594                 line = (const char *) response->final_response;
1595                 tokens = tcore_at_tok_new(line);
1596
1597                 if (g_slist_length(tokens) < 1) {
1598                         err("err cause not specified or string corrupted");
1599                         resp.err = TRUE;
1600                 } else {
1601                         error = atoi(g_slist_nth_data(tokens, 0));
1602
1603                         // TODO: CMEE error mapping is required.
1604                         resp.err = TRUE;
1605                 }
1606
1607                 // Free tokens
1608                 tcore_at_tok_free(tokens);
1609         }
1610
1611         if (ur) {
1612                 if ( resp.err ) {  // Send only failed notification . success notification send when destination device is set.
1613                         // Send notification to TAPI
1614                         tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1615                         setsoundpath = TRUE;
1616                 }
1617         } else {
1618                 err("User Request is NULL");
1619         }
1620
1621         dbg("Exit");
1622         return;
1623 }
1624
1625 static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1626 {
1627         UserRequest *ur = NULL;
1628         GSList *tokens = NULL;
1629         const char *line = NULL;
1630         char *resp_str = NULL;
1631         struct tresp_call_sound_set_path resp;
1632         const TcoreATResponse *response = data;
1633         gboolean error;
1634
1635         dbg("Entry");
1636
1637         ur = tcore_pending_ref_user_request(p);
1638         // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
1639
1640         if (!response) {
1641                 err("Input data is NULL");
1642                 return;
1643         }
1644
1645         if (ur) {
1646                 if (response->success > 0) {
1647                         dbg("RESPONSE OK");
1648
1649                         line = (const char *) (((GSList *) response->lines)->data);
1650                         tokens = tcore_at_tok_new(line);
1651
1652                         resp_str = g_slist_nth_data(tokens, 0);
1653                         if (!g_slist_nth_data(tokens, 0)) {
1654                                 dbg("group_id is missing");
1655                                 resp.err = TRUE;
1656                                 goto OUT;
1657                         }
1658
1659                         if (!g_slist_nth_data(tokens, 1)) {
1660                                 dbg("function_id is missing");
1661                                 resp.err = TRUE;
1662                                 goto OUT;
1663                         }
1664
1665                         resp_str = g_slist_nth_data(tokens, 2);
1666                         if (resp_str) {
1667                                 error = atoi(resp_str);
1668                                 if (0 == error) {
1669                                         dbg("Response is Success");
1670                                         resp.err = FALSE;
1671                                 } else {
1672                                         resp.err = TRUE;
1673                                 }
1674                         }
1675
1676 OUT:
1677                         // Free tokens
1678                         tcore_at_tok_free(tokens);
1679                 } else {
1680                         dbg("RESPONSE NOT OK");
1681
1682                         line = (const char *) response->final_response;
1683                         tokens = tcore_at_tok_new(line);
1684
1685                         if (g_slist_length(tokens) < 1) {
1686                                 err("err cause not specified or string corrupted");
1687                                 resp.err = TRUE;
1688                         } else {
1689                                 error = atoi(g_slist_nth_data(tokens, 0));
1690                                 // TODO: CMEE error mapping is required.
1691                                 resp.err = TRUE;
1692                         }
1693
1694                         // Free tokens
1695                         tcore_at_tok_free(tokens);
1696                 }
1697
1698                 if (setsoundpath == TRUE) {
1699                         setsoundpath = FALSE;
1700                 } else {
1701                         // Send response to TAPI
1702                         tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1703                 }
1704         } else {
1705                 dbg("User Request is NULL");
1706         }
1707
1708         dbg("Exit");
1709         return;
1710 }
1711
1712 static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1713 {
1714         UserRequest *ur = NULL;
1715         GSList *tokens = NULL;
1716         const char *line = NULL;
1717         const TcoreATResponse *response = data;
1718         char *resp_str = NULL;
1719         struct tresp_call_sound_set_volume_level resp;
1720         gboolean error;
1721
1722         ur = tcore_pending_ref_user_request(p);
1723         dbg("Entry");
1724         // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
1725         if (!response) {
1726                 err("Input data is NULL");
1727                 return;
1728         }
1729
1730         if (response->success > 0) {
1731                 dbg("RESPONSE OK");
1732
1733                 line = (const char *) (((GSList *) response->lines)->data);
1734                 tokens = tcore_at_tok_new(line);
1735
1736                 resp_str = g_slist_nth_data(tokens, 0);
1737                 if (!g_slist_nth_data(tokens, 0)) {
1738                         err("group_id is missing");
1739                         resp.err = TRUE;
1740                         goto OUT;
1741                 }
1742
1743                 if (!g_slist_nth_data(tokens, 1)) {
1744                         err("function_id is missing");
1745                         resp.err = TRUE;
1746                         goto OUT;
1747                 }
1748
1749                 resp_str = g_slist_nth_data(tokens, 2);
1750                 if (resp_str) {
1751                         error = atoi(resp_str);
1752
1753                         if (0 == error) {
1754                                 dbg("Response is Success ");
1755                                 resp.err = FALSE;
1756                         } else {
1757                                 resp.err = TRUE;
1758                         }
1759                 }
1760
1761 OUT:
1762                 // Free tokens
1763                 tcore_at_tok_free(tokens);
1764         } else {
1765                 dbg("RESPONSE NOT OK");
1766
1767                 line = (const char *) response->final_response;
1768                 tokens = tcore_at_tok_new(line);
1769
1770                 if (g_slist_length(tokens) < 1) {
1771                         err("err cause not specified or string corrupted");
1772                         resp.err = TRUE;
1773                 } else {
1774                         error = atoi(g_slist_nth_data(tokens, 0));
1775
1776                         // TODO: CMEE error mapping is required.
1777                         resp.err = TRUE;
1778                 }
1779
1780                 // Free tokens
1781                 tcore_at_tok_free(tokens);
1782         }
1783
1784         if (ur) {
1785                 if (resp.err && soundvolume == FALSE) {  // Send only failed notification . success notification send when destination device is set.
1786                         // Send reposne to TAPI
1787                         tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1788                         soundvolume = TRUE;
1789                 }
1790         } else {
1791                 err("User Request is NULL");
1792         }
1793
1794         dbg("Exit");
1795         return;
1796 }
1797
1798
1799 static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1800 {
1801         UserRequest *ur = NULL;
1802         GSList *tokens = NULL;
1803         const char *line = NULL;
1804         char *resp_str = NULL;
1805         const TcoreATResponse *response = data;
1806         struct tresp_call_sound_set_volume_level resp;
1807         gboolean error;
1808
1809         dbg("Entry");
1810
1811         ur = tcore_pending_ref_user_request(p);
1812
1813         // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
1814         if (!response) {
1815                 err("Input data is NULL");
1816                 return;
1817         }
1818
1819         if (ur) {
1820                 if (response->success > 0) {
1821                         dbg("RESPONSE OK");
1822                         line = (const char *) (((GSList *) response->lines)->data);
1823                         tokens = tcore_at_tok_new(line);
1824                         resp_str = g_slist_nth_data(tokens, 0);
1825
1826                         if (!g_slist_nth_data(tokens, 0)) {
1827                                 err("group_id is missing");
1828                                 resp.err = TRUE;
1829                                 goto OUT;
1830                         }
1831
1832                         if (!g_slist_nth_data(tokens, 1)) {
1833                                 err("function_id is missing");
1834                                 resp.err = TRUE;
1835                                 goto OUT;
1836                         }
1837
1838                         resp_str = g_slist_nth_data(tokens, 2);
1839
1840                         if (resp_str) {
1841                                 error = atoi(resp_str);
1842
1843                                 if (0 == error) {
1844                                         dbg("Response is Success");
1845                                         resp.err = FALSE;
1846                                 } else {
1847                                         resp.err = TRUE;
1848                                 }
1849                         }
1850
1851 OUT:
1852                         // Free tokens
1853                         tcore_at_tok_free(tokens);
1854                 } else {
1855                         dbg("RESPONSE NOT OK");
1856
1857                         line = (const char *) response->final_response;
1858                         tokens = tcore_at_tok_new(line);
1859
1860                         if (g_slist_length(tokens) < 1) {
1861                                 err("err cause not specified or string corrupted");
1862                                 resp.err = TRUE;
1863                         } else {
1864                                 error = atoi(g_slist_nth_data(tokens, 0));
1865
1866                                 // TODO: CMEE error mapping is required.
1867                                 resp.err = TRUE;
1868                         }
1869
1870                         tcore_at_tok_free(tokens);
1871                 }
1872
1873                 if (soundvolume == TRUE) {
1874                         soundvolume = FALSE;
1875                 } else {
1876                         // Send reposne to TAPI
1877                         tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1878                 }
1879         } else {
1880                 err("User Request is NULL");
1881         }
1882
1883         dbg("Exit");
1884         return;
1885 }
1886
1887
1888 static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
1889 {
1890         UserRequest *ur = NULL;
1891         GSList *tokens = NULL;
1892         const char *line = NULL;
1893         char *resp_str = NULL;
1894         struct tresp_call_mute resp;
1895         const TcoreATResponse *response = data;
1896         gboolean error;
1897
1898         dbg("Entry");
1899
1900         ur = tcore_pending_ref_user_request(p);
1901
1902         if (!response) {
1903                 err("Input data is NULL");
1904                 return;
1905         }
1906
1907         if (response->success > 0) {
1908                 dbg("RESPONSE OK");
1909
1910                 line = (const char *) (((GSList *) response->lines)->data);
1911                 tokens = tcore_at_tok_new(line);
1912                 resp_str = g_slist_nth_data(tokens, 0);
1913
1914                 if (!g_slist_nth_data(tokens, 0)) {
1915                         err("group_id is missing");
1916                         resp.err = TRUE;
1917                         goto OUT;
1918                 }
1919
1920                 if (!g_slist_nth_data(tokens, 1)) {
1921                         err(" function_id is missing");
1922                         resp.err = TRUE;
1923                         goto OUT;
1924                 }
1925
1926                 resp_str = g_slist_nth_data(tokens, 2);
1927
1928                 if (resp_str) {
1929                         error = atoi(resp_str);
1930                         if (0 == error) {
1931                                 dbg("Response is Success");
1932                                 resp.err = FALSE;
1933                         } else {
1934                                 resp.err = TRUE;
1935                         }
1936                 }
1937 OUT:
1938                 // Free tokens
1939                 tcore_at_tok_free(tokens);
1940         } else {
1941                 dbg("RESPONSE NOT OK");
1942
1943                 line = (const char *) response->final_response;
1944                 tokens = tcore_at_tok_new(line);
1945
1946                 if (g_slist_length(tokens) < 1) {
1947                         err("err cause not specified or string corrupted");
1948                         resp.err = TRUE;
1949                 } else {
1950                         error = atoi(g_slist_nth_data(tokens, 0));
1951
1952                         // TODO: CMEE error mapping is required.
1953                         resp.err = TRUE;
1954                 }
1955
1956                 // Free tokens
1957                 tcore_at_tok_free(tokens);
1958         }
1959
1960         if (ur) {
1961                 tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
1962         } else {
1963                 err("User Request is NULL");
1964         }
1965
1966         dbg("Exit");
1967         return;
1968 }
1969
1970 static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
1971 {
1972         const TcoreATResponse *response = NULL;
1973         struct tresp_call_unmute resp;
1974         GSList *tokens = NULL;
1975         const char *line = NULL;
1976         UserRequest *ur = NULL;
1977         char *resp_str = NULL;
1978         gboolean error;
1979
1980         dbg("Entry");
1981
1982         response = (TcoreATResponse *) data;
1983         ur = tcore_pending_ref_user_request(p);
1984
1985         if (!response) {
1986                 err("Input data is NULL");
1987                 return;
1988         }
1989
1990         if (response->success > 0) {
1991                 dbg("RESPONSE OK");
1992
1993                 line = (const char *) (((GSList *) response->lines)->data);
1994                 tokens = tcore_at_tok_new(line);
1995                 resp_str = g_slist_nth_data(tokens, 0);
1996
1997                 if (!g_slist_nth_data(tokens, 0)) {
1998                         err("group_id is missing");
1999                         resp.err = TRUE;
2000                         goto OUT;
2001                 }
2002
2003                 if (!g_slist_nth_data(tokens, 1)) {
2004                         err(" function_id is missing");
2005                         resp.err = TRUE;
2006                         goto OUT;
2007                 }
2008
2009                 resp_str = g_slist_nth_data(tokens, 2);
2010
2011                 if (resp_str) {
2012                         error = atoi(resp_str);
2013                         if (0 == error) {
2014                                 dbg("Response is Success");
2015                                 resp.err = FALSE;
2016                         } else {
2017                                 resp.err = TRUE;
2018                         }
2019                 }
2020 OUT:
2021                 // Free tokens
2022                 tcore_at_tok_free(tokens);
2023         } else {
2024                 dbg("RESPONSE NOT OK");
2025
2026                 line = (const char *) response->final_response;
2027                 tokens = tcore_at_tok_new(line);
2028
2029                 if (g_slist_length(tokens) < 1) {
2030                         err("err cause not specified or string corrupted");
2031                         resp.err = TRUE;
2032                 } else {
2033                         error = atoi(g_slist_nth_data(tokens, 0));
2034
2035                         // TODO: CMEE error mapping is required.
2036                         resp.err = TRUE;
2037                 }
2038
2039                 // Free tokens
2040                 tcore_at_tok_free(tokens);
2041         }
2042
2043         if (ur) {
2044                 tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
2045         } else {
2046                 err("User Request is NULL");
2047         }
2048
2049         dbg("Exit");
2050         return;
2051 }
2052
2053 // RESPONSE
2054 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
2055 {
2056         TcorePlugin *plugin = NULL;
2057         CoreObject *core_obj = NULL;
2058         CallObject *co = NULL;
2059         struct clcc_call_t *call_list = NULL;
2060         gboolean *event_flag = (gboolean *) user_data;
2061         const TcoreATResponse *response = data;
2062         GSList *resp_data = NULL;
2063         char *line = NULL;
2064
2065         int cllc_info = 0, countCalls = 0, countValidCalls = 0;
2066         int error = 0;
2067
2068         dbg("Entry");
2069
2070         plugin = tcore_pending_ref_plugin(p);
2071         core_obj = tcore_pending_ref_core_object(p);
2072
2073         if (response->success > 0) {
2074                 dbg("RESPONCE OK");
2075                 if (response->lines) {
2076                         resp_data = (GSList *) response->lines;
2077                         countCalls = g_slist_length(resp_data);
2078                         dbg("Total records : %d", countCalls);
2079                 }
2080
2081                 if (0 == countCalls) {
2082                         err("Call count is zero");
2083                         if (event_flag) {
2084                                 g_free(event_flag);
2085                                 event_flag = NULL;
2086                         }
2087                         return;
2088                 }
2089
2090                 call_list = g_new0(struct clcc_call_t, countCalls);
2091
2092                 for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
2093                         line = (char *) (resp_data->data);
2094
2095                         error = _callFromCLCCLine(line, call_list + countValidCalls);
2096                         if (0 != error) {
2097                                 continue;
2098                         }
2099
2100                         co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
2101                         if (!co) {
2102                                 co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
2103                                 if (!co) {
2104                                         err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
2105                                         continue;
2106                                 }
2107                         }
2108
2109                         // Call set parameters
2110                         tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
2111                         tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
2112                         tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
2113                         tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
2114                         tcore_call_object_set_active_line(co, 0);
2115
2116                         if (*event_flag) {
2117                                 dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
2118                                 _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
2119                         } else {
2120                                 // Set Status
2121                                 tcore_call_object_set_status(co, call_list[cllc_info].info.status);
2122
2123                                 dbg("Call id : (%d)", call_list[cllc_info].info.id);
2124                                 dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
2125                                 dbg("Call type : (%d)", call_list[cllc_info].info.type);
2126                                 dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
2127                                 dbg("Call number : (%s)", call_list[cllc_info].number);
2128                                 dbg("Call status : (%d)", call_list[cllc_info].info.status);
2129                         }
2130                 }
2131
2132                 // Free Call list
2133                 g_free(call_list);
2134         }
2135
2136         // Free User data
2137         if (event_flag) {
2138         g_free(event_flag);
2139                 event_flag = NULL;
2140         }
2141
2142         dbg("Exit");
2143         return;
2144 }
2145
2146 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
2147 {
2148         TcorePlugin *plugin = NULL;
2149         CoreObject *core_obj = NULL;
2150         CallObject *co = (CallObject *) user_data;
2151         const TcoreATResponse *response = data;
2152         const char *line = NULL;
2153         struct tnoti_call_status_idle call_status;
2154         GSList *tokens = NULL;
2155         char *resp_str;
2156         int error;
2157
2158         dbg("Entry");
2159         plugin = tcore_pending_ref_plugin(p);
2160         core_obj = tcore_pending_ref_core_object(p);
2161
2162         if (response->success > 0) {
2163                 dbg("RESPONSE OK");
2164                 line = (const char *) (((GSList *) response->lines)->data);
2165                 tokens = tcore_at_tok_new(line);
2166                 resp_str = g_slist_nth_data(tokens, 0);
2167                 if (!resp_str) {
2168                         err("call end cause - report value missing");
2169                 } else {
2170                         resp_str = g_slist_nth_data(tokens, 1);
2171                         if (!resp_str) {
2172                                 err("call end cause value missing");
2173                         }
2174                         error = atoi(resp_str);
2175                         dbg("call end cause - %d", error);
2176                         call_status.cause = _compare_call_end_cause(error);
2177                         dbg("TAPI call end cause - %d", call_status.cause);
2178                 }
2179
2180                 // Free tokens
2181                 tcore_at_tok_free(tokens);
2182         } else {
2183                 err("RESPONSE NOT OK");
2184                 line = (char *) response->final_response;
2185                 tokens = tcore_at_tok_new(line);
2186                 if (g_slist_length(tokens) < 1) {
2187                         err("err cause not specified or string corrupted");
2188                 } else {
2189                         err(" err cause  value: %d", atoi(g_slist_nth_data(tokens, 0)));
2190                 }
2191                 call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
2192                 // Free tokens
2193                 tcore_at_tok_free(tokens);
2194         }
2195
2196         call_status.type = tcore_call_object_get_type(co);
2197         dbg("data.type : [%d]", call_status.type);
2198
2199         call_status.id = tcore_call_object_get_id(co);
2200         dbg("data.id : [%d]", call_status.id);
2201
2202         // Set Status
2203         tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
2204
2205         // Send Notification to TAPI
2206         tcore_server_send_notification(tcore_plugin_ref_server(plugin),
2207                                                                    core_obj,
2208                                                                    TNOTI_CALL_STATUS_IDLE,
2209                                                                    sizeof(struct tnoti_call_status_idle),
2210                                                                    (void *) &call_status);
2211
2212         // Free Call object
2213         tcore_call_object_free(core_obj, co);
2214 }
2215
2216 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
2217 {
2218         // +CLCC: 1,0,2,0,0,"18005551212",145
2219         // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
2220         int state;
2221         int mode;
2222         int isMT;
2223         char *num = NULL;
2224         unsigned int num_type;
2225         GSList *tokens = NULL;
2226         char *resp = NULL;
2227
2228         dbg("Entry");
2229
2230         tokens = tcore_at_tok_new(line);
2231         // parse <id>
2232         resp = g_slist_nth_data(tokens, 0);
2233         if (!resp) {
2234                 err("InValid ID");
2235                 goto ERROR;
2236         }
2237         p_call->info.id = atoi(resp);
2238         dbg("id : [%d]\n", p_call->info.id);
2239
2240         // parse <dir>
2241         resp = g_slist_nth_data(tokens, 1);
2242         if (!resp) {
2243                 err("InValid Dir");
2244                 goto ERROR;
2245         }
2246         isMT = atoi(resp);
2247         if (0 == isMT) {
2248                 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
2249         } else {
2250                 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
2251         }
2252         dbg("Direction : [ %d ]\n", p_call->info.direction);
2253
2254         // parse <stat>
2255         resp = g_slist_nth_data(tokens, 2);
2256         if (!resp) {
2257                 err("InValid Stat");
2258                 goto ERROR;
2259         }
2260         state = atoi(resp);
2261         dbg("Call state : %d", state);
2262         switch (state) {
2263         case 0:     // active
2264                 p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
2265                 break;
2266
2267         case 1:
2268                 p_call->info.status = TCORE_CALL_STATUS_HELD;
2269                 break;
2270
2271         case 2:
2272                 p_call->info.status = TCORE_CALL_STATUS_DIALING;
2273                 break;
2274
2275         case 3:
2276                 p_call->info.status = TCORE_CALL_STATUS_ALERT;
2277                 break;
2278
2279         case 4:
2280                 p_call->info.status = TCORE_CALL_STATUS_INCOMING;
2281                 break;
2282
2283         case 5:
2284                 p_call->info.status = TCORE_CALL_STATUS_WAITING;
2285                 break;
2286         }
2287         dbg("Status : [%d]\n", p_call->info.status);
2288
2289         // parse <mode>
2290         resp = g_slist_nth_data(tokens, 3);
2291         if (!resp) {
2292                 err("InValid Mode");
2293                 goto ERROR;
2294         }
2295         mode = atoi(resp);
2296         switch (mode) {
2297         case 0:
2298                 p_call->info.type = TCORE_CALL_TYPE_VOICE;
2299                 break;
2300
2301         case 1:
2302                 p_call->info.type = TCORE_CALL_TYPE_VIDEO;
2303                 break;
2304
2305         default:        // only Voice/VT call is supported in CS. treat other unknown calls as error
2306                 dbg("invalid type : [%d]\n", mode);
2307                 goto ERROR;
2308         }
2309         dbg("Call type : [%d]\n", p_call->info.type);
2310
2311         // parse <mpty>
2312         resp = g_slist_nth_data(tokens, 4);
2313         if (!resp) {
2314                 err("InValid Mpty");
2315                 goto ERROR;
2316         }
2317
2318         p_call->info.mpty = atoi(resp);
2319         dbg("Mpty : [ %d ]\n", p_call->info.mpty);
2320
2321         // parse <num>
2322         resp = g_slist_nth_data(tokens, 5);
2323         dbg("Incoming number - %s and its len  - %d", resp, strlen(resp));
2324
2325         // tolerate null here
2326         if (!resp) {
2327                 err("Number is NULL");
2328                 goto ERROR;
2329         }
2330         // Strike off double quotes
2331         num = util_removeQuotes(resp);
2332         dbg("num  after removing quotes - %s", num);
2333
2334         p_call->info.num_len = strlen(resp);
2335         dbg("num_len : [0x%x]\n", p_call->info.num_len);
2336
2337         // parse <num type>
2338         resp = g_slist_nth_data(tokens, 6);
2339         if (!resp) {
2340                 dbg("InValid Num type");
2341                 goto ERROR;
2342         }
2343         p_call->info.num_type = atoi(resp);
2344         dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
2345
2346         // check number is international or national.
2347         num_type = ((p_call->info.num_type) >> 4) & 0x07;
2348         dbg("called party's type of number : [0x%x]\n", num_type);
2349
2350         if (num_type == 1 && num[0] != '+') {
2351                 // international number
2352                 p_call->number[0] = '+';
2353                 memcpy(&(p_call->number[1]), num, strlen(num));
2354         } else {
2355                 memcpy(&(p_call->number), num, strlen(num));
2356         }
2357         dbg("incoming number - %s", p_call->number);
2358
2359         g_free(num);
2360         num = NULL;
2361         // Free tokens
2362         tcore_at_tok_free(tokens);
2363
2364         dbg("Exit");
2365         return 0;
2366
2367 ERROR:
2368         err("Invalid CLCC line");
2369
2370         g_free(num);
2371
2372         // Free tokens
2373         tcore_at_tok_free(tokens);
2374         err("Exit");
2375         return -1;
2376 }
2377
2378 // NOTIFICATION
2379 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
2380 {
2381         GSList *tokens = NULL;
2382         const char *line = NULL;
2383         char *pId;
2384         int call_id;
2385         gboolean *eflag;
2386         GSList *pList = NULL;
2387         CallObject *co = NULL, *dupco = NULL;
2388
2389         dbg("function entrance");
2390         // check call with waiting status already exist
2391         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
2392
2393         if (pList != NULL) {
2394                 dbg("[error]Waiting call already exist. skip");
2395                 return;
2396         }
2397         // check call with incoming status already exist
2398         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2399
2400         if (pList != NULL) {
2401                 dbg("[error]incoming call already exist. skip");
2402                 return;
2403         }
2404         line = (char *) data;
2405         tokens = tcore_at_tok_new(line);
2406
2407         pId = g_slist_nth_data(tokens, 0);
2408         if (!pId) {
2409                 dbg("[error]:Call id is missing from +XCALLSTAT indication");
2410                 tcore_at_tok_free(tokens);
2411                 return;
2412         }
2413
2414         call_id = atoi(pId);
2415         dupco = tcore_call_object_find_by_id(o, call_id);
2416         if (dupco != NULL) {
2417                 dbg("co with same id already exist. skip");
2418                 tcore_at_tok_free(tokens);
2419                 return;
2420         }
2421         co = tcore_call_object_new(o, call_id);
2422         if (!co) {
2423                 dbg("[ error ] co is NULL");
2424                 tcore_at_tok_free(tokens);
2425                 return;
2426         }
2427
2428         tcore_at_tok_free(tokens);
2429
2430         eflag = g_new0(gboolean, 1);
2431         *eflag = TRUE;
2432         dbg("calling _call_list_get");
2433         _call_list_get(o, eflag);
2434 }
2435
2436 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
2437 {
2438         GSList *tokens = NULL;
2439         const char *line = NULL;
2440         char *pId;
2441         int call_id;
2442         gboolean *eflag;
2443         GSList *pList = NULL;
2444         CallObject *co = NULL, *dupco = NULL;
2445
2446         dbg("function entrance");
2447         // check call with incoming status already exist
2448         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2449
2450         if (pList != NULL) {
2451                 dbg("incoming call already exist. skip");
2452                 return;
2453         }
2454
2455         line = (char *) data;
2456         tokens = tcore_at_tok_new(line);
2457
2458         pId = g_slist_nth_data(tokens, 0);
2459         if (!pId) {
2460                 dbg("Error:Call id is missing from %XCALLSTAT indication");
2461                 tcore_at_tok_free(tokens);
2462                 return;
2463         }
2464
2465         call_id = atoi(pId);
2466
2467         dupco = tcore_call_object_find_by_id(o, call_id);
2468         if (dupco != NULL) {
2469                 dbg("co with same id already exist. skip");
2470                 tcore_at_tok_free(tokens);
2471                 return;
2472         }
2473
2474         co = tcore_call_object_new(o, call_id);
2475         if (!co) {
2476                 dbg("[ error ] co is NULL");
2477                 tcore_at_tok_free(tokens);
2478                 return;
2479         }
2480
2481         dbg("freeing  at token");
2482         tcore_at_tok_free(tokens);
2483
2484         eflag = g_new0(gboolean, 1);
2485         *eflag = TRUE;
2486
2487         dbg("calling  _call_list_get");
2488         _call_list_get(o, eflag);
2489 }
2490
2491 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
2492 {
2493         char *cmd = NULL;
2494         TcorePlugin *plugin = NULL;
2495         CallObject *co = NULL;
2496         int id = -1;
2497         int status = 0;
2498         int type = 0;
2499         char *stat = NULL;
2500         char *pCallId = NULL;
2501         GSList *tokens = NULL;
2502         gboolean *eflag = NULL;
2503         enum tcore_call_status co_status;
2504
2505         dbg("function entrance");
2506         plugin = tcore_object_ref_plugin(o);
2507         cmd = (char *) data;
2508         tokens = tcore_at_tok_new(cmd);
2509
2510         // parse <Call Id>
2511         pCallId = g_slist_nth_data(tokens, 0);
2512         if (!pCallId) {
2513                 dbg("CallId is missing from %XCALLSTAT indication");
2514                 tcore_at_tok_free(tokens);
2515                 return;
2516         } else {
2517                 id = atoi(pCallId);
2518                 dbg("call id = %d", id);
2519                 // parse <Stat>
2520                 if ((stat = g_slist_nth_data(tokens, 1))) {
2521                         status = atoi(stat);
2522                 }
2523                 dbg("call status = %d", status);
2524         }
2525
2526         tcore_at_tok_free(tokens);
2527         co_status = _call_status(status);
2528
2529         dbg("co_status = %d", co_status);
2530         switch (co_status) {
2531         case CALL_STATUS_ACTIVE:
2532         {
2533                 dbg("call(%d) status : [ ACTIVE ]", id);
2534                 co = tcore_call_object_find_by_id(o, id);
2535                 if (!co) {
2536                         dbg("co is NULL");
2537                         return;
2538                 }
2539                 _call_status_active(plugin, co);
2540         }
2541         break;
2542
2543         case CALL_STATUS_HELD:
2544                 dbg("call(%d) status : [ held ]", id);
2545                 break;
2546
2547         case CALL_STATUS_DIALING:
2548         {
2549                 dbg("call(%d) status : [ dialing ]", id);
2550                 co = tcore_call_object_find_by_id(o, id);
2551                 if (!co) {
2552                         co = tcore_call_object_new(o, id);
2553                         if (!co) {
2554                                 dbg("error : tcore_call_object_new [ id : %d ]", id);
2555                                 return;
2556                         }
2557                 }
2558
2559                 tcore_call_object_set_type(co, call_type(type));
2560                 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
2561                 _call_status_dialing(plugin, co);
2562         }
2563         break;
2564
2565         case CALL_STATUS_ALERT:
2566         {
2567                 dbg("call(%d) status : [ alert ]", id);
2568                 co = tcore_call_object_find_by_id(o, id);
2569                 if (!co) {
2570                         dbg("co is NULL");
2571                         return;
2572                 }
2573                 // Store dialed number information into Call object.
2574                 eflag = g_new0(gboolean, 1);
2575                 *eflag = TRUE;
2576                 dbg("calling _call_list_get");
2577                 _call_list_get(o, eflag);
2578         }
2579         break;
2580
2581         case CALL_STATUS_INCOMING:
2582         case CALL_STATUS_WAITING:
2583                 dbg("call(%d) status : [ incoming ]", id);
2584                 break;
2585
2586         case CALL_STATUS_IDLE:
2587         {
2588                 dbg("call(%d) status : [ release ]", id);
2589
2590                 co = tcore_call_object_find_by_id(o, id);
2591                 if (!co) {
2592                         dbg("co is NULL");
2593                         return;
2594                 }
2595
2596                 plugin = tcore_object_ref_plugin(o);
2597                 if (!plugin) {
2598                         dbg("plugin is NULL");
2599                         return;
2600                 }
2601                 _call_status_idle(plugin, co);
2602         }
2603         break;
2604
2605         default:
2606                 dbg("invalid call status", id);
2607                 break;
2608         }
2609 }
2610
2611 static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
2612 {
2613         struct treq_call_dial *data = 0;
2614         char *raw_str = NULL;
2615         char *cmd_str = NULL;
2616         const char *cclir;
2617         enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
2618         TcorePending *pending = NULL;
2619         TcoreATRequest *req;
2620         gboolean ret = FALSE;
2621
2622         dbg("function entrance");
2623
2624         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2625                 dbg("cp not ready/n");
2626                 return TCORE_RETURN_ENOSYS;
2627         }
2628
2629         data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
2630         if (data->type == CALL_TYPE_VIDEO) {
2631                 dbg("invalid call type");
2632                 return TCORE_RETURN_FAILURE;
2633         }
2634
2635         clir = _get_clir_status(data->number);
2636
2637         // Compose ATD Cmd string
2638         switch (clir) {
2639         case TCORE_CALL_CLI_MODE_PRESENT:
2640                 dbg("CALL_CLI_MODE_PRESENT");
2641                 cclir = "I";
2642                 break;  // invocation
2643
2644         case TCORE_CALL_CLI_MODE_RESTRICT:
2645                 dbg("CALL_CLI_MODE_RESTRICT");
2646                 cclir = "i";
2647                 break;  // suppression
2648
2649         case TCORE_CALL_CLI_MODE_DEFAULT:
2650         default:
2651                 cclir = "";
2652                 dbg("CALL_CLI_MODE_DEFAULT");
2653                 break;   // subscription default
2654         }
2655
2656         dbg("data->number = %s", data->number);
2657
2658         raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
2659         cmd_str = g_strdup_printf("%s", raw_str);
2660
2661         dbg("request command : %s", cmd_str);
2662
2663         pending = tcore_pending_new(o, 0);
2664         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2665         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2666
2667         tcore_pending_set_request_data(pending, 0, req);
2668         ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
2669
2670         g_free(raw_str);
2671         g_free(cmd_str);
2672
2673         if (!ret) {
2674                 dbg("AT request(%s) sent failed", req->cmd);
2675                 return TCORE_RETURN_FAILURE;
2676         }
2677
2678         dbg("AT request(%s) sent success", req->cmd);
2679
2680         return TCORE_RETURN_SUCCESS;
2681 }
2682
2683 static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
2684 {
2685         char *cmd_str = NULL;
2686         CallObject *co = NULL;
2687         struct treq_call_answer *data = 0;
2688         TcorePending *pending = NULL;
2689         TcoreATRequest *req;
2690         gboolean ret = FALSE;
2691
2692         dbg("function entrance");
2693
2694         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2695                 dbg("cp not ready/n");
2696                 return TCORE_RETURN_ENOSYS;
2697         }
2698
2699         data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
2700         co = tcore_call_object_find_by_id(o, data->id);
2701         if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
2702                 dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
2703
2704                 cmd_str = g_strdup_printf("%s", "ATA");
2705                 pending = tcore_pending_new(o, 0);
2706                 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2707                 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2708
2709                 tcore_pending_set_request_data(pending, 0, req);
2710                 ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
2711                 g_free(cmd_str);
2712
2713                 if (!ret) {
2714                         dbg("AT request(%s) sent failed", req->cmd);
2715                         return TCORE_RETURN_FAILURE;
2716                 }
2717         } else {
2718                 switch (data->type) {
2719                 case CALL_ANSWER_TYPE_REJECT:
2720                 {
2721                         dbg("call answer reject");
2722                         tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
2723                 }
2724                 break;
2725
2726                 case CALL_ANSWER_TYPE_REPLACE:
2727                 {
2728                         dbg("call answer replace");
2729                         tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
2730                 }
2731                 break;
2732
2733                 case CALL_ANSWER_TYPE_HOLD_ACCEPT:
2734                 {
2735                         dbg("call answer hold and accept");
2736                         tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
2737                 }
2738                 break;
2739
2740                 default:
2741                         dbg("[ error ] wrong answer type [ %d ]", data->type);
2742                         return TCORE_RETURN_FAILURE;
2743                 }
2744         }
2745
2746         return TCORE_RETURN_SUCCESS;
2747 }
2748
2749 static TReturn s_call_release(CoreObject *o, UserRequest *ur)
2750 {
2751         CallObject *co = NULL;
2752         struct treq_call_end *data = 0;
2753         UserRequest *ur_dup = NULL;
2754         char *chld0_cmd = NULL;
2755         char *chld1_cmd = NULL;
2756         TcorePending *pending = NULL, *pending1 = NULL;
2757         TcoreATRequest *req, *req1;
2758         gboolean ret = FALSE;
2759
2760         dbg("function entrance");
2761         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2762                 dbg("cp not ready/n");
2763                 return TCORE_RETURN_ENOSYS;
2764         }
2765         data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
2766         co = tcore_call_object_find_by_id(o, data->id);
2767
2768         dbg("type of release call = %d", data->type);
2769
2770         if (data->type == CALL_END_TYPE_ALL) {
2771                 // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
2772                 chld0_cmd = g_strdup("AT+CHLD=0");
2773                 chld1_cmd = g_strdup("AT+CHLD=1");
2774
2775                 pending = tcore_pending_new(o, 0);
2776                 req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
2777
2778                 dbg("input command is %s", chld0_cmd);
2779                 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2780
2781                 tcore_pending_set_request_data(pending, 0, req);
2782                 ur_dup = tcore_user_request_new(NULL, NULL);
2783                 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
2784                 g_free(chld0_cmd);
2785
2786                 if (!ret) {
2787                         dbg("AT request %s has failed ", req->cmd);
2788                         if (ur_dup) {
2789                                 tcore_user_request_free(ur_dup);
2790                                 ur_dup = NULL;
2791                         }
2792                         g_free(chld1_cmd);
2793                         return TCORE_RETURN_FAILURE;
2794                 }
2795
2796                 pending1 = tcore_pending_new(o, 0);
2797                 req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
2798
2799                 dbg("input command is %s", chld1_cmd);
2800                 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2801
2802                 tcore_pending_set_request_data(pending1, 0, req1);
2803                 ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
2804                 g_free(chld1_cmd);
2805
2806                 if (!ret) {
2807                         dbg("AT request %s has failed ", req->cmd);
2808                         return TCORE_RETURN_FAILURE;
2809                 }
2810         } else {
2811                 switch (data->type) {
2812                 case CALL_END_TYPE_DEFAULT:
2813                 {
2814                         int id = 0;
2815                         id = tcore_call_object_get_id(co);
2816
2817                         dbg("call end call id [%d]", id);
2818                         tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
2819                 }
2820                 break;
2821
2822                 case CALL_END_TYPE_ACTIVE_ALL:
2823                 {
2824                         dbg("call end all active");
2825                         tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
2826                 }
2827                 break;
2828
2829                 case CALL_END_TYPE_HOLD_ALL:
2830                 {
2831                         dbg("call end all held");
2832                         tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
2833                 }
2834                 break;
2835
2836                 default:
2837                         dbg("[ error ] wrong end type [ %d ]", data->type);
2838                         return TCORE_RETURN_FAILURE;
2839                 }
2840         }
2841
2842         return TCORE_RETURN_SUCCESS;
2843 }
2844
2845 static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
2846 {
2847         struct treq_call_hold *hold = 0;
2848         CallObject *co = NULL;
2849
2850         dbg("function entrance");
2851
2852         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2853                 dbg("cp not ready/n");
2854                 return TCORE_RETURN_ENOSYS;
2855         }
2856
2857         hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
2858         dbg("call id : [ %d ]", hold->id);
2859
2860         co = tcore_call_object_find_by_id(o, hold->id);
2861         tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
2862
2863         return TCORE_RETURN_SUCCESS;
2864 }
2865
2866 static TReturn s_call_active(CoreObject *o, UserRequest *ur)
2867 {
2868         struct treq_call_active *active = 0;
2869         CallObject *co = NULL;
2870
2871         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2872                 dbg("cp not ready/n");
2873                 return TCORE_RETURN_ENOSYS;
2874         }
2875
2876         active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
2877         dbg("call id : [ %d ]", active->id);
2878
2879         co = tcore_call_object_find_by_id(o, active->id);
2880         tcore_call_control_active(o, ur, on_confirmation_call_active, co);
2881
2882         return TCORE_RETURN_SUCCESS;
2883 }
2884
2885 static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
2886 {
2887         struct treq_call_swap *swap = NULL;
2888         CallObject *co = NULL;
2889
2890         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2891                 dbg("cp not ready/n");
2892                 return TCORE_RETURN_ENOSYS;
2893         }
2894
2895         swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
2896         dbg("call id : [ %d ]", swap->id);
2897
2898         co = tcore_call_object_find_by_id(o, swap->id);
2899         tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
2900
2901         return TCORE_RETURN_SUCCESS;
2902 }
2903
2904 static TReturn s_call_join(CoreObject *o, UserRequest *ur)
2905 {
2906         struct treq_call_join *join = 0;
2907         CallObject *co = NULL;
2908
2909         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2910                 dbg("cp not ready/n");
2911                 return TCORE_RETURN_ENOSYS;
2912         }
2913
2914         join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
2915         dbg("call id : [ %d ]", join->id);
2916
2917         co = tcore_call_object_find_by_id(o, join->id);
2918         tcore_call_control_join(o, ur, on_confirmation_call_join, co);
2919
2920         return TCORE_RETURN_SUCCESS;
2921 }
2922
2923 static TReturn s_call_split(CoreObject *o, UserRequest *ur)
2924 {
2925         struct treq_call_split *split = 0;
2926         CallObject *co = NULL;
2927
2928         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2929                 dbg("cp not ready/n");
2930                 return TCORE_RETURN_ENOSYS;
2931         }
2932
2933         split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
2934         co = tcore_call_object_find_by_id(o, split->id);
2935         dbg("call id : [ %d ]", split->id);
2936
2937         tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
2938
2939         return TCORE_RETURN_SUCCESS;
2940 }
2941
2942 static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
2943 {
2944         struct treq_call_deflect *deflect = 0;
2945         CallObject *co = NULL;
2946
2947         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2948                 dbg("cp not ready/n");
2949                 return TCORE_RETURN_ENOSYS;
2950         }
2951
2952         deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
2953         co = tcore_call_object_find_by_number(o, deflect->number);
2954         dbg("deflect number: [ %s ]", deflect->number);
2955
2956         tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
2957
2958         return TCORE_RETURN_SUCCESS;
2959 }
2960
2961 static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
2962 {
2963         struct treq_call_transfer *transfer = 0;
2964         CallObject *co = NULL;
2965
2966         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2967                 dbg("cp not ready/n");
2968                 return TCORE_RETURN_ENOSYS;
2969         }
2970
2971         transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
2972         dbg("call id : [ %d ]", transfer->id);
2973
2974         co = tcore_call_object_find_by_id(o, transfer->id);
2975         tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
2976
2977         return TCORE_RETURN_SUCCESS;
2978 }
2979
2980 static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
2981 {
2982         char *cmd_str = NULL;
2983         TcorePending *pending = NULL;
2984         TcoreATRequest *req;
2985         UserRequest *dup;
2986         gboolean ret = FALSE;
2987         struct treq_call_dtmf *dtmf = 0;
2988         char *dtmfstr = NULL, *tmp_dtmf = NULL;
2989         unsigned int dtmf_count;
2990
2991         dbg("Function enter");
2992
2993         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2994                 dbg("cp not ready/n");
2995                 return TCORE_RETURN_ENOSYS;
2996         }
2997
2998         dup = tcore_user_request_new(NULL, NULL);
2999         (void) _set_dtmf_tone_duration(o, dup);
3000
3001         dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
3002         dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1);    // DTMF digits + comma for each dtmf digit.
3003
3004         if (dtmfstr == NULL) {
3005                 dbg("Memory allocation failed");
3006                 return TCORE_RETURN_FAILURE;
3007         }
3008
3009         tmp_dtmf = dtmfstr;
3010
3011         for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
3012                 *tmp_dtmf = dtmf->digits[dtmf_count];
3013                 tmp_dtmf++;
3014
3015                 *tmp_dtmf = COMMA;
3016                 tmp_dtmf++;
3017         }
3018
3019         // last digit is having COMMA , overwrite it with '\0' .
3020         *(--tmp_dtmf) = '\0';
3021         dbg("Input DTMF string(%s)", dtmfstr);
3022
3023         // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
3024         cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
3025         dbg("request command : %s", cmd_str);
3026
3027         pending = tcore_pending_new(o, 0);
3028         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3029         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3030
3031         tcore_pending_set_request_data(pending, 0, req);
3032         ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
3033         g_free(dtmfstr);
3034         g_free(cmd_str);
3035
3036         if (!ret) {
3037                 dbg("AT request sent failed");
3038                 return TCORE_RETURN_FAILURE;
3039         }
3040
3041         return TCORE_RETURN_SUCCESS;
3042 }
3043
3044 static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
3045 {
3046         UserRequest *ur_dup = NULL;
3047         TcorePending *pending = NULL, *pending1 = NULL;
3048         TcoreATRequest *req, *req1;
3049         char *cmd_str = NULL, *cmd_str1 = NULL;
3050         int device_type = -1;
3051         struct treq_call_sound_set_path *sound_path = 0;
3052         gboolean ret = FALSE;
3053         TcorePlugin *plugin = tcore_object_ref_plugin(o);
3054         const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
3055
3056         dbg("function entrance");
3057
3058         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3059                 dbg("cp not ready/n");
3060                 return TCORE_RETURN_ENOSYS;
3061         }
3062         sound_path = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
3063         if (sound_path == NULL) {
3064                 dbg("invaling user request");
3065                 return TCORE_RETURN_FAILURE;
3066         }
3067         dbg("audio device type - 0x%x", sound_path->path);
3068         switch (sound_path->path) {
3069         case CALL_SOUND_PATH_HANDSET:
3070                 device_type = 1;
3071                 break;
3072
3073         case CALL_SOUND_PATH_HEADSET:
3074                 device_type = 2;
3075                 break;
3076
3077         case CALL_SOUND_PATH_HEADSET_3_5PI:
3078                 device_type = 3;
3079                 break;
3080
3081         case CALL_SOUND_PATH_SPEAKER:
3082                 device_type = 4;
3083                 break;
3084
3085         case CALL_SOUND_PATH_HANDFREE:
3086                 device_type = 5;
3087                 break;
3088
3089         case CALL_SOUND_PATH_HEADSET_HAC:
3090                 device_type = 6;
3091                 break;
3092
3093         case CALL_SOUND_PATH_BLUETOOTH:
3094         case CALL_SOUND_PATH_STEREO_BLUETOOTH:
3095                 device_type = 7;
3096                 break;
3097
3098         case CALL_SOUND_PATH_BT_NSEC_OFF:
3099         case CALL_SOUND_PATH_MIC1:
3100         case CALL_SOUND_PATH_MIC2:
3101         default:
3102                 dbg("unsupported device type");
3103                 return TCORE_RETURN_FAILURE;
3104         }
3105
3106         if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
3107                 struct tnoti_call_sound_path *tnoti_snd_path;
3108
3109                 tnoti_snd_path = g_try_new0(struct tnoti_call_sound_path, 1);
3110                 if (!tnoti_snd_path)
3111                         return TCORE_RETURN_ENOMEM;
3112
3113                 tnoti_snd_path->path = sound_path->path;
3114
3115                 /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
3116                 if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
3117                         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);
3118                         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);
3119                 }
3120                 else {
3121                         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);
3122                         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);
3123                 }
3124
3125                 /* Configure modem I2S2 and do the modem routing */
3126                 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);
3127                 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);
3128                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
3129                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
3130                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
3131                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
3132
3133                 /* amc enable */
3134                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
3135                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
3136                 /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
3137
3138                 pending = tcore_pending_new(o, 0);
3139                 req = tcore_at_request_new("AT+XDRV=40,6,0,2", "+XDRV", TCORE_AT_SINGLELINE);
3140                 dbg("XDRV req-cmd for source type  : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3141                 tcore_pending_set_request_data(pending, 0, req);
3142                 ur_dup = tcore_user_request_ref(ur);
3143                 ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, tnoti_snd_path);
3144
3145         } else {
3146
3147                 cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
3148                 pending = tcore_pending_new(o, 0);
3149                 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3150                 dbg("XDRV req-cmd for source type  : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3151                 tcore_pending_set_request_data(pending, 0, req);
3152                 ur_dup = tcore_user_request_ref(ur);
3153                 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
3154                 g_free(cmd_str);
3155
3156                 if (!ret) {
3157                         dbg("At request(%s) sent failed", req->cmd);
3158                         return TCORE_RETURN_FAILURE;
3159                 }
3160
3161                 cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
3162                 pending1 = tcore_pending_new(o, 0);
3163                 req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
3164                 dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
3165                 tcore_pending_set_request_data(pending1, 0, req1);
3166                 ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
3167                 g_free(cmd_str1);
3168
3169                 if (!ret) {
3170                         dbg("AT request %s has failed ", req1->cmd);
3171                         return TCORE_RETURN_FAILURE;
3172                 }
3173         }
3174
3175         return TCORE_RETURN_SUCCESS;
3176 }
3177
3178 static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
3179 {
3180         UserRequest *src_ur = NULL;
3181         UserRequest *dest_ur = NULL;
3182         TcorePending *src_pending = NULL;
3183         TcorePending *dest_pending = NULL;
3184         TcoreATRequest *src_req = NULL;
3185         TcoreATRequest *dest_req = NULL;
3186         char *cmd_str = NULL, *volume_level = NULL;
3187         gboolean ret = FALSE;
3188         struct treq_call_sound_set_volume_level *data = NULL;
3189
3190         dbg("Entry");
3191
3192         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3193                 dbg("cp not ready/n");
3194                 return TCORE_RETURN_ENOSYS;
3195         }
3196
3197         data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
3198
3199         // Hard-coded values for MIC & Speakers
3200         // Source volume
3201         dbg("Set Source volume");
3202
3203         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88");   // Source 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         src_ur = tcore_user_request_ref(ur);
3218
3219         // Send request
3220         ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3221         if (!ret) {
3222                 err("Failed to send AT-Command request");
3223                 return TCORE_RETURN_FAILURE;
3224         }
3225
3226         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88");   // Destination type
3227         dbg("Request command string: %s", cmd_str);
3228
3229         // Create new Pending request
3230         src_pending = tcore_pending_new(o, 0);
3231
3232         // Create new AT-Command request
3233         src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3234         dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3235
3236         // Free Command string
3237         g_free(cmd_str);
3238
3239         tcore_pending_set_request_data(src_pending, 0, src_req);
3240
3241         src_ur = tcore_user_request_ref(ur);
3242
3243         // Send request
3244         ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3245         if (!ret) {
3246                 err("Failed to send AT-Command request");
3247                 return TCORE_RETURN_FAILURE;
3248         }
3249
3250         // Destination volume
3251         dbg("Set Source volume");
3252
3253         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88");   // Source type
3254         dbg("Request command string: %s", cmd_str);
3255
3256         // Create new Pending request
3257         dest_pending = tcore_pending_new(o, 0);
3258
3259         // Create new AT-Command request
3260         dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3261         dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3262
3263         // Free Command string
3264         g_free(cmd_str);
3265
3266         tcore_pending_set_request_data(dest_pending, 0, dest_req);
3267         dest_ur = tcore_user_request_ref(ur);
3268
3269         // Send request
3270         ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3271         if (!ret) {
3272                 err("Failed to send AT-Command request");
3273                 return TCORE_RETURN_FAILURE;
3274         }
3275
3276         dbg("Input volume level - %d", data->volume);
3277         switch (data->volume) {
3278         case CALL_SOUND_MUTE:
3279                 volume_level = "0";
3280                 break;
3281
3282         case CALL_SOUND_VOLUME_LEVEL_1:
3283                 volume_level = "40";
3284                 break;
3285
3286         case CALL_SOUND_VOLUME_LEVEL_2:
3287                 volume_level = "46";
3288                 break;
3289
3290         case CALL_SOUND_VOLUME_LEVEL_3:
3291                 volume_level = "52";
3292                 break;
3293
3294         case CALL_SOUND_VOLUME_LEVEL_4:
3295                 volume_level = "58";
3296                 break;
3297
3298         case CALL_SOUND_VOLUME_LEVEL_5:
3299                 volume_level = "64";
3300                 break;
3301
3302         case CALL_SOUND_VOLUME_LEVEL_6:
3303                 volume_level = "70";
3304                 break;
3305
3306         case CALL_SOUND_VOLUME_LEVEL_7:
3307                 volume_level = "76";
3308                 break;
3309
3310         case CALL_SOUND_VOLUME_LEVEL_8:
3311                 volume_level = "82";
3312                 break;
3313
3314         case CALL_SOUND_VOLUME_LEVEL_9:
3315         default:
3316                 volume_level = "88";
3317                 break;
3318         }
3319         cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level);   // Destination type
3320         dbg("Request command string: %s", cmd_str);
3321
3322         // Create new Pending request
3323         dest_pending = tcore_pending_new(o, 0);
3324
3325         // Create new AT-Command request
3326         dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3327         dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3328
3329         // Free Command string
3330         g_free(cmd_str);
3331
3332         tcore_pending_set_request_data(dest_pending, 0, dest_req);
3333
3334         // Send request
3335         ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
3336         if (!ret) {
3337                 err("Failed to send AT-Command request");
3338                 return TCORE_RETURN_FAILURE;
3339         }
3340
3341         return TCORE_RETURN_SUCCESS;
3342 }
3343
3344
3345 static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
3346 {
3347         dbg("Entry");
3348
3349         dbg("Exit");
3350         return TCORE_RETURN_SUCCESS;
3351 }
3352
3353 static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
3354 {
3355         char *cmd_str = NULL;
3356         TcorePending *pending = NULL;
3357         TcoreATRequest *req = NULL;
3358         gboolean ret = FALSE;
3359
3360         dbg("Entry");
3361
3362         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3363                 dbg("cp not ready/n");
3364                 return TCORE_RETURN_ENOSYS;
3365         }
3366
3367         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
3368
3369         dbg("Request command string: %s", cmd_str);
3370
3371         // Create new Pending request
3372         pending = tcore_pending_new(o, 0);
3373
3374         // Create new AT-Command request
3375         req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3376         dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3377
3378         // Free command string
3379         g_free(cmd_str);
3380
3381         // Set request data (AT command) to Pending request
3382         tcore_pending_set_request_data(pending, 0, req);
3383
3384         // Send request
3385         ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
3386         if (!ret) {
3387                 err("Failed to send AT-Command request");
3388                 return TCORE_RETURN_FAILURE;
3389         }
3390
3391         dbg("Exit");
3392         return TCORE_RETURN_SUCCESS;
3393 }
3394
3395 static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
3396 {
3397         char *cmd_str = NULL;
3398         TcorePending *pending = NULL;
3399         TcoreATRequest *req = NULL;
3400         gboolean ret = FALSE;
3401
3402         dbg("Entry");
3403
3404         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3405                 dbg("cp not ready/n");
3406                 return TCORE_RETURN_ENOSYS;
3407         }
3408
3409         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
3410         dbg("Request command string: %s", cmd_str);
3411
3412         // Create new Pending request
3413         pending = tcore_pending_new(o, 0);
3414
3415         // Create new AT-Command request
3416         req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3417         dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3418
3419         // Free command string
3420         g_free(cmd_str);
3421
3422         // Set request data (AT command) to Pending request
3423         tcore_pending_set_request_data(pending, 0, req);
3424
3425         // Send request
3426         ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
3427         if (!ret) {
3428                 err("Failed to send AT-Command request");
3429                 return TCORE_RETURN_FAILURE;
3430         }
3431
3432         dbg("Exit");
3433         return TCORE_RETURN_SUCCESS;
3434 }
3435
3436
3437 static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
3438 {
3439         dbg("Entry");
3440
3441         dbg("Exit");
3442         return TCORE_RETURN_SUCCESS;
3443 }
3444
3445 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
3446 {
3447         char *cmd_str = NULL;
3448         TcorePending *pending = NULL;
3449         TcoreATRequest *req = NULL;
3450         gboolean ret = FALSE;
3451
3452         dbg("Entry");
3453
3454         cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where  n = (0 - 255) * 1/10 secs.
3455         dbg("Request command string: %s", cmd_str);
3456
3457         // Create new Pending request
3458         pending = tcore_pending_new(o, 0);
3459
3460         // Create new AT-Command request
3461         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3462         dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3463
3464         // Free command string */
3465         g_free(cmd_str);
3466
3467         // Set request data (AT command) to Pending request
3468         tcore_pending_set_request_data(pending, 0, req);
3469
3470         // Send request
3471         ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
3472         if (!ret) {
3473                 err("Failed to send AT-Command request");
3474                 if (ur) {
3475                         tcore_user_request_free(ur);
3476                         ur = NULL;
3477                 }
3478                 return TCORE_RETURN_FAILURE;
3479         }
3480
3481         dbg("Exit");
3482         return TCORE_RETURN_SUCCESS;
3483 }
3484
3485 // Call Operations
3486 static struct tcore_call_operations call_ops = {
3487         .dial = s_call_outgoing,
3488         .answer = s_call_answer,
3489         .end = s_call_release,
3490         .hold = s_call_hold,
3491         .active = s_call_active,
3492         .swap = s_call_swap,
3493         .join = s_call_join,
3494         .split = s_call_split,
3495         .deflect = s_call_deflect,
3496         .transfer = s_call_transfer,
3497         .send_dtmf = s_call_send_dtmf,
3498         .set_sound_path = s_call_set_sound_path,
3499         .set_sound_volume_level = s_call_set_sound_volume_level,
3500         .get_sound_volume_level = s_call_get_sound_volume_level,
3501         .mute = s_call_mute,
3502         .unmute = s_call_unmute,
3503         .get_mute_status = s_call_get_mute_status,
3504         .set_sound_recording = NULL,
3505         .set_sound_equalization = NULL,
3506         .set_sound_noise_reduction = NULL,
3507 };
3508
3509 gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call)
3510 {
3511         dbg("Entry");
3512
3513         tcore_call_override_ops(co_call, &call_ops, NULL);
3514
3515         /* Add Callbacks */
3516         tcore_object_override_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
3517         tcore_object_override_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
3518
3519         dbg("Exit");
3520
3521         return TRUE;
3522 }
3523
3524 void s_call_exit(TcorePlugin *cp, CoreObject *co_call)
3525 {
3526         dbg("Exit");
3527 }