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