4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: sharanayya mathapati <sharan.m@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
29 #include <core_object.h>
33 #include <user_request.h>
41 #define STATUS_INCOMING 4
42 #define STATUS_WAITING 5
43 #define STATUS_CONNECTED 7
46 static gboolean setsoundpath = FALSE;
47 static gboolean soundvolume = FALSE;
49 // End Cause field - Call state end cause
54 // These definitions are taken from GSM 04.08 Table 10.86
56 CC_CAUSE_UNASSIGNED_NUMBER,
57 CC_CAUSE_NO_ROUTE_TO_DEST,
58 CC_CAUSE_CHANNEL_UNACCEPTABLE,
59 CC_CAUSE_OPERATOR_DETERMINED_BARRING,
60 CC_CAUSE_NORMAL_CALL_CLEARING,
62 CC_CAUSE_NO_USER_RESPONDING,
63 CC_CAUSE_USER_ALERTING_NO_ANSWER,
64 CC_CAUSE_CALL_REJECTED,
65 CC_CAUSE_NUMBER_CHANGED,
66 CC_CAUSE_NON_SELECTED_USER_CLEARING,
67 CC_CAUSE_DESTINATION_OUT_OF_ORDER,
68 CC_CAUSE_INVALID_NUMBER_FORMAT,
69 CC_CAUSE_FACILITY_REJECTED,
70 CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY,
71 CC_CAUSE_NORMAL_UNSPECIFIED,
72 CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE,
73 CC_CAUSE_NETWORK_OUT_OF_ORDER,
74 CC_CAUSE_TEMPORARY_FAILURE,
75 CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION,
76 CC_CAUSE_ACCESS_INFORMATION_DISCARDED,
77 CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE,
78 CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED,
79 CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE,
80 CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED,
81 CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG,
82 CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED,
83 CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE,
84 CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE,
85 CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED,
86 CC_CAUSE_ACM_GEQ_ACMMAX,
87 CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED,
88 CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE,
89 CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED,
90 CC_CAUSE_INVALID_TRANSACTION_ID_VALUE,
91 CC_CAUSE_USER_NOT_MEMBER_OF_CUG,
92 CC_CAUSE_INCOMPATIBLE_DESTINATION,
93 CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION,
94 CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
95 CC_CAUSE_INVALID_MANDATORY_INFORMATION,
96 CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
97 CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE,
98 CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED,
99 CC_CAUSE_CONDITIONAL_IE_ERROR,
100 CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,
101 CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY,
102 CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
103 CC_CAUSE_INTERWORKING_UNSPECIFIED,
107 REJECT_CAUSE_IMSI_UNKNOWN_IN_HLR,
108 REJECT_CAUSE_ILLEGAL_MS,
109 REJECT_CAUSE_IMSI_UNKNOWN_IN_VLR,
110 REJECT_CAUSE_IMEI_NOT_ACCEPTED,
111 REJECT_CAUSE_ILLEGAL_ME,
112 REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED,
113 REJECT_CAUSE_GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,
114 REJECT_CAUSE_MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
115 REJECT_CAUSE_IMPLICITLY_DETACHED,
116 REJECT_CAUSE_PLMN_NOT_ALLOWED,
117 REJECT_CAUSE_LA_NOT_ALLOWED,
118 REJECT_CAUSE_NATIONAL_ROAMING_NOT_ALLOWED,
119 REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
120 REJECT_CAUSE_NO_SUITABLE_CELLS_IN_LA,
121 REJECT_CAUSE_MSC_TEMPORARILY_NOT_REACHABLE,
122 REJECT_CAUSE_NETWORK_FAILURE,
123 REJECT_CAUSE_MAC_FAILURE,
124 REJECT_CAUSE_SYNCH_FAILURE,
125 REJECT_CAUSE_CONGESTTION,
126 REJECT_CAUSE_GSM_AUTH_UNACCEPTED,
127 REJECT_CAUSE_SERVICE_OPTION_NOT_SUPPORTED,
128 REJECT_CAUSE_REQ_SERV_OPT_NOT_SUBSCRIBED,
129 REJECT_CAUSE_SERVICE_OPT__OUT_OF_ORDER,
130 REJECT_CAUSE_CALL_CANNOT_BE_IDENTIFIED,
131 REJECT_CAUSE_NO_PDP_CONTEXT_ACTIVATED,
132 REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MIN_VALUE,
133 REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MAX_VALUE,
134 REJECT_CAUSE_SEMANTICALLY_INCORRECT_MSG,
135 REJECT_CAUSE_INVALID_MANDATORY_INFO,
136 REJECT_CAUSE_MESSAGE_TYPE_NON_EXISTANT,
137 REJECT_CAUSE_MESSAGE_TYPE_NOT_COMP_PRT_ST,
138 REJECT_CAUSE_IE_NON_EXISTANT,
139 REJECT_CAUSE_MSG_NOT_COMPATIBLE_PROTOCOL_STATE,
142 // Connection Management establishment rejection cause
143 REJECT_CAUSE_REJ_UNSPECIFIED,
146 REJECT_CAUSE_AS_REJ_RR_REL_IND,
147 REJECT_CAUSE_AS_REJ_RR_RANDOM_ACCESS_FAILURE,
148 REJECT_CAUSE_AS_REJ_RRC_REL_IND,
149 REJECT_CAUSE_AS_REJ_RRC_CLOSE_SESSION_IND,
150 REJECT_CAUSE_AS_REJ_RRC_OPEN_SESSION_FAILURE,
151 REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL,
152 REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL_REDIAL_NOT_ALLOWED,
153 REJECT_CAUSE_AS_REJ_LOW_LEVEL_IMMED_RETRY,
156 REJECT_CAUSE_MM_REJ_INVALID_SIM,
157 REJECT_CAUSE_MM_REJ_NO_SERVICE,
158 REJECT_CAUSE_MM_REJ_TIMER_T3230_EXP,
159 REJECT_CAUSE_MM_REJ_NO_CELL_AVAILABLE,
160 REJECT_CAUSE_MM_REJ_WRONG_STATE,
161 REJECT_CAUSE_MM_REJ_ACCESS_CLASS_BLOCKED,
162 // Definitions for release ind causes between MM and CNM
163 REJECT_CAUSE_ABORT_MSG_RECEIVED,
164 REJECT_CAUSE_OTHER_CAUSE,
167 REJECT_CAUSE_CNM_REJ_TIMER_T303_EXP,
168 REJECT_CAUSE_CNM_REJ_NO_RESOURCES,
169 REJECT_CAUSE_CNM_MM_REL_PENDING,
170 REJECT_CAUSE_CNM_INVALID_USER_DATA,
171 CALL_END_CAUSE_MAX = 255
172 } call_end_cause_e_type;
176 struct call_CLCC_info {
178 enum tcore_call_direction direction;
179 enum tcore_call_status status;
180 enum tcore_call_type type;
192 } call_end_cause_info;
194 /**************************************************************************
195 * Local Function Prototypes
196 **************************************************************************/
197 /************************* REQUESTS ***************************/
198 static void _call_status_idle(TcorePlugin *p, CallObject *co);
199 static void _call_status_active(TcorePlugin *p, CallObject *co);
200 static void _call_status_dialing(TcorePlugin *p, CallObject *co);
201 static void _call_status_alert(TcorePlugin *p, CallObject *co);
202 static void _call_status_incoming(TcorePlugin *p, CallObject *co);
203 static void _call_status_waiting(TcorePlugin *p, CallObject *co);
204 static TReturn _call_list_get(CoreObject *o, gboolean *event_flag);
205 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur);
207 /************************* CONFIRMATION ***************************/
208 static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
209 static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data);
210 static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data);
211 static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data);
212 static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data);
214 static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type);
215 static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type);
216 static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data);
217 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data);
219 /************************* RESPONSES ***************************/
220 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);
222 /************************* NOTIIFICATIONS ***************************/
223 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data);
224 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data);
225 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data);
226 static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data);
227 static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data);
230 /**************************************************************************
231 * Local Utility Function Prototypes
232 **************************************************************************/
233 static gboolean _call_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
234 static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status);
235 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call);
237 /**************************************************************************
238 * Local Function Definitions
239 **************************************************************************/
241 const call_end_cause_info call_end_cause_table[] = // call end cause table to convert Netwotk cause to TAPI cause
243 { 1, CC_CAUSE_UNASSIGNED_NUMBER}, { 3, CC_CAUSE_NO_ROUTE_TO_DEST},
244 { 6, CC_CAUSE_CHANNEL_UNACCEPTABLE}, { 8, CC_CAUSE_OPERATOR_DETERMINED_BARRING},
245 { 16, CC_CAUSE_NORMAL_CALL_CLEARING}, { 17, CC_CAUSE_USER_BUSY},
246 { 18, CC_CAUSE_NO_USER_RESPONDING}, { 19, CC_CAUSE_USER_ALERTING_NO_ANSWER},
247 { 21, CC_CAUSE_CALL_REJECTED}, { 22, CC_CAUSE_NUMBER_CHANGED},
248 { 26, CC_CAUSE_NON_SELECTED_USER_CLEARING}, { 27, CC_CAUSE_DESTINATION_OUT_OF_ORDER},
249 { 28, CC_CAUSE_INVALID_NUMBER_FORMAT}, { 29, CC_CAUSE_FACILITY_REJECTED},
250 { 30, CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY}, { 31, CC_CAUSE_NORMAL_UNSPECIFIED},
251 { 34, CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE}, { 38, CC_CAUSE_NETWORK_OUT_OF_ORDER},
252 { 41, CC_CAUSE_TEMPORARY_FAILURE}, { 42, CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION},
253 { 43, CC_CAUSE_ACCESS_INFORMATION_DISCARDED}, { 44, CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE},
254 { 47, CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED}, { 49, CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE},
255 { 50, CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED}, { 55, CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG},
256 { 57, CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED}, { 58, CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE},
257 { 63, CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE}, { 65, CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED},
258 { 68, CC_CAUSE_ACM_GEQ_ACMMAX}, { 69, CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED},
259 { 70, CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE}, { 79, CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED},
260 { 81, CC_CAUSE_INVALID_TRANSACTION_ID_VALUE}, { 87, CC_CAUSE_USER_NOT_MEMBER_OF_CUG},
261 { 88, CC_CAUSE_INCOMPATIBLE_DESTINATION}, { 91, CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION},
262 { 95, CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE}, { 96, CC_CAUSE_INVALID_MANDATORY_INFORMATION},
263 { 97, CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT}, { 98, CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE},
264 { 99, CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED}, { 100, CC_CAUSE_CONDITIONAL_IE_ERROR},
265 { 101, CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE}, { 102, CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY},
266 { 111, CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED}, {127, CC_CAUSE_INTERWORKING_UNSPECIFIED},
269 static enum tcore_call_cli_mode _get_clir_status(char *num)
271 enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
274 if (!strncmp(num, "*31#", 4)) {
275 dbg("CLI mode restricted");
276 return TCORE_CALL_CLI_MODE_RESTRICT;
279 if (!strncmp(num, "#31#", 4)) {
280 dbg("CLI mode allowed");
281 return TCORE_CALL_CLI_MODE_PRESENT;
288 static enum tcore_call_status _call_status(unsigned int status)
294 return TCORE_CALL_STATUS_ACTIVE;
297 return TCORE_CALL_STATUS_HELD;
300 return TCORE_CALL_STATUS_DIALING;
303 return TCORE_CALL_STATUS_ALERT;
306 return TCORE_CALL_STATUS_INCOMING;
309 return TCORE_CALL_STATUS_WAITING;
311 case 6: // DISCONNECTED state // FALL THROUGH
313 return TCORE_CALL_STATUS_IDLE;
317 static gboolean _call_is_in_mpty(int mpty)
335 static enum tcore_call_type call_type(int type)
341 return TCORE_CALL_TYPE_VOICE;
344 return TCORE_CALL_TYPE_VIDEO;
350 return TCORE_CALL_TYPE_VOICE;
353 static int _compare_call_end_cause(int networkcause)
356 for (count = 0; count < sizeof(call_end_cause_table) / sizeof(call_end_cause_info); count++) {
357 if (call_end_cause_table[count].network_cause == networkcause)
358 return (call_end_cause_table[count].tapi_cause);
360 return CC_CAUSE_NORMAL_CALL_CLEARING;
364 static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data)
373 static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)
375 GSList *tokens = NULL;
376 GSList *lines = NULL;
377 const char *line = NULL;
383 lines = (GSList *) data;
384 if (1 != g_slist_length(lines)) {
385 err("Unsolicited message, BUT multiple lines present");
389 line = (char *) (lines->data);
390 tokens = tcore_at_tok_new(line);
392 stat = g_slist_nth_data(tokens, 1);
394 dbg("Stat is missing from %XCALLSTAT indiaction");
399 case STATUS_INCOMING:
400 dbg("calling on_notification_call_incoming");
401 on_notification_call_incoming(o, line, user_data);
405 dbg("calling on_notification_call_waiting");
406 on_notification_call_waiting(o, line, user_data);
409 case STATUS_CONNECTED: /*igonre Connected state. */
410 dbg("Connected state");
414 dbg("calling on_notification_call_status");
415 on_notification_call_status(o, line, user_data);
421 tcore_at_tok_free(tokens);
428 static gboolean _call_request_message(TcorePending *pending,
434 TcoreHal *hal = NULL;
438 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
441 tcore_pending_set_response_callback(pending, on_resp, user_data);
443 tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
446 tcore_pending_link_user_request(pending, ur);
448 err("User Request is NULL, is this internal request??");
452 hal = tcore_object_get_hal(o);
453 // Send request to HAL
454 ret = tcore_hal_send_request(hal, pending);
455 if (TCORE_RETURN_SUCCESS != ret) {
456 err("Request send failed");
464 static void _call_status_idle(TcorePlugin *p, CallObject *co)
466 CoreObject *core_obj = NULL;
467 char *cmd_str = NULL;
468 TcorePending *pending = NULL;
469 TcoreATRequest *req = NULL;
470 gboolean ret = FALSE;
474 core_obj = tcore_plugin_ref_core_object(p, "call");
475 dbg("Call ID [%d], Call Status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));
477 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_IDLE) {
478 // get call end cause.
479 cmd_str = g_strdup_printf("%s", "AT+XCEER");
480 dbg("Request command string: %s", cmd_str);
482 // Create new Pending request
483 pending = tcore_pending_new(core_obj, 0);
485 // Create new AT-Command request
486 req = tcore_at_request_new(cmd_str, "+XCEER", TCORE_AT_SINGLELINE);
487 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
488 // Free command string
491 // Set request data (AT command) to Pending request
492 tcore_pending_set_request_data(pending, 0, req);
494 ur = tcore_user_request_new(NULL, NULL);
496 ret = _call_request_message(pending, core_obj, ur, _on_confirmation_call_end_cause, co);
499 err("Failed to send AT-Command request");
503 err("Call object was not free");
504 tcore_call_object_free(core_obj, co);
510 static void _call_status_dialing(TcorePlugin *p, CallObject *co)
512 struct tnoti_call_status_dialing data;
515 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_DIALING) {
516 data.type = tcore_call_object_get_type(co);
517 dbg("data.type : [%d]", data.type);
519 data.id = tcore_call_object_get_id(co);
520 dbg("data.id : [%d]", data.id);
523 tcore_call_object_set_status(co, TCORE_CALL_STATUS_DIALING);
525 // Send notification to TAPI
526 tcore_server_send_notification(tcore_plugin_ref_server(p),
527 tcore_plugin_ref_core_object(p, "call"),
528 TNOTI_CALL_STATUS_DIALING,
529 sizeof(struct tnoti_call_status_dialing),
537 static void _call_status_alert(TcorePlugin *p, CallObject *co)
539 struct tnoti_call_status_alert data;
542 // Alerting has just 1 data 'CALL ID'
543 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ALERT) {
544 data.type = tcore_call_object_get_type(co);
545 dbg("data.type : [%d]", data.type);
547 data.id = tcore_call_object_get_id(co);
548 dbg("data.id : [%d]", data.id);
551 tcore_call_object_set_status(co, TCORE_CALL_STATUS_ALERT);
553 // Send notification to TAPI
554 tcore_server_send_notification(tcore_plugin_ref_server(p),
555 tcore_plugin_ref_core_object(p, "call"),
556 TNOTI_CALL_STATUS_ALERT,
557 sizeof(struct tnoti_call_status_alert),
565 static void _call_status_active(TcorePlugin *p, CallObject *co)
567 struct tnoti_call_status_active data;
570 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ACTIVE) {
571 data.type = tcore_call_object_get_type(co);
572 dbg("data.type : [%d]", data.type);
574 data.id = tcore_call_object_get_id(co);
575 dbg("data.id : [%d]", data.id);
578 tcore_call_object_set_status(co, TCORE_CALL_STATUS_ACTIVE);
580 // Send notification to TAPI
581 tcore_server_send_notification(tcore_plugin_ref_server(p),
582 tcore_plugin_ref_core_object(p, "call"),
583 TNOTI_CALL_STATUS_ACTIVE,
584 sizeof(struct tnoti_call_status_active),
592 static void _call_status_held(TcorePlugin *p, CallObject *co)
594 struct tnoti_call_status_held data;
597 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_HELD) {
598 data.type = tcore_call_object_get_type(co);
599 dbg("data.type : [%d]", data.type);
601 data.id = tcore_call_object_get_id(co);
602 dbg("data.id : [%d]", data.id);
605 tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
607 // Send notification to TAPI
608 tcore_server_send_notification(tcore_plugin_ref_server(p),
609 tcore_plugin_ref_core_object(p, "call"),
610 TNOTI_CALL_STATUS_HELD,
611 sizeof(struct tnoti_call_status_held),
619 static void _call_status_incoming(TcorePlugin *p, CallObject *co)
621 struct tnoti_call_status_incoming data;
624 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_INCOMING) {
625 tcore_call_object_set_status(co, TCORE_CALL_STATUS_INCOMING);
627 data.type = tcore_call_object_get_type(co);
628 dbg("data.type : [%d]", data.type);
630 data.id = tcore_call_object_get_id(co);
631 dbg("data.id : [%d]", data.id);
633 data.cli.mode = tcore_call_object_get_cli_mode(co);
634 dbg("data.cli.mode : [%d]", data.cli.mode);
636 tcore_call_object_get_number(co, data.cli.number);
637 dbg("data.cli.number : [%s]", data.cli.number);
639 data.cna.mode = tcore_call_object_get_cna_mode(co);
640 dbg("data.cna.mode : [%d]", data.cna.mode);
642 tcore_call_object_get_name(co, data.cna.name);
643 dbg("data.cna.name : [%s]", data.cna.name);
645 data.forward = FALSE; // this is tmp code
647 data.active_line = tcore_call_object_get_active_line(co);
648 dbg("data.active_line : [%d]", data.active_line);
650 // Send notification to TAPI
651 tcore_server_send_notification(tcore_plugin_ref_server(p),
652 tcore_plugin_ref_core_object(p, "call"),
653 TNOTI_CALL_STATUS_INCOMING,
654 sizeof(struct tnoti_call_status_incoming),
662 static void _call_status_waiting(TcorePlugin *p, CallObject *co)
665 _call_status_incoming(p, co);
671 static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status)
675 dbg("Call Status is %d", status);
677 case TCORE_CALL_STATUS_IDLE:
678 _call_status_idle(p, co);
681 case TCORE_CALL_STATUS_ACTIVE:
682 _call_status_active(p, co);
685 case TCORE_CALL_STATUS_HELD:
686 _call_status_held(p, co);
689 case TCORE_CALL_STATUS_DIALING:
690 _call_status_dialing(p, co);
693 case TCORE_CALL_STATUS_ALERT:
694 _call_status_alert(p, co);
697 case TCORE_CALL_STATUS_INCOMING:
698 _call_status_incoming(p, co);
701 case TCORE_CALL_STATUS_WAITING:
702 _call_status_waiting(p, co);
710 static TReturn _call_list_get(CoreObject *o, gboolean *event_flag)
712 UserRequest *ur = NULL;
713 TcorePending *pending = NULL;
714 char *cmd_str = NULL;
715 TcoreATRequest *req = NULL;
716 gboolean ret = FALSE;
720 err("Core Object is NULL");
721 return TCORE_RETURN_FAILURE;
724 // Create new User Request
725 ur = tcore_user_request_new(NULL, NULL);
728 cmd_str = g_strdup("AT+CLCC");
730 // Create new Pending Request
731 pending = tcore_pending_new(o, 0);
732 req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);
736 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
738 tcore_pending_set_request_data(pending, 0, req);
740 ret = _call_request_message(pending, o, ur, on_response_call_list_get, event_flag);
742 err("AT request (%s) sending failed", req->cmd);
743 return TCORE_RETURN_FAILURE;
746 dbg("AT request sent success");
747 return TCORE_RETURN_SUCCESS;
751 static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data)
755 if (result == FALSE) { // Fail
765 static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
767 UserRequest *ur = NULL;
768 GSList *tokens = NULL;
769 const char *line = NULL;
770 const TcoreATResponse *response = data;
771 struct tresp_call_dial resp;
775 ur = tcore_pending_ref_user_request(p);
777 if (response->success > 0) {
779 resp.err = TCORE_RETURN_SUCCESS;
781 dbg("RESPONSE NOT OK");
783 line = (const char *) response->final_response;
784 tokens = tcore_at_tok_new(line);
786 if (g_slist_length(tokens) < 1) {
787 err("Unspecified error cause OR string corrupted");
788 resp.err = TCORE_RETURN_3GPP_ERROR;
790 error = atoi(g_slist_nth_data(tokens, 0));
792 // TODO: CMEE error mapping is required.
793 resp.err = TCORE_RETURN_3GPP_ERROR;
797 tcore_at_tok_free(tokens);
800 // Send Response to TAPI
801 tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
803 err("User Request is NULL");
810 static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)
812 UserRequest *ur = NULL;
813 GSList *tokens = NULL;
814 const char *line = NULL;
815 const TcoreATResponse *response = data;
816 struct tresp_call_answer resp;
820 ur = tcore_pending_ref_user_request(p);
822 if (response->success > 0) {
824 resp.err = TCORE_RETURN_SUCCESS;
826 dbg("RESPONSE NOT OK");
828 line = (const char *) response->final_response;
829 tokens = tcore_at_tok_new(line);
831 if (g_slist_length(tokens) < 1) {
832 err("Unspecified error cause OR string corrupted");
833 resp.err = TCORE_RETURN_3GPP_ERROR;
835 error = atoi(g_slist_nth_data(tokens, 0));
837 // TODO: CMEE error mapping is required.
838 resp.err = TCORE_RETURN_3GPP_ERROR;
842 tcore_at_tok_free(tokens);
845 resp.id = tcore_call_object_get_id((CallObject *) user_data);
847 // Send Response to TAPI
848 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
850 err("User Request is NULL");
858 static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)
860 UserRequest *ur = NULL;
861 GSList *tokens = NULL;
862 const char *line = NULL;
863 const TcoreATResponse *response = data;
864 struct tresp_call_answer resp;
869 ur = tcore_pending_ref_user_request(p);
871 if (response->success > 0) {
873 resp.err = TCORE_RETURN_SUCCESS;
875 dbg("RESPONSE NOT OK");
876 line = (const char *) response->final_response;
877 tokens = tcore_at_tok_new(line);
879 if (g_slist_length(tokens) < 1) {
880 err("Unspecified error cause OR string corrupted");
881 resp.err = TCORE_RETURN_3GPP_ERROR;
883 error = atoi(g_slist_nth_data(tokens, 0));
884 // TODO: CMEE error mapping is required.
885 resp.err = TCORE_RETURN_3GPP_ERROR;
889 tcore_at_tok_free(tokens);
892 resp.id = tcore_call_object_get_id((CallObject *) user_data);
894 // Send Response to TAPI
895 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
897 err("User Request is NULL");
904 static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)
906 UserRequest *ur = NULL;
907 GSList *tokens = NULL;
908 const char *line = NULL;
909 const TcoreATResponse *response = data;
910 struct tresp_call_answer resp;
914 ur = tcore_pending_ref_user_request(p);
916 if (response->success > 0) {
918 resp.err = TCORE_RETURN_SUCCESS;
920 dbg("RESPONSE NOT OK");
921 line = (const char *) response->final_response;
922 tokens = tcore_at_tok_new(line);
924 if (g_slist_length(tokens) < 1) {
925 err("Unspecified error cause OR string corrupted");
926 resp.err = TCORE_RETURN_3GPP_ERROR;
928 error = atoi(g_slist_nth_data(tokens, 0));
929 // TODO: CMEE error mapping is required.
930 resp.err = TCORE_RETURN_3GPP_ERROR;
934 tcore_at_tok_free(tokens);
936 resp.id = tcore_call_object_get_id((CallObject *) user_data);
938 // Send Response to TAPI
939 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
941 dbg("User Request is NULL");
948 static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)
950 CoreObject *o = NULL;
951 UserRequest *ur = NULL;
952 GSList *tokens = NULL;
953 const char *line = NULL;
954 const TcoreATResponse *response = data;
955 struct tresp_call_answer resp;
960 o = tcore_pending_ref_core_object(p);
961 ur = tcore_pending_ref_user_request(p);
962 resp.id = tcore_call_object_get_id((CallObject *) user_data);
965 if (response->success > 0) {
967 resp.err = TCORE_RETURN_SUCCESS;
969 err("RESPONSE NOT OK");
970 line = (const char *) response->final_response;
971 tokens = tcore_at_tok_new(line);
973 if (g_slist_length(tokens) < 1) {
974 err("Unspecified error cause OR string corrupted");
975 resp.err = TCORE_RETURN_3GPP_ERROR;
977 error = atoi(g_slist_nth_data(tokens, 0));
979 // TODO: CMEE error mapping is required.
980 resp.err = TCORE_RETURN_3GPP_ERROR;
984 tcore_at_tok_free(tokens);
987 // Send response to TAPI
988 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
991 CallObject *co = NULL;
994 list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
996 err("Can't find active Call");
1000 co = (CallObject *) list->data;
1002 err("Can't get active Call object");
1007 tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
1008 dbg("Call status is set to HELD");
1011 err("User Request is NULL");
1018 static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1020 UserRequest *ur = NULL;
1021 struct tresp_call_end resp;
1022 GSList *tokens = NULL;
1023 const char *line = NULL;
1025 const TcoreATResponse *response = data;
1028 ur = tcore_pending_ref_user_request(p);
1030 if (response->success > 0) {
1032 resp.err = TCORE_RETURN_SUCCESS;
1034 err("RESPONSE NOT OK");
1036 line = (const char *) response->final_response;
1037 tokens = tcore_at_tok_new(line);
1039 if (g_slist_length(tokens) < 1) {
1040 err("Unspecified error cause OR string corrupted");
1041 resp.err = TCORE_RETURN_3GPP_ERROR;
1043 error = atoi(g_slist_nth_data(tokens, 0));
1045 // TODO: CMEE error mapping is required.
1046 resp.err = TCORE_RETURN_3GPP_ERROR;
1048 tcore_at_tok_free(tokens);
1052 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1053 dbg("resp.type = %d resp.id= %d", resp.type, resp.id);
1055 // Send reponse to TAPI
1056 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
1058 err("User Request is NULL");
1066 static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)
1068 // skip response handling - actual result will be handled in on_confirmation_call_release_all
1069 const TcoreATResponse *response = data;
1072 if (response->success > 0) {
1075 err("RESPONSE NOT OK");
1083 static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)
1086 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);
1092 static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)
1095 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);
1100 static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)
1103 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);
1108 static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)
1111 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);
1116 static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1118 UserRequest *ur = NULL;
1119 GSList *tokens = NULL;
1120 const char *line = NULL;
1121 const TcoreATResponse *response = NULL;
1125 ur = tcore_pending_ref_user_request(p);
1126 response = (TcoreATResponse *) data;
1127 if (response->success > 0) {
1129 error = TCORE_RETURN_SUCCESS;
1131 err("RESPONSE NOT OK");
1133 line = (const char *) response->final_response;
1134 tokens = tcore_at_tok_new(line);
1136 if (g_slist_length(tokens) < 1) {
1137 err("Unspecified error cause OR string corrupted");
1138 error = TCORE_RETURN_3GPP_ERROR;
1140 error = atoi(g_slist_nth_data(tokens, 0));
1142 // TODO: CMEE error mapping is required.
1143 error = TCORE_RETURN_3GPP_ERROR;
1147 tcore_at_tok_free(tokens);
1150 dbg("Response Call type -%d", type);
1152 case TRESP_CALL_HOLD:
1154 struct tresp_call_hold resp;
1157 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1158 dbg("call hold response");
1159 // Send reponse to TAPI
1160 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1164 case TRESP_CALL_ACTIVE:
1166 struct tresp_call_active resp;
1169 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1170 dbg("call active response");
1171 // Send reponse to TAPI
1172 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1176 case TRESP_CALL_JOIN:
1178 struct tresp_call_join resp;
1181 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1182 dbg("call join response");
1184 // Send reponse to TAPI
1185 tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
1189 case TRESP_CALL_SPLIT:
1191 struct tresp_call_split resp;
1194 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1195 dbg("call split response");
1196 // Send reponse to TAPI
1197 tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
1201 case TRESP_CALL_DEFLECT:
1203 struct tresp_call_deflect resp;
1206 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1207 dbg("call deflect response");
1208 // Send reponse to TAPI
1209 tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
1214 case TRESP_CALL_TRANSFER:
1216 struct tresp_call_transfer resp;
1219 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1220 dbg("call transfer response");
1221 // Send reponse to TAPI
1222 tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
1226 case TRESP_CALL_SEND_DTMF:
1228 struct tresp_call_dtmf resp;
1231 dbg("call dtmf response");
1232 // Send reponse to TAPI
1233 tcore_user_request_send_response(ur, TRESP_CALL_SEND_DTMF, sizeof(struct tresp_call_dtmf), &resp);
1239 dbg("type not supported");
1244 if ((type == TRESP_CALL_HOLD) || (type == TRESP_CALL_ACTIVE) || (type == TRESP_CALL_JOIN)
1245 || (type == TRESP_CALL_SPLIT)) {
1247 CoreObject *core_obj = NULL;
1248 gboolean *eflag = g_new0(gboolean, 1);
1250 core_obj = tcore_pending_ref_core_object(p);
1253 dbg("Calling _call_list_get");
1254 _call_list_get(core_obj, eflag);
1262 static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)
1265 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);
1270 static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)
1273 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);
1278 static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)
1281 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);
1286 static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)
1289 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);
1294 static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)
1297 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);
1302 static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)
1305 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);
1310 static void on_confirmation_call_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
1313 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SEND_DTMF);
1318 static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data)
1320 GSList *tokens = NULL;
1321 const char *line = NULL;
1322 const TcoreATResponse *response = data;
1327 if (response->success > 0) {
1329 error = TCORE_RETURN_SUCCESS;
1331 err("RESPONSE NOT OK");
1332 line = (const char *) response->final_response;
1333 tokens = tcore_at_tok_new(line);
1334 if (g_slist_length(tokens) < 1) {
1335 err("err cause not specified or string corrupted");
1336 error = TCORE_RETURN_3GPP_ERROR;
1338 error = atoi(g_slist_nth_data(tokens, 0));
1339 // TODO: CMEE error mapping is required.
1343 tcore_at_tok_free(tokens);
1346 dbg("Set dtmf tone duration response - %d", error);
1350 static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
1352 CoreObject *core_obj = NULL;
1353 UserRequest *ur = NULL;
1354 const TcoreATResponse *response = data;
1355 struct tresp_call_swap resp;
1356 GSList *tokens = NULL;
1357 const char *line = NULL;
1360 core_obj = tcore_pending_ref_core_object(p);
1361 ur = tcore_pending_ref_user_request(p);
1364 if (response->success > 0) {
1366 resp.err = TCORE_RETURN_SUCCESS;
1368 err("RESPONSE NOT OK");
1369 line = (const char *) response->final_response;
1370 tokens = tcore_at_tok_new(line);
1371 if (g_slist_length(tokens) < 1) {
1372 err("err cause not specified or string corrupted");
1373 resp.err = TCORE_RETURN_3GPP_ERROR;
1375 resp.err = atoi(g_slist_nth_data(tokens, 0));
1377 // TODO: CMEE error mapping is required.
1378 resp.err = TCORE_RETURN_3GPP_ERROR;
1382 tcore_at_tok_free(tokens);
1385 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1386 dbg("resp.id = %d", resp.id);
1388 // Send response to TAPI
1389 tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
1392 GSList *active = NULL;
1393 GSList *held = NULL;
1394 CallObject *co = NULL;
1395 gboolean *eflag = NULL;
1397 held = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_HELD);
1399 err("Can't find held Call");
1403 active = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_ACTIVE);
1405 dbg("Can't find active Call");
1410 co = (CallObject *) held->data;
1412 err("Can't get held Call object");
1416 resp.id = tcore_call_object_get_id(co);
1418 // Send response to TAPI
1419 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1421 held = g_slist_next(held);
1425 co = (CallObject *) active->data;
1427 err("[ error ] can't get active call object");
1431 resp.id = tcore_call_object_get_id(co);
1433 // Send response to TAPI
1434 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1435 active = g_slist_next(active);
1438 eflag = g_new0(gboolean, 1);
1441 dbg("calling _call_list_get");
1442 _call_list_get(core_obj, eflag);
1445 err("User Request is NULL");
1452 static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1454 UserRequest *ur = NULL;
1455 GSList *tokens = NULL;
1456 const char *line = NULL;
1457 const TcoreATResponse *response = data;
1458 char *resp_str = NULL;
1459 struct tresp_call_sound_set_path resp;
1463 ur = tcore_pending_ref_user_request(p);
1465 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1467 err("Input data is NULL");
1471 if (response->success > 0) {
1474 line = (const char *) (((GSList *) response->lines)->data);
1475 tokens = tcore_at_tok_new(line);
1477 resp_str = g_slist_nth_data(tokens, 0);
1478 if (!g_slist_nth_data(tokens, 0)) {
1479 err("group_id is missing");
1480 resp.err = TCORE_RETURN_3GPP_ERROR;
1484 if (!g_slist_nth_data(tokens, 1)) {
1485 err(" function_id is missing");
1486 resp.err = TCORE_RETURN_3GPP_ERROR;
1490 resp_str = g_slist_nth_data(tokens, 2);
1493 error = atoi(resp_str);
1495 dbg("Response is Success");
1496 resp.err = TCORE_RETURN_SUCCESS;
1498 resp.err = TCORE_RETURN_3GPP_ERROR;
1503 tcore_at_tok_free(tokens);
1505 dbg("RESPONSE NOT OK");
1507 line = (const char *) response->final_response;
1508 tokens = tcore_at_tok_new(line);
1510 if (g_slist_length(tokens) < 1) {
1511 err("err cause not specified or string corrupted");
1512 resp.err = TCORE_RETURN_3GPP_ERROR;
1514 error = atoi(g_slist_nth_data(tokens, 0));
1516 // TODO: CMEE error mapping is required.
1517 resp.err = TCORE_RETURN_3GPP_ERROR;
1521 tcore_at_tok_free(tokens);
1525 if (resp.err != TCORE_RETURN_SUCCESS) { // Send only failed notification . success notification send when destination device is set.
1526 // Send notification to TAPI
1527 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1528 setsoundpath = TRUE;
1531 err("User Request is NULL");
1538 static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1540 UserRequest *ur = NULL;
1541 GSList *tokens = NULL;
1542 const char *line = NULL;
1543 char *resp_str = NULL;
1544 struct tresp_call_sound_set_path resp;
1545 const TcoreATResponse *response = data;
1550 ur = tcore_pending_ref_user_request(p);
1551 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1554 err("Input data is NULL");
1559 if (response->success > 0) {
1562 line = (const char *) (((GSList *) response->lines)->data);
1563 tokens = tcore_at_tok_new(line);
1565 resp_str = g_slist_nth_data(tokens, 0);
1566 if (!g_slist_nth_data(tokens, 0)) {
1567 dbg("group_id is missing");
1568 resp.err = TCORE_RETURN_3GPP_ERROR;
1572 if (!g_slist_nth_data(tokens, 1)) {
1573 dbg("function_id is missing");
1574 resp.err = TCORE_RETURN_3GPP_ERROR;
1578 resp_str = g_slist_nth_data(tokens, 2);
1580 error = atoi(resp_str);
1582 dbg("Response is Success");
1583 resp.err = TCORE_RETURN_SUCCESS;
1585 resp.err = TCORE_RETURN_3GPP_ERROR;
1591 tcore_at_tok_free(tokens);
1593 dbg("RESPONSE NOT OK");
1595 line = (const char *) response->final_response;
1596 tokens = tcore_at_tok_new(line);
1598 if (g_slist_length(tokens) < 1) {
1599 err("err cause not specified or string corrupted");
1600 resp.err = TCORE_RETURN_3GPP_ERROR;
1602 error = atoi(g_slist_nth_data(tokens, 0));
1603 // TODO: CMEE error mapping is required.
1604 resp.err = TCORE_RETURN_3GPP_ERROR;
1608 tcore_at_tok_free(tokens);
1611 if (setsoundpath == TRUE) {
1612 setsoundpath = FALSE;
1614 // Send response to TAPI
1615 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1618 dbg("User Request is NULL");
1625 static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1627 UserRequest *ur = NULL;
1628 GSList *tokens = NULL;
1629 const char *line = NULL;
1630 const TcoreATResponse *response = data;
1631 char *resp_str = NULL;
1632 struct tresp_call_sound_set_volume_level resp;
1635 ur = tcore_pending_ref_user_request(p);
1637 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1639 err("Input data is NULL");
1643 if (response->success > 0) {
1646 line = (const char *) (((GSList *) response->lines)->data);
1647 tokens = tcore_at_tok_new(line);
1649 resp_str = g_slist_nth_data(tokens, 0);
1650 if (!g_slist_nth_data(tokens, 0)) {
1651 err("group_id is missing");
1652 resp.err = TCORE_RETURN_3GPP_ERROR;
1656 if (!g_slist_nth_data(tokens, 1)) {
1657 err("function_id is missing");
1658 resp.err = TCORE_RETURN_3GPP_ERROR;
1662 resp_str = g_slist_nth_data(tokens, 2);
1664 error = atoi(resp_str);
1667 dbg("Response is Success ");
1668 resp.err = TCORE_RETURN_SUCCESS;
1670 resp.err = TCORE_RETURN_3GPP_ERROR;
1676 tcore_at_tok_free(tokens);
1678 dbg("RESPONSE NOT OK");
1680 line = (const char *) response->final_response;
1681 tokens = tcore_at_tok_new(line);
1683 if (g_slist_length(tokens) < 1) {
1684 err("err cause not specified or string corrupted");
1685 resp.err = TCORE_RETURN_3GPP_ERROR;
1687 error = atoi(g_slist_nth_data(tokens, 0));
1689 // TODO: CMEE error mapping is required.
1690 resp.err = TCORE_RETURN_3GPP_ERROR;
1694 tcore_at_tok_free(tokens);
1698 if (resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.
1699 // Send reposne to TAPI
1700 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1704 err("User Request is NULL");
1712 static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1714 UserRequest *ur = NULL;
1715 GSList *tokens = NULL;
1716 const char *line = NULL;
1717 char *resp_str = NULL;
1718 const TcoreATResponse *response = data;
1719 struct tresp_call_sound_set_volume_level resp;
1724 ur = tcore_pending_ref_user_request(p);
1726 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1728 err("Input data is NULL");
1733 if (response->success > 0) {
1735 line = (const char *) (((GSList *) response->lines)->data);
1736 tokens = tcore_at_tok_new(line);
1737 resp_str = g_slist_nth_data(tokens, 0);
1739 if (!g_slist_nth_data(tokens, 0)) {
1740 err("group_id is missing");
1741 resp.err = TCORE_RETURN_3GPP_ERROR;
1745 if (!g_slist_nth_data(tokens, 1)) {
1746 err("function_id is missing");
1747 resp.err = TCORE_RETURN_3GPP_ERROR;
1751 resp_str = g_slist_nth_data(tokens, 2);
1754 error = atoi(resp_str);
1757 dbg("Response is Success");
1758 resp.err = TCORE_RETURN_SUCCESS;
1760 resp.err = TCORE_RETURN_3GPP_ERROR;
1766 tcore_at_tok_free(tokens);
1768 dbg("RESPONSE NOT OK");
1770 line = (const char *) response->final_response;
1771 tokens = tcore_at_tok_new(line);
1773 if (g_slist_length(tokens) < 1) {
1774 err("err cause not specified or string corrupted");
1775 resp.err = TCORE_RETURN_3GPP_ERROR;
1777 error = atoi(g_slist_nth_data(tokens, 0));
1779 // TODO: CMEE error mapping is required.
1780 resp.err = TCORE_RETURN_3GPP_ERROR;
1783 tcore_at_tok_free(tokens);
1786 if (soundvolume == TRUE) {
1787 soundvolume = FALSE;
1789 // Send reposne to TAPI
1790 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1793 err("User Request is NULL");
1801 static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
1803 UserRequest *ur = NULL;
1804 GSList *tokens = NULL;
1805 const char *line = NULL;
1806 char *resp_str = NULL;
1807 struct tresp_call_mute resp;
1808 const TcoreATResponse *response = data;
1813 ur = tcore_pending_ref_user_request(p);
1816 err("Input data is NULL");
1820 if (response->success > 0) {
1823 line = (const char *) (((GSList *) response->lines)->data);
1824 tokens = tcore_at_tok_new(line);
1825 resp_str = g_slist_nth_data(tokens, 0);
1827 if (!g_slist_nth_data(tokens, 0)) {
1828 err("group_id is missing");
1829 resp.err = TCORE_RETURN_3GPP_ERROR;
1833 if (!g_slist_nth_data(tokens, 1)) {
1834 err(" function_id is missing");
1835 resp.err = TCORE_RETURN_3GPP_ERROR;
1839 resp_str = g_slist_nth_data(tokens, 2);
1842 error = atoi(resp_str);
1844 dbg("Response is Success");
1845 resp.err = TCORE_RETURN_SUCCESS;
1847 resp.err = TCORE_RETURN_3GPP_ERROR;
1852 tcore_at_tok_free(tokens);
1854 dbg("RESPONSE NOT OK");
1856 line = (const char *) response->final_response;
1857 tokens = tcore_at_tok_new(line);
1859 if (g_slist_length(tokens) < 1) {
1860 err("err cause not specified or string corrupted");
1861 resp.err = TCORE_RETURN_3GPP_ERROR;
1863 error = atoi(g_slist_nth_data(tokens, 0));
1865 // TODO: CMEE error mapping is required.
1866 resp.err = TCORE_RETURN_3GPP_ERROR;
1870 tcore_at_tok_free(tokens);
1874 tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
1876 err("User Request is NULL");
1883 static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
1885 const TcoreATResponse *response = NULL;
1886 struct tresp_call_unmute resp;
1887 GSList *tokens = NULL;
1888 const char *line = NULL;
1889 UserRequest *ur = NULL;
1890 char *resp_str = NULL;
1895 response = (TcoreATResponse *) data;
1896 ur = tcore_pending_ref_user_request(p);
1899 err("Input data is NULL");
1903 if (response->success > 0) {
1906 line = (const char *) (((GSList *) response->lines)->data);
1907 tokens = tcore_at_tok_new(line);
1908 resp_str = g_slist_nth_data(tokens, 0);
1910 if (!g_slist_nth_data(tokens, 0)) {
1911 err("group_id is missing");
1912 resp.err = TCORE_RETURN_3GPP_ERROR;
1916 if (!g_slist_nth_data(tokens, 1)) {
1917 err(" function_id is missing");
1918 resp.err = TCORE_RETURN_3GPP_ERROR;
1922 resp_str = g_slist_nth_data(tokens, 2);
1925 error = atoi(resp_str);
1927 dbg("Response is Success");
1928 resp.err = TCORE_RETURN_SUCCESS;
1930 resp.err = TCORE_RETURN_3GPP_ERROR;
1935 tcore_at_tok_free(tokens);
1937 dbg("RESPONSE NOT OK");
1939 line = (const char *) response->final_response;
1940 tokens = tcore_at_tok_new(line);
1942 if (g_slist_length(tokens) < 1) {
1943 err("err cause not specified or string corrupted");
1944 resp.err = TCORE_RETURN_3GPP_ERROR;
1946 error = atoi(g_slist_nth_data(tokens, 0));
1948 // TODO: CMEE error mapping is required.
1949 resp.err = TCORE_RETURN_3GPP_ERROR;
1953 tcore_at_tok_free(tokens);
1957 tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
1959 err("User Request is NULL");
1967 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
1969 TcorePlugin *plugin = NULL;
1970 CoreObject *core_obj = NULL;
1971 CallObject *co = NULL;
1972 struct clcc_call_t *call_list = NULL;
1973 gboolean *event_flag = (gboolean *) user_data;
1974 const TcoreATResponse *response = data;
1975 GSList *resp_data = NULL;
1978 int cllc_info = 0, countCalls = 0, countValidCalls = 0;
1982 plugin = tcore_pending_ref_plugin(p);
1983 core_obj = tcore_pending_ref_core_object(p);
1985 if (response->success > 0) {
1987 if (response->lines) {
1988 resp_data = (GSList *) response->lines;
1989 countCalls = g_slist_length(resp_data);
1990 dbg("Total records : %d", countCalls);
1993 if (0 == countCalls) {
1994 err("Call count is zero");
1998 call_list = g_new0(struct clcc_call_t, countCalls);
2000 for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
2001 line = (char *) (resp_data->data);
2003 error = _callFromCLCCLine(line, call_list + countValidCalls);
2008 co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
2010 co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
2012 err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
2017 // Call set parameters
2018 tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
2019 tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
2020 tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
2021 tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
2022 tcore_call_object_set_active_line(co, 0);
2025 dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
2026 _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
2029 tcore_call_object_set_status(co, call_list[cllc_info].info.status);
2031 dbg("Call id : (%d)", call_list[cllc_info].info.id);
2032 dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
2033 dbg("Call type : (%d)", call_list[cllc_info].info.type);
2034 dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
2035 dbg("Call number : (%s)", call_list[cllc_info].number);
2036 dbg("Call status : (%d)", call_list[cllc_info].info.status);
2051 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
2053 TcorePlugin *plugin = NULL;
2054 CoreObject *core_obj = NULL;
2055 CallObject *co = (CallObject *) user_data;
2056 const TcoreATResponse *response = data;
2057 const char *line = NULL;
2058 struct tnoti_call_status_idle call_status;
2059 GSList *tokens = NULL;
2064 plugin = tcore_pending_ref_plugin(p);
2065 core_obj = tcore_pending_ref_core_object(p);
2067 if (response->success > 0) {
2069 line = (const char *) (((GSList *) response->lines)->data);
2070 tokens = tcore_at_tok_new(line);
2071 resp_str = g_slist_nth_data(tokens, 0);
2073 err("call end cause - report value missing");
2075 resp_str = g_slist_nth_data(tokens, 1);
2077 err("call end cause value missing");
2079 error = atoi(resp_str);
2080 dbg("call end cause - %d", error);
2081 call_status.cause = _compare_call_end_cause(error);
2082 dbg("TAPI call end cause - %d", call_status.cause);
2086 tcore_at_tok_free(tokens);
2088 err("RESPONSE NOT OK");
2089 line = (char *) response->final_response;
2090 tokens = tcore_at_tok_new(line);
2091 if (g_slist_length(tokens) < 1) {
2092 err("err cause not specified or string corrupted");
2094 err(" err cause value: %d", atoi(g_slist_nth_data(tokens, 0)));
2096 call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
2098 tcore_at_tok_free(tokens);
2101 call_status.type = tcore_call_object_get_type(co);
2102 dbg("data.type : [%d]", call_status.type);
2104 call_status.id = tcore_call_object_get_id(co);
2105 dbg("data.id : [%d]", call_status.id);
2108 tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
2110 // Send Notification to TAPI
2111 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
2113 TNOTI_CALL_STATUS_IDLE,
2114 sizeof(struct tnoti_call_status_idle),
2115 (void *) &call_status);
2118 tcore_call_object_free(core_obj, co);
2121 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
2123 // +CLCC: 1,0,2,0,0,"18005551212",145
2124 // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
2129 unsigned int num_type;
2130 GSList *tokens = NULL;
2134 tokens = tcore_at_tok_new(line);
2136 resp = g_slist_nth_data(tokens, 0);
2141 p_call->info.id = atoi(resp);
2142 dbg("id : [%d]\n", p_call->info.id);
2145 resp = g_slist_nth_data(tokens, 1);
2152 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
2154 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
2156 dbg("Direction : [ %d ]\n", p_call->info.direction);
2159 resp = g_slist_nth_data(tokens, 2);
2161 err("InValid Stat");
2165 dbg("Call state : %d", state);
2168 p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
2172 p_call->info.status = TCORE_CALL_STATUS_HELD;
2176 p_call->info.status = TCORE_CALL_STATUS_DIALING;
2180 p_call->info.status = TCORE_CALL_STATUS_ALERT;
2184 p_call->info.status = TCORE_CALL_STATUS_INCOMING;
2188 p_call->info.status = TCORE_CALL_STATUS_WAITING;
2191 dbg("Status : [%d]\n", p_call->info.status);
2194 resp = g_slist_nth_data(tokens, 3);
2196 err("InValid Mode");
2202 p_call->info.type = TCORE_CALL_TYPE_VOICE;
2206 p_call->info.type = TCORE_CALL_TYPE_VIDEO;
2209 default: // only Voice/VT call is supported in CS. treat other unknown calls as error
2210 dbg("invalid type : [%d]\n", mode);
2213 dbg("Call type : [%d]\n", p_call->info.type);
2216 resp = g_slist_nth_data(tokens, 4);
2218 err("InValid Mpty");
2222 p_call->info.mpty = atoi(resp);
2223 dbg("Mpty : [ %d ]\n", p_call->info.mpty);
2226 resp = g_slist_nth_data(tokens, 5);
2227 dbg("Incoming number - %s and its len - %d", resp, strlen(resp));
2229 // tolerate null here
2231 err("Number is NULL");
2234 // Strike off double quotes
2235 num = util_removeQuotes(resp);
2236 dbg("num after removing quotes - %s", num);
2238 p_call->info.num_len = strlen(resp);
2239 dbg("num_len : [0x%x]\n", p_call->info.num_len);
2242 resp = g_slist_nth_data(tokens, 6);
2244 dbg("InValid Num type");
2247 p_call->info.num_type = atoi(resp);
2248 dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
2250 // check number is international or national.
2251 num_type = ((p_call->info.num_type) >> 4) & 0x07;
2252 dbg("called party's type of number : [0x%x]\n", num_type);
2254 if (num_type == 1 && num[0] != '+') {
2255 // international number
2256 p_call->number[0] = '+';
2257 memcpy(&(p_call->number[1]), num, strlen(num));
2259 memcpy(&(p_call->number), num, strlen(num));
2261 dbg("incoming number - %s", p_call->number);
2266 tcore_at_tok_free(tokens);
2272 err("Invalid CLCC line");
2280 tcore_at_tok_free(tokens);
2286 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
2288 GSList *tokens = NULL;
2289 const char *line = NULL;
2293 GSList *pList = NULL;
2294 CallObject *co = NULL, *dupco = NULL;
2296 dbg("function entrance");
2297 // check call with waiting status already exist
2298 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
2300 if (pList != NULL) {
2301 dbg("[error]Waiting call already exist. skip");
2304 // check call with incoming status already exist
2305 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2307 if (pList != NULL) {
2308 dbg("[error]incoming call already exist. skip");
2311 line = (char *) data;
2312 tokens = tcore_at_tok_new(line);
2314 pId = g_slist_nth_data(tokens, 0);
2316 dbg("[error]:Call id is missing from +XCALLSTAT indication");
2320 call_id = atoi(pId);
2321 dupco = tcore_call_object_find_by_id(o, call_id);
2322 if (dupco != NULL) {
2323 dbg("co with same id already exist. skip");
2326 co = tcore_call_object_new(o, call_id);
2328 dbg("[ error ] co is NULL");
2332 tcore_at_tok_free(tokens);
2334 eflag = g_new0(gboolean, 1);
2336 dbg("calling _call_list_get");
2337 _call_list_get(o, eflag);
2340 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
2342 GSList *tokens = NULL;
2343 const char *line = NULL;
2347 GSList *pList = NULL;
2348 CallObject *co = NULL, *dupco = NULL;
2350 dbg("function entrance");
2351 // check call with incoming status already exist
2352 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2354 if (pList != NULL) {
2355 dbg("incoming call already exist. skip");
2359 line = (char *) data;
2360 tokens = tcore_at_tok_new(line);
2362 pId = g_slist_nth_data(tokens, 0);
2364 dbg("Error:Call id is missing from %XCALLSTAT indication");
2368 call_id = atoi(pId);
2370 dupco = tcore_call_object_find_by_id(o, call_id);
2371 if (dupco != NULL) {
2372 dbg("co with same id already exist. skip");
2376 co = tcore_call_object_new(o, call_id);
2378 dbg("[ error ] co is NULL");
2382 dbg("freeing at token")
2383 tcore_at_tok_free(tokens);
2385 eflag = g_new0(gboolean, 1);
2388 dbg("calling _call_list_get");
2389 _call_list_get(o, eflag);
2392 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
2395 TcorePlugin *plugin = NULL;
2396 CallObject *co = NULL;
2401 char *pCallId = NULL;
2402 GSList *tokens = NULL;
2403 gboolean *eflag = NULL;
2404 enum tcore_call_status co_status;
2406 dbg("function entrance");
2407 plugin = tcore_object_ref_plugin(o);
2408 cmd = (char *) data;
2409 tokens = tcore_at_tok_new(cmd);
2412 pCallId = g_slist_nth_data(tokens, 0);
2414 dbg("pCallId is missing from %XCALLSTAT indiaction");
2417 dbg("call id = %d", id);
2419 if ((stat = g_slist_nth_data(tokens, 1))) {
2420 status = atoi(stat);
2422 dbg("call status = %d", status);
2425 tcore_at_tok_free(tokens);
2426 co_status = _call_status(status);
2428 dbg("co_status = %d", co_status);
2429 switch (co_status) {
2430 case CALL_STATUS_ACTIVE:
2432 dbg("call(%d) status : [ ACTIVE ]", id);
2433 co = tcore_call_object_find_by_id(o, id);
2438 _call_status_active(plugin, co);
2442 case CALL_STATUS_HELD:
2443 dbg("call(%d) status : [ held ]", id);
2446 case CALL_STATUS_DIALING:
2448 dbg("call(%d) status : [ dialing ]", id);
2449 co = tcore_call_object_find_by_id(o, id);
2451 co = tcore_call_object_new(o, id);
2453 dbg("error : tcore_call_object_new [ id : %d ]", id);
2458 tcore_call_object_set_type(co, call_type(type));
2459 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
2460 _call_status_dialing(plugin, co);
2464 case CALL_STATUS_ALERT:
2466 dbg("call(%d) status : [ alert ]", id);
2467 co = tcore_call_object_find_by_id(o, id);
2472 // Store dialed number information into Call object.
2473 eflag = g_new0(gboolean, 1);
2475 dbg("calling _call_list_get");
2476 _call_list_get(o, eflag);
2480 case CALL_STATUS_INCOMING:
2481 case CALL_STATUS_WAITING:
2482 dbg("call(%d) status : [ incoming ]", id);
2485 case CALL_STATUS_IDLE:
2487 dbg("call(%d) status : [ release ]", id);
2489 co = tcore_call_object_find_by_id(o, id);
2495 plugin = tcore_object_ref_plugin(o);
2497 dbg("plugin is NULL");
2500 _call_status_idle(plugin, co);
2505 dbg("invalid call status", id);
2510 static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
2512 struct treq_call_dial *data = 0;
2513 char *raw_str = NULL;
2514 char *cmd_str = NULL;
2516 enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
2517 TcorePending *pending = NULL;
2518 TcoreATRequest *req;
2519 gboolean ret = FALSE;
2521 dbg("function entrance");
2522 data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
2523 clir = _get_clir_status(data->number);
2525 // Compose ATD Cmd string
2527 case TCORE_CALL_CLI_MODE_PRESENT:
2528 dbg("CALL_CLI_MODE_PRESENT");
2530 break; // invocation
2532 case TCORE_CALL_CLI_MODE_RESTRICT:
2533 dbg("CALL_CLI_MODE_RESTRICT");
2535 break; // suppression
2537 case TCORE_CALL_CLI_MODE_DEFAULT:
2540 dbg("CALL_CLI_MODE_DEFAULT");
2541 break; // subscription default
2544 dbg("data->number = %s", data->number);
2546 raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
2547 cmd_str = g_strdup_printf("%s", raw_str);
2549 dbg("request command : %s", cmd_str);
2551 pending = tcore_pending_new(o, 0);
2552 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2553 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2555 tcore_pending_set_request_data(pending, 0, req);
2556 ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
2562 dbg("AT request(%s) sent failed", req->cmd);
2563 return TCORE_RETURN_FAILURE;
2566 dbg("AT request(%s) sent success", req->cmd);
2568 return TCORE_RETURN_SUCCESS;
2571 static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
2573 char *cmd_str = NULL;
2574 CallObject *co = NULL;
2575 struct treq_call_answer *data = 0;
2576 TcorePending *pending = NULL;
2577 TcoreATRequest *req;
2578 gboolean ret = FALSE;
2580 dbg("function entrance");
2582 data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
2583 co = tcore_call_object_find_by_id(o, data->id);
2584 if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
2585 dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
2587 cmd_str = g_strdup_printf("%s", "ATA");
2588 pending = tcore_pending_new(o, 0);
2589 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2590 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2592 tcore_pending_set_request_data(pending, 0, req);
2593 ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
2597 dbg("AT request(%s) sent failed", req->cmd);
2598 return TCORE_RETURN_FAILURE;
2601 switch (data->type) {
2602 case CALL_ANSWER_TYPE_REJECT:
2604 dbg("call answer reject");
2605 tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
2609 case CALL_ANSWER_TYPE_REPLACE:
2611 dbg("call answer replace");
2612 tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
2616 case CALL_ANSWER_TYPE_HOLD_ACCEPT:
2618 dbg("call answer hold and accept");
2619 tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
2624 dbg("[ error ] wrong answer type [ %d ]", data->type);
2625 return TCORE_RETURN_FAILURE;
2629 return TCORE_RETURN_SUCCESS;
2632 static TReturn s_call_release(CoreObject *o, UserRequest *ur)
2634 CallObject *co = NULL;
2635 struct treq_call_end *data = 0;
2636 UserRequest *ur_dup = NULL;
2637 char *chld0_cmd = NULL;
2638 char *chld1_cmd = NULL;
2639 TcorePending *pending = NULL, *pending1 = NULL;
2640 TcoreATRequest *req, *req1;
2641 gboolean ret = FALSE;
2643 dbg("function entrance");
2644 data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
2645 co = tcore_call_object_find_by_id(o, data->id);
2647 dbg("type of release call = %d", data->type);
2649 if (data->type == CALL_END_TYPE_ALL) {
2650 // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
2651 chld0_cmd = g_strdup("AT+CHLD=0");
2652 chld1_cmd = g_strdup("AT+CHLD=1");
2654 pending = tcore_pending_new(o, 0);
2655 req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
2657 dbg("input command is %s", chld0_cmd);
2658 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2660 tcore_pending_set_request_data(pending, 0, req);
2661 ur_dup = tcore_user_request_new(NULL, NULL);
2662 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
2666 dbg("AT request %s has failed ", req->cmd);
2667 return TCORE_RETURN_FAILURE;
2670 pending1 = tcore_pending_new(o, 0);
2671 req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
2673 dbg("input command is %s", chld1_cmd);
2674 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2676 tcore_pending_set_request_data(pending1, 0, req1);
2677 ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
2681 dbg("AT request %s has failed ", req->cmd);
2682 return TCORE_RETURN_FAILURE;
2685 switch (data->type) {
2686 case CALL_END_TYPE_DEFAULT:
2689 id = tcore_call_object_get_id(co);
2691 dbg("call end call id [%d]", id);
2692 tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
2696 case CALL_END_TYPE_ACTIVE_ALL:
2698 dbg("call end all active");
2699 tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
2703 case CALL_END_TYPE_HOLD_ALL:
2705 dbg("call end all held");
2706 tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
2711 dbg("[ error ] wrong end type [ %d ]", data->type);
2712 return TCORE_RETURN_FAILURE;
2716 return TCORE_RETURN_SUCCESS;
2719 static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
2721 struct treq_call_hold *hold = 0;
2722 CallObject *co = NULL;
2724 dbg("function entrance");
2726 hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
2727 dbg("call id : [ %d ]", hold->id);
2729 co = tcore_call_object_find_by_id(o, hold->id);
2730 tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
2732 return TCORE_RETURN_SUCCESS;
2735 static TReturn s_call_active(CoreObject *o, UserRequest *ur)
2737 struct treq_call_active *active = 0;
2738 CallObject *co = NULL;
2740 active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
2741 dbg("call id : [ %d ]", active->id);
2743 co = tcore_call_object_find_by_id(o, active->id);
2744 tcore_call_control_active(o, ur, on_confirmation_call_active, co);
2746 return TCORE_RETURN_SUCCESS;
2749 static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
2751 struct treq_call_swap *swap = NULL;
2752 CallObject *co = NULL;
2754 swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
2755 dbg("call id : [ %d ]", swap->id);
2757 co = tcore_call_object_find_by_id(o, swap->id);
2758 tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
2760 return TCORE_RETURN_SUCCESS;
2763 static TReturn s_call_join(CoreObject *o, UserRequest *ur)
2765 struct treq_call_join *join = 0;
2766 CallObject *co = NULL;
2768 join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
2769 dbg("call id : [ %d ]", join->id);
2771 co = tcore_call_object_find_by_id(o, join->id);
2772 tcore_call_control_join(o, ur, on_confirmation_call_join, co);
2774 return TCORE_RETURN_SUCCESS;
2777 static TReturn s_call_split(CoreObject *o, UserRequest *ur)
2779 struct treq_call_split *split = 0;
2780 CallObject *co = NULL;
2782 split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
2783 co = tcore_call_object_find_by_id(o, split->id);
2784 dbg("call id : [ %d ]", split->id);
2786 tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
2788 return TCORE_RETURN_SUCCESS;
2791 static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
2793 struct treq_call_deflect *deflect = 0;
2794 CallObject *co = NULL;
2796 deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
2797 co = tcore_call_object_find_by_number(o, deflect->number);
2798 dbg("deflect number: [ %s ]", deflect->number);
2800 tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
2802 return TCORE_RETURN_SUCCESS;
2805 static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
2807 struct treq_call_transfer *transfer = 0;
2808 CallObject *co = NULL;
2810 transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
2811 dbg("call id : [ %d ]", transfer->id);
2813 co = tcore_call_object_find_by_id(o, transfer->id);
2814 tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
2816 return TCORE_RETURN_SUCCESS;
2819 static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
2821 char *cmd_str = NULL;
2822 TcorePending *pending = NULL;
2823 TcoreATRequest *req;
2825 gboolean ret = FALSE;
2826 struct treq_call_dtmf *dtmf = 0;
2827 char *dtmfstr = NULL, *tmp_dtmf = NULL;
2828 unsigned int dtmf_count;
2830 dbg("Function enter");
2832 dup = tcore_user_request_new(NULL, NULL);
2833 (void) _set_dtmf_tone_duration(o, dup);
2835 dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
2836 dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1); // DTMF digits + comma for each dtmf digit.
2838 if (dtmfstr == NULL) {
2839 dbg("Memory allocation failed");
2840 return TCORE_RETURN_FAILURE;
2845 for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
2846 *tmp_dtmf = dtmf->digits[dtmf_count];
2853 // last digit is having COMMA , overwrite it with '\0' .
2854 *(--tmp_dtmf) = '\0';
2855 dbg("Input DTMF string(%s)", dtmfstr);
2857 // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
2858 cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
2859 dbg("request command : %s", cmd_str);
2861 pending = tcore_pending_new(o, 0);
2862 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2863 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2865 tcore_pending_set_request_data(pending, 0, req);
2866 ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
2871 dbg("AT request sent failed")
2872 return TCORE_RETURN_FAILURE;
2875 return TCORE_RETURN_SUCCESS;
2878 static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
2880 UserRequest *ur_dup = NULL;
2881 TcorePending *pending = NULL, *pending1 = NULL;
2882 TcoreATRequest *req, *req1;
2883 char *cmd_str = NULL, *cmd_str1 = NULL;
2884 gboolean ret = FALSE;
2886 dbg("function entrance");
2888 // hard coded value for speaker.
2889 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,1"); // source type.
2890 cmd_str1 = g_strdup_printf("%s", "AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,1"); // destination type
2892 pending = tcore_pending_new(o, 0);
2893 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
2894 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2896 tcore_pending_set_request_data(pending, 0, req);
2897 ur_dup = tcore_user_request_ref(ur);
2899 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
2904 dbg("At request(%s) sent failed", req->cmd);
2905 return TCORE_RETURN_FAILURE;
2908 pending1 = tcore_pending_new(o, 0);
2909 req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
2910 dbg("input command is %s", cmd_str1);
2911 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2913 tcore_pending_set_request_data(pending1, 0, req1);
2914 ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
2919 dbg("AT request %s has failed ", req1->cmd);
2920 return TCORE_RETURN_FAILURE;
2923 return TCORE_RETURN_SUCCESS;
2926 static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
2928 UserRequest *src_ur = NULL;
2929 UserRequest *dest_ur = NULL;
2930 TcorePending *src_pending = NULL;
2931 TcorePending *dest_pending = NULL;
2932 TcoreATRequest *src_req = NULL;
2933 TcoreATRequest *dest_req = NULL;
2934 char *cmd_str = NULL, *volume_level = NULL;
2935 gboolean ret = FALSE;
2937 struct treq_call_sound_set_volume_level *data = NULL;
2938 data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
2940 // Hard-coded values for MIC & Speakers
2942 dbg("Set Source volume");
2944 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source type
2945 dbg("Request command string: %s", cmd_str);
2947 // Create new Pending request
2948 src_pending = tcore_pending_new(o, 0);
2950 // Create new AT-Command request
2951 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
2952 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
2954 // Free Command string
2957 tcore_pending_set_request_data(src_pending, 0, src_req);
2958 src_ur = tcore_user_request_ref(ur);
2961 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
2963 err("Failed to send AT-Command request");
2964 return TCORE_RETURN_FAILURE;
2967 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type
2968 dbg("Request command string: %s", cmd_str);
2970 // Create new Pending request
2971 src_pending = tcore_pending_new(o, 0);
2973 // Create new AT-Command request
2974 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
2975 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
2977 // Free Command string
2980 tcore_pending_set_request_data(src_pending, 0, src_req);
2982 src_ur = tcore_user_request_ref(ur);
2985 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
2987 err("Failed to send AT-Command request");
2988 return TCORE_RETURN_FAILURE;
2991 // Destination volume
2992 dbg("Set Source volume");
2994 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type
2995 dbg("Request command string: %s", cmd_str);
2997 // Create new Pending request
2998 dest_pending = tcore_pending_new(o, 0);
3000 // Create new AT-Command request
3001 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3002 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3004 // Free Command string
3007 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3008 dest_ur = tcore_user_request_ref(ur);
3011 ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3013 err("Failed to send AT-Command request");
3014 return TCORE_RETURN_FAILURE;
3017 dbg("Input volume level - %d", data->volume);
3018 switch (data->volume) {
3019 case CALL_SOUND_MUTE:
3023 case CALL_SOUND_VOLUME_LEVEL_1:
3024 volume_level = "40";
3027 case CALL_SOUND_VOLUME_LEVEL_2:
3028 volume_level = "46";
3031 case CALL_SOUND_VOLUME_LEVEL_3:
3032 volume_level = "52";
3035 case CALL_SOUND_VOLUME_LEVEL_4:
3036 volume_level = "58";
3039 case CALL_SOUND_VOLUME_LEVEL_5:
3040 volume_level = "64";
3043 case CALL_SOUND_VOLUME_LEVEL_6:
3044 volume_level = "70";
3047 case CALL_SOUND_VOLUME_LEVEL_7:
3048 volume_level = "76";
3051 case CALL_SOUND_VOLUME_LEVEL_8:
3052 volume_level = "82";
3055 case CALL_SOUND_VOLUME_LEVEL_9:
3057 volume_level = "88";
3060 cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level); // Destination type
3061 dbg("Request command string: %s", cmd_str);
3063 // Create new Pending request
3064 dest_pending = tcore_pending_new(o, 0);
3066 // Create new AT-Command request
3067 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3068 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3070 // Free Command string
3073 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3076 ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
3078 err("Failed to send AT-Command request");
3079 return TCORE_RETURN_FAILURE;
3082 return TCORE_RETURN_SUCCESS;
3086 static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
3091 return TCORE_RETURN_SUCCESS;
3094 static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
3096 char *cmd_str = NULL;
3097 TcorePending *pending = NULL;
3098 TcoreATRequest *req = NULL;
3099 gboolean ret = FALSE;
3102 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
3104 dbg("Request command string: %s", cmd_str);
3106 // Create new Pending request
3107 pending = tcore_pending_new(o, 0);
3109 // Create new AT-Command request
3110 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3111 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3113 // Free command string
3116 // Set request data (AT command) to Pending request
3117 tcore_pending_set_request_data(pending, 0, req);
3120 ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
3122 err("Failed to send AT-Command request");
3123 return TCORE_RETURN_FAILURE;
3127 return TCORE_RETURN_SUCCESS;
3130 static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
3132 char *cmd_str = NULL;
3133 TcorePending *pending = NULL;
3134 TcoreATRequest *req = NULL;
3135 gboolean ret = FALSE;
3138 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
3139 dbg("Request command string: %s", cmd_str);
3141 // Create new Pending request
3142 pending = tcore_pending_new(o, 0);
3144 // Create new AT-Command request
3145 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3146 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3148 // Free command string
3151 // Set request data (AT command) to Pending request
3152 tcore_pending_set_request_data(pending, 0, req);
3155 ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
3157 err("Failed to send AT-Command request");
3158 return TCORE_RETURN_FAILURE;
3162 return TCORE_RETURN_SUCCESS;
3166 static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
3171 return TCORE_RETURN_SUCCESS;
3174 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
3176 char *cmd_str = NULL;
3177 TcorePending *pending = NULL;
3178 TcoreATRequest *req = NULL;
3179 gboolean ret = FALSE;
3182 cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.
3183 dbg("Request command string: %s", cmd_str);
3185 // Create new Pending request
3186 pending = tcore_pending_new(o, 0);
3188 // Create new AT-Command request
3189 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3190 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3192 // Free command string */
3195 // Set request data (AT command) to Pending request
3196 tcore_pending_set_request_data(pending, 0, req);
3199 ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
3201 err("Failed to send AT-Command request");
3202 return TCORE_RETURN_FAILURE;
3206 return TCORE_RETURN_SUCCESS;
3210 static struct tcore_call_operations call_ops = {
3211 .dial = s_call_outgoing,
3212 .answer = s_call_answer,
3213 .end = s_call_release,
3214 .hold = s_call_hold,
3215 .active = s_call_active,
3216 .swap = s_call_swap,
3217 .join = s_call_join,
3218 .split = s_call_split,
3219 .deflect = s_call_deflect,
3220 .transfer = s_call_transfer,
3221 .send_dtmf = s_call_send_dtmf,
3222 .set_sound_path = s_call_set_sound_path,
3223 .set_sound_volume_level = s_call_set_sound_volume_level,
3224 .get_sound_volume_level = s_call_get_sound_volume_level,
3225 .mute = s_call_mute,
3226 .unmute = s_call_unmute,
3227 .get_mute_status = s_call_get_mute_status,
3228 .set_sound_recording = NULL,
3229 .set_sound_equalization = NULL,
3230 .set_sound_noise_reduction = NULL,
3233 static void s_call_info_mo_waiting(CoreObject *o)
3235 TcorePlugin *plugin = NULL;
3236 CallObject *co = NULL;
3241 plugin = tcore_object_ref_plugin(o);
3244 co = tcore_call_object_current_on_mo_processing(o);
3246 err("Failed to find Call Core object!");
3251 id = tcore_call_object_get_id(co);
3253 // Send notification to TAPI
3254 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3255 tcore_plugin_ref_core_object(plugin, "call"),
3256 TNOTI_CALL_INFO_WAITING,
3257 sizeof(unsigned int),
3264 static void s_call_info_mo_forwarded(CoreObject *o)
3266 TcorePlugin *plugin = NULL;
3267 CallObject *co = NULL;
3272 plugin = tcore_object_ref_plugin(o);
3275 co = tcore_call_object_current_on_mo_processing(o);
3277 err("Failed to find Call Core object!");
3282 id = tcore_call_object_get_id(co);
3284 // Send notification to TAPI
3285 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3286 tcore_plugin_ref_core_object(plugin, "call"),
3287 TNOTI_CALL_INFO_FORWARDED,
3288 sizeof(unsigned int),
3295 static void s_call_info_mo_barred_incoming(CoreObject *o)
3297 TcorePlugin *plugin = NULL;
3298 CallObject *co = NULL;
3303 plugin = tcore_object_ref_plugin(o);
3306 co = tcore_call_object_current_on_mo_processing(o);
3308 err("Failed to find Call Core object!");
3313 id = tcore_call_object_get_id(co);
3315 // Send notification to TAPI
3316 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3317 tcore_plugin_ref_core_object(plugin, "call"),
3318 TNOTI_CALL_INFO_BARRED_INCOMING,
3319 sizeof(unsigned int),
3326 static void s_call_info_mo_barred_outgoing(CoreObject *o)
3328 TcorePlugin *plugin = NULL;
3329 CallObject *co = NULL;
3334 plugin = tcore_object_ref_plugin(o);
3337 co = tcore_call_object_current_on_mo_processing(o);
3339 err("Failed to find Call Core object!");
3344 id = tcore_call_object_get_id(co);
3346 // Send notification to TAPI
3347 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3348 tcore_plugin_ref_core_object(plugin, "call"),
3349 TNOTI_CALL_INFO_BARRED_OUTGOING,
3350 sizeof(unsigned int),
3357 static void s_call_info_mo_deflected(CoreObject *o)
3359 TcorePlugin *plugin = NULL;
3360 CallObject *co = NULL;
3365 plugin = tcore_object_ref_plugin(o);
3368 co = tcore_call_object_current_on_mo_processing(o);
3370 err("Failed to find Call Core object!");
3375 id = tcore_call_object_get_id(co);
3377 // Send notification to TAPI
3378 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3379 tcore_plugin_ref_core_object(plugin, "call"),
3380 TNOTI_CALL_INFO_DEFLECTED,
3381 sizeof(unsigned int),
3388 static void s_call_info_mo_clir_suppression_reject(CoreObject *o)
3390 TcorePlugin *plugin = NULL;
3391 CallObject *co = NULL;
3396 plugin = tcore_object_ref_plugin(o);
3399 co = tcore_call_object_current_on_mo_processing(o);
3401 err("Failed to find Call Core object!");
3406 id = tcore_call_object_get_id(co);
3408 // Send notification to TAPI
3409 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3410 tcore_plugin_ref_core_object(plugin, "call"),
3411 TNOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT,
3412 sizeof(unsigned int),
3419 static void s_call_info_mo_cfu(CoreObject *o)
3421 TcorePlugin *plugin = NULL;
3422 CallObject *co = NULL;
3427 plugin = tcore_object_ref_plugin(o);
3430 co = tcore_call_object_current_on_mo_processing(o);
3432 err("Failed to find Call Core object!");
3437 id = tcore_call_object_get_id(co);
3439 // Send notification to TAPI
3440 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3441 tcore_plugin_ref_core_object(plugin, "call"),
3442 TNOTI_CALL_INFO_FORWARD_UNCONDITIONAL,
3443 sizeof(unsigned int),
3450 static void s_call_info_mo_cfc(CoreObject *o)
3452 TcorePlugin *plugin = NULL;
3453 CallObject *co = NULL;
3458 plugin = tcore_object_ref_plugin(o);
3461 co = tcore_call_object_current_on_mo_processing(o);
3463 err("Failed to find Call Core object!");
3468 id = tcore_call_object_get_id(co);
3470 // Send notification to TAPI
3471 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3472 tcore_plugin_ref_core_object(plugin, "call"),
3473 TNOTI_CALL_INFO_FORWARD_CONDITIONAL,
3474 sizeof(unsigned int),
3481 static void s_call_info_mt_cli(CoreObject *o, enum tcore_call_cli_mode mode, char *number)
3483 CallObject *co = NULL;
3487 co = tcore_call_object_current_on_mt_processing(o);
3489 err("Failed to find Call Core object!");
3493 // Set CLI information
3494 tcore_call_object_set_cli_info(co, mode, number);
3500 static void s_call_info_mt_cna(CoreObject *o, enum tcore_call_cna_mode mode, char *name, int dcs)
3502 CallObject *co = NULL;
3506 co = tcore_call_object_current_on_mt_processing(o);
3508 err("Failed to find Call Core object!");
3512 // Set CNA information
3513 tcore_call_object_set_cna_info(co, mode, name, dcs);
3519 static void s_call_info_mt_forwarded_call(CoreObject *o, char *number)
3521 TcorePlugin *plugin = NULL;
3522 CallObject *co = NULL;
3527 plugin = tcore_object_ref_plugin(o);
3530 co = tcore_call_object_find_by_number(o, number);
3532 err("Failed to find Call Core object!");
3537 id = tcore_call_object_get_id(co);
3539 // Send notification to TAPI
3540 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3541 tcore_plugin_ref_core_object(plugin, "call"),
3542 TNOTI_CALL_INFO_FORWARDED_CALL,
3543 sizeof(unsigned int),
3550 static void s_call_info_mt_deflected_call(CoreObject *o, char *number)
3552 TcorePlugin *plugin = NULL;
3553 CallObject *co = NULL;
3558 plugin = tcore_object_ref_plugin(o);
3561 co = tcore_call_object_find_by_number(o, number);
3563 err("Failed to find Call Core object!");
3568 id = tcore_call_object_get_id(co);
3570 // Send notification to TAPI
3571 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3572 tcore_plugin_ref_core_object(plugin, "call"),
3573 TNOTI_CALL_INFO_DEFLECTED_CALL,
3574 sizeof(unsigned int),
3581 static void s_call_info_mt_transfered(CoreObject *o, char *number)
3583 TcorePlugin *plugin = NULL;
3584 CallObject *co = NULL;
3589 plugin = tcore_object_ref_plugin(o);
3592 co = tcore_call_object_find_by_number(o, number);
3594 err("Failed to find Call Core object!");
3599 id = tcore_call_object_get_id(co);
3601 // Send notification to TAPI
3602 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3603 tcore_plugin_ref_core_object(plugin, "call"),
3604 TNOTI_CALL_INFO_TRANSFERED_CALL,
3605 sizeof(unsigned int),
3612 static void s_call_info_held(CoreObject *o, char *number)
3614 TcorePlugin *plugin = NULL;
3615 CallObject *co = NULL;
3620 plugin = tcore_object_ref_plugin(o);
3623 co = tcore_call_object_find_by_number(o, number);
3625 err("Failed to find Call Core object!");
3630 id = tcore_call_object_get_id(co);
3632 // Send notification to TAPI
3633 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3634 tcore_plugin_ref_core_object(plugin, "call"),
3635 TNOTI_CALL_INFO_HELD,
3636 sizeof(unsigned int),
3643 static void s_call_info_active(CoreObject *o, char *number)
3645 TcorePlugin *plugin = NULL;
3646 CallObject *co = NULL;
3651 plugin = tcore_object_ref_plugin(o);
3654 co = tcore_call_object_find_by_number(o, number);
3656 err("Failed to find Call Core object!");
3661 id = tcore_call_object_get_id(co);
3663 // Send notification to TAPI
3664 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3665 tcore_plugin_ref_core_object(plugin, "call"),
3666 TNOTI_CALL_INFO_ACTIVE,
3667 sizeof(unsigned int),
3674 static void s_call_info_joined(CoreObject *o, char *number)
3676 TcorePlugin *plugin = NULL;
3677 CallObject *co = NULL;
3682 plugin = tcore_object_ref_plugin(o);
3685 co = tcore_call_object_find_by_number(o, number);
3687 err("Failed to find Call Core object!");
3692 id = tcore_call_object_get_id(co);
3694 // Send notification to TAPI
3695 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3696 tcore_plugin_ref_core_object(plugin, "call"),
3697 TNOTI_CALL_INFO_JOINED,
3698 sizeof(unsigned int),
3705 static void s_call_info_released_on_hold(CoreObject *o, char *number)
3707 TcorePlugin *plugin = NULL;
3708 CallObject *co = NULL;
3713 plugin = tcore_object_ref_plugin(o);
3716 co = tcore_call_object_find_by_number(o, number);
3718 err("Failed to find Call Core object!");
3723 id = tcore_call_object_get_id(co);
3725 // Send notification to TAPI
3726 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3727 tcore_plugin_ref_core_object(plugin, "call"),
3728 TNOTI_CALL_INFO_RELEASED_ON_HOLD,
3729 sizeof(unsigned int),
3736 static void s_call_info_transfer_alert(CoreObject *o, char *number)
3738 TcorePlugin *plugin = NULL;
3739 CallObject *co = NULL;
3744 plugin = tcore_object_ref_plugin(o);
3747 co = tcore_call_object_find_by_number(o, number);
3749 err("Failed to find Call Core object!");
3754 id = tcore_call_object_get_id(co);
3756 // Send notification to TAPI
3757 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3758 tcore_plugin_ref_core_object(plugin, "call"),
3759 TNOTI_CALL_INFO_TRANSFER_ALERT,
3760 sizeof(unsigned int),
3767 static void s_call_info_transfered(CoreObject *o, char *number)
3769 TcorePlugin *plugin = NULL;
3770 CallObject *co = NULL;
3775 plugin = tcore_object_ref_plugin(o);
3778 co = tcore_call_object_find_by_number(o, number);
3780 err("Failed to find Call Core object!");
3785 id = tcore_call_object_get_id(co);
3787 // Send notification to TAPI
3788 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3789 tcore_plugin_ref_core_object(plugin, "call"),
3790 TNOTI_CALL_INFO_TRANSFERED,
3791 sizeof(unsigned int),
3798 static void s_call_info_cf_check_message(CoreObject *o, char *number)
3800 TcorePlugin *plugin = NULL;
3801 CallObject *co = NULL;
3806 plugin = tcore_object_ref_plugin(o);
3809 co = tcore_call_object_find_by_number(o, number);
3811 err("Failed to find Call Core object!");
3816 id = tcore_call_object_get_id(co);
3818 // Send notification to TAPI
3819 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
3820 tcore_plugin_ref_core_object(plugin, "call"),
3821 TNOTI_CALL_INFO_CF_CHECK_MESSAGE,
3822 sizeof(unsigned int),
3829 // Call Information Operations
3830 static struct tcore_call_information_operations call_information_ops = {
3832 .mo_call_waiting = s_call_info_mo_waiting,
3834 .mo_call_forwarded = s_call_info_mo_forwarded,
3835 .mo_call_barred_incoming = s_call_info_mo_barred_incoming,
3836 .mo_call_barred_outgoing = s_call_info_mo_barred_outgoing,
3837 .mo_call_deflected = s_call_info_mo_deflected,
3838 .mo_call_clir_suppression_reject = s_call_info_mo_clir_suppression_reject,
3839 .mo_call_cfu = s_call_info_mo_cfu,
3840 .mo_call_cfc = s_call_info_mo_cfc,
3841 .mt_call_cli = s_call_info_mt_cli,
3842 .mt_call_cna = s_call_info_mt_cna,
3843 .mt_call_forwarded_call = s_call_info_mt_forwarded_call,
3844 .mt_call_cug_call = 0,
3845 .mt_call_deflected_call = s_call_info_mt_deflected_call,
3846 .mt_call_transfered = s_call_info_mt_transfered,
3847 .call_held = s_call_info_held,
3848 .call_active = s_call_info_active,
3849 .call_joined = s_call_info_joined,
3850 .call_released_on_hold = s_call_info_released_on_hold,
3851 .call_transfer_alert = s_call_info_transfer_alert,
3852 .call_transfered = s_call_info_transfered,
3853 .call_cf_check_message = s_call_info_cf_check_message,
3856 gboolean s_call_init(TcorePlugin *p, TcoreHal *h)
3858 CoreObject *o = NULL;
3859 struct property_call_info *data = NULL;
3862 // Creating Call COre object
3863 o = tcore_call_new(p, "call", &call_ops, h);
3865 err("Failed to create Call Core Object");
3869 // Set Call Operations
3870 tcore_call_information_set_operations(o, &call_information_ops);
3873 tcore_object_add_callback(o, "+XCALLSTAT", on_notification_call_info, NULL);
3874 tcore_object_add_callback(o, "+CLIP", on_notification_call_clip_info, NULL);
3877 data = calloc(sizeof(struct property_call_info *), 1);
3878 tcore_plugin_link_property(p, "CALL", data);
3884 void s_call_exit(TcorePlugin *p)
3886 CoreObject *o = NULL;
3887 struct property_network_info *data = NULL;
3890 o = tcore_plugin_ref_core_object(p, "call");
3892 // Free Call Core Object */
3895 // Free 'CALL' property */
3896 data = tcore_plugin_ref_property(p, "CALL");