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;
275 if (!strncmp(num, "*31#", 4)) {
276 dbg("CLI mode restricted");
277 return TCORE_CALL_CLI_MODE_RESTRICT;
280 if (!strncmp(num, "#31#", 4)) {
281 dbg("CLI mode allowed");
282 return TCORE_CALL_CLI_MODE_PRESENT;
289 static enum tcore_call_status _call_status(unsigned int status)
295 return TCORE_CALL_STATUS_ACTIVE;
298 return TCORE_CALL_STATUS_HELD;
301 return TCORE_CALL_STATUS_DIALING;
304 return TCORE_CALL_STATUS_ALERT;
307 return TCORE_CALL_STATUS_INCOMING;
310 return TCORE_CALL_STATUS_WAITING;
312 case 6: // DISCONNECTED state // FALL THROUGH
314 return TCORE_CALL_STATUS_IDLE;
318 static gboolean _call_is_in_mpty(int mpty)
336 static enum tcore_call_type call_type(int type)
342 return TCORE_CALL_TYPE_VOICE;
345 return TCORE_CALL_TYPE_VIDEO;
351 return TCORE_CALL_TYPE_VOICE;
354 static int _compare_call_end_cause(int networkcause)
358 for (count = 0; count < sizeof(call_end_cause_table) / sizeof(call_end_cause_info); count++) {
359 if (call_end_cause_table[count].network_cause == networkcause)
360 return (call_end_cause_table[count].tapi_cause);
362 return CC_CAUSE_NORMAL_CALL_CLEARING;
366 static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data)
375 static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)
377 GSList *tokens = NULL;
378 GSList *lines = NULL;
379 const char *line = NULL;
385 lines = (GSList *) data;
386 if (1 != g_slist_length(lines)) {
387 err("Unsolicited message, BUT multiple lines present");
391 line = (char *) (lines->data);
392 tokens = tcore_at_tok_new(line);
394 stat = g_slist_nth_data(tokens, 1);
396 dbg("Stat is missing from %XCALLSTAT indiaction");
401 case STATUS_INCOMING:
402 dbg("calling on_notification_call_incoming");
403 on_notification_call_incoming(o, line, user_data);
407 dbg("calling on_notification_call_waiting");
408 on_notification_call_waiting(o, line, user_data);
411 case STATUS_CONNECTED: /*igonre Connected state. */
412 dbg("Connected state");
416 dbg("calling on_notification_call_status");
417 on_notification_call_status(o, line, user_data);
423 tcore_at_tok_free(tokens);
430 static gboolean _call_request_message(TcorePending *pending,
436 TcoreHal *hal = NULL;
441 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
444 tcore_pending_set_response_callback(pending, on_resp, user_data);
446 tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
449 tcore_pending_link_user_request(pending, ur);
451 err("User Request is NULL, is this internal request??");
455 hal = tcore_object_get_hal(o);
456 // Send request to HAL
457 ret = tcore_hal_send_request(hal, pending);
458 if (TCORE_RETURN_SUCCESS != ret) {
459 err("Request send failed");
467 static void _call_status_idle(TcorePlugin *p, CallObject *co)
469 CoreObject *core_obj = NULL;
470 char *cmd_str = NULL;
471 TcorePending *pending = NULL;
472 TcoreATRequest *req = NULL;
473 gboolean ret = FALSE;
477 core_obj = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
478 dbg("Call ID [%d], Call Status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));
480 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_IDLE) {
481 // get call end cause.
482 cmd_str = g_strdup_printf("%s", "AT+XCEER");
483 dbg("Request command string: %s", cmd_str);
485 // Create new Pending request
486 pending = tcore_pending_new(core_obj, 0);
488 // Create new AT-Command request
489 req = tcore_at_request_new(cmd_str, "+XCEER", TCORE_AT_SINGLELINE);
490 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
491 // Free command string
494 // Set request data (AT command) to Pending request
495 tcore_pending_set_request_data(pending, 0, req);
497 ur = tcore_user_request_new(NULL, NULL);
499 ret = _call_request_message(pending, core_obj, ur, _on_confirmation_call_end_cause, co);
502 err("Failed to send AT-Command request");
503 // free only UserRequest.
505 tcore_user_request_free(ur);
511 err("Call object was not free");
512 tcore_call_object_free(core_obj, co);
518 static void _call_status_dialing(TcorePlugin *p, CallObject *co)
520 struct tnoti_call_status_dialing data;
524 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_DIALING) {
525 data.type = tcore_call_object_get_type(co);
526 dbg("data.type : [%d]", data.type);
528 data.id = tcore_call_object_get_id(co);
529 dbg("data.id : [%d]", data.id);
532 tcore_call_object_set_status(co, TCORE_CALL_STATUS_DIALING);
534 // Send notification to TAPI
535 tcore_server_send_notification(tcore_plugin_ref_server(p),
536 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
537 TNOTI_CALL_STATUS_DIALING,
538 sizeof(struct tnoti_call_status_dialing),
546 static void _call_status_alert(TcorePlugin *p, CallObject *co)
548 struct tnoti_call_status_alert data;
552 // Alerting has just 1 data 'CALL ID'
553 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ALERT) {
554 data.type = tcore_call_object_get_type(co);
555 dbg("data.type : [%d]", data.type);
557 data.id = tcore_call_object_get_id(co);
558 dbg("data.id : [%d]", data.id);
561 tcore_call_object_set_status(co, TCORE_CALL_STATUS_ALERT);
563 // Send notification to TAPI
564 tcore_server_send_notification(tcore_plugin_ref_server(p),
565 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
566 TNOTI_CALL_STATUS_ALERT,
567 sizeof(struct tnoti_call_status_alert),
575 static void _call_status_active(TcorePlugin *p, CallObject *co)
577 struct tnoti_call_status_active data;
581 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ACTIVE) {
582 data.type = tcore_call_object_get_type(co);
583 dbg("data.type : [%d]", data.type);
585 data.id = tcore_call_object_get_id(co);
586 dbg("data.id : [%d]", data.id);
589 tcore_call_object_set_status(co, TCORE_CALL_STATUS_ACTIVE);
591 // Send notification to TAPI
592 tcore_server_send_notification(tcore_plugin_ref_server(p),
593 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
594 TNOTI_CALL_STATUS_ACTIVE,
595 sizeof(struct tnoti_call_status_active),
603 static void _call_status_held(TcorePlugin *p, CallObject *co)
605 struct tnoti_call_status_held data;
609 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_HELD) {
610 data.type = tcore_call_object_get_type(co);
611 dbg("data.type : [%d]", data.type);
613 data.id = tcore_call_object_get_id(co);
614 dbg("data.id : [%d]", data.id);
617 tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
619 // Send notification to TAPI
620 tcore_server_send_notification(tcore_plugin_ref_server(p),
621 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
622 TNOTI_CALL_STATUS_HELD,
623 sizeof(struct tnoti_call_status_held),
631 static void _call_status_incoming(TcorePlugin *p, CallObject *co)
633 struct tnoti_call_status_incoming data;
637 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_INCOMING) {
638 tcore_call_object_set_status(co, TCORE_CALL_STATUS_INCOMING);
640 data.type = tcore_call_object_get_type(co);
641 dbg("data.type : [%d]", data.type);
643 data.id = tcore_call_object_get_id(co);
644 dbg("data.id : [%d]", data.id);
646 data.cli.mode = tcore_call_object_get_cli_mode(co);
647 dbg("data.cli.mode : [%d]", data.cli.mode);
649 tcore_call_object_get_number(co, data.cli.number);
650 dbg("data.cli.number : [%s]", data.cli.number);
652 data.cna.mode = tcore_call_object_get_cna_mode(co);
653 dbg("data.cna.mode : [%d]", data.cna.mode);
655 tcore_call_object_get_name(co, data.cna.name);
656 dbg("data.cna.name : [%s]", data.cna.name);
658 data.forward = FALSE; // this is tmp code
660 data.active_line = tcore_call_object_get_active_line(co);
661 dbg("data.active_line : [%d]", data.active_line);
663 // Send notification to TAPI
664 tcore_server_send_notification(tcore_plugin_ref_server(p),
665 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
666 TNOTI_CALL_STATUS_INCOMING,
667 sizeof(struct tnoti_call_status_incoming),
675 static void _call_status_waiting(TcorePlugin *p, CallObject *co)
678 _call_status_incoming(p, co);
684 static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status)
688 dbg("Call Status is %d", status);
690 case TCORE_CALL_STATUS_IDLE:
691 _call_status_idle(p, co);
694 case TCORE_CALL_STATUS_ACTIVE:
695 _call_status_active(p, co);
698 case TCORE_CALL_STATUS_HELD:
699 _call_status_held(p, co);
702 case TCORE_CALL_STATUS_DIALING:
703 _call_status_dialing(p, co);
706 case TCORE_CALL_STATUS_ALERT:
707 _call_status_alert(p, co);
710 case TCORE_CALL_STATUS_INCOMING:
711 _call_status_incoming(p, co);
714 case TCORE_CALL_STATUS_WAITING:
715 _call_status_waiting(p, co);
723 static TReturn _call_list_get(CoreObject *o, gboolean *event_flag)
725 UserRequest *ur = NULL;
726 TcorePending *pending = NULL;
727 char *cmd_str = NULL;
728 TcoreATRequest *req = NULL;
729 gboolean ret = FALSE;
733 err("Core Object is NULL");
734 return TCORE_RETURN_FAILURE;
737 // Create new User Request
738 ur = tcore_user_request_new(NULL, NULL);
741 cmd_str = g_strdup("AT+CLCC");
743 // Create new Pending Request
744 pending = tcore_pending_new(o, 0);
745 req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);
749 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
751 tcore_pending_set_request_data(pending, 0, req);
753 ret = _call_request_message(pending, o, ur, on_response_call_list_get, event_flag);
755 err("AT request (%s) sending failed", req->cmd);
756 // free only UserRequest.
758 tcore_user_request_free(ur);
761 return TCORE_RETURN_FAILURE;
764 dbg("AT request sent success");
765 return TCORE_RETURN_SUCCESS;
769 static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data)
773 if (result == FALSE) { // Fail
783 static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
785 UserRequest *ur = NULL;
786 GSList *tokens = NULL;
787 const char *line = NULL;
788 const TcoreATResponse *response = data;
789 struct tresp_call_dial resp;
790 enum telephony_call_error error;
793 ur = tcore_pending_ref_user_request(p);
795 if (response->success > 0) {
797 resp.err = CALL_ERROR_NONE;
799 dbg("RESPONSE NOT OK");
801 line = (const char *) response->final_response;
802 tokens = tcore_at_tok_new(line);
804 if (g_slist_length(tokens) < 1) {
805 err("Unspecified error cause OR string corrupted");
806 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
808 error = atoi(g_slist_nth_data(tokens, 0));
810 // TODO: CMEE error mapping is required.
811 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
815 tcore_at_tok_free(tokens);
818 // Send Response to TAPI
819 tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
821 err("User Request is NULL");
828 static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)
830 UserRequest *ur = NULL;
831 GSList *tokens = NULL;
832 const char *line = NULL;
833 const TcoreATResponse *response = data;
834 struct tresp_call_answer resp;
835 enum telephony_call_error error;
838 ur = tcore_pending_ref_user_request(p);
840 if (response->success > 0) {
842 resp.err = CALL_ERROR_NONE;
844 dbg("RESPONSE NOT OK");
846 line = (const char *) response->final_response;
847 tokens = tcore_at_tok_new(line);
849 if (g_slist_length(tokens) < 1) {
850 err("Unspecified error cause OR string corrupted");
851 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
853 error = atoi(g_slist_nth_data(tokens, 0));
855 // TODO: CMEE error mapping is required.
856 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
860 tcore_at_tok_free(tokens);
863 resp.id = tcore_call_object_get_id((CallObject *) user_data);
865 // Send Response to TAPI
866 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
868 err("User Request is NULL");
876 static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)
878 UserRequest *ur = NULL;
879 GSList *tokens = NULL;
880 const char *line = NULL;
881 const TcoreATResponse *response = data;
882 struct tresp_call_answer resp;
883 enum telephony_call_error error;
887 ur = tcore_pending_ref_user_request(p);
889 if (response->success > 0) {
891 resp.err = CALL_ERROR_NONE;
893 dbg("RESPONSE NOT OK");
894 line = (const char *) response->final_response;
895 tokens = tcore_at_tok_new(line);
897 if (g_slist_length(tokens) < 1) {
898 err("Unspecified error cause OR string corrupted");
899 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
901 error = atoi(g_slist_nth_data(tokens, 0));
902 // TODO: CMEE error mapping is required.
903 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
907 tcore_at_tok_free(tokens);
910 resp.id = tcore_call_object_get_id((CallObject *) user_data);
912 // Send Response to TAPI
913 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
915 err("User Request is NULL");
922 static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)
924 UserRequest *ur = NULL;
925 GSList *tokens = NULL;
926 const char *line = NULL;
927 const TcoreATResponse *response = data;
928 struct tresp_call_answer resp;
929 enum telephony_call_error error;
932 ur = tcore_pending_ref_user_request(p);
934 if (response->success > 0) {
936 resp.err = CALL_ERROR_NONE;
938 dbg("RESPONSE NOT OK");
939 line = (const char *) response->final_response;
940 tokens = tcore_at_tok_new(line);
942 if (g_slist_length(tokens) < 1) {
943 err("Unspecified error cause OR string corrupted");
944 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
946 error = atoi(g_slist_nth_data(tokens, 0));
947 // TODO: CMEE error mapping is required.
948 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
952 tcore_at_tok_free(tokens);
954 resp.id = tcore_call_object_get_id((CallObject *) user_data);
956 // Send Response to TAPI
957 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
959 dbg("User Request is NULL");
966 static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)
968 CoreObject *o = NULL;
969 UserRequest *ur = NULL;
970 GSList *tokens = NULL;
971 const char *line = NULL;
972 const TcoreATResponse *response = data;
973 struct tresp_call_answer resp;
974 enum telephony_call_error error;
978 o = tcore_pending_ref_core_object(p);
979 ur = tcore_pending_ref_user_request(p);
980 resp.id = tcore_call_object_get_id((CallObject *) user_data);
983 if (response->success > 0) {
985 resp.err = CALL_ERROR_NONE;
987 err("RESPONSE NOT OK");
988 line = (const char *) response->final_response;
989 tokens = tcore_at_tok_new(line);
991 if (g_slist_length(tokens) < 1) {
992 err("Unspecified error cause OR string corrupted");
993 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
995 error = atoi(g_slist_nth_data(tokens, 0));
997 // TODO: CMEE error mapping is required.
998 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1002 tcore_at_tok_free(tokens);
1005 // Send response to TAPI
1006 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
1009 CallObject *co = NULL;
1012 list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
1014 err("Can't find active Call");
1018 co = (CallObject *) list->data;
1020 err("Can't get active Call object");
1025 tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
1026 dbg("Call status is set to HELD");
1029 err("User Request is NULL");
1036 static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1038 UserRequest *ur = NULL;
1039 struct tresp_call_end resp;
1040 GSList *tokens = NULL;
1041 const char *line = NULL;
1042 enum telephony_call_error error;
1043 const TcoreATResponse *response = data;
1046 ur = tcore_pending_ref_user_request(p);
1048 if (response->success > 0) {
1050 resp.err = CALL_ERROR_NONE;
1052 err("RESPONSE NOT OK");
1054 line = (const char *) response->final_response;
1055 tokens = tcore_at_tok_new(line);
1057 if (g_slist_length(tokens) < 1) {
1058 err("Unspecified error cause OR string corrupted");
1059 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1061 error = atoi(g_slist_nth_data(tokens, 0));
1063 // TODO: CMEE error mapping is required.
1064 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1066 tcore_at_tok_free(tokens);
1070 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1071 dbg("resp.type = %d resp.id= %d", resp.type, resp.id);
1073 // Send reponse to TAPI
1074 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
1076 err("User Request is NULL");
1084 static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)
1086 // skip response handling - actual result will be handled in on_confirmation_call_release_all
1087 const TcoreATResponse *response = data;
1091 if (response->success > 0) {
1094 err("RESPONSE NOT OK");
1102 static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)
1105 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);
1111 static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)
1114 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);
1119 static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)
1122 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);
1127 static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)
1130 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);
1135 static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1137 UserRequest *ur = NULL;
1138 GSList *tokens = NULL;
1139 const char *line = NULL;
1140 const TcoreATResponse *response = NULL;
1141 enum telephony_call_error error;
1144 ur = tcore_pending_ref_user_request(p);
1145 response = (TcoreATResponse *) data;
1146 if (response->success > 0) {
1148 error = CALL_ERROR_NONE;
1150 err("RESPONSE NOT OK");
1152 line = (const char *) response->final_response;
1153 tokens = tcore_at_tok_new(line);
1155 if (g_slist_length(tokens) < 1) {
1156 err("Unspecified error cause OR string corrupted");
1157 error = CALL_ERROR_SERVICE_UNAVAIL;
1159 error = atoi(g_slist_nth_data(tokens, 0));
1161 // TODO: CMEE error mapping is required.
1162 error = CALL_ERROR_SERVICE_UNAVAIL;
1166 tcore_at_tok_free(tokens);
1169 dbg("Response Call type -%d", type);
1171 case TRESP_CALL_HOLD:
1173 struct tresp_call_hold resp;
1176 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1177 dbg("call hold response");
1178 // Send reponse to TAPI
1179 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1183 case TRESP_CALL_ACTIVE:
1185 struct tresp_call_active resp;
1188 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1189 dbg("call active response");
1190 // Send reponse to TAPI
1191 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1195 case TRESP_CALL_JOIN:
1197 struct tresp_call_join resp;
1200 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1201 dbg("call join response");
1203 // Send reponse to TAPI
1204 tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
1208 case TRESP_CALL_SPLIT:
1210 struct tresp_call_split resp;
1213 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1214 dbg("call split response");
1215 // Send reponse to TAPI
1216 tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
1220 case TRESP_CALL_DEFLECT:
1222 struct tresp_call_deflect resp;
1225 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1226 dbg("call deflect response");
1227 // Send reponse to TAPI
1228 tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
1233 case TRESP_CALL_TRANSFER:
1235 struct tresp_call_transfer resp;
1238 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1239 dbg("call transfer response");
1240 // Send reponse to TAPI
1241 tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
1245 case TRESP_CALL_SEND_DTMF:
1247 struct tresp_call_dtmf resp;
1250 dbg("call dtmf response");
1251 // Send reponse to TAPI
1252 tcore_user_request_send_response(ur, TRESP_CALL_SEND_DTMF, sizeof(struct tresp_call_dtmf), &resp);
1258 dbg("type not supported");
1263 if ((type == TRESP_CALL_HOLD) || (type == TRESP_CALL_ACTIVE) || (type == TRESP_CALL_JOIN)
1264 || (type == TRESP_CALL_SPLIT)) {
1266 CoreObject *core_obj = NULL;
1267 gboolean *eflag = g_new0(gboolean, 1);
1269 core_obj = tcore_pending_ref_core_object(p);
1272 dbg("Calling _call_list_get");
1273 _call_list_get(core_obj, eflag);
1281 static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)
1284 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);
1289 static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)
1292 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);
1297 static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)
1300 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);
1305 static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)
1308 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);
1313 static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)
1316 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);
1321 static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)
1324 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);
1329 static void on_confirmation_call_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
1332 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SEND_DTMF);
1337 static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data)
1339 GSList *tokens = NULL;
1340 const char *line = NULL;
1341 const TcoreATResponse *response = data;
1342 enum telephony_call_error error;
1346 if (response->success > 0) {
1348 error = CALL_ERROR_NONE;
1350 err("RESPONSE NOT OK");
1351 line = (const char *) response->final_response;
1352 tokens = tcore_at_tok_new(line);
1353 if (g_slist_length(tokens) < 1) {
1354 err("err cause not specified or string corrupted");
1355 error = CALL_ERROR_SERVICE_UNAVAIL;
1357 error = atoi(g_slist_nth_data(tokens, 0));
1358 // TODO: CMEE error mapping is required.
1362 tcore_at_tok_free(tokens);
1365 dbg("Set dtmf tone duration response - %d", error);
1369 static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
1371 CoreObject *core_obj = NULL;
1372 UserRequest *ur = NULL;
1373 const TcoreATResponse *response = data;
1374 struct tresp_call_swap resp;
1375 GSList *tokens = NULL;
1376 const char *line = NULL;
1379 core_obj = tcore_pending_ref_core_object(p);
1380 ur = tcore_pending_ref_user_request(p);
1383 if (response->success > 0) {
1385 resp.err = CALL_ERROR_NONE;
1387 err("RESPONSE NOT OK");
1388 line = (const char *) response->final_response;
1389 tokens = tcore_at_tok_new(line);
1390 if (g_slist_length(tokens) < 1) {
1391 err("err cause not specified or string corrupted");
1392 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1394 resp.err = atoi(g_slist_nth_data(tokens, 0));
1396 // TODO: CMEE error mapping is required.
1397 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1401 tcore_at_tok_free(tokens);
1404 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1405 dbg("resp.id = %d", resp.id);
1407 // Send response to TAPI
1408 tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
1411 GSList *active = NULL;
1412 GSList *held = NULL;
1413 CallObject *co = NULL;
1414 gboolean *eflag = NULL;
1416 held = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_HELD);
1418 err("Can't find held Call");
1422 active = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_ACTIVE);
1424 dbg("Can't find active Call");
1429 co = (CallObject *) held->data;
1431 err("Can't get held Call object");
1435 resp.id = tcore_call_object_get_id(co);
1437 // Send response to TAPI
1438 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1440 held = g_slist_next(held);
1444 co = (CallObject *) active->data;
1446 err("[ error ] can't get active call object");
1450 resp.id = tcore_call_object_get_id(co);
1452 // Send response to TAPI
1453 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1454 active = g_slist_next(active);
1457 eflag = g_new0(gboolean, 1);
1460 dbg("calling _call_list_get");
1461 _call_list_get(core_obj, eflag);
1464 err("User Request is NULL");
1471 static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1473 UserRequest *ur = NULL;
1474 GSList *tokens = NULL;
1475 const char *line = NULL;
1476 const TcoreATResponse *response = data;
1477 char *resp_str = NULL;
1478 struct tresp_call_sound_set_path resp;
1482 ur = tcore_pending_ref_user_request(p);
1484 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1486 err("Input data is NULL");
1490 if (response->success > 0) {
1493 line = (const char *) (((GSList *) response->lines)->data);
1494 tokens = tcore_at_tok_new(line);
1496 resp_str = g_slist_nth_data(tokens, 0);
1497 if (!g_slist_nth_data(tokens, 0)) {
1498 err("group_id is missing");
1503 if (!g_slist_nth_data(tokens, 1)) {
1504 err(" function_id is missing");
1509 resp_str = g_slist_nth_data(tokens, 2);
1512 error = atoi(resp_str);
1514 dbg("Response is Success");
1522 tcore_at_tok_free(tokens);
1524 dbg("RESPONSE NOT OK");
1526 line = (const char *) response->final_response;
1527 tokens = tcore_at_tok_new(line);
1529 if (g_slist_length(tokens) < 1) {
1530 err("err cause not specified or string corrupted");
1533 error = atoi(g_slist_nth_data(tokens, 0));
1535 // TODO: CMEE error mapping is required.
1540 tcore_at_tok_free(tokens);
1544 if ( resp.err ) { // Send only failed notification . success notification send when destination device is set.
1545 // Send notification to TAPI
1546 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1547 setsoundpath = TRUE;
1550 err("User Request is NULL");
1557 static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1559 UserRequest *ur = NULL;
1560 GSList *tokens = NULL;
1561 const char *line = NULL;
1562 char *resp_str = NULL;
1563 struct tresp_call_sound_set_path resp;
1564 const TcoreATResponse *response = data;
1569 ur = tcore_pending_ref_user_request(p);
1570 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1573 err("Input data is NULL");
1578 if (response->success > 0) {
1581 line = (const char *) (((GSList *) response->lines)->data);
1582 tokens = tcore_at_tok_new(line);
1584 resp_str = g_slist_nth_data(tokens, 0);
1585 if (!g_slist_nth_data(tokens, 0)) {
1586 dbg("group_id is missing");
1591 if (!g_slist_nth_data(tokens, 1)) {
1592 dbg("function_id is missing");
1597 resp_str = g_slist_nth_data(tokens, 2);
1599 error = atoi(resp_str);
1601 dbg("Response is Success");
1610 tcore_at_tok_free(tokens);
1612 dbg("RESPONSE NOT OK");
1614 line = (const char *) response->final_response;
1615 tokens = tcore_at_tok_new(line);
1617 if (g_slist_length(tokens) < 1) {
1618 err("err cause not specified or string corrupted");
1621 error = atoi(g_slist_nth_data(tokens, 0));
1622 // TODO: CMEE error mapping is required.
1627 tcore_at_tok_free(tokens);
1630 if (setsoundpath == TRUE) {
1631 setsoundpath = FALSE;
1633 // Send response to TAPI
1634 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1637 dbg("User Request is NULL");
1644 static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1646 UserRequest *ur = NULL;
1647 GSList *tokens = NULL;
1648 const char *line = NULL;
1649 const TcoreATResponse *response = data;
1650 char *resp_str = NULL;
1651 struct tresp_call_sound_set_volume_level resp;
1654 ur = tcore_pending_ref_user_request(p);
1656 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1658 err("Input data is NULL");
1662 if (response->success > 0) {
1665 line = (const char *) (((GSList *) response->lines)->data);
1666 tokens = tcore_at_tok_new(line);
1668 resp_str = g_slist_nth_data(tokens, 0);
1669 if (!g_slist_nth_data(tokens, 0)) {
1670 err("group_id is missing");
1675 if (!g_slist_nth_data(tokens, 1)) {
1676 err("function_id is missing");
1681 resp_str = g_slist_nth_data(tokens, 2);
1683 error = atoi(resp_str);
1686 dbg("Response is Success ");
1695 tcore_at_tok_free(tokens);
1697 dbg("RESPONSE NOT OK");
1699 line = (const char *) response->final_response;
1700 tokens = tcore_at_tok_new(line);
1702 if (g_slist_length(tokens) < 1) {
1703 err("err cause not specified or string corrupted");
1706 error = atoi(g_slist_nth_data(tokens, 0));
1708 // TODO: CMEE error mapping is required.
1713 tcore_at_tok_free(tokens);
1717 if (resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.
1718 // Send reposne to TAPI
1719 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1723 err("User Request is NULL");
1731 static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1733 UserRequest *ur = NULL;
1734 GSList *tokens = NULL;
1735 const char *line = NULL;
1736 char *resp_str = NULL;
1737 const TcoreATResponse *response = data;
1738 struct tresp_call_sound_set_volume_level resp;
1743 ur = tcore_pending_ref_user_request(p);
1745 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1747 err("Input data is NULL");
1752 if (response->success > 0) {
1754 line = (const char *) (((GSList *) response->lines)->data);
1755 tokens = tcore_at_tok_new(line);
1756 resp_str = g_slist_nth_data(tokens, 0);
1758 if (!g_slist_nth_data(tokens, 0)) {
1759 err("group_id is missing");
1764 if (!g_slist_nth_data(tokens, 1)) {
1765 err("function_id is missing");
1770 resp_str = g_slist_nth_data(tokens, 2);
1773 error = atoi(resp_str);
1776 dbg("Response is Success");
1785 tcore_at_tok_free(tokens);
1787 dbg("RESPONSE NOT OK");
1789 line = (const char *) response->final_response;
1790 tokens = tcore_at_tok_new(line);
1792 if (g_slist_length(tokens) < 1) {
1793 err("err cause not specified or string corrupted");
1796 error = atoi(g_slist_nth_data(tokens, 0));
1798 // TODO: CMEE error mapping is required.
1802 tcore_at_tok_free(tokens);
1805 if (soundvolume == TRUE) {
1806 soundvolume = FALSE;
1808 // Send reposne to TAPI
1809 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1812 err("User Request is NULL");
1820 static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
1822 UserRequest *ur = NULL;
1823 GSList *tokens = NULL;
1824 const char *line = NULL;
1825 char *resp_str = NULL;
1826 struct tresp_call_mute resp;
1827 const TcoreATResponse *response = data;
1832 ur = tcore_pending_ref_user_request(p);
1835 err("Input data is NULL");
1839 if (response->success > 0) {
1842 line = (const char *) (((GSList *) response->lines)->data);
1843 tokens = tcore_at_tok_new(line);
1844 resp_str = g_slist_nth_data(tokens, 0);
1846 if (!g_slist_nth_data(tokens, 0)) {
1847 err("group_id is missing");
1852 if (!g_slist_nth_data(tokens, 1)) {
1853 err(" function_id is missing");
1858 resp_str = g_slist_nth_data(tokens, 2);
1861 error = atoi(resp_str);
1863 dbg("Response is Success");
1871 tcore_at_tok_free(tokens);
1873 dbg("RESPONSE NOT OK");
1875 line = (const char *) response->final_response;
1876 tokens = tcore_at_tok_new(line);
1878 if (g_slist_length(tokens) < 1) {
1879 err("err cause not specified or string corrupted");
1882 error = atoi(g_slist_nth_data(tokens, 0));
1884 // TODO: CMEE error mapping is required.
1889 tcore_at_tok_free(tokens);
1893 tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
1895 err("User Request is NULL");
1902 static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
1904 const TcoreATResponse *response = NULL;
1905 struct tresp_call_unmute resp;
1906 GSList *tokens = NULL;
1907 const char *line = NULL;
1908 UserRequest *ur = NULL;
1909 char *resp_str = NULL;
1914 response = (TcoreATResponse *) data;
1915 ur = tcore_pending_ref_user_request(p);
1918 err("Input data is NULL");
1922 if (response->success > 0) {
1925 line = (const char *) (((GSList *) response->lines)->data);
1926 tokens = tcore_at_tok_new(line);
1927 resp_str = g_slist_nth_data(tokens, 0);
1929 if (!g_slist_nth_data(tokens, 0)) {
1930 err("group_id is missing");
1935 if (!g_slist_nth_data(tokens, 1)) {
1936 err(" function_id is missing");
1941 resp_str = g_slist_nth_data(tokens, 2);
1944 error = atoi(resp_str);
1946 dbg("Response is Success");
1954 tcore_at_tok_free(tokens);
1956 dbg("RESPONSE NOT OK");
1958 line = (const char *) response->final_response;
1959 tokens = tcore_at_tok_new(line);
1961 if (g_slist_length(tokens) < 1) {
1962 err("err cause not specified or string corrupted");
1965 error = atoi(g_slist_nth_data(tokens, 0));
1967 // TODO: CMEE error mapping is required.
1972 tcore_at_tok_free(tokens);
1976 tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
1978 err("User Request is NULL");
1986 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
1988 TcorePlugin *plugin = NULL;
1989 CoreObject *core_obj = NULL;
1990 CallObject *co = NULL;
1991 struct clcc_call_t *call_list = NULL;
1992 gboolean *event_flag = (gboolean *) user_data;
1993 const TcoreATResponse *response = data;
1994 GSList *resp_data = NULL;
1997 int cllc_info = 0, countCalls = 0, countValidCalls = 0;
2002 plugin = tcore_pending_ref_plugin(p);
2003 core_obj = tcore_pending_ref_core_object(p);
2005 if (response->success > 0) {
2007 if (response->lines) {
2008 resp_data = (GSList *) response->lines;
2009 countCalls = g_slist_length(resp_data);
2010 dbg("Total records : %d", countCalls);
2013 if (0 == countCalls) {
2014 err("Call count is zero");
2022 call_list = g_new0(struct clcc_call_t, countCalls);
2024 for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
2025 line = (char *) (resp_data->data);
2027 error = _callFromCLCCLine(line, call_list + countValidCalls);
2032 co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
2034 co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
2036 err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
2041 // Call set parameters
2042 tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
2043 tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
2044 tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
2045 tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
2046 tcore_call_object_set_active_line(co, 0);
2049 dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
2050 _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
2053 tcore_call_object_set_status(co, call_list[cllc_info].info.status);
2055 dbg("Call id : (%d)", call_list[cllc_info].info.id);
2056 dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
2057 dbg("Call type : (%d)", call_list[cllc_info].info.type);
2058 dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
2059 dbg("Call number : (%s)", call_list[cllc_info].number);
2060 dbg("Call status : (%d)", call_list[cllc_info].info.status);
2078 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
2080 TcorePlugin *plugin = NULL;
2081 CoreObject *core_obj = NULL;
2082 CallObject *co = (CallObject *) user_data;
2083 const TcoreATResponse *response = data;
2084 const char *line = NULL;
2085 struct tnoti_call_status_idle call_status;
2086 GSList *tokens = NULL;
2091 plugin = tcore_pending_ref_plugin(p);
2092 core_obj = tcore_pending_ref_core_object(p);
2094 if (response->success > 0) {
2096 line = (const char *) (((GSList *) response->lines)->data);
2097 tokens = tcore_at_tok_new(line);
2098 resp_str = g_slist_nth_data(tokens, 0);
2100 err("call end cause - report value missing");
2102 resp_str = g_slist_nth_data(tokens, 1);
2104 err("call end cause value missing");
2106 error = atoi(resp_str);
2107 dbg("call end cause - %d", error);
2108 call_status.cause = _compare_call_end_cause(error);
2109 dbg("TAPI call end cause - %d", call_status.cause);
2113 tcore_at_tok_free(tokens);
2115 err("RESPONSE NOT OK");
2116 line = (char *) response->final_response;
2117 tokens = tcore_at_tok_new(line);
2118 if (g_slist_length(tokens) < 1) {
2119 err("err cause not specified or string corrupted");
2121 err(" err cause value: %d", atoi(g_slist_nth_data(tokens, 0)));
2123 call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
2125 tcore_at_tok_free(tokens);
2128 call_status.type = tcore_call_object_get_type(co);
2129 dbg("data.type : [%d]", call_status.type);
2131 call_status.id = tcore_call_object_get_id(co);
2132 dbg("data.id : [%d]", call_status.id);
2135 tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
2137 // Send Notification to TAPI
2138 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
2140 TNOTI_CALL_STATUS_IDLE,
2141 sizeof(struct tnoti_call_status_idle),
2142 (void *) &call_status);
2145 tcore_call_object_free(core_obj, co);
2148 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
2150 // +CLCC: 1,0,2,0,0,"18005551212",145
2151 // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
2156 unsigned int num_type;
2157 GSList *tokens = NULL;
2162 tokens = tcore_at_tok_new(line);
2164 resp = g_slist_nth_data(tokens, 0);
2169 p_call->info.id = atoi(resp);
2170 dbg("id : [%d]\n", p_call->info.id);
2173 resp = g_slist_nth_data(tokens, 1);
2180 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
2182 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
2184 dbg("Direction : [ %d ]\n", p_call->info.direction);
2187 resp = g_slist_nth_data(tokens, 2);
2189 err("InValid Stat");
2193 dbg("Call state : %d", state);
2196 p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
2200 p_call->info.status = TCORE_CALL_STATUS_HELD;
2204 p_call->info.status = TCORE_CALL_STATUS_DIALING;
2208 p_call->info.status = TCORE_CALL_STATUS_ALERT;
2212 p_call->info.status = TCORE_CALL_STATUS_INCOMING;
2216 p_call->info.status = TCORE_CALL_STATUS_WAITING;
2219 dbg("Status : [%d]\n", p_call->info.status);
2222 resp = g_slist_nth_data(tokens, 3);
2224 err("InValid Mode");
2230 p_call->info.type = TCORE_CALL_TYPE_VOICE;
2234 p_call->info.type = TCORE_CALL_TYPE_VIDEO;
2237 default: // only Voice/VT call is supported in CS. treat other unknown calls as error
2238 dbg("invalid type : [%d]\n", mode);
2241 dbg("Call type : [%d]\n", p_call->info.type);
2244 resp = g_slist_nth_data(tokens, 4);
2246 err("InValid Mpty");
2250 p_call->info.mpty = atoi(resp);
2251 dbg("Mpty : [ %d ]\n", p_call->info.mpty);
2254 resp = g_slist_nth_data(tokens, 5);
2255 dbg("Incoming number - %s and its len - %d", resp, strlen(resp));
2257 // tolerate null here
2259 err("Number is NULL");
2262 // Strike off double quotes
2263 num = util_removeQuotes(resp);
2264 dbg("num after removing quotes - %s", num);
2266 p_call->info.num_len = strlen(resp);
2267 dbg("num_len : [0x%x]\n", p_call->info.num_len);
2270 resp = g_slist_nth_data(tokens, 6);
2272 dbg("InValid Num type");
2275 p_call->info.num_type = atoi(resp);
2276 dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
2278 // check number is international or national.
2279 num_type = ((p_call->info.num_type) >> 4) & 0x07;
2280 dbg("called party's type of number : [0x%x]\n", num_type);
2282 if (num_type == 1 && num[0] != '+') {
2283 // international number
2284 p_call->number[0] = '+';
2285 memcpy(&(p_call->number[1]), num, strlen(num));
2287 memcpy(&(p_call->number), num, strlen(num));
2289 dbg("incoming number - %s", p_call->number);
2294 tcore_at_tok_free(tokens);
2300 err("Invalid CLCC line");
2308 tcore_at_tok_free(tokens);
2314 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
2316 GSList *tokens = NULL;
2317 const char *line = NULL;
2321 GSList *pList = NULL;
2322 CallObject *co = NULL, *dupco = NULL;
2324 dbg("function entrance");
2325 // check call with waiting status already exist
2326 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
2328 if (pList != NULL) {
2329 dbg("[error]Waiting call already exist. skip");
2332 // check call with incoming status already exist
2333 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2335 if (pList != NULL) {
2336 dbg("[error]incoming call already exist. skip");
2339 line = (char *) data;
2340 tokens = tcore_at_tok_new(line);
2342 pId = g_slist_nth_data(tokens, 0);
2344 dbg("[error]:Call id is missing from +XCALLSTAT indication");
2345 tcore_at_tok_free(tokens);
2349 call_id = atoi(pId);
2350 dupco = tcore_call_object_find_by_id(o, call_id);
2351 if (dupco != NULL) {
2352 dbg("co with same id already exist. skip");
2353 tcore_at_tok_free(tokens);
2356 co = tcore_call_object_new(o, call_id);
2358 dbg("[ error ] co is NULL");
2359 tcore_at_tok_free(tokens);
2363 tcore_at_tok_free(tokens);
2365 eflag = g_new0(gboolean, 1);
2367 dbg("calling _call_list_get");
2368 _call_list_get(o, eflag);
2371 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
2373 GSList *tokens = NULL;
2374 const char *line = NULL;
2378 GSList *pList = NULL;
2379 CallObject *co = NULL, *dupco = NULL;
2381 dbg("function entrance");
2382 // check call with incoming status already exist
2383 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2385 if (pList != NULL) {
2386 dbg("incoming call already exist. skip");
2390 line = (char *) data;
2391 tokens = tcore_at_tok_new(line);
2393 pId = g_slist_nth_data(tokens, 0);
2395 dbg("Error:Call id is missing from %XCALLSTAT indication");
2396 tcore_at_tok_free(tokens);
2400 call_id = atoi(pId);
2402 dupco = tcore_call_object_find_by_id(o, call_id);
2403 if (dupco != NULL) {
2404 dbg("co with same id already exist. skip");
2405 tcore_at_tok_free(tokens);
2409 co = tcore_call_object_new(o, call_id);
2411 dbg("[ error ] co is NULL");
2412 tcore_at_tok_free(tokens);
2416 dbg("freeing at token")
2417 tcore_at_tok_free(tokens);
2419 eflag = g_new0(gboolean, 1);
2422 dbg("calling _call_list_get");
2423 _call_list_get(o, eflag);
2426 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
2429 TcorePlugin *plugin = NULL;
2430 CallObject *co = NULL;
2435 char *pCallId = NULL;
2436 GSList *tokens = NULL;
2437 gboolean *eflag = NULL;
2438 enum tcore_call_status co_status;
2440 dbg("function entrance");
2441 plugin = tcore_object_ref_plugin(o);
2442 cmd = (char *) data;
2443 tokens = tcore_at_tok_new(cmd);
2446 pCallId = g_slist_nth_data(tokens, 0);
2448 dbg("CallId is missing from %XCALLSTAT indication");
2449 tcore_at_tok_free(tokens);
2453 dbg("call id = %d", id);
2455 if ((stat = g_slist_nth_data(tokens, 1))) {
2456 status = atoi(stat);
2458 dbg("call status = %d", status);
2461 tcore_at_tok_free(tokens);
2462 co_status = _call_status(status);
2464 dbg("co_status = %d", co_status);
2465 switch (co_status) {
2466 case CALL_STATUS_ACTIVE:
2468 dbg("call(%d) status : [ ACTIVE ]", id);
2469 co = tcore_call_object_find_by_id(o, id);
2474 _call_status_active(plugin, co);
2478 case CALL_STATUS_HELD:
2479 dbg("call(%d) status : [ held ]", id);
2482 case CALL_STATUS_DIALING:
2484 dbg("call(%d) status : [ dialing ]", id);
2485 co = tcore_call_object_find_by_id(o, id);
2487 co = tcore_call_object_new(o, id);
2489 dbg("error : tcore_call_object_new [ id : %d ]", id);
2494 tcore_call_object_set_type(co, call_type(type));
2495 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
2496 _call_status_dialing(plugin, co);
2500 case CALL_STATUS_ALERT:
2502 dbg("call(%d) status : [ alert ]", id);
2503 co = tcore_call_object_find_by_id(o, id);
2508 // Store dialed number information into Call object.
2509 eflag = g_new0(gboolean, 1);
2511 dbg("calling _call_list_get");
2512 _call_list_get(o, eflag);
2516 case CALL_STATUS_INCOMING:
2517 case CALL_STATUS_WAITING:
2518 dbg("call(%d) status : [ incoming ]", id);
2521 case CALL_STATUS_IDLE:
2523 dbg("call(%d) status : [ release ]", id);
2525 co = tcore_call_object_find_by_id(o, id);
2531 plugin = tcore_object_ref_plugin(o);
2533 dbg("plugin is NULL");
2536 _call_status_idle(plugin, co);
2541 dbg("invalid call status", id);
2546 static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
2548 struct treq_call_dial *data = 0;
2549 char *raw_str = NULL;
2550 char *cmd_str = NULL;
2552 enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
2553 TcorePending *pending = NULL;
2554 TcoreATRequest *req;
2555 gboolean ret = FALSE;
2557 dbg("function entrance");
2559 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2560 dbg("cp not ready/n");
2561 return TCORE_RETURN_ENOSYS;
2564 data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
2565 if (data->type == CALL_TYPE_VIDEO) {
2566 dbg("invalid call type")
2567 return TCORE_RETURN_FAILURE;
2570 clir = _get_clir_status(data->number);
2572 // Compose ATD Cmd string
2574 case TCORE_CALL_CLI_MODE_PRESENT:
2575 dbg("CALL_CLI_MODE_PRESENT");
2577 break; // invocation
2579 case TCORE_CALL_CLI_MODE_RESTRICT:
2580 dbg("CALL_CLI_MODE_RESTRICT");
2582 break; // suppression
2584 case TCORE_CALL_CLI_MODE_DEFAULT:
2587 dbg("CALL_CLI_MODE_DEFAULT");
2588 break; // subscription default
2591 dbg("data->number = %s", data->number);
2593 raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
2594 cmd_str = g_strdup_printf("%s", raw_str);
2596 dbg("request command : %s", cmd_str);
2598 pending = tcore_pending_new(o, 0);
2599 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2600 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2602 tcore_pending_set_request_data(pending, 0, req);
2603 ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
2609 dbg("AT request(%s) sent failed", req->cmd);
2610 return TCORE_RETURN_FAILURE;
2613 dbg("AT request(%s) sent success", req->cmd);
2615 return TCORE_RETURN_SUCCESS;
2618 static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
2620 char *cmd_str = NULL;
2621 CallObject *co = NULL;
2622 struct treq_call_answer *data = 0;
2623 TcorePending *pending = NULL;
2624 TcoreATRequest *req;
2625 gboolean ret = FALSE;
2627 dbg("function entrance");
2629 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2630 dbg("cp not ready/n");
2631 return TCORE_RETURN_ENOSYS;
2634 data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
2635 co = tcore_call_object_find_by_id(o, data->id);
2636 if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
2637 dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
2639 cmd_str = g_strdup_printf("%s", "ATA");
2640 pending = tcore_pending_new(o, 0);
2641 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2642 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2644 tcore_pending_set_request_data(pending, 0, req);
2645 ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
2649 dbg("AT request(%s) sent failed", req->cmd);
2650 return TCORE_RETURN_FAILURE;
2653 switch (data->type) {
2654 case CALL_ANSWER_TYPE_REJECT:
2656 dbg("call answer reject");
2657 tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
2661 case CALL_ANSWER_TYPE_REPLACE:
2663 dbg("call answer replace");
2664 tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
2668 case CALL_ANSWER_TYPE_HOLD_ACCEPT:
2670 dbg("call answer hold and accept");
2671 tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
2676 dbg("[ error ] wrong answer type [ %d ]", data->type);
2677 return TCORE_RETURN_FAILURE;
2681 return TCORE_RETURN_SUCCESS;
2684 static TReturn s_call_release(CoreObject *o, UserRequest *ur)
2686 CallObject *co = NULL;
2687 struct treq_call_end *data = 0;
2688 UserRequest *ur_dup = NULL;
2689 char *chld0_cmd = NULL;
2690 char *chld1_cmd = NULL;
2691 TcorePending *pending = NULL, *pending1 = NULL;
2692 TcoreATRequest *req, *req1;
2693 gboolean ret = FALSE;
2695 dbg("function entrance");
2696 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2697 dbg("cp not ready/n");
2698 return TCORE_RETURN_ENOSYS;
2700 data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
2701 co = tcore_call_object_find_by_id(o, data->id);
2703 dbg("type of release call = %d", data->type);
2705 if (data->type == CALL_END_TYPE_ALL) {
2706 // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
2707 chld0_cmd = g_strdup("AT+CHLD=0");
2708 chld1_cmd = g_strdup("AT+CHLD=1");
2710 pending = tcore_pending_new(o, 0);
2711 req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
2713 dbg("input command is %s", chld0_cmd);
2714 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2716 tcore_pending_set_request_data(pending, 0, req);
2717 ur_dup = tcore_user_request_new(NULL, NULL);
2718 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
2722 dbg("AT request %s has failed ", req->cmd);
2724 tcore_user_request_free(ur_dup);
2728 return TCORE_RETURN_FAILURE;
2731 pending1 = tcore_pending_new(o, 0);
2732 req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
2734 dbg("input command is %s", chld1_cmd);
2735 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2737 tcore_pending_set_request_data(pending1, 0, req1);
2738 ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
2742 dbg("AT request %s has failed ", req->cmd);
2743 return TCORE_RETURN_FAILURE;
2746 switch (data->type) {
2747 case CALL_END_TYPE_DEFAULT:
2750 id = tcore_call_object_get_id(co);
2752 dbg("call end call id [%d]", id);
2753 tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
2757 case CALL_END_TYPE_ACTIVE_ALL:
2759 dbg("call end all active");
2760 tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
2764 case CALL_END_TYPE_HOLD_ALL:
2766 dbg("call end all held");
2767 tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
2772 dbg("[ error ] wrong end type [ %d ]", data->type);
2773 return TCORE_RETURN_FAILURE;
2777 return TCORE_RETURN_SUCCESS;
2780 static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
2782 struct treq_call_hold *hold = 0;
2783 CallObject *co = NULL;
2785 dbg("function entrance");
2787 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2788 dbg("cp not ready/n");
2789 return TCORE_RETURN_ENOSYS;
2792 hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
2793 dbg("call id : [ %d ]", hold->id);
2795 co = tcore_call_object_find_by_id(o, hold->id);
2796 tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
2798 return TCORE_RETURN_SUCCESS;
2801 static TReturn s_call_active(CoreObject *o, UserRequest *ur)
2803 struct treq_call_active *active = 0;
2804 CallObject *co = NULL;
2806 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2807 dbg("cp not ready/n");
2808 return TCORE_RETURN_ENOSYS;
2811 active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
2812 dbg("call id : [ %d ]", active->id);
2814 co = tcore_call_object_find_by_id(o, active->id);
2815 tcore_call_control_active(o, ur, on_confirmation_call_active, co);
2817 return TCORE_RETURN_SUCCESS;
2820 static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
2822 struct treq_call_swap *swap = NULL;
2823 CallObject *co = NULL;
2825 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2826 dbg("cp not ready/n");
2827 return TCORE_RETURN_ENOSYS;
2830 swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
2831 dbg("call id : [ %d ]", swap->id);
2833 co = tcore_call_object_find_by_id(o, swap->id);
2834 tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
2836 return TCORE_RETURN_SUCCESS;
2839 static TReturn s_call_join(CoreObject *o, UserRequest *ur)
2841 struct treq_call_join *join = 0;
2842 CallObject *co = NULL;
2844 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2845 dbg("cp not ready/n");
2846 return TCORE_RETURN_ENOSYS;
2849 join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
2850 dbg("call id : [ %d ]", join->id);
2852 co = tcore_call_object_find_by_id(o, join->id);
2853 tcore_call_control_join(o, ur, on_confirmation_call_join, co);
2855 return TCORE_RETURN_SUCCESS;
2858 static TReturn s_call_split(CoreObject *o, UserRequest *ur)
2860 struct treq_call_split *split = 0;
2861 CallObject *co = NULL;
2863 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2864 dbg("cp not ready/n");
2865 return TCORE_RETURN_ENOSYS;
2868 split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
2869 co = tcore_call_object_find_by_id(o, split->id);
2870 dbg("call id : [ %d ]", split->id);
2872 tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
2874 return TCORE_RETURN_SUCCESS;
2877 static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
2879 struct treq_call_deflect *deflect = 0;
2880 CallObject *co = NULL;
2882 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2883 dbg("cp not ready/n");
2884 return TCORE_RETURN_ENOSYS;
2887 deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
2888 co = tcore_call_object_find_by_number(o, deflect->number);
2889 dbg("deflect number: [ %s ]", deflect->number);
2891 tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
2893 return TCORE_RETURN_SUCCESS;
2896 static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
2898 struct treq_call_transfer *transfer = 0;
2899 CallObject *co = NULL;
2901 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2902 dbg("cp not ready/n");
2903 return TCORE_RETURN_ENOSYS;
2906 transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
2907 dbg("call id : [ %d ]", transfer->id);
2909 co = tcore_call_object_find_by_id(o, transfer->id);
2910 tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
2912 return TCORE_RETURN_SUCCESS;
2915 static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
2917 char *cmd_str = NULL;
2918 TcorePending *pending = NULL;
2919 TcoreATRequest *req;
2921 gboolean ret = FALSE;
2922 struct treq_call_dtmf *dtmf = 0;
2923 char *dtmfstr = NULL, *tmp_dtmf = NULL;
2924 unsigned int dtmf_count;
2926 dbg("Function enter");
2928 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2929 dbg("cp not ready/n");
2930 return TCORE_RETURN_ENOSYS;
2933 dup = tcore_user_request_new(NULL, NULL);
2934 (void) _set_dtmf_tone_duration(o, dup);
2936 dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
2937 dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1); // DTMF digits + comma for each dtmf digit.
2939 if (dtmfstr == NULL) {
2940 dbg("Memory allocation failed");
2941 return TCORE_RETURN_FAILURE;
2946 for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
2947 *tmp_dtmf = dtmf->digits[dtmf_count];
2954 // last digit is having COMMA , overwrite it with '\0' .
2955 *(--tmp_dtmf) = '\0';
2956 dbg("Input DTMF string(%s)", dtmfstr);
2958 // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
2959 cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
2960 dbg("request command : %s", cmd_str);
2962 pending = tcore_pending_new(o, 0);
2963 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2964 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2966 tcore_pending_set_request_data(pending, 0, req);
2967 ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
2972 dbg("AT request sent failed")
2973 return TCORE_RETURN_FAILURE;
2976 return TCORE_RETURN_SUCCESS;
2979 static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
2981 UserRequest *ur_dup = NULL;
2982 TcorePending *pending = NULL, *pending1 = NULL;
2983 TcoreATRequest *req, *req1;
2984 char *cmd_str = NULL, *cmd_str1 = NULL;
2985 int device_type = -1;
2986 struct treq_call_sound_set_path *sound_path = 0;
2987 gboolean ret = FALSE;
2989 dbg("function entrance");
2991 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2992 dbg("cp not ready/n");
2993 return TCORE_RETURN_ENOSYS;
2995 sound_path = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
2996 if (sound_path == NULL) {
2997 dbg("invaling user request");
2998 return TCORE_RETURN_FAILURE;
3000 dbg("audio device type - 0x%x", sound_path->path);
3001 switch (sound_path->path) {
3002 case CALL_SOUND_PATH_HANDSET:
3006 case CALL_SOUND_PATH_HEADSET:
3010 case CALL_SOUND_PATH_HEADSET_3_5PI:
3014 case CALL_SOUND_PATH_SPEAKER:
3018 case CALL_SOUND_PATH_HANDFREE:
3022 case CALL_SOUND_PATH_HEADSET_HAC:
3026 case CALL_SOUND_PATH_BLUETOOTH:
3027 case CALL_SOUND_PATH_STEREO_BLUETOOTH:
3031 case CALL_SOUND_PATH_BT_NSEC_OFF:
3032 case CALL_SOUND_PATH_MIC1:
3033 case CALL_SOUND_PATH_MIC2:
3035 dbg("unsupported device type");
3036 return TCORE_RETURN_FAILURE;
3039 cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
3040 pending = tcore_pending_new(o, 0);
3041 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3042 dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3043 tcore_pending_set_request_data(pending, 0, req);
3044 ur_dup = tcore_user_request_ref(ur);
3045 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
3049 dbg("At request(%s) sent failed", req->cmd);
3050 return TCORE_RETURN_FAILURE;
3053 cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
3054 pending1 = tcore_pending_new(o, 0);
3055 req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
3056 dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
3057 tcore_pending_set_request_data(pending1, 0, req1);
3058 ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
3062 dbg("AT request %s has failed ", req1->cmd);
3063 return TCORE_RETURN_FAILURE;
3066 return TCORE_RETURN_SUCCESS;
3069 static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
3071 UserRequest *src_ur = NULL;
3072 UserRequest *dest_ur = NULL;
3073 TcorePending *src_pending = NULL;
3074 TcorePending *dest_pending = NULL;
3075 TcoreATRequest *src_req = NULL;
3076 TcoreATRequest *dest_req = NULL;
3077 char *cmd_str = NULL, *volume_level = NULL;
3078 gboolean ret = FALSE;
3079 struct treq_call_sound_set_volume_level *data = NULL;
3083 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3084 dbg("cp not ready/n");
3085 return TCORE_RETURN_ENOSYS;
3088 data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
3090 // Hard-coded values for MIC & Speakers
3092 dbg("Set Source volume");
3094 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source type
3095 dbg("Request command string: %s", cmd_str);
3097 // Create new Pending request
3098 src_pending = tcore_pending_new(o, 0);
3100 // Create new AT-Command request
3101 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3102 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3104 // Free Command string
3107 tcore_pending_set_request_data(src_pending, 0, src_req);
3108 src_ur = tcore_user_request_ref(ur);
3111 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3113 err("Failed to send AT-Command request");
3114 return TCORE_RETURN_FAILURE;
3117 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type
3118 dbg("Request command string: %s", cmd_str);
3120 // Create new Pending request
3121 src_pending = tcore_pending_new(o, 0);
3123 // Create new AT-Command request
3124 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3125 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3127 // Free Command string
3130 tcore_pending_set_request_data(src_pending, 0, src_req);
3132 src_ur = tcore_user_request_ref(ur);
3135 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3137 err("Failed to send AT-Command request");
3138 return TCORE_RETURN_FAILURE;
3141 // Destination volume
3142 dbg("Set Source volume");
3144 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type
3145 dbg("Request command string: %s", cmd_str);
3147 // Create new Pending request
3148 dest_pending = tcore_pending_new(o, 0);
3150 // Create new AT-Command request
3151 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3152 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3154 // Free Command string
3157 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3158 dest_ur = tcore_user_request_ref(ur);
3161 ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3163 err("Failed to send AT-Command request");
3164 return TCORE_RETURN_FAILURE;
3167 dbg("Input volume level - %d", data->volume);
3168 switch (data->volume) {
3169 case CALL_SOUND_MUTE:
3173 case CALL_SOUND_VOLUME_LEVEL_1:
3174 volume_level = "40";
3177 case CALL_SOUND_VOLUME_LEVEL_2:
3178 volume_level = "46";
3181 case CALL_SOUND_VOLUME_LEVEL_3:
3182 volume_level = "52";
3185 case CALL_SOUND_VOLUME_LEVEL_4:
3186 volume_level = "58";
3189 case CALL_SOUND_VOLUME_LEVEL_5:
3190 volume_level = "64";
3193 case CALL_SOUND_VOLUME_LEVEL_6:
3194 volume_level = "70";
3197 case CALL_SOUND_VOLUME_LEVEL_7:
3198 volume_level = "76";
3201 case CALL_SOUND_VOLUME_LEVEL_8:
3202 volume_level = "82";
3205 case CALL_SOUND_VOLUME_LEVEL_9:
3207 volume_level = "88";
3210 cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level); // Destination type
3211 dbg("Request command string: %s", cmd_str);
3213 // Create new Pending request
3214 dest_pending = tcore_pending_new(o, 0);
3216 // Create new AT-Command request
3217 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3218 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3220 // Free Command string
3223 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3226 ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
3228 err("Failed to send AT-Command request");
3229 return TCORE_RETURN_FAILURE;
3232 return TCORE_RETURN_SUCCESS;
3236 static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
3241 return TCORE_RETURN_SUCCESS;
3244 static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
3246 char *cmd_str = NULL;
3247 TcorePending *pending = NULL;
3248 TcoreATRequest *req = NULL;
3249 gboolean ret = FALSE;
3253 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3254 dbg("cp not ready/n");
3255 return TCORE_RETURN_ENOSYS;
3258 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
3260 dbg("Request command string: %s", cmd_str);
3262 // Create new Pending request
3263 pending = tcore_pending_new(o, 0);
3265 // Create new AT-Command request
3266 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3267 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3269 // Free command string
3272 // Set request data (AT command) to Pending request
3273 tcore_pending_set_request_data(pending, 0, req);
3276 ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
3278 err("Failed to send AT-Command request");
3279 return TCORE_RETURN_FAILURE;
3283 return TCORE_RETURN_SUCCESS;
3286 static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
3288 char *cmd_str = NULL;
3289 TcorePending *pending = NULL;
3290 TcoreATRequest *req = NULL;
3291 gboolean ret = FALSE;
3295 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3296 dbg("cp not ready/n");
3297 return TCORE_RETURN_ENOSYS;
3300 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
3301 dbg("Request command string: %s", cmd_str);
3303 // Create new Pending request
3304 pending = tcore_pending_new(o, 0);
3306 // Create new AT-Command request
3307 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3308 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3310 // Free command string
3313 // Set request data (AT command) to Pending request
3314 tcore_pending_set_request_data(pending, 0, req);
3317 ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
3319 err("Failed to send AT-Command request");
3320 return TCORE_RETURN_FAILURE;
3324 return TCORE_RETURN_SUCCESS;
3328 static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
3333 return TCORE_RETURN_SUCCESS;
3336 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
3338 char *cmd_str = NULL;
3339 TcorePending *pending = NULL;
3340 TcoreATRequest *req = NULL;
3341 gboolean ret = FALSE;
3345 cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.
3346 dbg("Request command string: %s", cmd_str);
3348 // Create new Pending request
3349 pending = tcore_pending_new(o, 0);
3351 // Create new AT-Command request
3352 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3353 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3355 // Free command string */
3358 // Set request data (AT command) to Pending request
3359 tcore_pending_set_request_data(pending, 0, req);
3362 ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
3364 err("Failed to send AT-Command request");
3366 tcore_user_request_free(ur);
3369 return TCORE_RETURN_FAILURE;
3373 return TCORE_RETURN_SUCCESS;
3377 static struct tcore_call_operations call_ops = {
3378 .dial = s_call_outgoing,
3379 .answer = s_call_answer,
3380 .end = s_call_release,
3381 .hold = s_call_hold,
3382 .active = s_call_active,
3383 .swap = s_call_swap,
3384 .join = s_call_join,
3385 .split = s_call_split,
3386 .deflect = s_call_deflect,
3387 .transfer = s_call_transfer,
3388 .send_dtmf = s_call_send_dtmf,
3389 .set_sound_path = s_call_set_sound_path,
3390 .set_sound_volume_level = s_call_set_sound_volume_level,
3391 .get_sound_volume_level = s_call_get_sound_volume_level,
3392 .mute = s_call_mute,
3393 .unmute = s_call_unmute,
3394 .get_mute_status = s_call_get_mute_status,
3395 .set_sound_recording = NULL,
3396 .set_sound_equalization = NULL,
3397 .set_sound_noise_reduction = NULL,
3400 gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call)
3404 tcore_call_override_ops(co_call, &call_ops, NULL);
3407 tcore_object_override_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
3408 tcore_object_override_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
3415 void s_call_exit(TcorePlugin *cp, CoreObject *co_call)