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