• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 
6 #include <stdbool.h>
7 #include <sys/param.h>
8 #include <sys/socket.h>
9 #include <sys/time.h>
10 #include <syslog.h>
11 
12 #include "cras_audio_area.h"
13 #include "cras_hfp_ag_profile.h"
14 #include "cras_hfp_iodev.h"
15 #include "cras_hfp_info.h"
16 #include "cras_hfp_slc.h"
17 #include "cras_iodev.h"
18 #include "cras_system_state.h"
19 #include "cras_util.h"
20 #include "utlist.h"
21 
22 /* Implementation of bluetooth hands-free profile iodev.
23  * Members:
24  *    base - The cras_iodev structure base class.
25  *    device - The assciated bt_device.
26  *    slc - Handle to the HFP service level connection.
27  *    info - hfp_info taking care of SCO data read/write.
28  *    drain_complete - Flag to indicate if valid samples are drained
29  *        in no stream state. Only used for output.
30  *    filled_zeros - Number of zero data in frames have been filled
31  *        to buffer of hfp_info in no stream state. Only used for output
32  */
33 struct hfp_io {
34 	struct cras_iodev base;
35 	struct cras_bt_device *device;
36 	struct hfp_slc_handle *slc;
37 	struct hfp_info *info;
38 	bool drain_complete;
39 	unsigned int filled_zeros;
40 };
41 
update_supported_formats(struct cras_iodev * iodev)42 static int update_supported_formats(struct cras_iodev *iodev)
43 {
44 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
45 
46 	free(iodev->supported_rates);
47 	iodev->supported_rates = (size_t *)malloc(2 * sizeof(size_t));
48 
49 	/* 16 bit, mono, 8kHz for narrowband and 16KHz for wideband */
50 	iodev->supported_rates[0] =
51 		(hfp_slc_get_selected_codec(hfpio->slc) == HFP_CODEC_ID_MSBC) ?
52 			16000 :
53 			8000;
54 	iodev->supported_rates[1] = 0;
55 
56 	free(iodev->supported_channel_counts);
57 	iodev->supported_channel_counts = (size_t *)malloc(2 * sizeof(size_t));
58 	iodev->supported_channel_counts[0] = 1;
59 	iodev->supported_channel_counts[1] = 0;
60 
61 	free(iodev->supported_formats);
62 	iodev->supported_formats =
63 		(snd_pcm_format_t *)malloc(2 * sizeof(snd_pcm_format_t));
64 	iodev->supported_formats[0] = SND_PCM_FORMAT_S16_LE;
65 	iodev->supported_formats[1] = 0;
66 
67 	return 0;
68 }
69 
no_stream(struct cras_iodev * iodev,int enable)70 static int no_stream(struct cras_iodev *iodev, int enable)
71 {
72 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
73 	struct timespec hw_tstamp;
74 	unsigned int hw_level;
75 	unsigned int level_target;
76 
77 	if (iodev->direction != CRAS_STREAM_OUTPUT)
78 		return 0;
79 
80 	hw_level = iodev->frames_queued(iodev, &hw_tstamp);
81 	if (enable) {
82 		if (!hfpio->drain_complete && (hw_level <= hfpio->filled_zeros))
83 			hfpio->drain_complete = 1;
84 		hfpio->filled_zeros += hfp_fill_output_with_zeros(
85 			hfpio->info, iodev->buffer_size);
86 		return 0;
87 	}
88 
89 	/* Leave no stream state.*/
90 	level_target = iodev->min_cb_level;
91 	if (hfpio->drain_complete) {
92 		hfp_force_output_level(hfpio->info, level_target);
93 	} else {
94 		unsigned int valid_samples = 0;
95 		if (hw_level > hfpio->filled_zeros)
96 			valid_samples = hw_level - hfpio->filled_zeros;
97 		level_target = MAX(level_target, valid_samples);
98 
99 		if (level_target > hw_level)
100 			hfp_fill_output_with_zeros(hfpio->info,
101 						   level_target - hw_level);
102 		else
103 			hfp_force_output_level(hfpio->info, level_target);
104 	}
105 	hfpio->drain_complete = 0;
106 	hfpio->filled_zeros = 0;
107 
108 	return 0;
109 }
110 
frames_queued(const struct cras_iodev * iodev,struct timespec * tstamp)111 static int frames_queued(const struct cras_iodev *iodev,
112 			 struct timespec *tstamp)
113 {
114 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
115 
116 	if (!hfp_info_running(hfpio->info))
117 		return -1;
118 
119 	/* Do not enable timestamp mechanism on HFP device because last time
120 	 * stamp might be a long time ago and it is not really useful. */
121 	clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
122 	return hfp_buf_queued(hfpio->info, iodev->direction);
123 }
124 
output_underrun(struct cras_iodev * iodev)125 static int output_underrun(struct cras_iodev *iodev)
126 {
127 	/* Handle it the same way as cras_iodev_output_underrun(). */
128 	return cras_iodev_fill_odev_zeros(iodev, iodev->min_cb_level);
129 }
130 
configure_dev(struct cras_iodev * iodev)131 static int configure_dev(struct cras_iodev *iodev)
132 {
133 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
134 	int sk, err, mtu;
135 
136 	/* Assert format is set before opening device. */
137 	if (iodev->format == NULL)
138 		return -EINVAL;
139 
140 	iodev->format->format = SND_PCM_FORMAT_S16_LE;
141 	cras_iodev_init_audio_area(iodev, iodev->format->num_channels);
142 
143 	if (hfp_info_running(hfpio->info))
144 		goto add_dev;
145 
146 	/*
147 	 * Might require a codec negotiation before building the sco connection.
148 	 */
149 	hfp_slc_codec_connection_setup(hfpio->slc);
150 
151 	sk = cras_bt_device_sco_connect(hfpio->device,
152 					hfp_slc_get_selected_codec(hfpio->slc));
153 	if (sk < 0)
154 		goto error;
155 
156 	mtu = cras_bt_device_sco_packet_size(
157 		hfpio->device, sk, hfp_slc_get_selected_codec(hfpio->slc));
158 
159 	/* Start hfp_info */
160 	err = hfp_info_start(sk, mtu, hfp_slc_get_selected_codec(hfpio->slc),
161 			     hfpio->info);
162 	if (err)
163 		goto error;
164 
165 	hfpio->drain_complete = 0;
166 	hfpio->filled_zeros = 0;
167 add_dev:
168 	hfp_info_add_iodev(hfpio->info, iodev->direction, iodev->format);
169 	hfp_set_call_status(hfpio->slc, 1);
170 
171 	iodev->buffer_size = hfp_buf_size(hfpio->info, iodev->direction);
172 
173 	return 0;
174 error:
175 	syslog(LOG_ERR, "Failed to open HFP iodev");
176 	return -1;
177 }
178 
close_dev(struct cras_iodev * iodev)179 static int close_dev(struct cras_iodev *iodev)
180 {
181 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
182 
183 	hfp_info_rm_iodev(hfpio->info, iodev->direction);
184 	if (hfp_info_running(hfpio->info) && !hfp_info_has_iodev(hfpio->info)) {
185 		hfp_info_stop(hfpio->info);
186 		hfp_set_call_status(hfpio->slc, 0);
187 	}
188 
189 	cras_iodev_free_format(iodev);
190 	cras_iodev_free_audio_area(iodev);
191 	return 0;
192 }
193 
set_hfp_volume(struct cras_iodev * iodev)194 static void set_hfp_volume(struct cras_iodev *iodev)
195 {
196 	size_t volume;
197 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
198 
199 	volume = cras_system_get_volume();
200 	if (iodev->active_node)
201 		volume = cras_iodev_adjust_node_volume(iodev->active_node,
202 						       volume);
203 
204 	hfp_event_speaker_gain(hfpio->slc, volume);
205 }
206 
delay_frames(const struct cras_iodev * iodev)207 static int delay_frames(const struct cras_iodev *iodev)
208 {
209 	struct timespec tstamp;
210 
211 	return frames_queued(iodev, &tstamp);
212 }
213 
get_buffer(struct cras_iodev * iodev,struct cras_audio_area ** area,unsigned * frames)214 static int get_buffer(struct cras_iodev *iodev, struct cras_audio_area **area,
215 		      unsigned *frames)
216 {
217 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
218 	uint8_t *dst = NULL;
219 
220 	if (!hfp_info_running(hfpio->info))
221 		return -1;
222 
223 	hfp_buf_acquire(hfpio->info, iodev->direction, &dst, frames);
224 
225 	iodev->area->frames = *frames;
226 	/* HFP is mono only. */
227 	iodev->area->channels[0].step_bytes =
228 		cras_get_format_bytes(iodev->format);
229 	iodev->area->channels[0].buf = dst;
230 
231 	*area = iodev->area;
232 	return 0;
233 }
234 
put_buffer(struct cras_iodev * iodev,unsigned nwritten)235 static int put_buffer(struct cras_iodev *iodev, unsigned nwritten)
236 {
237 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
238 
239 	if (!hfp_info_running(hfpio->info))
240 		return -1;
241 
242 	hfp_buf_release(hfpio->info, iodev->direction, nwritten);
243 	return 0;
244 }
245 
flush_buffer(struct cras_iodev * iodev)246 static int flush_buffer(struct cras_iodev *iodev)
247 {
248 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
249 	unsigned nframes;
250 
251 	if (iodev->direction == CRAS_STREAM_INPUT) {
252 		nframes = hfp_buf_queued(hfpio->info, iodev->direction);
253 		hfp_buf_release(hfpio->info, iodev->direction, nframes);
254 	}
255 	return 0;
256 }
257 
update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)258 static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
259 			       unsigned dev_enabled)
260 {
261 }
262 
hfp_iodev_is_hsp(struct cras_iodev * iodev)263 int hfp_iodev_is_hsp(struct cras_iodev *iodev)
264 {
265 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
266 	return hfp_slc_is_hsp(hfpio->slc);
267 }
268 
hfp_free_resources(struct hfp_io * hfpio)269 void hfp_free_resources(struct hfp_io *hfpio)
270 {
271 	struct cras_ionode *node;
272 	node = hfpio->base.active_node;
273 	if (node) {
274 		cras_iodev_rm_node(&hfpio->base, node);
275 		free(node);
276 	}
277 	free(hfpio->base.supported_channel_counts);
278 	free(hfpio->base.supported_rates);
279 	free(hfpio->base.supported_formats);
280 	cras_iodev_free_resources(&hfpio->base);
281 }
282 
hfp_iodev_create(enum CRAS_STREAM_DIRECTION dir,struct cras_bt_device * device,struct hfp_slc_handle * slc,enum cras_bt_device_profile profile,struct hfp_info * info)283 struct cras_iodev *hfp_iodev_create(enum CRAS_STREAM_DIRECTION dir,
284 				    struct cras_bt_device *device,
285 				    struct hfp_slc_handle *slc,
286 				    enum cras_bt_device_profile profile,
287 				    struct hfp_info *info)
288 {
289 	struct hfp_io *hfpio;
290 	struct cras_iodev *iodev;
291 	struct cras_ionode *node;
292 	const char *name;
293 
294 	hfpio = (struct hfp_io *)calloc(1, sizeof(*hfpio));
295 	if (!hfpio)
296 		goto error;
297 
298 	iodev = &hfpio->base;
299 	iodev->direction = dir;
300 
301 	hfpio->device = device;
302 	hfpio->slc = slc;
303 
304 	/* Set iodev's name to device readable name or the address. */
305 	name = cras_bt_device_name(device);
306 	if (!name)
307 		name = cras_bt_device_object_path(device);
308 
309 	snprintf(iodev->info.name, sizeof(iodev->info.name), "%s", name);
310 	iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = 0;
311 	iodev->info.stable_id = cras_bt_device_get_stable_id(device);
312 
313 	iodev->configure_dev = configure_dev;
314 	iodev->frames_queued = frames_queued;
315 	iodev->delay_frames = delay_frames;
316 	iodev->get_buffer = get_buffer;
317 	iodev->put_buffer = put_buffer;
318 	iodev->flush_buffer = flush_buffer;
319 	iodev->no_stream = no_stream;
320 	iodev->close_dev = close_dev;
321 	iodev->update_supported_formats = update_supported_formats;
322 	iodev->update_active_node = update_active_node;
323 	iodev->set_volume = set_hfp_volume;
324 	iodev->output_underrun = output_underrun;
325 
326 	node = (struct cras_ionode *)calloc(1, sizeof(*node));
327 	node->dev = iodev;
328 	strcpy(node->name, iodev->info.name);
329 
330 	node->plugged = 1;
331 	/* If headset mic doesn't support the wideband speech, report a
332 	 * different node type so UI can set different plug priority. */
333 	node->type = CRAS_NODE_TYPE_BLUETOOTH;
334 	if (!hfp_slc_get_wideband_speech_supported(hfpio->slc) &&
335 	    (dir == CRAS_STREAM_INPUT))
336 		node->type = CRAS_NODE_TYPE_BLUETOOTH_NB_MIC;
337 
338 	node->volume = 100;
339 	gettimeofday(&node->plugged_time, NULL);
340 
341 	/* Prepare active node before append, so bt_io can extract correct
342 	 * info from HFP iodev and node. */
343 	cras_iodev_add_node(iodev, node);
344 	cras_iodev_set_active_node(iodev, node);
345 	cras_bt_device_append_iodev(device, iodev, profile);
346 
347 	hfpio->info = info;
348 
349 	/* Record max supported channels into cras_iodev_info. */
350 	iodev->info.max_supported_channels = 1;
351 
352 	ewma_power_disable(&iodev->ewma);
353 
354 	return iodev;
355 
356 error:
357 	if (hfpio) {
358 		hfp_free_resources(hfpio);
359 		free(hfpio);
360 	}
361 	return NULL;
362 }
363 
hfp_iodev_destroy(struct cras_iodev * iodev)364 void hfp_iodev_destroy(struct cras_iodev *iodev)
365 {
366 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
367 
368 	cras_bt_device_rm_iodev(hfpio->device, iodev);
369 	hfp_free_resources(hfpio);
370 	free(hfpio);
371 }
372