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>
34 #include <user_request.h>
42 #define STATUS_INCOMING 4
43 #define STATUS_WAITING 5
44 #define STATUS_CONNECTED 7
47 static gboolean setsoundpath = FALSE;
48 static gboolean soundvolume = FALSE;
50 // End Cause field - Call state end cause
55 // These definitions are taken from GSM 04.08 Table 10.86
57 CC_CAUSE_UNASSIGNED_NUMBER,
58 CC_CAUSE_NO_ROUTE_TO_DEST,
59 CC_CAUSE_CHANNEL_UNACCEPTABLE,
60 CC_CAUSE_OPERATOR_DETERMINED_BARRING,
61 CC_CAUSE_NORMAL_CALL_CLEARING,
63 CC_CAUSE_NO_USER_RESPONDING,
64 CC_CAUSE_USER_ALERTING_NO_ANSWER,
65 CC_CAUSE_CALL_REJECTED,
66 CC_CAUSE_NUMBER_CHANGED,
67 CC_CAUSE_NON_SELECTED_USER_CLEARING,
68 CC_CAUSE_DESTINATION_OUT_OF_ORDER,
69 CC_CAUSE_INVALID_NUMBER_FORMAT,
70 CC_CAUSE_FACILITY_REJECTED,
71 CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY,
72 CC_CAUSE_NORMAL_UNSPECIFIED,
73 CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE,
74 CC_CAUSE_NETWORK_OUT_OF_ORDER,
75 CC_CAUSE_TEMPORARY_FAILURE,
76 CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION,
77 CC_CAUSE_ACCESS_INFORMATION_DISCARDED,
78 CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE,
79 CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED,
80 CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE,
81 CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED,
82 CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG,
83 CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED,
84 CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE,
85 CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE,
86 CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED,
87 CC_CAUSE_ACM_GEQ_ACMMAX,
88 CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED,
89 CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE,
90 CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED,
91 CC_CAUSE_INVALID_TRANSACTION_ID_VALUE,
92 CC_CAUSE_USER_NOT_MEMBER_OF_CUG,
93 CC_CAUSE_INCOMPATIBLE_DESTINATION,
94 CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION,
95 CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
96 CC_CAUSE_INVALID_MANDATORY_INFORMATION,
97 CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
98 CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE,
99 CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED,
100 CC_CAUSE_CONDITIONAL_IE_ERROR,
101 CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,
102 CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY,
103 CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
104 CC_CAUSE_INTERWORKING_UNSPECIFIED,
108 REJECT_CAUSE_IMSI_UNKNOWN_IN_HLR,
109 REJECT_CAUSE_ILLEGAL_MS,
110 REJECT_CAUSE_IMSI_UNKNOWN_IN_VLR,
111 REJECT_CAUSE_IMEI_NOT_ACCEPTED,
112 REJECT_CAUSE_ILLEGAL_ME,
113 REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED,
114 REJECT_CAUSE_GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,
115 REJECT_CAUSE_MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
116 REJECT_CAUSE_IMPLICITLY_DETACHED,
117 REJECT_CAUSE_PLMN_NOT_ALLOWED,
118 REJECT_CAUSE_LA_NOT_ALLOWED,
119 REJECT_CAUSE_NATIONAL_ROAMING_NOT_ALLOWED,
120 REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
121 REJECT_CAUSE_NO_SUITABLE_CELLS_IN_LA,
122 REJECT_CAUSE_MSC_TEMPORARILY_NOT_REACHABLE,
123 REJECT_CAUSE_NETWORK_FAILURE,
124 REJECT_CAUSE_MAC_FAILURE,
125 REJECT_CAUSE_SYNCH_FAILURE,
126 REJECT_CAUSE_CONGESTTION,
127 REJECT_CAUSE_GSM_AUTH_UNACCEPTED,
128 REJECT_CAUSE_SERVICE_OPTION_NOT_SUPPORTED,
129 REJECT_CAUSE_REQ_SERV_OPT_NOT_SUBSCRIBED,
130 REJECT_CAUSE_SERVICE_OPT__OUT_OF_ORDER,
131 REJECT_CAUSE_CALL_CANNOT_BE_IDENTIFIED,
132 REJECT_CAUSE_NO_PDP_CONTEXT_ACTIVATED,
133 REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MIN_VALUE,
134 REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MAX_VALUE,
135 REJECT_CAUSE_SEMANTICALLY_INCORRECT_MSG,
136 REJECT_CAUSE_INVALID_MANDATORY_INFO,
137 REJECT_CAUSE_MESSAGE_TYPE_NON_EXISTANT,
138 REJECT_CAUSE_MESSAGE_TYPE_NOT_COMP_PRT_ST,
139 REJECT_CAUSE_IE_NON_EXISTANT,
140 REJECT_CAUSE_MSG_NOT_COMPATIBLE_PROTOCOL_STATE,
143 // Connection Management establishment rejection cause
144 REJECT_CAUSE_REJ_UNSPECIFIED,
147 REJECT_CAUSE_AS_REJ_RR_REL_IND,
148 REJECT_CAUSE_AS_REJ_RR_RANDOM_ACCESS_FAILURE,
149 REJECT_CAUSE_AS_REJ_RRC_REL_IND,
150 REJECT_CAUSE_AS_REJ_RRC_CLOSE_SESSION_IND,
151 REJECT_CAUSE_AS_REJ_RRC_OPEN_SESSION_FAILURE,
152 REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL,
153 REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL_REDIAL_NOT_ALLOWED,
154 REJECT_CAUSE_AS_REJ_LOW_LEVEL_IMMED_RETRY,
157 REJECT_CAUSE_MM_REJ_INVALID_SIM,
158 REJECT_CAUSE_MM_REJ_NO_SERVICE,
159 REJECT_CAUSE_MM_REJ_TIMER_T3230_EXP,
160 REJECT_CAUSE_MM_REJ_NO_CELL_AVAILABLE,
161 REJECT_CAUSE_MM_REJ_WRONG_STATE,
162 REJECT_CAUSE_MM_REJ_ACCESS_CLASS_BLOCKED,
163 // Definitions for release ind causes between MM and CNM
164 REJECT_CAUSE_ABORT_MSG_RECEIVED,
165 REJECT_CAUSE_OTHER_CAUSE,
168 REJECT_CAUSE_CNM_REJ_TIMER_T303_EXP,
169 REJECT_CAUSE_CNM_REJ_NO_RESOURCES,
170 REJECT_CAUSE_CNM_MM_REL_PENDING,
171 REJECT_CAUSE_CNM_INVALID_USER_DATA,
172 CALL_END_CAUSE_MAX = 255
173 } call_end_cause_e_type;
177 struct call_CLCC_info {
179 enum tcore_call_direction direction;
180 enum tcore_call_status status;
181 enum tcore_call_type type;
193 } call_end_cause_info;
195 /**************************************************************************
196 * Local Function Prototypes
197 **************************************************************************/
198 /************************* REQUESTS ***************************/
199 static void _call_status_idle(TcorePlugin *p, CallObject *co);
200 static void _call_status_active(TcorePlugin *p, CallObject *co);
201 static void _call_status_dialing(TcorePlugin *p, CallObject *co);
202 static void _call_status_alert(TcorePlugin *p, CallObject *co);
203 static void _call_status_incoming(TcorePlugin *p, CallObject *co);
204 static void _call_status_waiting(TcorePlugin *p, CallObject *co);
205 static TReturn _call_list_get(CoreObject *o, gboolean *event_flag);
206 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur);
208 /************************* CONFIRMATION ***************************/
209 static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
210 static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data);
211 static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data);
212 static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data);
213 static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data);
215 static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type);
216 static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type);
217 static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data);
218 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data);
220 /************************* RESPONSES ***************************/
221 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);
223 /************************* NOTIIFICATIONS ***************************/
224 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data);
225 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data);
226 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data);
227 static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data);
228 static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data);
231 /**************************************************************************
232 * Local Utility Function Prototypes
233 **************************************************************************/
234 static gboolean _call_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
235 static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status);
236 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call);
238 /**************************************************************************
239 * Local Function Definitions
240 **************************************************************************/
242 const call_end_cause_info call_end_cause_table[] = // call end cause table to convert Netwotk cause to TAPI cause
244 { 1, CC_CAUSE_UNASSIGNED_NUMBER}, { 3, CC_CAUSE_NO_ROUTE_TO_DEST},
245 { 6, CC_CAUSE_CHANNEL_UNACCEPTABLE}, { 8, CC_CAUSE_OPERATOR_DETERMINED_BARRING},
246 { 16, CC_CAUSE_NORMAL_CALL_CLEARING}, { 17, CC_CAUSE_USER_BUSY},
247 { 18, CC_CAUSE_NO_USER_RESPONDING}, { 19, CC_CAUSE_USER_ALERTING_NO_ANSWER},
248 { 21, CC_CAUSE_CALL_REJECTED}, { 22, CC_CAUSE_NUMBER_CHANGED},
249 { 26, CC_CAUSE_NON_SELECTED_USER_CLEARING}, { 27, CC_CAUSE_DESTINATION_OUT_OF_ORDER},
250 { 28, CC_CAUSE_INVALID_NUMBER_FORMAT}, { 29, CC_CAUSE_FACILITY_REJECTED},
251 { 30, CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY}, { 31, CC_CAUSE_NORMAL_UNSPECIFIED},
252 { 34, CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE}, { 38, CC_CAUSE_NETWORK_OUT_OF_ORDER},
253 { 41, CC_CAUSE_TEMPORARY_FAILURE}, { 42, CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION},
254 { 43, CC_CAUSE_ACCESS_INFORMATION_DISCARDED}, { 44, CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE},
255 { 47, CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED}, { 49, CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE},
256 { 50, CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED}, { 55, CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG},
257 { 57, CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED}, { 58, CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE},
258 { 63, CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE}, { 65, CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED},
259 { 68, CC_CAUSE_ACM_GEQ_ACMMAX}, { 69, CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED},
260 { 70, CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE}, { 79, CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED},
261 { 81, CC_CAUSE_INVALID_TRANSACTION_ID_VALUE}, { 87, CC_CAUSE_USER_NOT_MEMBER_OF_CUG},
262 { 88, CC_CAUSE_INCOMPATIBLE_DESTINATION}, { 91, CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION},
263 { 95, CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE}, { 96, CC_CAUSE_INVALID_MANDATORY_INFORMATION},
264 { 97, CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT}, { 98, CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE},
265 { 99, CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED}, { 100, CC_CAUSE_CONDITIONAL_IE_ERROR},
266 { 101, CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE}, { 102, CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY},
267 { 111, CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED}, {127, CC_CAUSE_INTERWORKING_UNSPECIFIED},
270 static enum tcore_call_cli_mode _get_clir_status(char *num)
272 enum tcore_call_cli_mode clir = TCORE_CALL_CLI_MODE_DEFAULT;
276 if (!strncmp(num, "*31#", 4)) {
277 dbg("CLI mode restricted");
278 return TCORE_CALL_CLI_MODE_RESTRICT;
281 if (!strncmp(num, "#31#", 4)) {
282 dbg("CLI mode allowed");
283 return TCORE_CALL_CLI_MODE_PRESENT;
286 dbg("CLI mode default");
293 static enum tcore_call_status _call_status(unsigned int status)
299 return TCORE_CALL_STATUS_ACTIVE;
302 return TCORE_CALL_STATUS_HELD;
305 return TCORE_CALL_STATUS_DIALING;
308 return TCORE_CALL_STATUS_ALERT;
311 return TCORE_CALL_STATUS_INCOMING;
314 return TCORE_CALL_STATUS_WAITING;
316 case 6: // DISCONNECTED state // FALL THROUGH
318 return TCORE_CALL_STATUS_IDLE;
322 static gboolean _call_is_in_mpty(int mpty)
340 static enum tcore_call_type call_type(int type)
346 return TCORE_CALL_TYPE_VOICE;
349 return TCORE_CALL_TYPE_VIDEO;
355 return TCORE_CALL_TYPE_VOICE;
358 static int _compare_call_end_cause(int networkcause)
362 for (count = 0; count < sizeof(call_end_cause_table) / sizeof(call_end_cause_info); count++) {
363 if (call_end_cause_table[count].network_cause == networkcause)
364 return (call_end_cause_table[count].tapi_cause);
366 return CC_CAUSE_NORMAL_CALL_CLEARING;
370 static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data)
379 static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)
381 GSList *tokens = NULL;
382 GSList *lines = NULL;
383 const char *line = NULL;
389 lines = (GSList *) data;
390 if (1 != g_slist_length(lines)) {
391 err("Unsolicited message, BUT multiple lines present");
395 line = (char *) (lines->data);
396 tokens = tcore_at_tok_new(line);
398 stat = g_slist_nth_data(tokens, 1);
400 dbg("Stat is missing from %XCALLSTAT indiaction");
405 case STATUS_INCOMING:
406 dbg("calling on_notification_call_incoming");
407 on_notification_call_incoming(o, line, user_data);
411 dbg("calling on_notification_call_waiting");
412 on_notification_call_waiting(o, line, user_data);
415 case STATUS_CONNECTED: /*igonre Connected state. */
416 dbg("Connected state");
420 dbg("calling on_notification_call_status");
421 on_notification_call_status(o, line, user_data);
427 tcore_at_tok_free(tokens);
434 static gboolean _call_request_message(TcorePending *pending,
440 TcoreHal *hal = NULL;
445 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
448 tcore_pending_set_response_callback(pending, on_resp, user_data);
450 tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
453 tcore_pending_link_user_request(pending, ur);
455 err("User Request is NULL, is this internal request??");
459 hal = tcore_object_get_hal(o);
460 // Send request to HAL
461 ret = tcore_hal_send_request(hal, pending);
462 if (TCORE_RETURN_SUCCESS != ret) {
463 err("Request send failed");
471 static void _call_status_idle(TcorePlugin *p, CallObject *co)
473 CoreObject *core_obj = NULL;
474 char *cmd_str = NULL;
475 TcorePending *pending = NULL;
476 TcoreATRequest *req = NULL;
477 gboolean ret = FALSE;
481 core_obj = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
482 dbg("Call ID [%d], Call Status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));
484 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_IDLE) {
485 // get call end cause.
486 cmd_str = g_strdup_printf("%s", "AT+XCEER");
487 dbg("Request command string: %s", cmd_str);
489 // Create new Pending request
490 pending = tcore_pending_new(core_obj, 0);
492 // Create new AT-Command request
493 req = tcore_at_request_new(cmd_str, "+XCEER", TCORE_AT_SINGLELINE);
494 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
495 // Free command string
498 // Set request data (AT command) to Pending request
499 tcore_pending_set_request_data(pending, 0, req);
501 ur = tcore_user_request_new(NULL, NULL);
503 ret = _call_request_message(pending, core_obj, ur, _on_confirmation_call_end_cause, co);
506 err("Failed to send AT-Command request");
507 // free only UserRequest.
509 tcore_user_request_free(ur);
515 err("Call object was not free");
516 tcore_call_object_free(core_obj, co);
522 static void _call_status_dialing(TcorePlugin *p, CallObject *co)
524 struct tnoti_call_status_dialing data;
528 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_DIALING) {
529 data.type = tcore_call_object_get_type(co);
530 dbg("data.type : [%d]", data.type);
532 data.id = tcore_call_object_get_id(co);
533 dbg("data.id : [%d]", data.id);
536 tcore_call_object_set_status(co, TCORE_CALL_STATUS_DIALING);
538 // Send notification to TAPI
539 tcore_server_send_notification(tcore_plugin_ref_server(p),
540 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
541 TNOTI_CALL_STATUS_DIALING,
542 sizeof(struct tnoti_call_status_dialing),
550 static void _call_status_alert(TcorePlugin *p, CallObject *co)
552 struct tnoti_call_status_alert data;
556 // Alerting has just 1 data 'CALL ID'
557 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ALERT) {
558 data.type = tcore_call_object_get_type(co);
559 dbg("data.type : [%d]", data.type);
561 data.id = tcore_call_object_get_id(co);
562 dbg("data.id : [%d]", data.id);
565 tcore_call_object_set_status(co, TCORE_CALL_STATUS_ALERT);
567 // Send notification to TAPI
568 tcore_server_send_notification(tcore_plugin_ref_server(p),
569 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
570 TNOTI_CALL_STATUS_ALERT,
571 sizeof(struct tnoti_call_status_alert),
579 static void _call_status_active(TcorePlugin *p, CallObject *co)
581 struct tnoti_call_status_active data;
585 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ACTIVE) {
586 data.type = tcore_call_object_get_type(co);
587 dbg("data.type : [%d]", data.type);
589 data.id = tcore_call_object_get_id(co);
590 dbg("data.id : [%d]", data.id);
593 tcore_call_object_set_status(co, TCORE_CALL_STATUS_ACTIVE);
595 // Send notification to TAPI
596 tcore_server_send_notification(tcore_plugin_ref_server(p),
597 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
598 TNOTI_CALL_STATUS_ACTIVE,
599 sizeof(struct tnoti_call_status_active),
607 static void _call_status_held(TcorePlugin *p, CallObject *co)
609 struct tnoti_call_status_held data;
613 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_HELD) {
614 data.type = tcore_call_object_get_type(co);
615 dbg("data.type : [%d]", data.type);
617 data.id = tcore_call_object_get_id(co);
618 dbg("data.id : [%d]", data.id);
621 tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
623 // Send notification to TAPI
624 tcore_server_send_notification(tcore_plugin_ref_server(p),
625 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
626 TNOTI_CALL_STATUS_HELD,
627 sizeof(struct tnoti_call_status_held),
635 static void _call_status_incoming(TcorePlugin *p, CallObject *co)
637 struct tnoti_call_status_incoming data;
641 if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_INCOMING) {
642 tcore_call_object_set_status(co, TCORE_CALL_STATUS_INCOMING);
644 data.type = tcore_call_object_get_type(co);
645 dbg("data.type : [%d]", data.type);
647 data.id = tcore_call_object_get_id(co);
648 dbg("data.id : [%d]", data.id);
650 data.cli.mode = tcore_call_object_get_cli_mode(co);
651 dbg("data.cli.mode : [%d]", data.cli.mode);
653 tcore_call_object_get_number(co, data.cli.number);
654 dbg("data.cli.number : [%s]", data.cli.number);
656 data.cna.mode = tcore_call_object_get_cna_mode(co);
657 dbg("data.cna.mode : [%d]", data.cna.mode);
659 tcore_call_object_get_name(co, data.cna.name);
660 dbg("data.cna.name : [%s]", data.cna.name);
662 data.forward = FALSE; // this is tmp code
664 data.active_line = tcore_call_object_get_active_line(co);
665 dbg("data.active_line : [%d]", data.active_line);
667 // Send notification to TAPI
668 tcore_server_send_notification(tcore_plugin_ref_server(p),
669 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
670 TNOTI_CALL_STATUS_INCOMING,
671 sizeof(struct tnoti_call_status_incoming),
679 static void _call_status_waiting(TcorePlugin *p, CallObject *co)
682 _call_status_incoming(p, co);
688 static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status)
692 dbg("Call Status is %d", status);
694 case TCORE_CALL_STATUS_IDLE:
695 _call_status_idle(p, co);
698 case TCORE_CALL_STATUS_ACTIVE:
699 _call_status_active(p, co);
702 case TCORE_CALL_STATUS_HELD:
703 _call_status_held(p, co);
706 case TCORE_CALL_STATUS_DIALING:
707 _call_status_dialing(p, co);
710 case TCORE_CALL_STATUS_ALERT:
711 _call_status_alert(p, co);
714 case TCORE_CALL_STATUS_INCOMING:
715 _call_status_incoming(p, co);
718 case TCORE_CALL_STATUS_WAITING:
719 _call_status_waiting(p, co);
727 static TReturn _call_list_get(CoreObject *o, gboolean *event_flag)
729 UserRequest *ur = NULL;
730 TcorePending *pending = NULL;
731 char *cmd_str = NULL;
732 TcoreATRequest *req = NULL;
733 gboolean ret = FALSE;
737 err("Core Object is NULL");
738 return TCORE_RETURN_FAILURE;
741 // Create new User Request
742 ur = tcore_user_request_new(NULL, NULL);
745 cmd_str = g_strdup("AT+CLCC");
747 // Create new Pending Request
748 pending = tcore_pending_new(o, 0);
749 req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);
753 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
755 tcore_pending_set_request_data(pending, 0, req);
757 ret = _call_request_message(pending, o, ur, on_response_call_list_get, event_flag);
759 err("AT request (%s) sending failed", req->cmd);
760 // free only UserRequest.
762 tcore_user_request_free(ur);
765 return TCORE_RETURN_FAILURE;
768 dbg("AT request sent success");
769 return TCORE_RETURN_SUCCESS;
773 static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data)
777 if (result == FALSE) { // Fail
787 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)
789 TcoreATRequest *req = NULL;
790 TcoreHal *hal = NULL;
791 TcorePending *pending = NULL;
794 hal = tcore_object_get_hal(co);
797 pending = tcore_pending_new(co, 0);
799 dbg("Pending is NULL");
800 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
802 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
804 tcore_pending_set_request_data(pending, 0, req);
805 tcore_pending_set_response_callback(pending, callback, NULL);
806 tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
807 ret = tcore_hal_send_request(hal, pending);
810 static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
812 UserRequest *ur = NULL;
813 GSList *tokens = NULL;
814 const char *line = NULL;
815 const TcoreATResponse *response = data;
816 struct tresp_call_dial resp;
817 enum telephony_call_error error;
820 ur = tcore_pending_ref_user_request(p);
822 if (response->success > 0) {
824 resp.err = CALL_ERROR_NONE;
826 dbg("RESPONSE NOT OK");
828 line = (const char *) response->final_response;
829 tokens = tcore_at_tok_new(line);
831 if (g_slist_length(tokens) < 1) {
832 err("Unspecified error cause OR string corrupted");
833 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
835 error = atoi(g_slist_nth_data(tokens, 0));
837 // TODO: CMEE error mapping is required.
838 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
842 tcore_at_tok_free(tokens);
845 // Send Response to TAPI
846 tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
848 err("User Request is NULL");
855 static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)
857 UserRequest *ur = NULL;
858 GSList *tokens = NULL;
859 const char *line = NULL;
860 const TcoreATResponse *response = data;
861 struct tresp_call_answer resp;
862 enum telephony_call_error error;
865 ur = tcore_pending_ref_user_request(p);
867 if (response->success > 0) {
869 resp.err = CALL_ERROR_NONE;
871 dbg("RESPONSE NOT OK");
873 line = (const char *) response->final_response;
874 tokens = tcore_at_tok_new(line);
876 if (g_slist_length(tokens) < 1) {
877 err("Unspecified error cause OR string corrupted");
878 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
880 error = atoi(g_slist_nth_data(tokens, 0));
882 // TODO: CMEE error mapping is required.
883 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
887 tcore_at_tok_free(tokens);
890 resp.id = tcore_call_object_get_id((CallObject *) user_data);
892 // Send Response to TAPI
893 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
895 err("User Request is NULL");
903 static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)
905 UserRequest *ur = NULL;
906 GSList *tokens = NULL;
907 const char *line = NULL;
908 const TcoreATResponse *response = data;
909 struct tresp_call_answer resp;
910 enum telephony_call_error error;
914 ur = tcore_pending_ref_user_request(p);
916 if (response->success > 0) {
918 resp.err = CALL_ERROR_NONE;
920 dbg("RESPONSE NOT OK");
921 line = (const char *) response->final_response;
922 tokens = tcore_at_tok_new(line);
924 if (g_slist_length(tokens) < 1) {
925 err("Unspecified error cause OR string corrupted");
926 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
928 error = atoi(g_slist_nth_data(tokens, 0));
929 // TODO: CMEE error mapping is required.
930 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
934 tcore_at_tok_free(tokens);
937 resp.id = tcore_call_object_get_id((CallObject *) user_data);
939 // Send Response to TAPI
940 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
942 err("User Request is NULL");
949 static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)
951 UserRequest *ur = NULL;
952 GSList *tokens = NULL;
953 const char *line = NULL;
954 const TcoreATResponse *response = data;
955 struct tresp_call_answer resp;
956 enum telephony_call_error error;
959 ur = tcore_pending_ref_user_request(p);
961 if (response->success > 0) {
963 resp.err = CALL_ERROR_NONE;
965 dbg("RESPONSE NOT OK");
966 line = (const char *) response->final_response;
967 tokens = tcore_at_tok_new(line);
969 if (g_slist_length(tokens) < 1) {
970 err("Unspecified error cause OR string corrupted");
971 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
973 error = atoi(g_slist_nth_data(tokens, 0));
974 // TODO: CMEE error mapping is required.
975 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
979 tcore_at_tok_free(tokens);
981 resp.id = tcore_call_object_get_id((CallObject *) user_data);
983 // Send Response to TAPI
984 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
986 dbg("User Request is NULL");
993 static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)
995 CoreObject *o = NULL;
996 UserRequest *ur = NULL;
997 GSList *tokens = NULL;
998 const char *line = NULL;
999 const TcoreATResponse *response = data;
1000 struct tresp_call_answer resp;
1001 enum telephony_call_error error;
1005 o = tcore_pending_ref_core_object(p);
1006 ur = tcore_pending_ref_user_request(p);
1007 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1010 if (response->success > 0) {
1012 resp.err = CALL_ERROR_NONE;
1014 err("RESPONSE NOT OK");
1015 line = (const char *) response->final_response;
1016 tokens = tcore_at_tok_new(line);
1018 if (g_slist_length(tokens) < 1) {
1019 err("Unspecified error cause OR string corrupted");
1020 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1022 error = atoi(g_slist_nth_data(tokens, 0));
1024 // TODO: CMEE error mapping is required.
1025 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1029 tcore_at_tok_free(tokens);
1032 // Send response to TAPI
1033 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
1036 CallObject *co = NULL;
1039 list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
1041 err("Can't find active Call");
1045 co = (CallObject *) list->data;
1047 err("Can't get active Call object");
1052 tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
1053 dbg("Call status is set to HELD");
1056 err("User Request is NULL");
1063 static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1065 UserRequest *ur = NULL;
1066 struct tresp_call_end resp;
1067 GSList *tokens = NULL;
1068 const char *line = NULL;
1069 enum telephony_call_error error;
1070 const TcoreATResponse *response = data;
1073 ur = tcore_pending_ref_user_request(p);
1075 if (response->success > 0) {
1077 resp.err = CALL_ERROR_NONE;
1079 err("RESPONSE NOT OK");
1081 line = (const char *) response->final_response;
1082 tokens = tcore_at_tok_new(line);
1084 if (g_slist_length(tokens) < 1) {
1085 err("Unspecified error cause OR string corrupted");
1086 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1088 error = atoi(g_slist_nth_data(tokens, 0));
1090 // TODO: CMEE error mapping is required.
1091 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1093 tcore_at_tok_free(tokens);
1097 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1098 dbg("resp.type = %d resp.id= %d", resp.type, resp.id);
1100 // Send reponse to TAPI
1101 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
1103 err("User Request is NULL");
1111 static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)
1113 // skip response handling - actual result will be handled in on_confirmation_call_release_all
1114 const TcoreATResponse *response = data;
1118 if (response->success > 0) {
1121 err("RESPONSE NOT OK");
1129 static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)
1132 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);
1138 static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)
1141 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);
1146 static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)
1149 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);
1154 static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)
1157 _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);
1162 static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)
1164 UserRequest *ur = NULL;
1165 GSList *tokens = NULL;
1166 const char *line = NULL;
1167 const TcoreATResponse *response = NULL;
1168 enum telephony_call_error error;
1171 ur = tcore_pending_ref_user_request(p);
1172 response = (TcoreATResponse *) data;
1173 if (response->success > 0) {
1175 error = CALL_ERROR_NONE;
1177 err("RESPONSE NOT OK");
1179 line = (const char *) response->final_response;
1180 tokens = tcore_at_tok_new(line);
1182 if (g_slist_length(tokens) < 1) {
1183 err("Unspecified error cause OR string corrupted");
1184 error = CALL_ERROR_SERVICE_UNAVAIL;
1186 error = atoi(g_slist_nth_data(tokens, 0));
1188 // TODO: CMEE error mapping is required.
1189 error = CALL_ERROR_SERVICE_UNAVAIL;
1193 tcore_at_tok_free(tokens);
1196 dbg("Response Call type -%d", type);
1198 case TRESP_CALL_HOLD:
1200 struct tresp_call_hold resp;
1203 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1204 dbg("call hold response");
1205 // Send reponse to TAPI
1206 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1210 case TRESP_CALL_ACTIVE:
1212 struct tresp_call_active resp;
1215 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1216 dbg("call active response");
1217 // Send reponse to TAPI
1218 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1222 case TRESP_CALL_JOIN:
1224 struct tresp_call_join resp;
1227 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1228 dbg("call join response");
1230 // Send reponse to TAPI
1231 tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
1235 case TRESP_CALL_SPLIT:
1237 struct tresp_call_split resp;
1240 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1241 dbg("call split response");
1242 // Send reponse to TAPI
1243 tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
1247 case TRESP_CALL_DEFLECT:
1249 struct tresp_call_deflect resp;
1252 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1253 dbg("call deflect response");
1254 // Send reponse to TAPI
1255 tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
1260 case TRESP_CALL_TRANSFER:
1262 struct tresp_call_transfer resp;
1265 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1266 dbg("call transfer response");
1267 // Send reponse to TAPI
1268 tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
1272 case TRESP_CALL_SEND_DTMF:
1274 struct tresp_call_dtmf resp;
1277 dbg("call dtmf response");
1278 // Send reponse to TAPI
1279 tcore_user_request_send_response(ur, TRESP_CALL_SEND_DTMF, sizeof(struct tresp_call_dtmf), &resp);
1285 dbg("type not supported");
1290 if ((type == TRESP_CALL_HOLD) || (type == TRESP_CALL_ACTIVE) || (type == TRESP_CALL_JOIN)
1291 || (type == TRESP_CALL_SPLIT)) {
1293 CoreObject *core_obj = NULL;
1294 gboolean *eflag = g_new0(gboolean, 1);
1296 core_obj = tcore_pending_ref_core_object(p);
1299 dbg("Calling _call_list_get");
1300 _call_list_get(core_obj, eflag);
1308 static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)
1311 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);
1316 static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)
1319 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);
1324 static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)
1327 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);
1332 static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)
1335 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);
1340 static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)
1343 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);
1348 static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)
1351 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);
1356 static void on_confirmation_call_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
1359 _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SEND_DTMF);
1364 static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data)
1366 GSList *tokens = NULL;
1367 const char *line = NULL;
1368 const TcoreATResponse *response = data;
1369 enum telephony_call_error error;
1373 if (response->success > 0) {
1375 error = CALL_ERROR_NONE;
1377 err("RESPONSE NOT OK");
1378 line = (const char *) response->final_response;
1379 tokens = tcore_at_tok_new(line);
1380 if (g_slist_length(tokens) < 1) {
1381 err("err cause not specified or string corrupted");
1382 error = CALL_ERROR_SERVICE_UNAVAIL;
1384 error = atoi(g_slist_nth_data(tokens, 0));
1385 // TODO: CMEE error mapping is required.
1389 tcore_at_tok_free(tokens);
1392 dbg("Set dtmf tone duration response - %d", error);
1396 static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
1398 CoreObject *core_obj = NULL;
1399 UserRequest *ur = NULL;
1400 const TcoreATResponse *response = data;
1401 struct tresp_call_swap resp;
1402 GSList *tokens = NULL;
1403 const char *line = NULL;
1406 core_obj = tcore_pending_ref_core_object(p);
1407 ur = tcore_pending_ref_user_request(p);
1410 if (response->success > 0) {
1412 resp.err = CALL_ERROR_NONE;
1414 err("RESPONSE NOT OK");
1415 line = (const char *) response->final_response;
1416 tokens = tcore_at_tok_new(line);
1417 if (g_slist_length(tokens) < 1) {
1418 err("err cause not specified or string corrupted");
1419 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1421 resp.err = atoi(g_slist_nth_data(tokens, 0));
1423 // TODO: CMEE error mapping is required.
1424 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1428 tcore_at_tok_free(tokens);
1431 resp.id = tcore_call_object_get_id((CallObject *) user_data);
1432 dbg("resp.id = %d", resp.id);
1434 // Send response to TAPI
1435 tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
1438 GSList *active = NULL;
1439 GSList *held = NULL;
1440 CallObject *co = NULL;
1441 gboolean *eflag = NULL;
1443 held = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_HELD);
1445 err("Can't find held Call");
1449 active = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_ACTIVE);
1451 dbg("Can't find active Call");
1456 co = (CallObject *) held->data;
1458 err("Can't get held Call object");
1462 resp.id = tcore_call_object_get_id(co);
1464 // Send response to TAPI
1465 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
1467 held = g_slist_next(held);
1471 co = (CallObject *) active->data;
1473 err("[ error ] can't get active call object");
1477 resp.id = tcore_call_object_get_id(co);
1479 // Send response to TAPI
1480 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
1481 active = g_slist_next(active);
1484 eflag = g_new0(gboolean, 1);
1487 dbg("calling _call_list_get");
1488 _call_list_get(core_obj, eflag);
1491 err("User Request is NULL");
1498 static void on_confirmation_set_sound_path(TcorePending *p, int data_len,
1502 const TcoreATResponse *resp = data;
1503 struct tnoti_call_sound_path *snd_path = user_data;
1504 struct tresp_call_sound_set_path resp_set_sound_path;
1505 UserRequest *ur = tcore_pending_ref_user_request(p);
1506 TcorePlugin *plugin = tcore_pending_ref_plugin(p);
1507 CoreObject *co_call;
1510 err("User Request is NULL");
1515 if (resp->success <= 0) {
1517 dbg("RESPONSE NOT OK");
1518 resp_set_sound_path.err = TRUE;
1524 resp_set_sound_path.err = FALSE;
1526 co_call = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
1528 /* Notify control plugin about sound path */
1529 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
1530 co_call, TNOTI_CALL_SOUND_PATH,
1531 sizeof(struct tnoti_call_sound_path),
1535 /* Answer TAPI request */
1536 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH,
1537 sizeof(resp_set_sound_path),
1538 &resp_set_sound_path);
1543 static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1545 UserRequest *ur = NULL;
1546 GSList *tokens = NULL;
1547 const char *line = NULL;
1548 const TcoreATResponse *response = data;
1549 char *resp_str = NULL;
1550 struct tresp_call_sound_set_path resp;
1554 ur = tcore_pending_ref_user_request(p);
1556 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1558 err("Input data is NULL");
1562 if (response->success > 0) {
1565 line = (const char *) (((GSList *) response->lines)->data);
1566 tokens = tcore_at_tok_new(line);
1568 resp_str = g_slist_nth_data(tokens, 0);
1569 if (!g_slist_nth_data(tokens, 0)) {
1570 err("group_id is missing");
1575 if (!g_slist_nth_data(tokens, 1)) {
1576 err(" function_id is missing");
1581 resp_str = g_slist_nth_data(tokens, 2);
1584 error = atoi(resp_str);
1586 dbg("Response is Success");
1594 tcore_at_tok_free(tokens);
1596 dbg("RESPONSE NOT OK");
1598 line = (const char *) response->final_response;
1599 tokens = tcore_at_tok_new(line);
1601 if (g_slist_length(tokens) < 1) {
1602 err("err cause not specified or string corrupted");
1605 error = atoi(g_slist_nth_data(tokens, 0));
1607 // TODO: CMEE error mapping is required.
1612 tcore_at_tok_free(tokens);
1616 if ( resp.err ) { // Send only failed notification . success notification send when destination device is set.
1617 // Send notification to TAPI
1618 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1619 setsoundpath = TRUE;
1622 err("User Request is NULL");
1629 static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
1631 UserRequest *ur = NULL;
1632 GSList *tokens = NULL;
1633 const char *line = NULL;
1634 char *resp_str = NULL;
1635 struct tresp_call_sound_set_path resp;
1636 const TcoreATResponse *response = data;
1641 ur = tcore_pending_ref_user_request(p);
1642 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1645 err("Input data is NULL");
1650 if (response->success > 0) {
1653 line = (const char *) (((GSList *) response->lines)->data);
1654 tokens = tcore_at_tok_new(line);
1656 resp_str = g_slist_nth_data(tokens, 0);
1657 if (!g_slist_nth_data(tokens, 0)) {
1658 dbg("group_id is missing");
1663 if (!g_slist_nth_data(tokens, 1)) {
1664 dbg("function_id is missing");
1669 resp_str = g_slist_nth_data(tokens, 2);
1671 error = atoi(resp_str);
1673 dbg("Response is Success");
1682 tcore_at_tok_free(tokens);
1684 dbg("RESPONSE NOT OK");
1686 line = (const char *) response->final_response;
1687 tokens = tcore_at_tok_new(line);
1689 if (g_slist_length(tokens) < 1) {
1690 err("err cause not specified or string corrupted");
1693 error = atoi(g_slist_nth_data(tokens, 0));
1694 // TODO: CMEE error mapping is required.
1699 tcore_at_tok_free(tokens);
1702 if (setsoundpath == TRUE) {
1703 setsoundpath = FALSE;
1705 // Send response to TAPI
1706 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
1709 dbg("User Request is NULL");
1716 static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1718 UserRequest *ur = NULL;
1719 GSList *tokens = NULL;
1720 const char *line = NULL;
1721 const TcoreATResponse *response = data;
1722 char *resp_str = NULL;
1723 struct tresp_call_sound_set_volume_level resp;
1726 ur = tcore_pending_ref_user_request(p);
1728 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1730 err("Input data is NULL");
1734 if (response->success > 0) {
1737 line = (const char *) (((GSList *) response->lines)->data);
1738 tokens = tcore_at_tok_new(line);
1740 resp_str = g_slist_nth_data(tokens, 0);
1741 if (!g_slist_nth_data(tokens, 0)) {
1742 err("group_id is missing");
1747 if (!g_slist_nth_data(tokens, 1)) {
1748 err("function_id is missing");
1753 resp_str = g_slist_nth_data(tokens, 2);
1755 error = atoi(resp_str);
1758 dbg("Response is Success ");
1767 tcore_at_tok_free(tokens);
1769 dbg("RESPONSE NOT OK");
1771 line = (const char *) response->final_response;
1772 tokens = tcore_at_tok_new(line);
1774 if (g_slist_length(tokens) < 1) {
1775 err("err cause not specified or string corrupted");
1778 error = atoi(g_slist_nth_data(tokens, 0));
1780 // TODO: CMEE error mapping is required.
1785 tcore_at_tok_free(tokens);
1789 if (resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.
1790 // Send reposne to TAPI
1791 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1795 err("User Request is NULL");
1803 static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
1805 UserRequest *ur = NULL;
1806 GSList *tokens = NULL;
1807 const char *line = NULL;
1808 char *resp_str = NULL;
1809 const TcoreATResponse *response = data;
1810 struct tresp_call_sound_set_volume_level resp;
1815 ur = tcore_pending_ref_user_request(p);
1817 // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
\ 3
1819 err("Input data is NULL");
1824 if (response->success > 0) {
1826 line = (const char *) (((GSList *) response->lines)->data);
1827 tokens = tcore_at_tok_new(line);
1828 resp_str = g_slist_nth_data(tokens, 0);
1830 if (!g_slist_nth_data(tokens, 0)) {
1831 err("group_id is missing");
1836 if (!g_slist_nth_data(tokens, 1)) {
1837 err("function_id is missing");
1842 resp_str = g_slist_nth_data(tokens, 2);
1845 error = atoi(resp_str);
1848 dbg("Response is Success");
1857 tcore_at_tok_free(tokens);
1859 dbg("RESPONSE NOT OK");
1861 line = (const char *) response->final_response;
1862 tokens = tcore_at_tok_new(line);
1864 if (g_slist_length(tokens) < 1) {
1865 err("err cause not specified or string corrupted");
1868 error = atoi(g_slist_nth_data(tokens, 0));
1870 // TODO: CMEE error mapping is required.
1874 tcore_at_tok_free(tokens);
1877 if (soundvolume == TRUE) {
1878 soundvolume = FALSE;
1880 // Send reposne to TAPI
1881 tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
1884 err("User Request is NULL");
1892 static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
1894 UserRequest *ur = NULL;
1895 GSList *tokens = NULL;
1896 const char *line = NULL;
1897 char *resp_str = NULL;
1898 struct tresp_call_mute resp;
1899 const TcoreATResponse *response = data;
1904 ur = tcore_pending_ref_user_request(p);
1907 err("Input data is NULL");
1911 if (response->success > 0) {
1914 line = (const char *) (((GSList *) response->lines)->data);
1915 tokens = tcore_at_tok_new(line);
1916 resp_str = g_slist_nth_data(tokens, 0);
1918 if (!g_slist_nth_data(tokens, 0)) {
1919 err("group_id is missing");
1924 if (!g_slist_nth_data(tokens, 1)) {
1925 err(" function_id is missing");
1930 resp_str = g_slist_nth_data(tokens, 2);
1933 error = atoi(resp_str);
1935 dbg("Response is Success");
1943 tcore_at_tok_free(tokens);
1945 dbg("RESPONSE NOT OK");
1947 line = (const char *) response->final_response;
1948 tokens = tcore_at_tok_new(line);
1950 if (g_slist_length(tokens) < 1) {
1951 err("err cause not specified or string corrupted");
1954 error = atoi(g_slist_nth_data(tokens, 0));
1956 // TODO: CMEE error mapping is required.
1961 tcore_at_tok_free(tokens);
1965 tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
1967 err("User Request is NULL");
1974 static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
1976 const TcoreATResponse *response = NULL;
1977 struct tresp_call_unmute resp;
1978 GSList *tokens = NULL;
1979 const char *line = NULL;
1980 UserRequest *ur = NULL;
1981 char *resp_str = NULL;
1986 response = (TcoreATResponse *) data;
1987 ur = tcore_pending_ref_user_request(p);
1990 err("Input data is NULL");
1994 if (response->success > 0) {
1997 line = (const char *) (((GSList *) response->lines)->data);
1998 tokens = tcore_at_tok_new(line);
1999 resp_str = g_slist_nth_data(tokens, 0);
2001 if (!g_slist_nth_data(tokens, 0)) {
2002 err("group_id is missing");
2007 if (!g_slist_nth_data(tokens, 1)) {
2008 err(" function_id is missing");
2013 resp_str = g_slist_nth_data(tokens, 2);
2016 error = atoi(resp_str);
2018 dbg("Response is Success");
2026 tcore_at_tok_free(tokens);
2028 dbg("RESPONSE NOT OK");
2030 line = (const char *) response->final_response;
2031 tokens = tcore_at_tok_new(line);
2033 if (g_slist_length(tokens) < 1) {
2034 err("err cause not specified or string corrupted");
2037 error = atoi(g_slist_nth_data(tokens, 0));
2039 // TODO: CMEE error mapping is required.
2044 tcore_at_tok_free(tokens);
2048 tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
2050 err("User Request is NULL");
2058 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
2060 TcorePlugin *plugin = NULL;
2061 CoreObject *core_obj = NULL;
2062 CallObject *co = NULL;
2063 struct clcc_call_t *call_list = NULL;
2064 gboolean *event_flag = (gboolean *) user_data;
2065 const TcoreATResponse *response = data;
2066 GSList *resp_data = NULL;
2069 int cllc_info = 0, countCalls = 0, countValidCalls = 0;
2074 plugin = tcore_pending_ref_plugin(p);
2075 core_obj = tcore_pending_ref_core_object(p);
2077 if (response->success > 0) {
2079 if (response->lines) {
2080 resp_data = (GSList *) response->lines;
2081 countCalls = g_slist_length(resp_data);
2082 dbg("Total records : %d", countCalls);
2085 if (0 == countCalls) {
2086 err("Call count is zero");
2094 call_list = g_new0(struct clcc_call_t, countCalls);
2096 for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
2097 line = (char *) (resp_data->data);
2099 error = _callFromCLCCLine(line, call_list + countValidCalls);
2104 co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
2106 co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
2108 err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
2113 // Call set parameters
2114 tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
2115 tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
2116 tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
2117 tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
2118 tcore_call_object_set_active_line(co, 0);
2121 dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
2122 _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
2125 tcore_call_object_set_status(co, call_list[cllc_info].info.status);
2127 dbg("Call id : (%d)", call_list[cllc_info].info.id);
2128 dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
2129 dbg("Call type : (%d)", call_list[cllc_info].info.type);
2130 dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
2131 dbg("Call number : (%s)", call_list[cllc_info].number);
2132 dbg("Call status : (%d)", call_list[cllc_info].info.status);
2150 static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
2152 TcorePlugin *plugin = NULL;
2153 CoreObject *core_obj = NULL;
2154 CallObject *co = (CallObject *) user_data;
2155 const TcoreATResponse *response = data;
2156 const char *line = NULL;
2157 struct tnoti_call_status_idle call_status;
2158 GSList *tokens = NULL;
2163 plugin = tcore_pending_ref_plugin(p);
2164 core_obj = tcore_pending_ref_core_object(p);
2166 if (response->success > 0) {
2168 line = (const char *) (((GSList *) response->lines)->data);
2169 tokens = tcore_at_tok_new(line);
2170 resp_str = g_slist_nth_data(tokens, 0);
2172 err("call end cause - report value missing");
2174 resp_str = g_slist_nth_data(tokens, 1);
2176 err("call end cause value missing");
2178 error = atoi(resp_str);
2179 dbg("call end cause - %d", error);
2180 call_status.cause = _compare_call_end_cause(error);
2181 dbg("TAPI call end cause - %d", call_status.cause);
2185 tcore_at_tok_free(tokens);
2187 err("RESPONSE NOT OK");
2188 line = (char *) response->final_response;
2189 tokens = tcore_at_tok_new(line);
2190 if (g_slist_length(tokens) < 1) {
2191 err("err cause not specified or string corrupted");
2193 err(" err cause value: %d", atoi(g_slist_nth_data(tokens, 0)));
2195 call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
2197 tcore_at_tok_free(tokens);
2200 call_status.type = tcore_call_object_get_type(co);
2201 dbg("data.type : [%d]", call_status.type);
2203 call_status.id = tcore_call_object_get_id(co);
2204 dbg("data.id : [%d]", call_status.id);
2207 tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
2209 // Send Notification to TAPI
2210 tcore_server_send_notification(tcore_plugin_ref_server(plugin),
2212 TNOTI_CALL_STATUS_IDLE,
2213 sizeof(struct tnoti_call_status_idle),
2214 (void *) &call_status);
2217 tcore_call_object_free(core_obj, co);
2220 static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
2222 // +CLCC: 1,0,2,0,0,"18005551212",145
2223 // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
2228 unsigned int num_type;
2229 GSList *tokens = NULL;
2234 tokens = tcore_at_tok_new(line);
2236 resp = g_slist_nth_data(tokens, 0);
2241 p_call->info.id = atoi(resp);
2242 dbg("id : [%d]\n", p_call->info.id);
2245 resp = g_slist_nth_data(tokens, 1);
2252 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
2254 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
2256 dbg("Direction : [ %d ]\n", p_call->info.direction);
2259 resp = g_slist_nth_data(tokens, 2);
2261 err("InValid Stat");
2265 dbg("Call state : %d", state);
2268 p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
2272 p_call->info.status = TCORE_CALL_STATUS_HELD;
2276 p_call->info.status = TCORE_CALL_STATUS_DIALING;
2280 p_call->info.status = TCORE_CALL_STATUS_ALERT;
2284 p_call->info.status = TCORE_CALL_STATUS_INCOMING;
2288 p_call->info.status = TCORE_CALL_STATUS_WAITING;
2291 dbg("Status : [%d]\n", p_call->info.status);
2294 resp = g_slist_nth_data(tokens, 3);
2296 err("InValid Mode");
2302 p_call->info.type = TCORE_CALL_TYPE_VOICE;
2306 p_call->info.type = TCORE_CALL_TYPE_VIDEO;
2309 default: // only Voice/VT call is supported in CS. treat other unknown calls as error
2310 dbg("invalid type : [%d]\n", mode);
2313 dbg("Call type : [%d]\n", p_call->info.type);
2316 resp = g_slist_nth_data(tokens, 4);
2318 err("InValid Mpty");
2322 p_call->info.mpty = atoi(resp);
2323 dbg("Mpty : [ %d ]\n", p_call->info.mpty);
2326 resp = g_slist_nth_data(tokens, 5);
2327 dbg("Incoming number - %s and its len - %d", resp, strlen(resp));
2329 // tolerate null here
2331 err("Number is NULL");
2334 // Strike off double quotes
2335 num = util_removeQuotes(resp);
2336 dbg("num after removing quotes - %s", num);
2338 p_call->info.num_len = strlen(resp);
2339 dbg("num_len : [0x%x]\n", p_call->info.num_len);
2342 resp = g_slist_nth_data(tokens, 6);
2344 dbg("InValid Num type");
2347 p_call->info.num_type = atoi(resp);
2348 dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
2350 // check number is international or national.
2351 num_type = ((p_call->info.num_type) >> 4) & 0x07;
2352 dbg("called party's type of number : [0x%x]\n", num_type);
2354 if (num_type == 1 && num[0] != '+') {
2355 // international number
2356 p_call->number[0] = '+';
2357 memcpy(&(p_call->number[1]), num, strlen(num));
2359 memcpy(&(p_call->number), num, strlen(num));
2361 dbg("incoming number - %s", p_call->number);
2366 tcore_at_tok_free(tokens);
2372 err("Invalid CLCC line");
2377 tcore_at_tok_free(tokens);
2383 static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
2385 GSList *tokens = NULL;
2386 const char *line = NULL;
2390 GSList *pList = NULL;
2391 CallObject *co = NULL, *dupco = NULL;
2393 dbg("function entrance");
2394 // check call with waiting status already exist
2395 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
2397 if (pList != NULL) {
2398 dbg("[error]Waiting call already exist. skip");
2401 // check call with incoming status already exist
2402 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2404 if (pList != NULL) {
2405 dbg("[error]incoming call already exist. skip");
2408 line = (char *) data;
2409 tokens = tcore_at_tok_new(line);
2411 pId = g_slist_nth_data(tokens, 0);
2413 dbg("[error]:Call id is missing from +XCALLSTAT indication");
2414 tcore_at_tok_free(tokens);
2418 call_id = atoi(pId);
2419 dupco = tcore_call_object_find_by_id(o, call_id);
2420 if (dupco != NULL) {
2421 dbg("co with same id already exist. skip");
2422 tcore_at_tok_free(tokens);
2425 co = tcore_call_object_new(o, call_id);
2427 dbg("[ error ] co is NULL");
2428 tcore_at_tok_free(tokens);
2432 tcore_at_tok_free(tokens);
2434 eflag = g_new0(gboolean, 1);
2436 dbg("calling _call_list_get");
2437 _call_list_get(o, eflag);
2440 static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
2442 GSList *tokens = NULL;
2443 const char *line = NULL;
2447 GSList *pList = NULL;
2448 CallObject *co = NULL, *dupco = NULL;
2450 dbg("function entrance");
2451 // check call with incoming status already exist
2452 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
2454 if (pList != NULL) {
2455 dbg("incoming call already exist. skip");
2459 line = (char *) data;
2460 tokens = tcore_at_tok_new(line);
2462 pId = g_slist_nth_data(tokens, 0);
2464 dbg("Error:Call id is missing from %XCALLSTAT indication");
2465 tcore_at_tok_free(tokens);
2469 call_id = atoi(pId);
2471 dupco = tcore_call_object_find_by_id(o, call_id);
2472 if (dupco != NULL) {
2473 dbg("co with same id already exist. skip");
2474 tcore_at_tok_free(tokens);
2478 co = tcore_call_object_new(o, call_id);
2480 dbg("[ error ] co is NULL");
2481 tcore_at_tok_free(tokens);
2485 dbg("freeing at token");
2486 tcore_at_tok_free(tokens);
2488 eflag = g_new0(gboolean, 1);
2491 dbg("calling _call_list_get");
2492 _call_list_get(o, eflag);
2495 static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
2498 TcorePlugin *plugin = NULL;
2499 CallObject *co = NULL;
2504 char *pCallId = NULL;
2505 GSList *tokens = NULL;
2506 gboolean *eflag = NULL;
2507 enum tcore_call_status co_status;
2509 dbg("function entrance");
2510 plugin = tcore_object_ref_plugin(o);
2511 cmd = (char *) data;
2512 tokens = tcore_at_tok_new(cmd);
2515 pCallId = g_slist_nth_data(tokens, 0);
2517 dbg("CallId is missing from %XCALLSTAT indication");
2518 tcore_at_tok_free(tokens);
2522 dbg("call id = %d", id);
2524 if ((stat = g_slist_nth_data(tokens, 1))) {
2525 status = atoi(stat);
2527 dbg("call status = %d", status);
2530 tcore_at_tok_free(tokens);
2531 co_status = _call_status(status);
2533 dbg("co_status = %d", co_status);
2534 switch (co_status) {
2535 case CALL_STATUS_ACTIVE:
2537 dbg("call(%d) status : [ ACTIVE ]", id);
2538 co = tcore_call_object_find_by_id(o, id);
2543 _call_status_active(plugin, co);
2547 case CALL_STATUS_HELD:
2548 dbg("call(%d) status : [ held ]", id);
2551 case CALL_STATUS_DIALING:
2553 dbg("call(%d) status : [ dialing ]", id);
2554 co = tcore_call_object_find_by_id(o, id);
2556 co = tcore_call_object_new(o, id);
2558 dbg("error : tcore_call_object_new [ id : %d ]", id);
2563 tcore_call_object_set_type(co, call_type(type));
2564 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
2565 _call_status_dialing(plugin, co);
2569 case CALL_STATUS_ALERT:
2571 dbg("call(%d) status : [ alert ]", id);
2572 co = tcore_call_object_find_by_id(o, id);
2577 // Store dialed number information into Call object.
2578 eflag = g_new0(gboolean, 1);
2580 dbg("calling _call_list_get");
2581 _call_list_get(o, eflag);
2585 case CALL_STATUS_INCOMING:
2586 case CALL_STATUS_WAITING:
2587 dbg("call(%d) status : [ incoming ]", id);
2590 case CALL_STATUS_IDLE:
2592 dbg("call(%d) status : [ release ]", id);
2594 co = tcore_call_object_find_by_id(o, id);
2600 plugin = tcore_object_ref_plugin(o);
2602 dbg("plugin is NULL");
2605 _call_status_idle(plugin, co);
2610 dbg("invalid call status", id);
2615 static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
2617 struct treq_call_dial *data = 0;
2619 const char *cclir, *num;
2620 enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
2621 TcorePending *pending;
2622 TcoreATRequest *req;
2627 data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
2628 if (data->type == CALL_TYPE_VIDEO) {
2629 dbg("invalid call type");
2630 return TCORE_RETURN_FAILURE;
2633 clir = _get_clir_status(data->number);
2635 if (clir == TCORE_CALL_CLI_MODE_DEFAULT) {
2636 TcorePlugin *plugin = tcore_object_ref_plugin(o);
2637 Server *server = tcore_plugin_ref_server(plugin);
2640 dbg("Reading VCONF key");
2642 strg = tcore_server_find_storage(server, "vconf");
2643 clir = tcore_storage_get_int(strg,
2644 STORAGE_KEY_CISSAPPL_SHOW_MY_NUMBER_INT);
2648 /* Need to remove CLIR code from dialing number */
2649 num = data->number + 4;
2651 /* Compose ATD Cmd string */
2653 case TCORE_CALL_CLI_MODE_PRESENT:
2654 dbg("CALL_CLI_MODE_PRESENT");
2658 case TCORE_CALL_CLI_MODE_RESTRICT:
2659 dbg("CALL_CLI_MODE_RESTRICT");
2663 case TCORE_CALL_CLI_MODE_DEFAULT:
2666 dbg("CALL_CLI_MODE_DEFAULT");
2670 dbg("data->number = %s", data->number);
2672 cmd_str = g_strdup_printf("ATD%s%s;", num, cclir);
2674 dbg("request command : %s", cmd_str);
2676 pending = tcore_pending_new(o, 0);
2677 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2678 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2680 tcore_pending_set_request_data(pending, 0, req);
2681 ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
2686 dbg("AT request(%s) sent failed", req->cmd);
2687 return TCORE_RETURN_FAILURE;
2690 dbg("AT request(%s) sent success", req->cmd);
2694 return TCORE_RETURN_SUCCESS;
2697 static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
2699 char *cmd_str = NULL;
2700 CallObject *co = NULL;
2701 struct treq_call_answer *data = 0;
2702 TcorePending *pending = NULL;
2703 TcoreATRequest *req;
2704 gboolean ret = FALSE;
2706 dbg("function entrance");
2708 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2709 dbg("cp not ready/n");
2710 return TCORE_RETURN_ENOSYS;
2713 data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
2714 co = tcore_call_object_find_by_id(o, data->id);
2715 if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
2716 dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
2718 cmd_str = g_strdup_printf("%s", "ATA");
2719 pending = tcore_pending_new(o, 0);
2720 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2721 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2723 tcore_pending_set_request_data(pending, 0, req);
2724 ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
2728 dbg("AT request(%s) sent failed", req->cmd);
2729 return TCORE_RETURN_FAILURE;
2732 switch (data->type) {
2733 case CALL_ANSWER_TYPE_REJECT:
2735 dbg("call answer reject");
2736 tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
2740 case CALL_ANSWER_TYPE_REPLACE:
2742 dbg("call answer replace");
2743 tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
2747 case CALL_ANSWER_TYPE_HOLD_ACCEPT:
2749 dbg("call answer hold and accept");
2750 tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
2755 dbg("[ error ] wrong answer type [ %d ]", data->type);
2756 return TCORE_RETURN_FAILURE;
2760 return TCORE_RETURN_SUCCESS;
2763 static TReturn s_call_release(CoreObject *o, UserRequest *ur)
2765 CallObject *co = NULL;
2766 struct treq_call_end *data = 0;
2767 UserRequest *ur_dup = NULL;
2768 char *chld0_cmd = NULL;
2769 char *chld1_cmd = NULL;
2770 TcorePending *pending = NULL, *pending1 = NULL;
2771 TcoreATRequest *req, *req1;
2772 gboolean ret = FALSE;
2774 dbg("function entrance");
2775 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2776 dbg("cp not ready/n");
2777 return TCORE_RETURN_ENOSYS;
2779 data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
2780 co = tcore_call_object_find_by_id(o, data->id);
2782 dbg("type of release call = %d", data->type);
2784 if (data->type == CALL_END_TYPE_ALL) {
2785 // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
2786 chld0_cmd = g_strdup("AT+CHLD=0");
2787 chld1_cmd = g_strdup("AT+CHLD=1");
2789 pending = tcore_pending_new(o, 0);
2790 req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
2792 dbg("input command is %s", chld0_cmd);
2793 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2795 tcore_pending_set_request_data(pending, 0, req);
2796 ur_dup = tcore_user_request_new(NULL, NULL);
2797 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
2801 dbg("AT request %s has failed ", req->cmd);
2803 tcore_user_request_free(ur_dup);
2807 return TCORE_RETURN_FAILURE;
2810 pending1 = tcore_pending_new(o, 0);
2811 req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
2813 dbg("input command is %s", chld1_cmd);
2814 dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
2816 tcore_pending_set_request_data(pending1, 0, req1);
2817 ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
2821 dbg("AT request %s has failed ", req->cmd);
2822 return TCORE_RETURN_FAILURE;
2825 switch (data->type) {
2826 case CALL_END_TYPE_DEFAULT:
2829 id = tcore_call_object_get_id(co);
2831 dbg("call end call id [%d]", id);
2832 tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
2836 case CALL_END_TYPE_ACTIVE_ALL:
2838 dbg("call end all active");
2839 tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
2843 case CALL_END_TYPE_HOLD_ALL:
2845 dbg("call end all held");
2846 tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
2851 dbg("[ error ] wrong end type [ %d ]", data->type);
2852 return TCORE_RETURN_FAILURE;
2856 return TCORE_RETURN_SUCCESS;
2859 static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
2861 struct treq_call_hold *hold = 0;
2862 CallObject *co = NULL;
2864 dbg("function entrance");
2866 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2867 dbg("cp not ready/n");
2868 return TCORE_RETURN_ENOSYS;
2871 hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
2872 dbg("call id : [ %d ]", hold->id);
2874 co = tcore_call_object_find_by_id(o, hold->id);
2875 tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
2877 return TCORE_RETURN_SUCCESS;
2880 static TReturn s_call_active(CoreObject *o, UserRequest *ur)
2882 struct treq_call_active *active = 0;
2883 CallObject *co = NULL;
2885 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2886 dbg("cp not ready/n");
2887 return TCORE_RETURN_ENOSYS;
2890 active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
2891 dbg("call id : [ %d ]", active->id);
2893 co = tcore_call_object_find_by_id(o, active->id);
2894 tcore_call_control_active(o, ur, on_confirmation_call_active, co);
2896 return TCORE_RETURN_SUCCESS;
2899 static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
2901 struct treq_call_swap *swap = NULL;
2902 CallObject *co = NULL;
2904 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2905 dbg("cp not ready/n");
2906 return TCORE_RETURN_ENOSYS;
2909 swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
2910 dbg("call id : [ %d ]", swap->id);
2912 co = tcore_call_object_find_by_id(o, swap->id);
2913 tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
2915 return TCORE_RETURN_SUCCESS;
2918 static TReturn s_call_join(CoreObject *o, UserRequest *ur)
2920 struct treq_call_join *join = 0;
2921 CallObject *co = NULL;
2923 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2924 dbg("cp not ready/n");
2925 return TCORE_RETURN_ENOSYS;
2928 join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
2929 dbg("call id : [ %d ]", join->id);
2931 co = tcore_call_object_find_by_id(o, join->id);
2932 tcore_call_control_join(o, ur, on_confirmation_call_join, co);
2934 return TCORE_RETURN_SUCCESS;
2937 static TReturn s_call_split(CoreObject *o, UserRequest *ur)
2939 struct treq_call_split *split = 0;
2940 CallObject *co = NULL;
2942 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2943 dbg("cp not ready/n");
2944 return TCORE_RETURN_ENOSYS;
2947 split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
2948 co = tcore_call_object_find_by_id(o, split->id);
2949 dbg("call id : [ %d ]", split->id);
2951 tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
2953 return TCORE_RETURN_SUCCESS;
2956 static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
2958 struct treq_call_deflect *deflect = 0;
2959 CallObject *co = NULL;
2961 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2962 dbg("cp not ready/n");
2963 return TCORE_RETURN_ENOSYS;
2966 deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
2967 co = tcore_call_object_find_by_number(o, deflect->number);
2968 dbg("deflect number: [ %s ]", deflect->number);
2970 tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
2972 return TCORE_RETURN_SUCCESS;
2975 static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
2977 struct treq_call_transfer *transfer = 0;
2978 CallObject *co = NULL;
2980 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
2981 dbg("cp not ready/n");
2982 return TCORE_RETURN_ENOSYS;
2985 transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
2986 dbg("call id : [ %d ]", transfer->id);
2988 co = tcore_call_object_find_by_id(o, transfer->id);
2989 tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
2991 return TCORE_RETURN_SUCCESS;
2994 static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
2996 char *cmd_str = NULL;
2997 TcorePending *pending = NULL;
2998 TcoreATRequest *req;
3000 gboolean ret = FALSE;
3001 struct treq_call_dtmf *dtmf = 0;
3002 char *dtmfstr = NULL, *tmp_dtmf = NULL;
3003 unsigned int dtmf_count;
3005 dbg("Function enter");
3007 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3008 dbg("cp not ready/n");
3009 return TCORE_RETURN_ENOSYS;
3012 dup = tcore_user_request_new(NULL, NULL);
3013 (void) _set_dtmf_tone_duration(o, dup);
3015 dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
3016 dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1); // DTMF digits + comma for each dtmf digit.
3018 if (dtmfstr == NULL) {
3019 dbg("Memory allocation failed");
3020 return TCORE_RETURN_FAILURE;
3025 for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
3026 *tmp_dtmf = dtmf->digits[dtmf_count];
3033 // last digit is having COMMA , overwrite it with '\0' .
3034 *(--tmp_dtmf) = '\0';
3035 dbg("Input DTMF string(%s)", dtmfstr);
3037 // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
3038 cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
3039 dbg("request command : %s", cmd_str);
3041 pending = tcore_pending_new(o, 0);
3042 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3043 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3045 tcore_pending_set_request_data(pending, 0, req);
3046 ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
3051 dbg("AT request sent failed");
3052 return TCORE_RETURN_FAILURE;
3055 return TCORE_RETURN_SUCCESS;
3058 static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
3060 UserRequest *ur_dup = NULL;
3061 TcorePending *pending = NULL, *pending1 = NULL;
3062 TcoreATRequest *req, *req1;
3063 char *cmd_str = NULL, *cmd_str1 = NULL;
3064 int device_type = -1;
3065 struct treq_call_sound_set_path *sound_path = 0;
3066 gboolean ret = FALSE;
3067 TcorePlugin *plugin = tcore_object_ref_plugin(o);
3068 const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
3070 dbg("function entrance");
3072 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3073 dbg("cp not ready/n");
3074 return TCORE_RETURN_ENOSYS;
3076 sound_path = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
3077 if (sound_path == NULL) {
3078 dbg("invaling user request");
3079 return TCORE_RETURN_FAILURE;
3081 dbg("audio device type - 0x%x", sound_path->path);
3082 switch (sound_path->path) {
3083 case CALL_SOUND_PATH_HANDSET:
3087 case CALL_SOUND_PATH_HEADSET:
3091 case CALL_SOUND_PATH_HEADSET_3_5PI:
3095 case CALL_SOUND_PATH_SPEAKER:
3099 case CALL_SOUND_PATH_HANDFREE:
3103 case CALL_SOUND_PATH_HEADSET_HAC:
3107 case CALL_SOUND_PATH_BLUETOOTH:
3108 case CALL_SOUND_PATH_STEREO_BLUETOOTH:
3112 case CALL_SOUND_PATH_BT_NSEC_OFF:
3113 case CALL_SOUND_PATH_MIC1:
3114 case CALL_SOUND_PATH_MIC2:
3116 dbg("unsupported device type");
3117 return TCORE_RETURN_FAILURE;
3120 if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
3121 struct tnoti_call_sound_path *tnoti_snd_path;
3123 tnoti_snd_path = g_try_new0(struct tnoti_call_sound_path, 1);
3124 if (!tnoti_snd_path)
3125 return TCORE_RETURN_ENOMEM;
3127 tnoti_snd_path->path = sound_path->path;
3129 /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
3130 if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
3131 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);
3132 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);
3135 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);
3136 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);
3139 /* Configure modem I2S2 and do the modem routing */
3140 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);
3141 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);
3142 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
3143 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
3144 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
3145 call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
3148 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
3149 call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
3150 /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
3152 pending = tcore_pending_new(o, 0);
3153 req = tcore_at_request_new("AT+XDRV=40,6,0,2", "+XDRV", TCORE_AT_SINGLELINE);
3154 dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3155 tcore_pending_set_request_data(pending, 0, req);
3156 ur_dup = tcore_user_request_ref(ur);
3157 ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, tnoti_snd_path);
3161 cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
3162 pending = tcore_pending_new(o, 0);
3163 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3164 dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3165 tcore_pending_set_request_data(pending, 0, req);
3166 ur_dup = tcore_user_request_ref(ur);
3167 ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
3171 dbg("At request(%s) sent failed", req->cmd);
3172 return TCORE_RETURN_FAILURE;
3175 cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
3176 pending1 = tcore_pending_new(o, 0);
3177 req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
3178 dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
3179 tcore_pending_set_request_data(pending1, 0, req1);
3180 ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
3184 dbg("AT request %s has failed ", req1->cmd);
3185 return TCORE_RETURN_FAILURE;
3189 return TCORE_RETURN_SUCCESS;
3192 static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
3194 UserRequest *src_ur = NULL;
3195 UserRequest *dest_ur = NULL;
3196 TcorePending *src_pending = NULL;
3197 TcorePending *dest_pending = NULL;
3198 TcoreATRequest *src_req = NULL;
3199 TcoreATRequest *dest_req = NULL;
3200 char *cmd_str = NULL, *volume_level = NULL;
3201 gboolean ret = FALSE;
3202 struct treq_call_sound_set_volume_level *data = NULL;
3206 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3207 dbg("cp not ready/n");
3208 return TCORE_RETURN_ENOSYS;
3211 data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
3213 // Hard-coded values for MIC & Speakers
3215 dbg("Set Source volume");
3217 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source type
3218 dbg("Request command string: %s", cmd_str);
3220 // Create new Pending request
3221 src_pending = tcore_pending_new(o, 0);
3223 // Create new AT-Command request
3224 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3225 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3227 // Free Command string
3230 tcore_pending_set_request_data(src_pending, 0, src_req);
3231 src_ur = tcore_user_request_ref(ur);
3234 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3236 err("Failed to send AT-Command request");
3237 return TCORE_RETURN_FAILURE;
3240 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type
3241 dbg("Request command string: %s", cmd_str);
3243 // Create new Pending request
3244 src_pending = tcore_pending_new(o, 0);
3246 // Create new AT-Command request
3247 src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3248 dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
3250 // Free Command string
3253 tcore_pending_set_request_data(src_pending, 0, src_req);
3255 src_ur = tcore_user_request_ref(ur);
3258 ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3260 err("Failed to send AT-Command request");
3261 return TCORE_RETURN_FAILURE;
3264 // Destination volume
3265 dbg("Set Source volume");
3267 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type
3268 dbg("Request command string: %s", cmd_str);
3270 // Create new Pending request
3271 dest_pending = tcore_pending_new(o, 0);
3273 // Create new AT-Command request
3274 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3275 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3277 // Free Command string
3280 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3281 dest_ur = tcore_user_request_ref(ur);
3284 ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
3286 err("Failed to send AT-Command request");
3287 return TCORE_RETURN_FAILURE;
3290 dbg("Input volume level - %d", data->volume);
3291 switch (data->volume) {
3292 case CALL_SOUND_MUTE:
3296 case CALL_SOUND_VOLUME_LEVEL_1:
3297 volume_level = "40";
3300 case CALL_SOUND_VOLUME_LEVEL_2:
3301 volume_level = "46";
3304 case CALL_SOUND_VOLUME_LEVEL_3:
3305 volume_level = "52";
3308 case CALL_SOUND_VOLUME_LEVEL_4:
3309 volume_level = "58";
3312 case CALL_SOUND_VOLUME_LEVEL_5:
3313 volume_level = "64";
3316 case CALL_SOUND_VOLUME_LEVEL_6:
3317 volume_level = "70";
3320 case CALL_SOUND_VOLUME_LEVEL_7:
3321 volume_level = "76";
3324 case CALL_SOUND_VOLUME_LEVEL_8:
3325 volume_level = "82";
3328 case CALL_SOUND_VOLUME_LEVEL_9:
3330 volume_level = "88";
3333 cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level); // Destination type
3334 dbg("Request command string: %s", cmd_str);
3336 // Create new Pending request
3337 dest_pending = tcore_pending_new(o, 0);
3339 // Create new AT-Command request
3340 dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3341 dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
3343 // Free Command string
3346 tcore_pending_set_request_data(dest_pending, 0, dest_req);
3349 ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
3351 err("Failed to send AT-Command request");
3352 return TCORE_RETURN_FAILURE;
3355 return TCORE_RETURN_SUCCESS;
3359 static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
3364 return TCORE_RETURN_SUCCESS;
3367 static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
3369 char *cmd_str = NULL;
3370 TcorePending *pending = NULL;
3371 TcoreATRequest *req = NULL;
3372 gboolean ret = FALSE;
3376 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3377 dbg("cp not ready/n");
3378 return TCORE_RETURN_ENOSYS;
3381 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
3383 dbg("Request command string: %s", cmd_str);
3385 // Create new Pending request
3386 pending = tcore_pending_new(o, 0);
3388 // Create new AT-Command request
3389 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3390 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3392 // Free command string
3395 // Set request data (AT command) to Pending request
3396 tcore_pending_set_request_data(pending, 0, req);
3399 ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
3401 err("Failed to send AT-Command request");
3402 return TCORE_RETURN_FAILURE;
3406 return TCORE_RETURN_SUCCESS;
3409 static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
3411 char *cmd_str = NULL;
3412 TcorePending *pending = NULL;
3413 TcoreATRequest *req = NULL;
3414 gboolean ret = FALSE;
3418 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3419 dbg("cp not ready/n");
3420 return TCORE_RETURN_ENOSYS;
3423 cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
3424 dbg("Request command string: %s", cmd_str);
3426 // Create new Pending request
3427 pending = tcore_pending_new(o, 0);
3429 // Create new AT-Command request
3430 req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
3431 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3433 // Free command string
3436 // Set request data (AT command) to Pending request
3437 tcore_pending_set_request_data(pending, 0, req);
3440 ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
3442 err("Failed to send AT-Command request");
3443 return TCORE_RETURN_FAILURE;
3447 return TCORE_RETURN_SUCCESS;
3451 static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
3456 return TCORE_RETURN_SUCCESS;
3459 static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
3461 char *cmd_str = NULL;
3462 TcorePending *pending = NULL;
3463 TcoreATRequest *req = NULL;
3464 gboolean ret = FALSE;
3468 cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.
3469 dbg("Request command string: %s", cmd_str);
3471 // Create new Pending request
3472 pending = tcore_pending_new(o, 0);
3474 // Create new AT-Command request
3475 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3476 dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
3478 // Free command string */
3481 // Set request data (AT command) to Pending request
3482 tcore_pending_set_request_data(pending, 0, req);
3485 ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
3487 err("Failed to send AT-Command request");
3489 tcore_user_request_free(ur);
3492 return TCORE_RETURN_FAILURE;
3496 return TCORE_RETURN_SUCCESS;
3500 static struct tcore_call_operations call_ops = {
3501 .dial = s_call_outgoing,
3502 .answer = s_call_answer,
3503 .end = s_call_release,
3504 .hold = s_call_hold,
3505 .active = s_call_active,
3506 .swap = s_call_swap,
3507 .join = s_call_join,
3508 .split = s_call_split,
3509 .deflect = s_call_deflect,
3510 .transfer = s_call_transfer,
3511 .send_dtmf = s_call_send_dtmf,
3512 .set_sound_path = s_call_set_sound_path,
3513 .set_sound_volume_level = s_call_set_sound_volume_level,
3514 .get_sound_volume_level = s_call_get_sound_volume_level,
3515 .mute = s_call_mute,
3516 .unmute = s_call_unmute,
3517 .get_mute_status = s_call_get_mute_status,
3518 .set_sound_recording = NULL,
3519 .set_sound_equalization = NULL,
3520 .set_sound_noise_reduction = NULL,
3523 gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call)
3527 tcore_call_override_ops(co_call, &call_ops, NULL);
3530 tcore_object_override_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
3531 tcore_object_override_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
3538 void s_call_exit(TcorePlugin *cp, CoreObject *co_call)