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 (at) 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 /* HFP feature bits */ 30 #define AG_FEATURE_THREE_WAY_CALLING 0x0001 31 #define AG_FEATURE_EC_ANDOR_NR 0x0002 32 #define AG_FEATURE_VOICE_RECOGNITION 0x0004 33 #define AG_FEATURE_INBAND_RINGTONE 0x0008 34 #define AG_FEATURE_ATTACH_NUMBER_TO_VOICETAG 0x0010 35 #define AG_FEATURE_REJECT_A_CALL 0x0020 36 #define AG_FEATURE_ENHANCED_CALL_STATUS 0x0040 37 #define AG_FEATURE_ENHANCED_CALL_CONTROL 0x0080 38 #define AG_FEATURE_EXTENDED_ERROR_RESULT_CODES 0x0100 39 40 #define HF_FEATURE_EC_ANDOR_NR 0x0001 41 #define HF_FEATURE_CALL_WAITING_AND_3WAY 0x0002 42 #define HF_FEATURE_CLI_PRESENTATION 0x0004 43 #define HF_FEATURE_VOICE_RECOGNITION 0x0008 44 #define HF_FEATURE_REMOTE_VOLUME_CONTROL 0x0010 45 #define HF_FEATURE_ENHANCED_CALL_STATUS 0x0020 46 #define HF_FEATURE_ENHANCED_CALL_CONTROL 0x0040 47 48 /* Indicator event values */ 49 #define EV_SERVICE_NONE 0 50 #define EV_SERVICE_PRESENT 1 51 52 #define EV_CALL_INACTIVE 0 53 #define EV_CALL_ACTIVE 1 54 55 #define EV_CALLSETUP_INACTIVE 0 56 #define EV_CALLSETUP_INCOMING 1 57 #define EV_CALLSETUP_OUTGOING 2 58 #define EV_CALLSETUP_ALERTING 3 59 60 #define EV_CALLHELD_NONE 0 61 #define EV_CALLHELD_MULTIPLE 1 62 #define EV_CALLHELD_ON_HOLD 2 63 64 #define EV_ROAM_INACTIVE 0 65 #define EV_ROAM_ACTIVE 1 66 67 /* Call parameters */ 68 #define CALL_DIR_OUTGOING 0 69 #define CALL_DIR_INCOMING 1 70 71 #define CALL_STATUS_ACTIVE 0 72 #define CALL_STATUS_HELD 1 73 #define CALL_STATUS_DIALING 2 74 #define CALL_STATUS_ALERTING 3 75 #define CALL_STATUS_INCOMING 4 76 #define CALL_STATUS_WAITING 5 77 78 #define CALL_MODE_VOICE 0 79 #define CALL_MODE_DATA 1 80 #define CALL_MODE_FAX 2 81 82 #define CALL_MULTIPARTY_NO 0 83 #define CALL_MULTIPARTY_YES 1 84 85 /* Subscriber number parameters */ 86 #define SUBSCRIBER_SERVICE_VOICE 4 87 #define SUBSCRIBER_SERVICE_FAX 5 88 89 /* Operator selection mode values */ 90 #define OPERATOR_MODE_AUTO 0 91 #define OPERATOR_MODE_MANUAL 1 92 #define OPERATOR_MODE_DEREGISTER 2 93 #define OPERATOR_MODE_MANUAL_AUTO 4 94 95 /* Some common number types */ 96 #define NUMBER_TYPE_UNKNOWN 128 97 #define NUMBER_TYPE_TELEPHONY 129 98 #define NUMBER_TYPE_INTERNATIONAL 145 99 #define NUMBER_TYPE_NATIONAL 161 100 #define NUMBER_TYPE_VOIP 255 101 102 /* Extended Audio Gateway Error Result Codes */ 103 typedef enum { 104 CME_ERROR_NONE = -1, 105 CME_ERROR_AG_FAILURE = 0, 106 CME_ERROR_NO_PHONE_CONNECTION = 1, 107 CME_ERROR_NOT_ALLOWED = 3, 108 CME_ERROR_NOT_SUPPORTED = 4, 109 CME_ERROR_PH_SIM_PIN_REQUIRED = 5, 110 CME_ERROR_SIM_NOT_INSERTED = 10, 111 CME_ERROR_SIM_PIN_REQUIRED = 11, 112 CME_ERROR_SIM_PUK_REQUIRED = 12, 113 CME_ERROR_SIM_FAILURE = 13, 114 CME_ERROR_SIM_BUSY = 14, 115 CME_ERROR_INCORRECT_PASSWORD = 16, 116 CME_ERROR_SIM_PIN2_REQUIRED = 17, 117 CME_ERROR_SIM_PUK2_REQUIRED = 18, 118 CME_ERROR_MEMORY_FULL = 20, 119 CME_ERROR_INVALID_INDEX = 21, 120 CME_ERROR_MEMORY_FAILURE = 23, 121 CME_ERROR_TEXT_STRING_TOO_LONG = 24, 122 CME_ERROR_INVALID_TEXT_STRING = 25, 123 CME_ERROR_DIAL_STRING_TOO_LONG = 26, 124 CME_ERROR_INVALID_DIAL_STRING = 27, 125 CME_ERROR_NO_NETWORK_SERVICE = 30, 126 CME_ERROR_NETWORK_TIMEOUT = 31, 127 CME_ERROR_NETWORK_NOT_ALLOWED = 32, 128 } cme_error_t; 129 130 struct indicator { 131 const char *desc; 132 const char *range; 133 int val; 134 gboolean ignore_redundant; 135 }; 136 137 /* Notify telephony-*.c of connected/disconnected devices. Implemented by 138 * telephony-*.c 139 */ 140 void telephony_device_connected(void *telephony_device); 141 void telephony_device_disconnected(void *telephony_device); 142 143 /* HF requests (sent by the handsfree device). These are implemented by 144 * telephony-*.c 145 */ 146 void telephony_event_reporting_req(void *telephony_device, int ind); 147 void telephony_response_and_hold_req(void *telephony_device, int rh); 148 void telephony_last_dialed_number_req(void *telephony_device); 149 void telephony_terminate_call_req(void *telephony_device); 150 void telephony_answer_call_req(void *telephony_device); 151 void telephony_dial_number_req(void *telephony_device, const char *number); 152 void telephony_transmit_dtmf_req(void *telephony_device, char tone); 153 void telephony_subscriber_number_req(void *telephony_device); 154 void telephony_list_current_calls_req(void *telephony_device); 155 void telephony_operator_selection_req(void *telephony_device); 156 void telephony_call_hold_req(void *telephony_device, const char *cmd); 157 void telephony_nr_and_ec_req(void *telephony_device, gboolean enable); 158 void telephony_voice_dial_req(void *telephony_device, gboolean enable); 159 void telephony_key_press_req(void *telephony_device, const char *keys); 160 161 /* AG responses to HF requests. These are implemented by headset.c */ 162 int telephony_event_reporting_rsp(void *telephony_device, cme_error_t err); 163 int telephony_response_and_hold_rsp(void *telephony_device, cme_error_t err); 164 int telephony_last_dialed_number_rsp(void *telephony_device, cme_error_t err); 165 int telephony_terminate_call_rsp(void *telephony_device, cme_error_t err); 166 int telephony_answer_call_rsp(void *telephony_device, cme_error_t err); 167 int telephony_dial_number_rsp(void *telephony_device, cme_error_t err); 168 int telephony_transmit_dtmf_rsp(void *telephony_device, cme_error_t err); 169 int telephony_subscriber_number_rsp(void *telephony_device, cme_error_t err); 170 int telephony_list_current_calls_rsp(void *telephony_device, cme_error_t err); 171 int telephony_operator_selection_rsp(void *telephony_device, cme_error_t err); 172 int telephony_call_hold_rsp(void *telephony_device, cme_error_t err); 173 int telephony_nr_and_ec_rsp(void *telephony_device, cme_error_t err); 174 int telephony_voice_dial_rsp(void *telephony_device, cme_error_t err); 175 int telephony_key_press_rsp(void *telephony_device, cme_error_t err); 176 177 /* Event indications by AG. These are implemented by headset.c */ 178 int telephony_event_ind(int index); 179 int telephony_response_and_hold_ind(int rh); 180 int telephony_incoming_call_ind(const char *number, int type); 181 int telephony_calling_stopped_ind(void); 182 int telephony_ready_ind(uint32_t features, const struct indicator *indicators, 183 int rh, const char *chld); 184 int telephony_list_current_call_ind(int idx, int dir, int status, int mode, 185 int mprty, const char *number, 186 int type); 187 int telephony_subscriber_number_ind(const char *number, int type, 188 int service); 189 int telephony_call_waiting_ind(const char *number, int type); 190 int telephony_operator_selection_ind(int mode, const char *oper); 191 192 /* Helper function for quick indicator updates */ 193 static inline int telephony_update_indicator(struct indicator *indicators, 194 const char *desc, 195 int new_val) 196 { 197 int i; 198 struct indicator *ind = NULL; 199 200 for (i = 0; indicators[i].desc != NULL; i++) { 201 if (g_str_equal(indicators[i].desc, desc)) { 202 ind = &indicators[i]; 203 break; 204 } 205 } 206 207 if (!ind) 208 return -ENOENT; 209 210 DBG("Telephony indicator \"%s\" %d->%d", desc, ind->val, new_val); 211 212 if (ind->ignore_redundant && ind->val == new_val) { 213 DBG("Ignoring no-change indication"); 214 return 0; 215 } 216 217 ind->val = new_val; 218 219 return telephony_event_ind(i); 220 } 221 222 static inline int telephony_get_indicator(const struct indicator *indicators, 223 const char *desc) 224 { 225 int i; 226 227 for (i = 0; indicators[i].desc != NULL; i++) { 228 if (g_str_equal(indicators[i].desc, desc)) 229 return indicators[i].val; 230 } 231 232 return -ENOENT; 233 } 234 235 int telephony_init(void); 236 void telephony_exit(void); 237