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