• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2006-2007  Nokia Corporation
6  *  Copyright (C) 2004-2009  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 /* 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_key_press_req(void *telephony_device, const char *keys);
159 
160 /* AG responses to HF requests. These are implemented by headset.c */
161 int telephony_event_reporting_rsp(void *telephony_device, cme_error_t err);
162 int telephony_response_and_hold_rsp(void *telephony_device, cme_error_t err);
163 int telephony_last_dialed_number_rsp(void *telephony_device, cme_error_t err);
164 int telephony_terminate_call_rsp(void *telephony_device, cme_error_t err);
165 int telephony_answer_call_rsp(void *telephony_device, cme_error_t err);
166 int telephony_dial_number_rsp(void *telephony_device, cme_error_t err);
167 int telephony_transmit_dtmf_rsp(void *telephony_device, cme_error_t err);
168 int telephony_subscriber_number_rsp(void *telephony_device, cme_error_t err);
169 int telephony_list_current_calls_rsp(void *telephony_device, cme_error_t err);
170 int telephony_operator_selection_rsp(void *telephony_device, cme_error_t err);
171 int telephony_call_hold_rsp(void *telephony_device, cme_error_t err);
172 int telephony_nr_and_ec_rsp(void *telephony_device, cme_error_t err);
173 int telephony_key_press_rsp(void *telephony_device, cme_error_t err);
174 
175 /* Event indications by AG. These are implemented by headset.c */
176 int telephony_event_ind(int index);
177 int telephony_response_and_hold_ind(int rh);
178 int telephony_incoming_call_ind(const char *number, int type);
179 int telephony_calling_stopped_ind(void);
180 int telephony_ready_ind(uint32_t features, const struct indicator *indicators,
181 			int rh, const char *chld);
182 int telephony_list_current_call_ind(int idx, int dir, int status, int mode,
183 					int mprty, const char *number,
184 					int type);
185 int telephony_subscriber_number_ind(const char *number, int type,
186 					int service);
187 int telephony_call_waiting_ind(const char *number, int type);
188 int telephony_operator_selection_ind(int mode, const char *oper);
189 
190 /* Helper function for quick indicator updates */
telephony_update_indicator(struct indicator * indicators,const char * desc,int new_val)191 static inline int telephony_update_indicator(struct indicator *indicators,
192 						const char *desc,
193 						int new_val)
194 {
195 	int i;
196 	struct indicator *ind = NULL;
197 
198 	for (i = 0; indicators[i].desc != NULL; i++) {
199 		if (g_str_equal(indicators[i].desc, desc)) {
200 			ind = &indicators[i];
201 			break;
202 		}
203 	}
204 
205 	if (!ind)
206 		return -ENOENT;
207 
208 	debug("Telephony indicator \"%s\" %d->%d", desc, ind->val, new_val);
209 
210 	if (ind->ignore_redundant && ind->val == new_val) {
211 		debug("Ignoring no-change indication");
212 		return 0;
213 	}
214 
215 	ind->val = new_val;
216 
217 	return telephony_event_ind(i);
218 }
219 
telephony_get_indicator(const struct indicator * indicators,const char * desc)220 static inline int telephony_get_indicator(const struct indicator *indicators,
221 						const char *desc)
222 {
223 	int i;
224 
225 	for (i = 0; indicators[i].desc != NULL; i++) {
226 		if (g_str_equal(indicators[i].desc, desc))
227 			return indicators[i].val;
228 	}
229 
230 	return -ENOENT;
231 }
232 
233 int telephony_init(void);
234 void telephony_exit(void);
235