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