-/*\r
- * tel-plugin-imc\r
- *\r
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
- *\r
- * Contact: sharanayya mathapati <sharan.m@samsung.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <glib.h>\r
-\r
-#include <tcore.h>\r
-#include <hal.h>\r
-#include <core_object.h>\r
-#include <plugin.h>\r
-#include <queue.h>\r
-#include <co_call.h>\r
-#include <user_request.h>\r
-#include <server.h>\r
-#include <at.h>\r
-\r
-#include "s_common.h"\r
-#include "s_call.h"\r
-\r
-\r
-#define STATUS_INCOMING 4\r
-#define STATUS_WAITING 5\r
-#define STATUS_CONNECTED 7\r
-#define COMMA 0X2c\r
-\r
-static gboolean setsoundpath = FALSE;\r
-static gboolean soundvolume = FALSE;\r
-\r
-// End Cause field - Call state end cause\r
-\r
-typedef enum {\r
- CALL_END_NO_CAUSE,\r
-\r
- // These definitions are taken from GSM 04.08 Table 10.86\r
-\r
- CC_CAUSE_UNASSIGNED_NUMBER,\r
- CC_CAUSE_NO_ROUTE_TO_DEST,\r
- CC_CAUSE_CHANNEL_UNACCEPTABLE,\r
- CC_CAUSE_OPERATOR_DETERMINED_BARRING,\r
- CC_CAUSE_NORMAL_CALL_CLEARING,\r
- CC_CAUSE_USER_BUSY,\r
- CC_CAUSE_NO_USER_RESPONDING,\r
- CC_CAUSE_USER_ALERTING_NO_ANSWER,\r
- CC_CAUSE_CALL_REJECTED,\r
- CC_CAUSE_NUMBER_CHANGED,\r
- CC_CAUSE_NON_SELECTED_USER_CLEARING,\r
- CC_CAUSE_DESTINATION_OUT_OF_ORDER,\r
- CC_CAUSE_INVALID_NUMBER_FORMAT,\r
- CC_CAUSE_FACILITY_REJECTED,\r
- CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY,\r
- CC_CAUSE_NORMAL_UNSPECIFIED,\r
- CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE,\r
- CC_CAUSE_NETWORK_OUT_OF_ORDER,\r
- CC_CAUSE_TEMPORARY_FAILURE,\r
- CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION,\r
- CC_CAUSE_ACCESS_INFORMATION_DISCARDED,\r
- CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE,\r
- CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED,\r
- CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE,\r
- CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED,\r
- CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG,\r
- CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED,\r
- CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE,\r
- CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE,\r
- CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED,\r
- CC_CAUSE_ACM_GEQ_ACMMAX,\r
- CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED,\r
- CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE,\r
- CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED,\r
- CC_CAUSE_INVALID_TRANSACTION_ID_VALUE,\r
- CC_CAUSE_USER_NOT_MEMBER_OF_CUG,\r
- CC_CAUSE_INCOMPATIBLE_DESTINATION,\r
- CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION,\r
- CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,\r
- CC_CAUSE_INVALID_MANDATORY_INFORMATION,\r
- CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT,\r
- CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE,\r
- CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED,\r
- CC_CAUSE_CONDITIONAL_IE_ERROR,\r
- CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,\r
- CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY,\r
- CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,\r
- CC_CAUSE_INTERWORKING_UNSPECIFIED,\r
- CC_CAUSE_END = 128,\r
-\r
- // Reject causes\r
- REJECT_CAUSE_IMSI_UNKNOWN_IN_HLR,\r
- REJECT_CAUSE_ILLEGAL_MS,\r
- REJECT_CAUSE_IMSI_UNKNOWN_IN_VLR,\r
- REJECT_CAUSE_IMEI_NOT_ACCEPTED,\r
- REJECT_CAUSE_ILLEGAL_ME,\r
- REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED,\r
- REJECT_CAUSE_GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,\r
- REJECT_CAUSE_MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,\r
- REJECT_CAUSE_IMPLICITLY_DETACHED,\r
- REJECT_CAUSE_PLMN_NOT_ALLOWED,\r
- REJECT_CAUSE_LA_NOT_ALLOWED,\r
- REJECT_CAUSE_NATIONAL_ROAMING_NOT_ALLOWED,\r
- REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,\r
- REJECT_CAUSE_NO_SUITABLE_CELLS_IN_LA,\r
- REJECT_CAUSE_MSC_TEMPORARILY_NOT_REACHABLE,\r
- REJECT_CAUSE_NETWORK_FAILURE ,\r
- REJECT_CAUSE_MAC_FAILURE,\r
- REJECT_CAUSE_SYNCH_FAILURE,\r
- REJECT_CAUSE_CONGESTTION,\r
- REJECT_CAUSE_GSM_AUTH_UNACCEPTED,\r
- REJECT_CAUSE_SERVICE_OPTION_NOT_SUPPORTED,\r
- REJECT_CAUSE_REQ_SERV_OPT_NOT_SUBSCRIBED,\r
- REJECT_CAUSE_SERVICE_OPT__OUT_OF_ORDER,\r
- REJECT_CAUSE_CALL_CANNOT_BE_IDENTIFIED,\r
- REJECT_CAUSE_NO_PDP_CONTEXT_ACTIVATED,\r
- REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MIN_VALUE,\r
- REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MAX_VALUE,\r
- REJECT_CAUSE_SEMANTICALLY_INCORRECT_MSG,\r
- REJECT_CAUSE_INVALID_MANDATORY_INFO,\r
- REJECT_CAUSE_MESSAGE_TYPE_NON_EXISTANT,\r
- REJECT_CAUSE_MESSAGE_TYPE_NOT_COMP_PRT_ST,\r
- REJECT_CAUSE_IE_NON_EXISTANT,\r
- REJECT_CAUSE_MSG_NOT_COMPATIBLE_PROTOCOL_STATE,\r
-\r
-\r
- // Connection Management establishment rejection cause\r
- REJECT_CAUSE_REJ_UNSPECIFIED,\r
-\r
- // AS reject causes\r
- REJECT_CAUSE_AS_REJ_RR_REL_IND,\r
- REJECT_CAUSE_AS_REJ_RR_RANDOM_ACCESS_FAILURE,\r
- REJECT_CAUSE_AS_REJ_RRC_REL_IND,\r
- REJECT_CAUSE_AS_REJ_RRC_CLOSE_SESSION_IND,\r
- REJECT_CAUSE_AS_REJ_RRC_OPEN_SESSION_FAILURE,\r
- REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL,\r
- REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL_REDIAL_NOT_ALLOWED,\r
- REJECT_CAUSE_AS_REJ_LOW_LEVEL_IMMED_RETRY,\r
-\r
- // MM reject causes\r
- REJECT_CAUSE_MM_REJ_INVALID_SIM,\r
- REJECT_CAUSE_MM_REJ_NO_SERVICE,\r
- REJECT_CAUSE_MM_REJ_TIMER_T3230_EXP,\r
- REJECT_CAUSE_MM_REJ_NO_CELL_AVAILABLE,\r
- REJECT_CAUSE_MM_REJ_WRONG_STATE,\r
- REJECT_CAUSE_MM_REJ_ACCESS_CLASS_BLOCKED,\r
- // Definitions for release ind causes between MM and CNM\r
- REJECT_CAUSE_ABORT_MSG_RECEIVED,\r
- REJECT_CAUSE_OTHER_CAUSE,\r
-\r
- // CNM reject causes\r
- REJECT_CAUSE_CNM_REJ_TIMER_T303_EXP,\r
- REJECT_CAUSE_CNM_REJ_NO_RESOURCES,\r
- REJECT_CAUSE_CNM_MM_REL_PENDING,\r
- REJECT_CAUSE_CNM_INVALID_USER_DATA,\r
- CALL_END_CAUSE_MAX = 255\r
-}call_end_cause_e_type;\r
-\r
-\r
-struct clcc_call_t {\r
- struct call_CLCC_info {\r
- int id;\r
- enum tcore_call_direction direction;\r
- enum tcore_call_status status;\r
- enum tcore_call_type type;\r
- int mpty;\r
- int num_len;\r
- int num_type;\r
- } info;\r
- char number[90];\r
-};\r
-\r
-typedef struct {\r
- int network_cause;\r
- int tapi_cause;\r
-}call_end_cause_info;\r
-\r
-/**************************************************************************\r
- * Local Function Prototypes\r
- **************************************************************************/\r
-/************************* REQUESTS ***************************/\r
-static void _call_status_idle(TcorePlugin *p, CallObject *co);\r
-static void _call_status_active(TcorePlugin *p, CallObject *co);\r
-static void _call_status_dialing(TcorePlugin *p, CallObject *co);\r
-static void _call_status_alert(TcorePlugin *p, CallObject *co);\r
-static void _call_status_incoming(TcorePlugin *p, CallObject *co);\r
-static void _call_status_waiting(TcorePlugin *p, CallObject *co);\r
-static TReturn _call_list_get(CoreObject *o, gboolean *event_flag);\r
-static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur);\r
-\r
-/************************* CONFIRMATION ***************************/\r
-static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel\r
-static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data);\r
-static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data);\r
-static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data);\r
-static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data);\r
-\r
-static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type);\r
-static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type);\r
-static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data);\r
-static void _on_confirmation_call_end_cause(TcorePending * p, int data_len, const void * data, void * user_data);\r
-\r
-/************************* RESPONSES ***************************/\r
-static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);\r
-\r
-/************************* NOTIIFICATIONS ***************************/\r
-static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data);\r
-static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data);\r
-static void on_notification_call_status(CoreObject *o, const void *data, void *user_data);\r
-static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data);\r
-static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data);\r
-\r
-\r
-/**************************************************************************\r
- * Local Utility Function Prototypes\r
- **************************************************************************/\r
-static gboolean _call_request_message(TcorePending *pending, CoreObject *o, UserRequest* ur, void* on_resp, void* user_data);\r
-static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status);\r
-static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call);\r
-\r
-/**************************************************************************\r
- * Local Function Definitions\r
- **************************************************************************/\r
-\r
-const call_end_cause_info call_end_cause_table[] = { // call end cause table to convert Netwotk cause to TAPI cause\r
-\r
- { 1, CC_CAUSE_UNASSIGNED_NUMBER}, { 3, CC_CAUSE_NO_ROUTE_TO_DEST},\r
- { 6, CC_CAUSE_CHANNEL_UNACCEPTABLE}, { 8, CC_CAUSE_OPERATOR_DETERMINED_BARRING},\r
- { 16, CC_CAUSE_NORMAL_CALL_CLEARING}, { 17, CC_CAUSE_USER_BUSY},\r
- { 18, CC_CAUSE_NO_USER_RESPONDING}, { 19, CC_CAUSE_USER_ALERTING_NO_ANSWER},\r
- { 21, CC_CAUSE_CALL_REJECTED}, { 22, CC_CAUSE_NUMBER_CHANGED},\r
- { 26, CC_CAUSE_NON_SELECTED_USER_CLEARING}, { 27, CC_CAUSE_DESTINATION_OUT_OF_ORDER},\r
- { 28, CC_CAUSE_INVALID_NUMBER_FORMAT}, { 29, CC_CAUSE_FACILITY_REJECTED},\r
- { 30, CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY}, { 31, CC_CAUSE_NORMAL_UNSPECIFIED},\r
- { 34, CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE},{ 38, CC_CAUSE_NETWORK_OUT_OF_ORDER},\r
- { 41, CC_CAUSE_TEMPORARY_FAILURE}, { 42, CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION},\r
- { 43, CC_CAUSE_ACCESS_INFORMATION_DISCARDED},{ 44, CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE},\r
- { 47, CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED}, { 49, CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE},\r
- { 50, CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED}, { 55, CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG},\r
- { 57, CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED}, { 58, CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE},\r
- { 63, CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE}, { 65, CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED},\r
- { 68, CC_CAUSE_ACM_GEQ_ACMMAX}, { 69, CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED},\r
- { 70, CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE}, { 79, CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED},\r
- { 81, CC_CAUSE_INVALID_TRANSACTION_ID_VALUE}, { 87, CC_CAUSE_USER_NOT_MEMBER_OF_CUG},\r
- { 88, CC_CAUSE_INCOMPATIBLE_DESTINATION}, { 91, CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION},\r
- { 95, CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE}, { 96, CC_CAUSE_INVALID_MANDATORY_INFORMATION},\r
- { 97, CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT}, { 98, CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE},\r
- { 99, CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED}, { 100, CC_CAUSE_CONDITIONAL_IE_ERROR},\r
- { 101,CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE},{ 102, CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY},\r
- { 111 ,CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED}, {127, CC_CAUSE_INTERWORKING_UNSPECIFIED},\r
-\r
-};\r
-\r
-static enum tcore_call_cli_mode _get_clir_status(char *num)\r
-{\r
- enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;\r
- dbg("Entry");\r
-\r
- if(!strncmp(num, "*31#", 4)) {\r
- dbg("CLI mode restricted");\r
- return TCORE_CALL_CLI_MODE_RESTRICT;\r
- }\r
-\r
- if(!strncmp(num, "#31#", 4)) {\r
- dbg("CLI mode allowed");\r
- return TCORE_CALL_CLI_MODE_PRESENT;\r
- }\r
-\r
- err("Exit");\r
- return clir;\r
-}\r
-\r
-static enum tcore_call_status _call_status(unsigned int status)\r
-{\r
- dbg("Entry");\r
-\r
- switch(status) {\r
- case 0:\r
- return TCORE_CALL_STATUS_ACTIVE;\r
- case 1:\r
- return TCORE_CALL_STATUS_HELD;\r
- case 2:\r
- return TCORE_CALL_STATUS_DIALING;\r
- case 3:\r
- return TCORE_CALL_STATUS_ALERT;\r
- case 4:\r
- return TCORE_CALL_STATUS_INCOMING;\r
- case 5:\r
- return TCORE_CALL_STATUS_WAITING;\r
- case 6: // DISCONNECTED state // FALL THROUGH\r
- default:\r
- return TCORE_CALL_STATUS_IDLE;\r
- }\r
-}\r
-\r
-static gboolean _call_is_in_mpty(int mpty)\r
-{\r
- dbg("Entry");\r
-\r
- switch(mpty) {\r
- case 0:\r
- return FALSE;\r
- case 1:\r
- return TRUE;\r
- default:\r
- break;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-static enum tcore_call_type call_type(int type)\r
-{\r
- dbg("Entry");\r
-\r
- switch (type) {\r
- case 0:\r
- return TCORE_CALL_TYPE_VOICE;\r
- case 1:\r
- return TCORE_CALL_TYPE_VIDEO;\r
- default:\r
- break;\r
- }\r
-\r
- return TCORE_CALL_TYPE_VOICE;\r
-}\r
-\r
-static int _compare_call_end_cause(int networkcause)\r
-{\r
- unsigned int count;\r
- for (count = 0; count < sizeof(call_end_cause_table)/sizeof(call_end_cause_info); count++){\r
- if (call_end_cause_table[count].network_cause == networkcause)\r
- return (call_end_cause_table[count].tapi_cause);\r
- }\r
- return CC_CAUSE_NORMAL_CALL_CLEARING;\r
- dbg("Exit");\r
-}\r
-\r
-static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
-\r
- // TODO\r
-\r
- return TRUE;\r
-}\r
-\r
-static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)\r
-{\r
- GSList *tokens = NULL;\r
- GSList *lines = NULL;\r
- const char *line = NULL;\r
- char *stat;\r
- int status;\r
-\r
- dbg("Entry");\r
-\r
- lines = (GSList*)data;\r
- if (1 != g_slist_length(lines)) {\r
- err("Unsolicited message, BUT multiple lines present");\r
- goto OUT;\r
- }\r
-\r
- line = (char*)(lines->data);\r
- tokens = tcore_at_tok_new(line);\r
-\r
- stat = g_slist_nth_data(tokens, 1);\r
- if(!stat) {\r
- dbg("Stat is missing from %XCALLSTAT indiaction");\r
- }\r
- else {\r
- status = atoi(stat);\r
-\r
- switch(status) {\r
- case STATUS_INCOMING:\r
- dbg("calling on_notification_call_incoming");\r
- on_notification_call_incoming(o, line, user_data);\r
- break;\r
- case STATUS_WAITING:\r
- dbg("calling on_notification_call_waiting");\r
- on_notification_call_waiting(o, line, user_data);\r
- break;\r
- case STATUS_CONNECTED: /*igonre Connected state. */\r
- dbg("Connected state");\r
- break;\r
- default:\r
- dbg("calling on_notification_call_status");\r
- on_notification_call_status(o, line, user_data);\r
- break;\r
- }\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
-\r
-OUT:\r
- dbg("Exit");\r
- return TRUE;\r
-}\r
-\r
-static gboolean _call_request_message(TcorePending *pending,\r
- CoreObject *o,\r
- UserRequest *ur,\r
- void* on_resp,\r
- void* user_data)\r
-{\r
- TcoreHal *hal = NULL;\r
- TReturn ret;\r
- dbg("Entry");\r
-\r
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);\r
-\r
- if (on_resp) {\r
- tcore_pending_set_response_callback(pending, on_resp, user_data);\r
- }\r
- tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);\r
-\r
- if (ur) {\r
- tcore_pending_link_user_request(pending, ur);\r
- }\r
- else {\r
- err("User Request is NULL, is this internal request??");\r
- }\r
-\r
- // HAL\r
- hal = tcore_object_get_hal(o);\r
- // Send request to HAL\r
- ret = tcore_hal_send_request(hal, pending);\r
- if(TCORE_RETURN_SUCCESS != ret) {\r
- err("Request send failed");\r
- return FALSE;\r
- }\r
-\r
- dbg("Exit");\r
- return TRUE;\r
-}\r
-\r
-static void _call_status_idle(TcorePlugin *p, CallObject *co)\r
-{\r
- CoreObject *core_obj = NULL;\r
- char *cmd_str = NULL;\r
- TcorePending *pending = NULL;\r
- TcoreATRequest *req = NULL;\r
- gboolean ret = FALSE;\r
- UserRequest *ur;\r
-\r
- dbg("Entry");\r
- core_obj = tcore_plugin_ref_core_object(p, "call");\r
- dbg("Call ID [%d], Call Status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));\r
-\r
- if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_IDLE) {\r
-\r
- //get call end cause.\r
- cmd_str = g_strdup_printf("%s","AT+XCEER");\r
- dbg("Request command string: %s", cmd_str);\r
-\r
- // Create new Pending request\r
- pending = tcore_pending_new(core_obj, 0);\r
-\r
- // Create new AT-Command request\r
- req = tcore_at_request_new(cmd_str, "+XCEER", TCORE_AT_SINGLELINE);\r
- dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));\r
- // Free command string\r
- g_free(cmd_str);\r
-\r
- // Set request data (AT command) to Pending request\r
- tcore_pending_set_request_data(pending, 0, req);\r
-\r
- ur = tcore_user_request_new(NULL, NULL);\r
- // Send request\r
- ret = _call_request_message (pending, core_obj, ur, _on_confirmation_call_end_cause, co);\r
-\r
- if (!ret) {\r
- err("Failed to send AT-Command request");\r
- return ;\r
- }\r
-\r
- }\r
- else {\r
- err("Call object was not free");\r
- tcore_call_object_free(core_obj, co);\r
- }\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void _call_status_dialing(TcorePlugin *p, CallObject *co)\r
-{\r
- struct tnoti_call_status_dialing data;\r
- dbg("Entry");\r
-\r
- if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_DIALING) {\r
- data.type = tcore_call_object_get_type(co);\r
- dbg("data.type : [%d]", data.type);\r
-\r
- data.id = tcore_call_object_get_id(co);\r
- dbg("data.id : [%d]", data.id);\r
-\r
- // Set Status\r
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_DIALING);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(p),\r
- tcore_plugin_ref_core_object(p, "call"),\r
- TNOTI_CALL_STATUS_DIALING,\r
- sizeof(struct tnoti_call_status_dialing),\r
- (void*)&data);\r
-\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void _call_status_alert(TcorePlugin *p, CallObject *co)\r
-{\r
- struct tnoti_call_status_alert data;\r
- dbg("Entry");\r
-\r
- // Alerting has just 1 data 'CALL ID'\r
- if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ALERT) {\r
- data.type = tcore_call_object_get_type(co);\r
- dbg("data.type : [%d]", data.type);\r
-\r
- data.id = tcore_call_object_get_id(co);\r
- dbg("data.id : [%d]", data.id);\r
-\r
- // Set Status\r
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_ALERT);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(p),\r
- tcore_plugin_ref_core_object(p, "call"),\r
- TNOTI_CALL_STATUS_ALERT,\r
- sizeof(struct tnoti_call_status_alert),\r
- (void*)&data);\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void _call_status_active(TcorePlugin *p, CallObject *co)\r
-{\r
- struct tnoti_call_status_active data;\r
- dbg("Entry");\r
-\r
- if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ACTIVE) {\r
- data.type = tcore_call_object_get_type(co);\r
- dbg("data.type : [%d]", data.type);\r
-\r
- data.id = tcore_call_object_get_id(co);\r
- dbg("data.id : [%d]", data.id);\r
-\r
- // Set Status\r
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_ACTIVE);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(p),\r
- tcore_plugin_ref_core_object(p, "call"),\r
- TNOTI_CALL_STATUS_ACTIVE,\r
- sizeof(struct tnoti_call_status_active),\r
- (void*)&data);\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void _call_status_held(TcorePlugin *p, CallObject *co)\r
-{\r
- struct tnoti_call_status_held data;\r
- dbg("Entry");\r
-\r
- if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_HELD) {\r
- data.type = tcore_call_object_get_type(co);\r
- dbg("data.type : [%d]", data.type);\r
-\r
- data.id = tcore_call_object_get_id(co);\r
- dbg("data.id : [%d]", data.id);\r
-\r
- // Set Status\r
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(p),\r
- tcore_plugin_ref_core_object(p, "call"),\r
- TNOTI_CALL_STATUS_HELD,\r
- sizeof(struct tnoti_call_status_held),\r
- (void*)&data);\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void _call_status_incoming(TcorePlugin *p, CallObject *co)\r
-{\r
- struct tnoti_call_status_incoming data;\r
- dbg("Entry");\r
-\r
- if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_INCOMING) {\r
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_INCOMING);\r
-\r
- data.type = tcore_call_object_get_type(co);\r
- dbg("data.type : [%d]", data.type);\r
-\r
- data.id = tcore_call_object_get_id(co);\r
- dbg("data.id : [%d]", data.id);\r
-\r
- data.cli.mode = tcore_call_object_get_cli_mode(co);\r
- dbg("data.cli.mode : [%d]", data.cli.mode);\r
-\r
- tcore_call_object_get_number(co, data.cli.number);\r
- dbg("data.cli.number : [%s]", data.cli.number);\r
-\r
- data.cna.mode = tcore_call_object_get_cna_mode(co);\r
- dbg("data.cna.mode : [%d]", data.cna.mode);\r
-\r
- tcore_call_object_get_name(co, data.cna.name);\r
- dbg("data.cna.name : [%s]", data.cna.name);\r
-\r
- data.forward = FALSE; // this is tmp code\r
-\r
- data.active_line = tcore_call_object_get_active_line(co);\r
- dbg("data.active_line : [%d]", data.active_line);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(p),\r
- tcore_plugin_ref_core_object(p, "call"),\r
- TNOTI_CALL_STATUS_INCOMING,\r
- sizeof(struct tnoti_call_status_incoming),\r
- (void*)&data);\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void _call_status_waiting(TcorePlugin *p, CallObject *co)\r
-{\r
- dbg("Entry");\r
- _call_status_incoming(p, co);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status)\r
-{\r
- dbg("Entry");\r
-\r
- dbg("Call Status is %d", status);\r
- switch (status) {\r
- case TCORE_CALL_STATUS_IDLE:\r
- _call_status_idle(p, co);\r
- break;\r
-\r
- case TCORE_CALL_STATUS_ACTIVE:\r
- _call_status_active(p, co);\r
- break;\r
-\r
- case TCORE_CALL_STATUS_HELD:\r
- _call_status_held(p, co);\r
- break;\r
-\r
- case TCORE_CALL_STATUS_DIALING:\r
- _call_status_dialing(p, co);\r
- break;\r
-\r
- case TCORE_CALL_STATUS_ALERT:\r
- _call_status_alert(p, co);\r
- break;\r
-\r
- case TCORE_CALL_STATUS_INCOMING:\r
- _call_status_incoming(p, co);\r
- break;\r
-\r
- case TCORE_CALL_STATUS_WAITING:\r
- _call_status_waiting(p, co);\r
- break;\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static TReturn _call_list_get(CoreObject *o, gboolean *event_flag)\r
-{\r
- UserRequest* ur = NULL;\r
- TcorePending *pending = NULL;\r
- char *cmd_str = NULL;\r
- TcoreATRequest *req = NULL;\r
- gboolean ret = FALSE;\r
-\r
- dbg("Entry");\r
- if (!o) {\r
- err("Core Object is NULL");\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- // Create new User Request\r
- ur = tcore_user_request_new(NULL, NULL);\r
-\r
- // Command string\r
- cmd_str = g_strdup("AT+CLCC");\r
-\r
- // Create new Pending Request\r
- pending = tcore_pending_new(o, 0);\r
- req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);\r
-\r
- g_free(cmd_str);\r
-\r
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));\r
-\r
- tcore_pending_set_request_data(pending, 0, req);\r
-\r
- ret = _call_request_message (pending, o, ur, on_response_call_list_get, event_flag);\r
- if (!ret) {\r
- err("AT request (%s) sending failed", req->cmd);\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- dbg("AT request sent success");\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-// CONFIRMATION\r
-static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data)\r
-{\r
- dbg("Entry");\r
-\r
- if (result == FALSE) { // Fail\r
- dbg("SEND FAIL");\r
- }\r
- else {\r
- dbg("SEND OK");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- const TcoreATResponse* response = data;\r
- struct tresp_call_dial resp;\r
- int error;\r
- dbg("Entry");\r
-\r
- ur = tcore_pending_ref_user_request(p);\r
- if (ur) {\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- dbg("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("Unspecified error cause OR string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- // Send Response to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit")\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- const TcoreATResponse* response = data;\r
- struct tresp_call_answer resp;\r
- int error;\r
- dbg("Entry");\r
-\r
- ur = tcore_pending_ref_user_request(p);\r
- if (ur) {\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- dbg("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("Unspecified error cause OR string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- //Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
-\r
- // Send Response to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-\r
-static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- const TcoreATResponse* response = data;\r
- struct tresp_call_answer resp;\r
- int error;\r
-\r
- dbg("Entry");\r
-\r
- ur = tcore_pending_ref_user_request(p);\r
- if (ur) {\r
- if (response->success > 0) {\r
-\r
- dbg("RESPONSE OK");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
-\r
- dbg("RESPONSE NOT OK");\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("Unspecified error cause OR string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
-\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
-\r
- //Send Response to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- const TcoreATResponse* response = data;\r
- struct tresp_call_answer resp;\r
- int error;\r
-\r
- dbg("Entry");\r
- ur = tcore_pending_ref_user_request(p);\r
- if (ur) {\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
-\r
- dbg("RESPONSE NOT OK");\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("Unspecified error cause OR string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
-\r
- // Send Response to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);\r
- }\r
- else {\r
- dbg("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- CoreObject *o = NULL;\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- const TcoreATResponse* response = data;\r
- struct tresp_call_answer resp;\r
- int error;\r
-\r
- dbg("Entry");\r
-\r
- o = tcore_pending_ref_core_object(p);\r
- ur = tcore_pending_ref_user_request(p);\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
-\r
- if (ur) {\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- err("RESPONSE NOT OK");\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("Unspecified error cause OR string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- // Send response to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);\r
- if (!resp.err) {\r
-\r
- GSList *list = 0;\r
- CallObject *co = NULL;\r
-\r
- // Active Call\r
- list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);\r
- if (!list) {\r
- err("Can't find active Call");\r
- return;\r
- }\r
-\r
- co = (CallObject*)list->data;\r
- if (!co) {\r
- err("Can't get active Call object");\r
- return;\r
- }\r
-\r
- // Set Call Status\r
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);\r
- dbg("Call status is set to HELD");\r
- }\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)\r
-{\r
- UserRequest *ur = NULL;\r
- struct tresp_call_end resp;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- int error;\r
- const TcoreATResponse* response = data;\r
-\r
- dbg("Entry");\r
- ur = tcore_pending_ref_user_request(p);\r
- if (ur) {\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- err("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("Unspecified error cause OR string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- resp.type = type;\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
- dbg("resp.type = %d resp.id= %d", resp.type,resp.id);\r
-\r
- // Send reponse to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-// RESPONSE\r
-static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- // skip response handling - actual result will be handled in on_confirmation_call_release_all\r
- const TcoreATResponse* response = data;\r
- dbg("Entry");\r
-\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
- }\r
- else {\r
- err("RESPONSE NOT OK");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-\r
-static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);\r
-\r
- return;\r
-}\r
-\r
-\r
-static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);\r
-\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);\r
-\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);\r
-\r
- return;\r
-}\r
-\r
-static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- const TcoreATResponse *response = NULL;\r
- int error;\r
-\r
- dbg("Entry");\r
- ur = tcore_pending_ref_user_request(p);\r
- response = (TcoreATResponse *)data;\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
- error = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- err("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("Unspecified error cause OR string corrupted");\r
- error = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- error = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- dbg("Response Call type -%d", type);\r
- switch(type){\r
-\r
- case TRESP_CALL_HOLD:\r
- {\r
- struct tresp_call_hold resp;\r
-\r
- resp.err = error;\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
- dbg("call hold response");\r
- // Send reponse to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);\r
- }\r
- break;\r
- case TRESP_CALL_ACTIVE:\r
- {\r
- struct tresp_call_active resp;\r
-\r
- resp.err = error;\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
- dbg("call active response");\r
- // Send reponse to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);\r
- }\r
- break;\r
- case TRESP_CALL_JOIN:\r
- {\r
- struct tresp_call_join resp;\r
-\r
- resp.err = error;\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
- dbg("call join response");\r
-\r
- // Send reponse to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);\r
- }\r
- break;\r
- case TRESP_CALL_SPLIT:\r
- {\r
- struct tresp_call_split resp;\r
-\r
- resp.err = error;\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
- dbg("call split response");\r
- // Send reponse to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);\r
- }\r
- break;\r
- case TRESP_CALL_DEFLECT:\r
- {\r
- struct tresp_call_deflect resp;\r
-\r
- resp.err = error;\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
- dbg("call deflect response");\r
- // Send reponse to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);\r
- }\r
-\r
- break;\r
- case TRESP_CALL_TRANSFER:\r
- {\r
- struct tresp_call_transfer resp;\r
-\r
- resp.err = error;\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
- dbg("call transfer response");\r
- //Send reponse to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);\r
- }\r
- break;\r
- case TRESP_CALL_SEND_DTMF:\r
- {\r
- struct tresp_call_dtmf resp;\r
-\r
- resp.err = error;\r
- dbg("call dtmf response");\r
- // Send reponse to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_SEND_DTMF, sizeof(struct tresp_call_dtmf), &resp);\r
- }\r
- break;\r
- default:\r
- {\r
- dbg("type not supported");\r
- return;\r
- }\r
- }\r
-\r
- if ((type == TRESP_CALL_HOLD)||(type == TRESP_CALL_ACTIVE)||(type == TRESP_CALL_JOIN)\r
- ||(type == TRESP_CALL_SPLIT)) {\r
-\r
- if (!error) {\r
- CoreObject *core_obj = NULL;\r
- gboolean *eflag = g_new0(gboolean, 1);\r
-\r
- core_obj = tcore_pending_ref_core_object(p);\r
- *eflag = FALSE;\r
-\r
- dbg("Calling _call_list_get");\r
- _call_list_get(core_obj, eflag);\r
- }\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);\r
-\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);\r
-\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);\r
-\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);\r
-\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);\r
-\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);\r
-\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- dbg("Entry");\r
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SEND_DTMF);\r
-\r
- return;\r
-}\r
-\r
-static void _on_confirmation_dtmf_tone_duration(TcorePending * p, int data_len, const void * data, void * user_data)\r
-{\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- const TcoreATResponse* response = data;\r
- int error;\r
-\r
- dbg("Entry");\r
-\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
- error = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
-\r
- err("RESPONSE NOT OK");\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
- if (g_slist_length(tokens) < 1) {\r
- err("err cause not specified or string corrupted");\r
- error = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
- // TODO: CMEE error mapping is required.\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- dbg("Set dtmf tone duration response - %d", error);\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- CoreObject *core_obj = NULL;\r
- UserRequest *ur = NULL;\r
- const TcoreATResponse* response = data;\r
- struct tresp_call_swap resp;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
-\r
- dbg("Entry");\r
- core_obj = tcore_pending_ref_core_object(p);\r
- ur = tcore_pending_ref_user_request(p);\r
-\r
- if (ur) {\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
-\r
- err("RESPONSE NOT OK");\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
- if (g_slist_length(tokens) < 1) {\r
- err("err cause not specified or string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- resp.err = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- //Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- resp.id = tcore_call_object_get_id((CallObject*)user_data);\r
- dbg("resp.id = %d", resp.id);\r
-\r
- // Send response to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);\r
-\r
- if (!resp.err) {\r
-\r
- GSList *active = NULL;\r
- GSList *held = NULL;\r
- CallObject *co = NULL;\r
- gboolean *eflag = NULL;\r
-\r
- held = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_HELD);\r
- if (!held) {\r
- err("Can't find held Call");\r
- return;\r
- }\r
-\r
- active = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_ACTIVE);\r
- if (!active) {\r
- dbg("Can't find active Call");\r
- return;\r
- }\r
-\r
- while (held) {\r
- co = (CallObject*)held->data;\r
- if (!co) {\r
- err("Can't get held Call object");\r
- return;\r
- }\r
-\r
- resp.id = tcore_call_object_get_id(co);\r
-\r
- // Send response to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);\r
-\r
- held = g_slist_next(held);\r
- }\r
-\r
- while (active) {\r
- co = (CallObject*)active->data;\r
- if (!co) {\r
- err("[ error ] can't get active call object");\r
- return;\r
- }\r
-\r
- resp.id = tcore_call_object_get_id(co);\r
-\r
- // Send response to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);\r
- active = g_slist_next(active);\r
- }\r
-\r
- eflag = g_new0(gboolean, 1);\r
- *eflag = FALSE;\r
-\r
- dbg("calling _call_list_get");\r
- _call_list_get(core_obj, eflag);\r
- }\r
- }\r
- else {\r
-\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- const TcoreATResponse* response = data;\r
- char *resp_str = NULL;\r
- struct tresp_call_sound_set_path resp;\r
- int error;\r
-\r
- dbg("Entry");\r
- ur = tcore_pending_ref_user_request(p);\r
-\r
- //+XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3\r
- if (!response) {\r
- err("Input data is NULL");\r
- return;\r
- }\r
-\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
-\r
- line = (const char*) (((GSList*)response->lines)->data);\r
- tokens = tcore_at_tok_new(line);\r
-\r
- resp_str = g_slist_nth_data(tokens, 0);\r
- if(!g_slist_nth_data(tokens, 0)) {\r
- err("group_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- if(!g_slist_nth_data(tokens, 1)) {\r
- err(" function_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- resp_str = g_slist_nth_data(tokens, 2);\r
-\r
- if(resp_str) {\r
- error = atoi(resp_str);\r
- if(0 == error) {\r
- dbg("Response is Success");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- }\r
-OUT:\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
- else {\r
- dbg("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("err cause not specified or string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- if (ur) {\r
- if(resp.err != TCORE_RETURN_SUCCESS) { // Send only failed notification . success notification send when destination device is set.\r
- // Send notification to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);\r
- setsoundpath = TRUE;\r
- }\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- char *resp_str = NULL ;\r
- struct tresp_call_sound_set_path resp;\r
- const TcoreATResponse* response = data;\r
- int error;\r
-\r
- dbg("Entry");\r
-\r
- ur = tcore_pending_ref_user_request(p);\r
- // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3\r
-\r
- if (!response) {\r
- err("Input data is NULL");\r
- return;\r
- }\r
-\r
- if (ur) {\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
-\r
- line = (const char*) (((GSList*)response->lines)->data);\r
- tokens = tcore_at_tok_new(line);\r
-\r
- resp_str = g_slist_nth_data(tokens, 0);\r
- if(!g_slist_nth_data(tokens, 0)) {\r
- dbg("group_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- if(!g_slist_nth_data(tokens, 1)) {\r
- dbg("function_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- resp_str = g_slist_nth_data(tokens, 2);\r
- if(resp_str) {\r
- error = atoi(resp_str);\r
- if(0 == error) {\r
- dbg("Response is Success");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- }\r
-\r
-OUT:\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
- else {\r
- dbg("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("err cause not specified or string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- if(setsoundpath == TRUE) {\r
- setsoundpath = FALSE;\r
- }\r
- else {\r
- // Send response to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);\r
- }\r
- }\r
- else {\r
- dbg("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- const TcoreATResponse* response = data;\r
- char *resp_str = NULL;\r
- struct tresp_call_sound_set_volume_level resp;\r
- int error;\r
-\r
- ur = tcore_pending_ref_user_request(p);\r
- dbg("Entry");\r
- // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3\r
- if (!response) {\r
- err("Input data is NULL");\r
- return;\r
- }\r
-\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
-\r
- line = (const char*) (((GSList*)response->lines)->data);\r
- tokens = tcore_at_tok_new(line);\r
-\r
- resp_str = g_slist_nth_data(tokens, 0);\r
- if(!g_slist_nth_data(tokens, 0)) {\r
- err("group_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- if(!g_slist_nth_data(tokens, 1)) {\r
- err("function_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- resp_str = g_slist_nth_data(tokens, 2);\r
- if(resp_str) {\r
- error = atoi(resp_str);\r
-\r
- if(0 == error) {\r
- dbg("Response is Success ");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- }\r
-\r
-OUT:\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
- else {\r
- dbg("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("err cause not specified or string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- if (ur) {\r
- if(resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.\r
- // Send reposne to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);\r
- soundvolume = TRUE;\r
- }\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-\r
-static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- char *resp_str = NULL;\r
- const TcoreATResponse* response = data;\r
- struct tresp_call_sound_set_volume_level resp;\r
- int error;\r
-\r
- dbg("Entry");\r
-\r
- ur = tcore_pending_ref_user_request(p);\r
-\r
- // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3\r
- if (!response) {\r
- err("Input data is NULL");\r
- return;\r
- }\r
-\r
- if (ur) {\r
- if (response->success > 0) {\r
-\r
- dbg("RESPONSE OK");\r
- line = (const char*) (((GSList*)response->lines)->data);\r
- tokens = tcore_at_tok_new(line);\r
- resp_str = g_slist_nth_data(tokens, 0);\r
-\r
- if(!g_slist_nth_data(tokens, 0)) {\r
- err("group_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- if(!g_slist_nth_data(tokens, 1)) {\r
- err("function_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- resp_str = g_slist_nth_data(tokens, 2);\r
-\r
- if(resp_str) {\r
- error = atoi(resp_str);\r
-\r
- if(0 == error) {\r
- dbg("Response is Success");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- }\r
-\r
-OUT:\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
- else {\r
- dbg("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("err cause not specified or string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- if(soundvolume == TRUE){\r
- soundvolume = FALSE;\r
- }\r
- else{\r
- // Send reposne to TAPI\r
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);\r
- }\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-\r
-static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- UserRequest *ur = NULL;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- char *resp_str = NULL;\r
- struct tresp_call_mute resp;\r
- const TcoreATResponse* response = data;\r
- int error;\r
-\r
- dbg("Entry");\r
-\r
- ur = tcore_pending_ref_user_request(p);\r
-\r
- if (!response) {\r
- err("Input data is NULL");\r
- return;\r
- }\r
-\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
-\r
- line = (const char*) (((GSList*)response->lines)->data);\r
- tokens = tcore_at_tok_new(line);\r
- resp_str = g_slist_nth_data(tokens, 0);\r
-\r
- if(!g_slist_nth_data(tokens, 0)) {\r
- err("group_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- if(!g_slist_nth_data(tokens, 1)) {\r
- err(" function_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- resp_str = g_slist_nth_data(tokens, 2);\r
-\r
- if(resp_str) {\r
- error = atoi(resp_str);\r
- if(0 == error) {\r
- dbg("Response is Success");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- }\r
-OUT:\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
- else {\r
- dbg("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("err cause not specified or string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- if (ur) {\r
- tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- const TcoreATResponse *response = NULL;\r
- struct tresp_call_unmute resp;\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- UserRequest *ur = NULL;\r
- char *resp_str = NULL;\r
- int error;\r
-\r
- dbg("Entry");\r
-\r
- response = (TcoreATResponse *)data;\r
- ur = tcore_pending_ref_user_request(p);\r
-\r
- if (!response) {\r
- err("Input data is NULL");\r
- return;\r
- }\r
-\r
- if (response->success > 0) {\r
- dbg("RESPONSE OK");\r
-\r
- line = (const char*) (((GSList*)response->lines)->data);\r
- tokens = tcore_at_tok_new(line);\r
- resp_str = g_slist_nth_data(tokens, 0);\r
-\r
- if(!g_slist_nth_data(tokens, 0)) {\r
- err("group_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- if(!g_slist_nth_data(tokens, 1)) {\r
- err(" function_id is missing");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- goto OUT;\r
- }\r
-\r
- resp_str = g_slist_nth_data(tokens, 2);\r
-\r
- if(resp_str) {\r
- error = atoi(resp_str);\r
- if(0 == error) {\r
- dbg("Response is Success");\r
- resp.err = TCORE_RETURN_SUCCESS;\r
- }\r
- else {\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- }\r
-OUT:\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
- else {\r
- dbg("RESPONSE NOT OK");\r
-\r
- line = (const char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- if (g_slist_length(tokens) < 1) {\r
- err("err cause not specified or string corrupted");\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
- else {\r
- error = atoi(g_slist_nth_data(tokens, 0));\r
-\r
- // TODO: CMEE error mapping is required.\r
- resp.err = TCORE_RETURN_3GPP_ERROR;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- if (ur) {\r
- tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);\r
- }\r
- else {\r
- err("User Request is NULL");\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-// RESPONSE\r
-static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CoreObject *core_obj = NULL;\r
- CallObject *co = NULL;\r
- struct clcc_call_t *call_list = NULL;\r
- gboolean *event_flag = (gboolean*)user_data;\r
- const TcoreATResponse *response = data;\r
- GSList *resp_data = NULL;\r
- char *line = NULL;\r
-\r
- int cllc_info = 0, countCalls = 0, countValidCalls = 0;\r
- int error = 0;\r
- dbg("Entry");\r
-\r
- plugin = tcore_pending_ref_plugin(p);\r
- core_obj = tcore_pending_ref_core_object(p);\r
-\r
- if(response->success > 0) {\r
- dbg("RESPONCE OK");\r
- if(response->lines) {\r
- resp_data = (GSList*)response->lines;\r
- countCalls = g_slist_length(resp_data);\r
- dbg("Total records : %d",countCalls);\r
- }\r
-\r
- if (0 == countCalls) {\r
- err("Call count is zero");\r
- return;\r
- }\r
-\r
- call_list = g_new0(struct clcc_call_t, countCalls);\r
-\r
- for (countValidCalls = 0;resp_data != NULL ;resp_data = resp_data->next,countValidCalls++,cllc_info++) {\r
-\r
- line = (char*)(resp_data->data);\r
-\r
- error = _callFromCLCCLine(line, call_list + countValidCalls);\r
- if (0 != error) {\r
- continue;\r
- }\r
-\r
- co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);\r
- if (!co) {\r
- co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);\r
- if (!co) {\r
- err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);\r
- continue;\r
- }\r
- }\r
-\r
- // Call set parameters\r
- tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));\r
- tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);\r
- tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));\r
- tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);\r
- tcore_call_object_set_active_line(co, 0);\r
-\r
- if (*event_flag) {\r
- dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);\r
- _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);\r
- }\r
- else {\r
- // Set Status\r
- tcore_call_object_set_status(co, call_list[cllc_info].info.status);\r
-\r
- dbg("Call id : (%d)", call_list[cllc_info].info.id);\r
- dbg("Call direction : (%d)", call_list[cllc_info].info.direction);\r
- dbg("Call type : (%d)", call_list[cllc_info].info.type);\r
- dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);\r
- dbg("Call number : (%s)", call_list[cllc_info].number);\r
- dbg("Call status : (%d)", call_list[cllc_info].info.status);\r
- }\r
- }\r
-\r
- // Free Call list\r
- g_free(call_list);\r
- }\r
-\r
- // Free User data\r
- g_free(event_flag);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void _on_confirmation_call_end_cause(TcorePending * p, int data_len, const void * data, void * user_data)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CoreObject *core_obj = NULL;\r
- CallObject *co = (CallObject *)user_data;\r
- const TcoreATResponse *response = data;\r
- const char *line = NULL;\r
- struct tnoti_call_status_idle call_status;\r
- GSList *tokens = NULL;\r
- char* resp_str;\r
- int error;\r
-\r
- dbg("Entry");\r
- plugin = tcore_pending_ref_plugin(p);\r
- core_obj = tcore_pending_ref_core_object(p);\r
-\r
- if (response->success > 0){\r
- dbg("RESPONSE OK");\r
- line = (const char*) (((GSList*)response->lines)->data);\r
- tokens = tcore_at_tok_new(line);\r
- resp_str = g_slist_nth_data(tokens, 0);\r
- if(!resp_str){\r
- err("call end cause - report value missing");\r
- }\r
- else {\r
- resp_str = g_slist_nth_data(tokens, 1);\r
- if(!resp_str){\r
- err("call end cause value missing");\r
- }\r
- error = atoi(resp_str);\r
- dbg("call end cause - %d",error);\r
- call_status.cause =_compare_call_end_cause(error);\r
- dbg("TAPI call end cause - %d",call_status.cause);\r
- }\r
-\r
- //Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
- else {\r
- err("RESPONSE NOT OK");\r
- line = (char*)response->final_response;\r
- tokens = tcore_at_tok_new(line);\r
- if (g_slist_length(tokens) < 1) {\r
- err("err cause not specified or string corrupted");\r
- }\r
- else {\r
- err(" err cause value: %d",atoi(g_slist_nth_data(tokens, 0)));\r
- }\r
- call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;\r
- //Free tokens\r
- tcore_at_tok_free(tokens);\r
- }\r
-\r
- call_status.type = tcore_call_object_get_type(co);\r
- dbg("data.type : [%d]", call_status.type);\r
-\r
- call_status.id = tcore_call_object_get_id(co);\r
- dbg("data.id : [%d]", call_status.id);\r
-\r
- // Set Status\r
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);\r
-\r
- // Send Notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- core_obj,\r
- TNOTI_CALL_STATUS_IDLE,\r
- sizeof(struct tnoti_call_status_idle),\r
- (void*)&call_status);\r
-\r
- // Free Call object\r
- tcore_call_object_free(core_obj, co);\r
-}\r
-\r
-static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)\r
-{\r
- //+CLCC: 1,0,2,0,0,"18005551212",145\r
- //[+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]\r
- int state;\r
- int mode;\r
- int isMT;\r
- char *num = NULL;\r
- unsigned int num_type;\r
- GSList *tokens = NULL;\r
- char *resp = NULL;\r
- dbg("Entry");\r
-\r
- tokens = tcore_at_tok_new(line);\r
- // parse <id>\r
- resp = g_slist_nth_data(tokens, 0);\r
- if(!resp) {\r
- err("InValid ID");\r
- goto ERROR;\r
- }\r
- p_call->info.id = atoi(resp);\r
- dbg("id : [%d]\n", p_call->info.id);\r
-\r
- //parse <dir>\r
- resp = g_slist_nth_data(tokens, 1);\r
- if(!resp) {\r
- err("InValid Dir");\r
- goto ERROR;\r
- }\r
- isMT = atoi(resp);\r
- if(0 == isMT) {\r
- p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;\r
- }\r
- else {\r
- p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;\r
- }\r
- dbg("Direction : [ %d ]\n", p_call->info.direction);\r
-\r
- // parse <stat>\r
- resp = g_slist_nth_data(tokens, 2);\r
- if(!resp) {\r
- err("InValid Stat");\r
- goto ERROR;\r
- }\r
- state = atoi(resp);\r
- dbg("Call state : %d", state);\r
- switch(state){\r
- case 0: //active\r
- p_call->info.status = TCORE_CALL_STATUS_ACTIVE;\r
- break;\r
- case 1:\r
- p_call->info.status = TCORE_CALL_STATUS_HELD;\r
- break;\r
- case 2:\r
- p_call->info.status = TCORE_CALL_STATUS_DIALING;\r
- break;\r
- case 3:\r
- p_call->info.status = TCORE_CALL_STATUS_ALERT;\r
- break;\r
- case 4:\r
- p_call->info.status = TCORE_CALL_STATUS_INCOMING;\r
- break;\r
- case 5:\r
- p_call->info.status = TCORE_CALL_STATUS_WAITING;\r
- break;\r
- }\r
- dbg("Status : [%d]\n", p_call->info.status);\r
-\r
- // parse <mode>\r
- resp = g_slist_nth_data(tokens, 3);\r
- if(!resp) {\r
- err("InValid Mode");\r
- goto ERROR;\r
- }\r
- mode = atoi(resp);\r
- switch(mode)\r
- {\r
- case 0:\r
- p_call->info.type = TCORE_CALL_TYPE_VOICE;\r
- break;\r
- case 1:\r
- p_call->info.type = TCORE_CALL_TYPE_VIDEO;\r
- break;\r
- default: // only Voice/VT call is supported in CS. treat other unknown calls as error\r
- dbg("invalid type : [%d]\n", mode);\r
- goto ERROR;\r
- }\r
- dbg("Call type : [%d]\n", p_call->info.type);\r
-\r
- // parse <mpty>\r
- resp = g_slist_nth_data(tokens, 4);\r
- if(!resp) {\r
- err("InValid Mpty");\r
- goto ERROR;\r
- }\r
-\r
- p_call->info.mpty = atoi(resp);\r
- dbg("Mpty : [ %d ]\n", p_call->info.mpty);\r
-\r
- // parse <num>\r
- resp = g_slist_nth_data(tokens, 5);\r
- dbg("Incoming number - %s and its len - %d", resp, strlen(resp));\r
-\r
- // tolerate null here\r
- if (!resp) {\r
- err("Number is NULL");\r
- goto ERROR;\r
- }\r
- // Strike off double quotes\r
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: sharanayya mathapati <sharan.m@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <queue.h>
+#include <co_call.h>
+#include <user_request.h>
+#include <server.h>
+#include <at.h>
+
+#include "s_common.h"
+#include "s_call.h"
+
+
+#define STATUS_INCOMING 4
+#define STATUS_WAITING 5
+#define STATUS_CONNECTED 7
+#define COMMA 0X2c
+
+static gboolean setsoundpath = FALSE;
+static gboolean soundvolume = FALSE;
+
+// End Cause field - Call state end cause
+
+typedef enum {
+ CALL_END_NO_CAUSE,
+
+ // These definitions are taken from GSM 04.08 Table 10.86
+
+ CC_CAUSE_UNASSIGNED_NUMBER,
+ CC_CAUSE_NO_ROUTE_TO_DEST,
+ CC_CAUSE_CHANNEL_UNACCEPTABLE,
+ CC_CAUSE_OPERATOR_DETERMINED_BARRING,
+ CC_CAUSE_NORMAL_CALL_CLEARING,
+ CC_CAUSE_USER_BUSY,
+ CC_CAUSE_NO_USER_RESPONDING,
+ CC_CAUSE_USER_ALERTING_NO_ANSWER,
+ CC_CAUSE_CALL_REJECTED,
+ CC_CAUSE_NUMBER_CHANGED,
+ CC_CAUSE_NON_SELECTED_USER_CLEARING,
+ CC_CAUSE_DESTINATION_OUT_OF_ORDER,
+ CC_CAUSE_INVALID_NUMBER_FORMAT,
+ CC_CAUSE_FACILITY_REJECTED,
+ CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY,
+ CC_CAUSE_NORMAL_UNSPECIFIED,
+ CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE,
+ CC_CAUSE_NETWORK_OUT_OF_ORDER,
+ CC_CAUSE_TEMPORARY_FAILURE,
+ CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION,
+ CC_CAUSE_ACCESS_INFORMATION_DISCARDED,
+ CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE,
+ CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED,
+ CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE,
+ CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED,
+ CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG,
+ CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED,
+ CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE,
+ CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE,
+ CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED,
+ CC_CAUSE_ACM_GEQ_ACMMAX,
+ CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED,
+ CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE,
+ CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED,
+ CC_CAUSE_INVALID_TRANSACTION_ID_VALUE,
+ CC_CAUSE_USER_NOT_MEMBER_OF_CUG,
+ CC_CAUSE_INCOMPATIBLE_DESTINATION,
+ CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION,
+ CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
+ CC_CAUSE_INVALID_MANDATORY_INFORMATION,
+ CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
+ CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE,
+ CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED,
+ CC_CAUSE_CONDITIONAL_IE_ERROR,
+ CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,
+ CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY,
+ CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
+ CC_CAUSE_INTERWORKING_UNSPECIFIED,
+ CC_CAUSE_END = 128,
+
+ // Reject causes
+ REJECT_CAUSE_IMSI_UNKNOWN_IN_HLR,
+ REJECT_CAUSE_ILLEGAL_MS,
+ REJECT_CAUSE_IMSI_UNKNOWN_IN_VLR,
+ REJECT_CAUSE_IMEI_NOT_ACCEPTED,
+ REJECT_CAUSE_ILLEGAL_ME,
+ REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED,
+ REJECT_CAUSE_GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,
+ REJECT_CAUSE_MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
+ REJECT_CAUSE_IMPLICITLY_DETACHED,
+ REJECT_CAUSE_PLMN_NOT_ALLOWED,
+ REJECT_CAUSE_LA_NOT_ALLOWED,
+ REJECT_CAUSE_NATIONAL_ROAMING_NOT_ALLOWED,
+ REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
+ REJECT_CAUSE_NO_SUITABLE_CELLS_IN_LA,
+ REJECT_CAUSE_MSC_TEMPORARILY_NOT_REACHABLE,
+ REJECT_CAUSE_NETWORK_FAILURE,
+ REJECT_CAUSE_MAC_FAILURE,
+ REJECT_CAUSE_SYNCH_FAILURE,
+ REJECT_CAUSE_CONGESTTION,
+ REJECT_CAUSE_GSM_AUTH_UNACCEPTED,
+ REJECT_CAUSE_SERVICE_OPTION_NOT_SUPPORTED,
+ REJECT_CAUSE_REQ_SERV_OPT_NOT_SUBSCRIBED,
+ REJECT_CAUSE_SERVICE_OPT__OUT_OF_ORDER,
+ REJECT_CAUSE_CALL_CANNOT_BE_IDENTIFIED,
+ REJECT_CAUSE_NO_PDP_CONTEXT_ACTIVATED,
+ REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MIN_VALUE,
+ REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MAX_VALUE,
+ REJECT_CAUSE_SEMANTICALLY_INCORRECT_MSG,
+ REJECT_CAUSE_INVALID_MANDATORY_INFO,
+ REJECT_CAUSE_MESSAGE_TYPE_NON_EXISTANT,
+ REJECT_CAUSE_MESSAGE_TYPE_NOT_COMP_PRT_ST,
+ REJECT_CAUSE_IE_NON_EXISTANT,
+ REJECT_CAUSE_MSG_NOT_COMPATIBLE_PROTOCOL_STATE,
+
+
+ // Connection Management establishment rejection cause
+ REJECT_CAUSE_REJ_UNSPECIFIED,
+
+ // AS reject causes
+ REJECT_CAUSE_AS_REJ_RR_REL_IND,
+ REJECT_CAUSE_AS_REJ_RR_RANDOM_ACCESS_FAILURE,
+ REJECT_CAUSE_AS_REJ_RRC_REL_IND,
+ REJECT_CAUSE_AS_REJ_RRC_CLOSE_SESSION_IND,
+ REJECT_CAUSE_AS_REJ_RRC_OPEN_SESSION_FAILURE,
+ REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL,
+ REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL_REDIAL_NOT_ALLOWED,
+ REJECT_CAUSE_AS_REJ_LOW_LEVEL_IMMED_RETRY,
+
+ // MM reject causes
+ REJECT_CAUSE_MM_REJ_INVALID_SIM,
+ REJECT_CAUSE_MM_REJ_NO_SERVICE,
+ REJECT_CAUSE_MM_REJ_TIMER_T3230_EXP,
+ REJECT_CAUSE_MM_REJ_NO_CELL_AVAILABLE,
+ REJECT_CAUSE_MM_REJ_WRONG_STATE,
+ REJECT_CAUSE_MM_REJ_ACCESS_CLASS_BLOCKED,
+ // Definitions for release ind causes between MM and CNM
+ REJECT_CAUSE_ABORT_MSG_RECEIVED,
+ REJECT_CAUSE_OTHER_CAUSE,
+
+ // CNM reject causes
+ REJECT_CAUSE_CNM_REJ_TIMER_T303_EXP,
+ REJECT_CAUSE_CNM_REJ_NO_RESOURCES,
+ REJECT_CAUSE_CNM_MM_REL_PENDING,
+ REJECT_CAUSE_CNM_INVALID_USER_DATA,
+ CALL_END_CAUSE_MAX = 255
+} call_end_cause_e_type;
+
+
+struct clcc_call_t {
+ struct call_CLCC_info {
+ int id;
+ enum tcore_call_direction direction;
+ enum tcore_call_status status;
+ enum tcore_call_type type;
+ int mpty;
+ int num_len;
+ int num_type;
+ }
+ info;
+ char number[90];
+};
+
+typedef struct {
+ int network_cause;
+ int tapi_cause;
+} call_end_cause_info;
+
+/**************************************************************************
+ * Local Function Prototypes
+ **************************************************************************/
+/************************* REQUESTS ***************************/
+static void _call_status_idle(TcorePlugin *p, CallObject *co);
+static void _call_status_active(TcorePlugin *p, CallObject *co);
+static void _call_status_dialing(TcorePlugin *p, CallObject *co);
+static void _call_status_alert(TcorePlugin *p, CallObject *co);
+static void _call_status_incoming(TcorePlugin *p, CallObject *co);
+static void _call_status_waiting(TcorePlugin *p, CallObject *co);
+static TReturn _call_list_get(CoreObject *o, gboolean *event_flag);
+static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur);
+
+/************************* CONFIRMATION ***************************/
+static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
+static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data);
+
+static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type);
+static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type);
+static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data);
+static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data);
+
+/************************* RESPONSES ***************************/
+static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);
+
+/************************* NOTIIFICATIONS ***************************/
+static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data);
+static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data);
+static void on_notification_call_status(CoreObject *o, const void *data, void *user_data);
+static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data);
+static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data);
+
+
+/**************************************************************************
+ * Local Utility Function Prototypes
+ **************************************************************************/
+static gboolean _call_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
+static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status);
+static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call);
+
+/**************************************************************************
+ * Local Function Definitions
+ **************************************************************************/
+
+const call_end_cause_info call_end_cause_table[] = // call end cause table to convert Netwotk cause to TAPI cause
+{
+ { 1, CC_CAUSE_UNASSIGNED_NUMBER}, { 3, CC_CAUSE_NO_ROUTE_TO_DEST},
+ { 6, CC_CAUSE_CHANNEL_UNACCEPTABLE}, { 8, CC_CAUSE_OPERATOR_DETERMINED_BARRING},
+ { 16, CC_CAUSE_NORMAL_CALL_CLEARING}, { 17, CC_CAUSE_USER_BUSY},
+ { 18, CC_CAUSE_NO_USER_RESPONDING}, { 19, CC_CAUSE_USER_ALERTING_NO_ANSWER},
+ { 21, CC_CAUSE_CALL_REJECTED}, { 22, CC_CAUSE_NUMBER_CHANGED},
+ { 26, CC_CAUSE_NON_SELECTED_USER_CLEARING}, { 27, CC_CAUSE_DESTINATION_OUT_OF_ORDER},
+ { 28, CC_CAUSE_INVALID_NUMBER_FORMAT}, { 29, CC_CAUSE_FACILITY_REJECTED},
+ { 30, CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY}, { 31, CC_CAUSE_NORMAL_UNSPECIFIED},
+ { 34, CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE}, { 38, CC_CAUSE_NETWORK_OUT_OF_ORDER},
+ { 41, CC_CAUSE_TEMPORARY_FAILURE}, { 42, CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION},
+ { 43, CC_CAUSE_ACCESS_INFORMATION_DISCARDED}, { 44, CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE},
+ { 47, CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED}, { 49, CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE},
+ { 50, CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED}, { 55, CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG},
+ { 57, CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED}, { 58, CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE},
+ { 63, CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE}, { 65, CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED},
+ { 68, CC_CAUSE_ACM_GEQ_ACMMAX}, { 69, CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED},
+ { 70, CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE}, { 79, CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED},
+ { 81, CC_CAUSE_INVALID_TRANSACTION_ID_VALUE}, { 87, CC_CAUSE_USER_NOT_MEMBER_OF_CUG},
+ { 88, CC_CAUSE_INCOMPATIBLE_DESTINATION}, { 91, 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},
+ { 111, CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED}, {127, CC_CAUSE_INTERWORKING_UNSPECIFIED},
+};
+
+static enum tcore_call_cli_mode _get_clir_status(char *num)
+{
+ enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
+ dbg("Entry");
+
+ if (!strncmp(num, "*31#", 4)) {
+ dbg("CLI mode restricted");
+ return TCORE_CALL_CLI_MODE_RESTRICT;
+ }
+
+ if (!strncmp(num, "#31#", 4)) {
+ dbg("CLI mode allowed");
+ return TCORE_CALL_CLI_MODE_PRESENT;
+ }
+
+ err("Exit");
+ return clir;
+}
+
+static enum tcore_call_status _call_status(unsigned int status)
+{
+ dbg("Entry");
+
+ switch (status) {
+ case 0:
+ return TCORE_CALL_STATUS_ACTIVE;
+
+ case 1:
+ return TCORE_CALL_STATUS_HELD;
+
+ case 2:
+ return TCORE_CALL_STATUS_DIALING;
+
+ case 3:
+ return TCORE_CALL_STATUS_ALERT;
+
+ case 4:
+ return TCORE_CALL_STATUS_INCOMING;
+
+ case 5:
+ return TCORE_CALL_STATUS_WAITING;
+
+ case 6: // DISCONNECTED state // FALL THROUGH
+ default:
+ return TCORE_CALL_STATUS_IDLE;
+ }
+}
+
+static gboolean _call_is_in_mpty(int mpty)
+{
+ dbg("Entry");
+
+ switch (mpty) {
+ case 0:
+ return FALSE;
+
+ case 1:
+ return TRUE;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+static enum tcore_call_type call_type(int type)
+{
+ dbg("Entry");
+
+ switch (type) {
+ case 0:
+ return TCORE_CALL_TYPE_VOICE;
+
+ case 1:
+ return TCORE_CALL_TYPE_VIDEO;
+
+ default:
+ break;
+ }
+
+ return TCORE_CALL_TYPE_VOICE;
+}
+
+static int _compare_call_end_cause(int networkcause)
+{
+ unsigned int count;
+ for (count = 0; count < sizeof(call_end_cause_table) / sizeof(call_end_cause_info); count++) {
+ if (call_end_cause_table[count].network_cause == networkcause)
+ return (call_end_cause_table[count].tapi_cause);
+ }
+ return CC_CAUSE_NORMAL_CALL_CLEARING;
+ dbg("Exit");
+}
+
+static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data)
+{
+ dbg("Entry");
+
+ // TODO
+
+ return TRUE;
+}
+
+static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ const char *line = NULL;
+ char *stat;
+ int status;
+
+ dbg("Entry");
+
+ lines = (GSList *) data;
+ if (1 != g_slist_length(lines)) {
+ err("Unsolicited message, BUT multiple lines present");
+ goto OUT;
+ }
+
+ line = (char *) (lines->data);
+ tokens = tcore_at_tok_new(line);
+
+ stat = g_slist_nth_data(tokens, 1);
+ if (!stat) {
+ dbg("Stat is missing from %XCALLSTAT indiaction");
+ } else {
+ status = atoi(stat);
+
+ switch (status) {
+ case STATUS_INCOMING:
+ dbg("calling on_notification_call_incoming");
+ on_notification_call_incoming(o, line, user_data);
+ break;
+
+ case STATUS_WAITING:
+ dbg("calling on_notification_call_waiting");
+ on_notification_call_waiting(o, line, user_data);
+ break;
+
+ case STATUS_CONNECTED: /*igonre Connected state. */
+ dbg("Connected state");
+ break;
+
+ default:
+ dbg("calling on_notification_call_status");
+ on_notification_call_status(o, line, user_data);
+ break;
+ }
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+
+OUT:
+ dbg("Exit");
+ return TRUE;
+}
+
+static gboolean _call_request_message(TcorePending *pending,
+ CoreObject *o,
+ UserRequest *ur,
+ void *on_resp,
+ void *user_data)
+{
+ TcoreHal *hal = NULL;
+ TReturn ret;
+ dbg("Entry");
+
+ tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
+
+ if (on_resp) {
+ tcore_pending_set_response_callback(pending, on_resp, user_data);
+ }
+ tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
+
+ if (ur) {
+ tcore_pending_link_user_request(pending, ur);
+ } else {
+ err("User Request is NULL, is this internal request??");
+ }
+
+ // HAL
+ hal = tcore_object_get_hal(o);
+ // Send request to HAL
+ ret = tcore_hal_send_request(hal, pending);
+ if (TCORE_RETURN_SUCCESS != ret) {
+ err("Request send failed");
+ return FALSE;
+ }
+
+ dbg("Exit");
+ return TRUE;
+}
+
+static void _call_status_idle(TcorePlugin *p, CallObject *co)
+{
+ CoreObject *core_obj = NULL;
+ char *cmd_str = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req = NULL;
+ gboolean ret = FALSE;
+ UserRequest *ur;
+
+ dbg("Entry");
+ core_obj = tcore_plugin_ref_core_object(p, "call");
+ dbg("Call ID [%d], Call Status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));
+
+ if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_IDLE) {
+ // get call end cause.
+ cmd_str = g_strdup_printf("%s", "AT+XCEER");
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ pending = tcore_pending_new(core_obj, 0);
+
+ // Create new AT-Command request
+ req = tcore_at_request_new(cmd_str, "+XCEER", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
+ // Free command string
+ g_free(cmd_str);
+
+ // Set request data (AT command) to Pending request
+ tcore_pending_set_request_data(pending, 0, req);
+
+ ur = tcore_user_request_new(NULL, NULL);
+ // Send request
+ ret = _call_request_message(pending, core_obj, ur, _on_confirmation_call_end_cause, co);
+
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return;
+ }
+ } else {
+ err("Call object was not free");
+ tcore_call_object_free(core_obj, co);
+ }
+ dbg("Exit");
+ return;
+}
+
+static void _call_status_dialing(TcorePlugin *p, CallObject *co)
+{
+ struct tnoti_call_status_dialing data;
+ dbg("Entry");
+
+ if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_DIALING) {
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ // Set Status
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_DIALING);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(p),
+ tcore_plugin_ref_core_object(p, "call"),
+ TNOTI_CALL_STATUS_DIALING,
+ sizeof(struct tnoti_call_status_dialing),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _call_status_alert(TcorePlugin *p, CallObject *co)
+{
+ struct tnoti_call_status_alert data;
+ dbg("Entry");
+
+ // Alerting has just 1 data 'CALL ID'
+ if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ALERT) {
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ // Set Status
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_ALERT);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(p),
+ tcore_plugin_ref_core_object(p, "call"),
+ TNOTI_CALL_STATUS_ALERT,
+ sizeof(struct tnoti_call_status_alert),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _call_status_active(TcorePlugin *p, CallObject *co)
+{
+ struct tnoti_call_status_active data;
+ dbg("Entry");
+
+ if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ACTIVE) {
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ // Set Status
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_ACTIVE);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(p),
+ tcore_plugin_ref_core_object(p, "call"),
+ TNOTI_CALL_STATUS_ACTIVE,
+ sizeof(struct tnoti_call_status_active),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _call_status_held(TcorePlugin *p, CallObject *co)
+{
+ struct tnoti_call_status_held data;
+ dbg("Entry");
+
+ if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_HELD) {
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ // Set Status
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(p),
+ tcore_plugin_ref_core_object(p, "call"),
+ TNOTI_CALL_STATUS_HELD,
+ sizeof(struct tnoti_call_status_held),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _call_status_incoming(TcorePlugin *p, CallObject *co)
+{
+ struct tnoti_call_status_incoming data;
+ dbg("Entry");
+
+ if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_INCOMING) {
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_INCOMING);
+
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ data.cli.mode = tcore_call_object_get_cli_mode(co);
+ dbg("data.cli.mode : [%d]", data.cli.mode);
+
+ tcore_call_object_get_number(co, data.cli.number);
+ dbg("data.cli.number : [%s]", data.cli.number);
+
+ data.cna.mode = tcore_call_object_get_cna_mode(co);
+ dbg("data.cna.mode : [%d]", data.cna.mode);
+
+ tcore_call_object_get_name(co, data.cna.name);
+ dbg("data.cna.name : [%s]", data.cna.name);
+
+ data.forward = FALSE; // this is tmp code
+
+ data.active_line = tcore_call_object_get_active_line(co);
+ dbg("data.active_line : [%d]", data.active_line);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(p),
+ tcore_plugin_ref_core_object(p, "call"),
+ TNOTI_CALL_STATUS_INCOMING,
+ sizeof(struct tnoti_call_status_incoming),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _call_status_waiting(TcorePlugin *p, CallObject *co)
+{
+ dbg("Entry");
+ _call_status_incoming(p, co);
+
+ dbg("Exit");
+ return;
+}
+
+static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status)
+{
+ dbg("Entry");
+
+ dbg("Call Status is %d", status);
+ switch (status) {
+ case TCORE_CALL_STATUS_IDLE:
+ _call_status_idle(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_ACTIVE:
+ _call_status_active(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_HELD:
+ _call_status_held(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_DIALING:
+ _call_status_dialing(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_ALERT:
+ _call_status_alert(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_INCOMING:
+ _call_status_incoming(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_WAITING:
+ _call_status_waiting(p, co);
+ break;
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static TReturn _call_list_get(CoreObject *o, gboolean *event_flag)
+{
+ UserRequest *ur = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ TcoreATRequest *req = NULL;
+ gboolean ret = FALSE;
+
+ dbg("Entry");
+ if (!o) {
+ err("Core Object is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ // Create new User Request
+ ur = tcore_user_request_new(NULL, NULL);
+
+ // Command string
+ cmd_str = g_strdup("AT+CLCC");
+
+ // Create new Pending Request
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);
+
+ g_free(cmd_str);
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+
+ ret = _call_request_message(pending, o, ur, on_response_call_list_get, event_flag);
+ if (!ret) {
+ err("AT request (%s) sending failed", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("AT request sent success");
+ return TCORE_RETURN_SUCCESS;
+}
+
+// CONFIRMATION
+static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data)
+{
+ dbg("Entry");
+
+ if (result == FALSE) { // Fail
+ dbg("SEND FAIL");
+ } else {
+ dbg("SEND OK");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_dial resp;
+ int error;
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ // Send Response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit")
+ return;
+}
+
+static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_answer resp;
+ int error;
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+
+ // Send Response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+
+static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_answer resp;
+ int error;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("RESPONSE NOT OK");
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+
+ // Send Response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_answer resp;
+ int error;
+
+ dbg("Entry");
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("RESPONSE NOT OK");
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+
+ // Send Response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+ } else {
+ dbg("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *o = NULL;
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_answer resp;
+ int error;
+
+ dbg("Entry");
+
+ o = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ err("RESPONSE NOT OK");
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+ if (!resp.err) {
+ GSList *list = 0;
+ CallObject *co = NULL;
+
+ // Active Call
+ list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
+ if (!list) {
+ err("Can't find active Call");
+ return;
+ }
+
+ co = (CallObject *) list->data;
+ if (!co) {
+ err("Can't get active Call object");
+ return;
+ }
+
+ // Set Call Status
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
+ dbg("Call status is set to HELD");
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)
+{
+ UserRequest *ur = NULL;
+ struct tresp_call_end resp;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ int error;
+ const TcoreATResponse *response = data;
+
+ dbg("Entry");
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ err("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ resp.type = type;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("resp.type = %d resp.id= %d", resp.type, resp.id);
+
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+// RESPONSE
+static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ // skip response handling - actual result will be handled in on_confirmation_call_release_all
+ const TcoreATResponse *response = data;
+ dbg("Entry");
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ } else {
+ err("RESPONSE NOT OK");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+
+static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);
+
+ return;
+}
+
+
+static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);
+
+ return;
+}
+
+static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);
+
+ return;
+}
+
+static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);
+
+ return;
+}
+
+static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = NULL;
+ int error;
+
+ dbg("Entry");
+ ur = tcore_pending_ref_user_request(p);
+ response = (TcoreATResponse *) data;
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ error = TCORE_RETURN_SUCCESS;
+ } else {
+ err("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ error = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ error = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("Response Call type -%d", type);
+ switch (type) {
+ case TRESP_CALL_HOLD:
+ {
+ struct tresp_call_hold resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call hold response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
+ }
+ break;
+
+ case TRESP_CALL_ACTIVE:
+ {
+ struct tresp_call_active resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call active response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
+ }
+ break;
+
+ case TRESP_CALL_JOIN:
+ {
+ struct tresp_call_join resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call join response");
+
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
+ }
+ break;
+
+ case TRESP_CALL_SPLIT:
+ {
+ struct tresp_call_split resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call split response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
+ }
+ break;
+
+ case TRESP_CALL_DEFLECT:
+ {
+ struct tresp_call_deflect resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call deflect response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
+ }
+
+ break;
+
+ case TRESP_CALL_TRANSFER:
+ {
+ struct tresp_call_transfer resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call transfer response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
+ }
+ break;
+
+ case TRESP_CALL_SEND_DTMF:
+ {
+ struct tresp_call_dtmf resp;
+
+ resp.err = error;
+ dbg("call dtmf response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_SEND_DTMF, sizeof(struct tresp_call_dtmf), &resp);
+ }
+ break;
+
+ default:
+ {
+ dbg("type not supported");
+ return;
+ }
+ }
+
+ if ((type == TRESP_CALL_HOLD) || (type == TRESP_CALL_ACTIVE) || (type == TRESP_CALL_JOIN)
+ || (type == TRESP_CALL_SPLIT)) {
+ if (!error) {
+ CoreObject *core_obj = NULL;
+ gboolean *eflag = g_new0(gboolean, 1);
+
+ core_obj = tcore_pending_ref_core_object(p);
+ *eflag = FALSE;
+
+ dbg("Calling _call_list_get");
+ _call_list_get(core_obj, eflag);
+ }
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);
+
+ return;
+}
+
+static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);
+
+ return;
+}
+
+static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);
+
+ return;
+}
+
+static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);
+
+ return;
+}
+
+static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);
+
+ return;
+}
+
+static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);
+
+ return;
+}
+
+static void on_confirmation_call_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SEND_DTMF);
+
+ return;
+}
+
+static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ int error;
+
+ dbg("Entry");
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ error = TCORE_RETURN_SUCCESS;
+ } else {
+ err("RESPONSE NOT OK");
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ error = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("Set dtmf tone duration response - %d", error);
+ return;
+}
+
+static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *core_obj = NULL;
+ UserRequest *ur = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_swap resp;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+
+ dbg("Entry");
+ core_obj = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ err("RESPONSE NOT OK");
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ resp.err = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("resp.id = %d", resp.id);
+
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
+
+ if (!resp.err) {
+ GSList *active = NULL;
+ GSList *held = NULL;
+ CallObject *co = NULL;
+ gboolean *eflag = NULL;
+
+ held = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_HELD);
+ if (!held) {
+ err("Can't find held Call");
+ return;
+ }
+
+ active = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_ACTIVE);
+ if (!active) {
+ dbg("Can't find active Call");
+ return;
+ }
+
+ while (held) {
+ co = (CallObject *) held->data;
+ if (!co) {
+ err("Can't get held Call object");
+ return;
+ }
+
+ resp.id = tcore_call_object_get_id(co);
+
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
+
+ held = g_slist_next(held);
+ }
+
+ while (active) {
+ co = (CallObject *) active->data;
+ if (!co) {
+ err("[ error ] can't get active call object");
+ return;
+ }
+
+ resp.id = tcore_call_object_get_id(co);
+
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
+ active = g_slist_next(active);
+ }
+
+ eflag = g_new0(gboolean, 1);
+ *eflag = FALSE;
+
+ dbg("calling _call_list_get");
+ _call_list_get(core_obj, eflag);
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ char *resp_str = NULL;
+ struct tresp_call_sound_set_path resp;
+ int error;
+
+ dbg("Entry");
+ ur = tcore_pending_ref_user_request(p);
+
+ // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+ if (!response) {
+ err("Input data is NULL");
+ return;
+ }
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+
+ line = (const char *) (((GSList *) response->lines)->data);
+ tokens = tcore_at_tok_new(line);
+
+ resp_str = g_slist_nth_data(tokens, 0);
+ if (!g_slist_nth_data(tokens, 0)) {
+ err("group_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err(" function_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ resp_str = g_slist_nth_data(tokens, 2);
+
+ if (resp_str) {
+ error = atoi(resp_str);
+ if (0 == error) {
+ dbg("Response is Success");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+ }
+OUT:
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ if (ur) {
+ if (resp.err != TCORE_RETURN_SUCCESS) { // Send only failed notification . success notification send when destination device is set.
+ // Send notification to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
+ setsoundpath = TRUE;
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ char *resp_str = NULL;
+ struct tresp_call_sound_set_path resp;
+ const TcoreATResponse *response = data;
+ int error;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+
+ if (!response) {
+ err("Input data is NULL");
+ return;
+ }
+
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+
+ line = (const char *) (((GSList *) response->lines)->data);
+ tokens = tcore_at_tok_new(line);
+
+ resp_str = g_slist_nth_data(tokens, 0);
+ if (!g_slist_nth_data(tokens, 0)) {
+ dbg("group_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ dbg("function_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ resp_str = g_slist_nth_data(tokens, 2);
+ if (resp_str) {
+ error = atoi(resp_str);
+ if (0 == error) {
+ dbg("Response is Success");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+ }
+
+OUT:
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ if (setsoundpath == TRUE) {
+ setsoundpath = FALSE;
+ } else {
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
+ }
+ } else {
+ dbg("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ char *resp_str = NULL;
+ struct tresp_call_sound_set_volume_level resp;
+ int error;
+
+ ur = tcore_pending_ref_user_request(p);
+ dbg("Entry");
+ // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+ if (!response) {
+ err("Input data is NULL");
+ return;
+ }
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+
+ line = (const char *) (((GSList *) response->lines)->data);
+ tokens = tcore_at_tok_new(line);
+
+ resp_str = g_slist_nth_data(tokens, 0);
+ if (!g_slist_nth_data(tokens, 0)) {
+ err("group_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err("function_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ resp_str = g_slist_nth_data(tokens, 2);
+ if (resp_str) {
+ error = atoi(resp_str);
+
+ if (0 == error) {
+ dbg("Response is Success ");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+ }
+
+OUT:
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ if (ur) {
+ if (resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.
+ // Send reposne to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
+ soundvolume = TRUE;
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+
+static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ char *resp_str = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_sound_set_volume_level resp;
+ int error;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+
+ // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+ if (!response) {
+ err("Input data is NULL");
+ return;
+ }
+
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ line = (const char *) (((GSList *) response->lines)->data);
+ tokens = tcore_at_tok_new(line);
+ resp_str = g_slist_nth_data(tokens, 0);
+
+ if (!g_slist_nth_data(tokens, 0)) {
+ err("group_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err("function_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ resp_str = g_slist_nth_data(tokens, 2);
+
+ if (resp_str) {
+ error = atoi(resp_str);
+
+ if (0 == error) {
+ dbg("Response is Success");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+ }
+
+OUT:
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+
+ if (soundvolume == TRUE) {
+ soundvolume = FALSE;
+ } else {
+ // Send reposne to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+
+static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ char *resp_str = NULL;
+ struct tresp_call_mute resp;
+ const TcoreATResponse *response = data;
+ int error;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+
+ if (!response) {
+ err("Input data is NULL");
+ return;
+ }
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+
+ line = (const char *) (((GSList *) response->lines)->data);
+ tokens = tcore_at_tok_new(line);
+ resp_str = g_slist_nth_data(tokens, 0);
+
+ if (!g_slist_nth_data(tokens, 0)) {
+ err("group_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err(" function_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ resp_str = g_slist_nth_data(tokens, 2);
+
+ if (resp_str) {
+ error = atoi(resp_str);
+ if (0 == error) {
+ dbg("Response is Success");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+ }
+OUT:
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *response = NULL;
+ struct tresp_call_unmute resp;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ UserRequest *ur = NULL;
+ char *resp_str = NULL;
+ int error;
+
+ dbg("Entry");
+
+ response = (TcoreATResponse *) data;
+ ur = tcore_pending_ref_user_request(p);
+
+ if (!response) {
+ err("Input data is NULL");
+ return;
+ }
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+
+ line = (const char *) (((GSList *) response->lines)->data);
+ tokens = tcore_at_tok_new(line);
+ resp_str = g_slist_nth_data(tokens, 0);
+
+ if (!g_slist_nth_data(tokens, 0)) {
+ err("group_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err(" function_id is missing");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ goto OUT;
+ }
+
+ resp_str = g_slist_nth_data(tokens, 2);
+
+ if (resp_str) {
+ error = atoi(resp_str);
+ if (0 == error) {
+ dbg("Response is Success");
+ resp.err = TCORE_RETURN_SUCCESS;
+ } else {
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+ }
+OUT:
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+// RESPONSE
+static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ TcorePlugin *plugin = NULL;
+ CoreObject *core_obj = NULL;
+ CallObject *co = NULL;
+ struct clcc_call_t *call_list = NULL;
+ gboolean *event_flag = (gboolean *) user_data;
+ const TcoreATResponse *response = data;
+ GSList *resp_data = NULL;
+ char *line = NULL;
+
+ int cllc_info = 0, countCalls = 0, countValidCalls = 0;
+ int error = 0;
+ dbg("Entry");
+
+ plugin = tcore_pending_ref_plugin(p);
+ core_obj = tcore_pending_ref_core_object(p);
+
+ if (response->success > 0) {
+ dbg("RESPONCE OK");
+ if (response->lines) {
+ resp_data = (GSList *) response->lines;
+ countCalls = g_slist_length(resp_data);
+ dbg("Total records : %d", countCalls);
+ }
+
+ if (0 == countCalls) {
+ err("Call count is zero");
+ return;
+ }
+
+ call_list = g_new0(struct clcc_call_t, countCalls);
+
+ for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
+ line = (char *) (resp_data->data);
+
+ error = _callFromCLCCLine(line, call_list + countValidCalls);
+ if (0 != error) {
+ continue;
+ }
+
+ co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
+ if (!co) {
+ co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
+ if (!co) {
+ err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
+ continue;
+ }
+ }
+
+ // Call set parameters
+ tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
+ tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
+ tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
+ tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
+ tcore_call_object_set_active_line(co, 0);
+
+ if (*event_flag) {
+ dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
+ _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
+ } else {
+ // Set Status
+ tcore_call_object_set_status(co, call_list[cllc_info].info.status);
+
+ dbg("Call id : (%d)", call_list[cllc_info].info.id);
+ dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
+ dbg("Call type : (%d)", call_list[cllc_info].info.type);
+ dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
+ dbg("Call number : (%s)", call_list[cllc_info].number);
+ dbg("Call status : (%d)", call_list[cllc_info].info.status);
+ }
+ }
+
+ // Free Call list
+ g_free(call_list);
+ }
+
+ // Free User data
+ g_free(event_flag);
+
+ dbg("Exit");
+ return;
+}
+
+static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ TcorePlugin *plugin = NULL;
+ CoreObject *core_obj = NULL;
+ CallObject *co = (CallObject *) user_data;
+ const TcoreATResponse *response = data;
+ const char *line = NULL;
+ struct tnoti_call_status_idle call_status;
+ GSList *tokens = NULL;
+ char *resp_str;
+ int error;
+
+ dbg("Entry");
+ plugin = tcore_pending_ref_plugin(p);
+ core_obj = tcore_pending_ref_core_object(p);
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ line = (const char *) (((GSList *) response->lines)->data);
+ tokens = tcore_at_tok_new(line);
+ resp_str = g_slist_nth_data(tokens, 0);
+ if (!resp_str) {
+ err("call end cause - report value missing");
+ } else {
+ resp_str = g_slist_nth_data(tokens, 1);
+ if (!resp_str) {
+ err("call end cause value missing");
+ }
+ error = atoi(resp_str);
+ dbg("call end cause - %d", error);
+ call_status.cause = _compare_call_end_cause(error);
+ dbg("TAPI call end cause - %d", call_status.cause);
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ } else {
+ err("RESPONSE NOT OK");
+ line = (char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ } else {
+ err(" err cause value: %d", atoi(g_slist_nth_data(tokens, 0)));
+ }
+ call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ call_status.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", call_status.type);
+
+ call_status.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", call_status.id);
+
+ // Set Status
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
+
+ // Send Notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ core_obj,
+ TNOTI_CALL_STATUS_IDLE,
+ sizeof(struct tnoti_call_status_idle),
+ (void *) &call_status);
+
+ // Free Call object
+ tcore_call_object_free(core_obj, co);
+}
+
+static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
+{
+ // +CLCC: 1,0,2,0,0,"18005551212",145
+ // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
+ int state;
+ int mode;
+ int isMT;
+ char *num = NULL;
+ unsigned int num_type;
+ GSList *tokens = NULL;
+ char *resp = NULL;
+ dbg("Entry");
+
+ tokens = tcore_at_tok_new(line);
+ // parse <id>
+ resp = g_slist_nth_data(tokens, 0);
+ if (!resp) {
+ err("InValid ID");
+ goto ERROR;
+ }
+ p_call->info.id = atoi(resp);
+ dbg("id : [%d]\n", p_call->info.id);
+
+ // parse <dir>
+ resp = g_slist_nth_data(tokens, 1);
+ if (!resp) {
+ err("InValid Dir");
+ goto ERROR;
+ }
+ isMT = atoi(resp);
+ if (0 == isMT) {
+ p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
+ } else {
+ p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
+ }
+ dbg("Direction : [ %d ]\n", p_call->info.direction);
+
+ // parse <stat>
+ resp = g_slist_nth_data(tokens, 2);
+ if (!resp) {
+ err("InValid Stat");
+ goto ERROR;
+ }
+ state = atoi(resp);
+ dbg("Call state : %d", state);
+ switch (state) {
+ case 0: // active
+ p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
+ break;
+
+ case 1:
+ p_call->info.status = TCORE_CALL_STATUS_HELD;
+ break;
+
+ case 2:
+ p_call->info.status = TCORE_CALL_STATUS_DIALING;
+ break;
+
+ case 3:
+ p_call->info.status = TCORE_CALL_STATUS_ALERT;
+ break;
+
+ case 4:
+ p_call->info.status = TCORE_CALL_STATUS_INCOMING;
+ break;
+
+ case 5:
+ p_call->info.status = TCORE_CALL_STATUS_WAITING;
+ break;
+ }
+ dbg("Status : [%d]\n", p_call->info.status);
+
+ // parse <mode>
+ resp = g_slist_nth_data(tokens, 3);
+ if (!resp) {
+ err("InValid Mode");
+ goto ERROR;
+ }
+ mode = atoi(resp);
+ switch (mode) {
+ case 0:
+ p_call->info.type = TCORE_CALL_TYPE_VOICE;
+ break;
+
+ case 1:
+ p_call->info.type = TCORE_CALL_TYPE_VIDEO;
+ break;
+
+ default: // only Voice/VT call is supported in CS. treat other unknown calls as error
+ dbg("invalid type : [%d]\n", mode);
+ goto ERROR;
+ }
+ dbg("Call type : [%d]\n", p_call->info.type);
+
+ // parse <mpty>
+ resp = g_slist_nth_data(tokens, 4);
+ if (!resp) {
+ err("InValid Mpty");
+ goto ERROR;
+ }
+
+ p_call->info.mpty = atoi(resp);
+ dbg("Mpty : [ %d ]\n", p_call->info.mpty);
+
+ // parse <num>
+ resp = g_slist_nth_data(tokens, 5);
+ dbg("Incoming number - %s and its len - %d", resp, strlen(resp));
+
+ // tolerate null here
+ if (!resp) {
+ err("Number is NULL");
+ goto ERROR;
+ }
+ // Strike off double quotes
num = util_removeQuotes(resp);
- dbg("num after removing quotes - %s", num);\r
-\r
- p_call->info.num_len = strlen(resp);\r
- dbg("num_len : [0x%x]\n", p_call->info.num_len);\r
-\r
- // parse <num type>\r
- resp = g_slist_nth_data(tokens, 6);\r
- if(!resp) {\r
- dbg("InValid Num type");\r
- goto ERROR;\r
- }\r
- p_call->info.num_type = atoi(resp);\r
- dbg("BCD num type: [0x%x]\n", p_call->info.num_type);\r
-\r
- //check number is international or national.\r
- num_type = ((p_call->info.num_type) >> 4) & 0x07;\r
- dbg("called party's type of number : [0x%x]\n", num_type);\r
-\r
- if(num_type == 1 && num[0] != '+') {\r
- //international number\r
- p_call->number[0] = '+';\r
- memcpy(&(p_call->number[1]),num,strlen(num));\r
- }\r
- else{\r
- memcpy(&(p_call->number),num,strlen(num));\r
- }\r
- dbg("incoming number - %s", p_call->number);\r
-\r
- g_free(num);\r
- num = NULL;\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
-\r
- dbg("Exit");\r
- return 0;\r
-\r
-ERROR:\r
- err("Invalid CLCC line");\r
-\r
- if(num){\r
- g_free(num);\r
- num = NULL;\r
- }\r
-\r
- // Free tokens\r
- tcore_at_tok_free(tokens);\r
- err("Exit");\r
- return -1;\r
-}\r
-\r
-// NOTIFICATION\r
-static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)\r
-{\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- char *pId;\r
- int call_id;\r
- gboolean *eflag;\r
- GSList* pList = NULL;\r
- CallObject *co = NULL, *dupco = NULL;\r
-\r
- dbg("function entrance");\r
- // check call with waiting status already exist\r
- pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);\r
-\r
- if(pList != NULL) {\r
- dbg("[error]Waiting call already exist. skip");\r
- return;\r
- }\r
- // check call with incoming status already exist\r
- pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);\r
-\r
- if(pList != NULL){\r
- dbg("[error]incoming call already exist. skip");\r
- return;\r
- }\r
- line = (char*)data;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- pId = g_slist_nth_data(tokens, 0);\r
- if(!pId){\r
- dbg("[error]:Call id is missing from +XCALLSTAT indication");\r
- return;\r
- }\r
-\r
- call_id = atoi(pId);\r
- dupco = tcore_call_object_find_by_id(o, call_id);\r
- if(dupco!= NULL){\r
- dbg("co with same id already exist. skip");\r
- return;\r
- }\r
- co = tcore_call_object_new(o, call_id);\r
- if (!co){\r
- dbg("[ error ] co is NULL");\r
- return ;\r
- }\r
-\r
- tcore_at_tok_free(tokens);\r
-\r
- eflag = g_new0(gboolean, 1);\r
- *eflag = TRUE;\r
- dbg("calling _call_list_get");\r
- _call_list_get(o, eflag);\r
-\r
-}\r
-\r
-static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)\r
-{\r
- GSList *tokens = NULL;\r
- const char *line = NULL;\r
- char *pId;\r
- int call_id;\r
- gboolean *eflag;\r
- GSList* pList = NULL;\r
- CallObject *co = NULL, *dupco = NULL;\r
-\r
- dbg("function entrance");\r
- // check call with incoming status already exist\r
- pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);\r
-\r
- if(pList != NULL){\r
- dbg("incoming call already exist. skip");\r
- return;\r
- }\r
-\r
- line = (char*)data;\r
- tokens = tcore_at_tok_new(line);\r
-\r
- pId = g_slist_nth_data(tokens, 0);\r
- if(!pId){\r
- dbg("Error:Call id is missing from %XCALLSTAT indication");\r
- return;\r
- }\r
-\r
- call_id = atoi(pId);\r
-\r
- dupco = tcore_call_object_find_by_id(o, call_id);\r
- if(dupco!= NULL){\r
- dbg("co with same id already exist. skip");\r
- return;\r
- }\r
-\r
- co = tcore_call_object_new(o, call_id);\r
- if (!co){\r
- dbg("[ error ] co is NULL");\r
- return ;\r
- }\r
-\r
- dbg("freeing at token")\r
- tcore_at_tok_free(tokens);\r
-\r
- eflag = g_new0(gboolean, 1);\r
- *eflag = TRUE;\r
-\r
- dbg("calling _call_list_get");\r
- _call_list_get(o, eflag);\r
-\r
-}\r
-\r
-static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)\r
-{\r
- char* cmd = NULL;\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = -1;\r
- int status = 0;\r
- int type = 0;\r
- char *stat = NULL;\r
- char *pCallId = NULL;\r
- GSList *tokens = NULL;\r
- gboolean *eflag = NULL;
- enum tcore_call_status co_status;\r
-\r
- dbg("function entrance");\r
- plugin = tcore_object_ref_plugin(o);\r
- cmd = (char*)data;\r
- tokens = tcore_at_tok_new(cmd);\r
-\r
- // parse <Call Id>\r
- pCallId = g_slist_nth_data(tokens, 0);\r
- if(!pCallId) {\r
- dbg("pCallId is missing from %XCALLSTAT indiaction");\r
-\r
- }\r
- else {\r
- id = atoi(pCallId);\r
- dbg("call id = %d", id);\r
- //parse <Stat>\r
- if ((stat = g_slist_nth_data(tokens, 1))) {\r
- status = atoi(stat);\r
- }\r
- dbg("call status = %d", status);\r
- }\r
-\r
- tcore_at_tok_free(tokens);\r
- co_status = _call_status(status);\r
-\r
- dbg("co_status = %d", co_status);\r
- switch (co_status) {\r
-\r
- case CALL_STATUS_ACTIVE:\r
- {\r
- dbg("call(%d) status : [ ACTIVE ]", id);\r
- co = tcore_call_object_find_by_id(o,id);\r
- if (!co) {\r
- dbg("co is NULL");\r
- return ;\r
- }\r
- _call_status_active(plugin, co);\r
-\r
- }\r
- break;\r
-\r
- case CALL_STATUS_HELD:\r
- dbg("call(%d) status : [ held ]", id);\r
- break;\r
-\r
- case CALL_STATUS_DIALING:\r
- {\r
- dbg("call(%d) status : [ dialing ]", id);\r
- co = tcore_call_object_find_by_id(o,id);\r
- if (!co) {\r
- co = tcore_call_object_new(o, id);\r
- if (!co) {\r
- dbg("error : tcore_call_object_new [ id : %d ]", id);\r
- return ;\r
- }\r
- }\r
-\r
- tcore_call_object_set_type(co, call_type(type));\r
- tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);\r
- _call_status_dialing(plugin, co);\r
- }\r
- break;\r
- case CALL_STATUS_ALERT:\r
- {\r
- dbg("call(%d) status : [ alert ]", id);\r
- co = tcore_call_object_find_by_id(o, id);\r
- if (!co){\r
- dbg("co is NULL");\r
- return ;\r
- }\r
- //Store dialed number information into Call object.
- eflag = g_new0(gboolean, 1);
- *eflag = TRUE;
- dbg("calling _call_list_get");
- _call_list_get(o, eflag);
-\r
- }\r
- break;\r
- case CALL_STATUS_INCOMING:\r
- case CALL_STATUS_WAITING:\r
- dbg("call(%d) status : [ incoming ]", id);\r
- break;\r
- case CALL_STATUS_IDLE:\r
- {\r
-\r
- dbg("call(%d) status : [ release ]", id);\r
-\r
- co = tcore_call_object_find_by_id(o, id);\r
- if (!co) {\r
- dbg("co is NULL");\r
- return ;\r
- }\r
-\r
- plugin = tcore_object_ref_plugin(o);\r
- if (!plugin) {\r
- dbg("plugin is NULL");\r
- return ;\r
- }\r
- _call_status_idle(plugin, co);\r
- }\r
- break;\r
-\r
- default:\r
- dbg("invalid call status", id);\r
- break;\r
- }\r
-}\r
-\r
-static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)\r
-{\r
- struct treq_call_dial* data = 0;\r
- char* raw_str= NULL;\r
- char*cmd_str = NULL;\r
- const char *cclir;\r
- enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;\r
- TcorePending *pending = NULL;\r
- TcoreATRequest *req;\r
- gboolean ret = FALSE;\r
-\r
- dbg("function entrance");\r
- data = (struct treq_call_dial*)tcore_user_request_ref_data(ur, 0);\r
- clir = _get_clir_status(data->number);\r
-\r
- //Compose ATD Cmd string\r
- switch (clir) {\r
- case TCORE_CALL_CLI_MODE_PRESENT:\r
- dbg("CALL_CLI_MODE_PRESENT");\r
- cclir = "I";\r
- break; //invocation\r
- case TCORE_CALL_CLI_MODE_RESTRICT:\r
- dbg("CALL_CLI_MODE_RESTRICT");\r
- cclir = "i";\r
- break; //suppression\r
- case TCORE_CALL_CLI_MODE_DEFAULT:\r
- default:\r
- cclir = "";\r
- dbg("CALL_CLI_MODE_DEFAULT");\r
- break; //subscription default\r
- }\r
-\r
- dbg("data->number = %s",data->number);\r
-\r
- raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);\r
- cmd_str = g_strdup_printf("%s",raw_str);\r
-\r
- dbg("request command : %s", cmd_str);\r
-\r
- pending = tcore_pending_new(o, 0);\r
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);\r
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));\r
-\r
- tcore_pending_set_request_data(pending, 0, req);\r
- ret = _call_request_message (pending, o, ur, on_confirmation_call_outgoing, NULL);\r
-\r
- g_free(raw_str);\r
- g_free(cmd_str);\r
-\r
- if (!ret) {\r
- dbg("AT request(%s) sent failed", req->cmd);\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- dbg("AT request(%s) sent success",req->cmd);\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_answer(CoreObject *o, UserRequest *ur)\r
-{\r
- char* cmd_str = NULL;\r
- CallObject* co = NULL;\r
- struct treq_call_answer* data = 0;\r
- TcorePending *pending = NULL;\r
- TcoreATRequest *req;\r
- gboolean ret = FALSE;\r
-\r
- dbg("function entrance");\r
-\r
- data = (struct treq_call_answer*)tcore_user_request_ref_data(ur, 0);\r
- co = tcore_call_object_find_by_id(o, data->id);\r
- if (data->type == CALL_ANSWER_TYPE_ACCEPT) {\r
-\r
- dbg(" request type CALL_ANSWER_TYPE_ACCEPT");\r
-\r
- cmd_str = g_strdup_printf("%s","ATA");\r
- pending = tcore_pending_new(o, 0);\r
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);\r
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));\r
-\r
- tcore_pending_set_request_data(pending, 0, req);\r
- ret = _call_request_message (pending, o, ur, on_confirmation_call_accept, co);\r
- g_free(cmd_str);\r
-\r
- if (!ret) {\r
- dbg("AT request(%s) sent failed", req->cmd);\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- }\r
- else {\r
-\r
- switch (data->type) {\r
- case CALL_ANSWER_TYPE_REJECT:\r
- {\r
- dbg("call answer reject");\r
- tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);\r
- } break;\r
-\r
- case CALL_ANSWER_TYPE_REPLACE:\r
- {\r
- dbg("call answer replace");\r
- tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);\r
- } break;\r
-\r
- case CALL_ANSWER_TYPE_HOLD_ACCEPT:\r
- {\r
- dbg("call answer hold and accept");\r
- tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);\r
- } break;\r
-\r
- default :\r
- dbg("[ error ] wrong answer type [ %d ]", data->type);\r
- return TCORE_RETURN_FAILURE;\r
- }\r
- }\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_release(CoreObject *o, UserRequest *ur)\r
-{\r
- CallObject* co = NULL;\r
- struct treq_call_end* data = 0;\r
- UserRequest* ur_dup = NULL;\r
- char* chld0_cmd = NULL;\r
- char* chld1_cmd = NULL;\r
- TcorePending *pending = NULL, *pending1 = NULL;\r
- TcoreATRequest *req, *req1;\r
- gboolean ret = FALSE;\r
-\r
- dbg("function entrance");\r
- data = (struct treq_call_end*)tcore_user_request_ref_data(ur, 0);\r
- co = tcore_call_object_find_by_id(o, data->id);\r
-\r
- dbg("type of release call = %d" , data->type);\r
-\r
- if (data->type == CALL_END_TYPE_ALL) {\r
-\r
- //releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence\r
- chld0_cmd = g_strdup("AT+CHLD=0");\r
- chld1_cmd = g_strdup("AT+CHLD=1");\r
-\r
- pending = tcore_pending_new(o, 0);\r
- req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);\r
-\r
- dbg("input command is %s",chld0_cmd);\r
- dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));\r
-\r
- tcore_pending_set_request_data(pending, 0, req);\r
- ur_dup = tcore_user_request_new(NULL, NULL);\r
- ret = _call_request_message(pending ,o, ur_dup, on_confirmation_call_endall, NULL);\r
- g_free(chld0_cmd);\r
-\r
- if (!ret) {\r
- dbg("AT request %s has failed ",req->cmd);\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- pending1 = tcore_pending_new(o, 0);\r
- req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);\r
-\r
- dbg("input command is %s",chld1_cmd);\r
- dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));\r
-\r
- tcore_pending_set_request_data(pending1, 0, req1);\r
- ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);\r
- g_free(chld1_cmd);\r
-\r
- if (!ret) {\r
- dbg("AT request %s has failed ",req->cmd);\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- }\r
- else {\r
-\r
- switch (data->type) {\r
-\r
- case CALL_END_TYPE_DEFAULT:\r
- {\r
- int id = 0;\r
- id = tcore_call_object_get_id(co);\r
-\r
- dbg("call end call id [%d]", id);\r
- tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);\r
- } break;\r
-\r
- case CALL_END_TYPE_ACTIVE_ALL:\r
- {\r
-\r
- dbg("call end all active");\r
- tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);\r
- } break;\r
-\r
- case CALL_END_TYPE_HOLD_ALL:\r
- {\r
-\r
- dbg("call end all held");\r
- tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);\r
- } break;\r
-\r
- default :\r
- dbg("[ error ] wrong end type [ %d ]", data->type);\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- }\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_hold(CoreObject *o, UserRequest *ur)\r
-{\r
- struct treq_call_hold *hold = 0;\r
- CallObject *co = NULL;\r
-\r
- dbg("function entrance");\r
-\r
- hold = (struct treq_call_hold*)tcore_user_request_ref_data(ur, 0);\r
- dbg("call id : [ %d ]", hold->id);\r
-\r
- co = tcore_call_object_find_by_id(o, hold->id);\r
- tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_active(CoreObject *o, UserRequest *ur)\r
-{\r
- struct treq_call_active *active = 0;\r
- CallObject *co = NULL;\r
-\r
- active = (struct treq_call_active*)tcore_user_request_ref_data(ur, 0);\r
- dbg("call id : [ %d ]", active->id);\r
-\r
- co = tcore_call_object_find_by_id(o, active->id);\r
- tcore_call_control_active(o, ur, on_confirmation_call_active, co);\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_swap(CoreObject *o, UserRequest *ur)\r
-{\r
- struct treq_call_swap *swap = NULL;\r
- CallObject *co = NULL;\r
-\r
- swap = (struct treq_call_swap*)tcore_user_request_ref_data(ur, 0);\r
- dbg("call id : [ %d ]", swap->id);\r
-\r
- co = tcore_call_object_find_by_id(o, swap->id);\r
- tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_join(CoreObject *o, UserRequest *ur)\r
-{\r
- struct treq_call_join *join = 0;\r
- CallObject *co = NULL;\r
-\r
- join = (struct treq_call_join*)tcore_user_request_ref_data(ur, 0);\r
- dbg("call id : [ %d ]", join->id);\r
-\r
- co = tcore_call_object_find_by_id(o, join->id);\r
- tcore_call_control_join(o, ur, on_confirmation_call_join, co);\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_split(CoreObject *o, UserRequest *ur)\r
-{\r
- struct treq_call_split *split = 0;\r
- CallObject *co = NULL;\r
-\r
- split = (struct treq_call_split*)tcore_user_request_ref_data(ur, 0);\r
- co = tcore_call_object_find_by_id (o, split->id);\r
- dbg("call id : [ %d ]", split->id);\r
-\r
- tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)\r
-{\r
- struct treq_call_deflect *deflect = 0;\r
- CallObject *co = NULL;\r
-\r
- deflect = (struct treq_call_deflect*)tcore_user_request_ref_data(ur, 0);\r
- co = tcore_call_object_find_by_number(o, deflect->number);\r
- dbg("deflect number: [ %s ]", deflect->number);\r
-\r
- tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)\r
-{\r
- struct treq_call_transfer *transfer = 0;\r
- CallObject *co = NULL;\r
-\r
- transfer = (struct treq_call_transfer*)tcore_user_request_ref_data(ur, 0);\r
- dbg("call id : [ %d ]", transfer->id);\r
-\r
- co = tcore_call_object_find_by_id(o, transfer->id);\r
- tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)\r
-{\r
- char*cmd_str = NULL;\r
- TcorePending *pending = NULL;\r
- TcoreATRequest *req;\r
- UserRequest *dup;\r
- gboolean ret = FALSE;\r
- struct treq_call_dtmf *dtmf = 0;\r
- char *dtmfstr = NULL, *tmp_dtmf = NULL;\r
- unsigned int dtmf_count;\r
-\r
- dbg("Function enter");\r
-\r
- dup = tcore_user_request_new(NULL, NULL);\r
- (void)_set_dtmf_tone_duration(o, dup);\r
-\r
- dtmf = (struct treq_call_dtmf*)tcore_user_request_ref_data(ur, 0);\r
- dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2)+ 1); // DTMF digits + comma for each dtmf digit.\r
-\r
- if(dtmfstr == NULL) {\r
- dbg("Memory allocation failed");\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- tmp_dtmf = dtmfstr;\r
-\r
- for(dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {\r
-\r
- *tmp_dtmf = dtmf->digits[dtmf_count];\r
- tmp_dtmf ++;\r
-\r
- *tmp_dtmf = COMMA;\r
- tmp_dtmf++;\r
- }\r
-\r
- //last digit is having COMMA , overwrite it with '\0' .\r
- *(--tmp_dtmf) = '\0';\r
- dbg("Input DTMF string(%s)",dtmfstr);\r
-\r
- //AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>\r
- cmd_str = g_strdup_printf("AT+VTS=%s",dtmfstr);\r
- dbg("request command : %s", cmd_str);\r
-\r
- pending = tcore_pending_new(o, 0);\r
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);\r
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));\r
-\r
- tcore_pending_set_request_data(pending, 0, req);\r
- ret = _call_request_message (pending, o, ur, on_confirmation_call_dtmf, NULL);\r
- g_free(dtmfstr);\r
- g_free(cmd_str);\r
-\r
- if (!ret) {\r
-\r
- dbg("AT request sent failed")\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)\r
-{\r
- UserRequest *ur_dup = NULL;\r
- TcorePending *pending = NULL , *pending1 = NULL;\r
- TcoreATRequest *req , *req1;\r
- char *cmd_str = NULL , *cmd_str1 = NULL;\r
- gboolean ret = FALSE;\r
-\r
- dbg("function entrance");\r
-\r
- //hard coded value for speaker.\r
- cmd_str = g_strdup_printf("%s","AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,1"); //source type.\r
- cmd_str1 = g_strdup_printf("%s","AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,1"); //destination type\r
-\r
- pending = tcore_pending_new(o, 0);\r
- req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);\r
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));\r
-\r
- tcore_pending_set_request_data(pending, 0, req);\r
- ur_dup = tcore_user_request_ref(ur);\r
-\r
- ret = _call_request_message (pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);\r
-\r
- g_free(cmd_str);\r
-\r
- if (!ret) {\r
-\r
- dbg("At request(%s) sent failed",req->cmd);\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- pending1 = tcore_pending_new(o, 0);\r
- req1 = tcore_at_request_new(cmd_str1,"+XDRV", TCORE_AT_SINGLELINE);\r
- dbg("input command is %s",cmd_str1);\r
- dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));\r
-\r
- tcore_pending_set_request_data(pending1, 0, req1);\r
- ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);\r
-\r
- g_free(cmd_str1);\r
-\r
- if (!ret) {\r
- dbg("AT request %s has failed ",req1->cmd);\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-\r
-}\r
-\r
-static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)\r
-{\r
- UserRequest *src_ur = NULL;\r
- UserRequest *dest_ur = NULL;\r
- TcorePending *src_pending = NULL;\r
- TcorePending *dest_pending = NULL;\r
- TcoreATRequest *src_req = NULL;\r
- TcoreATRequest *dest_req = NULL;\r
- char *cmd_str = NULL, *volume_level = NULL;\r
- gboolean ret = FALSE;\r
-\r
- struct treq_call_sound_set_volume_level* data = NULL;\r
- data = (struct treq_call_sound_set_volume_level*)tcore_user_request_ref_data( ur, 0 );\r
- dbg("Entry");\r
- // Hard-coded values for MIC & Speakers\r
- // Source volume\r
- dbg("Set Source volume");\r
-\r
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source type\r
- dbg("Request command string: %s", cmd_str);\r
-\r
- // Create new Pending request\r
- src_pending = tcore_pending_new(o, 0);\r
-\r
- // Create new AT-Command request\r
- src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);\r
- dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));\r
-\r
- // Free Command string\r
- g_free(cmd_str);\r
-\r
- tcore_pending_set_request_data(src_pending, 0, src_req);\r
- src_ur = tcore_user_request_ref(ur);\r
-\r
- // Send request\r
- ret = _call_request_message (src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);\r
- if (!ret) {\r
- err("Failed to send AT-Command request");\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type\r
- dbg("Request command string: %s", cmd_str);\r
-\r
- // Create new Pending request\r
- src_pending = tcore_pending_new(o, 0);\r
-\r
- // Create new AT-Command request\r
- src_req = tcore_at_request_new(cmd_str,"+XDRV", TCORE_AT_SINGLELINE);\r
- dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));\r
-\r
- // Free Command string\r
- g_free(cmd_str);\r
-\r
- tcore_pending_set_request_data(src_pending, 0, src_req);\r
-\r
- src_ur= tcore_user_request_ref(ur);\r
-\r
- // Send request\r
- ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);\r
- if (!ret) {\r
- err("Failed to send AT-Command request");\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- // Destination volume\r
- dbg("Set Source volume");\r
-\r
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type\r
- dbg("Request command string: %s", cmd_str);\r
-\r
- // Create new Pending request\r
- dest_pending = tcore_pending_new(o, 0);\r
-\r
- // Create new AT-Command request\r
- dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);\r
- dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));\r
-\r
- // Free Command string\r
- g_free(cmd_str);\r
-\r
- tcore_pending_set_request_data(dest_pending, 0, dest_req);\r
- dest_ur = tcore_user_request_ref(ur);\r
-\r
- // Send request\r
- ret = _call_request_message (dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);\r
- if (!ret) {\r
- err("Failed to send AT-Command request");\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- dbg("Input volume level - %d",data->volume);\r
- switch(data->volume) {\r
-\r
- case CALL_SOUND_MUTE:\r
- volume_level = "0";\r
- break;\r
- case CALL_SOUND_VOLUME_LEVEL_1:\r
- volume_level = "40";\r
- break;\r
- case CALL_SOUND_VOLUME_LEVEL_2:\r
- volume_level = "46";\r
- break;\r
- case CALL_SOUND_VOLUME_LEVEL_3:\r
- volume_level = "52";\r
- break;\r
- case CALL_SOUND_VOLUME_LEVEL_4:\r
- volume_level = "58";\r
- break;\r
- case CALL_SOUND_VOLUME_LEVEL_5:\r
- volume_level = "64";\r
- break;\r
- case CALL_SOUND_VOLUME_LEVEL_6:\r
- volume_level = "70";\r
- break;\r
- case CALL_SOUND_VOLUME_LEVEL_7:\r
- volume_level = "76";\r
- break;\r
- case CALL_SOUND_VOLUME_LEVEL_8:\r
- volume_level = "82";\r
- break;\r
- case CALL_SOUND_VOLUME_LEVEL_9:\r
- default:\r
- volume_level = "88";\r
- break;\r
- }\r
- cmd_str = g_strdup_printf("%s%s","AT+XDRV=40,8,2,",volume_level); //Destination type\r
- dbg("Request command string: %s", cmd_str);\r
-\r
- // Create new Pending request\r
- dest_pending = tcore_pending_new(o, 0);\r
-\r
- // Create new AT-Command request\r
- dest_req = tcore_at_request_new(cmd_str,"+XDRV", TCORE_AT_SINGLELINE);\r
- dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));\r
-\r
- // Free Command string\r
- g_free(cmd_str);\r
-\r
- tcore_pending_set_request_data(dest_pending, 0, dest_req);\r
-\r
- // Send request\r
- ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);\r
- if (!ret) {\r
- err("Failed to send AT-Command request");\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-\r
-static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)\r
-{\r
- dbg("Entry");\r
-\r
- dbg("Exit");\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_mute(CoreObject *o, UserRequest *ur)\r
-{\r
- char *cmd_str = NULL;\r
- TcorePending *pending = NULL;\r
- TcoreATRequest *req = NULL;\r
- gboolean ret = FALSE;\r
-\r
- dbg("Entry");\r
- cmd_str = g_strdup_printf("%s","AT+XDRV=40,8,0,0,0");\r
-\r
- dbg("Request command string: %s", cmd_str);\r
-\r
- // Create new Pending request\r
- pending = tcore_pending_new(o, 0);\r
-\r
- // Create new AT-Command request\r
- req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);\r
- dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));\r
-\r
- // Free command string\r
- g_free(cmd_str);\r
-\r
- // Set request data (AT command) to Pending request\r
- tcore_pending_set_request_data(pending, 0, req);\r
-\r
- // Send request\r
- ret = _call_request_message (pending, o, ur, on_confirmation_call_mute, NULL);\r
- if (!ret) {\r
- err("Failed to send AT-Command request");\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- dbg("Exit");\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)\r
-{\r
- char *cmd_str = NULL;\r
- TcorePending *pending = NULL;\r
- TcoreATRequest *req = NULL;\r
- gboolean ret = FALSE;\r
- dbg("Entry");\r
-\r
- cmd_str = g_strdup_printf("%s","AT+XDRV=40,8,0,0,88");\r
- dbg("Request command string: %s", cmd_str);\r
-\r
- // Create new Pending request\r
- pending = tcore_pending_new(o, 0);\r
-\r
- // Create new AT-Command request\r
- req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);\r
- dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));\r
-\r
- // Free command string\r
- g_free(cmd_str);\r
-\r
- // Set request data (AT command) to Pending request\r
- tcore_pending_set_request_data(pending, 0, req);\r
-\r
- // Send request\r
- ret = _call_request_message (pending, o, ur, on_confirmation_call_unmute, NULL);\r
- if (!ret) {\r
- err("Failed to send AT-Command request");\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- dbg("Exit");\r
- return TCORE_RETURN_SUCCESS;\r
-\r
-}\r
-\r
-\r
-static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)\r
-{\r
- dbg("Entry");\r
-\r
- dbg("Exit");\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)\r
-{\r
- char *cmd_str = NULL;\r
- TcorePending *pending = NULL;\r
- TcoreATRequest *req = NULL;\r
- gboolean ret = FALSE;\r
- dbg("Entry");\r
-\r
- cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.\r
- dbg("Request command string: %s", cmd_str);\r
-\r
- // Create new Pending request\r
- pending = tcore_pending_new(o, 0);\r
-\r
- // Create new AT-Command request\r
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);\r
- dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));\r
-\r
- // Free command string */\r
- g_free(cmd_str);\r
-\r
- // Set request data (AT command) to Pending request\r
- tcore_pending_set_request_data(pending, 0, req);\r
-\r
- // Send request\r
- ret = _call_request_message (pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);\r
- if (!ret) {\r
- err("Failed to send AT-Command request");\r
- return TCORE_RETURN_FAILURE;\r
- }\r
-\r
- dbg("Exit");\r
- return TCORE_RETURN_SUCCESS;\r
-}\r
-\r
-//Call Operations\r
-static struct tcore_call_operations call_ops = {\r
- .dial = s_call_outgoing,\r
- .answer = s_call_answer,\r
- .end = s_call_release,\r
- .hold = s_call_hold,\r
- .active = s_call_active,\r
- .swap = s_call_swap,\r
- .join = s_call_join,\r
- .split = s_call_split,\r
- .deflect = s_call_deflect,\r
- .transfer = s_call_transfer,\r
- .send_dtmf = s_call_send_dtmf,\r
- .set_sound_path = s_call_set_sound_path,\r
- .set_sound_volume_level = s_call_set_sound_volume_level,\r
- .get_sound_volume_level = s_call_get_sound_volume_level,\r
- .mute = s_call_mute,\r
- .unmute = s_call_unmute,\r
- .get_mute_status = s_call_get_mute_status,\r
- .set_sound_recording = NULL,\r
- .set_sound_equalization = NULL,\r
- .set_sound_noise_reduction = NULL,\r
-};\r
-\r
-static void s_call_info_mo_waiting(CoreObject *o)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mo_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_WAITING,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mo_forwarded(CoreObject *o)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mo_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_FORWARDED,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mo_barred_incoming(CoreObject *o)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mo_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_BARRED_INCOMING,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mo_barred_outgoing(CoreObject *o)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mo_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_BARRED_OUTGOING,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mo_deflected(CoreObject *o)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mo_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_DEFLECTED,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mo_clir_suppression_reject(CoreObject *o)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mo_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mo_cfu(CoreObject *o)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mo_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_FORWARD_UNCONDITIONAL,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mo_cfc(CoreObject *o)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mo_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_FORWARD_CONDITIONAL,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mt_cli(CoreObject *o, enum tcore_call_cli_mode mode, char* number)\r
-{\r
- CallObject *co = NULL;\r
- dbg("Entry");\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mt_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Set CLI information\r
- tcore_call_object_set_cli_info(co, mode, number);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mt_cna(CoreObject *o, enum tcore_call_cna_mode mode, char* name, int dcs)\r
-{\r
- CallObject *co = NULL;\r
- dbg("Entry");\r
-\r
- // Call Core object\r
- co = tcore_call_object_current_on_mt_processing(o);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Set CNA information\r
- tcore_call_object_set_cna_info(co, mode, name, dcs);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mt_forwarded_call(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_FORWARDED_CALL,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mt_deflected_call(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_DEFLECTED_CALL,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_mt_transfered(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_TRANSFERED_CALL,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_held(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_HELD,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_active(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_ACTIVE,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_joined(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- //Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- //Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_JOINED,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_released_on_hold(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_RELEASED_ON_HOLD,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_transfer_alert(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- //Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- //Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_TRANSFER_ALERT,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_transfered(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_TRANSFERED,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-static void s_call_info_cf_check_message(CoreObject *o, char* number)\r
-{\r
- TcorePlugin *plugin = NULL;\r
- CallObject *co = NULL;\r
- int id = 0;\r
- dbg("Entry");\r
-\r
- // Parent plugin\r
- plugin = tcore_object_ref_plugin(o);\r
-\r
- // Call Core object\r
- co = tcore_call_object_find_by_number(o, number);\r
- if (!co) {\r
- err("Failed to find Call Core object!");\r
- return;\r
- }\r
-\r
- // Call ID\r
- id = tcore_call_object_get_id(co);\r
-\r
- // Send notification to TAPI\r
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),\r
- tcore_plugin_ref_core_object(plugin, "call"),\r
- TNOTI_CALL_INFO_CF_CHECK_MESSAGE,\r
- sizeof(unsigned int),\r
- (void*)&id);\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
-\r
-// Call Information Operations\r
-static struct tcore_call_information_operations call_information_ops = {\r
- .mo_call_col = 0,\r
- .mo_call_waiting = s_call_info_mo_waiting,\r
- .mo_call_cug = 0,\r
- .mo_call_forwarded = s_call_info_mo_forwarded,\r
- .mo_call_barred_incoming = s_call_info_mo_barred_incoming,\r
- .mo_call_barred_outgoing = s_call_info_mo_barred_outgoing,\r
- .mo_call_deflected = s_call_info_mo_deflected,\r
- .mo_call_clir_suppression_reject = s_call_info_mo_clir_suppression_reject,\r
- .mo_call_cfu = s_call_info_mo_cfu,\r
- .mo_call_cfc = s_call_info_mo_cfc,\r
- .mt_call_cli = s_call_info_mt_cli,\r
- .mt_call_cna = s_call_info_mt_cna,\r
- .mt_call_forwarded_call = s_call_info_mt_forwarded_call,\r
- .mt_call_cug_call = 0,\r
- .mt_call_deflected_call = s_call_info_mt_deflected_call,\r
- .mt_call_transfered = s_call_info_mt_transfered,\r
- .call_held = s_call_info_held,\r
- .call_active = s_call_info_active,\r
- .call_joined = s_call_info_joined,\r
- .call_released_on_hold = s_call_info_released_on_hold,\r
- .call_transfer_alert = s_call_info_transfer_alert,\r
- .call_transfered = s_call_info_transfered,\r
- .call_cf_check_message = s_call_info_cf_check_message,\r
-};\r
-\r
-gboolean s_call_init(TcorePlugin *p, TcoreHal *h)\r
-{\r
- CoreObject *o = NULL;\r
- struct property_call_info *data = NULL;\r
- dbg("Entry");\r
-\r
- //Creating Call COre object\r
- o = tcore_call_new(p, "call", &call_ops, h);\r
- if (!o) {\r
- err("Failed to create Call Core Object");\r
- return FALSE;\r
- }\r
-\r
- //Set Call Operations\r
- tcore_call_information_set_operations(o, &call_information_ops);\r
-\r
- // Add Callbacks\r
- tcore_object_add_callback(o, "+XCALLSTAT", on_notification_call_info, NULL);\r
- tcore_object_add_callback(o, "+CLIP", on_notification_call_clip_info, NULL);\r
-\r
- // User Data\r
- data = calloc(sizeof(struct property_call_info *), 1);\r
- tcore_plugin_link_property(p, "CALL", data);\r
-\r
- dbg("Exit");\r
- return TRUE;\r
-}\r
-\r
-void s_call_exit(TcorePlugin *p)\r
-{\r
- CoreObject *o = NULL;\r
- struct property_network_info *data = NULL;\r
- dbg("Entry");\r
-\r
- o = tcore_plugin_ref_core_object(p, "call");\r
-\r
- // Free Call Core Object */\r
- tcore_call_free(o);\r
-\r
- // Free 'CALL' property */\r
- data = tcore_plugin_ref_property(p, "CALL");\r
- if (data) {\r
- g_free(data);\r
- }\r
-\r
- dbg("Exit");\r
- return;\r
-}\r
+ dbg("num after removing quotes - %s", num);
+
+ p_call->info.num_len = strlen(resp);
+ dbg("num_len : [0x%x]\n", p_call->info.num_len);
+
+ // parse <num type>
+ resp = g_slist_nth_data(tokens, 6);
+ if (!resp) {
+ dbg("InValid Num type");
+ goto ERROR;
+ }
+ p_call->info.num_type = atoi(resp);
+ dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
+
+ // check number is international or national.
+ num_type = ((p_call->info.num_type) >> 4) & 0x07;
+ dbg("called party's type of number : [0x%x]\n", num_type);
+
+ if (num_type == 1 && num[0] != '+') {
+ // international number
+ p_call->number[0] = '+';
+ memcpy(&(p_call->number[1]), num, strlen(num));
+ } else {
+ memcpy(&(p_call->number), num, strlen(num));
+ }
+ dbg("incoming number - %s", p_call->number);
+
+ g_free(num);
+ num = NULL;
+ // Free tokens
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return 0;
+
+ERROR:
+ err("Invalid CLCC line");
+
+ if (num) {
+ g_free(num);
+ num = NULL;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ err("Exit");
+ return -1;
+}
+
+// NOTIFICATION
+static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ char *pId;
+ int call_id;
+ gboolean *eflag;
+ GSList *pList = NULL;
+ CallObject *co = NULL, *dupco = NULL;
+
+ dbg("function entrance");
+ // check call with waiting status already exist
+ pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
+
+ if (pList != NULL) {
+ dbg("[error]Waiting call already exist. skip");
+ return;
+ }
+ // check call with incoming status already exist
+ pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
+
+ if (pList != NULL) {
+ dbg("[error]incoming call already exist. skip");
+ return;
+ }
+ line = (char *) data;
+ tokens = tcore_at_tok_new(line);
+
+ pId = g_slist_nth_data(tokens, 0);
+ if (!pId) {
+ dbg("[error]:Call id is missing from +XCALLSTAT indication");
+ return;
+ }
+
+ call_id = atoi(pId);
+ dupco = tcore_call_object_find_by_id(o, call_id);
+ if (dupco != NULL) {
+ dbg("co with same id already exist. skip");
+ return;
+ }
+ co = tcore_call_object_new(o, call_id);
+ if (!co) {
+ dbg("[ error ] co is NULL");
+ return;
+ }
+
+ tcore_at_tok_free(tokens);
+
+ eflag = g_new0(gboolean, 1);
+ *eflag = TRUE;
+ dbg("calling _call_list_get");
+ _call_list_get(o, eflag);
+}
+
+static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ char *pId;
+ int call_id;
+ gboolean *eflag;
+ GSList *pList = NULL;
+ CallObject *co = NULL, *dupco = NULL;
+
+ dbg("function entrance");
+ // check call with incoming status already exist
+ pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
+
+ if (pList != NULL) {
+ dbg("incoming call already exist. skip");
+ return;
+ }
+
+ line = (char *) data;
+ tokens = tcore_at_tok_new(line);
+
+ pId = g_slist_nth_data(tokens, 0);
+ if (!pId) {
+ dbg("Error:Call id is missing from %XCALLSTAT indication");
+ return;
+ }
+
+ call_id = atoi(pId);
+
+ dupco = tcore_call_object_find_by_id(o, call_id);
+ if (dupco != NULL) {
+ dbg("co with same id already exist. skip");
+ return;
+ }
+
+ co = tcore_call_object_new(o, call_id);
+ if (!co) {
+ dbg("[ error ] co is NULL");
+ return;
+ }
+
+ dbg("freeing at token")
+ tcore_at_tok_free(tokens);
+
+ eflag = g_new0(gboolean, 1);
+ *eflag = TRUE;
+
+ dbg("calling _call_list_get");
+ _call_list_get(o, eflag);
+}
+
+static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
+{
+ char *cmd = NULL;
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = -1;
+ int status = 0;
+ int type = 0;
+ char *stat = NULL;
+ char *pCallId = NULL;
+ GSList *tokens = NULL;
+ gboolean *eflag = NULL;
+ enum tcore_call_status co_status;
+
+ dbg("function entrance");
+ plugin = tcore_object_ref_plugin(o);
+ cmd = (char *) data;
+ tokens = tcore_at_tok_new(cmd);
+
+ // parse <Call Id>
+ pCallId = g_slist_nth_data(tokens, 0);
+ if (!pCallId) {
+ dbg("pCallId is missing from %XCALLSTAT indiaction");
+ } else {
+ id = atoi(pCallId);
+ dbg("call id = %d", id);
+ // parse <Stat>
+ if ((stat = g_slist_nth_data(tokens, 1))) {
+ status = atoi(stat);
+ }
+ dbg("call status = %d", status);
+ }
+
+ tcore_at_tok_free(tokens);
+ co_status = _call_status(status);
+
+ dbg("co_status = %d", co_status);
+ switch (co_status) {
+ case CALL_STATUS_ACTIVE:
+ {
+ dbg("call(%d) status : [ ACTIVE ]", id);
+ co = tcore_call_object_find_by_id(o, id);
+ if (!co) {
+ dbg("co is NULL");
+ return;
+ }
+ _call_status_active(plugin, co);
+ }
+ break;
+
+ case CALL_STATUS_HELD:
+ dbg("call(%d) status : [ held ]", id);
+ break;
+
+ case CALL_STATUS_DIALING:
+ {
+ dbg("call(%d) status : [ dialing ]", id);
+ co = tcore_call_object_find_by_id(o, id);
+ if (!co) {
+ co = tcore_call_object_new(o, id);
+ if (!co) {
+ dbg("error : tcore_call_object_new [ id : %d ]", id);
+ return;
+ }
+ }
+
+ tcore_call_object_set_type(co, call_type(type));
+ tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
+ _call_status_dialing(plugin, co);
+ }
+ break;
+
+ case CALL_STATUS_ALERT:
+ {
+ dbg("call(%d) status : [ alert ]", id);
+ co = tcore_call_object_find_by_id(o, id);
+ if (!co) {
+ dbg("co is NULL");
+ return;
+ }
+ // Store dialed number information into Call object.
+ eflag = g_new0(gboolean, 1);
+ *eflag = TRUE;
+ dbg("calling _call_list_get");
+ _call_list_get(o, eflag);
+ }
+ break;
+
+ case CALL_STATUS_INCOMING:
+ case CALL_STATUS_WAITING:
+ dbg("call(%d) status : [ incoming ]", id);
+ break;
+
+ case CALL_STATUS_IDLE:
+ {
+ dbg("call(%d) status : [ release ]", id);
+
+ co = tcore_call_object_find_by_id(o, id);
+ if (!co) {
+ dbg("co is NULL");
+ return;
+ }
+
+ plugin = tcore_object_ref_plugin(o);
+ if (!plugin) {
+ dbg("plugin is NULL");
+ return;
+ }
+ _call_status_idle(plugin, co);
+ }
+ break;
+
+ default:
+ dbg("invalid call status", id);
+ break;
+ }
+}
+
+static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
+{
+ struct treq_call_dial *data = 0;
+ char *raw_str = NULL;
+ char *cmd_str = NULL;
+ const char *cclir;
+ enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req;
+ gboolean ret = FALSE;
+
+ dbg("function entrance");
+ data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
+ clir = _get_clir_status(data->number);
+
+ // Compose ATD Cmd string
+ switch (clir) {
+ case TCORE_CALL_CLI_MODE_PRESENT:
+ dbg("CALL_CLI_MODE_PRESENT");
+ cclir = "I";
+ break; // invocation
+
+ case TCORE_CALL_CLI_MODE_RESTRICT:
+ dbg("CALL_CLI_MODE_RESTRICT");
+ cclir = "i";
+ break; // suppression
+
+ case TCORE_CALL_CLI_MODE_DEFAULT:
+ default:
+ cclir = "";
+ dbg("CALL_CLI_MODE_DEFAULT");
+ break; // subscription default
+ }
+
+ dbg("data->number = %s", data->number);
+
+ raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
+ cmd_str = g_strdup_printf("%s", raw_str);
+
+ dbg("request command : %s", cmd_str);
+
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
+
+ g_free(raw_str);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request(%s) sent failed", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("AT request(%s) sent success", req->cmd);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
+{
+ char *cmd_str = NULL;
+ CallObject *co = NULL;
+ struct treq_call_answer *data = 0;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req;
+ gboolean ret = FALSE;
+
+ dbg("function entrance");
+
+ data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
+ co = tcore_call_object_find_by_id(o, data->id);
+ if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
+ dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
+
+ cmd_str = g_strdup_printf("%s", "ATA");
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request(%s) sent failed", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+ } else {
+ switch (data->type) {
+ case CALL_ANSWER_TYPE_REJECT:
+ {
+ dbg("call answer reject");
+ tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
+ }
+ break;
+
+ case CALL_ANSWER_TYPE_REPLACE:
+ {
+ dbg("call answer replace");
+ tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
+ }
+ break;
+
+ case CALL_ANSWER_TYPE_HOLD_ACCEPT:
+ {
+ dbg("call answer hold and accept");
+ tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
+ }
+ break;
+
+ default:
+ dbg("[ error ] wrong answer type [ %d ]", data->type);
+ return TCORE_RETURN_FAILURE;
+ }
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_release(CoreObject *o, UserRequest *ur)
+{
+ CallObject *co = NULL;
+ struct treq_call_end *data = 0;
+ UserRequest *ur_dup = NULL;
+ char *chld0_cmd = NULL;
+ char *chld1_cmd = NULL;
+ TcorePending *pending = NULL, *pending1 = NULL;
+ TcoreATRequest *req, *req1;
+ gboolean ret = FALSE;
+
+ dbg("function entrance");
+ data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
+ co = tcore_call_object_find_by_id(o, data->id);
+
+ dbg("type of release call = %d", data->type);
+
+ if (data->type == CALL_END_TYPE_ALL) {
+ // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
+ chld0_cmd = g_strdup("AT+CHLD=0");
+ chld1_cmd = g_strdup("AT+CHLD=1");
+
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
+
+ dbg("input command is %s", chld0_cmd);
+ dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ ur_dup = tcore_user_request_new(NULL, NULL);
+ ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
+ g_free(chld0_cmd);
+
+ if (!ret) {
+ dbg("AT request %s has failed ", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ pending1 = tcore_pending_new(o, 0);
+ req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
+
+ dbg("input command is %s", chld1_cmd);
+ dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
+
+ tcore_pending_set_request_data(pending1, 0, req1);
+ ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
+ g_free(chld1_cmd);
+
+ if (!ret) {
+ dbg("AT request %s has failed ", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+ } else {
+ switch (data->type) {
+ case CALL_END_TYPE_DEFAULT:
+ {
+ int id = 0;
+ id = tcore_call_object_get_id(co);
+
+ dbg("call end call id [%d]", id);
+ tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
+ }
+ break;
+
+ case CALL_END_TYPE_ACTIVE_ALL:
+ {
+ dbg("call end all active");
+ tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
+ }
+ break;
+
+ case CALL_END_TYPE_HOLD_ALL:
+ {
+ dbg("call end all held");
+ tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
+ }
+ break;
+
+ default:
+ dbg("[ error ] wrong end type [ %d ]", data->type);
+ return TCORE_RETURN_FAILURE;
+ }
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
+{
+ struct treq_call_hold *hold = 0;
+ CallObject *co = NULL;
+
+ dbg("function entrance");
+
+ hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
+ dbg("call id : [ %d ]", hold->id);
+
+ co = tcore_call_object_find_by_id(o, hold->id);
+ tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_active(CoreObject *o, UserRequest *ur)
+{
+ struct treq_call_active *active = 0;
+ CallObject *co = NULL;
+
+ active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
+ dbg("call id : [ %d ]", active->id);
+
+ co = tcore_call_object_find_by_id(o, active->id);
+ tcore_call_control_active(o, ur, on_confirmation_call_active, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
+{
+ struct treq_call_swap *swap = NULL;
+ CallObject *co = NULL;
+
+ swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
+ dbg("call id : [ %d ]", swap->id);
+
+ co = tcore_call_object_find_by_id(o, swap->id);
+ tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_join(CoreObject *o, UserRequest *ur)
+{
+ struct treq_call_join *join = 0;
+ CallObject *co = NULL;
+
+ join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
+ dbg("call id : [ %d ]", join->id);
+
+ co = tcore_call_object_find_by_id(o, join->id);
+ tcore_call_control_join(o, ur, on_confirmation_call_join, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_split(CoreObject *o, UserRequest *ur)
+{
+ struct treq_call_split *split = 0;
+ CallObject *co = NULL;
+
+ split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
+ co = tcore_call_object_find_by_id(o, split->id);
+ dbg("call id : [ %d ]", split->id);
+
+ tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
+{
+ struct treq_call_deflect *deflect = 0;
+ CallObject *co = NULL;
+
+ deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
+ co = tcore_call_object_find_by_number(o, deflect->number);
+ dbg("deflect number: [ %s ]", deflect->number);
+
+ tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
+{
+ struct treq_call_transfer *transfer = 0;
+ CallObject *co = NULL;
+
+ transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
+ dbg("call id : [ %d ]", transfer->id);
+
+ co = tcore_call_object_find_by_id(o, transfer->id);
+ tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
+{
+ char *cmd_str = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req;
+ UserRequest *dup;
+ gboolean ret = FALSE;
+ struct treq_call_dtmf *dtmf = 0;
+ char *dtmfstr = NULL, *tmp_dtmf = NULL;
+ unsigned int dtmf_count;
+
+ dbg("Function enter");
+
+ dup = tcore_user_request_new(NULL, NULL);
+ (void) _set_dtmf_tone_duration(o, dup);
+
+ dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
+ dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1); // DTMF digits + comma for each dtmf digit.
+
+ if (dtmfstr == NULL) {
+ dbg("Memory allocation failed");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ tmp_dtmf = dtmfstr;
+
+ for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
+ *tmp_dtmf = dtmf->digits[dtmf_count];
+ tmp_dtmf++;
+
+ *tmp_dtmf = COMMA;
+ tmp_dtmf++;
+ }
+
+ // last digit is having COMMA , overwrite it with '\0' .
+ *(--tmp_dtmf) = '\0';
+ dbg("Input DTMF string(%s)", dtmfstr);
+
+ // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
+ cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
+ dbg("request command : %s", cmd_str);
+
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
+ g_free(dtmfstr);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request sent failed")
+ return TCORE_RETURN_FAILURE;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
+{
+ UserRequest *ur_dup = NULL;
+ TcorePending *pending = NULL, *pending1 = NULL;
+ TcoreATRequest *req, *req1;
+ char *cmd_str = NULL, *cmd_str1 = NULL;
+ gboolean ret = FALSE;
+
+ dbg("function entrance");
+
+ // hard coded value for speaker.
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,1"); // source type.
+ cmd_str1 = g_strdup_printf("%s", "AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,1"); // destination type
+
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ ur_dup = tcore_user_request_ref(ur);
+
+ ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
+
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("At request(%s) sent failed", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ pending1 = tcore_pending_new(o, 0);
+ req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("input command is %s", cmd_str1);
+ dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
+
+ tcore_pending_set_request_data(pending1, 0, req1);
+ ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
+
+ g_free(cmd_str1);
+
+ if (!ret) {
+ dbg("AT request %s has failed ", req1->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
+{
+ UserRequest *src_ur = NULL;
+ UserRequest *dest_ur = NULL;
+ TcorePending *src_pending = NULL;
+ TcorePending *dest_pending = NULL;
+ TcoreATRequest *src_req = NULL;
+ TcoreATRequest *dest_req = NULL;
+ char *cmd_str = NULL, *volume_level = NULL;
+ gboolean ret = FALSE;
+
+ struct treq_call_sound_set_volume_level *data = NULL;
+ data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
+ dbg("Entry");
+ // Hard-coded values for MIC & Speakers
+ // Source volume
+ dbg("Set Source volume");
+
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source type
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ src_pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
+
+ // Free Command string
+ g_free(cmd_str);
+
+ tcore_pending_set_request_data(src_pending, 0, src_req);
+ src_ur = tcore_user_request_ref(ur);
+
+ // Send request
+ ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ src_pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
+
+ // Free Command string
+ g_free(cmd_str);
+
+ tcore_pending_set_request_data(src_pending, 0, src_req);
+
+ src_ur = tcore_user_request_ref(ur);
+
+ // Send request
+ ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ // Destination volume
+ dbg("Set Source volume");
+
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ dest_pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
+
+ // Free Command string
+ g_free(cmd_str);
+
+ tcore_pending_set_request_data(dest_pending, 0, dest_req);
+ dest_ur = tcore_user_request_ref(ur);
+
+ // Send request
+ ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Input volume level - %d", data->volume);
+ switch (data->volume) {
+ case CALL_SOUND_MUTE:
+ volume_level = "0";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_1:
+ volume_level = "40";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_2:
+ volume_level = "46";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_3:
+ volume_level = "52";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_4:
+ volume_level = "58";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_5:
+ volume_level = "64";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_6:
+ volume_level = "70";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_7:
+ volume_level = "76";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_8:
+ volume_level = "82";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_9:
+ default:
+ volume_level = "88";
+ break;
+ }
+ cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level); // Destination type
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ dest_pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
+
+ // Free Command string
+ g_free(cmd_str);
+
+ tcore_pending_set_request_data(dest_pending, 0, dest_req);
+
+ // Send request
+ ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+
+static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
+{
+ dbg("Entry");
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
+{
+ char *cmd_str = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req = NULL;
+ gboolean ret = FALSE;
+
+ dbg("Entry");
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
+
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ // Free command string
+ g_free(cmd_str);
+
+ // Set request data (AT command) to Pending request
+ tcore_pending_set_request_data(pending, 0, req);
+
+ // Send request
+ ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
+{
+ char *cmd_str = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req = NULL;
+ gboolean ret = FALSE;
+ dbg("Entry");
+
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ // Free command string
+ g_free(cmd_str);
+
+ // Set request data (AT command) to Pending request
+ tcore_pending_set_request_data(pending, 0, req);
+
+ // Send request
+ ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+
+static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
+{
+ dbg("Entry");
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
+{
+ char *cmd_str = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req = NULL;
+ gboolean ret = FALSE;
+ dbg("Entry");
+
+ cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ // Free command string */
+ g_free(cmd_str);
+
+ // Set request data (AT command) to Pending request
+ tcore_pending_set_request_data(pending, 0, req);
+
+ // Send request
+ ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+// Call Operations
+static struct tcore_call_operations call_ops = {
+ .dial = s_call_outgoing,
+ .answer = s_call_answer,
+ .end = s_call_release,
+ .hold = s_call_hold,
+ .active = s_call_active,
+ .swap = s_call_swap,
+ .join = s_call_join,
+ .split = s_call_split,
+ .deflect = s_call_deflect,
+ .transfer = s_call_transfer,
+ .send_dtmf = s_call_send_dtmf,
+ .set_sound_path = s_call_set_sound_path,
+ .set_sound_volume_level = s_call_set_sound_volume_level,
+ .get_sound_volume_level = s_call_get_sound_volume_level,
+ .mute = s_call_mute,
+ .unmute = s_call_unmute,
+ .get_mute_status = s_call_get_mute_status,
+ .set_sound_recording = NULL,
+ .set_sound_equalization = NULL,
+ .set_sound_noise_reduction = NULL,
+};
+
+static void s_call_info_mo_waiting(CoreObject *o)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_current_on_mo_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_WAITING,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mo_forwarded(CoreObject *o)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_current_on_mo_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_FORWARDED,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mo_barred_incoming(CoreObject *o)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_current_on_mo_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_BARRED_INCOMING,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mo_barred_outgoing(CoreObject *o)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_current_on_mo_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_BARRED_OUTGOING,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mo_deflected(CoreObject *o)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_current_on_mo_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_DEFLECTED,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mo_clir_suppression_reject(CoreObject *o)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_current_on_mo_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mo_cfu(CoreObject *o)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_current_on_mo_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_FORWARD_UNCONDITIONAL,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mo_cfc(CoreObject *o)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_current_on_mo_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_FORWARD_CONDITIONAL,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mt_cli(CoreObject *o, enum tcore_call_cli_mode mode, char *number)
+{
+ CallObject *co = NULL;
+ dbg("Entry");
+
+ // Call Core object
+ co = tcore_call_object_current_on_mt_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Set CLI information
+ tcore_call_object_set_cli_info(co, mode, number);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mt_cna(CoreObject *o, enum tcore_call_cna_mode mode, char *name, int dcs)
+{
+ CallObject *co = NULL;
+ dbg("Entry");
+
+ // Call Core object
+ co = tcore_call_object_current_on_mt_processing(o);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Set CNA information
+ tcore_call_object_set_cna_info(co, mode, name, dcs);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mt_forwarded_call(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_FORWARDED_CALL,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mt_deflected_call(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_DEFLECTED_CALL,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_mt_transfered(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_TRANSFERED_CALL,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_held(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_HELD,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_active(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_ACTIVE,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_joined(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_JOINED,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_released_on_hold(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_RELEASED_ON_HOLD,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_transfer_alert(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_TRANSFER_ALERT,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_transfered(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_TRANSFERED,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+static void s_call_info_cf_check_message(CoreObject *o, char *number)
+{
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = 0;
+ dbg("Entry");
+
+ // Parent plugin
+ plugin = tcore_object_ref_plugin(o);
+
+ // Call Core object
+ co = tcore_call_object_find_by_number(o, number);
+ if (!co) {
+ err("Failed to find Call Core object!");
+ return;
+ }
+
+ // Call ID
+ id = tcore_call_object_get_id(co);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ tcore_plugin_ref_core_object(plugin, "call"),
+ TNOTI_CALL_INFO_CF_CHECK_MESSAGE,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ dbg("Exit");
+ return;
+}
+
+// Call Information Operations
+static struct tcore_call_information_operations call_information_ops = {
+ .mo_call_col = 0,
+ .mo_call_waiting = s_call_info_mo_waiting,
+ .mo_call_cug = 0,
+ .mo_call_forwarded = s_call_info_mo_forwarded,
+ .mo_call_barred_incoming = s_call_info_mo_barred_incoming,
+ .mo_call_barred_outgoing = s_call_info_mo_barred_outgoing,
+ .mo_call_deflected = s_call_info_mo_deflected,
+ .mo_call_clir_suppression_reject = s_call_info_mo_clir_suppression_reject,
+ .mo_call_cfu = s_call_info_mo_cfu,
+ .mo_call_cfc = s_call_info_mo_cfc,
+ .mt_call_cli = s_call_info_mt_cli,
+ .mt_call_cna = s_call_info_mt_cna,
+ .mt_call_forwarded_call = s_call_info_mt_forwarded_call,
+ .mt_call_cug_call = 0,
+ .mt_call_deflected_call = s_call_info_mt_deflected_call,
+ .mt_call_transfered = s_call_info_mt_transfered,
+ .call_held = s_call_info_held,
+ .call_active = s_call_info_active,
+ .call_joined = s_call_info_joined,
+ .call_released_on_hold = s_call_info_released_on_hold,
+ .call_transfer_alert = s_call_info_transfer_alert,
+ .call_transfered = s_call_info_transfered,
+ .call_cf_check_message = s_call_info_cf_check_message,
+};
+
+gboolean s_call_init(TcorePlugin *p, TcoreHal *h)
+{
+ CoreObject *o = NULL;
+ struct property_call_info *data = NULL;
+ dbg("Entry");
+
+ // Creating Call COre object
+ o = tcore_call_new(p, "call", &call_ops, h);
+ if (!o) {
+ err("Failed to create Call Core Object");
+ return FALSE;
+ }
+
+ // Set Call Operations
+ tcore_call_information_set_operations(o, &call_information_ops);
+
+ // Add Callbacks
+ tcore_object_add_callback(o, "+XCALLSTAT", on_notification_call_info, NULL);
+ tcore_object_add_callback(o, "+CLIP", on_notification_call_clip_info, NULL);
+
+ // User Data
+ data = calloc(sizeof(struct property_call_info *), 1);
+ tcore_plugin_link_property(p, "CALL", data);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void s_call_exit(TcorePlugin *p)
+{
+ CoreObject *o = NULL;
+ struct property_network_info *data = NULL;
+ dbg("Entry");
+
+ o = tcore_plugin_ref_core_object(p, "call");
+
+ // Free Call Core Object */
+ tcore_call_free(o);
+
+ // Free 'CALL' property */
+ data = tcore_plugin_ref_property(p, "CALL");
+ if (data) {
+ g_free(data);
+ }
+
+ dbg("Exit");
+ return;
+}