3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2006-2010 Nokia Corporation
6 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
7 * Copyright (C) 2009 Lennart Poettering
8 * Copyright (C) 2008 Joao Paulo Rechi Vita
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
46 #define DBG(fmt, arg...) \
47 printf("debug %s: " fmt "\n" , __FUNCTION__ , ## arg)
48 #define ERR(fmt, arg...) \
49 fprintf(stderr, "ERROR %s: " fmt "\n" , __FUNCTION__ , ## arg)
51 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
54 # define MIN(x, y) ((x) < (y) ? (x) : (y))
58 # define MAX(x, y) ((x) > (y) ? (x) : (y))
69 #define YES_NO(t) ((t) ? "yes" : "no")
71 #define BUFFER_SIZE 2048
72 #define MAX_BITPOOL 64
76 sbc_capabilities_t sbc_capabilities;
77 sbc_t sbc; /* Codec data */
78 int sbc_initialized; /* Keep track if the encoder is initialized */
79 size_t codesize; /* SBC codesize */
81 void* buffer; /* Codec transfer buffer */
82 size_t buffer_size; /* Size of the buffer */
84 uint16_t seq_num; /* Cumulative packet sequence */
88 pcm_capabilities_t pcm_capabilities;
94 GIOChannel *stream_channel;
96 GIOChannel *gin; /* dude, I am thirsty now */
102 struct a2dp_info a2dp;
106 gboolean debug_stream_read : 1;
107 gboolean debug_stream_write : 1;
110 static struct userdata data = {
113 .transport = BT_CAPABILITIES_TRANSPORT_A2DP,
119 static int start_stream(struct userdata *u);
120 static int stop_stream(struct userdata *u);
121 static gboolean input_cb(GIOChannel *gin, GIOCondition condition, gpointer data);
123 static GMainLoop *main_loop;
125 static int service_send(struct userdata *u, const bt_audio_msg_header_t *msg)
132 length = msg->length ? msg->length : BT_SUGGESTED_BUFFER_SIZE;
134 DBG("sending %s:%s", bt_audio_strtype(msg->type),
135 bt_audio_strname(msg->name));
137 if (send(u->service_fd, msg, length, 0) > 0)
141 ERR("Error sending data to audio service: %s(%d)",
142 strerror(-err), -err);
148 static int service_recv(struct userdata *u, bt_audio_msg_header_t *rsp)
151 const char *type, *name;
156 length = rsp->length ? : BT_SUGGESTED_BUFFER_SIZE;
158 DBG("trying to receive msg from audio service...");
159 if (recv(u->service_fd, rsp, length, 0) > 0) {
160 type = bt_audio_strtype(rsp->type);
161 name = bt_audio_strname(rsp->name);
163 DBG("Received %s - %s", type, name);
167 ERR("Bogus message type %d - name %d"
168 "received from audio service",
169 rsp->type, rsp->name);
173 ERR("Error receiving data from audio service: %s(%d)",
174 strerror(-err), -err);
180 static ssize_t service_expect(struct userdata *u, bt_audio_msg_header_t *rsp,
181 uint8_t expected_name)
186 assert(u->service_fd >= 0);
189 if ((r = service_recv(u, rsp)) < 0)
192 if ((rsp->type != BT_INDICATION && rsp->type != BT_RESPONSE) ||
193 (rsp->name != expected_name)) {
194 if (rsp->type == BT_ERROR && rsp->length == sizeof(bt_audio_error_t))
195 ERR("Received error condition: %s",
196 strerror(((bt_audio_error_t*) rsp)->posix_errno));
198 ERR("Bogus message %s received while %s was expected",
199 bt_audio_strname(rsp->name),
200 bt_audio_strname(expected_name));
207 static int init_bt(struct userdata *u)
211 if (u->service_fd != -1)
214 DBG("bt_audio_service_open");
216 u->service_fd = bt_audio_service_open();
217 if (u->service_fd < 0) {
220 ERR("bt_audio_service_open() failed: %s (%d)", strerror(-err),
229 static int parse_caps(struct userdata *u, const struct bt_get_capabilities_rsp *rsp)
233 codec_capabilities_t codec;
238 bytes_left = rsp->h.length - sizeof(*rsp);
240 if (bytes_left < sizeof(codec_capabilities_t)) {
241 ERR("Packet too small to store codec information.");
245 ptr = ((void *) rsp) + sizeof(*rsp);
247 memcpy(&codec, ptr, sizeof(codec)); /** ALIGNMENT? **/
249 DBG("Payload size is %lu %lu",
250 (unsigned long) bytes_left, (unsigned long) sizeof(codec));
252 if (u->transport != codec.transport) {
253 ERR("Got capabilities for wrong codec.");
257 if (u->transport == BT_CAPABILITIES_TRANSPORT_SCO) {
259 if (bytes_left <= 0 ||
260 codec.length != sizeof(u->hsp.pcm_capabilities))
263 assert(codec.type == BT_HFP_CODEC_PCM);
265 memcpy(&u->hsp.pcm_capabilities,
266 &codec, sizeof(u->hsp.pcm_capabilities));
269 YES_NO(u->hsp.pcm_capabilities.flags & BT_PCM_FLAG_NREC));
271 } else if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP) {
273 while (bytes_left > 0) {
274 if (codec.type == BT_A2DP_SBC_SINK &&
275 !(codec.lock & BT_WRITE_LOCK))
278 bytes_left -= codec.length;
280 memcpy(&codec, ptr, sizeof(codec));
283 DBG("bytes_left = %d, codec.length = %d",
284 bytes_left, codec.length);
286 if (bytes_left <= 0 ||
287 codec.length != sizeof(u->a2dp.sbc_capabilities))
290 assert(codec.type == BT_A2DP_SBC_SINK);
292 memcpy(&u->a2dp.sbc_capabilities, &codec,
293 sizeof(u->a2dp.sbc_capabilities));
301 static int get_caps(struct userdata *u)
304 struct bt_get_capabilities_req getcaps_req;
305 struct bt_get_capabilities_rsp getcaps_rsp;
306 bt_audio_error_t error;
307 uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
312 memset(&msg, 0, sizeof(msg));
313 msg.getcaps_req.h.type = BT_REQUEST;
314 msg.getcaps_req.h.name = BT_GET_CAPABILITIES;
315 msg.getcaps_req.h.length = sizeof(msg.getcaps_req);
317 strncpy(msg.getcaps_req.destination, u->address,
318 sizeof(msg.getcaps_req.destination));
319 msg.getcaps_req.transport = u->transport;
320 msg.getcaps_req.flags = BT_FLAG_AUTOCONNECT;
322 if (service_send(u, &msg.getcaps_req.h) < 0)
325 msg.getcaps_rsp.h.length = 0;
326 if (service_expect(u, &msg.getcaps_rsp.h, BT_GET_CAPABILITIES) < 0)
329 return parse_caps(u, &msg.getcaps_rsp);
332 static uint8_t a2dp_default_bitpool(uint8_t freq, uint8_t mode)
335 case BT_SBC_SAMPLING_FREQ_16000:
336 case BT_SBC_SAMPLING_FREQ_32000:
339 case BT_SBC_SAMPLING_FREQ_44100:
342 case BT_A2DP_CHANNEL_MODE_MONO:
343 case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
346 case BT_A2DP_CHANNEL_MODE_STEREO:
347 case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
351 DBG("Invalid channel mode %u", mode);
355 case BT_SBC_SAMPLING_FREQ_48000:
358 case BT_A2DP_CHANNEL_MODE_MONO:
359 case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
362 case BT_A2DP_CHANNEL_MODE_STEREO:
363 case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
367 DBG("Invalid channel mode %u", mode);
372 DBG("Invalid sampling freq %u", freq);
377 static int setup_a2dp(struct userdata *u)
379 sbc_capabilities_t *cap;
382 static const struct {
386 { 16000U, BT_SBC_SAMPLING_FREQ_16000 },
387 { 32000U, BT_SBC_SAMPLING_FREQ_32000 },
388 { 44100U, BT_SBC_SAMPLING_FREQ_44100 },
389 { 48000U, BT_SBC_SAMPLING_FREQ_48000 }
393 assert(u->transport == BT_CAPABILITIES_TRANSPORT_A2DP);
395 cap = &u->a2dp.sbc_capabilities;
397 /* Find the lowest freq that is at least as high as the requested
399 for (i = 0; (unsigned) i < ARRAY_SIZE(freq_table); i++)
400 if (freq_table[i].rate >= u->rate &&
401 (cap->frequency & freq_table[i].cap)) {
402 u->rate = freq_table[i].rate;
403 cap->frequency = freq_table[i].cap;
407 if ((unsigned) i >= ARRAY_SIZE(freq_table)) {
408 for (; i >= 0; i--) {
409 if (cap->frequency & freq_table[i].cap) {
410 u->rate = freq_table[i].rate;
411 cap->frequency = freq_table[i].cap;
417 DBG("Not suitable sample rate");
422 if (u->channels <= 1) {
423 if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
424 cap->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
430 if (u->channels >= 2) {
433 if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO)
434 cap->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
435 else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO)
436 cap->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO;
437 else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL)
438 cap->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
439 else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
440 cap->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
443 DBG("No supported channel modes");
448 if (cap->block_length & BT_A2DP_BLOCK_LENGTH_16)
449 cap->block_length = BT_A2DP_BLOCK_LENGTH_16;
450 else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_12)
451 cap->block_length = BT_A2DP_BLOCK_LENGTH_12;
452 else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_8)
453 cap->block_length = BT_A2DP_BLOCK_LENGTH_8;
454 else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_4)
455 cap->block_length = BT_A2DP_BLOCK_LENGTH_4;
457 DBG("No supported block lengths");
461 if (cap->subbands & BT_A2DP_SUBBANDS_8)
462 cap->subbands = BT_A2DP_SUBBANDS_8;
463 else if (cap->subbands & BT_A2DP_SUBBANDS_4)
464 cap->subbands = BT_A2DP_SUBBANDS_4;
466 DBG("No supported subbands");
470 if (cap->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS)
471 cap->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS;
472 else if (cap->allocation_method & BT_A2DP_ALLOCATION_SNR)
473 cap->allocation_method = BT_A2DP_ALLOCATION_SNR;
475 cap->min_bitpool = (uint8_t) MAX(MIN_BITPOOL, cap->min_bitpool);
476 cap->max_bitpool = (uint8_t) MIN(
477 a2dp_default_bitpool(cap->frequency, cap->channel_mode),
483 static void setup_sbc(struct a2dp_info *a2dp)
485 sbc_capabilities_t *active_capabilities;
489 active_capabilities = &a2dp->sbc_capabilities;
491 if (a2dp->sbc_initialized)
492 sbc_reinit(&a2dp->sbc, 0);
494 sbc_init(&a2dp->sbc, 0);
495 a2dp->sbc_initialized = TRUE;
497 switch (active_capabilities->frequency) {
498 case BT_SBC_SAMPLING_FREQ_16000:
499 a2dp->sbc.frequency = SBC_FREQ_16000;
501 case BT_SBC_SAMPLING_FREQ_32000:
502 a2dp->sbc.frequency = SBC_FREQ_32000;
504 case BT_SBC_SAMPLING_FREQ_44100:
505 a2dp->sbc.frequency = SBC_FREQ_44100;
507 case BT_SBC_SAMPLING_FREQ_48000:
508 a2dp->sbc.frequency = SBC_FREQ_48000;
514 switch (active_capabilities->channel_mode) {
515 case BT_A2DP_CHANNEL_MODE_MONO:
516 a2dp->sbc.mode = SBC_MODE_MONO;
518 case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
519 a2dp->sbc.mode = SBC_MODE_DUAL_CHANNEL;
521 case BT_A2DP_CHANNEL_MODE_STEREO:
522 a2dp->sbc.mode = SBC_MODE_STEREO;
524 case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
525 a2dp->sbc.mode = SBC_MODE_JOINT_STEREO;
531 switch (active_capabilities->allocation_method) {
532 case BT_A2DP_ALLOCATION_SNR:
533 a2dp->sbc.allocation = SBC_AM_SNR;
535 case BT_A2DP_ALLOCATION_LOUDNESS:
536 a2dp->sbc.allocation = SBC_AM_LOUDNESS;
542 switch (active_capabilities->subbands) {
543 case BT_A2DP_SUBBANDS_4:
544 a2dp->sbc.subbands = SBC_SB_4;
546 case BT_A2DP_SUBBANDS_8:
547 a2dp->sbc.subbands = SBC_SB_8;
553 switch (active_capabilities->block_length) {
554 case BT_A2DP_BLOCK_LENGTH_4:
555 a2dp->sbc.blocks = SBC_BLK_4;
557 case BT_A2DP_BLOCK_LENGTH_8:
558 a2dp->sbc.blocks = SBC_BLK_8;
560 case BT_A2DP_BLOCK_LENGTH_12:
561 a2dp->sbc.blocks = SBC_BLK_12;
563 case BT_A2DP_BLOCK_LENGTH_16:
564 a2dp->sbc.blocks = SBC_BLK_16;
570 a2dp->sbc.bitpool = active_capabilities->max_bitpool;
571 a2dp->codesize = (uint16_t) sbc_get_codesize(&a2dp->sbc);
574 static int bt_open(struct userdata *u)
577 struct bt_open_req open_req;
578 struct bt_open_rsp open_rsp;
579 bt_audio_error_t error;
580 uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
583 memset(&msg, 0, sizeof(msg));
584 msg.open_req.h.type = BT_REQUEST;
585 msg.open_req.h.name = BT_OPEN;
586 msg.open_req.h.length = sizeof(msg.open_req);
588 strncpy(msg.open_req.destination, u->address,
589 sizeof(msg.open_req.destination));
590 msg.open_req.seid = u->transport == BT_CAPABILITIES_TRANSPORT_A2DP ?
591 u->a2dp.sbc_capabilities.capability.seid :
592 BT_A2DP_SEID_RANGE + 1;
593 msg.open_req.lock = u->transport == BT_CAPABILITIES_TRANSPORT_A2DP ?
594 BT_WRITE_LOCK : BT_READ_LOCK | BT_WRITE_LOCK;
596 if (service_send(u, &msg.open_req.h) < 0)
599 msg.open_rsp.h.length = sizeof(msg.open_rsp);
600 if (service_expect(u, &msg.open_rsp.h, BT_OPEN) < 0)
606 static int set_conf(struct userdata *u)
609 struct bt_set_configuration_req setconf_req;
610 struct bt_set_configuration_rsp setconf_rsp;
611 bt_audio_error_t error;
612 uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
615 if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP) {
616 if (setup_a2dp(u) < 0)
620 memset(&msg, 0, sizeof(msg));
621 msg.setconf_req.h.type = BT_REQUEST;
622 msg.setconf_req.h.name = BT_SET_CONFIGURATION;
623 msg.setconf_req.h.length = sizeof(msg.setconf_req);
625 if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP) {
626 memcpy(&msg.setconf_req.codec, &u->a2dp.sbc_capabilities,
627 sizeof(u->a2dp.sbc_capabilities));
628 msg.setconf_req.h.length += msg.setconf_req.codec.length -
629 sizeof(msg.setconf_req.codec);
631 msg.setconf_req.codec.transport = BT_CAPABILITIES_TRANSPORT_SCO;
632 msg.setconf_req.codec.seid = BT_A2DP_SEID_RANGE + 1;
633 msg.setconf_req.codec.length = sizeof(pcm_capabilities_t);
636 if (service_send(u, &msg.setconf_req.h) < 0)
639 msg.setconf_rsp.h.length = sizeof(msg.setconf_rsp);
640 if (service_expect(u, &msg.setconf_rsp.h, BT_SET_CONFIGURATION) < 0)
643 u->link_mtu = msg.setconf_rsp.link_mtu;
645 /* setup SBC encoder now we agree on parameters */
646 if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP) {
648 u->block_size = u->a2dp.codesize;
649 DBG("SBC parameters:\n\tallocation=%u\n"
650 "\tsubbands=%u\n\tblocks=%u\n\tbitpool=%u\n",
651 u->a2dp.sbc.allocation, u->a2dp.sbc.subbands,
652 u->a2dp.sbc.blocks, u->a2dp.sbc.bitpool);
654 u->block_size = u->link_mtu;
659 static int setup_bt(struct userdata *u)
666 DBG("Got device caps");
677 static int init_profile(struct userdata *u)
684 static void shutdown_bt(struct userdata *u)
688 if (u->stream_fd != -1) {
690 DBG("close(stream_fd)");
695 if (u->service_fd != -1) {
696 DBG("bt_audio_service_close");
697 bt_audio_service_close(u->service_fd);
702 static void make_fd_nonblock(int fd)
707 assert((v = fcntl(fd, F_GETFL)) >= 0);
709 if (!(v & O_NONBLOCK))
710 assert(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0);
713 static void make_socket_low_delay(int fd)
715 /* FIXME: is this widely supported? */
721 if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority,
722 sizeof(priority)) < 0)
723 ERR("SO_PRIORITY failed: %s", strerror(errno));
727 static int read_stream(struct userdata *u)
734 assert(u->stream_fd >= 0);
736 buf = alloca(u->link_mtu);
739 l = read(u->stream_fd, buf, u->link_mtu);
740 if (u->debug_stream_read)
741 DBG("read from socket: %lli bytes", (long long) l);
743 if (l < 0 && errno == EINTR)
746 ERR("Failed to read date from stream_fd: %s",
747 ret < 0 ? strerror(errno) : "EOF");
758 /* It's what PulseAudio is doing, not sure it's necessary for this
760 static ssize_t pa_write(int fd, const void *buf, size_t count)
764 if ((r = send(fd, buf, count, MSG_NOSIGNAL)) >= 0)
767 if (errno != ENOTSOCK)
770 return write(fd, buf, count);
773 static int write_stream(struct userdata *u)
780 assert(u->stream_fd >= 0);
781 buf = alloca(u->link_mtu);
784 l = pa_write(u->stream_fd, buf, u->link_mtu);
785 if (u->debug_stream_write)
786 DBG("written to socket: %lli bytes", (long long) l);
792 ERR("Failed to write data: %s", strerror(errno));
797 assert((size_t)l <= u->link_mtu);
805 static gboolean stream_cb(GIOChannel *gin, GIOCondition condition, gpointer data)
811 if (condition & G_IO_IN) {
812 if (read_stream(u) < 0)
814 } else if (condition & G_IO_OUT) {
815 if (write_stream(u) < 0)
818 DBG("Got %d", condition);
819 g_main_loop_quit(main_loop);
830 static int start_stream(struct userdata *u)
833 bt_audio_msg_header_t rsp;
834 struct bt_start_stream_req start_req;
835 struct bt_start_stream_rsp start_rsp;
836 struct bt_new_stream_ind streamfd_ind;
837 bt_audio_error_t error;
838 uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
843 if (u->stream_fd >= 0)
845 if (u->stream_watch != 0) {
846 g_source_remove(u->stream_watch);
849 if (u->stream_channel != 0) {
850 g_io_channel_unref(u->stream_channel);
851 u->stream_channel = NULL;
854 memset(msg.buf, 0, BT_SUGGESTED_BUFFER_SIZE);
855 msg.start_req.h.type = BT_REQUEST;
856 msg.start_req.h.name = BT_START_STREAM;
857 msg.start_req.h.length = sizeof(msg.start_req);
859 if (service_send(u, &msg.start_req.h) < 0)
862 msg.rsp.length = sizeof(msg.start_rsp);
863 if (service_expect(u, &msg.rsp, BT_START_STREAM) < 0)
866 msg.rsp.length = sizeof(msg.streamfd_ind);
867 if (service_expect(u, &msg.rsp, BT_NEW_STREAM) < 0)
870 if ((u->stream_fd = bt_audio_service_get_data_fd(u->service_fd)) < 0) {
871 DBG("Failed to get stream fd from audio service.");
875 make_fd_nonblock(u->stream_fd);
876 make_socket_low_delay(u->stream_fd);
878 assert(u->stream_channel = g_io_channel_unix_new(u->stream_fd));
880 u->stream_watch = g_io_add_watch(u->stream_channel,
881 G_IO_IN|G_IO_OUT|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
887 static int stop_stream(struct userdata *u)
890 bt_audio_msg_header_t rsp;
891 struct bt_stop_stream_req stop_req;
892 struct bt_stop_stream_rsp stop_rsp;
893 bt_audio_error_t error;
894 uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
898 if (u->stream_fd < 0)
902 assert(u->stream_channel);
904 g_source_remove(u->stream_watch);
906 g_io_channel_unref(u->stream_channel);
907 u->stream_channel = NULL;
909 memset(msg.buf, 0, BT_SUGGESTED_BUFFER_SIZE);
910 msg.stop_req.h.type = BT_REQUEST;
911 msg.stop_req.h.name = BT_STOP_STREAM;
912 msg.stop_req.h.length = sizeof(msg.stop_req);
914 if (service_send(u, &msg.stop_req.h) < 0) {
919 msg.rsp.length = sizeof(msg.stop_rsp);
920 if (service_expect(u, &msg.rsp, BT_STOP_STREAM) < 0)
930 static gboolean sleep_cb(gpointer data)
936 u->gin_watch = g_io_add_watch(u->gin,
937 G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, input_cb, data);
945 static gboolean input_cb(GIOChannel *gin, GIOCondition condition, gpointer data)
949 GError *error = NULL;
954 if (!(condition & G_IO_IN)) {
955 DBG("Got %d", condition);
956 g_main_loop_quit(main_loop);
960 if (g_io_channel_read_line(gin, &line, NULL, &term_pos, &error) !=
964 line[term_pos] = '\0';
966 if ((tmp = strchr(line, '#')))
970 #define IF_CMD(cmd) \
971 if (!success && (success = (strncmp(line, #cmd, strlen(#cmd)) == 0)))
974 g_main_loop_quit(main_loop);
979 unsigned int seconds;
980 if (sscanf(line, "%*s %d", &seconds) != 1)
981 DBG("sleep SECONDS");
983 g_source_remove(u->gin_watch);
984 g_timeout_add_seconds(seconds, sleep_cb, u);
993 if (sscanf(line, "%*s %as %d", &what, &enable) != 1)
994 DBG("debug [stream_read|stream_write] [0|1]");
995 if (strncmp(what, "stream_read", 12) == 0) {
996 u->debug_stream_read = enable;
997 } else if (strncmp(what, "stream_write", 13) == 0) {
998 u->debug_stream_write = enable;
1000 DBG("debug [stream_read|stream_write] [0|1]");
1005 DBG("%d", init_bt(u));
1008 IF_CMD(init_profile) {
1009 DBG("%d", init_profile(u));
1012 IF_CMD(start_stream) {
1013 DBG("%d", start_stream(u));
1016 IF_CMD(stop_stream) {
1017 DBG("%d", stop_stream(u));
1020 IF_CMD(shutdown_bt) {
1025 if (sscanf(line, "%*s %d", &u->rate) != 1)
1026 DBG("set with rate RATE");
1027 DBG("rate %d", u->rate);
1033 if (sscanf(line, "%*s %as", &address) != 1)
1034 DBG("set with bdaddr BDADDR");
1038 u->address = address;
1039 DBG("bdaddr %s", u->address);
1043 char *profile = NULL;
1045 if (sscanf(line, "%*s %as", &profile) != 1)
1046 DBG("set with profile [hsp|a2dp]");
1047 if (strncmp(profile, "hsp", 4) == 0) {
1048 u->transport = BT_CAPABILITIES_TRANSPORT_SCO;
1049 } else if (strncmp(profile, "a2dp", 5) == 0) {
1050 u->transport = BT_CAPABILITIES_TRANSPORT_A2DP;
1052 DBG("set with profile [hsp|a2dp]");
1056 DBG("profile %s", u->transport == BT_CAPABILITIES_TRANSPORT_SCO ?
1060 if (!success && strlen(line) != 0) {
1061 DBG("%s, unknown command", line);
1070 static void show_usage(char* prgname)
1072 printf("%s: ipctest [--interactive] BDADDR\n", basename(prgname));
1075 static void sig_term(int sig)
1077 g_main_loop_quit(main_loop);
1080 int main(int argc, char *argv[])
1083 show_usage(argv[0]);
1087 assert(main_loop = g_main_loop_new(NULL, FALSE));
1089 if (strncmp("--interactive", argv[1], 14) == 0) {
1091 show_usage(argv[0]);
1095 data.address = strdup(argv[2]);
1097 signal(SIGTERM, sig_term);
1098 signal(SIGINT, sig_term);
1100 assert(data.gin = g_io_channel_unix_new(fileno(stdin)));
1102 data.gin_watch = g_io_add_watch(data.gin,
1103 G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, input_cb, &data);
1108 g_main_loop_run(main_loop);
1111 data.address = strdup(argv[1]);
1113 assert(init_bt(&data) == 0);
1115 assert(init_profile(&data) == 0);
1117 assert(start_stream(&data) == 0);
1119 g_main_loop_run(main_loop);
1121 assert(stop_stream(&data) == 0);
1126 g_main_loop_unref(main_loop);
1128 printf("\nExiting\n");