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");
1513 static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1515 UserRequest *ur = NULL;
1516 GSList *tokens = NULL;
1517 const char *line = NULL;
1518 const TcoreATResponse *response = data;
1519 char *resp_str = NULL;
1520 struct tresp_call_sound_set_path resp;
1524 ur = tcore_pending_ref_user_request(p);
1526 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1528 err("Input data is NULL");
1532 if (response->success > 0) {
1535 line = (const char *) (((GSList *) response->lines)->data);
1536 tokens = tcore_at_tok_new(line);
1538 resp_str = g_slist_nth_data(tokens, 0);
1539 if (!g_slist_nth_data(tokens, 0)) {
1540 err("group_id is missing");
1545 if (!g_slist_nth_data(tokens, 1)) {
1546 err(" function_id is missing");
1551 resp_str = g_slist_nth_data(tokens, 2);
1554 error = atoi(resp_str);
1556 dbg("Response is Success");
1564 tcore_at_tok_free(tokens);
1566 dbg("RESPONSE NOT OK");
1568 line = (const char *) response->final_response;
1569 tokens = tcore_at_tok_new(line);
1571 if (g_slist_length(tokens) < 1) {
1572 err("err cause not specified or string corrupted");
1575 error = atoi(g_slist_nth_data(tokens, 0));
1577 // TODO: CMEE error mapping is required.
1582 tcore_at_tok_free(tokens);
1586 if ( resp.err ) { // Send only failed notification . success notification send when destination device is set.
1587 // Send notification to TAPI
1588 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1589 setsoundpath = TRUE;
1592 err("User Request is NULL");
1599 static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1601 UserRequest *ur = NULL;
1602 GSList *tokens = NULL;
1603 const char *line = NULL;
1604 char *resp_str = NULL;
1605 struct tresp_call_sound_set_path resp;
1606 const TcoreATResponse *response = data;
1611 ur = tcore_pending_ref_user_request(p);
1612 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1615 err("Input data is NULL");
1620 if (response->success > 0) {
1623 line = (const char *) (((GSList *) response->lines)->data);
1624 tokens = tcore_at_tok_new(line);
1626 resp_str = g_slist_nth_data(tokens, 0);
1627 if (!g_slist_nth_data(tokens, 0)) {
1628 dbg("group_id is missing");
1633 if (!g_slist_nth_data(tokens, 1)) {
1634 dbg("function_id is missing");
1639 resp_str = g_slist_nth_data(tokens, 2);
1641 error = atoi(resp_str);
1643 dbg("Response is Success");
1652 tcore_at_tok_free(tokens);
1654 dbg("RESPONSE NOT OK");
1656 line = (const char *) response->final_response;
1657 tokens = tcore_at_tok_new(line);
1659 if (g_slist_length(tokens) < 1) {
1660 err("err cause not specified or string corrupted");
1663 error = atoi(g_slist_nth_data(tokens, 0));
1664 // TODO: CMEE error mapping is required.
1669 tcore_at_tok_free(tokens);
1672 if (setsoundpath == TRUE) {
1673 setsoundpath = FALSE;
1675 // Send response to TAPI
1676 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1679 dbg("User Request is NULL");
1686 static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1688 UserRequest *ur = NULL;
1689 GSList *tokens = NULL;
1690 const char *line = NULL;
1691 const TcoreATResponse *response = data;
1692 char *resp_str = NULL;
1693 struct tresp_call_sound_set_volume_level resp;
1696 ur = tcore_pending_ref_user_request(p);
1698 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1700 err("Input data is NULL");
1704 if (response->success > 0) {
1707 line = (const char *) (((GSList *) response->lines)->data);
1708 tokens = tcore_at_tok_new(line);
1710 resp_str = g_slist_nth_data(tokens, 0);
1711 if (!g_slist_nth_data(tokens, 0)) {
1712 err("group_id is missing");
1717 if (!g_slist_nth_data(tokens, 1)) {
1718 err("function_id is missing");
1723 resp_str = g_slist_nth_data(tokens, 2);
1725 error = atoi(resp_str);
1728 dbg("Response is Success ");
1737 tcore_at_tok_free(tokens);
1739 dbg("RESPONSE NOT OK");
1741 line = (const char *) response->final_response;
1742 tokens = tcore_at_tok_new(line);
1744 if (g_slist_length(tokens) < 1) {
1745 err("err cause not specified or string corrupted");
1748 error = atoi(g_slist_nth_data(tokens, 0));
1750 // TODO: CMEE error mapping is required.
1755 tcore_at_tok_free(tokens);
1759 if (resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.
1760 // Send reposne to TAPI
1761 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1765 err("User Request is NULL");
1773 static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1775 UserRequest *ur = NULL;
1776 GSList *tokens = NULL;
1777 const char *line = NULL;
1778 char *resp_str = NULL;
1779 const TcoreATResponse *response = data;
1780 struct tresp_call_sound_set_volume_level resp;
1785 ur = tcore_pending_ref_user_request(p);
1787 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1789 err("Input data is NULL");
1794 if (response->success > 0) {
1796 line = (const char *) (((GSList *) response->lines)->data);
1797 tokens = tcore_at_tok_new(line);
1798 resp_str = g_slist_nth_data(tokens, 0);
1800 if (!g_slist_nth_data(tokens, 0)) {
1801 err("group_id is missing");
1806 if (!g_slist_nth_data(tokens, 1)) {
1807 err("function_id is missing");
1812 resp_str = g_slist_nth_data(tokens, 2);
1815 error = atoi(resp_str);
1818 dbg("Response is Success");
1827 tcore_at_tok_free(tokens);
1829 dbg("RESPONSE NOT OK");
1831 line = (const char *) response->final_response;
1832 tokens = tcore_at_tok_new(line);
1834 if (g_slist_length(tokens) < 1) {
1835 err("err cause not specified or string corrupted");
1838 error = atoi(g_slist_nth_data(tokens, 0));
1840 // TODO: CMEE error mapping is required.
1844 tcore_at_tok_free(tokens);
1847 if (soundvolume == TRUE) {
1848 soundvolume = FALSE;
1850 // Send reposne to TAPI
1851 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1854 err("User Request is NULL");
1862 static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
1864 UserRequest *ur = NULL;
1865 GSList *tokens = NULL;
1866 const char *line = NULL;
1867 char *resp_str = NULL;
1868 struct tresp_call_mute resp;
1869 const TcoreATResponse *response = data;
1874 ur = tcore_pending_ref_user_request(p);
1877 err("Input data is NULL");
1881 if (response->success > 0) {
1884 line = (const char *) (((GSList *) response->lines)->data);
1885 tokens = tcore_at_tok_new(line);
1886 resp_str = g_slist_nth_data(tokens, 0);
1888 if (!g_slist_nth_data(tokens, 0)) {
1889 err("group_id is missing");
1894 if (!g_slist_nth_data(tokens, 1)) {
1895 err(" function_id is missing");
1900 resp_str = g_slist_nth_data(tokens, 2);
1903 error = atoi(resp_str);
1905 dbg("Response is Success");
1913 tcore_at_tok_free(tokens);
1915 dbg("RESPONSE NOT OK");
1917 line = (const char *) response->final_response;
1918 tokens = tcore_at_tok_new(line);
1920 if (g_slist_length(tokens) < 1) {
1921 err("err cause not specified or string corrupted");
1924 error = atoi(g_slist_nth_data(tokens, 0));
1926 // TODO: CMEE error mapping is required.
1931 tcore_at_tok_free(tokens);
1935 tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
1937 err("User Request is NULL");
1944 static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
1946 const TcoreATResponse *response = NULL;
1947 struct tresp_call_unmute resp;
1948 GSList *tokens = NULL;
1949 const char *line = NULL;
1950 UserRequest *ur = NULL;
1951 char *resp_str = NULL;
1956 response = (TcoreATResponse *) data;
1957 ur = tcore_pending_ref_user_request(p);
1960 err("Input data is NULL");
1964 if (response->success > 0) {
1967 line = (const char *) (((GSList *) response->lines)->data);
1968 tokens = tcore_at_tok_new(line);
1969 resp_str = g_slist_nth_data(tokens, 0);
1971 if (!g_slist_nth_data(tokens, 0)) {
1972 err("group_id is missing");
1977 if (!g_slist_nth_data(tokens, 1)) {
1978 err(" function_id is missing");
1983 resp_str = g_slist_nth_data(tokens, 2);
1986 error = atoi(resp_str);
1988 dbg("Response is Success");
1996 tcore_at_tok_free(tokens);
1998 dbg("RESPONSE NOT OK");
2000 line = (const char *) response->final_response;
2001 tokens = tcore_at_tok_new(line);
2003 if (g_slist_length(tokens) < 1) {
2004 err("err cause not specified or string corrupted");
2007 error = atoi(g_slist_nth_data(tokens, 0));
2009 // TODO: CMEE error mapping is required.
2014 tcore_at_tok_free(tokens);
2018 tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
2020 err("User Request is NULL");
2028 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
2030 TcorePlugin *plugin = NULL;
2031 CoreObject *core_obj = NULL;
2032 CallObject *co = NULL;
2033 struct clcc_call_t *call_list = NULL;
2034 gboolean *event_flag = (gboolean *) user_data;
2035 const TcoreATResponse *response = data;
2036 GSList *resp_data = NULL;
2039 int cllc_info = 0, countCalls = 0, countValidCalls = 0;
2044 plugin = tcore_pending_ref_plugin(p);
2045 core_obj = tcore_pending_ref_core_object(p);
2047 if (response->success > 0) {
2049 if (response->lines) {
2050 resp_data = (GSList *) response->lines;
2051 countCalls = g_slist_length(resp_data);
2052 dbg("Total records : %d", countCalls);
2055 if (0 == countCalls) {
2056 err("Call count is zero");
2064 call_list = g_new0(struct clcc_call_t, countCalls);
2066 for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
2067 line = (char *) (resp_data->data);
2069 error = _callFromCLCCLine(line, call_list + countValidCalls);
2074 co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
2076 co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
2078 err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
2083 // Call set parameters
2084 tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
2085 tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
2086 tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
2087 tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
2088 tcore_call_object_set_active_line(co, 0);
2091 dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
2092 _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
2095 tcore_call_object_set_status(co, call_list[cllc_info].info.status);
2097 dbg("Call id : (%d)", call_list[cllc_info].info.id);
2098 dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
2099 dbg("Call type : (%d)", call_list[cllc_info].info.type);
2100 dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
2101 dbg("Call number : (%s)", call_list[cllc_info].number);
2102 dbg("Call status : (%d)", call_list[cllc_info].info.status);
2120 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
2122 TcorePlugin *plugin = NULL;
2123 CoreObject *core_obj = NULL;
2124 CallObject *co = (CallObject *) user_data;
2125 const TcoreATResponse *response = data;
2126 const char *line = NULL;
2127 struct tnoti_call_status_idle call_status;
2128 GSList *tokens = NULL;
2133 plugin = tcore_pending_ref_plugin(p);
2134 core_obj = tcore_pending_ref_core_object(p);
2136 if (response->success > 0) {
2138 line = (const char *) (((GSList *) response->lines)->data);
2139 tokens = tcore_at_tok_new(line);
2140 resp_str = g_slist_nth_data(tokens, 0);
2142 err("call end cause - report value missing");
2144 resp_str = g_slist_nth_data(tokens, 1);
2146 err("call end cause value missing");
2148 error = atoi(resp_str);
2149 dbg("call end cause - %d", error);
2150 call_status.cause = _compare_call_end_cause(error);
2151 dbg("TAPI call end cause - %d", call_status.cause);
2155 tcore_at_tok_free(tokens);
2157 err("RESPONSE NOT OK");
2158 line = (char *) response->final_response;
2159 tokens = tcore_at_tok_new(line);
2160 if (g_slist_length(tokens) < 1) {
2161 err("err cause not specified or string corrupted");
2163 err(" err cause value: %d", atoi(g_slist_nth_data(tokens, 0)));
2165 call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
2167 tcore_at_tok_free(tokens);
2170 call_status.type = tcore_call_object_get_type(co);
2171 dbg("data.type : [%d]", call_status.type);
2173 call_status.id = tcore_call_object_get_id(co);
2174 dbg("data.id : [%d]", call_status.id);
2177 tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
2179 // Send Notification to TAPI
2180 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
2182 TNOTI_CALL_STATUS_IDLE,
2183 sizeof(struct tnoti_call_status_idle),
2184 (void *) &call_status);
2187 tcore_call_object_free(core_obj, co);
2190 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
2192 // +CLCC: 1,0,2,0,0,"18005551212",145
2193 // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
2198 unsigned int num_type;
2199 GSList *tokens = NULL;
2204 tokens = tcore_at_tok_new(line);
2206 resp = g_slist_nth_data(tokens, 0);
2211 p_call->info.id = atoi(resp);
2212 dbg("id : [%d]\n", p_call->info.id);
2215 resp = g_slist_nth_data(tokens, 1);
2222 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
2224 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
2226 dbg("Direction : [ %d ]\n", p_call->info.direction);
2229 resp = g_slist_nth_data(tokens, 2);
2231 err("InValid Stat");
2235 dbg("Call state : %d", state);
2238 p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
2242 p_call->info.status = TCORE_CALL_STATUS_HELD;
2246 p_call->info.status = TCORE_CALL_STATUS_DIALING;
2250 p_call->info.status = TCORE_CALL_STATUS_ALERT;
2254 p_call->info.status = TCORE_CALL_STATUS_INCOMING;
2258 p_call->info.status = TCORE_CALL_STATUS_WAITING;
2261 dbg("Status : [%d]\n", p_call->info.status);
2264 resp = g_slist_nth_data(tokens, 3);
2266 err("InValid Mode");
2272 p_call->info.type = TCORE_CALL_TYPE_VOICE;
2276 p_call->info.type = TCORE_CALL_TYPE_VIDEO;
2279 default: // only Voice/VT call is supported in CS. treat other unknown calls as error
2280 dbg("invalid type : [%d]\n", mode);
2283 dbg("Call type : [%d]\n", p_call->info.type);
2286 resp = g_slist_nth_data(tokens, 4);
2288 err("InValid Mpty");
2292 p_call->info.mpty = atoi(resp);
2293 dbg("Mpty : [ %d ]\n", p_call->info.mpty);
2296 resp = g_slist_nth_data(tokens, 5);
2297 dbg("Incoming number - %s and its len - %d", resp, strlen(resp));
2299 // tolerate null here
2301 err("Number is NULL");
2304 // Strike off double quotes
2305 num = util_removeQuotes(resp);
2306 dbg("num after removing quotes - %s", num);
2308 p_call->info.num_len = strlen(resp);
2309 dbg("num_len : [0x%x]\n", p_call->info.num_len);
2312 resp = g_slist_nth_data(tokens, 6);
2314 dbg("InValid Num type");
2317 p_call->info.num_type = atoi(resp);
2318 dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
2320 // check number is international or national.
2321 num_type = ((p_call->info.num_type) >> 4) & 0x07;
2322 dbg("called party's type of number : [0x%x]\n", num_type);
2324 if (num_type == 1 && num[0] != '+') {
2325 // international number
2326 p_call->number[0] = '+';
2327 memcpy(&(p_call->number[1]), num, strlen(num));
2329 memcpy(&(p_call->number), num, strlen(num));
2331 dbg("incoming number - %s", p_call->number);
2336 tcore_at_tok_free(tokens);
2342 err("Invalid CLCC line");
2350 tcore_at_tok_free(tokens);
2356 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
2358 GSList *tokens = NULL;
2359 const char *line = NULL;
2363 GSList *pList = NULL;
2364 CallObject *co = NULL, *dupco = NULL;
2366 dbg("function entrance");
2367 // check call with waiting status already exist
2368 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
2370 if (pList != NULL) {
2371 dbg("[error]Waiting call already exist. skip");
2374 // check call with incoming status already exist
2375 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2377 if (pList != NULL) {
2378 dbg("[error]incoming call already exist. skip");
2381 line = (char *) data;
2382 tokens = tcore_at_tok_new(line);
2384 pId = g_slist_nth_data(tokens, 0);
2386 dbg("[error]:Call id is missing from +XCALLSTAT indication");
2387 tcore_at_tok_free(tokens);
2391 call_id = atoi(pId);
2392 dupco = tcore_call_object_find_by_id(o, call_id);
2393 if (dupco != NULL) {
2394 dbg("co with same id already exist. skip");
2395 tcore_at_tok_free(tokens);
2398 co = tcore_call_object_new(o, call_id);
2400 dbg("[ error ] co is NULL");
2401 tcore_at_tok_free(tokens);
2405 tcore_at_tok_free(tokens);
2407 eflag = g_new0(gboolean, 1);
2409 dbg("calling _call_list_get");
2410 _call_list_get(o, eflag);
2413 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
2415 GSList *tokens = NULL;
2416 const char *line = NULL;
2420 GSList *pList = NULL;
2421 CallObject *co = NULL, *dupco = NULL;
2423 dbg("function entrance");
2424 // check call with incoming status already exist
2425 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2427 if (pList != NULL) {
2428 dbg("incoming call already exist. skip");
2432 line = (char *) data;
2433 tokens = tcore_at_tok_new(line);
2435 pId = g_slist_nth_data(tokens, 0);
2437 dbg("Error:Call id is missing from %XCALLSTAT indication");
2438 tcore_at_tok_free(tokens);
2442 call_id = atoi(pId);
2444 dupco = tcore_call_object_find_by_id(o, call_id);
2445 if (dupco != NULL) {
2446 dbg("co with same id already exist. skip");
2447 tcore_at_tok_free(tokens);
2451 co = tcore_call_object_new(o, call_id);
2453 dbg("[ error ] co is NULL");
2454 tcore_at_tok_free(tokens);
2458 dbg("freeing at token")
2459 tcore_at_tok_free(tokens);
2461 eflag = g_new0(gboolean, 1);
2464 dbg("calling _call_list_get");
2465 _call_list_get(o, eflag);
2468 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
2471 TcorePlugin *plugin = NULL;
2472 CallObject *co = NULL;
2477 char *pCallId = NULL;
2478 GSList *tokens = NULL;
2479 gboolean *eflag = NULL;
2480 enum tcore_call_status co_status;
2482 dbg("function entrance");
2483 plugin = tcore_object_ref_plugin(o);
2484 cmd = (char *) data;
2485 tokens = tcore_at_tok_new(cmd);
2488 pCallId = g_slist_nth_data(tokens, 0);
2490 dbg("CallId is missing from %XCALLSTAT indication");
2491 tcore_at_tok_free(tokens);
2495 dbg("call id = %d", id);
2497 if ((stat = g_slist_nth_data(tokens, 1))) {
2498 status = atoi(stat);
2500 dbg("call status = %d", status);
2503 tcore_at_tok_free(tokens);
2504 co_status = _call_status(status);
2506 dbg("co_status = %d", co_status);
2507 switch (co_status) {
2508 case CALL_STATUS_ACTIVE:
2510 dbg("call(%d) status : [ ACTIVE ]", id);
2511 co = tcore_call_object_find_by_id(o, id);
2516 _call_status_active(plugin, co);
2520 case CALL_STATUS_HELD:
2521 dbg("call(%d) status : [ held ]", id);
2524 case CALL_STATUS_DIALING:
2526 dbg("call(%d) status : [ dialing ]", id);
2527 co = tcore_call_object_find_by_id(o, id);
2529 co = tcore_call_object_new(o, id);
2531 dbg("error : tcore_call_object_new [ id : %d ]", id);
2536 tcore_call_object_set_type(co, call_type(type));
2537 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
2538 _call_status_dialing(plugin, co);
2542 case CALL_STATUS_ALERT:
2544 dbg("call(%d) status : [ alert ]", id);
2545 co = tcore_call_object_find_by_id(o, id);
2550 // Store dialed number information into Call object.
2551 eflag = g_new0(gboolean, 1);
2553 dbg("calling _call_list_get");
2554 _call_list_get(o, eflag);
2558 case CALL_STATUS_INCOMING:
2559 case CALL_STATUS_WAITING:
2560 dbg("call(%d) status : [ incoming ]", id);
2563 case CALL_STATUS_IDLE:
2565 dbg("call(%d) status : [ release ]", id);
2567 co = tcore_call_object_find_by_id(o, id);
2573 plugin = tcore_object_ref_plugin(o);
2575 dbg("plugin is NULL");
2578 _call_status_idle(plugin, co);
2583 dbg("invalid call status", id);
2588 static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
2590 struct treq_call_dial *data = 0;
2591 char *raw_str = NULL;
2592 char *cmd_str = NULL;
2594 enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
2595 TcorePending *pending = NULL;
2596 TcoreATRequest *req;
2597 gboolean ret = FALSE;
2599 dbg("function entrance");
2601 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2602 dbg("cp not ready/n");
2603 return TCORE_RETURN_ENOSYS;
2606 data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
2607 if (data->type == CALL_TYPE_VIDEO) {
2608 dbg("invalid call type")
2609 return TCORE_RETURN_FAILURE;
2612 clir = _get_clir_status(data->number);
2614 // Compose ATD Cmd string
2616 case TCORE_CALL_CLI_MODE_PRESENT:
2617 dbg("CALL_CLI_MODE_PRESENT");
2619 break; // invocation
2621 case TCORE_CALL_CLI_MODE_RESTRICT:
2622 dbg("CALL_CLI_MODE_RESTRICT");
2624 break; // suppression
2626 case TCORE_CALL_CLI_MODE_DEFAULT:
2629 dbg("CALL_CLI_MODE_DEFAULT");
2630 break; // subscription default
2633 dbg("data->number = %s", data->number);
2635 raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
2636 cmd_str = g_strdup_printf("%s", raw_str);
2638 dbg("request command : %s", cmd_str);
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_outgoing, NULL);
2651 dbg("AT request(%s) sent failed", req->cmd);
2652 return TCORE_RETURN_FAILURE;
2655 dbg("AT request(%s) sent success", req->cmd);
2657 return TCORE_RETURN_SUCCESS;
2660 static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
2662 char *cmd_str = NULL;
2663 CallObject *co = NULL;
2664 struct treq_call_answer *data = 0;
2665 TcorePending *pending = NULL;
2666 TcoreATRequest *req;
2667 gboolean ret = FALSE;
2669 dbg("function entrance");
2671 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2672 dbg("cp not ready/n");
2673 return TCORE_RETURN_ENOSYS;
2676 data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
2677 co = tcore_call_object_find_by_id(o, data->id);
2678 if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
2679 dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
2681 cmd_str = g_strdup_printf("%s", "ATA");
2682 pending = tcore_pending_new(o, 0);
2683 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2684 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2686 tcore_pending_set_request_data(pending, 0, req);
2687 ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
2691 dbg("AT request(%s) sent failed", req->cmd);
2692 return TCORE_RETURN_FAILURE;
2695 switch (data->type) {
2696 case CALL_ANSWER_TYPE_REJECT:
2698 dbg("call answer reject");
2699 tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
2703 case CALL_ANSWER_TYPE_REPLACE:
2705 dbg("call answer replace");
2706 tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
2710 case CALL_ANSWER_TYPE_HOLD_ACCEPT:
2712 dbg("call answer hold and accept");
2713 tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
2718 dbg("[ error ] wrong answer type [ %d ]", data->type);
2719 return TCORE_RETURN_FAILURE;
2723 return TCORE_RETURN_SUCCESS;
2726 static TReturn s_call_release(CoreObject *o, UserRequest *ur)
2728 CallObject *co = NULL;
2729 struct treq_call_end *data = 0;
2730 UserRequest *ur_dup = NULL;
2731 char *chld0_cmd = NULL;
2732 char *chld1_cmd = NULL;
2733 TcorePending *pending = NULL, *pending1 = NULL;
2734 TcoreATRequest *req, *req1;
2735 gboolean ret = FALSE;
2737 dbg("function entrance");
2738 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2739 dbg("cp not ready/n");
2740 return TCORE_RETURN_ENOSYS;
2742 data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
2743 co = tcore_call_object_find_by_id(o, data->id);
2745 dbg("type of release call = %d", data->type);
2747 if (data->type == CALL_END_TYPE_ALL) {
2748 // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
2749 chld0_cmd = g_strdup("AT+CHLD=0");
2750 chld1_cmd = g_strdup("AT+CHLD=1");
2752 pending = tcore_pending_new(o, 0);
2753 req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
2755 dbg("input command is %s", chld0_cmd);
2756 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2758 tcore_pending_set_request_data(pending, 0, req);
2759 ur_dup = tcore_user_request_new(NULL, NULL);
2760 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
2764 dbg("AT request %s has failed ", req->cmd);
2766 tcore_user_request_free(ur_dup);
2770 return TCORE_RETURN_FAILURE;
2773 pending1 = tcore_pending_new(o, 0);
2774 req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
2776 dbg("input command is %s", chld1_cmd);
2777 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2779 tcore_pending_set_request_data(pending1, 0, req1);
2780 ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
2784 dbg("AT request %s has failed ", req->cmd);
2785 return TCORE_RETURN_FAILURE;
2788 switch (data->type) {
2789 case CALL_END_TYPE_DEFAULT:
2792 id = tcore_call_object_get_id(co);
2794 dbg("call end call id [%d]", id);
2795 tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
2799 case CALL_END_TYPE_ACTIVE_ALL:
2801 dbg("call end all active");
2802 tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
2806 case CALL_END_TYPE_HOLD_ALL:
2808 dbg("call end all held");
2809 tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
2814 dbg("[ error ] wrong end type [ %d ]", data->type);
2815 return TCORE_RETURN_FAILURE;
2819 return TCORE_RETURN_SUCCESS;
2822 static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
2824 struct treq_call_hold *hold = 0;
2825 CallObject *co = NULL;
2827 dbg("function entrance");
2829 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2830 dbg("cp not ready/n");
2831 return TCORE_RETURN_ENOSYS;
2834 hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
2835 dbg("call id : [ %d ]", hold->id);
2837 co = tcore_call_object_find_by_id(o, hold->id);
2838 tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
2840 return TCORE_RETURN_SUCCESS;
2843 static TReturn s_call_active(CoreObject *o, UserRequest *ur)
2845 struct treq_call_active *active = 0;
2846 CallObject *co = NULL;
2848 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2849 dbg("cp not ready/n");
2850 return TCORE_RETURN_ENOSYS;
2853 active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
2854 dbg("call id : [ %d ]", active->id);
2856 co = tcore_call_object_find_by_id(o, active->id);
2857 tcore_call_control_active(o, ur, on_confirmation_call_active, co);
2859 return TCORE_RETURN_SUCCESS;
2862 static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
2864 struct treq_call_swap *swap = NULL;
2865 CallObject *co = NULL;
2867 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2868 dbg("cp not ready/n");
2869 return TCORE_RETURN_ENOSYS;
2872 swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
2873 dbg("call id : [ %d ]", swap->id);
2875 co = tcore_call_object_find_by_id(o, swap->id);
2876 tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
2878 return TCORE_RETURN_SUCCESS;
2881 static TReturn s_call_join(CoreObject *o, UserRequest *ur)
2883 struct treq_call_join *join = 0;
2884 CallObject *co = NULL;
2886 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2887 dbg("cp not ready/n");
2888 return TCORE_RETURN_ENOSYS;
2891 join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
2892 dbg("call id : [ %d ]", join->id);
2894 co = tcore_call_object_find_by_id(o, join->id);
2895 tcore_call_control_join(o, ur, on_confirmation_call_join, co);
2897 return TCORE_RETURN_SUCCESS;
2900 static TReturn s_call_split(CoreObject *o, UserRequest *ur)
2902 struct treq_call_split *split = 0;
2903 CallObject *co = NULL;
2905 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2906 dbg("cp not ready/n");
2907 return TCORE_RETURN_ENOSYS;
2910 split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
2911 co = tcore_call_object_find_by_id(o, split->id);
2912 dbg("call id : [ %d ]", split->id);
2914 tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
2916 return TCORE_RETURN_SUCCESS;
2919 static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
2921 struct treq_call_deflect *deflect = 0;
2922 CallObject *co = NULL;
2924 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2925 dbg("cp not ready/n");
2926 return TCORE_RETURN_ENOSYS;
2929 deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
2930 co = tcore_call_object_find_by_number(o, deflect->number);
2931 dbg("deflect number: [ %s ]", deflect->number);
2933 tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
2935 return TCORE_RETURN_SUCCESS;
2938 static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
2940 struct treq_call_transfer *transfer = 0;
2941 CallObject *co = NULL;
2943 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2944 dbg("cp not ready/n");
2945 return TCORE_RETURN_ENOSYS;
2948 transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
2949 dbg("call id : [ %d ]", transfer->id);
2951 co = tcore_call_object_find_by_id(o, transfer->id);
2952 tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
2954 return TCORE_RETURN_SUCCESS;
2957 static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
2959 char *cmd_str = NULL;
2960 TcorePending *pending = NULL;
2961 TcoreATRequest *req;
2963 gboolean ret = FALSE;
2964 struct treq_call_dtmf *dtmf = 0;
2965 char *dtmfstr = NULL, *tmp_dtmf = NULL;
2966 unsigned int dtmf_count;
2968 dbg("Function enter");
2970 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2971 dbg("cp not ready/n");
2972 return TCORE_RETURN_ENOSYS;
2975 dup = tcore_user_request_new(NULL, NULL);
2976 (void) _set_dtmf_tone_duration(o, dup);
2978 dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
2979 dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1); // DTMF digits + comma for each dtmf digit.
2981 if (dtmfstr == NULL) {
2982 dbg("Memory allocation failed");
2983 return TCORE_RETURN_FAILURE;
2988 for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
2989 *tmp_dtmf = dtmf->digits[dtmf_count];
2996 // last digit is having COMMA , overwrite it with '\0' .
2997 *(--tmp_dtmf) = '\0';
2998 dbg("Input DTMF string(%s)", dtmfstr);
3000 // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
3001 cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
3002 dbg("request command : %s", cmd_str);
3004 pending = tcore_pending_new(o, 0);
3005 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3006 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3008 tcore_pending_set_request_data(pending, 0, req);
3009 ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
3014 dbg("AT request sent failed")
3015 return TCORE_RETURN_FAILURE;
3018 return TCORE_RETURN_SUCCESS;
3021 static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
3023 UserRequest *ur_dup = NULL;
3024 TcorePending *pending = NULL, *pending1 = NULL;
3025 TcoreATRequest *req, *req1;
3026 char *cmd_str = NULL, *cmd_str1 = NULL;
3027 int device_type = -1;
3028 struct treq_call_sound_set_path *sound_path = 0;
3029 gboolean ret = FALSE;
3030 TcorePlugin *plugin = tcore_object_ref_plugin(o);
3031 const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
3033 dbg("function entrance");
3035 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3036 dbg("cp not ready/n");
3037 return TCORE_RETURN_ENOSYS;
3039 sound_path = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
3040 if (sound_path == NULL) {
3041 dbg("invaling user request");
3042 return TCORE_RETURN_FAILURE;
3044 dbg("audio device type - 0x%x", sound_path->path);
3045 switch (sound_path->path) {
3046 case CALL_SOUND_PATH_HANDSET:
3050 case CALL_SOUND_PATH_HEADSET:
3054 case CALL_SOUND_PATH_HEADSET_3_5PI:
3058 case CALL_SOUND_PATH_SPEAKER:
3062 case CALL_SOUND_PATH_HANDFREE:
3066 case CALL_SOUND_PATH_HEADSET_HAC:
3070 case CALL_SOUND_PATH_BLUETOOTH:
3071 case CALL_SOUND_PATH_STEREO_BLUETOOTH:
3075 case CALL_SOUND_PATH_BT_NSEC_OFF:
3076 case CALL_SOUND_PATH_MIC1:
3077 case CALL_SOUND_PATH_MIC2:
3079 dbg("unsupported device type");
3080 return TCORE_RETURN_FAILURE;
3083 if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
3084 struct tnoti_call_sound_path *tnoti_snd_path;
3086 tnoti_snd_path = g_try_new0(struct tnoti_call_sound_path, 1);
3087 if (!tnoti_snd_path)
3088 return TCORE_RETURN_ENOMEM;
3090 tnoti_snd_path->path = sound_path->path;
3092 /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
3093 if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
3094 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);
3095 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);
3098 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);
3099 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);
3102 /* Configure modem I2S2 and do the modem routing */
3103 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);
3104 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);
3105 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
3106 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
3107 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
3108 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
3111 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
3112 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
3113 /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
3115 pending = tcore_pending_new(o, 0);
3116 req = tcore_at_request_new("AT+XDRV=40,6,0,2", "+XDRV", TCORE_AT_SINGLELINE);
3117 dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3118 tcore_pending_set_request_data(pending, 0, req);
3119 ur_dup = tcore_user_request_ref(ur);
3120 ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, tnoti_snd_path);
3124 cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
3125 pending = tcore_pending_new(o, 0);
3126 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3127 dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3128 tcore_pending_set_request_data(pending, 0, req);
3129 ur_dup = tcore_user_request_ref(ur);
3130 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
3134 dbg("At request(%s) sent failed", req->cmd);
3135 return TCORE_RETURN_FAILURE;
3138 cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
3139 pending1 = tcore_pending_new(o, 0);
3140 req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
3141 dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
3142 tcore_pending_set_request_data(pending1, 0, req1);
3143 ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
3147 dbg("AT request %s has failed ", req1->cmd);
3148 return TCORE_RETURN_FAILURE;
3152 return TCORE_RETURN_SUCCESS;
3155 static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
3157 UserRequest *src_ur = NULL;
3158 UserRequest *dest_ur = NULL;
3159 TcorePending *src_pending = NULL;
3160 TcorePending *dest_pending = NULL;
3161 TcoreATRequest *src_req = NULL;
3162 TcoreATRequest *dest_req = NULL;
3163 char *cmd_str = NULL, *volume_level = NULL;
3164 gboolean ret = FALSE;
3165 struct treq_call_sound_set_volume_level *data = NULL;
3169 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3170 dbg("cp not ready/n");
3171 return TCORE_RETURN_ENOSYS;
3174 data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
3176 // Hard-coded values for MIC & Speakers
3178 dbg("Set Source volume");
3180 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source type
3181 dbg("Request command string: %s", cmd_str);
3183 // Create new Pending request
3184 src_pending = tcore_pending_new(o, 0);
3186 // Create new AT-Command request
3187 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3188 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3190 // Free Command string
3193 tcore_pending_set_request_data(src_pending, 0, src_req);
3194 src_ur = tcore_user_request_ref(ur);
3197 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3199 err("Failed to send AT-Command request");
3200 return TCORE_RETURN_FAILURE;
3203 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type
3204 dbg("Request command string: %s", cmd_str);
3206 // Create new Pending request
3207 src_pending = tcore_pending_new(o, 0);
3209 // Create new AT-Command request
3210 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3211 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3213 // Free Command string
3216 tcore_pending_set_request_data(src_pending, 0, src_req);
3218 src_ur = tcore_user_request_ref(ur);
3221 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3223 err("Failed to send AT-Command request");
3224 return TCORE_RETURN_FAILURE;
3227 // Destination volume
3228 dbg("Set Source volume");
3230 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type
3231 dbg("Request command string: %s", cmd_str);
3233 // Create new Pending request
3234 dest_pending = tcore_pending_new(o, 0);
3236 // Create new AT-Command request
3237 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3238 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3240 // Free Command string
3243 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3244 dest_ur = tcore_user_request_ref(ur);
3247 ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3249 err("Failed to send AT-Command request");
3250 return TCORE_RETURN_FAILURE;
3253 dbg("Input volume level - %d", data->volume);
3254 switch (data->volume) {
3255 case CALL_SOUND_MUTE:
3259 case CALL_SOUND_VOLUME_LEVEL_1:
3260 volume_level = "40";
3263 case CALL_SOUND_VOLUME_LEVEL_2:
3264 volume_level = "46";
3267 case CALL_SOUND_VOLUME_LEVEL_3:
3268 volume_level = "52";
3271 case CALL_SOUND_VOLUME_LEVEL_4:
3272 volume_level = "58";
3275 case CALL_SOUND_VOLUME_LEVEL_5:
3276 volume_level = "64";
3279 case CALL_SOUND_VOLUME_LEVEL_6:
3280 volume_level = "70";
3283 case CALL_SOUND_VOLUME_LEVEL_7:
3284 volume_level = "76";
3287 case CALL_SOUND_VOLUME_LEVEL_8:
3288 volume_level = "82";
3291 case CALL_SOUND_VOLUME_LEVEL_9:
3293 volume_level = "88";
3296 cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level); // Destination type
3297 dbg("Request command string: %s", cmd_str);
3299 // Create new Pending request
3300 dest_pending = tcore_pending_new(o, 0);
3302 // Create new AT-Command request
3303 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3304 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3306 // Free Command string
3309 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3312 ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
3314 err("Failed to send AT-Command request");
3315 return TCORE_RETURN_FAILURE;
3318 return TCORE_RETURN_SUCCESS;
3322 static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
3327 return TCORE_RETURN_SUCCESS;
3330 static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
3332 char *cmd_str = NULL;
3333 TcorePending *pending = NULL;
3334 TcoreATRequest *req = NULL;
3335 gboolean ret = FALSE;
3339 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3340 dbg("cp not ready/n");
3341 return TCORE_RETURN_ENOSYS;
3344 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
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, "+XDRV", TCORE_AT_SINGLELINE);
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_call_mute, NULL);
3364 err("Failed to send AT-Command request");
3365 return TCORE_RETURN_FAILURE;
3369 return TCORE_RETURN_SUCCESS;
3372 static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
3374 char *cmd_str = NULL;
3375 TcorePending *pending = NULL;
3376 TcoreATRequest *req = NULL;
3377 gboolean ret = FALSE;
3381 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3382 dbg("cp not ready/n");
3383 return TCORE_RETURN_ENOSYS;
3386 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
3387 dbg("Request command string: %s", cmd_str);
3389 // Create new Pending request
3390 pending = tcore_pending_new(o, 0);
3392 // Create new AT-Command request
3393 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3394 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3396 // Free command string
3399 // Set request data (AT command) to Pending request
3400 tcore_pending_set_request_data(pending, 0, req);
3403 ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
3405 err("Failed to send AT-Command request");
3406 return TCORE_RETURN_FAILURE;
3410 return TCORE_RETURN_SUCCESS;
3414 static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
3419 return TCORE_RETURN_SUCCESS;
3422 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
3424 char *cmd_str = NULL;
3425 TcorePending *pending = NULL;
3426 TcoreATRequest *req = NULL;
3427 gboolean ret = FALSE;
3431 cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.
3432 dbg("Request command string: %s", cmd_str);
3434 // Create new Pending request
3435 pending = tcore_pending_new(o, 0);
3437 // Create new AT-Command request
3438 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3439 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3441 // Free command string */
3444 // Set request data (AT command) to Pending request
3445 tcore_pending_set_request_data(pending, 0, req);
3448 ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
3450 err("Failed to send AT-Command request");
3452 tcore_user_request_free(ur);
3455 return TCORE_RETURN_FAILURE;
3459 return TCORE_RETURN_SUCCESS;
3463 static struct tcore_call_operations call_ops = {
3464 .dial = s_call_outgoing,
3465 .answer = s_call_answer,
3466 .end = s_call_release,
3467 .hold = s_call_hold,
3468 .active = s_call_active,
3469 .swap = s_call_swap,
3470 .join = s_call_join,
3471 .split = s_call_split,
3472 .deflect = s_call_deflect,
3473 .transfer = s_call_transfer,
3474 .send_dtmf = s_call_send_dtmf,
3475 .set_sound_path = s_call_set_sound_path,
3476 .set_sound_volume_level = s_call_set_sound_volume_level,
3477 .get_sound_volume_level = s_call_get_sound_volume_level,
3478 .mute = s_call_mute,
3479 .unmute = s_call_unmute,
3480 .get_mute_status = s_call_get_mute_status,
3481 .set_sound_recording = NULL,
3482 .set_sound_equalization = NULL,
3483 .set_sound_noise_reduction = NULL,
3486 gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call)
3490 tcore_call_override_ops(co_call, &call_ops, NULL);
3493 tcore_object_override_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
3494 tcore_object_override_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
3501 void s_call_exit(TcorePlugin *cp, CoreObject *co_call)