From b3bf67571f931cf26b697841350612930d4a9862 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 23 May 2016 13:57:53 +0200 Subject: [PATCH 1/4] libusb: use more transfers for isochronous data --- port/libusb/hci_transport_h2_libusb.c | 42 ++++++++++++++++----------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/port/libusb/hci_transport_h2_libusb.c b/port/libusb/hci_transport_h2_libusb.c index 216328451..ae84b6084 100644 --- a/port/libusb/hci_transport_h2_libusb.c +++ b/port/libusb/hci_transport_h2_libusb.c @@ -69,11 +69,13 @@ #define HAVE_USB_VENDOR_ID_AND_PRODUCT_ID #endif -#define ASYNC_BUFFERS 2 -#define AYSNC_POLLING_INTERVAL_MS 1 +#define ASYNC_BUFFERS 3 +#define ISOC_BUFFERS 10 + +#define ASYNC_POLLING_INTERVAL_MS 1 // -// Bluetooth USB Transprot Alternate Settings: +// Bluetooth USB Transport Alternate Settings: // // 0: No active voice channels (for USB compliance) // 1: One 8 kHz voice channel with 8-bit encoding @@ -147,8 +149,8 @@ static H2_SCO_STATE sco_state; static uint8_t sco_buffer[255+3 + SCO_PACKET_SIZE]; static uint16_t sco_read_pos; static uint16_t sco_bytes_to_read; -static struct libusb_transfer *sco_in_transfer[ASYNC_BUFFERS]; -static uint8_t hci_sco_in_buffer[ASYNC_BUFFERS][SCO_PACKET_SIZE]; +static struct libusb_transfer *sco_in_transfer[ISOC_BUFFERS]; +static uint8_t hci_sco_in_buffer[ISOC_BUFFERS][SCO_PACKET_SIZE]; // outgoing SCO static uint8_t sco_ring_buffer[SCO_RING_BUFFER_SIZE]; @@ -439,7 +441,7 @@ static void usb_process_ts(btstack_timer_source_t *timer) { usb_process_ds((struct btstack_data_source *) NULL, DATA_SOURCE_CALLBACK_READ); // Get the amount of time until next event is due - long msec = AYSNC_POLLING_INTERVAL_MS; + long msec = ASYNC_POLLING_INTERVAL_MS; // Activate timer btstack_run_loop_set_timer(&usb_timer, msec); @@ -774,7 +776,7 @@ static int usb_open(void){ #ifdef ENABLE_SCO_OVER_HCI // incoming - for (c = 0 ; c < ASYNC_BUFFERS ; c++) { + for (c = 0 ; c < ISOC_BUFFERS ; c++) { sco_in_transfer[c] = libusb_alloc_transfer(NUM_ISO_PACKETS); // isochronous transfers SCO in log_info("Alloc iso transfer"); if (!sco_in_transfer[c]) { @@ -853,7 +855,7 @@ static int usb_open(void){ log_info("Async using timers:"); usb_timer.process = usb_process_ts; - btstack_run_loop_set_timer(&usb_timer, AYSNC_POLLING_INTERVAL_MS); + btstack_run_loop_set_timer(&usb_timer, ASYNC_POLLING_INTERVAL_MS); btstack_run_loop_add_timer(&usb_timer); usb_timer_active = 1; } @@ -882,10 +884,13 @@ static int usb_close(void){ for (c = 0 ; c < ASYNC_BUFFERS ; c++) { libusb_cancel_transfer(event_in_transfer[c]); libusb_cancel_transfer(acl_in_transfer[c]); -#ifdef ENABLE_SCO_OVER_HCI - libusb_cancel_transfer(sco_in_transfer[c]); -#endif } +#ifdef ENABLE_SCO_OVER_HCI + // Cancel all synchronous transfer + for (c = 0 ; c < ISOC_BUFFERS ; c++) { + libusb_cancel_transfer(sco_in_transfer[c]); + } +#endif /* TODO - find a better way to ensure that all transfers have completed */ struct timeval tv; @@ -905,16 +910,19 @@ static int usb_close(void){ } case LIB_USB_INTERFACE_CLAIMED: + // Cancel any asynchronous transfers for (c = 0 ; c < ASYNC_BUFFERS ; c++) { - if (event_in_transfer[c]) libusb_free_transfer(event_in_transfer[c]); - if (acl_in_transfer[c]) libusb_free_transfer(acl_in_transfer[c]); -#ifdef ENABLE_SCO_OVER_HCI - if (sco_in_transfer[c]) libusb_free_transfer(sco_in_transfer[c]); -#endif + libusb_cancel_transfer(event_in_transfer[c]); + libusb_cancel_transfer(acl_in_transfer[c]); } +#ifdef ENABLE_SCO_OVER_HCI + // Cancel all synchronous transfer + for (c = 0 ; c < ISOC_BUFFERS ; c++) { + libusb_cancel_transfer(sco_in_transfer[c]); + } +#endif // TODO free control and acl out transfers - libusb_release_interface(handle, 0); case LIB_USB_DEVICE_OPENDED: From 47c58a2a6e7c34a530f98c9c35883c5cdaaabde7 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 23 May 2016 18:02:21 +0200 Subject: [PATCH 2/4] posix-h4: disable ehcill - sleep mode entered while data transferred via SCO-via-HCI --- port/posix-h4/btstack_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port/posix-h4/btstack_config.h b/port/posix-h4/btstack_config.h index 34d701205..c37cb3ab3 100644 --- a/port/posix-h4/btstack_config.h +++ b/port/posix-h4/btstack_config.h @@ -19,7 +19,7 @@ #define ENABLE_LOG_INTO_HCI_DUMP #define ENABLE_SCO_OVER_HCI #define ENABLE_SDP_DES_DUMP -#define ENABLE_EHCILL +// #define ENABLE_EHCILL // BTstack configuration. buffers, sizes, ... #define HCI_INCOMING_PRE_BUFFER_SIZE 14 // sizeof benep heade, avoid memcpy From 185c8cd41d180fc243951d3e0fbaa89088e1c73b Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 23 May 2016 18:03:11 +0200 Subject: [PATCH 3/4] example/hsp+hfp: extract SCO test code into sco_demo_util --- example/Makefile.inc | 8 +++---- example/hfp_ag_demo.c | 54 ++++++++---------------------------------- example/hfp_hf_demo.c | 30 ++++++++++++++++++++--- example/hsp_ag_demo.c | 52 ++++------------------------------------ example/hsp_hs_demo.c | 52 ++++------------------------------------ port/libusb/Makefile | 7 ++++++ port/posix-h4/Makefile | 10 +++++++- port/posix-h5/Makefile | 7 ++++++ 8 files changed, 74 insertions(+), 146 deletions(-) diff --git a/example/Makefile.inc b/example/Makefile.inc index c0eed68e9..e8f4a25e8 100644 --- a/example/Makefile.inc +++ b/example/Makefile.inc @@ -160,16 +160,16 @@ led_counter: ${CORE_OBJ} ${COMMON_OBJ} led_counter.c gap_le_advertisements: ${CORE_OBJ} ${COMMON_OBJ} ad_parser.c gap_le_advertisements.c ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ -hsp_hs_demo: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} hsp_hs.o hsp_hs_demo.c +hsp_hs_demo: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} sco_demo_util.o hsp_hs.o hsp_hs_demo.c ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ -hsp_ag_demo: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} hsp_ag.o hsp_ag_demo.c +hsp_ag_demo: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} sco_demo_util.o hsp_ag.o hsp_ag_demo.c ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ -hfp_ag_demo: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} hfp.o hfp_gsm_model.o hfp_ag.o hfp_ag_demo.c +hfp_ag_demo: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} sco_demo_util.o hfp.o hfp_gsm_model.o hfp_ag.o hfp_ag_demo.c ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ -hfp_hf_demo: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} hfp.o hfp_hf.o hfp_hf_demo.c +hfp_hf_demo: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} sco_demo_util.o hfp.o hfp_hf.o hfp_hf_demo.c ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ clean: diff --git a/example/hfp_ag_demo.c b/example/hfp_ag_demo.c index 4a9234bb4..352241a8c 100644 --- a/example/hfp_ag_demo.c +++ b/example/hfp_ag_demo.c @@ -56,22 +56,11 @@ #include #include "btstack.h" +#include "sco_demo_util.h" #ifdef HAVE_POSIX_STDIN #include "stdin_support.h" #endif - -static int phase = 0; - -// input signal: pre-computed sine wave, 160 Hz -static const uint8_t sine[] = { - 0, 15, 31, 46, 61, 74, 86, 97, 107, 114, - 120, 124, 126, 126, 124, 120, 114, 107, 97, 86, - 74, 61, 46, 31, 15, 0, 241, 225, 210, 195, - 182, 170, 159, 149, 142, 136, 132, 130, 130, 132, - 136, 142, 149, 159, 170, 182, 195, 210, 225, 241, -}; - uint8_t hfp_service_buffer[150]; const uint8_t rfcomm_channel_nr = 1; const char hfp_ag_service_name[] = "BTstack HFP AG Test"; @@ -79,7 +68,9 @@ const char hfp_ag_service_name[] = "BTstack HFP AG Test"; // PTS // static bd_addr_t device_addr = {0x00,0x15,0x83,0x5F,0x9D,0x46}; // BT-201 -static bd_addr_t device_addr = {0x00, 0x07, 0xB0, 0x83, 0x02, 0x5E}; +// static bd_addr_t device_addr = {0x00, 0x07, 0xB0, 0x83, 0x02, 0x5E}; +// CC256x +bd_addr_t device_addr = { 0xD0, 0x39, 0x72, 0xCD, 0x83, 0x45}; static uint8_t codecs[1] = {HFP_CODEC_CVSD}; static uint16_t handle = -1; @@ -565,36 +556,6 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac } #endif -#define SCO_REPORT_PERIOD 100 -static void send_sco_data(void){ - if (!sco_handle) return; - - const int sco_packet_length = hci_get_sco_packet_length(); - const int sco_payload_length = sco_packet_length - 3; - const int frames_per_packet = sco_payload_length; // for 8-bit data. for 16-bit data it's /2 - - hci_reserve_packet_buffer(); - uint8_t * sco_packet = hci_get_outgoing_packet_buffer(); - // set handle + flags - little_endian_store_16(sco_packet, 0, sco_handle); - // set len - sco_packet[2] = sco_payload_length; - int i; - for (i=0;i= sizeof(sine)) phase = 0; - } - hci_send_sco_packet_buffer(sco_packet_length); - - // request another send event - hci_request_sco_can_send_now_event(); - - static int count = 0; - count++; - if ((count % SCO_REPORT_PERIOD) == 0) printf("Sent %u\n", count); -} - static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){ switch (packet_type){ case HCI_EVENT_PACKET: @@ -606,7 +567,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even inquiry_packet_handler(HCI_EVENT_PACKET, event, event_size); break; case HCI_EVENT_SCO_CAN_SEND_NOW: - send_sco_data(); + sco_demo_send(sco_handle); break; default: break; @@ -680,6 +641,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even printf("Event not handled %u\n", event[2]); break; } + case HCI_SCO_DATA_PACKET: + sco_demo_receive(event, event_size); + break; default: break; } @@ -703,6 +667,8 @@ static hfp_phone_number_t subscriber_number = { int btstack_main(int argc, const char * argv[]); int btstack_main(int argc, const char * argv[]){ + sco_demo_init(); + gap_discoverable_control(1); // L2CAP diff --git a/example/hfp_hf_demo.c b/example/hfp_hf_demo.c index 693d07e10..eb5453386 100644 --- a/example/hfp_hf_demo.c +++ b/example/hfp_hf_demo.c @@ -59,20 +59,24 @@ #include #include "btstack.h" +#include "sco_demo_util.h" #ifdef HAVE_POSIX_STDIN #include "stdin_support.h" #endif + uint8_t hfp_service_buffer[150]; const uint8_t rfcomm_channel_nr = 1; const char hfp_hf_service_name[] = "BTstack HFP HF Demo"; #ifdef HAVE_POSIX_STDIN -static bd_addr_t device_addr = {0xD8,0xBb,0x2C,0xDf,0xF1,0x08}; +static bd_addr_t device_addr = {0x80,0xbe,0x05,0xd5,0x28,0x48}; +// 80:BE:05:D5:28:48 // prototypes static void show_usage(void); #endif static uint16_t handle = -1; +static hci_con_handle_t sco_handle; static uint8_t codecs[] = {HFP_CODEC_CVSD, HFP_CODEC_MSBC}; static uint16_t indicators[1] = {0x01}; @@ -445,6 +449,12 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac #endif static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){ + + if (event[0] == HCI_EVENT_SCO_CAN_SEND_NOW){ + sco_demo_send(sco_handle); + return; + } + if (event[0] != HCI_EVENT_HFP_META) return; switch (event[2]) { @@ -456,10 +466,18 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even printf("Service level connection released.\n\n"); break; case HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED: - printf("\n** Audio connection established **\n"); + if (hfp_subevent_audio_connection_established_get_status(event)){ + sco_handle = 0; + printf("Audio connection establishment failed with status %u\n", hfp_subevent_audio_connection_established_get_status(event)); + } else { + sco_handle = hfp_subevent_audio_connection_established_get_handle(event); + printf("Audio connection established with SCO handle 0x%04x.\n", sco_handle); + hci_request_sco_can_send_now_event(); + } break; case HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED: - printf("\n** Audio connection released **\n"); + sco_handle = 0; + printf("Audio connection released\n"); break; case HFP_SUBEVENT_COMPLETE: switch (cmd){ @@ -512,6 +530,11 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even /* LISTING_START(MainConfiguration): Setup HFP Hands-Free unit */ int btstack_main(int argc, const char * argv[]); int btstack_main(int argc, const char * argv[]){ + + sco_demo_init(); + + gap_discoverable_control(1); + // HFP AG address is hardcoded, please change it // init L2CAP l2cap_init(); @@ -524,6 +547,7 @@ int btstack_main(int argc, const char * argv[]){ hfp_hf_init_codecs(sizeof(codecs), codecs); hfp_hf_register_packet_handler(packet_handler); + hci_register_sco_packet_handler(&packet_handler); memset(hfp_service_buffer, 0, sizeof(hfp_service_buffer)); hfp_hf_create_sdp_record(hfp_service_buffer, 0x10001, rfcomm_channel_nr, hfp_hf_service_name, 0); diff --git a/example/hsp_ag_demo.c b/example/hsp_ag_demo.c index e6fe0ac31..da1fb078f 100644 --- a/example/hsp_ag_demo.c +++ b/example/hsp_ag_demo.c @@ -59,12 +59,11 @@ #include #include "btstack.h" +#include "sco_demo_util.h" #ifdef HAVE_POSIX_STDIN #include "stdin_support.h" #endif -#define SCO_REPORT_PERIOD 255 - static uint8_t hsp_service_buffer[150]; static const uint8_t rfcomm_channel_nr = 1; static const char hsp_ag_service_name[] = "Audio Gateway Test"; @@ -74,17 +73,6 @@ static char hs_cmd_buffer[100]; static bd_addr_t device_addr = {0x00,0x1b,0xDC,0x07,0x32,0xEF}; -static int phase = 0; - -// input signal: pre-computed sine wave, 160 Hz -static const uint8_t sine[] = { - 0, 15, 31, 46, 61, 74, 86, 97, 107, 114, - 120, 124, 126, 126, 124, 120, 114, 107, 97, 86, - 74, 61, 46, 31, 15, 0, 241, 225, 210, 195, - 182, 170, 159, 149, 142, 136, 132, 130, 130, 132, - 136, 142, 149, 159, 170, 182, 195, 210, 225, 241, -}; - /* @section Audio Transfer Setup * * @text A pre-computed sine wave (160Hz) is used as the input audio signal. 160 Hz. @@ -190,44 +178,12 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac } #endif -static void send_sco_data(void){ - if (!sco_handle) return; - - const int sco_packet_length = hci_get_sco_packet_length(); - const int sco_payload_length = sco_packet_length - 3; - const int frames_per_packet = sco_payload_length; // for 8-bit data. for 16-bit data it's /2 - - hci_reserve_packet_buffer(); - uint8_t * sco_packet = hci_get_outgoing_packet_buffer(); - // set handle + flags - little_endian_store_16(sco_packet, 0, sco_handle); - // set len - sco_packet[2] = sco_payload_length; - int i; - for (i=0;i= sizeof(sine)) phase = 0; - } - hci_send_sco_packet_buffer(sco_packet_length); - - // request another send event - hci_request_sco_can_send_now_event(); - - static int count = 0; - if ((count % SCO_REPORT_PERIOD) == 0) printf("Sent %u\n", count); -} - static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){ - static int count = 0; - switch (packet_type){ case HCI_SCO_DATA_PACKET: - count++; - if ((count & SCO_REPORT_PERIOD)) return; - printf("SCO packets received: %u\n", count); + sco_demo_receive(event, event_size); break; case HCI_EVENT_PACKET: @@ -237,7 +193,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even show_usage(); break; case HCI_EVENT_SCO_CAN_SEND_NOW: - send_sco_data(); + sco_demo_send(sco_handle); break; case HCI_EVENT_HSP_META: switch (event[2]) { @@ -319,6 +275,8 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even int btstack_main(int argc, const char * argv[]); int btstack_main(int argc, const char * argv[]){ + sco_demo_init(); + l2cap_init(); sdp_init(); diff --git a/example/hsp_hs_demo.c b/example/hsp_hs_demo.c index 81aae70fe..4d870f4d0 100644 --- a/example/hsp_hs_demo.c +++ b/example/hsp_hs_demo.c @@ -59,12 +59,11 @@ #include #include "btstack.h" +#include "sco_demo_util.h" #ifdef HAVE_POSIX_STDIN #include "stdin_support.h" #endif -#define SCO_REPORT_PERIOD 255 - static btstack_packet_callback_registration_t hci_event_callback_registration; static uint8_t hsp_service_buffer[150]; @@ -75,17 +74,6 @@ static hci_con_handle_t sco_handle = 0; static char hs_cmd_buffer[100]; static bd_addr_t device_addr = {0x00,0x1b,0xDC,0x07,0x32,0xEF}; -static int phase = 0; - -// input signal: pre-computed sine wave, 160 Hz -static const uint8_t sine[] = { - 0, 15, 31, 46, 61, 74, 86, 97, 107, 114, - 120, 124, 126, 126, 124, 120, 114, 107, 97, 86, - 74, 61, 46, 31, 15, 0, 241, 225, 210, 195, - 182, 170, 159, 149, 142, 136, 132, 130, 130, 132, - 136, 142, 149, 159, 170, 182, 195, 210, 225, 241, -}; - /* @section Audio Transfer Setup * * @text A pre-computed sine wave (160Hz) is used as the input audio signal. 160 Hz. @@ -190,42 +178,10 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac } #endif -static void send_sco_data(void){ - if (!sco_handle) return; - - const int sco_packet_length = hci_get_sco_packet_length(); - const int sco_payload_length = sco_packet_length - 3; - const int frames_per_packet = sco_payload_length; // for 8-bit data. for 16-bit data it's /2 - - hci_reserve_packet_buffer(); - uint8_t * sco_packet = hci_get_outgoing_packet_buffer(); - // set handle + flags - little_endian_store_16(sco_packet, 0, sco_handle); - // set len - sco_packet[2] = sco_payload_length; - int i; - for (i=0;i= sizeof(sine)) phase = 0; - } - hci_send_sco_packet_buffer(sco_packet_length); - - // request another send event - hci_request_sco_can_send_now_event(); - - static int count = 0; - count++; - if ((count % SCO_REPORT_PERIOD) == 0) printf("Sent %u\n", count); -} - static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){ - static int sco_rev_count = 0; switch (packet_type){ case HCI_SCO_DATA_PACKET: - sco_rev_count++; - if ((sco_rev_count & SCO_REPORT_PERIOD)) break; - printf("SCO packets received: %u\n", sco_rev_count); + sco_demo_receive(event, event_size); break; case HCI_EVENT_PACKET: switch (event[0]) { @@ -234,7 +190,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even show_usage(); break; case HCI_EVENT_SCO_CAN_SEND_NOW: - send_sco_data(); + sco_demo_send(sco_handle); break; case HCI_EVENT_HSP_META: switch (event[2]) { @@ -321,6 +277,8 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even int btstack_main(int argc, const char * argv[]); int btstack_main(int argc, const char * argv[]){ + sco_demo_init(); + // register for HCI events hci_event_callback_registration.callback = &packet_handler; hci_add_event_handler(&hci_event_callback_registration); diff --git a/port/libusb/Makefile b/port/libusb/Makefile index a56e8c3a9..340f8f02c 100644 --- a/port/libusb/Makefile +++ b/port/libusb/Makefile @@ -28,4 +28,11 @@ CFLAGS += $(shell pkg-config libusb-1.0 --cflags) LDFLAGS += $(shell pkg-config libusb-1.0 --libs) endif +# use pkg-config for portaudio +# CFLAGS += $(shell pkg-config portaudio-2.0 --cflags) -DHAVE_PORTAUDIO +# LDFLAGS += $(shell pkg-config portaudio-2.0 --libs) +# hard coded flags for portaudio in /usr/local/lib +# CFLAGS += -I/usr/local/include -DHAVE_PORTAUDIO +# LDFLAGS += -L/sw/lib -lportaudio -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,Carbon + all: ${EXAMPLES} diff --git a/port/posix-h4/Makefile b/port/posix-h4/Makefile index 9002a15ad..d407713c3 100644 --- a/port/posix-h4/Makefile +++ b/port/posix-h4/Makefile @@ -2,7 +2,6 @@ BTSTACK_ROOT = ../.. CORE += \ - bluetooth_init_cc2564B_1.4_BT_Spec_4.1.c \ btstack_chipset_cc256x.c \ btstack_chipset_csr.c \ btstack_chipset_em9301.c \ @@ -14,6 +13,8 @@ CORE += \ hci_transport_h4.c \ main.c \ stdin_support.c \ + bluetooth_init_cc2564B_1.4_BT_Spec_4.1.c \ +# bluetooth_init_cc2564_2.14.c \ # btstack_chipset_bcm.c \ # TI-WL183x requires TIInit_11.8.32.c @@ -53,4 +54,11 @@ ifneq ($(OS),Windows_NT) EXAMPLES += ${EXAMPLES_CLI} endif +# use pkg-config for portaudio +# CFLAGS += $(shell pkg-config portaudio-2.0 --cflags) -DHAVE_PORTAUDIO +# LDFLAGS += $(shell pkg-config portaudio-2.0 --libs) +# hard coded flags for portaudio in /usr/local/lib +# CFLAGS += -I/usr/local/include -DHAVE_PORTAUDIO +# LDFLAGS += -L/sw/lib -lportaudio -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,Carbon + all: ${EXAMPLES} diff --git a/port/posix-h5/Makefile b/port/posix-h5/Makefile index b335fd85a..dab67446d 100644 --- a/port/posix-h5/Makefile +++ b/port/posix-h5/Makefile @@ -54,4 +54,11 @@ ifneq ($(OS),Windows_NT) EXAMPLES += ${EXAMPLES_CLI} endif +# use pkg-config for portaudio +# CFLAGS += $(shell pkg-config portaudio-2.0 --cflags) -DHAVE_PORTAUDIO +# LDFLAGS += $(shell pkg-config portaudio-2.0 --libs) +# hard coded flags for portaudio in /usr/local/lib +# CFLAGS += -I/usr/local/include -DHAVE_PORTAUDIO +# LDFLAGS += -L/sw/lib -lportaudio -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,Carbon + all: ${EXAMPLES} From f7c85330b9f3d4bd7d09de78eedacfe6f41e7561 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 23 May 2016 18:04:57 +0200 Subject: [PATCH 4/4] example/hsp+hfp: extract SCO test code into sco_demo_util --- example/sco_demo_util.c | 219 ++++++++++++++++++++++++++++++++++++++++ example/sco_demo_util.h | 72 +++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 example/sco_demo_util.c create mode 100644 example/sco_demo_util.h diff --git a/example/sco_demo_util.c b/example/sco_demo_util.c new file mode 100644 index 000000000..d80edc21c --- /dev/null +++ b/example/sco_demo_util.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2016 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +/* + * sco_demo_util.c - send/receive test data via SCO, used by hfp_*_demo and hsp_*_demo + */ + +#include "sco_demo_util.h" +#include + +// configure test mode +#define SCO_DEMO_MODE_SINE 0 +#define SCO_DEMO_MODE_ASCII 1 +#define SCO_DEMO_MODE_COUNTER 2 + +// SCO demo configuration +#define SCO_DEMO_MODE SCO_DEMO_MODE_SINE +#define SCO_REPORT_PERIOD 100 + +// portaudio config +#define NUM_CHANNELS 1 +#define SAMPLE_RATE 8000 +#define FRAMES_PER_BUFFER 24 +#define PA_SAMPLE_TYPE paInt8 + +#if defined(HAVE_PORTAUDIO) && (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) +#define USE_PORTAUDIO +#endif + + +#ifdef USE_PORTAUDIO +#include +// portaudio globals +static PaStream * stream; +#endif + +#if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE +// input signal: pre-computed sine wave, 160 Hz +static const uint8_t sine[] = { + 0, 15, 31, 46, 61, 74, 86, 97, 107, 114, + 120, 124, 126, 126, 124, 120, 114, 107, 97, 86, + 74, 61, 46, 31, 15, 0, 241, 225, 210, 195, + 182, 170, 159, 149, 142, 136, 132, 130, 130, 132, + 136, 142, 149, 159, 170, 182, 195, 210, 225, 241, +}; +#endif + +static int phase; + +void sco_demo_init(void){ + + // status +#if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE +#ifdef HAVE_PORTAUDIO + printf("SCO Demo: Sending sine wave, audio output via portaudio.\n"); +#else + printf("SCO Demo: Sending sine wave, hexdump received data.\n"); +#endif +#endif +#if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII + printf("SCO Demo: Sending ASCII blocks, print received data.\n"); +#endif +#if SCO_DEMO_MODE == SCO_DEMO_MODE_COUNTER + printf("SCO Demo: Sending counter value, hexdump received data.\n"); +#endif + +#ifdef USE_PORTAUDIO + int err; + PaStreamParameters outputParameters; + + /* -- initialize PortAudio -- */ + err = Pa_Initialize(); + if( err != paNoError ) return; + /* -- setup input and output -- */ + outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ + outputParameters.channelCount = NUM_CHANNELS; + outputParameters.sampleFormat = PA_SAMPLE_TYPE; + outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; + outputParameters.hostApiSpecificStreamInfo = NULL; + /* -- setup stream -- */ + err = Pa_OpenStream( + &stream, + NULL, // &inputParameters, + &outputParameters, + SAMPLE_RATE, + FRAMES_PER_BUFFER, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + NULL, /* no callback, use blocking API */ + NULL ); /* no callback, so no callback userData */ + if( err != paNoError ) return; + /* -- start stream -- */ + err = Pa_StartStream( stream ); + if( err != paNoError ) return; +#endif + +#if SCO_DEMO_MODE != SCO_DEMO_MODE_SINE + hci_set_sco_voice_setting(0x03); // linear, unsigned, 8-bit, transparent +#endif + +#if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII + phase = 'a'; +#endif +} + + +void sco_demo_send(hci_con_handle_t sco_handle){ + + if (!sco_handle) return; + + const int sco_packet_length = 24 + 3; // hci_get_sco_packet_length(); + const int sco_payload_length = sco_packet_length - 3; + + hci_reserve_packet_buffer(); + uint8_t * sco_packet = hci_get_outgoing_packet_buffer(); + // set handle + flags + little_endian_store_16(sco_packet, 0, sco_handle); + // set len + sco_packet[2] = sco_payload_length; + const int frames_per_packet = sco_payload_length; // for 8-bit data. for 16-bit data it's /2 + +#if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE + int i; + for (i=0;i= sizeof(sine)) phase = 0; + } +#else +#if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII + memset(&sco_packet[3], phase++, frames_per_packet); + if (phase > 'z') phase = 'a'; +#else + for (i=0;i> 4); + printf_hexdump(&packet[3], size-3); + return; + } + +#if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE +#ifdef USE_PORTAUDIO + uint32_t start = btstack_run_loop_get_time_ms(); + Pa_WriteStream( stream, &packet[3], size -3); + uint32_t end = btstack_run_loop_get_time_ms(); + if (end - start > 5){ + printf("Portaudio: write stream took %u ms\n", end - start); + } +#else + printf_hexdump(&packet[3], size-3); +#endif +#else + printf("data: "); +#if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII + int i; + for (i=3;i