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 /* 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 */
telephony_update_indicator(struct indicator * indicators,const char * desc,int new_val)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
telephony_get_indicator(const struct indicator * indicators,const char * desc)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