Always use semi-colon at the end of macro to avoid missleading
[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         if (num) {
2371                 g_free(num);
2372                 num = NULL;
2373         }
2374
2375         // Free tokens
2376         tcore_at_tok_free(tokens);
2377         err("Exit");
2378         return -1;
2379 }
2380
2381 // NOTIFICATION
2382 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
2383 {
2384         GSList *tokens = NULL;
2385         const char *line = NULL;
2386         char *pId;
2387         int call_id;
2388         gboolean *eflag;
2389         GSList *pList = NULL;
2390         CallObject *co = NULL, *dupco = NULL;
2391
2392         dbg("function entrance");
2393         // check call with waiting status already exist
2394         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
2395
2396         if (pList != NULL) {
2397                 dbg("[error]Waiting call already exist. skip");
2398                 return;
2399         }
2400         // check call with incoming status already exist
2401         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2402
2403         if (pList != NULL) {
2404                 dbg("[error]incoming call already exist. skip");
2405                 return;
2406         }
2407         line = (char *) data;
2408         tokens = tcore_at_tok_new(line);
2409
2410         pId = g_slist_nth_data(tokens, 0);
2411         if (!pId) {
2412                 dbg("[error]:Call id is missing from +XCALLSTAT indication");
2413                 tcore_at_tok_free(tokens);
2414                 return;
2415         }
2416
2417         call_id = atoi(pId);
2418         dupco = tcore_call_object_find_by_id(o, call_id);
2419         if (dupco != NULL) {
2420                 dbg("co with same id already exist. skip");
2421                 tcore_at_tok_free(tokens);
2422                 return;
2423         }
2424         co = tcore_call_object_new(o, call_id);
2425         if (!co) {
2426                 dbg("[ error ] co is NULL");
2427                 tcore_at_tok_free(tokens);
2428                 return;
2429         }
2430
2431         tcore_at_tok_free(tokens);
2432
2433         eflag = g_new0(gboolean, 1);
2434         *eflag = TRUE;
2435         dbg("calling _call_list_get");
2436         _call_list_get(o, eflag);
2437 }
2438
2439 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
2440 {
2441         GSList *tokens = NULL;
2442         const char *line = NULL;
2443         char *pId;
2444         int call_id;
2445         gboolean *eflag;
2446         GSList *pList = NULL;
2447         CallObject *co = NULL, *dupco = NULL;
2448
2449         dbg("function entrance");
2450         // check call with incoming status already exist
2451         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2452
2453         if (pList != NULL) {
2454                 dbg("incoming call already exist. skip");
2455                 return;
2456         }
2457
2458         line = (char *) data;
2459         tokens = tcore_at_tok_new(line);
2460
2461         pId = g_slist_nth_data(tokens, 0);
2462         if (!pId) {
2463                 dbg("Error:Call id is missing from %XCALLSTAT indication");
2464                 tcore_at_tok_free(tokens);
2465                 return;
2466         }
2467
2468         call_id = atoi(pId);
2469
2470         dupco = tcore_call_object_find_by_id(o, call_id);
2471         if (dupco != NULL) {
2472                 dbg("co with same id already exist. skip");
2473                 tcore_at_tok_free(tokens);
2474                 return;
2475         }
2476
2477         co = tcore_call_object_new(o, call_id);
2478         if (!co) {
2479                 dbg("[ error ] co is NULL");
2480                 tcore_at_tok_free(tokens);
2481                 return;
2482         }
2483
2484         dbg("freeing  at token");
2485         tcore_at_tok_free(tokens);
2486
2487         eflag = g_new0(gboolean, 1);
2488         *eflag = TRUE;
2489
2490         dbg("calling  _call_list_get");
2491         _call_list_get(o, eflag);
2492 }
2493
2494 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
2495 {
2496         char *cmd = NULL;
2497         TcorePlugin *plugin = NULL;
2498         CallObject *co = NULL;
2499         int id = -1;
2500         int status = 0;
2501         int type = 0;
2502         char *stat = NULL;
2503         char *pCallId = NULL;
2504         GSList *tokens = NULL;
2505         gboolean *eflag = NULL;
2506         enum tcore_call_status co_status;
2507
2508         dbg("function entrance");
2509         plugin = tcore_object_ref_plugin(o);
2510         cmd = (char *) data;
2511         tokens = tcore_at_tok_new(cmd);
2512
2513         // parse <Call Id>
2514         pCallId = g_slist_nth_data(tokens, 0);
2515         if (!pCallId) {
2516                 dbg("CallId is missing from %XCALLSTAT indication");
2517                 tcore_at_tok_free(tokens);
2518                 return;
2519         } else {
2520                 id = atoi(pCallId);
2521                 dbg("call id = %d", id);
2522                 // parse <Stat>
2523                 if ((stat = g_slist_nth_data(tokens, 1))) {
2524                         status = atoi(stat);
2525                 }
2526                 dbg("call status = %d", status);
2527         }
2528
2529         tcore_at_tok_free(tokens);
2530         co_status = _call_status(status);
2531
2532         dbg("co_status = %d", co_status);
2533         switch (co_status) {
2534         case CALL_STATUS_ACTIVE:
2535         {
2536                 dbg("call(%d) status : [ ACTIVE ]", id);
2537                 co = tcore_call_object_find_by_id(o, id);
2538                 if (!co) {
2539                         dbg("co is NULL");
2540                         return;
2541                 }
2542                 _call_status_active(plugin, co);
2543         }
2544         break;
2545
2546         case CALL_STATUS_HELD:
2547                 dbg("call(%d) status : [ held ]", id);
2548                 break;
2549
2550         case CALL_STATUS_DIALING:
2551         {
2552                 dbg("call(%d) status : [ dialing ]", id);
2553                 co = tcore_call_object_find_by_id(o, id);
2554                 if (!co) {
2555                         co = tcore_call_object_new(o, id);
2556                         if (!co) {
2557                                 dbg("error : tcore_call_object_new [ id : %d ]", id);
2558                                 return;
2559                         }
2560                 }
2561
2562                 tcore_call_object_set_type(co, call_type(type));
2563                 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
2564                 _call_status_dialing(plugin, co);
2565         }
2566         break;
2567
2568         case CALL_STATUS_ALERT:
2569         {
2570                 dbg("call(%d) status : [ alert ]", id);
2571                 co = tcore_call_object_find_by_id(o, id);
2572                 if (!co) {
2573                         dbg("co is NULL");
2574                         return;
2575                 }
2576                 // Store dialed number information into Call object.
2577                 eflag = g_new0(gboolean, 1);
2578                 *eflag = TRUE;
2579                 dbg("calling _call_list_get");
2580                 _call_list_get(o, eflag);
2581         }
2582         break;
2583
2584         case CALL_STATUS_INCOMING:
2585         case CALL_STATUS_WAITING:
2586                 dbg("call(%d) status : [ incoming ]", id);
2587                 break;
2588
2589         case CALL_STATUS_IDLE:
2590         {
2591                 dbg("call(%d) status : [ release ]", id);
2592
2593                 co = tcore_call_object_find_by_id(o, id);
2594                 if (!co) {
2595                         dbg("co is NULL");
2596                         return;
2597                 }
2598
2599                 plugin = tcore_object_ref_plugin(o);
2600                 if (!plugin) {
2601                         dbg("plugin is NULL");
2602                         return;
2603                 }
2604                 _call_status_idle(plugin, co);
2605         }
2606         break;
2607
2608         default:
2609                 dbg("invalid call status", id);
2610                 break;
2611         }
2612 }
2613
2614 static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
2615 {
2616         struct treq_call_dial *data = 0;
2617         char *raw_str = NULL;
2618         char *cmd_str = NULL;
2619         const char *cclir;
2620         enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
2621         TcorePending *pending = NULL;
2622         TcoreATRequest *req;
2623         gboolean ret = FALSE;
2624
2625         dbg("function entrance");
2626
2627         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2628                 dbg("cp not ready/n");
2629                 return TCORE_RETURN_ENOSYS;
2630         }
2631
2632         data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
2633         if (data->type == CALL_TYPE_VIDEO) {
2634                 dbg("invalid call type");
2635                 return TCORE_RETURN_FAILURE;
2636         }
2637
2638         clir = _get_clir_status(data->number);
2639
2640         // Compose ATD Cmd string
2641         switch (clir) {
2642         case TCORE_CALL_CLI_MODE_PRESENT:
2643                 dbg("CALL_CLI_MODE_PRESENT");
2644                 cclir = "I";
2645                 break;  // invocation
2646
2647         case TCORE_CALL_CLI_MODE_RESTRICT:
2648                 dbg("CALL_CLI_MODE_RESTRICT");
2649                 cclir = "i";
2650                 break;  // suppression
2651
2652         case TCORE_CALL_CLI_MODE_DEFAULT:
2653         default:
2654                 cclir = "";
2655                 dbg("CALL_CLI_MODE_DEFAULT");
2656                 break;   // subscription default
2657         }
2658
2659         dbg("data->number = %s", data->number);
2660
2661         raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
2662         cmd_str = g_strdup_printf("%s", raw_str);
2663
2664         dbg("request command : %s", cmd_str);
2665
2666         pending = tcore_pending_new(o, 0);
2667         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2668         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2669
2670         tcore_pending_set_request_data(pending, 0, req);
2671         ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
2672
2673         g_free(raw_str);
2674         g_free(cmd_str);
2675
2676         if (!ret) {
2677                 dbg("AT request(%s) sent failed", req->cmd);
2678                 return TCORE_RETURN_FAILURE;
2679         }
2680
2681         dbg("AT request(%s) sent success", req->cmd);
2682
2683         return TCORE_RETURN_SUCCESS;
2684 }
2685
2686 static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
2687 {
2688         char *cmd_str = NULL;
2689         CallObject *co = NULL;
2690         struct treq_call_answer *data = 0;
2691         TcorePending *pending = NULL;
2692         TcoreATRequest *req;
2693         gboolean ret = FALSE;
2694
2695         dbg("function entrance");
2696
2697         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2698                 dbg("cp not ready/n");
2699                 return TCORE_RETURN_ENOSYS;
2700         }
2701
2702         data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
2703         co = tcore_call_object_find_by_id(o, data->id);
2704         if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
2705                 dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
2706
2707                 cmd_str = g_strdup_printf("%s", "ATA");
2708                 pending = tcore_pending_new(o, 0);
2709                 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2710                 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2711
2712                 tcore_pending_set_request_data(pending, 0, req);
2713                 ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
2714                 g_free(cmd_str);
2715
2716                 if (!ret) {
2717                         dbg("AT request(%s) sent failed", req->cmd);
2718                         return TCORE_RETURN_FAILURE;
2719                 }
2720         } else {
2721                 switch (data->type) {
2722                 case CALL_ANSWER_TYPE_REJECT:
2723                 {
2724                         dbg("call answer reject");
2725                         tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
2726                 }
2727                 break;
2728
2729                 case CALL_ANSWER_TYPE_REPLACE:
2730                 {
2731                         dbg("call answer replace");
2732                         tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
2733                 }
2734                 break;
2735
2736                 case CALL_ANSWER_TYPE_HOLD_ACCEPT:
2737                 {
2738                         dbg("call answer hold and accept");
2739                         tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
2740                 }
2741                 break;
2742
2743                 default:
2744                         dbg("[ error ] wrong answer type [ %d ]", data->type);
2745                         return TCORE_RETURN_FAILURE;
2746                 }
2747         }
2748
2749         return TCORE_RETURN_SUCCESS;
2750 }
2751
2752 static TReturn s_call_release(CoreObject *o, UserRequest *ur)
2753 {
2754         CallObject *co = NULL;
2755         struct treq_call_end *data = 0;
2756         UserRequest *ur_dup = NULL;
2757         char *chld0_cmd = NULL;
2758         char *chld1_cmd = NULL;
2759         TcorePending *pending = NULL, *pending1 = NULL;
2760         TcoreATRequest *req, *req1;
2761         gboolean ret = FALSE;
2762
2763         dbg("function entrance");
2764         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2765                 dbg("cp not ready/n");
2766                 return TCORE_RETURN_ENOSYS;
2767         }
2768         data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
2769         co = tcore_call_object_find_by_id(o, data->id);
2770
2771         dbg("type of release call = %d", data->type);
2772
2773         if (data->type == CALL_END_TYPE_ALL) {
2774                 // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
2775                 chld0_cmd = g_strdup("AT+CHLD=0");
2776                 chld1_cmd = g_strdup("AT+CHLD=1");
2777
2778                 pending = tcore_pending_new(o, 0);
2779                 req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
2780
2781                 dbg("input command is %s", chld0_cmd);
2782                 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2783
2784                 tcore_pending_set_request_data(pending, 0, req);
2785                 ur_dup = tcore_user_request_new(NULL, NULL);
2786                 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
2787                 g_free(chld0_cmd);
2788
2789                 if (!ret) {
2790                         dbg("AT request %s has failed ", req->cmd);
2791                         if (ur_dup) {
2792                                 tcore_user_request_free(ur_dup);
2793                                 ur_dup = NULL;
2794                         }
2795                         g_free(chld1_cmd);
2796                         return TCORE_RETURN_FAILURE;
2797                 }
2798
2799                 pending1 = tcore_pending_new(o, 0);
2800                 req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
2801
2802                 dbg("input command is %s", chld1_cmd);
2803                 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2804
2805                 tcore_pending_set_request_data(pending1, 0, req1);
2806                 ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
2807                 g_free(chld1_cmd);
2808
2809                 if (!ret) {
2810                         dbg("AT request %s has failed ", req->cmd);
2811                         return TCORE_RETURN_FAILURE;
2812                 }
2813         } else {
2814                 switch (data->type) {
2815                 case CALL_END_TYPE_DEFAULT:
2816                 {
2817                         int id = 0;
2818                         id = tcore_call_object_get_id(co);
2819
2820                         dbg("call end call id [%d]", id);
2821                         tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
2822                 }
2823                 break;
2824
2825                 case CALL_END_TYPE_ACTIVE_ALL:
2826                 {
2827                         dbg("call end all active");
2828                         tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
2829                 }
2830                 break;
2831
2832                 case CALL_END_TYPE_HOLD_ALL:
2833                 {
2834                         dbg("call end all held");
2835                         tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
2836                 }
2837                 break;
2838
2839                 default:
2840                         dbg("[ error ] wrong end type [ %d ]", data->type);
2841                         return TCORE_RETURN_FAILURE;
2842                 }
2843         }
2844
2845         return TCORE_RETURN_SUCCESS;
2846 }
2847
2848 static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
2849 {
2850         struct treq_call_hold *hold = 0;
2851         CallObject *co = NULL;
2852
2853         dbg("function entrance");
2854
2855         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2856                 dbg("cp not ready/n");
2857                 return TCORE_RETURN_ENOSYS;
2858         }
2859
2860         hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
2861         dbg("call id : [ %d ]", hold->id);
2862
2863         co = tcore_call_object_find_by_id(o, hold->id);
2864         tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
2865
2866         return TCORE_RETURN_SUCCESS;
2867 }
2868
2869 static TReturn s_call_active(CoreObject *o, UserRequest *ur)
2870 {
2871         struct treq_call_active *active = 0;
2872         CallObject *co = NULL;
2873
2874         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2875                 dbg("cp not ready/n");
2876                 return TCORE_RETURN_ENOSYS;
2877         }
2878
2879         active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
2880         dbg("call id : [ %d ]", active->id);
2881
2882         co = tcore_call_object_find_by_id(o, active->id);
2883         tcore_call_control_active(o, ur, on_confirmation_call_active, co);
2884
2885         return TCORE_RETURN_SUCCESS;
2886 }
2887
2888 static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
2889 {
2890         struct treq_call_swap *swap = NULL;
2891         CallObject *co = NULL;
2892
2893         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2894                 dbg("cp not ready/n");
2895                 return TCORE_RETURN_ENOSYS;
2896         }
2897
2898         swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
2899         dbg("call id : [ %d ]", swap->id);
2900
2901         co = tcore_call_object_find_by_id(o, swap->id);
2902         tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
2903
2904         return TCORE_RETURN_SUCCESS;
2905 }
2906
2907 static TReturn s_call_join(CoreObject *o, UserRequest *ur)
2908 {
2909         struct treq_call_join *join = 0;
2910         CallObject *co = NULL;
2911
2912         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2913                 dbg("cp not ready/n");
2914                 return TCORE_RETURN_ENOSYS;
2915         }
2916
2917         join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
2918         dbg("call id : [ %d ]", join->id);
2919
2920         co = tcore_call_object_find_by_id(o, join->id);
2921         tcore_call_control_join(o, ur, on_confirmation_call_join, co);
2922
2923         return TCORE_RETURN_SUCCESS;
2924 }
2925
2926 static TReturn s_call_split(CoreObject *o, UserRequest *ur)
2927 {
2928         struct treq_call_split *split = 0;
2929         CallObject *co = NULL;
2930
2931         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2932                 dbg("cp not ready/n");
2933                 return TCORE_RETURN_ENOSYS;
2934         }
2935
2936         split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
2937         co = tcore_call_object_find_by_id(o, split->id);
2938         dbg("call id : [ %d ]", split->id);
2939
2940         tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
2941
2942         return TCORE_RETURN_SUCCESS;
2943 }
2944
2945 static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
2946 {
2947         struct treq_call_deflect *deflect = 0;
2948         CallObject *co = NULL;
2949
2950         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2951                 dbg("cp not ready/n");
2952                 return TCORE_RETURN_ENOSYS;
2953         }
2954
2955         deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
2956         co = tcore_call_object_find_by_number(o, deflect->number);
2957         dbg("deflect number: [ %s ]", deflect->number);
2958
2959         tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
2960
2961         return TCORE_RETURN_SUCCESS;
2962 }
2963
2964 static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
2965 {
2966         struct treq_call_transfer *transfer = 0;
2967         CallObject *co = NULL;
2968
2969         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2970                 dbg("cp not ready/n");
2971                 return TCORE_RETURN_ENOSYS;
2972         }
2973
2974         transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
2975         dbg("call id : [ %d ]", transfer->id);
2976
2977         co = tcore_call_object_find_by_id(o, transfer->id);
2978         tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
2979
2980         return TCORE_RETURN_SUCCESS;
2981 }
2982
2983 static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
2984 {
2985         char *cmd_str = NULL;
2986         TcorePending *pending = NULL;
2987         TcoreATRequest *req;
2988         UserRequest *dup;
2989         gboolean ret = FALSE;
2990         struct treq_call_dtmf *dtmf = 0;
2991         char *dtmfstr = NULL, *tmp_dtmf = NULL;
2992         unsigned int dtmf_count;
2993
2994         dbg("Function enter");
2995
2996         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2997                 dbg("cp not ready/n");
2998                 return TCORE_RETURN_ENOSYS;
2999         }
3000
3001         dup = tcore_user_request_new(NULL, NULL);
3002         (void) _set_dtmf_tone_duration(o, dup);
3003
3004         dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
3005         dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1);    // DTMF digits + comma for each dtmf digit.
3006
3007         if (dtmfstr == NULL) {
3008                 dbg("Memory allocation failed");
3009                 return TCORE_RETURN_FAILURE;
3010         }
3011
3012         tmp_dtmf = dtmfstr;
3013
3014         for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
3015                 *tmp_dtmf = dtmf->digits[dtmf_count];
3016                 tmp_dtmf++;
3017
3018                 *tmp_dtmf = COMMA;
3019                 tmp_dtmf++;
3020         }
3021
3022         // last digit is having COMMA , overwrite it with '\0' .
3023         *(--tmp_dtmf) = '\0';
3024         dbg("Input DTMF string(%s)", dtmfstr);
3025
3026         // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
3027         cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
3028         dbg("request command : %s", cmd_str);
3029
3030         pending = tcore_pending_new(o, 0);
3031         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3032         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3033
3034         tcore_pending_set_request_data(pending, 0, req);
3035         ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
3036         g_free(dtmfstr);
3037         g_free(cmd_str);
3038
3039         if (!ret) {
3040                 dbg("AT request sent failed");
3041                 return TCORE_RETURN_FAILURE;
3042         }
3043
3044         return TCORE_RETURN_SUCCESS;
3045 }
3046
3047 static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
3048 {
3049         UserRequest *ur_dup = NULL;
3050         TcorePending *pending = NULL, *pending1 = NULL;
3051         TcoreATRequest *req, *req1;
3052         char *cmd_str = NULL, *cmd_str1 = NULL;
3053         int device_type = -1;
3054         struct treq_call_sound_set_path *sound_path = 0;
3055         gboolean ret = FALSE;
3056         TcorePlugin *plugin = tcore_object_ref_plugin(o);
3057         const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
3058
3059         dbg("function entrance");
3060
3061         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3062                 dbg("cp not ready/n");
3063                 return TCORE_RETURN_ENOSYS;
3064         }
3065         sound_path = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
3066         if (sound_path == NULL) {
3067                 dbg("invaling user request");
3068                 return TCORE_RETURN_FAILURE;
3069         }
3070         dbg("audio device type - 0x%x", sound_path->path);
3071         switch (sound_path->path) {
3072         case CALL_SOUND_PATH_HANDSET:
3073                 device_type = 1;
3074                 break;
3075
3076         case CALL_SOUND_PATH_HEADSET:
3077                 device_type = 2;
3078                 break;
3079
3080         case CALL_SOUND_PATH_HEADSET_3_5PI:
3081                 device_type = 3;
3082                 break;
3083
3084         case CALL_SOUND_PATH_SPEAKER:
3085                 device_type = 4;
3086                 break;
3087
3088         case CALL_SOUND_PATH_HANDFREE:
3089                 device_type = 5;
3090                 break;
3091
3092         case CALL_SOUND_PATH_HEADSET_HAC:
3093                 device_type = 6;
3094                 break;
3095
3096         case CALL_SOUND_PATH_BLUETOOTH:
3097         case CALL_SOUND_PATH_STEREO_BLUETOOTH:
3098                 device_type = 7;
3099                 break;
3100
3101         case CALL_SOUND_PATH_BT_NSEC_OFF:
3102         case CALL_SOUND_PATH_MIC1:
3103         case CALL_SOUND_PATH_MIC2:
3104         default:
3105                 dbg("unsupported device type");
3106                 return TCORE_RETURN_FAILURE;
3107         }
3108
3109         if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
3110                 struct tnoti_call_sound_path *tnoti_snd_path;
3111
3112                 tnoti_snd_path = g_try_new0(struct tnoti_call_sound_path, 1);
3113                 if (!tnoti_snd_path)
3114                         return TCORE_RETURN_ENOMEM;
3115
3116                 tnoti_snd_path->path = sound_path->path;
3117
3118                 /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
3119                 if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
3120                         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);
3121                         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);
3122                 }
3123                 else {
3124                         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);
3125                         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);
3126                 }
3127
3128                 /* Configure modem I2S2 and do the modem routing */
3129                 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);
3130                 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);
3131                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
3132                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
3133                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
3134                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
3135
3136                 /* amc enable */
3137                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
3138                 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
3139                 /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
3140
3141                 pending = tcore_pending_new(o, 0);
3142                 req = tcore_at_request_new("AT+XDRV=40,6,0,2", "+XDRV", TCORE_AT_SINGLELINE);
3143                 dbg("XDRV req-cmd for source type  : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3144                 tcore_pending_set_request_data(pending, 0, req);
3145                 ur_dup = tcore_user_request_ref(ur);
3146                 ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, tnoti_snd_path);
3147
3148         } else {
3149
3150                 cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
3151                 pending = tcore_pending_new(o, 0);
3152                 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3153                 dbg("XDRV req-cmd for source type  : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3154                 tcore_pending_set_request_data(pending, 0, req);
3155                 ur_dup = tcore_user_request_ref(ur);
3156                 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
3157                 g_free(cmd_str);
3158
3159                 if (!ret) {
3160                         dbg("At request(%s) sent failed", req->cmd);
3161                         return TCORE_RETURN_FAILURE;
3162                 }
3163
3164                 cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
3165                 pending1 = tcore_pending_new(o, 0);
3166                 req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
3167                 dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
3168                 tcore_pending_set_request_data(pending1, 0, req1);
3169                 ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
3170                 g_free(cmd_str1);
3171
3172                 if (!ret) {
3173                         dbg("AT request %s has failed ", req1->cmd);
3174                         return TCORE_RETURN_FAILURE;
3175                 }
3176         }
3177
3178         return TCORE_RETURN_SUCCESS;
3179 }
3180
3181 static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
3182 {
3183         UserRequest *src_ur = NULL;
3184         UserRequest *dest_ur = NULL;
3185         TcorePending *src_pending = NULL;
3186         TcorePending *dest_pending = NULL;
3187         TcoreATRequest *src_req = NULL;
3188         TcoreATRequest *dest_req = NULL;
3189         char *cmd_str = NULL, *volume_level = NULL;
3190         gboolean ret = FALSE;
3191         struct treq_call_sound_set_volume_level *data = NULL;
3192
3193         dbg("Entry");
3194
3195         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3196                 dbg("cp not ready/n");
3197                 return TCORE_RETURN_ENOSYS;
3198         }
3199
3200         data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
3201
3202         // Hard-coded values for MIC & Speakers
3203         // Source volume
3204         dbg("Set Source volume");
3205
3206         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88");   // Source type
3207         dbg("Request command string: %s", cmd_str);
3208
3209         // Create new Pending request
3210         src_pending = tcore_pending_new(o, 0);
3211
3212         // Create new AT-Command request
3213         src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3214         dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3215
3216         // Free Command string
3217         g_free(cmd_str);
3218
3219         tcore_pending_set_request_data(src_pending, 0, src_req);
3220         src_ur = tcore_user_request_ref(ur);
3221
3222         // Send request
3223         ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3224         if (!ret) {
3225                 err("Failed to send AT-Command request");
3226                 return TCORE_RETURN_FAILURE;
3227         }
3228
3229         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88");   // Destination type
3230         dbg("Request command string: %s", cmd_str);
3231
3232         // Create new Pending request
3233         src_pending = tcore_pending_new(o, 0);
3234
3235         // Create new AT-Command request
3236         src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3237         dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3238
3239         // Free Command string
3240         g_free(cmd_str);
3241
3242         tcore_pending_set_request_data(src_pending, 0, src_req);
3243
3244         src_ur = tcore_user_request_ref(ur);
3245
3246         // Send request
3247         ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3248         if (!ret) {
3249                 err("Failed to send AT-Command request");
3250                 return TCORE_RETURN_FAILURE;
3251         }
3252
3253         // Destination volume
3254         dbg("Set Source volume");
3255
3256         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88");   // Source type
3257         dbg("Request command string: %s", cmd_str);
3258
3259         // Create new Pending request
3260         dest_pending = tcore_pending_new(o, 0);
3261
3262         // Create new AT-Command request
3263         dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3264         dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3265
3266         // Free Command string
3267         g_free(cmd_str);
3268
3269         tcore_pending_set_request_data(dest_pending, 0, dest_req);
3270         dest_ur = tcore_user_request_ref(ur);
3271
3272         // Send request
3273         ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3274         if (!ret) {
3275                 err("Failed to send AT-Command request");
3276                 return TCORE_RETURN_FAILURE;
3277         }
3278
3279         dbg("Input volume level - %d", data->volume);
3280         switch (data->volume) {
3281         case CALL_SOUND_MUTE:
3282                 volume_level = "0";
3283                 break;
3284
3285         case CALL_SOUND_VOLUME_LEVEL_1:
3286                 volume_level = "40";
3287                 break;
3288
3289         case CALL_SOUND_VOLUME_LEVEL_2:
3290                 volume_level = "46";
3291                 break;
3292
3293         case CALL_SOUND_VOLUME_LEVEL_3:
3294                 volume_level = "52";
3295                 break;
3296
3297         case CALL_SOUND_VOLUME_LEVEL_4:
3298                 volume_level = "58";
3299                 break;
3300
3301         case CALL_SOUND_VOLUME_LEVEL_5:
3302                 volume_level = "64";
3303                 break;
3304
3305         case CALL_SOUND_VOLUME_LEVEL_6:
3306                 volume_level = "70";
3307                 break;
3308
3309         case CALL_SOUND_VOLUME_LEVEL_7:
3310                 volume_level = "76";
3311                 break;
3312
3313         case CALL_SOUND_VOLUME_LEVEL_8:
3314                 volume_level = "82";
3315                 break;
3316
3317         case CALL_SOUND_VOLUME_LEVEL_9:
3318         default:
3319                 volume_level = "88";
3320                 break;
3321         }
3322         cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level);   // Destination type
3323         dbg("Request command string: %s", cmd_str);
3324
3325         // Create new Pending request
3326         dest_pending = tcore_pending_new(o, 0);
3327
3328         // Create new AT-Command request
3329         dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3330         dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3331
3332         // Free Command string
3333         g_free(cmd_str);
3334
3335         tcore_pending_set_request_data(dest_pending, 0, dest_req);
3336
3337         // Send request
3338         ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
3339         if (!ret) {
3340                 err("Failed to send AT-Command request");
3341                 return TCORE_RETURN_FAILURE;
3342         }
3343
3344         return TCORE_RETURN_SUCCESS;
3345 }
3346
3347
3348 static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
3349 {
3350         dbg("Entry");
3351
3352         dbg("Exit");
3353         return TCORE_RETURN_SUCCESS;
3354 }
3355
3356 static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
3357 {
3358         char *cmd_str = NULL;
3359         TcorePending *pending = NULL;
3360         TcoreATRequest *req = NULL;
3361         gboolean ret = FALSE;
3362
3363         dbg("Entry");
3364
3365         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3366                 dbg("cp not ready/n");
3367                 return TCORE_RETURN_ENOSYS;
3368         }
3369
3370         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
3371
3372         dbg("Request command string: %s", cmd_str);
3373
3374         // Create new Pending request
3375         pending = tcore_pending_new(o, 0);
3376
3377         // Create new AT-Command request
3378         req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3379         dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3380
3381         // Free command string
3382         g_free(cmd_str);
3383
3384         // Set request data (AT command) to Pending request
3385         tcore_pending_set_request_data(pending, 0, req);
3386
3387         // Send request
3388         ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
3389         if (!ret) {
3390                 err("Failed to send AT-Command request");
3391                 return TCORE_RETURN_FAILURE;
3392         }
3393
3394         dbg("Exit");
3395         return TCORE_RETURN_SUCCESS;
3396 }
3397
3398 static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
3399 {
3400         char *cmd_str = NULL;
3401         TcorePending *pending = NULL;
3402         TcoreATRequest *req = NULL;
3403         gboolean ret = FALSE;
3404
3405         dbg("Entry");
3406
3407         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3408                 dbg("cp not ready/n");
3409                 return TCORE_RETURN_ENOSYS;
3410         }
3411
3412         cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
3413         dbg("Request command string: %s", cmd_str);
3414
3415         // Create new Pending request
3416         pending = tcore_pending_new(o, 0);
3417
3418         // Create new AT-Command request
3419         req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3420         dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3421
3422         // Free command string
3423         g_free(cmd_str);
3424
3425         // Set request data (AT command) to Pending request
3426         tcore_pending_set_request_data(pending, 0, req);
3427
3428         // Send request
3429         ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
3430         if (!ret) {
3431                 err("Failed to send AT-Command request");
3432                 return TCORE_RETURN_FAILURE;
3433         }
3434
3435         dbg("Exit");
3436         return TCORE_RETURN_SUCCESS;
3437 }
3438
3439
3440 static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
3441 {
3442         dbg("Entry");
3443
3444         dbg("Exit");
3445         return TCORE_RETURN_SUCCESS;
3446 }
3447
3448 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
3449 {
3450         char *cmd_str = NULL;
3451         TcorePending *pending = NULL;
3452         TcoreATRequest *req = NULL;
3453         gboolean ret = FALSE;
3454
3455         dbg("Entry");
3456
3457         cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where  n = (0 - 255) * 1/10 secs.
3458         dbg("Request command string: %s", cmd_str);
3459
3460         // Create new Pending request
3461         pending = tcore_pending_new(o, 0);
3462
3463         // Create new AT-Command request
3464         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3465         dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3466
3467         // Free command string */
3468         g_free(cmd_str);
3469
3470         // Set request data (AT command) to Pending request
3471         tcore_pending_set_request_data(pending, 0, req);
3472
3473         // Send request
3474         ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
3475         if (!ret) {
3476                 err("Failed to send AT-Command request");
3477                 if (ur) {
3478                         tcore_user_request_free(ur);
3479                         ur = NULL;
3480                 }
3481                 return TCORE_RETURN_FAILURE;
3482         }
3483
3484         dbg("Exit");
3485         return TCORE_RETURN_SUCCESS;
3486 }
3487
3488 // Call Operations
3489 static struct tcore_call_operations call_ops = {
3490         .dial = s_call_outgoing,
3491         .answer = s_call_answer,
3492         .end = s_call_release,
3493         .hold = s_call_hold,
3494         .active = s_call_active,
3495         .swap = s_call_swap,
3496         .join = s_call_join,
3497         .split = s_call_split,
3498         .deflect = s_call_deflect,
3499         .transfer = s_call_transfer,
3500         .send_dtmf = s_call_send_dtmf,
3501         .set_sound_path = s_call_set_sound_path,
3502         .set_sound_volume_level = s_call_set_sound_volume_level,
3503         .get_sound_volume_level = s_call_get_sound_volume_level,
3504         .mute = s_call_mute,
3505         .unmute = s_call_unmute,
3506         .get_mute_status = s_call_get_mute_status,
3507         .set_sound_recording = NULL,
3508         .set_sound_equalization = NULL,
3509         .set_sound_noise_reduction = NULL,
3510 };
3511
3512 gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call)
3513 {
3514         dbg("Entry");
3515
3516         tcore_call_override_ops(co_call, &call_ops, NULL);
3517
3518         /* Add Callbacks */
3519         tcore_object_override_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
3520         tcore_object_override_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
3521
3522         dbg("Exit");
3523
3524         return TRUE;
3525 }
3526
3527 void s_call_exit(TcorePlugin *cp, CoreObject *co_call)
3528 {
3529         dbg("Exit");
3530 }