Home | History | Annotate | Download | only in audio
      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