Merge branch 'develop' of https://github.com/bluekitchen/btstack into develop

This commit is contained in:
Matthias Ringwald 2017-02-01 12:35:40 +01:00
commit 32d0cda316
22 changed files with 244 additions and 72 deletions

View File

@ -72,7 +72,6 @@ ENABLE_EHCILL | Enable eHCILL low power mode on TI CC256x/WL18xx
ENABLE_LOG_DEBUG | Enable log_debug messages
ENABLE_LOG_ERROR | Enable log_error messages
ENABLE_LOG_INFO | Enable log_info messages
ENABLE_LOG_INTO_HCI_DUMP | Log debug messages as part of packet log
ENABLE_SCO_OVER_HCI | Enable SCO over HCI for chipsets (only CC256x/WL18xx and USB CSR controllers)
ENABLE_LE_SECURE_CONNECTIONS | Enable LE Secure Connections using [mbed TLS library](https://tls.mbed.org)
ENABLE_LE_DATA_CHANNELS | Enable LE Data Channels in credit-based flow control mode

View File

@ -72,7 +72,7 @@
// number of sco packets until 'report' on console
#define SCO_REPORT_PERIOD 100
// length and name of wav file on disc
// length and name of wav file on disk
#define SCO_WAV_DURATION_IN_SECONDS 15
#define SCO_WAV_FILENAME "sco_input.wav"
@ -346,40 +346,48 @@ static void portaudio_terminate(void){
}
#endif
#if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
static void handle_pcm_data(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context){
UNUSED(context);
UNUSED(sample_rate);
UNUSED(data);
UNUSED(num_samples);
UNUSED(num_channels);
#if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
// printf("handle_pcm_data num samples %u, sample rate %d\n", num_samples, num_channels);
#ifdef HAVE_PORTAUDIO
// samples in callback in host endianess, ready for PortAudio playback
btstack_ring_buffer_write(&pa_output_ring_buffer, (uint8_t *)data, num_samples*num_channels*2);
#else
UNUSED(num_channels);
#endif
#ifdef SCO_WAV_FILENAME
if (!num_samples_to_write) return;
num_samples = btstack_min(num_samples, num_samples_to_write);
num_samples_to_write -= num_samples;
wav_writer_write_int16(num_samples, data);
if (num_samples_to_write == 0){
sco_demo_close();
wav_writer_close();
}
#endif
#endif
}
static void sco_demo_init_mSBC(void){
printf("SCO Demo: Init mSBC\n");
wav_writer_open(SCO_WAV_FILENAME, 1, MSBC_SAMPLE_RATE);
btstack_sbc_decoder_init(&decoder_state, SBC_MODE_mSBC, &handle_pcm_data, NULL);
num_samples_to_write = MSBC_SAMPLE_RATE * SCO_WAV_DURATION_IN_SECONDS;
hfp_msbc_init();
#ifdef SCO_WAV_FILENAME
num_samples_to_write = MSBC_SAMPLE_RATE * SCO_WAV_DURATION_IN_SECONDS;
wav_writer_open(SCO_WAV_FILENAME, 1, MSBC_SAMPLE_RATE);
#endif
#if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE
sco_demo_msbc_fill_sine_audio_frame();
#endif
@ -412,10 +420,12 @@ static void sco_demo_receive_mSBC(uint8_t * packet, uint16_t size){
static void sco_demo_init_CVSD(void){
printf("SCO Demo: Init CVSD\n");
wav_writer_open(SCO_WAV_FILENAME, 1, CVSD_SAMPLE_RATE);
btstack_cvsd_plc_init(&cvsd_plc_state);
#ifdef SCO_WAV_FILENAME
num_samples_to_write = CVSD_SAMPLE_RATE * SCO_WAV_DURATION_IN_SECONDS;
wav_writer_open(SCO_WAV_FILENAME, 1, CVSD_SAMPLE_RATE);
#endif
#ifdef USE_PORTAUDIO
portaudio_initialize(CVSD_SAMPLE_RATE);
@ -424,22 +434,16 @@ static void sco_demo_init_CVSD(void){
static void sco_demo_receive_CVSD(uint8_t * packet, uint16_t size){
if (!num_samples_to_write) return;
int16_t audio_frame_out[128]; //
if (size > sizeof(audio_frame_out)){
printf("sco_demo_receive_CVSD: SCO packet larger than local output buffer - dropping data.\n");
return;
}
const int audio_bytes_read = size - 3;
const int num_samples = audio_bytes_read / CVSD_BYTES_PER_FRAME;
const int samples_to_write = btstack_min(num_samples, num_samples_to_write);
// Samples in CVSD SCO packet are in little endian, ready for wav files (take shortcut)
wav_writer_write_le_int16(samples_to_write, audio_frame_out);
num_samples_to_write -= samples_to_write;
if (num_samples_to_write == 0){
sco_demo_close();
}
// convert into host endian
int16_t audio_frame_in[128];
@ -450,60 +454,60 @@ static void sco_demo_receive_CVSD(uint8_t * packet, uint16_t size){
btstack_cvsd_plc_process_data(&cvsd_plc_state, audio_frame_in, num_samples, audio_frame_out);
#ifdef SCO_WAV_FILENAME
// Samples in CVSD SCO packet are in little endian, ready for wav files (take shortcut)
const int samples_to_write = btstack_min(num_samples, num_samples_to_write);
wav_writer_write_le_int16(samples_to_write, audio_frame_out);
num_samples_to_write -= samples_to_write;
if (num_samples_to_write == 0){
wav_writer_close();
}
#endif
#ifdef USE_PORTAUDIO
btstack_ring_buffer_write(&pa_output_ring_buffer, (uint8_t *)audio_frame_out, audio_bytes_read);
#endif
}
#endif
void sco_demo_close(void){
printf("SCO demo close\n");
#if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
#if defined(SCO_WAV_FILENAME) || defined(SCO_SBC_FILENAME)
wav_writer_close();
#endif
printf("SCO demo statistics: ");
if (negotiated_codec == HFP_CODEC_MSBC){
printf("Used mSBC with PLC, number of processed frames: \n - %d good frames, \n - %d zero frames, \n - %d bad frames.", decoder_state.good_frames_nr, decoder_state.zero_frames_nr, decoder_state.bad_frames_nr);
printf("Used mSBC with PLC, number of processed frames: \n - %d good frames, \n - %d zero frames, \n - %d bad frames.\n", decoder_state.good_frames_nr, decoder_state.zero_frames_nr, decoder_state.bad_frames_nr);
} else {
printf("Used CVSD with PLC, number of proccesed frames: \n - %d good frames, \n - %d bad frames.", cvsd_plc_state.good_frames_nr, cvsd_plc_state.bad_frames_nr);
printf("Used CVSD with PLC, number of proccesed frames: \n - %d good frames, \n - %d bad frames.\n", cvsd_plc_state.good_frames_nr, cvsd_plc_state.bad_frames_nr);
}
negotiated_codec = -1;
#if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
#if defined(SCO_WAV_FILENAME)
wav_writer_close();
#endif
#ifdef HAVE_PORTAUDIO
portaudio_terminate();
#endif
#ifdef SCO_WAV_FILENAME
#if 0
printf("SCO Demo: closing wav file\n");
if (negotiated_codec == HFP_CODEC_MSBC){
wav_writer_state_t * writer_state = &wav_writer_state;
if (!writer_state->wav_file) return;
rewind(writer_state->wav_file);
write_wav_header(writer_state->wav_file, writer_state->total_num_samples, btstack_sbc_decoder_num_channels(&decoder_state), btstack_sbc_decoder_sample_rate(&decoder_state),2);
fclose(writer_state->wav_file);
writer_state->wav_file = NULL;
}
#endif
#endif
negotiated_codec = -1;
#endif
}
void sco_demo_set_codec(uint8_t codec){
if (negotiated_codec == codec) return;
negotiated_codec = codec;
#if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
#if defined(SCO_WAV_FILENAME) || defined(SCO_SBC_FILENAME)
if (negotiated_codec == HFP_CODEC_MSBC){
sco_demo_init_mSBC();
} else {
sco_demo_init_CVSD();
}
#endif
#endif
}
void sco_demo_init(void){

View File

@ -10,7 +10,6 @@
// BTstack features that can be enabled
#define ENABLE_BLE
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_LOG_INFO
#define ENABLE_LOG_ERROR
#define ENABLE_LE_PERIPHERAL

View File

@ -29,6 +29,7 @@ usb_sources = @USB_SOURCES@
libBTstack_SOURCES = \
btstack.c \
socket_connection.c \
hci_dump.c \
hci_cmd.c \
daemon_cmds.c \
btstack_linked_list.c \
@ -79,7 +80,7 @@ libBTstack.$(BTSTACK_LIB_EXTENSION): $(libBTstack_SOURCES)
# ranlib $@
BTdaemon: $(BTdaemon_SOURCES)
$(CC) $(CFLAGS) -DENABLE_LOG_INTO_HCI_DUMP -o $@ $^ $(LDFLAGS) $(LIBUSB_CFLAGS) $(LIBUSB_LDFLAGS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBUSB_CFLAGS) $(LIBUSB_LDFLAGS)
clean:
rm -rf libBTstack* BTdaemon *.o

View File

@ -13,7 +13,6 @@
#define ENABLE_CLASSIC
#define ENABLE_LE_PERIPHERAL
// #define ENABLE_LE_CENTRAL
#define ENABLE_LOG_INTO_HCI_DUMP
// #define ENABLE_LOG_ERROR
// #define ENABLE_LOG_INFO
// #define ENABLE_EHCILL

View File

@ -15,7 +15,6 @@
#define ENABLE_CLASSIC
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SDP_DES_DUMP
// BTstack configuration. buffers, sizes, ...

View File

@ -19,7 +19,6 @@
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SCO_OVER_HCI
#define ENABLE_SDP_DES_DUMP

View File

@ -0,0 +1,29 @@
//
// btstack_config.h for libusb port
//
#ifndef __BTSTACK_CONFIG
#define __BTSTACK_CONFIG
// Port related features
#define HAVE_MALLOC
#define HAVE_POSIX_FILE_IO
#define HAVE_POSIX_STDIN
#define HAVE_POSIX_TIME
// BTstack features that can be enabled
#define ENABLE_BLE
#define ENABLE_CLASSIC
#define ENABLE_LE_PERIPHERAL
#define ENABLE_LE_CENTRAL
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_SCO_OVER_HCI
#define ENABLE_SDP_DES_DUMP
// BTstack configuration. buffers, sizes, ...
#define HCI_ACL_PAYLOAD_SIZE (1691 + 4)
#define HCI_INCOMING_PRE_BUFFER_SIZE 14 // sizeof BNEP header, avoid memcpy
#endif

View File

@ -13,7 +13,6 @@
#define ENABLE_CLASSIC
#define ENABLE_LE_PERIPHERAL
// #define ENABLE_LE_CENTRAL
// #define ENABLE_LOG_INTO_HCI_DUMP
// #define ENABLE_LOG_ERROR
// #define ENABLE_LOG_INFO
// #define ENABLE_EHCILL

View File

@ -13,7 +13,6 @@
#define ENABLE_CLASSIC
#define ENABLE_LE_PERIPHERAL
// #define ENABLE_LE_CENTRAL
#define ENABLE_LOG_INTO_HCI_DUMP
// #define ENABLE_LOG_ERROR
// #define ENABLE_LOG_INFO
// #define ENABLE_EHCILL

View File

@ -17,7 +17,6 @@
#define ENABLE_LE_CENTRAL
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SDP_DES_DUMP
// BTstack configuration. buffers, sizes, ...

View File

@ -19,7 +19,6 @@
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SCO_OVER_HCI
#define ENABLE_SDP_DES_DUMP
// #define ENABLE_EHCILL

View File

@ -19,7 +19,6 @@
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SCO_OVER_HCI
#define ENABLE_SDP_DES_DUMP

View File

@ -0,0 +1,29 @@
//
// btstack_config.h for generic POSIX H4 port
//
#ifndef __BTSTACK_CONFIG
#define __BTSTACK_CONFIG
// Port related features
#define HAVE_MALLOC
#define HAVE_POSIX_FILE_IO
#define HAVE_POSIX_STDIN
#define HAVE_POSIX_TIME
// BTstack features that can be enabled
#define ENABLE_BLE
#define ENABLE_CLASSIC
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_SCO_OVER_HCI
#define ENABLE_SDP_DES_DUMP
// #define ENABLE_EHCILL
// BTstack configuration. buffers, sizes, ...
#define HCI_INCOMING_PRE_BUFFER_SIZE 14 // sizeof benep heade, avoid memcpy
#define HCI_ACL_PAYLOAD_SIZE (1691 + 4)
#endif

View File

@ -19,7 +19,6 @@
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SCO_OVER_HCI
#define ENABLE_SDP_DES_DUMP

View File

@ -19,7 +19,6 @@
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SCO_OVER_HCI
#define ENABLE_SDP_DES_DUMP

View File

@ -75,32 +75,20 @@ static inline void __log_unused(const char *format, ...) {
#endif
#ifdef ENABLE_LOG_DEBUG
#ifdef ENABLE_LOG_INTO_HCI_DUMP
#define log_debug(format, ...) HCI_DUMP_LOG(LOG_LEVEL_DEBUG, format, ## __VA_ARGS__)
#else
#define log_debug(format, ...) BTSTACK_PRINTF(format "\n", ## __VA_ARGS__)
#endif
#else
#define log_debug(...) __log_unused(__VA_ARGS__)
#endif
#ifdef ENABLE_LOG_INFO
#ifdef ENABLE_LOG_INTO_HCI_DUMP
#define log_info(format, ...) HCI_DUMP_LOG(LOG_LEVEL_INFO, format, ## __VA_ARGS__)
#else
#define log_info(format, ...) BTSTACK_PRINTF(format "\n", ## __VA_ARGS__)
#endif
#else
#define log_info(...) __log_unused(__VA_ARGS__)
#endif
#ifdef ENABLE_LOG_ERROR
#ifdef ENABLE_LOG_INTO_HCI_DUMP
#define log_error(format, ...) HCI_DUMP_LOG(LOG_LEVEL_ERROR, format, ## __VA_ARGS__)
#else
#define log_error(format, ...) BTSTACK_PRINTF(format "\n", ## __VA_ARGS__)
#endif
#else
#define log_error(...) __log_unused(__VA_ARGS__)
#endif

View File

@ -561,7 +561,15 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr);
hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr);
if (!hfp_connection || hfp_connection->state != HFP_IDLE) return;
if (!hfp_connection){
log_info("hfp: no memory to accept incoming connection - decline");
rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet));
return;
}
if (hfp_connection->state != HFP_IDLE) {
log_error("hfp: incoming connection but state != HFP_IDLE");
return;
}
hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;

View File

@ -17,7 +17,6 @@
#define ENABLE_LOG_DEBUG
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SDP_DES_DUMP
#define ENABLE_SDP_EXTRA_QUERIES
// #define ENABLE_LE_SECURE_CONNECTIONS

View File

@ -14,7 +14,6 @@
#define ENABLE_LOG_DEBUG
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SDP_DES_DUMP
#define ENABLE_SDP_EXTRA_QUERIES

View File

@ -303,6 +303,10 @@ void rfcomm_accept_connection(uint16_t rfcomm_cid){
// printf("rfcomm_accept_connection \n");
}
void rfcomm_decline_connection(uint16_t rfcomm_cid){
// printf("rfcomm_accept_connection \n");
}
void btstack_run_loop_add_timer(btstack_timer_source_t *timer){
}

123
tool/bluetooth_sdp.py Executable file
View File

@ -0,0 +1,123 @@
#!/usr/bin/env python
#
# Scrape SDP UUIDs from Bluetooth SIG page
# Copyright 2017 BlueKitchen GmbH
#
from lxml import html
import datetime
import requests
import sys
import os
import codecs
import re
program_info = '''
BTstack SDP UUID Scraper for BTstack
Copyright 2017, BlueKitchen GmbH
'''
header = '''
/**
* bluetooth_sdp.h generated from Bluetooth SIG website for BTstack
*/
#ifndef __BLUETOOTH_SDP_H
#define __BLUETOOTH_SDP_H
'''
page_info = '''
/**
* Assigned numbers from {page}
*/
'''
trailer = '''
#endif
'''
# Convert CamelCase to snake_case from http://stackoverflow.com/a/1176023
def camel_to_underscore(name):
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).upper()
def create_pretty_define(name):
name = name.replace(' - ', '_')
name = name.replace(' ', '_')
name = name.replace('/','')
name = name.replace('(','_')
name = name.replace(')','')
name = name.replace('-','_')
name = name.replace('PnP', 'PNP')
return camel_to_underscore(name).replace('__','_').replace('3_D','3D').replace('L2_CAP','L2CAP')
def clean_remark(remark):
return " ".join(remark.split())
def process_table(fout, table, pattern):
rows = table.getchildren()
for row in rows:
columns = row.getchildren()
name = columns[0].text_content().encode('ascii','ignore')
value = columns[1].text_content().encode('ascii','ignore')
remark = columns[2].text_content().encode('ascii','ignore')
# skip table headers
if name == "Protocol Name":
continue
if name == "Service Class Name":
continue
# skip table footers
if value.startswith('(Max value '):
continue
name = create_pretty_define(name)
remark = clean_remark(remark)
fout.write(pattern % (name, value, remark))
# print("'%s' = '%s' -- %s" % (name, value, remark))
fout.write('\n')
def scrape_page(fout, url):
print("Parsing %s" % url)
fout.write(page_info.format(page=url))
# get from web
# r = requests.get(url)
# content = r.text
# test: fetch from local file 'service-discovery.html'
f = codecs.open("service-discovery.html", "r", "utf-8")
content = f.read();
tree = html.fromstring(content)
# process tables
tables = tree.xpath('//table/tbody')
index = 0
for table in tables:
# table_name = table_names[index]
index = index + 1
# 2 - Protocol Identifiers
if index == 2:
fout.write('//\n')
fout.write('// Protocol Identifiers\n')
fout.write('//\n')
process_table(fout, table, '#define BLUETOOTH_PROTOCOL_%-55s %s // %s\n')
# 3 - Service Classes
if index == 3:
fout.write('//\n')
fout.write('// Service Classes\n')
fout.write('//\n')
process_table(fout, table, '#define BLUEROOTH_SERVICE_CLASS_%-50s %s // %s\n')
btstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..')
gen_path = btstack_root + '/src/bluetooth_sdp.h'
print(program_info)
with open(gen_path, 'wt') as fout:
fout.write(header.format(datetime=str(datetime.datetime.now())))
scrape_page(fout, 'https://www.bluetooth.com/specifications/assigned-numbers/service-discovery')
fout.write(trailer)
print('Scraping successful!\n')