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 call_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
785 TcoreATRequest *req = NULL;
786 TcoreHal *hal = NULL;
787 TcorePending *pending = NULL;
790 hal = tcore_object_get_hal(co);
793 pending = tcore_pending_new(co, 0);
795 dbg("Pending is NULL");
796 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
798 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
800 tcore_pending_set_request_data(pending, 0, req);
801 tcore_pending_set_response_callback(pending, callback, NULL);
802 tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
803 ret = tcore_hal_send_request(hal, pending);
806 static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
808 UserRequest *ur = NULL;
809 GSList *tokens = NULL;
810 const char *line = NULL;
811 const TcoreATResponse *response = data;
812 struct tresp_call_dial resp;
813 enum telephony_call_error error;
816 ur = tcore_pending_ref_user_request(p);
818 if (response->success > 0) {
820 resp.err = CALL_ERROR_NONE;
822 dbg("RESPONSE NOT OK");
824 line = (const char *) response->final_response;
825 tokens = tcore_at_tok_new(line);
827 if (g_slist_length(tokens) < 1) {
828 err("Unspecified error cause OR string corrupted");
829 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
831 error = atoi(g_slist_nth_data(tokens, 0));
833 // TODO: CMEE error mapping is required.
834 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
838 tcore_at_tok_free(tokens);
841 // Send Response to TAPI
842 tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
844 err("User Request is NULL");
851 static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)
853 UserRequest *ur = NULL;
854 GSList *tokens = NULL;
855 const char *line = NULL;
856 const TcoreATResponse *response = data;
857 struct tresp_call_answer resp;
858 enum telephony_call_error error;
861 ur = tcore_pending_ref_user_request(p);
863 if (response->success > 0) {
865 resp.err = CALL_ERROR_NONE;
867 dbg("RESPONSE NOT OK");
869 line = (const char *) response->final_response;
870 tokens = tcore_at_tok_new(line);
872 if (g_slist_length(tokens) < 1) {
873 err("Unspecified error cause OR string corrupted");
874 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
876 error = atoi(g_slist_nth_data(tokens, 0));
878 // TODO: CMEE error mapping is required.
879 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
883 tcore_at_tok_free(tokens);
886 resp.id = tcore_call_object_get_id((CallObject *) user_data);
888 // Send Response to TAPI
889 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
891 err("User Request is NULL");
899 static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)
901 UserRequest *ur = NULL;
902 GSList *tokens = NULL;
903 const char *line = NULL;
904 const TcoreATResponse *response = data;
905 struct tresp_call_answer resp;
906 enum telephony_call_error error;
910 ur = tcore_pending_ref_user_request(p);
912 if (response->success > 0) {
914 resp.err = CALL_ERROR_NONE;
916 dbg("RESPONSE NOT OK");
917 line = (const char *) response->final_response;
918 tokens = tcore_at_tok_new(line);
920 if (g_slist_length(tokens) < 1) {
921 err("Unspecified error cause OR string corrupted");
922 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
924 error = atoi(g_slist_nth_data(tokens, 0));
925 // TODO: CMEE error mapping is required.
926 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
930 tcore_at_tok_free(tokens);
933 resp.id = tcore_call_object_get_id((CallObject *) user_data);
935 // Send Response to TAPI
936 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
938 err("User Request is NULL");
945 static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)
947 UserRequest *ur = NULL;
948 GSList *tokens = NULL;
949 const char *line = NULL;
950 const TcoreATResponse *response = data;
951 struct tresp_call_answer resp;
952 enum telephony_call_error error;
955 ur = tcore_pending_ref_user_request(p);
957 if (response->success > 0) {
959 resp.err = CALL_ERROR_NONE;
961 dbg("RESPONSE NOT OK");
962 line = (const char *) response->final_response;
963 tokens = tcore_at_tok_new(line);
965 if (g_slist_length(tokens) < 1) {
966 err("Unspecified error cause OR string corrupted");
967 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
969 error = atoi(g_slist_nth_data(tokens, 0));
970 // TODO: CMEE error mapping is required.
971 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
975 tcore_at_tok_free(tokens);
977 resp.id = tcore_call_object_get_id((CallObject *) user_data);
979 // Send Response to TAPI
980 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
982 dbg("User Request is NULL");
989 static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)
991 CoreObject *o = NULL;
992 UserRequest *ur = NULL;
993 GSList *tokens = NULL;
994 const char *line = NULL;
995 const TcoreATResponse *response = data;
996 struct tresp_call_answer resp;
997 enum telephony_call_error error;
1001 o = tcore_pending_ref_core_object(p);
1002 ur = tcore_pending_ref_user_request(p);
1003 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1006 if (response->success > 0) {
1008 resp.err = CALL_ERROR_NONE;
1010 err("RESPONSE NOT OK");
1011 line = (const char *) response->final_response;
1012 tokens = tcore_at_tok_new(line);
1014 if (g_slist_length(tokens) < 1) {
1015 err("Unspecified error cause OR string corrupted");
1016 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1018 error = atoi(g_slist_nth_data(tokens, 0));
1020 // TODO: CMEE error mapping is required.
1021 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1025 tcore_at_tok_free(tokens);
1028 // Send response to TAPI
1029 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
1032 CallObject *co = NULL;
1035 list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
1037 err("Can't find active Call");
1041 co = (CallObject *) list->data;
1043 err("Can't get active Call object");
1048 tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
1049 dbg("Call status is set to HELD");
1052 err("User Request is NULL");
1059 static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1061 UserRequest *ur = NULL;
1062 struct tresp_call_end resp;
1063 GSList *tokens = NULL;
1064 const char *line = NULL;
1065 enum telephony_call_error error;
1066 const TcoreATResponse *response = data;
1069 ur = tcore_pending_ref_user_request(p);
1071 if (response->success > 0) {
1073 resp.err = CALL_ERROR_NONE;
1075 err("RESPONSE NOT OK");
1077 line = (const char *) response->final_response;
1078 tokens = tcore_at_tok_new(line);
1080 if (g_slist_length(tokens) < 1) {
1081 err("Unspecified error cause OR string corrupted");
1082 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1084 error = atoi(g_slist_nth_data(tokens, 0));
1086 // TODO: CMEE error mapping is required.
1087 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1089 tcore_at_tok_free(tokens);
1093 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1094 dbg("resp.type = %d resp.id= %d", resp.type, resp.id);
1096 // Send reponse to TAPI
1097 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
1099 err("User Request is NULL");
1107 static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)
1109 // skip response handling - actual result will be handled in on_confirmation_call_release_all
1110 const TcoreATResponse *response = data;
1114 if (response->success > 0) {
1117 err("RESPONSE NOT OK");
1125 static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)
1128 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);
1134 static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)
1137 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);
1142 static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)
1145 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);
1150 static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)
1153 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);
1158 static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1160 UserRequest *ur = NULL;
1161 GSList *tokens = NULL;
1162 const char *line = NULL;
1163 const TcoreATResponse *response = NULL;
1164 enum telephony_call_error error;
1167 ur = tcore_pending_ref_user_request(p);
1168 response = (TcoreATResponse *) data;
1169 if (response->success > 0) {
1171 error = CALL_ERROR_NONE;
1173 err("RESPONSE NOT OK");
1175 line = (const char *) response->final_response;
1176 tokens = tcore_at_tok_new(line);
1178 if (g_slist_length(tokens) < 1) {
1179 err("Unspecified error cause OR string corrupted");
1180 error = CALL_ERROR_SERVICE_UNAVAIL;
1182 error = atoi(g_slist_nth_data(tokens, 0));
1184 // TODO: CMEE error mapping is required.
1185 error = CALL_ERROR_SERVICE_UNAVAIL;
1189 tcore_at_tok_free(tokens);
1192 dbg("Response Call type -%d", type);
1194 case TRESP_CALL_HOLD:
1196 struct tresp_call_hold resp;
1199 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1200 dbg("call hold response");
1201 // Send reponse to TAPI
1202 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1206 case TRESP_CALL_ACTIVE:
1208 struct tresp_call_active resp;
1211 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1212 dbg("call active response");
1213 // Send reponse to TAPI
1214 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1218 case TRESP_CALL_JOIN:
1220 struct tresp_call_join resp;
1223 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1224 dbg("call join response");
1226 // Send reponse to TAPI
1227 tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
1231 case TRESP_CALL_SPLIT:
1233 struct tresp_call_split resp;
1236 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1237 dbg("call split response");
1238 // Send reponse to TAPI
1239 tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
1243 case TRESP_CALL_DEFLECT:
1245 struct tresp_call_deflect resp;
1248 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1249 dbg("call deflect response");
1250 // Send reponse to TAPI
1251 tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
1256 case TRESP_CALL_TRANSFER:
1258 struct tresp_call_transfer resp;
1261 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1262 dbg("call transfer response");
1263 // Send reponse to TAPI
1264 tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
1268 case TRESP_CALL_SEND_DTMF:
1270 struct tresp_call_dtmf resp;
1273 dbg("call dtmf response");
1274 // Send reponse to TAPI
1275 tcore_user_request_send_response(ur, TRESP_CALL_SEND_DTMF, sizeof(struct tresp_call_dtmf), &resp);
1281 dbg("type not supported");
1286 if ((type == TRESP_CALL_HOLD) || (type == TRESP_CALL_ACTIVE) || (type == TRESP_CALL_JOIN)
1287 || (type == TRESP_CALL_SPLIT)) {
1289 CoreObject *core_obj = NULL;
1290 gboolean *eflag = g_new0(gboolean, 1);
1292 core_obj = tcore_pending_ref_core_object(p);
1295 dbg("Calling _call_list_get");
1296 _call_list_get(core_obj, eflag);
1304 static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)
1307 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);
1312 static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)
1315 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);
1320 static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)
1323 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);
1328 static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)
1331 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);
1336 static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)
1339 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);
1344 static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)
1347 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);
1352 static void on_confirmation_call_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
1355 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SEND_DTMF);
1360 static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data)
1362 GSList *tokens = NULL;
1363 const char *line = NULL;
1364 const TcoreATResponse *response = data;
1365 enum telephony_call_error error;
1369 if (response->success > 0) {
1371 error = CALL_ERROR_NONE;
1373 err("RESPONSE NOT OK");
1374 line = (const char *) response->final_response;
1375 tokens = tcore_at_tok_new(line);
1376 if (g_slist_length(tokens) < 1) {
1377 err("err cause not specified or string corrupted");
1378 error = CALL_ERROR_SERVICE_UNAVAIL;
1380 error = atoi(g_slist_nth_data(tokens, 0));
1381 // TODO: CMEE error mapping is required.
1385 tcore_at_tok_free(tokens);
1388 dbg("Set dtmf tone duration response - %d", error);
1392 static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
1394 CoreObject *core_obj = NULL;
1395 UserRequest *ur = NULL;
1396 const TcoreATResponse *response = data;
1397 struct tresp_call_swap resp;
1398 GSList *tokens = NULL;
1399 const char *line = NULL;
1402 core_obj = tcore_pending_ref_core_object(p);
1403 ur = tcore_pending_ref_user_request(p);
1406 if (response->success > 0) {
1408 resp.err = CALL_ERROR_NONE;
1410 err("RESPONSE NOT OK");
1411 line = (const char *) response->final_response;
1412 tokens = tcore_at_tok_new(line);
1413 if (g_slist_length(tokens) < 1) {
1414 err("err cause not specified or string corrupted");
1415 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1417 resp.err = atoi(g_slist_nth_data(tokens, 0));
1419 // TODO: CMEE error mapping is required.
1420 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1424 tcore_at_tok_free(tokens);
1427 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1428 dbg("resp.id = %d", resp.id);
1430 // Send response to TAPI
1431 tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
1434 GSList *active = NULL;
1435 GSList *held = NULL;
1436 CallObject *co = NULL;
1437 gboolean *eflag = NULL;
1439 held = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_HELD);
1441 err("Can't find held Call");
1445 active = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_ACTIVE);
1447 dbg("Can't find active Call");
1452 co = (CallObject *) held->data;
1454 err("Can't get held Call object");
1458 resp.id = tcore_call_object_get_id(co);
1460 // Send response to TAPI
1461 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1463 held = g_slist_next(held);
1467 co = (CallObject *) active->data;
1469 err("[ error ] can't get active call object");
1473 resp.id = tcore_call_object_get_id(co);
1475 // Send response to TAPI
1476 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1477 active = g_slist_next(active);
1480 eflag = g_new0(gboolean, 1);
1483 dbg("calling _call_list_get");
1484 _call_list_get(core_obj, eflag);
1487 err("User Request is NULL");
1494 static void on_confirmation_set_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1496 const TcoreATResponse *resp = data;
1497 struct tnoti_call_sound_path *snd_path = user_data;
1498 TcorePlugin *plugin = tcore_pending_ref_plugin(p);
1500 if (resp->success > 0) {
1501 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
1502 tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL),
1503 TNOTI_CALL_SOUND_PATH,
1504 sizeof(struct tnoti_call_sound_path),
1507 dbg("Error in set sound path");
1511 static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1513 UserRequest *ur = NULL;
1514 GSList *tokens = NULL;
1515 const char *line = NULL;
1516 const TcoreATResponse *response = data;
1517 char *resp_str = NULL;
1518 struct tresp_call_sound_set_path resp;
1522 ur = tcore_pending_ref_user_request(p);
1524 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1526 err("Input data is NULL");
1530 if (response->success > 0) {
1533 line = (const char *) (((GSList *) response->lines)->data);
1534 tokens = tcore_at_tok_new(line);
1536 resp_str = g_slist_nth_data(tokens, 0);
1537 if (!g_slist_nth_data(tokens, 0)) {
1538 err("group_id is missing");
1543 if (!g_slist_nth_data(tokens, 1)) {
1544 err(" function_id is missing");
1549 resp_str = g_slist_nth_data(tokens, 2);
1552 error = atoi(resp_str);
1554 dbg("Response is Success");
1562 tcore_at_tok_free(tokens);
1564 dbg("RESPONSE NOT OK");
1566 line = (const char *) response->final_response;
1567 tokens = tcore_at_tok_new(line);
1569 if (g_slist_length(tokens) < 1) {
1570 err("err cause not specified or string corrupted");
1573 error = atoi(g_slist_nth_data(tokens, 0));
1575 // TODO: CMEE error mapping is required.
1580 tcore_at_tok_free(tokens);
1584 if ( resp.err ) { // Send only failed notification . success notification send when destination device is set.
1585 // Send notification to TAPI
1586 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1587 setsoundpath = TRUE;
1590 err("User Request is NULL");
1597 static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1599 UserRequest *ur = NULL;
1600 GSList *tokens = NULL;
1601 const char *line = NULL;
1602 char *resp_str = NULL;
1603 struct tresp_call_sound_set_path resp;
1604 const TcoreATResponse *response = data;
1609 ur = tcore_pending_ref_user_request(p);
1610 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1613 err("Input data is NULL");
1618 if (response->success > 0) {
1621 line = (const char *) (((GSList *) response->lines)->data);
1622 tokens = tcore_at_tok_new(line);
1624 resp_str = g_slist_nth_data(tokens, 0);
1625 if (!g_slist_nth_data(tokens, 0)) {
1626 dbg("group_id is missing");
1631 if (!g_slist_nth_data(tokens, 1)) {
1632 dbg("function_id is missing");
1637 resp_str = g_slist_nth_data(tokens, 2);
1639 error = atoi(resp_str);
1641 dbg("Response is Success");
1650 tcore_at_tok_free(tokens);
1652 dbg("RESPONSE NOT OK");
1654 line = (const char *) response->final_response;
1655 tokens = tcore_at_tok_new(line);
1657 if (g_slist_length(tokens) < 1) {
1658 err("err cause not specified or string corrupted");
1661 error = atoi(g_slist_nth_data(tokens, 0));
1662 // TODO: CMEE error mapping is required.
1667 tcore_at_tok_free(tokens);
1670 if (setsoundpath == TRUE) {
1671 setsoundpath = FALSE;
1673 // Send response to TAPI
1674 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1677 dbg("User Request is NULL");
1684 static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1686 UserRequest *ur = NULL;
1687 GSList *tokens = NULL;
1688 const char *line = NULL;
1689 const TcoreATResponse *response = data;
1690 char *resp_str = NULL;
1691 struct tresp_call_sound_set_volume_level resp;
1694 ur = tcore_pending_ref_user_request(p);
1696 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1698 err("Input data is NULL");
1702 if (response->success > 0) {
1705 line = (const char *) (((GSList *) response->lines)->data);
1706 tokens = tcore_at_tok_new(line);
1708 resp_str = g_slist_nth_data(tokens, 0);
1709 if (!g_slist_nth_data(tokens, 0)) {
1710 err("group_id is missing");
1715 if (!g_slist_nth_data(tokens, 1)) {
1716 err("function_id is missing");
1721 resp_str = g_slist_nth_data(tokens, 2);
1723 error = atoi(resp_str);
1726 dbg("Response is Success ");
1735 tcore_at_tok_free(tokens);
1737 dbg("RESPONSE NOT OK");
1739 line = (const char *) response->final_response;
1740 tokens = tcore_at_tok_new(line);
1742 if (g_slist_length(tokens) < 1) {
1743 err("err cause not specified or string corrupted");
1746 error = atoi(g_slist_nth_data(tokens, 0));
1748 // TODO: CMEE error mapping is required.
1753 tcore_at_tok_free(tokens);
1757 if (resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.
1758 // Send reposne to TAPI
1759 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1763 err("User Request is NULL");
1771 static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1773 UserRequest *ur = NULL;
1774 GSList *tokens = NULL;
1775 const char *line = NULL;
1776 char *resp_str = NULL;
1777 const TcoreATResponse *response = data;
1778 struct tresp_call_sound_set_volume_level resp;
1783 ur = tcore_pending_ref_user_request(p);
1785 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1787 err("Input data is NULL");
1792 if (response->success > 0) {
1794 line = (const char *) (((GSList *) response->lines)->data);
1795 tokens = tcore_at_tok_new(line);
1796 resp_str = g_slist_nth_data(tokens, 0);
1798 if (!g_slist_nth_data(tokens, 0)) {
1799 err("group_id is missing");
1804 if (!g_slist_nth_data(tokens, 1)) {
1805 err("function_id is missing");
1810 resp_str = g_slist_nth_data(tokens, 2);
1813 error = atoi(resp_str);
1816 dbg("Response is Success");
1825 tcore_at_tok_free(tokens);
1827 dbg("RESPONSE NOT OK");
1829 line = (const char *) response->final_response;
1830 tokens = tcore_at_tok_new(line);
1832 if (g_slist_length(tokens) < 1) {
1833 err("err cause not specified or string corrupted");
1836 error = atoi(g_slist_nth_data(tokens, 0));
1838 // TODO: CMEE error mapping is required.
1842 tcore_at_tok_free(tokens);
1845 if (soundvolume == TRUE) {
1846 soundvolume = FALSE;
1848 // Send reposne to TAPI
1849 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1852 err("User Request is NULL");
1860 static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
1862 UserRequest *ur = NULL;
1863 GSList *tokens = NULL;
1864 const char *line = NULL;
1865 char *resp_str = NULL;
1866 struct tresp_call_mute resp;
1867 const TcoreATResponse *response = data;
1872 ur = tcore_pending_ref_user_request(p);
1875 err("Input data is NULL");
1879 if (response->success > 0) {
1882 line = (const char *) (((GSList *) response->lines)->data);
1883 tokens = tcore_at_tok_new(line);
1884 resp_str = g_slist_nth_data(tokens, 0);
1886 if (!g_slist_nth_data(tokens, 0)) {
1887 err("group_id is missing");
1892 if (!g_slist_nth_data(tokens, 1)) {
1893 err(" function_id is missing");
1898 resp_str = g_slist_nth_data(tokens, 2);
1901 error = atoi(resp_str);
1903 dbg("Response is Success");
1911 tcore_at_tok_free(tokens);
1913 dbg("RESPONSE NOT OK");
1915 line = (const char *) response->final_response;
1916 tokens = tcore_at_tok_new(line);
1918 if (g_slist_length(tokens) < 1) {
1919 err("err cause not specified or string corrupted");
1922 error = atoi(g_slist_nth_data(tokens, 0));
1924 // TODO: CMEE error mapping is required.
1929 tcore_at_tok_free(tokens);
1933 tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
1935 err("User Request is NULL");
1942 static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
1944 const TcoreATResponse *response = NULL;
1945 struct tresp_call_unmute resp;
1946 GSList *tokens = NULL;
1947 const char *line = NULL;
1948 UserRequest *ur = NULL;
1949 char *resp_str = NULL;
1954 response = (TcoreATResponse *) data;
1955 ur = tcore_pending_ref_user_request(p);
1958 err("Input data is NULL");
1962 if (response->success > 0) {
1965 line = (const char *) (((GSList *) response->lines)->data);
1966 tokens = tcore_at_tok_new(line);
1967 resp_str = g_slist_nth_data(tokens, 0);
1969 if (!g_slist_nth_data(tokens, 0)) {
1970 err("group_id is missing");
1975 if (!g_slist_nth_data(tokens, 1)) {
1976 err(" function_id is missing");
1981 resp_str = g_slist_nth_data(tokens, 2);
1984 error = atoi(resp_str);
1986 dbg("Response is Success");
1994 tcore_at_tok_free(tokens);
1996 dbg("RESPONSE NOT OK");
1998 line = (const char *) response->final_response;
1999 tokens = tcore_at_tok_new(line);
2001 if (g_slist_length(tokens) < 1) {
2002 err("err cause not specified or string corrupted");
2005 error = atoi(g_slist_nth_data(tokens, 0));
2007 // TODO: CMEE error mapping is required.
2012 tcore_at_tok_free(tokens);
2016 tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
2018 err("User Request is NULL");
2026 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
2028 TcorePlugin *plugin = NULL;
2029 CoreObject *core_obj = NULL;
2030 CallObject *co = NULL;
2031 struct clcc_call_t *call_list = NULL;
2032 gboolean *event_flag = (gboolean *) user_data;
2033 const TcoreATResponse *response = data;
2034 GSList *resp_data = NULL;
2037 int cllc_info = 0, countCalls = 0, countValidCalls = 0;
2042 plugin = tcore_pending_ref_plugin(p);
2043 core_obj = tcore_pending_ref_core_object(p);
2045 if (response->success > 0) {
2047 if (response->lines) {
2048 resp_data = (GSList *) response->lines;
2049 countCalls = g_slist_length(resp_data);
2050 dbg("Total records : %d", countCalls);
2053 if (0 == countCalls) {
2054 err("Call count is zero");
2062 call_list = g_new0(struct clcc_call_t, countCalls);
2064 for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
2065 line = (char *) (resp_data->data);
2067 error = _callFromCLCCLine(line, call_list + countValidCalls);
2072 co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
2074 co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
2076 err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
2081 // Call set parameters
2082 tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
2083 tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
2084 tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
2085 tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
2086 tcore_call_object_set_active_line(co, 0);
2089 dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
2090 _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
2093 tcore_call_object_set_status(co, call_list[cllc_info].info.status);
2095 dbg("Call id : (%d)", call_list[cllc_info].info.id);
2096 dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
2097 dbg("Call type : (%d)", call_list[cllc_info].info.type);
2098 dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
2099 dbg("Call number : (%s)", call_list[cllc_info].number);
2100 dbg("Call status : (%d)", call_list[cllc_info].info.status);
2118 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
2120 TcorePlugin *plugin = NULL;
2121 CoreObject *core_obj = NULL;
2122 CallObject *co = (CallObject *) user_data;
2123 const TcoreATResponse *response = data;
2124 const char *line = NULL;
2125 struct tnoti_call_status_idle call_status;
2126 GSList *tokens = NULL;
2131 plugin = tcore_pending_ref_plugin(p);
2132 core_obj = tcore_pending_ref_core_object(p);
2134 if (response->success > 0) {
2136 line = (const char *) (((GSList *) response->lines)->data);
2137 tokens = tcore_at_tok_new(line);
2138 resp_str = g_slist_nth_data(tokens, 0);
2140 err("call end cause - report value missing");
2142 resp_str = g_slist_nth_data(tokens, 1);
2144 err("call end cause value missing");
2146 error = atoi(resp_str);
2147 dbg("call end cause - %d", error);
2148 call_status.cause = _compare_call_end_cause(error);
2149 dbg("TAPI call end cause - %d", call_status.cause);
2153 tcore_at_tok_free(tokens);
2155 err("RESPONSE NOT OK");
2156 line = (char *) response->final_response;
2157 tokens = tcore_at_tok_new(line);
2158 if (g_slist_length(tokens) < 1) {
2159 err("err cause not specified or string corrupted");
2161 err(" err cause value: %d", atoi(g_slist_nth_data(tokens, 0)));
2163 call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
2165 tcore_at_tok_free(tokens);
2168 call_status.type = tcore_call_object_get_type(co);
2169 dbg("data.type : [%d]", call_status.type);
2171 call_status.id = tcore_call_object_get_id(co);
2172 dbg("data.id : [%d]", call_status.id);
2175 tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
2177 // Send Notification to TAPI
2178 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
2180 TNOTI_CALL_STATUS_IDLE,
2181 sizeof(struct tnoti_call_status_idle),
2182 (void *) &call_status);
2185 tcore_call_object_free(core_obj, co);
2188 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
2190 // +CLCC: 1,0,2,0,0,"18005551212",145
2191 // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
2196 unsigned int num_type;
2197 GSList *tokens = NULL;
2202 tokens = tcore_at_tok_new(line);
2204 resp = g_slist_nth_data(tokens, 0);
2209 p_call->info.id = atoi(resp);
2210 dbg("id : [%d]\n", p_call->info.id);
2213 resp = g_slist_nth_data(tokens, 1);
2220 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
2222 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
2224 dbg("Direction : [ %d ]\n", p_call->info.direction);
2227 resp = g_slist_nth_data(tokens, 2);
2229 err("InValid Stat");
2233 dbg("Call state : %d", state);
2236 p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
2240 p_call->info.status = TCORE_CALL_STATUS_HELD;
2244 p_call->info.status = TCORE_CALL_STATUS_DIALING;
2248 p_call->info.status = TCORE_CALL_STATUS_ALERT;
2252 p_call->info.status = TCORE_CALL_STATUS_INCOMING;
2256 p_call->info.status = TCORE_CALL_STATUS_WAITING;
2259 dbg("Status : [%d]\n", p_call->info.status);
2262 resp = g_slist_nth_data(tokens, 3);
2264 err("InValid Mode");
2270 p_call->info.type = TCORE_CALL_TYPE_VOICE;
2274 p_call->info.type = TCORE_CALL_TYPE_VIDEO;
2277 default: // only Voice/VT call is supported in CS. treat other unknown calls as error
2278 dbg("invalid type : [%d]\n", mode);
2281 dbg("Call type : [%d]\n", p_call->info.type);
2284 resp = g_slist_nth_data(tokens, 4);
2286 err("InValid Mpty");
2290 p_call->info.mpty = atoi(resp);
2291 dbg("Mpty : [ %d ]\n", p_call->info.mpty);
2294 resp = g_slist_nth_data(tokens, 5);
2295 dbg("Incoming number - %s and its len - %d", resp, strlen(resp));
2297 // tolerate null here
2299 err("Number is NULL");
2302 // Strike off double quotes
2303 num = util_removeQuotes(resp);
2304 dbg("num after removing quotes - %s", num);
2306 p_call->info.num_len = strlen(resp);
2307 dbg("num_len : [0x%x]\n", p_call->info.num_len);
2310 resp = g_slist_nth_data(tokens, 6);
2312 dbg("InValid Num type");
2315 p_call->info.num_type = atoi(resp);
2316 dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
2318 // check number is international or national.
2319 num_type = ((p_call->info.num_type) >> 4) & 0x07;
2320 dbg("called party's type of number : [0x%x]\n", num_type);
2322 if (num_type == 1 && num[0] != '+') {
2323 // international number
2324 p_call->number[0] = '+';
2325 memcpy(&(p_call->number[1]), num, strlen(num));
2327 memcpy(&(p_call->number), num, strlen(num));
2329 dbg("incoming number - %s", p_call->number);
2334 tcore_at_tok_free(tokens);
2340 err("Invalid CLCC line");
2348 tcore_at_tok_free(tokens);
2354 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
2356 GSList *tokens = NULL;
2357 const char *line = NULL;
2361 GSList *pList = NULL;
2362 CallObject *co = NULL, *dupco = NULL;
2364 dbg("function entrance");
2365 // check call with waiting status already exist
2366 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
2368 if (pList != NULL) {
2369 dbg("[error]Waiting call already exist. skip");
2372 // check call with incoming status already exist
2373 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2375 if (pList != NULL) {
2376 dbg("[error]incoming call already exist. skip");
2379 line = (char *) data;
2380 tokens = tcore_at_tok_new(line);
2382 pId = g_slist_nth_data(tokens, 0);
2384 dbg("[error]:Call id is missing from +XCALLSTAT indication");
2385 tcore_at_tok_free(tokens);
2389 call_id = atoi(pId);
2390 dupco = tcore_call_object_find_by_id(o, call_id);
2391 if (dupco != NULL) {
2392 dbg("co with same id already exist. skip");
2393 tcore_at_tok_free(tokens);
2396 co = tcore_call_object_new(o, call_id);
2398 dbg("[ error ] co is NULL");
2399 tcore_at_tok_free(tokens);
2403 tcore_at_tok_free(tokens);
2405 eflag = g_new0(gboolean, 1);
2407 dbg("calling _call_list_get");
2408 _call_list_get(o, eflag);
2411 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
2413 GSList *tokens = NULL;
2414 const char *line = NULL;
2418 GSList *pList = NULL;
2419 CallObject *co = NULL, *dupco = NULL;
2421 dbg("function entrance");
2422 // check call with incoming status already exist
2423 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2425 if (pList != NULL) {
2426 dbg("incoming call already exist. skip");
2430 line = (char *) data;
2431 tokens = tcore_at_tok_new(line);
2433 pId = g_slist_nth_data(tokens, 0);
2435 dbg("Error:Call id is missing from %XCALLSTAT indication");
2436 tcore_at_tok_free(tokens);
2440 call_id = atoi(pId);
2442 dupco = tcore_call_object_find_by_id(o, call_id);
2443 if (dupco != NULL) {
2444 dbg("co with same id already exist. skip");
2445 tcore_at_tok_free(tokens);
2449 co = tcore_call_object_new(o, call_id);
2451 dbg("[ error ] co is NULL");
2452 tcore_at_tok_free(tokens);
2456 dbg("freeing at token")
2457 tcore_at_tok_free(tokens);
2459 eflag = g_new0(gboolean, 1);
2462 dbg("calling _call_list_get");
2463 _call_list_get(o, eflag);
2466 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
2469 TcorePlugin *plugin = NULL;
2470 CallObject *co = NULL;
2475 char *pCallId = NULL;
2476 GSList *tokens = NULL;
2477 gboolean *eflag = NULL;
2478 enum tcore_call_status co_status;
2480 dbg("function entrance");
2481 plugin = tcore_object_ref_plugin(o);
2482 cmd = (char *) data;
2483 tokens = tcore_at_tok_new(cmd);
2486 pCallId = g_slist_nth_data(tokens, 0);
2488 dbg("CallId is missing from %XCALLSTAT indication");
2489 tcore_at_tok_free(tokens);
2493 dbg("call id = %d", id);
2495 if ((stat = g_slist_nth_data(tokens, 1))) {
2496 status = atoi(stat);
2498 dbg("call status = %d", status);
2501 tcore_at_tok_free(tokens);
2502 co_status = _call_status(status);
2504 dbg("co_status = %d", co_status);
2505 switch (co_status) {
2506 case CALL_STATUS_ACTIVE:
2508 dbg("call(%d) status : [ ACTIVE ]", id);
2509 co = tcore_call_object_find_by_id(o, id);
2514 _call_status_active(plugin, co);
2518 case CALL_STATUS_HELD:
2519 dbg("call(%d) status : [ held ]", id);
2522 case CALL_STATUS_DIALING:
2524 dbg("call(%d) status : [ dialing ]", id);
2525 co = tcore_call_object_find_by_id(o, id);
2527 co = tcore_call_object_new(o, id);
2529 dbg("error : tcore_call_object_new [ id : %d ]", id);
2534 tcore_call_object_set_type(co, call_type(type));
2535 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
2536 _call_status_dialing(plugin, co);
2540 case CALL_STATUS_ALERT:
2542 dbg("call(%d) status : [ alert ]", id);
2543 co = tcore_call_object_find_by_id(o, id);
2548 // Store dialed number information into Call object.
2549 eflag = g_new0(gboolean, 1);
2551 dbg("calling _call_list_get");
2552 _call_list_get(o, eflag);
2556 case CALL_STATUS_INCOMING:
2557 case CALL_STATUS_WAITING:
2558 dbg("call(%d) status : [ incoming ]", id);
2561 case CALL_STATUS_IDLE:
2563 dbg("call(%d) status : [ release ]", id);
2565 co = tcore_call_object_find_by_id(o, id);
2571 plugin = tcore_object_ref_plugin(o);
2573 dbg("plugin is NULL");
2576 _call_status_idle(plugin, co);
2581 dbg("invalid call status", id);
2586 static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
2588 struct treq_call_dial *data = 0;
2589 char *raw_str = NULL;
2590 char *cmd_str = NULL;
2592 enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
2593 TcorePending *pending = NULL;
2594 TcoreATRequest *req;
2595 gboolean ret = FALSE;
2597 dbg("function entrance");
2599 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2600 dbg("cp not ready/n");
2601 return TCORE_RETURN_ENOSYS;
2604 data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
2605 if (data->type == CALL_TYPE_VIDEO) {
2606 dbg("invalid call type")
2607 return TCORE_RETURN_FAILURE;
2610 clir = _get_clir_status(data->number);
2612 // Compose ATD Cmd string
2614 case TCORE_CALL_CLI_MODE_PRESENT:
2615 dbg("CALL_CLI_MODE_PRESENT");
2617 break; // invocation
2619 case TCORE_CALL_CLI_MODE_RESTRICT:
2620 dbg("CALL_CLI_MODE_RESTRICT");
2622 break; // suppression
2624 case TCORE_CALL_CLI_MODE_DEFAULT:
2627 dbg("CALL_CLI_MODE_DEFAULT");
2628 break; // subscription default
2631 dbg("data->number = %s", data->number);
2633 raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
2634 cmd_str = g_strdup_printf("%s", raw_str);
2636 dbg("request command : %s", cmd_str);
2638 pending = tcore_pending_new(o, 0);
2639 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2640 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2642 tcore_pending_set_request_data(pending, 0, req);
2643 ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
2649 dbg("AT request(%s) sent failed", req->cmd);
2650 return TCORE_RETURN_FAILURE;
2653 dbg("AT request(%s) sent success", req->cmd);
2655 return TCORE_RETURN_SUCCESS;
2658 static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
2660 char *cmd_str = NULL;
2661 CallObject *co = NULL;
2662 struct treq_call_answer *data = 0;
2663 TcorePending *pending = NULL;
2664 TcoreATRequest *req;
2665 gboolean ret = FALSE;
2667 dbg("function entrance");
2669 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2670 dbg("cp not ready/n");
2671 return TCORE_RETURN_ENOSYS;
2674 data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
2675 co = tcore_call_object_find_by_id(o, data->id);
2676 if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
2677 dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
2679 cmd_str = g_strdup_printf("%s", "ATA");
2680 pending = tcore_pending_new(o, 0);
2681 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2682 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2684 tcore_pending_set_request_data(pending, 0, req);
2685 ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
2689 dbg("AT request(%s) sent failed", req->cmd);
2690 return TCORE_RETURN_FAILURE;
2693 switch (data->type) {
2694 case CALL_ANSWER_TYPE_REJECT:
2696 dbg("call answer reject");
2697 tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
2701 case CALL_ANSWER_TYPE_REPLACE:
2703 dbg("call answer replace");
2704 tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
2708 case CALL_ANSWER_TYPE_HOLD_ACCEPT:
2710 dbg("call answer hold and accept");
2711 tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
2716 dbg("[ error ] wrong answer type [ %d ]", data->type);
2717 return TCORE_RETURN_FAILURE;
2721 return TCORE_RETURN_SUCCESS;
2724 static TReturn s_call_release(CoreObject *o, UserRequest *ur)
2726 CallObject *co = NULL;
2727 struct treq_call_end *data = 0;
2728 UserRequest *ur_dup = NULL;
2729 char *chld0_cmd = NULL;
2730 char *chld1_cmd = NULL;
2731 TcorePending *pending = NULL, *pending1 = NULL;
2732 TcoreATRequest *req, *req1;
2733 gboolean ret = FALSE;
2735 dbg("function entrance");
2736 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2737 dbg("cp not ready/n");
2738 return TCORE_RETURN_ENOSYS;
2740 data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
2741 co = tcore_call_object_find_by_id(o, data->id);
2743 dbg("type of release call = %d", data->type);
2745 if (data->type == CALL_END_TYPE_ALL) {
2746 // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
2747 chld0_cmd = g_strdup("AT+CHLD=0");
2748 chld1_cmd = g_strdup("AT+CHLD=1");
2750 pending = tcore_pending_new(o, 0);
2751 req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
2753 dbg("input command is %s", chld0_cmd);
2754 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2756 tcore_pending_set_request_data(pending, 0, req);
2757 ur_dup = tcore_user_request_new(NULL, NULL);
2758 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
2762 dbg("AT request %s has failed ", req->cmd);
2764 tcore_user_request_free(ur_dup);
2768 return TCORE_RETURN_FAILURE;
2771 pending1 = tcore_pending_new(o, 0);
2772 req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
2774 dbg("input command is %s", chld1_cmd);
2775 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2777 tcore_pending_set_request_data(pending1, 0, req1);
2778 ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
2782 dbg("AT request %s has failed ", req->cmd);
2783 return TCORE_RETURN_FAILURE;
2786 switch (data->type) {
2787 case CALL_END_TYPE_DEFAULT:
2790 id = tcore_call_object_get_id(co);
2792 dbg("call end call id [%d]", id);
2793 tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
2797 case CALL_END_TYPE_ACTIVE_ALL:
2799 dbg("call end all active");
2800 tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
2804 case CALL_END_TYPE_HOLD_ALL:
2806 dbg("call end all held");
2807 tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
2812 dbg("[ error ] wrong end type [ %d ]", data->type);
2813 return TCORE_RETURN_FAILURE;
2817 return TCORE_RETURN_SUCCESS;
2820 static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
2822 struct treq_call_hold *hold = 0;
2823 CallObject *co = NULL;
2825 dbg("function entrance");
2827 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2828 dbg("cp not ready/n");
2829 return TCORE_RETURN_ENOSYS;
2832 hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
2833 dbg("call id : [ %d ]", hold->id);
2835 co = tcore_call_object_find_by_id(o, hold->id);
2836 tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
2838 return TCORE_RETURN_SUCCESS;
2841 static TReturn s_call_active(CoreObject *o, UserRequest *ur)
2843 struct treq_call_active *active = 0;
2844 CallObject *co = NULL;
2846 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2847 dbg("cp not ready/n");
2848 return TCORE_RETURN_ENOSYS;
2851 active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
2852 dbg("call id : [ %d ]", active->id);
2854 co = tcore_call_object_find_by_id(o, active->id);
2855 tcore_call_control_active(o, ur, on_confirmation_call_active, co);
2857 return TCORE_RETURN_SUCCESS;
2860 static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
2862 struct treq_call_swap *swap = NULL;
2863 CallObject *co = NULL;
2865 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2866 dbg("cp not ready/n");
2867 return TCORE_RETURN_ENOSYS;
2870 swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
2871 dbg("call id : [ %d ]", swap->id);
2873 co = tcore_call_object_find_by_id(o, swap->id);
2874 tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
2876 return TCORE_RETURN_SUCCESS;
2879 static TReturn s_call_join(CoreObject *o, UserRequest *ur)
2881 struct treq_call_join *join = 0;
2882 CallObject *co = NULL;
2884 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2885 dbg("cp not ready/n");
2886 return TCORE_RETURN_ENOSYS;
2889 join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
2890 dbg("call id : [ %d ]", join->id);
2892 co = tcore_call_object_find_by_id(o, join->id);
2893 tcore_call_control_join(o, ur, on_confirmation_call_join, co);
2895 return TCORE_RETURN_SUCCESS;
2898 static TReturn s_call_split(CoreObject *o, UserRequest *ur)
2900 struct treq_call_split *split = 0;
2901 CallObject *co = NULL;
2903 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2904 dbg("cp not ready/n");
2905 return TCORE_RETURN_ENOSYS;
2908 split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
2909 co = tcore_call_object_find_by_id(o, split->id);
2910 dbg("call id : [ %d ]", split->id);
2912 tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
2914 return TCORE_RETURN_SUCCESS;
2917 static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
2919 struct treq_call_deflect *deflect = 0;
2920 CallObject *co = NULL;
2922 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2923 dbg("cp not ready/n");
2924 return TCORE_RETURN_ENOSYS;
2927 deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
2928 co = tcore_call_object_find_by_number(o, deflect->number);
2929 dbg("deflect number: [ %s ]", deflect->number);
2931 tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
2933 return TCORE_RETURN_SUCCESS;
2936 static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
2938 struct treq_call_transfer *transfer = 0;
2939 CallObject *co = NULL;
2941 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2942 dbg("cp not ready/n");
2943 return TCORE_RETURN_ENOSYS;
2946 transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
2947 dbg("call id : [ %d ]", transfer->id);
2949 co = tcore_call_object_find_by_id(o, transfer->id);
2950 tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
2952 return TCORE_RETURN_SUCCESS;
2955 static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
2957 char *cmd_str = NULL;
2958 TcorePending *pending = NULL;
2959 TcoreATRequest *req;
2961 gboolean ret = FALSE;
2962 struct treq_call_dtmf *dtmf = 0;
2963 char *dtmfstr = NULL, *tmp_dtmf = NULL;
2964 unsigned int dtmf_count;
2966 dbg("Function enter");
2968 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2969 dbg("cp not ready/n");
2970 return TCORE_RETURN_ENOSYS;
2973 dup = tcore_user_request_new(NULL, NULL);
2974 (void) _set_dtmf_tone_duration(o, dup);
2976 dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
2977 dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1); // DTMF digits + comma for each dtmf digit.
2979 if (dtmfstr == NULL) {
2980 dbg("Memory allocation failed");
2981 return TCORE_RETURN_FAILURE;
2986 for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
2987 *tmp_dtmf = dtmf->digits[dtmf_count];
2994 // last digit is having COMMA , overwrite it with '\0' .
2995 *(--tmp_dtmf) = '\0';
2996 dbg("Input DTMF string(%s)", dtmfstr);
2998 // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
2999 cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
3000 dbg("request command : %s", cmd_str);
3002 pending = tcore_pending_new(o, 0);
3003 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3004 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3006 tcore_pending_set_request_data(pending, 0, req);
3007 ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
3012 dbg("AT request sent failed")
3013 return TCORE_RETURN_FAILURE;
3016 return TCORE_RETURN_SUCCESS;
3019 static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
3021 UserRequest *ur_dup = NULL;
3022 TcorePending *pending = NULL, *pending1 = NULL;
3023 TcoreATRequest *req, *req1;
3024 char *cmd_str = NULL, *cmd_str1 = NULL;
3025 int device_type = -1;
3026 struct treq_call_sound_set_path *sound_path = 0;
3027 gboolean ret = FALSE;
3028 TcorePlugin *plugin = tcore_object_ref_plugin(o);
3029 const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
3031 dbg("function entrance");
3033 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3034 dbg("cp not ready/n");
3035 return TCORE_RETURN_ENOSYS;
3037 sound_path = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
3038 if (sound_path == NULL) {
3039 dbg("invaling user request");
3040 return TCORE_RETURN_FAILURE;
3042 dbg("audio device type - 0x%x", sound_path->path);
3043 switch (sound_path->path) {
3044 case CALL_SOUND_PATH_HANDSET:
3048 case CALL_SOUND_PATH_HEADSET:
3052 case CALL_SOUND_PATH_HEADSET_3_5PI:
3056 case CALL_SOUND_PATH_SPEAKER:
3060 case CALL_SOUND_PATH_HANDFREE:
3064 case CALL_SOUND_PATH_HEADSET_HAC:
3068 case CALL_SOUND_PATH_BLUETOOTH:
3069 case CALL_SOUND_PATH_STEREO_BLUETOOTH:
3073 case CALL_SOUND_PATH_BT_NSEC_OFF:
3074 case CALL_SOUND_PATH_MIC1:
3075 case CALL_SOUND_PATH_MIC2:
3077 dbg("unsupported device type");
3078 return TCORE_RETURN_FAILURE;
3081 if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
3082 struct tnoti_call_sound_path tnoti_snd_path;
3083 tnoti_snd_path.path = sound_path->path;
3084 /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
3085 if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
3086 call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,3,0,1,0,0,0,0,0,0,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
3087 call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,2,0,1,0,0,0,0,0,0,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
3090 call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,3,0,1,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
3091 call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,2,0,1,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
3094 /* Configure modem I2S2 and do the modem routing */
3095 call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,4,0,0,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
3096 call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,3,0,0,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
3097 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
3098 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
3099 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
3100 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
3103 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
3104 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
3105 /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
3107 pending = tcore_pending_new(o, 0);
3108 req = tcore_at_request_new("AT+XDRV=40,6,0,2", "+XDRV", TCORE_AT_SINGLELINE);
3109 dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3110 tcore_pending_set_request_data(pending, 0, req);
3111 ur_dup = tcore_user_request_ref(ur);
3112 ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, &tnoti_snd_path);
3116 cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
3117 pending = tcore_pending_new(o, 0);
3118 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3119 dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3120 tcore_pending_set_request_data(pending, 0, req);
3121 ur_dup = tcore_user_request_ref(ur);
3122 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
3126 dbg("At request(%s) sent failed", req->cmd);
3127 return TCORE_RETURN_FAILURE;
3130 cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
3131 pending1 = tcore_pending_new(o, 0);
3132 req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
3133 dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
3134 tcore_pending_set_request_data(pending1, 0, req1);
3135 ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
3139 dbg("AT request %s has failed ", req1->cmd);
3140 return TCORE_RETURN_FAILURE;
3144 return TCORE_RETURN_SUCCESS;
3147 static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
3149 UserRequest *src_ur = NULL;
3150 UserRequest *dest_ur = NULL;
3151 TcorePending *src_pending = NULL;
3152 TcorePending *dest_pending = NULL;
3153 TcoreATRequest *src_req = NULL;
3154 TcoreATRequest *dest_req = NULL;
3155 char *cmd_str = NULL, *volume_level = NULL;
3156 gboolean ret = FALSE;
3157 struct treq_call_sound_set_volume_level *data = NULL;
3161 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3162 dbg("cp not ready/n");
3163 return TCORE_RETURN_ENOSYS;
3166 data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
3168 // Hard-coded values for MIC & Speakers
3170 dbg("Set Source volume");
3172 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source type
3173 dbg("Request command string: %s", cmd_str);
3175 // Create new Pending request
3176 src_pending = tcore_pending_new(o, 0);
3178 // Create new AT-Command request
3179 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3180 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3182 // Free Command string
3185 tcore_pending_set_request_data(src_pending, 0, src_req);
3186 src_ur = tcore_user_request_ref(ur);
3189 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3191 err("Failed to send AT-Command request");
3192 return TCORE_RETURN_FAILURE;
3195 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type
3196 dbg("Request command string: %s", cmd_str);
3198 // Create new Pending request
3199 src_pending = tcore_pending_new(o, 0);
3201 // Create new AT-Command request
3202 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3203 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3205 // Free Command string
3208 tcore_pending_set_request_data(src_pending, 0, src_req);
3210 src_ur = tcore_user_request_ref(ur);
3213 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3215 err("Failed to send AT-Command request");
3216 return TCORE_RETURN_FAILURE;
3219 // Destination volume
3220 dbg("Set Source volume");
3222 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type
3223 dbg("Request command string: %s", cmd_str);
3225 // Create new Pending request
3226 dest_pending = tcore_pending_new(o, 0);
3228 // Create new AT-Command request
3229 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3230 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3232 // Free Command string
3235 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3236 dest_ur = tcore_user_request_ref(ur);
3239 ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3241 err("Failed to send AT-Command request");
3242 return TCORE_RETURN_FAILURE;
3245 dbg("Input volume level - %d", data->volume);
3246 switch (data->volume) {
3247 case CALL_SOUND_MUTE:
3251 case CALL_SOUND_VOLUME_LEVEL_1:
3252 volume_level = "40";
3255 case CALL_SOUND_VOLUME_LEVEL_2:
3256 volume_level = "46";
3259 case CALL_SOUND_VOLUME_LEVEL_3:
3260 volume_level = "52";
3263 case CALL_SOUND_VOLUME_LEVEL_4:
3264 volume_level = "58";
3267 case CALL_SOUND_VOLUME_LEVEL_5:
3268 volume_level = "64";
3271 case CALL_SOUND_VOLUME_LEVEL_6:
3272 volume_level = "70";
3275 case CALL_SOUND_VOLUME_LEVEL_7:
3276 volume_level = "76";
3279 case CALL_SOUND_VOLUME_LEVEL_8:
3280 volume_level = "82";
3283 case CALL_SOUND_VOLUME_LEVEL_9:
3285 volume_level = "88";
3288 cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level); // Destination type
3289 dbg("Request command string: %s", cmd_str);
3291 // Create new Pending request
3292 dest_pending = tcore_pending_new(o, 0);
3294 // Create new AT-Command request
3295 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3296 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3298 // Free Command string
3301 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3304 ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
3306 err("Failed to send AT-Command request");
3307 return TCORE_RETURN_FAILURE;
3310 return TCORE_RETURN_SUCCESS;
3314 static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
3319 return TCORE_RETURN_SUCCESS;
3322 static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
3324 char *cmd_str = NULL;
3325 TcorePending *pending = NULL;
3326 TcoreATRequest *req = NULL;
3327 gboolean ret = FALSE;
3331 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3332 dbg("cp not ready/n");
3333 return TCORE_RETURN_ENOSYS;
3336 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
3338 dbg("Request command string: %s", cmd_str);
3340 // Create new Pending request
3341 pending = tcore_pending_new(o, 0);
3343 // Create new AT-Command request
3344 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3345 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3347 // Free command string
3350 // Set request data (AT command) to Pending request
3351 tcore_pending_set_request_data(pending, 0, req);
3354 ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
3356 err("Failed to send AT-Command request");
3357 return TCORE_RETURN_FAILURE;
3361 return TCORE_RETURN_SUCCESS;
3364 static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
3366 char *cmd_str = NULL;
3367 TcorePending *pending = NULL;
3368 TcoreATRequest *req = NULL;
3369 gboolean ret = FALSE;
3373 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3374 dbg("cp not ready/n");
3375 return TCORE_RETURN_ENOSYS;
3378 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
3379 dbg("Request command string: %s", cmd_str);
3381 // Create new Pending request
3382 pending = tcore_pending_new(o, 0);
3384 // Create new AT-Command request
3385 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3386 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3388 // Free command string
3391 // Set request data (AT command) to Pending request
3392 tcore_pending_set_request_data(pending, 0, req);
3395 ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
3397 err("Failed to send AT-Command request");
3398 return TCORE_RETURN_FAILURE;
3402 return TCORE_RETURN_SUCCESS;
3406 static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
3411 return TCORE_RETURN_SUCCESS;
3414 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
3416 char *cmd_str = NULL;
3417 TcorePending *pending = NULL;
3418 TcoreATRequest *req = NULL;
3419 gboolean ret = FALSE;
3423 cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.
3424 dbg("Request command string: %s", cmd_str);
3426 // Create new Pending request
3427 pending = tcore_pending_new(o, 0);
3429 // Create new AT-Command request
3430 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3431 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3433 // Free command string */
3436 // Set request data (AT command) to Pending request
3437 tcore_pending_set_request_data(pending, 0, req);
3440 ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
3442 err("Failed to send AT-Command request");
3444 tcore_user_request_free(ur);
3447 return TCORE_RETURN_FAILURE;
3451 return TCORE_RETURN_SUCCESS;
3455 static struct tcore_call_operations call_ops = {
3456 .dial = s_call_outgoing,
3457 .answer = s_call_answer,
3458 .end = s_call_release,
3459 .hold = s_call_hold,
3460 .active = s_call_active,
3461 .swap = s_call_swap,
3462 .join = s_call_join,
3463 .split = s_call_split,
3464 .deflect = s_call_deflect,
3465 .transfer = s_call_transfer,
3466 .send_dtmf = s_call_send_dtmf,
3467 .set_sound_path = s_call_set_sound_path,
3468 .set_sound_volume_level = s_call_set_sound_volume_level,
3469 .get_sound_volume_level = s_call_get_sound_volume_level,
3470 .mute = s_call_mute,
3471 .unmute = s_call_unmute,
3472 .get_mute_status = s_call_get_mute_status,
3473 .set_sound_recording = NULL,
3474 .set_sound_equalization = NULL,
3475 .set_sound_noise_reduction = NULL,
3478 gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call)
3482 tcore_call_override_ops(co_call, &call_ops, NULL);
3485 tcore_object_override_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
3486 tcore_object_override_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
3493 void s_call_exit(TcorePlugin *cp, CoreObject *co_call)