1/* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2006-2010 Nokia Corporation 6 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25#include <stdint.h> 26#include <errno.h> 27#include <glib.h> 28 29/* Response and hold values */ 30#define BTRH_NOT_SUPPORTED -2 31#define BTRH_NONE -1 32#define BTRH_HOLD 0 33#define BTRH_ACCEPT 1 34#define BTRH_REJECT 2 35 36/* HFP feature bits */ 37#define AG_FEATURE_THREE_WAY_CALLING 0x0001 38#define AG_FEATURE_EC_ANDOR_NR 0x0002 39#define AG_FEATURE_VOICE_RECOGNITION 0x0004 40#define AG_FEATURE_INBAND_RINGTONE 0x0008 41#define AG_FEATURE_ATTACH_NUMBER_TO_VOICETAG 0x0010 42#define AG_FEATURE_REJECT_A_CALL 0x0020 43#define AG_FEATURE_ENHANCED_CALL_STATUS 0x0040 44#define AG_FEATURE_ENHANCED_CALL_CONTROL 0x0080 45#define AG_FEATURE_EXTENDED_ERROR_RESULT_CODES 0x0100 46 47#define HF_FEATURE_EC_ANDOR_NR 0x0001 48#define HF_FEATURE_CALL_WAITING_AND_3WAY 0x0002 49#define HF_FEATURE_CLI_PRESENTATION 0x0004 50#define HF_FEATURE_VOICE_RECOGNITION 0x0008 51#define HF_FEATURE_REMOTE_VOLUME_CONTROL 0x0010 52#define HF_FEATURE_ENHANCED_CALL_STATUS 0x0020 53#define HF_FEATURE_ENHANCED_CALL_CONTROL 0x0040 54 55/* Indicator event values */ 56#define EV_SERVICE_NONE 0 57#define EV_SERVICE_PRESENT 1 58 59#define EV_CALL_INACTIVE 0 60#define EV_CALL_ACTIVE 1 61 62#define EV_CALLSETUP_INACTIVE 0 63#define EV_CALLSETUP_INCOMING 1 64#define EV_CALLSETUP_OUTGOING 2 65#define EV_CALLSETUP_ALERTING 3 66 67#define EV_CALLHELD_NONE 0 68#define EV_CALLHELD_MULTIPLE 1 69#define EV_CALLHELD_ON_HOLD 2 70 71#define EV_ROAM_INACTIVE 0 72#define EV_ROAM_ACTIVE 1 73 74/* Call parameters */ 75#define CALL_DIR_OUTGOING 0 76#define CALL_DIR_INCOMING 1 77 78#define CALL_STATUS_ACTIVE 0 79#define CALL_STATUS_HELD 1 80#define CALL_STATUS_DIALING 2 81#define CALL_STATUS_ALERTING 3 82#define CALL_STATUS_INCOMING 4 83#define CALL_STATUS_WAITING 5 84 85#define CALL_MODE_VOICE 0 86#define CALL_MODE_DATA 1 87#define CALL_MODE_FAX 2 88 89#define CALL_MULTIPARTY_NO 0 90#define CALL_MULTIPARTY_YES 1 91 92/* Subscriber number parameters */ 93#define SUBSCRIBER_SERVICE_VOICE 4 94#define SUBSCRIBER_SERVICE_FAX 5 95 96/* Operator selection mode values */ 97#define OPERATOR_MODE_AUTO 0 98#define OPERATOR_MODE_MANUAL 1 99#define OPERATOR_MODE_DEREGISTER 2 100#define OPERATOR_MODE_MANUAL_AUTO 4 101 102/* Some common number types */ 103#define NUMBER_TYPE_UNKNOWN 128 104#define NUMBER_TYPE_TELEPHONY 129 105#define NUMBER_TYPE_INTERNATIONAL 145 106#define NUMBER_TYPE_NATIONAL 161 107#define NUMBER_TYPE_VOIP 255 108 109/* Extended Audio Gateway Error Result Codes */ 110typedef enum { 111 CME_ERROR_NONE = -1, 112 CME_ERROR_AG_FAILURE = 0, 113 CME_ERROR_NO_PHONE_CONNECTION = 1, 114 CME_ERROR_NOT_ALLOWED = 3, 115 CME_ERROR_NOT_SUPPORTED = 4, 116 CME_ERROR_PH_SIM_PIN_REQUIRED = 5, 117 CME_ERROR_SIM_NOT_INSERTED = 10, 118 CME_ERROR_SIM_PIN_REQUIRED = 11, 119 CME_ERROR_SIM_PUK_REQUIRED = 12, 120 CME_ERROR_SIM_FAILURE = 13, 121 CME_ERROR_SIM_BUSY = 14, 122 CME_ERROR_INCORRECT_PASSWORD = 16, 123 CME_ERROR_SIM_PIN2_REQUIRED = 17, 124 CME_ERROR_SIM_PUK2_REQUIRED = 18, 125 CME_ERROR_MEMORY_FULL = 20, 126 CME_ERROR_INVALID_INDEX = 21, 127 CME_ERROR_MEMORY_FAILURE = 23, 128 CME_ERROR_TEXT_STRING_TOO_LONG = 24, 129 CME_ERROR_INVALID_TEXT_STRING = 25, 130 CME_ERROR_DIAL_STRING_TOO_LONG = 26, 131 CME_ERROR_INVALID_DIAL_STRING = 27, 132 CME_ERROR_NO_NETWORK_SERVICE = 30, 133 CME_ERROR_NETWORK_TIMEOUT = 31, 134 CME_ERROR_NETWORK_NOT_ALLOWED = 32, 135} cme_error_t; 136 137struct indicator { 138 const char *desc; 139 const char *range; 140 int val; 141 gboolean ignore_redundant; 142}; 143 144/* Notify telephony-*.c of connected/disconnected devices. Implemented by 145 * telephony-*.c 146 */ 147void telephony_device_connected(void *telephony_device); 148void telephony_device_disconnected(void *telephony_device); 149 150/* HF requests (sent by the handsfree device). These are implemented by 151 * telephony-*.c 152 */ 153void telephony_event_reporting_req(void *telephony_device, int ind); 154void telephony_response_and_hold_req(void *telephony_device, int rh); 155void telephony_last_dialed_number_req(void *telephony_device); 156void telephony_terminate_call_req(void *telephony_device); 157void telephony_answer_call_req(void *telephony_device); 158void telephony_dial_number_req(void *telephony_device, const char *number); 159void telephony_transmit_dtmf_req(void *telephony_device, char tone); 160void telephony_subscriber_number_req(void *telephony_device); 161void telephony_list_current_calls_req(void *telephony_device); 162void telephony_operator_selection_req(void *telephony_device); 163void telephony_call_hold_req(void *telephony_device, const char *cmd); 164void telephony_nr_and_ec_req(void *telephony_device, gboolean enable); 165void telephony_voice_dial_req(void *telephony_device, gboolean enable); 166void telephony_key_press_req(void *telephony_device, const char *keys); 167 168/* AG responses to HF requests. These are implemented by headset.c */ 169int telephony_event_reporting_rsp(void *telephony_device, cme_error_t err); 170int telephony_response_and_hold_rsp(void *telephony_device, cme_error_t err); 171int telephony_last_dialed_number_rsp(void *telephony_device, cme_error_t err); 172int telephony_terminate_call_rsp(void *telephony_device, cme_error_t err); 173int telephony_answer_call_rsp(void *telephony_device, cme_error_t err); 174int telephony_dial_number_rsp(void *telephony_device, cme_error_t err); 175int telephony_transmit_dtmf_rsp(void *telephony_device, cme_error_t err); 176int telephony_subscriber_number_rsp(void *telephony_device, cme_error_t err); 177int telephony_list_current_calls_rsp(void *telephony_device, cme_error_t err); 178int telephony_operator_selection_rsp(void *telephony_device, cme_error_t err); 179int telephony_call_hold_rsp(void *telephony_device, cme_error_t err); 180int telephony_nr_and_ec_rsp(void *telephony_device, cme_error_t err); 181int telephony_voice_dial_rsp(void *telephony_device, cme_error_t err); 182int telephony_key_press_rsp(void *telephony_device, cme_error_t err); 183 184/* Event indications by AG. These are implemented by headset.c */ 185int telephony_event_ind(int index); 186int telephony_response_and_hold_ind(int rh); 187int telephony_incoming_call_ind(const char *number, int type); 188int telephony_calling_stopped_ind(void); 189int telephony_ready_ind(uint32_t features, const struct indicator *indicators, 190 int rh, const char *chld); 191int telephony_deinit(void); 192int telephony_list_current_call_ind(int idx, int dir, int status, int mode, 193 int mprty, const char *number, 194 int type); 195int telephony_subscriber_number_ind(const char *number, int type, 196 int service); 197int telephony_call_waiting_ind(const char *number, int type); 198int telephony_operator_selection_ind(int mode, const char *oper); 199 200/* Helper function for quick indicator updates */ 201static inline int telephony_update_indicator(struct indicator *indicators, 202 const char *desc, 203 int new_val) 204{ 205 int i; 206 struct indicator *ind = NULL; 207 208 for (i = 0; indicators[i].desc != NULL; i++) { 209 if (g_str_equal(indicators[i].desc, desc)) { 210 ind = &indicators[i]; 211 break; 212 } 213 } 214 215 if (!ind) 216 return -ENOENT; 217 218 DBG("Telephony indicator \"%s\" %d->%d", desc, ind->val, new_val); 219 220 if (ind->ignore_redundant && ind->val == new_val) { 221 DBG("Ignoring no-change indication"); 222 return 0; 223 } 224 225 ind->val = new_val; 226 227 return telephony_event_ind(i); 228} 229 230static inline int telephony_get_indicator(const struct indicator *indicators, 231 const char *desc) 232{ 233 int i; 234 235 for (i = 0; indicators[i].desc != NULL; i++) { 236 if (g_str_equal(indicators[i].desc, desc)) 237 return indicators[i].val; 238 } 239 240 return -ENOENT; 241} 242 243int telephony_init(void); 244void telephony_exit(void); 245