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 <stdint.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <sys/socket.h> 10 #include <syslog.h> 11 12 #include "audio_thread.h" 13 #include "byte_buffer.h" 14 #include "cras_iodev_list.h" 15 #include "cras_hfp_info.h" 16 #include "utlist.h" 17 18 /* The max buffer size. Note that the actual used size must set to multiple 19 * of SCO packet size, and the packet size does not necessarily be equal to 20 * MTU. 21 */ 22 #define MAX_HFP_BUF_SIZE_BYTES 16384 23 24 /* rate(8kHz) * sample_size(2 bytes) * channels(1) */ 25 #define HFP_BYTE_RATE 16000 26 27 /* Structure to hold variables for a HFP connection. Since HFP supports 28 * bi-direction audio, two iodevs should share one hfp_info if they 29 * represent two directions of the same HFP headset 30 * Members: 31 * fd - The file descriptor for SCO socket. 32 * started - If the hfp_info has started to read/write SCO data. 33 * mtu - The max transmit unit reported from BT adapter. 34 * packet_size - The size of SCO packet to read/write preferred by 35 * adapter, could be different than mtu. 36 * capture_buf - The buffer to hold samples read from SCO socket. 37 * playback_buf - The buffer to hold samples about to write to SCO socket. 38 * idev - The input iodev using this hfp_info. 39 * odev - The output iodev using this hfp_info. 40 * packet_size_changed_cbs - The callbacks to trigger when SCO packet 41 * size changed. 42 */ 43 struct hfp_info { 44 int fd; 45 int started; 46 unsigned int mtu; 47 unsigned int packet_size; 48 struct byte_buffer *capture_buf; 49 struct byte_buffer *playback_buf; 50 51 struct cras_iodev *idev; 52 struct cras_iodev *odev; 53 struct hfp_packet_size_changed_callback *packet_size_changed_cbs; 54 }; 55 56 int hfp_info_add_iodev(struct hfp_info *info, struct cras_iodev *dev) 57 { 58 if (dev->direction == CRAS_STREAM_OUTPUT) { 59 if (info->odev) 60 goto invalid; 61 info->odev = dev; 62 63 buf_reset(info->playback_buf); 64 } else if (dev->direction == CRAS_STREAM_INPUT) { 65 if (info->idev) 66 goto invalid; 67 info->idev = dev; 68 69 buf_reset(info->capture_buf); 70 } 71 72 return 0; 73 74 invalid: 75 return -EINVAL; 76 } 77 78 int hfp_info_rm_iodev(struct hfp_info *info, struct cras_iodev *dev) 79 { 80 if (dev->direction == CRAS_STREAM_OUTPUT && info->odev == dev) { 81 info->odev = NULL; 82 } else if (dev->direction == CRAS_STREAM_INPUT && info->idev == dev){ 83 info->idev = NULL; 84 } else 85 return -EINVAL; 86 87 return 0; 88 } 89 90 int hfp_info_has_iodev(struct hfp_info *info) 91 { 92 return info->odev || info->idev; 93 } 94 95 void hfp_buf_acquire(struct hfp_info *info, struct cras_iodev *dev, 96 uint8_t **buf, unsigned *count) 97 { 98 size_t format_bytes; 99 unsigned int buf_avail; 100 format_bytes = cras_get_format_bytes(dev->format); 101 102 *count *= format_bytes; 103 104 if (dev->direction == CRAS_STREAM_OUTPUT) 105 *buf = buf_write_pointer_size(info->playback_buf, &buf_avail); 106 else 107 *buf = buf_read_pointer_size(info->capture_buf, &buf_avail); 108 109 if (*count > buf_avail) 110 *count = buf_avail; 111 *count /= format_bytes; 112 } 113 114 int hfp_buf_size(struct hfp_info *info, struct cras_iodev *dev) 115 { 116 return info->playback_buf->used_size / cras_get_format_bytes(dev->format); 117 } 118 119 void hfp_buf_release(struct hfp_info *info, struct cras_iodev *dev, 120 unsigned written_frames) 121 { 122 size_t format_bytes; 123 format_bytes = cras_get_format_bytes(dev->format); 124 125 written_frames *= format_bytes; 126 127 if (dev->direction == CRAS_STREAM_OUTPUT) 128 buf_increment_write(info->playback_buf, written_frames); 129 else 130 buf_increment_read(info->capture_buf, written_frames); 131 } 132 133 int hfp_buf_queued(struct hfp_info *info, const struct cras_iodev *dev) 134 { 135 size_t format_bytes; 136 format_bytes = cras_get_format_bytes(dev->format); 137 138 if (dev->direction == CRAS_STREAM_OUTPUT) 139 return buf_queued(info->playback_buf) / format_bytes; 140 else 141 return buf_queued(info->capture_buf) / format_bytes; 142 } 143 144 int hfp_write(struct hfp_info *info) 145 { 146 int err = 0; 147 unsigned to_send; 148 uint8_t *samples; 149 150 /* Write something */ 151 samples = buf_read_pointer_size(info->playback_buf, &to_send); 152 if (to_send < info->packet_size) 153 return 0; 154 to_send = info->packet_size; 155 156 send_sample: 157 err = send(info->fd, samples, to_send, 0); 158 if (err < 0) { 159 if (errno == EINTR) 160 goto send_sample; 161 162 return err; 163 } 164 165 if (err != (int)info->packet_size) { 166 syslog(LOG_ERR, 167 "Partially write %d bytes for SCO packet size %u", 168 err, info->packet_size); 169 return -1; 170 } 171 172 buf_increment_read(info->playback_buf, to_send); 173 174 return err; 175 } 176 177 178 static void hfp_info_set_packet_size(struct hfp_info *info, 179 unsigned int packet_size) 180 { 181 struct hfp_packet_size_changed_callback *callback; 182 unsigned int used_size = 183 MAX_HFP_BUF_SIZE_BYTES / packet_size * packet_size; 184 info->packet_size = packet_size; 185 byte_buffer_set_used_size(info->playback_buf, used_size); 186 byte_buffer_set_used_size(info->capture_buf, used_size); 187 188 DL_FOREACH(info->packet_size_changed_cbs, callback) 189 callback->cb(callback->data); 190 } 191 192 void hfp_register_packet_size_changed_callback(struct hfp_info *info, 193 void (*cb)(void *data), 194 void *data) 195 { 196 struct hfp_packet_size_changed_callback *callback = 197 (struct hfp_packet_size_changed_callback *)calloc(1, 198 sizeof(struct hfp_packet_size_changed_callback)); 199 callback->data = data; 200 callback->cb = cb; 201 DL_APPEND(info->packet_size_changed_cbs, callback); 202 } 203 204 void hfp_unregister_packet_size_changed_callback(struct hfp_info *info, 205 void *data) 206 { 207 struct hfp_packet_size_changed_callback *callback; 208 DL_FOREACH(info->packet_size_changed_cbs, callback) { 209 if (data == callback->data) { 210 DL_DELETE(info->packet_size_changed_cbs, callback); 211 free(callback); 212 } 213 } 214 } 215 216 int hfp_read(struct hfp_info *info) 217 { 218 int err = 0; 219 unsigned to_read; 220 uint8_t *capture_buf; 221 222 capture_buf = buf_write_pointer_size(info->capture_buf, &to_read); 223 224 if (to_read < info->packet_size) 225 return 0; 226 to_read = info->packet_size; 227 228 recv_sample: 229 err = recv(info->fd, capture_buf, to_read, 0); 230 if (err < 0) { 231 syslog(LOG_ERR, "Read error %s", strerror(errno)); 232 if (errno == EINTR) 233 goto recv_sample; 234 235 return err; 236 } 237 238 if (err != (int)info->packet_size) { 239 /* Allow the SCO packet size be modified from the default MTU 240 * value to the size of SCO data we first read. This is for 241 * some adapters who prefers a different value than MTU for 242 * transmitting SCO packet. 243 */ 244 if (err && (info->packet_size == info->mtu)) { 245 hfp_info_set_packet_size(info, err); 246 } else { 247 syslog(LOG_ERR, "Partially read %d bytes for %u size SCO packet", 248 err, info->packet_size); 249 return -1; 250 } 251 } 252 253 buf_increment_write(info->capture_buf, err); 254 255 return err; 256 } 257 258 /* Callback function to handle sample read and write. 259 * Note that we poll the SCO socket for read sample, since it reflects 260 * there is actual some sample to read while the socket always reports 261 * writable even when device buffer is full. 262 * The strategy is to synchronize read & write operations: 263 * 1. Read one chunk of MTU bytes of data. 264 * 2. When input device not attached, ignore the data just read. 265 * 3. When output device attached, write one chunk of MTU bytes of data. 266 */ 267 static int hfp_info_callback(void *arg) 268 { 269 struct hfp_info *info = (struct hfp_info *)arg; 270 int err; 271 272 if (!info->started) 273 goto read_write_error; 274 275 err = hfp_read(info); 276 if (err < 0) { 277 syslog(LOG_ERR, "Read error"); 278 goto read_write_error; 279 } 280 281 /* Ignore the MTU bytes just read if input dev not in present */ 282 if (!info->idev) 283 buf_increment_read(info->capture_buf, info->packet_size); 284 285 if (info->odev) { 286 err = hfp_write(info); 287 if (err < 0) { 288 syslog(LOG_ERR, "Write error"); 289 goto read_write_error; 290 } 291 } 292 293 return 0; 294 295 read_write_error: 296 hfp_info_stop(info); 297 298 return 0; 299 } 300 301 struct hfp_info *hfp_info_create() 302 { 303 struct hfp_info *info; 304 info = (struct hfp_info *)calloc(1, sizeof(*info)); 305 if (!info) 306 goto error; 307 308 info->capture_buf = byte_buffer_create(MAX_HFP_BUF_SIZE_BYTES); 309 if (!info->capture_buf) 310 goto error; 311 312 info->playback_buf = byte_buffer_create(MAX_HFP_BUF_SIZE_BYTES); 313 if (!info->playback_buf) 314 goto error; 315 316 return info; 317 318 error: 319 if (info) { 320 if (info->capture_buf) 321 byte_buffer_destroy(&info->capture_buf); 322 if (info->playback_buf) 323 byte_buffer_destroy(&info->playback_buf); 324 free(info); 325 } 326 return NULL; 327 } 328 329 int hfp_info_running(struct hfp_info *info) 330 { 331 return info->started; 332 } 333 334 int hfp_info_start(int fd, unsigned int mtu, struct hfp_info *info) 335 { 336 info->fd = fd; 337 info->mtu = mtu; 338 339 /* Make sure buffer size is multiple of packet size, which initially 340 * set to MTU. */ 341 hfp_info_set_packet_size(info, mtu); 342 buf_reset(info->playback_buf); 343 buf_reset(info->capture_buf); 344 345 audio_thread_add_callback(info->fd, hfp_info_callback, info); 346 347 info->started = 1; 348 349 return 0; 350 } 351 352 int hfp_info_stop(struct hfp_info *info) 353 { 354 if (!info->started) 355 return 0; 356 357 audio_thread_rm_callback_sync( 358 cras_iodev_list_get_audio_thread(), 359 info->fd); 360 361 close(info->fd); 362 info->fd = 0; 363 info->started = 0; 364 365 return 0; 366 } 367 368 void hfp_info_destroy(struct hfp_info *info) 369 { 370 if (info->capture_buf) 371 byte_buffer_destroy(&info->capture_buf); 372 373 if (info->playback_buf) 374 byte_buffer_destroy(&info->playback_buf); 375 376 free(info); 377 } 378