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,
1498 const TcoreATResponse *resp = data;
1499 struct tnoti_call_sound_path *snd_path = user_data;
1500 struct tresp_call_sound_set_path resp_set_sound_path;
1501 UserRequest *ur = tcore_pending_ref_user_request(p);
1502 TcorePlugin *plugin = tcore_pending_ref_plugin(p);
1503 CoreObject *co_call;
1506 err("User Request is NULL");
1511 if (resp->success <= 0) {
1513 dbg("RESPONSE NOT OK");
1514 resp_set_sound_path.err = TRUE;
1520 resp_set_sound_path.err = FALSE;
1522 co_call = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
1524 /* Notify control plugin about sound path */
1525 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
1526 co_call, TNOTI_CALL_SOUND_PATH,
1527 sizeof(struct tnoti_call_sound_path),
1531 /* Answer TAPI request */
1532 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH,
1533 sizeof(resp_set_sound_path),
1534 &resp_set_sound_path);
1539 static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1541 UserRequest *ur = NULL;
1542 GSList *tokens = NULL;
1543 const char *line = NULL;
1544 const TcoreATResponse *response = data;
1545 char *resp_str = NULL;
1546 struct tresp_call_sound_set_path resp;
1550 ur = tcore_pending_ref_user_request(p);
1552 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1554 err("Input data is NULL");
1558 if (response->success > 0) {
1561 line = (const char *) (((GSList *) response->lines)->data);
1562 tokens = tcore_at_tok_new(line);
1564 resp_str = g_slist_nth_data(tokens, 0);
1565 if (!g_slist_nth_data(tokens, 0)) {
1566 err("group_id is missing");
1571 if (!g_slist_nth_data(tokens, 1)) {
1572 err(" function_id is missing");
1577 resp_str = g_slist_nth_data(tokens, 2);
1580 error = atoi(resp_str);
1582 dbg("Response is Success");
1590 tcore_at_tok_free(tokens);
1592 dbg("RESPONSE NOT OK");
1594 line = (const char *) response->final_response;
1595 tokens = tcore_at_tok_new(line);
1597 if (g_slist_length(tokens) < 1) {
1598 err("err cause not specified or string corrupted");
1601 error = atoi(g_slist_nth_data(tokens, 0));
1603 // TODO: CMEE error mapping is required.
1608 tcore_at_tok_free(tokens);
1612 if ( resp.err ) { // Send only failed notification . success notification send when destination device is set.
1613 // Send notification to TAPI
1614 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1615 setsoundpath = TRUE;
1618 err("User Request is NULL");
1625 static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1627 UserRequest *ur = NULL;
1628 GSList *tokens = NULL;
1629 const char *line = NULL;
1630 char *resp_str = NULL;
1631 struct tresp_call_sound_set_path resp;
1632 const TcoreATResponse *response = data;
1637 ur = tcore_pending_ref_user_request(p);
1638 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1641 err("Input data is NULL");
1646 if (response->success > 0) {
1649 line = (const char *) (((GSList *) response->lines)->data);
1650 tokens = tcore_at_tok_new(line);
1652 resp_str = g_slist_nth_data(tokens, 0);
1653 if (!g_slist_nth_data(tokens, 0)) {
1654 dbg("group_id is missing");
1659 if (!g_slist_nth_data(tokens, 1)) {
1660 dbg("function_id is missing");
1665 resp_str = g_slist_nth_data(tokens, 2);
1667 error = atoi(resp_str);
1669 dbg("Response is Success");
1678 tcore_at_tok_free(tokens);
1680 dbg("RESPONSE NOT OK");
1682 line = (const char *) response->final_response;
1683 tokens = tcore_at_tok_new(line);
1685 if (g_slist_length(tokens) < 1) {
1686 err("err cause not specified or string corrupted");
1689 error = atoi(g_slist_nth_data(tokens, 0));
1690 // TODO: CMEE error mapping is required.
1695 tcore_at_tok_free(tokens);
1698 if (setsoundpath == TRUE) {
1699 setsoundpath = FALSE;
1701 // Send response to TAPI
1702 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1705 dbg("User Request is NULL");
1712 static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1714 UserRequest *ur = NULL;
1715 GSList *tokens = NULL;
1716 const char *line = NULL;
1717 const TcoreATResponse *response = data;
1718 char *resp_str = NULL;
1719 struct tresp_call_sound_set_volume_level resp;
1722 ur = tcore_pending_ref_user_request(p);
1724 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1726 err("Input data is NULL");
1730 if (response->success > 0) {
1733 line = (const char *) (((GSList *) response->lines)->data);
1734 tokens = tcore_at_tok_new(line);
1736 resp_str = g_slist_nth_data(tokens, 0);
1737 if (!g_slist_nth_data(tokens, 0)) {
1738 err("group_id is missing");
1743 if (!g_slist_nth_data(tokens, 1)) {
1744 err("function_id is missing");
1749 resp_str = g_slist_nth_data(tokens, 2);
1751 error = atoi(resp_str);
1754 dbg("Response is Success ");
1763 tcore_at_tok_free(tokens);
1765 dbg("RESPONSE NOT OK");
1767 line = (const char *) response->final_response;
1768 tokens = tcore_at_tok_new(line);
1770 if (g_slist_length(tokens) < 1) {
1771 err("err cause not specified or string corrupted");
1774 error = atoi(g_slist_nth_data(tokens, 0));
1776 // TODO: CMEE error mapping is required.
1781 tcore_at_tok_free(tokens);
1785 if (resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.
1786 // Send reposne to TAPI
1787 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1791 err("User Request is NULL");
1799 static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1801 UserRequest *ur = NULL;
1802 GSList *tokens = NULL;
1803 const char *line = NULL;
1804 char *resp_str = NULL;
1805 const TcoreATResponse *response = data;
1806 struct tresp_call_sound_set_volume_level resp;
1811 ur = tcore_pending_ref_user_request(p);
1813 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1815 err("Input data is NULL");
1820 if (response->success > 0) {
1822 line = (const char *) (((GSList *) response->lines)->data);
1823 tokens = tcore_at_tok_new(line);
1824 resp_str = g_slist_nth_data(tokens, 0);
1826 if (!g_slist_nth_data(tokens, 0)) {
1827 err("group_id is missing");
1832 if (!g_slist_nth_data(tokens, 1)) {
1833 err("function_id is missing");
1838 resp_str = g_slist_nth_data(tokens, 2);
1841 error = atoi(resp_str);
1844 dbg("Response is Success");
1853 tcore_at_tok_free(tokens);
1855 dbg("RESPONSE NOT OK");
1857 line = (const char *) response->final_response;
1858 tokens = tcore_at_tok_new(line);
1860 if (g_slist_length(tokens) < 1) {
1861 err("err cause not specified or string corrupted");
1864 error = atoi(g_slist_nth_data(tokens, 0));
1866 // TODO: CMEE error mapping is required.
1870 tcore_at_tok_free(tokens);
1873 if (soundvolume == TRUE) {
1874 soundvolume = FALSE;
1876 // Send reposne to TAPI
1877 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1880 err("User Request is NULL");
1888 static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
1890 UserRequest *ur = NULL;
1891 GSList *tokens = NULL;
1892 const char *line = NULL;
1893 char *resp_str = NULL;
1894 struct tresp_call_mute resp;
1895 const TcoreATResponse *response = data;
1900 ur = tcore_pending_ref_user_request(p);
1903 err("Input data is NULL");
1907 if (response->success > 0) {
1910 line = (const char *) (((GSList *) response->lines)->data);
1911 tokens = tcore_at_tok_new(line);
1912 resp_str = g_slist_nth_data(tokens, 0);
1914 if (!g_slist_nth_data(tokens, 0)) {
1915 err("group_id is missing");
1920 if (!g_slist_nth_data(tokens, 1)) {
1921 err(" function_id is missing");
1926 resp_str = g_slist_nth_data(tokens, 2);
1929 error = atoi(resp_str);
1931 dbg("Response is Success");
1939 tcore_at_tok_free(tokens);
1941 dbg("RESPONSE NOT OK");
1943 line = (const char *) response->final_response;
1944 tokens = tcore_at_tok_new(line);
1946 if (g_slist_length(tokens) < 1) {
1947 err("err cause not specified or string corrupted");
1950 error = atoi(g_slist_nth_data(tokens, 0));
1952 // TODO: CMEE error mapping is required.
1957 tcore_at_tok_free(tokens);
1961 tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
1963 err("User Request is NULL");
1970 static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
1972 const TcoreATResponse *response = NULL;
1973 struct tresp_call_unmute resp;
1974 GSList *tokens = NULL;
1975 const char *line = NULL;
1976 UserRequest *ur = NULL;
1977 char *resp_str = NULL;
1982 response = (TcoreATResponse *) data;
1983 ur = tcore_pending_ref_user_request(p);
1986 err("Input data is NULL");
1990 if (response->success > 0) {
1993 line = (const char *) (((GSList *) response->lines)->data);
1994 tokens = tcore_at_tok_new(line);
1995 resp_str = g_slist_nth_data(tokens, 0);
1997 if (!g_slist_nth_data(tokens, 0)) {
1998 err("group_id is missing");
2003 if (!g_slist_nth_data(tokens, 1)) {
2004 err(" function_id is missing");
2009 resp_str = g_slist_nth_data(tokens, 2);
2012 error = atoi(resp_str);
2014 dbg("Response is Success");
2022 tcore_at_tok_free(tokens);
2024 dbg("RESPONSE NOT OK");
2026 line = (const char *) response->final_response;
2027 tokens = tcore_at_tok_new(line);
2029 if (g_slist_length(tokens) < 1) {
2030 err("err cause not specified or string corrupted");
2033 error = atoi(g_slist_nth_data(tokens, 0));
2035 // TODO: CMEE error mapping is required.
2040 tcore_at_tok_free(tokens);
2044 tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
2046 err("User Request is NULL");
2054 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
2056 TcorePlugin *plugin = NULL;
2057 CoreObject *core_obj = NULL;
2058 CallObject *co = NULL;
2059 struct clcc_call_t *call_list = NULL;
2060 gboolean *event_flag = (gboolean *) user_data;
2061 const TcoreATResponse *response = data;
2062 GSList *resp_data = NULL;
2065 int cllc_info = 0, countCalls = 0, countValidCalls = 0;
2070 plugin = tcore_pending_ref_plugin(p);
2071 core_obj = tcore_pending_ref_core_object(p);
2073 if (response->success > 0) {
2075 if (response->lines) {
2076 resp_data = (GSList *) response->lines;
2077 countCalls = g_slist_length(resp_data);
2078 dbg("Total records : %d", countCalls);
2081 if (0 == countCalls) {
2082 err("Call count is zero");
2090 call_list = g_new0(struct clcc_call_t, countCalls);
2092 for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
2093 line = (char *) (resp_data->data);
2095 error = _callFromCLCCLine(line, call_list + countValidCalls);
2100 co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
2102 co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
2104 err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
2109 // Call set parameters
2110 tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
2111 tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
2112 tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
2113 tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
2114 tcore_call_object_set_active_line(co, 0);
2117 dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
2118 _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
2121 tcore_call_object_set_status(co, call_list[cllc_info].info.status);
2123 dbg("Call id : (%d)", call_list[cllc_info].info.id);
2124 dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
2125 dbg("Call type : (%d)", call_list[cllc_info].info.type);
2126 dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
2127 dbg("Call number : (%s)", call_list[cllc_info].number);
2128 dbg("Call status : (%d)", call_list[cllc_info].info.status);
2146 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
2148 TcorePlugin *plugin = NULL;
2149 CoreObject *core_obj = NULL;
2150 CallObject *co = (CallObject *) user_data;
2151 const TcoreATResponse *response = data;
2152 const char *line = NULL;
2153 struct tnoti_call_status_idle call_status;
2154 GSList *tokens = NULL;
2159 plugin = tcore_pending_ref_plugin(p);
2160 core_obj = tcore_pending_ref_core_object(p);
2162 if (response->success > 0) {
2164 line = (const char *) (((GSList *) response->lines)->data);
2165 tokens = tcore_at_tok_new(line);
2166 resp_str = g_slist_nth_data(tokens, 0);
2168 err("call end cause - report value missing");
2170 resp_str = g_slist_nth_data(tokens, 1);
2172 err("call end cause value missing");
2174 error = atoi(resp_str);
2175 dbg("call end cause - %d", error);
2176 call_status.cause = _compare_call_end_cause(error);
2177 dbg("TAPI call end cause - %d", call_status.cause);
2181 tcore_at_tok_free(tokens);
2183 err("RESPONSE NOT OK");
2184 line = (char *) response->final_response;
2185 tokens = tcore_at_tok_new(line);
2186 if (g_slist_length(tokens) < 1) {
2187 err("err cause not specified or string corrupted");
2189 err(" err cause value: %d", atoi(g_slist_nth_data(tokens, 0)));
2191 call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
2193 tcore_at_tok_free(tokens);
2196 call_status.type = tcore_call_object_get_type(co);
2197 dbg("data.type : [%d]", call_status.type);
2199 call_status.id = tcore_call_object_get_id(co);
2200 dbg("data.id : [%d]", call_status.id);
2203 tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
2205 // Send Notification to TAPI
2206 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
2208 TNOTI_CALL_STATUS_IDLE,
2209 sizeof(struct tnoti_call_status_idle),
2210 (void *) &call_status);
2213 tcore_call_object_free(core_obj, co);
2216 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
2218 // +CLCC: 1,0,2,0,0,"18005551212",145
2219 // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
2224 unsigned int num_type;
2225 GSList *tokens = NULL;
2230 tokens = tcore_at_tok_new(line);
2232 resp = g_slist_nth_data(tokens, 0);
2237 p_call->info.id = atoi(resp);
2238 dbg("id : [%d]\n", p_call->info.id);
2241 resp = g_slist_nth_data(tokens, 1);
2248 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
2250 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
2252 dbg("Direction : [ %d ]\n", p_call->info.direction);
2255 resp = g_slist_nth_data(tokens, 2);
2257 err("InValid Stat");
2261 dbg("Call state : %d", state);
2264 p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
2268 p_call->info.status = TCORE_CALL_STATUS_HELD;
2272 p_call->info.status = TCORE_CALL_STATUS_DIALING;
2276 p_call->info.status = TCORE_CALL_STATUS_ALERT;
2280 p_call->info.status = TCORE_CALL_STATUS_INCOMING;
2284 p_call->info.status = TCORE_CALL_STATUS_WAITING;
2287 dbg("Status : [%d]\n", p_call->info.status);
2290 resp = g_slist_nth_data(tokens, 3);
2292 err("InValid Mode");
2298 p_call->info.type = TCORE_CALL_TYPE_VOICE;
2302 p_call->info.type = TCORE_CALL_TYPE_VIDEO;
2305 default: // only Voice/VT call is supported in CS. treat other unknown calls as error
2306 dbg("invalid type : [%d]\n", mode);
2309 dbg("Call type : [%d]\n", p_call->info.type);
2312 resp = g_slist_nth_data(tokens, 4);
2314 err("InValid Mpty");
2318 p_call->info.mpty = atoi(resp);
2319 dbg("Mpty : [ %d ]\n", p_call->info.mpty);
2322 resp = g_slist_nth_data(tokens, 5);
2323 dbg("Incoming number - %s and its len - %d", resp, strlen(resp));
2325 // tolerate null here
2327 err("Number is NULL");
2330 // Strike off double quotes
2331 num = util_removeQuotes(resp);
2332 dbg("num after removing quotes - %s", num);
2334 p_call->info.num_len = strlen(resp);
2335 dbg("num_len : [0x%x]\n", p_call->info.num_len);
2338 resp = g_slist_nth_data(tokens, 6);
2340 dbg("InValid Num type");
2343 p_call->info.num_type = atoi(resp);
2344 dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
2346 // check number is international or national.
2347 num_type = ((p_call->info.num_type) >> 4) & 0x07;
2348 dbg("called party's type of number : [0x%x]\n", num_type);
2350 if (num_type == 1 && num[0] != '+') {
2351 // international number
2352 p_call->number[0] = '+';
2353 memcpy(&(p_call->number[1]), num, strlen(num));
2355 memcpy(&(p_call->number), num, strlen(num));
2357 dbg("incoming number - %s", p_call->number);
2362 tcore_at_tok_free(tokens);
2368 err("Invalid CLCC line");
2373 tcore_at_tok_free(tokens);
2379 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
2381 GSList *tokens = NULL;
2382 const char *line = NULL;
2386 GSList *pList = NULL;
2387 CallObject *co = NULL, *dupco = NULL;
2389 dbg("function entrance");
2390 // check call with waiting status already exist
2391 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
2393 if (pList != NULL) {
2394 dbg("[error]Waiting call already exist. skip");
2397 // check call with incoming status already exist
2398 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2400 if (pList != NULL) {
2401 dbg("[error]incoming call already exist. skip");
2404 line = (char *) data;
2405 tokens = tcore_at_tok_new(line);
2407 pId = g_slist_nth_data(tokens, 0);
2409 dbg("[error]:Call id is missing from +XCALLSTAT indication");
2410 tcore_at_tok_free(tokens);
2414 call_id = atoi(pId);
2415 dupco = tcore_call_object_find_by_id(o, call_id);
2416 if (dupco != NULL) {
2417 dbg("co with same id already exist. skip");
2418 tcore_at_tok_free(tokens);
2421 co = tcore_call_object_new(o, call_id);
2423 dbg("[ error ] co is NULL");
2424 tcore_at_tok_free(tokens);
2428 tcore_at_tok_free(tokens);
2430 eflag = g_new0(gboolean, 1);
2432 dbg("calling _call_list_get");
2433 _call_list_get(o, eflag);
2436 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
2438 GSList *tokens = NULL;
2439 const char *line = NULL;
2443 GSList *pList = NULL;
2444 CallObject *co = NULL, *dupco = NULL;
2446 dbg("function entrance");
2447 // check call with incoming status already exist
2448 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2450 if (pList != NULL) {
2451 dbg("incoming call already exist. skip");
2455 line = (char *) data;
2456 tokens = tcore_at_tok_new(line);
2458 pId = g_slist_nth_data(tokens, 0);
2460 dbg("Error:Call id is missing from %XCALLSTAT indication");
2461 tcore_at_tok_free(tokens);
2465 call_id = atoi(pId);
2467 dupco = tcore_call_object_find_by_id(o, call_id);
2468 if (dupco != NULL) {
2469 dbg("co with same id already exist. skip");
2470 tcore_at_tok_free(tokens);
2474 co = tcore_call_object_new(o, call_id);
2476 dbg("[ error ] co is NULL");
2477 tcore_at_tok_free(tokens);
2481 dbg("freeing at token");
2482 tcore_at_tok_free(tokens);
2484 eflag = g_new0(gboolean, 1);
2487 dbg("calling _call_list_get");
2488 _call_list_get(o, eflag);
2491 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
2494 TcorePlugin *plugin = NULL;
2495 CallObject *co = NULL;
2500 char *pCallId = NULL;
2501 GSList *tokens = NULL;
2502 gboolean *eflag = NULL;
2503 enum tcore_call_status co_status;
2505 dbg("function entrance");
2506 plugin = tcore_object_ref_plugin(o);
2507 cmd = (char *) data;
2508 tokens = tcore_at_tok_new(cmd);
2511 pCallId = g_slist_nth_data(tokens, 0);
2513 dbg("CallId is missing from %XCALLSTAT indication");
2514 tcore_at_tok_free(tokens);
2518 dbg("call id = %d", id);
2520 if ((stat = g_slist_nth_data(tokens, 1))) {
2521 status = atoi(stat);
2523 dbg("call status = %d", status);
2526 tcore_at_tok_free(tokens);
2527 co_status = _call_status(status);
2529 dbg("co_status = %d", co_status);
2530 switch (co_status) {
2531 case CALL_STATUS_ACTIVE:
2533 dbg("call(%d) status : [ ACTIVE ]", id);
2534 co = tcore_call_object_find_by_id(o, id);
2539 _call_status_active(plugin, co);
2543 case CALL_STATUS_HELD:
2544 dbg("call(%d) status : [ held ]", id);
2547 case CALL_STATUS_DIALING:
2549 dbg("call(%d) status : [ dialing ]", id);
2550 co = tcore_call_object_find_by_id(o, id);
2552 co = tcore_call_object_new(o, id);
2554 dbg("error : tcore_call_object_new [ id : %d ]", id);
2559 tcore_call_object_set_type(co, call_type(type));
2560 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
2561 _call_status_dialing(plugin, co);
2565 case CALL_STATUS_ALERT:
2567 dbg("call(%d) status : [ alert ]", id);
2568 co = tcore_call_object_find_by_id(o, id);
2573 // Store dialed number information into Call object.
2574 eflag = g_new0(gboolean, 1);
2576 dbg("calling _call_list_get");
2577 _call_list_get(o, eflag);
2581 case CALL_STATUS_INCOMING:
2582 case CALL_STATUS_WAITING:
2583 dbg("call(%d) status : [ incoming ]", id);
2586 case CALL_STATUS_IDLE:
2588 dbg("call(%d) status : [ release ]", id);
2590 co = tcore_call_object_find_by_id(o, id);
2596 plugin = tcore_object_ref_plugin(o);
2598 dbg("plugin is NULL");
2601 _call_status_idle(plugin, co);
2606 dbg("invalid call status", id);
2611 static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
2613 struct treq_call_dial *data = 0;
2614 char *raw_str = NULL;
2615 char *cmd_str = NULL;
2617 enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
2618 TcorePending *pending = NULL;
2619 TcoreATRequest *req;
2620 gboolean ret = FALSE;
2622 dbg("function entrance");
2624 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2625 dbg("cp not ready/n");
2626 return TCORE_RETURN_ENOSYS;
2629 data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
2630 if (data->type == CALL_TYPE_VIDEO) {
2631 dbg("invalid call type");
2632 return TCORE_RETURN_FAILURE;
2635 clir = _get_clir_status(data->number);
2637 // Compose ATD Cmd string
2639 case TCORE_CALL_CLI_MODE_PRESENT:
2640 dbg("CALL_CLI_MODE_PRESENT");
2642 break; // invocation
2644 case TCORE_CALL_CLI_MODE_RESTRICT:
2645 dbg("CALL_CLI_MODE_RESTRICT");
2647 break; // suppression
2649 case TCORE_CALL_CLI_MODE_DEFAULT:
2652 dbg("CALL_CLI_MODE_DEFAULT");
2653 break; // subscription default
2656 dbg("data->number = %s", data->number);
2658 raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
2659 cmd_str = g_strdup_printf("%s", raw_str);
2661 dbg("request command : %s", cmd_str);
2663 pending = tcore_pending_new(o, 0);
2664 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2665 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2667 tcore_pending_set_request_data(pending, 0, req);
2668 ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
2674 dbg("AT request(%s) sent failed", req->cmd);
2675 return TCORE_RETURN_FAILURE;
2678 dbg("AT request(%s) sent success", req->cmd);
2680 return TCORE_RETURN_SUCCESS;
2683 static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
2685 char *cmd_str = NULL;
2686 CallObject *co = NULL;
2687 struct treq_call_answer *data = 0;
2688 TcorePending *pending = NULL;
2689 TcoreATRequest *req;
2690 gboolean ret = FALSE;
2692 dbg("function entrance");
2694 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2695 dbg("cp not ready/n");
2696 return TCORE_RETURN_ENOSYS;
2699 data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
2700 co = tcore_call_object_find_by_id(o, data->id);
2701 if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
2702 dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
2704 cmd_str = g_strdup_printf("%s", "ATA");
2705 pending = tcore_pending_new(o, 0);
2706 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2707 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2709 tcore_pending_set_request_data(pending, 0, req);
2710 ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
2714 dbg("AT request(%s) sent failed", req->cmd);
2715 return TCORE_RETURN_FAILURE;
2718 switch (data->type) {
2719 case CALL_ANSWER_TYPE_REJECT:
2721 dbg("call answer reject");
2722 tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
2726 case CALL_ANSWER_TYPE_REPLACE:
2728 dbg("call answer replace");
2729 tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
2733 case CALL_ANSWER_TYPE_HOLD_ACCEPT:
2735 dbg("call answer hold and accept");
2736 tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
2741 dbg("[ error ] wrong answer type [ %d ]", data->type);
2742 return TCORE_RETURN_FAILURE;
2746 return TCORE_RETURN_SUCCESS;
2749 static TReturn s_call_release(CoreObject *o, UserRequest *ur)
2751 CallObject *co = NULL;
2752 struct treq_call_end *data = 0;
2753 UserRequest *ur_dup = NULL;
2754 char *chld0_cmd = NULL;
2755 char *chld1_cmd = NULL;
2756 TcorePending *pending = NULL, *pending1 = NULL;
2757 TcoreATRequest *req, *req1;
2758 gboolean ret = FALSE;
2760 dbg("function entrance");
2761 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2762 dbg("cp not ready/n");
2763 return TCORE_RETURN_ENOSYS;
2765 data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
2766 co = tcore_call_object_find_by_id(o, data->id);
2768 dbg("type of release call = %d", data->type);
2770 if (data->type == CALL_END_TYPE_ALL) {
2771 // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
2772 chld0_cmd = g_strdup("AT+CHLD=0");
2773 chld1_cmd = g_strdup("AT+CHLD=1");
2775 pending = tcore_pending_new(o, 0);
2776 req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
2778 dbg("input command is %s", chld0_cmd);
2779 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2781 tcore_pending_set_request_data(pending, 0, req);
2782 ur_dup = tcore_user_request_new(NULL, NULL);
2783 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
2787 dbg("AT request %s has failed ", req->cmd);
2789 tcore_user_request_free(ur_dup);
2793 return TCORE_RETURN_FAILURE;
2796 pending1 = tcore_pending_new(o, 0);
2797 req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
2799 dbg("input command is %s", chld1_cmd);
2800 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2802 tcore_pending_set_request_data(pending1, 0, req1);
2803 ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
2807 dbg("AT request %s has failed ", req->cmd);
2808 return TCORE_RETURN_FAILURE;
2811 switch (data->type) {
2812 case CALL_END_TYPE_DEFAULT:
2815 id = tcore_call_object_get_id(co);
2817 dbg("call end call id [%d]", id);
2818 tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
2822 case CALL_END_TYPE_ACTIVE_ALL:
2824 dbg("call end all active");
2825 tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
2829 case CALL_END_TYPE_HOLD_ALL:
2831 dbg("call end all held");
2832 tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
2837 dbg("[ error ] wrong end type [ %d ]", data->type);
2838 return TCORE_RETURN_FAILURE;
2842 return TCORE_RETURN_SUCCESS;
2845 static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
2847 struct treq_call_hold *hold = 0;
2848 CallObject *co = NULL;
2850 dbg("function entrance");
2852 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2853 dbg("cp not ready/n");
2854 return TCORE_RETURN_ENOSYS;
2857 hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
2858 dbg("call id : [ %d ]", hold->id);
2860 co = tcore_call_object_find_by_id(o, hold->id);
2861 tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
2863 return TCORE_RETURN_SUCCESS;
2866 static TReturn s_call_active(CoreObject *o, UserRequest *ur)
2868 struct treq_call_active *active = 0;
2869 CallObject *co = NULL;
2871 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2872 dbg("cp not ready/n");
2873 return TCORE_RETURN_ENOSYS;
2876 active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
2877 dbg("call id : [ %d ]", active->id);
2879 co = tcore_call_object_find_by_id(o, active->id);
2880 tcore_call_control_active(o, ur, on_confirmation_call_active, co);
2882 return TCORE_RETURN_SUCCESS;
2885 static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
2887 struct treq_call_swap *swap = NULL;
2888 CallObject *co = NULL;
2890 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2891 dbg("cp not ready/n");
2892 return TCORE_RETURN_ENOSYS;
2895 swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
2896 dbg("call id : [ %d ]", swap->id);
2898 co = tcore_call_object_find_by_id(o, swap->id);
2899 tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
2901 return TCORE_RETURN_SUCCESS;
2904 static TReturn s_call_join(CoreObject *o, UserRequest *ur)
2906 struct treq_call_join *join = 0;
2907 CallObject *co = NULL;
2909 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2910 dbg("cp not ready/n");
2911 return TCORE_RETURN_ENOSYS;
2914 join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
2915 dbg("call id : [ %d ]", join->id);
2917 co = tcore_call_object_find_by_id(o, join->id);
2918 tcore_call_control_join(o, ur, on_confirmation_call_join, co);
2920 return TCORE_RETURN_SUCCESS;
2923 static TReturn s_call_split(CoreObject *o, UserRequest *ur)
2925 struct treq_call_split *split = 0;
2926 CallObject *co = NULL;
2928 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2929 dbg("cp not ready/n");
2930 return TCORE_RETURN_ENOSYS;
2933 split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
2934 co = tcore_call_object_find_by_id(o, split->id);
2935 dbg("call id : [ %d ]", split->id);
2937 tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
2939 return TCORE_RETURN_SUCCESS;
2942 static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
2944 struct treq_call_deflect *deflect = 0;
2945 CallObject *co = NULL;
2947 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2948 dbg("cp not ready/n");
2949 return TCORE_RETURN_ENOSYS;
2952 deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
2953 co = tcore_call_object_find_by_number(o, deflect->number);
2954 dbg("deflect number: [ %s ]", deflect->number);
2956 tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
2958 return TCORE_RETURN_SUCCESS;
2961 static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
2963 struct treq_call_transfer *transfer = 0;
2964 CallObject *co = NULL;
2966 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2967 dbg("cp not ready/n");
2968 return TCORE_RETURN_ENOSYS;
2971 transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
2972 dbg("call id : [ %d ]", transfer->id);
2974 co = tcore_call_object_find_by_id(o, transfer->id);
2975 tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
2977 return TCORE_RETURN_SUCCESS;
2980 static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
2982 char *cmd_str = NULL;
2983 TcorePending *pending = NULL;
2984 TcoreATRequest *req;
2986 gboolean ret = FALSE;
2987 struct treq_call_dtmf *dtmf = 0;
2988 char *dtmfstr = NULL, *tmp_dtmf = NULL;
2989 unsigned int dtmf_count;
2991 dbg("Function enter");
2993 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2994 dbg("cp not ready/n");
2995 return TCORE_RETURN_ENOSYS;
2998 dup = tcore_user_request_new(NULL, NULL);
2999 (void) _set_dtmf_tone_duration(o, dup);
3001 dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
3002 dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1); // DTMF digits + comma for each dtmf digit.
3004 if (dtmfstr == NULL) {
3005 dbg("Memory allocation failed");
3006 return TCORE_RETURN_FAILURE;
3011 for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
3012 *tmp_dtmf = dtmf->digits[dtmf_count];
3019 // last digit is having COMMA , overwrite it with '\0' .
3020 *(--tmp_dtmf) = '\0';
3021 dbg("Input DTMF string(%s)", dtmfstr);
3023 // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
3024 cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
3025 dbg("request command : %s", cmd_str);
3027 pending = tcore_pending_new(o, 0);
3028 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3029 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3031 tcore_pending_set_request_data(pending, 0, req);
3032 ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
3037 dbg("AT request sent failed");
3038 return TCORE_RETURN_FAILURE;
3041 return TCORE_RETURN_SUCCESS;
3044 static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
3046 UserRequest *ur_dup = NULL;
3047 TcorePending *pending = NULL, *pending1 = NULL;
3048 TcoreATRequest *req, *req1;
3049 char *cmd_str = NULL, *cmd_str1 = NULL;
3050 int device_type = -1;
3051 struct treq_call_sound_set_path *sound_path = 0;
3052 gboolean ret = FALSE;
3053 TcorePlugin *plugin = tcore_object_ref_plugin(o);
3054 const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
3056 dbg("function entrance");
3058 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3059 dbg("cp not ready/n");
3060 return TCORE_RETURN_ENOSYS;
3062 sound_path = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
3063 if (sound_path == NULL) {
3064 dbg("invaling user request");
3065 return TCORE_RETURN_FAILURE;
3067 dbg("audio device type - 0x%x", sound_path->path);
3068 switch (sound_path->path) {
3069 case CALL_SOUND_PATH_HANDSET:
3073 case CALL_SOUND_PATH_HEADSET:
3077 case CALL_SOUND_PATH_HEADSET_3_5PI:
3081 case CALL_SOUND_PATH_SPEAKER:
3085 case CALL_SOUND_PATH_HANDFREE:
3089 case CALL_SOUND_PATH_HEADSET_HAC:
3093 case CALL_SOUND_PATH_BLUETOOTH:
3094 case CALL_SOUND_PATH_STEREO_BLUETOOTH:
3098 case CALL_SOUND_PATH_BT_NSEC_OFF:
3099 case CALL_SOUND_PATH_MIC1:
3100 case CALL_SOUND_PATH_MIC2:
3102 dbg("unsupported device type");
3103 return TCORE_RETURN_FAILURE;
3106 if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
3107 struct tnoti_call_sound_path *tnoti_snd_path;
3109 tnoti_snd_path = g_try_new0(struct tnoti_call_sound_path, 1);
3110 if (!tnoti_snd_path)
3111 return TCORE_RETURN_ENOMEM;
3113 tnoti_snd_path->path = sound_path->path;
3115 /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
3116 if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
3117 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);
3118 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);
3121 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);
3122 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);
3125 /* Configure modem I2S2 and do the modem routing */
3126 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);
3127 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);
3128 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
3129 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
3130 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
3131 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
3134 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
3135 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
3136 /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
3138 pending = tcore_pending_new(o, 0);
3139 req = tcore_at_request_new("AT+XDRV=40,6,0,2", "+XDRV", TCORE_AT_SINGLELINE);
3140 dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3141 tcore_pending_set_request_data(pending, 0, req);
3142 ur_dup = tcore_user_request_ref(ur);
3143 ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, tnoti_snd_path);
3147 cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
3148 pending = tcore_pending_new(o, 0);
3149 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3150 dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3151 tcore_pending_set_request_data(pending, 0, req);
3152 ur_dup = tcore_user_request_ref(ur);
3153 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
3157 dbg("At request(%s) sent failed", req->cmd);
3158 return TCORE_RETURN_FAILURE;
3161 cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
3162 pending1 = tcore_pending_new(o, 0);
3163 req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
3164 dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
3165 tcore_pending_set_request_data(pending1, 0, req1);
3166 ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
3170 dbg("AT request %s has failed ", req1->cmd);
3171 return TCORE_RETURN_FAILURE;
3175 return TCORE_RETURN_SUCCESS;
3178 static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
3180 UserRequest *src_ur = NULL;
3181 UserRequest *dest_ur = NULL;
3182 TcorePending *src_pending = NULL;
3183 TcorePending *dest_pending = NULL;
3184 TcoreATRequest *src_req = NULL;
3185 TcoreATRequest *dest_req = NULL;
3186 char *cmd_str = NULL, *volume_level = NULL;
3187 gboolean ret = FALSE;
3188 struct treq_call_sound_set_volume_level *data = NULL;
3192 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3193 dbg("cp not ready/n");
3194 return TCORE_RETURN_ENOSYS;
3197 data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
3199 // Hard-coded values for MIC & Speakers
3201 dbg("Set Source volume");
3203 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source 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);
3217 src_ur = tcore_user_request_ref(ur);
3220 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3222 err("Failed to send AT-Command request");
3223 return TCORE_RETURN_FAILURE;
3226 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type
3227 dbg("Request command string: %s", cmd_str);
3229 // Create new Pending request
3230 src_pending = tcore_pending_new(o, 0);
3232 // Create new AT-Command request
3233 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3234 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3236 // Free Command string
3239 tcore_pending_set_request_data(src_pending, 0, src_req);
3241 src_ur = tcore_user_request_ref(ur);
3244 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3246 err("Failed to send AT-Command request");
3247 return TCORE_RETURN_FAILURE;
3250 // Destination volume
3251 dbg("Set Source volume");
3253 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type
3254 dbg("Request command string: %s", cmd_str);
3256 // Create new Pending request
3257 dest_pending = tcore_pending_new(o, 0);
3259 // Create new AT-Command request
3260 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3261 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3263 // Free Command string
3266 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3267 dest_ur = tcore_user_request_ref(ur);
3270 ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3272 err("Failed to send AT-Command request");
3273 return TCORE_RETURN_FAILURE;
3276 dbg("Input volume level - %d", data->volume);
3277 switch (data->volume) {
3278 case CALL_SOUND_MUTE:
3282 case CALL_SOUND_VOLUME_LEVEL_1:
3283 volume_level = "40";
3286 case CALL_SOUND_VOLUME_LEVEL_2:
3287 volume_level = "46";
3290 case CALL_SOUND_VOLUME_LEVEL_3:
3291 volume_level = "52";
3294 case CALL_SOUND_VOLUME_LEVEL_4:
3295 volume_level = "58";
3298 case CALL_SOUND_VOLUME_LEVEL_5:
3299 volume_level = "64";
3302 case CALL_SOUND_VOLUME_LEVEL_6:
3303 volume_level = "70";
3306 case CALL_SOUND_VOLUME_LEVEL_7:
3307 volume_level = "76";
3310 case CALL_SOUND_VOLUME_LEVEL_8:
3311 volume_level = "82";
3314 case CALL_SOUND_VOLUME_LEVEL_9:
3316 volume_level = "88";
3319 cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level); // Destination type
3320 dbg("Request command string: %s", cmd_str);
3322 // Create new Pending request
3323 dest_pending = tcore_pending_new(o, 0);
3325 // Create new AT-Command request
3326 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3327 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3329 // Free Command string
3332 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3335 ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
3337 err("Failed to send AT-Command request");
3338 return TCORE_RETURN_FAILURE;
3341 return TCORE_RETURN_SUCCESS;
3345 static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
3350 return TCORE_RETURN_SUCCESS;
3353 static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
3355 char *cmd_str = NULL;
3356 TcorePending *pending = NULL;
3357 TcoreATRequest *req = NULL;
3358 gboolean ret = FALSE;
3362 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3363 dbg("cp not ready/n");
3364 return TCORE_RETURN_ENOSYS;
3367 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
3369 dbg("Request command string: %s", cmd_str);
3371 // Create new Pending request
3372 pending = tcore_pending_new(o, 0);
3374 // Create new AT-Command request
3375 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3376 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3378 // Free command string
3381 // Set request data (AT command) to Pending request
3382 tcore_pending_set_request_data(pending, 0, req);
3385 ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
3387 err("Failed to send AT-Command request");
3388 return TCORE_RETURN_FAILURE;
3392 return TCORE_RETURN_SUCCESS;
3395 static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
3397 char *cmd_str = NULL;
3398 TcorePending *pending = NULL;
3399 TcoreATRequest *req = NULL;
3400 gboolean ret = FALSE;
3404 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3405 dbg("cp not ready/n");
3406 return TCORE_RETURN_ENOSYS;
3409 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
3410 dbg("Request command string: %s", cmd_str);
3412 // Create new Pending request
3413 pending = tcore_pending_new(o, 0);
3415 // Create new AT-Command request
3416 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3417 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3419 // Free command string
3422 // Set request data (AT command) to Pending request
3423 tcore_pending_set_request_data(pending, 0, req);
3426 ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
3428 err("Failed to send AT-Command request");
3429 return TCORE_RETURN_FAILURE;
3433 return TCORE_RETURN_SUCCESS;
3437 static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
3442 return TCORE_RETURN_SUCCESS;
3445 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
3447 char *cmd_str = NULL;
3448 TcorePending *pending = NULL;
3449 TcoreATRequest *req = NULL;
3450 gboolean ret = FALSE;
3454 cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.
3455 dbg("Request command string: %s", cmd_str);
3457 // Create new Pending request
3458 pending = tcore_pending_new(o, 0);
3460 // Create new AT-Command request
3461 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3462 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3464 // Free command string */
3467 // Set request data (AT command) to Pending request
3468 tcore_pending_set_request_data(pending, 0, req);
3471 ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
3473 err("Failed to send AT-Command request");
3475 tcore_user_request_free(ur);
3478 return TCORE_RETURN_FAILURE;
3482 return TCORE_RETURN_SUCCESS;
3486 static struct tcore_call_operations call_ops = {
3487 .dial = s_call_outgoing,
3488 .answer = s_call_answer,
3489 .end = s_call_release,
3490 .hold = s_call_hold,
3491 .active = s_call_active,
3492 .swap = s_call_swap,
3493 .join = s_call_join,
3494 .split = s_call_split,
3495 .deflect = s_call_deflect,
3496 .transfer = s_call_transfer,
3497 .send_dtmf = s_call_send_dtmf,
3498 .set_sound_path = s_call_set_sound_path,
3499 .set_sound_volume_level = s_call_set_sound_volume_level,
3500 .get_sound_volume_level = s_call_get_sound_volume_level,
3501 .mute = s_call_mute,
3502 .unmute = s_call_unmute,
3503 .get_mute_status = s_call_get_mute_status,
3504 .set_sound_recording = NULL,
3505 .set_sound_equalization = NULL,
3506 .set_sound_noise_reduction = NULL,
3509 gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call)
3513 tcore_call_override_ops(co_call, &call_ops, NULL);
3516 tcore_object_override_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
3517 tcore_object_override_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
3524 void s_call_exit(TcorePlugin *cp, CoreObject *co_call)