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 <sys/socket.h>
7 #include <sys/time.h>
8 #include <syslog.h>
9 
10 #include "cras_audio_area.h"
11 #include "cras_hfp_iodev.h"
12 #include "cras_hfp_info.h"
13 #include "cras_hfp_slc.h"
14 #include "cras_iodev.h"
15 #include "cras_system_state.h"
16 #include "cras_util.h"
17 #include "sfh.h"
18 #include "utlist.h"
19 
20 
21 struct hfp_io {
22 	struct cras_iodev base;
23 	struct cras_bt_device *device;
24 	struct hfp_slc_handle *slc;
25 	struct hfp_info *info;
26 };
27 
update_supported_formats(struct cras_iodev * iodev)28 static int update_supported_formats(struct cras_iodev *iodev)
29 {
30 	// 16 bit, mono, 8kHz
31 	iodev->format->format = SND_PCM_FORMAT_S16_LE;
32 
33 	free(iodev->supported_rates);
34 	iodev->supported_rates = (size_t *)malloc(2 * sizeof(size_t));
35 	iodev->supported_rates[0] = 8000;
36 	iodev->supported_rates[1] = 0;
37 
38 	free(iodev->supported_channel_counts);
39 	iodev->supported_channel_counts = (size_t *)malloc(2 * sizeof(size_t));
40 	iodev->supported_channel_counts[0] = 1;
41 	iodev->supported_channel_counts[1] = 0;
42 
43 	free(iodev->supported_formats);
44 	iodev->supported_formats =
45 		(snd_pcm_format_t *)malloc(2 * sizeof(snd_pcm_format_t));
46 	iodev->supported_formats[0] = SND_PCM_FORMAT_S16_LE;
47 	iodev->supported_formats[1] = 0;
48 
49 	return 0;
50 }
51 
frames_queued(const struct cras_iodev * iodev,struct timespec * tstamp)52 static int frames_queued(const struct cras_iodev *iodev,
53 			 struct timespec *tstamp)
54 {
55 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
56 
57 	if (!hfp_info_running(hfpio->info))
58 		return -1;
59 
60 	/* Do not enable timestamp mechanism on HFP device because last time
61 	 * stamp might be a long time ago and it is not really useful. */
62 	clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
63 	return hfp_buf_queued(hfpio->info, iodev);
64 }
65 
66 /* Modify the hfpio's buffer_size when the SCO packet size has changed. */
hfp_packet_size_changed(void * data)67 static void hfp_packet_size_changed(void *data)
68 {
69 	struct hfp_io *hfpio = (struct hfp_io *)data;
70 	struct cras_iodev *iodev = &hfpio->base;
71 
72 	if (!cras_iodev_is_open(iodev))
73 		return;
74 	iodev->buffer_size = hfp_buf_size(hfpio->info, iodev);
75 	cras_bt_device_iodev_buffer_size_changed(hfpio->device);
76 }
77 
configure_dev(struct cras_iodev * iodev)78 static int configure_dev(struct cras_iodev *iodev)
79 {
80 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
81 	int sk, err, mtu;
82 
83 	/* Assert format is set before opening device. */
84 	if (iodev->format == NULL)
85 		return -EINVAL;
86 	iodev->format->format = SND_PCM_FORMAT_S16_LE;
87 	cras_iodev_init_audio_area(iodev, iodev->format->num_channels);
88 
89 	if (hfp_info_running(hfpio->info))
90 		goto add_dev;
91 
92 	sk = cras_bt_device_sco_connect(hfpio->device);
93 	if (sk < 0)
94 		goto error;
95 
96 	mtu = cras_bt_device_sco_mtu(hfpio->device, sk);
97 
98 	/* Start hfp_info */
99 	err = hfp_info_start(sk, mtu, hfpio->info);
100 	if (err)
101 		goto error;
102 
103 add_dev:
104 	hfp_info_add_iodev(hfpio->info, iodev);
105 	hfp_set_call_status(hfpio->slc, 1);
106 
107 	iodev->buffer_size = hfp_buf_size(hfpio->info, iodev);
108 
109 	return 0;
110 error:
111 	syslog(LOG_ERR, "Failed to open HFP iodev");
112 	return -1;
113 }
114 
close_dev(struct cras_iodev * iodev)115 static int close_dev(struct cras_iodev *iodev)
116 {
117 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
118 
119 	hfp_info_rm_iodev(hfpio->info, iodev);
120 	if (hfp_info_running(hfpio->info) && !hfp_info_has_iodev(hfpio->info)) {
121 		hfp_info_stop(hfpio->info);
122 		hfp_set_call_status(hfpio->slc, 0);
123 	}
124 
125 	cras_iodev_free_format(iodev);
126 	cras_iodev_free_audio_area(iodev);
127 	return 0;
128 }
129 
set_hfp_volume(struct cras_iodev * iodev)130 static void set_hfp_volume(struct cras_iodev *iodev)
131 {
132 	size_t volume;
133 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
134 
135 	volume = cras_system_get_volume();
136 	if (iodev->active_node)
137 		volume = cras_iodev_adjust_node_volume(iodev->active_node, volume);
138 
139 	hfp_event_speaker_gain(hfpio->slc, volume);
140 }
141 
delay_frames(const struct cras_iodev * iodev)142 static int delay_frames(const struct cras_iodev *iodev)
143 {
144 	struct timespec tstamp;
145 
146 	return frames_queued(iodev, &tstamp);
147 }
148 
get_buffer(struct cras_iodev * iodev,struct cras_audio_area ** area,unsigned * frames)149 static int get_buffer(struct cras_iodev *iodev,
150 		      struct cras_audio_area **area,
151 		      unsigned *frames)
152 {
153 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
154 	uint8_t *dst = NULL;
155 
156 	if (!hfp_info_running(hfpio->info))
157 		return -1;
158 
159 	hfp_buf_acquire(hfpio->info, iodev, &dst, frames);
160 
161 	iodev->area->frames = *frames;
162 	/* HFP is mono only. */
163 	iodev->area->channels[0].step_bytes =
164 		cras_get_format_bytes(iodev->format);
165 	iodev->area->channels[0].buf = dst;
166 
167 	*area = iodev->area;
168 	return 0;
169 }
170 
put_buffer(struct cras_iodev * iodev,unsigned nwritten)171 static int put_buffer(struct cras_iodev *iodev, unsigned nwritten)
172 {
173 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
174 
175 	if (!hfp_info_running(hfpio->info))
176 		return -1;
177 
178 	hfp_buf_release(hfpio->info, iodev, nwritten);
179 	return 0;
180 }
181 
flush_buffer(struct cras_iodev * iodev)182 static int flush_buffer(struct cras_iodev *iodev)
183 {
184 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
185 	unsigned nframes;
186 
187 	if (iodev->direction == CRAS_STREAM_INPUT) {
188 		nframes = hfp_buf_queued(hfpio->info, iodev);
189 		hfp_buf_release(hfpio->info, iodev, nframes);
190 	}
191 	return 0;
192 }
193 
update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)194 static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
195 			       unsigned dev_enabled)
196 {
197 }
198 
hfp_free_resources(struct hfp_io * hfpio)199 void hfp_free_resources(struct hfp_io *hfpio)
200 {
201 	struct cras_ionode *node;
202 	node = hfpio->base.active_node;
203 	if (node) {
204 		cras_iodev_rm_node(&hfpio->base, node);
205 		free(node);
206 	}
207 	free(hfpio->base.supported_channel_counts);
208 	free(hfpio->base.supported_rates);
209 	free(hfpio->base.supported_formats);
210 	cras_iodev_free_resources(&hfpio->base);
211 }
212 
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)213 struct cras_iodev *hfp_iodev_create(
214 		enum CRAS_STREAM_DIRECTION dir,
215 		struct cras_bt_device *device,
216 		struct hfp_slc_handle *slc,
217 		enum cras_bt_device_profile profile,
218 		struct hfp_info *info)
219 {
220 	struct hfp_io *hfpio;
221 	struct cras_iodev *iodev;
222 	struct cras_ionode *node;
223 	const char *name;
224 
225 	hfpio = (struct hfp_io *)calloc(1, sizeof(*hfpio));
226 	if (!hfpio)
227 		goto error;
228 
229 	iodev = &hfpio->base;
230 	iodev->direction = dir;
231 
232 	hfpio->device = device;
233 	hfpio->slc = slc;
234 
235 	/* Set iodev's name to device readable name or the address. */
236 	name = cras_bt_device_name(device);
237 	if (!name)
238 		name = cras_bt_device_object_path(device);
239 
240 	snprintf(iodev->info.name, sizeof(iodev->info.name), "%s", name);
241 	iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = 0;
242 	iodev->info.stable_id = SuperFastHash(
243 			cras_bt_device_object_path(device),
244 			strlen(cras_bt_device_object_path(device)),
245 			strlen(cras_bt_device_object_path(device)));
246 	iodev->info.stable_id_new = iodev->info.stable_id;
247 
248 	iodev->configure_dev= configure_dev;
249 	iodev->frames_queued = frames_queued;
250 	iodev->delay_frames = delay_frames;
251 	iodev->get_buffer = get_buffer;
252 	iodev->put_buffer = put_buffer;
253 	iodev->flush_buffer = flush_buffer;
254 	iodev->close_dev = close_dev;
255 	iodev->update_supported_formats = update_supported_formats;
256 	iodev->update_active_node = update_active_node;
257 	iodev->set_volume = set_hfp_volume;
258 
259 	node = (struct cras_ionode *)calloc(1, sizeof(*node));
260 	node->dev = iodev;
261 	strcpy(node->name, iodev->info.name);
262 
263 	node->plugged = 1;
264 	node->type = CRAS_NODE_TYPE_BLUETOOTH;
265 	node->volume = 100;
266 	gettimeofday(&node->plugged_time, NULL);
267 
268 	cras_bt_device_append_iodev(device, iodev, profile);
269 	cras_iodev_add_node(iodev, node);
270 	cras_iodev_set_active_node(iodev, node);
271 
272 	hfpio->info = info;
273 	hfp_register_packet_size_changed_callback(info,
274 						  hfp_packet_size_changed,
275 						  hfpio);
276 
277 	return iodev;
278 
279 error:
280 	if (hfpio) {
281 		hfp_free_resources(hfpio);
282 		free(hfpio);
283 	}
284 	return NULL;
285 }
286 
hfp_iodev_destroy(struct cras_iodev * iodev)287 void hfp_iodev_destroy(struct cras_iodev *iodev)
288 {
289 	struct hfp_io *hfpio = (struct hfp_io *)iodev;
290 
291 	cras_bt_device_rm_iodev(hfpio->device, iodev);
292 	hfp_unregister_packet_size_changed_callback(hfpio->info, hfpio);
293 	hfp_free_resources(hfpio);
294 	free(hfpio);
295 }
296