mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-24 04:43:36 +00:00
support for prefsbundle, bug fixes, other stuff
This commit is contained in:
parent
f6b3c2766c
commit
3c4d4b9093
@ -6,8 +6,12 @@ if USE_BLUETOOL
|
||||
patchbluetool = PatchBlueTool
|
||||
endif
|
||||
|
||||
if USE_PREFSBUNDLE
|
||||
patchbluetool = PrefsBundle
|
||||
endif
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
SUBDIRS = src example $(springboardaccess) $(patchbluetool)
|
||||
SUBDIRS = src example $(springboardaccess) $(prefsbundle) $(patchbluetool)
|
||||
|
||||
iphone_ip=@IPHONE_IP@
|
||||
install-iphone: src/BTdaemon
|
||||
|
@ -1 +1 @@
|
||||
./configure --target=iphone --enable-launchd --enable-ldid --with-uart-speed=921600
|
||||
./configure --target=iphone --enable-launchd --enable-ldid --with-prefsbundle --with-uart-speed=921600
|
@ -12,6 +12,7 @@ AC_ARG_WITH(uart-speed, [AS_HELP_STRING([--with-uart-speed=uartSpeed], [Specify
|
||||
AC_ARG_ENABLE(bluetool, [AS_HELP_STRING([--disable-bluetool],[Disable init of Bluetooth module by BlueTool])], USE_BLUETOOL=$enableval, USE_BLUETOOL="DEFAULT")
|
||||
AC_ARG_ENABLE(springboard, [AS_HELP_STRING([--disable-springboard],[Disable display of BTstack status in SpringBoard])], USE_SPRINGBOARD=$enableval, USE_SPRINGBOARD="DEFAULT")
|
||||
AC_ARG_ENABLE(launchd, [AS_HELP_STRING([--enable-launchd],[Compiles BTdaemon for use by launchd])], USE_LAUNCHD=$enableval, USE_LAUNCHD="no")
|
||||
AC_ARG_WITH(prefsbundle, [AS_HELP_STRING([--with-prefsbundle],[Compiles iPhone Preferences Bundle])], USE_PREFSBUNDLE=$enableval, USE_PREFSBUNDLE="no")
|
||||
AC_ARG_WITH(iphone-ip, [AS_HELP_STRING([--with-iphone-ip=192.168.1.5], [Specify IP address used by iPhone for installation (not supported yet)])], IPHONE_IP=$withval, IPHONE_IP="")
|
||||
AC_ARG_WITH(vendor-id, [AS_HELP_STRING([--with-vendor-id=vendorID], [Specify USB BT Dongle vendorID])], USB_VENDOR_ID=$withval, USB_VENDOR_ID="")
|
||||
AC_ARG_WITH(product-id, [AS_HELP_STRING([--with-product-id=productID], [Specify USB BT Dongle productID])], USB_PRODUCT_ID=$withval, USB_PRODUCT_ID="")
|
||||
@ -189,6 +190,7 @@ fi
|
||||
|
||||
AM_CONDITIONAL(USE_SPRINGBOARD, [test "x$USE_SPRINGBOARD" == "xyes"])
|
||||
AM_CONDITIONAL(USE_BLUETOOL, [test "x$USE_BLUETOOL" == "xyes"])
|
||||
AM_CONDITIONAL(USE_PREFSBUNDLE, [test "x$USE_PREFSBUNDLE" == "xyes"])
|
||||
|
||||
# summary
|
||||
if test "x$HCI_TRANSPORT" = xUSB; then
|
||||
@ -203,6 +205,7 @@ fi
|
||||
|
||||
echo "USE_LAUNCHD: $USE_LAUNCHD"
|
||||
echo "USE_SPRINGBOARD: $USE_SPRINGBOARD"
|
||||
echo "USE_PREFSBUNDLE: $USE_PREFSBUNDLE"
|
||||
echo "USE_COCOA_RUN_LOOP: $USE_COCOA_RUN_LOOP"
|
||||
echo "REMOTE_DEVICE_DB: $REMOTE_DEVICE_DB"
|
||||
echo
|
||||
|
@ -215,6 +215,7 @@ extern const hci_cmd_t btstack_get_version;
|
||||
extern const hci_cmd_t btstack_get_system_bluetooth_enabled;
|
||||
extern const hci_cmd_t btstack_set_system_bluetooth_enabled;
|
||||
extern const hci_cmd_t btstack_set_discoverable;
|
||||
extern const hci_cmd_t btstack_set_bluetooth_enabled; // only used by btstack config
|
||||
|
||||
extern const hci_cmd_t hci_accept_connection_request;
|
||||
extern const hci_cmd_t hci_authentication_requested;
|
||||
|
@ -79,12 +79,33 @@ typedef enum {
|
||||
#define SDP_ClientExecutableURL 0x000b
|
||||
#define SDP_IconURL 0x000c
|
||||
#define SDP_AdditionalProtocolDescriptorList 0x000d
|
||||
#define SDP_SupportedFormatsList 0x0303
|
||||
|
||||
// SERVICE CLASSES
|
||||
#define SDP_OBEXObjectPush 0x1105
|
||||
#define SDP_OBEXFileTransfer 0x1106
|
||||
#define SDP_PublicBrowseGroup 0x1002
|
||||
|
||||
// PROTOCOLS
|
||||
#define SDP_SDPProtocol 0x0001
|
||||
#define SDP_UDPProtocol 0x0002
|
||||
#define SDP_RFCOMMProtocol 0x0003
|
||||
#define SDP_OBEXProtocol 0x0008
|
||||
#define SDP_L2CAPProtocol 0x0100
|
||||
|
||||
// OFFSETS FOR LOCALIZED ATTRIBUTES - SDP_LanguageBaseAttributeIDList
|
||||
#define SDP_Offest_ServiceName 0x0000
|
||||
#define SDP_Offest_ServiceDescription 0x0001
|
||||
#define SDP_Offest_ProviderName 0x0002
|
||||
|
||||
// OBEX
|
||||
#define SDP_vCard_2_1 0x01
|
||||
#define SDP_vCard_3_0 0x02
|
||||
#define SDP_vCal_1_0 0x03
|
||||
#define SDP_iCal_2_0 0x04
|
||||
#define SDP_vNote 0x05
|
||||
#define SDP_vMessage 0x06
|
||||
#define SDP_OBEXFileTypeAny 0xFF
|
||||
|
||||
#pragma mark DateElement
|
||||
void de_dump_data_element(uint8_t * record);
|
||||
|
38
src/daemon.c
38
src/daemon.c
@ -61,6 +61,7 @@
|
||||
|
||||
#ifdef USE_BLUETOOL
|
||||
#include "bt_control_iphone.h"
|
||||
#include <notify.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPRINGBOARD
|
||||
@ -94,6 +95,7 @@ static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state);
|
||||
static client_state_t * client_for_connection(connection_t *connection);
|
||||
static int clients_require_power_on();
|
||||
static int clients_require_discoverable();
|
||||
static int clients_clear_power_request();
|
||||
static void start_power_off_timer();
|
||||
static void stop_power_off_timer();
|
||||
|
||||
@ -106,6 +108,7 @@ static int power_management_sleep = 0;
|
||||
static linked_list_t clients = NULL; // list of connected clients
|
||||
static void (*bluetooth_status_handler)(BLUETOOTH_STATE state) = dummy_bluetooth_status_handler;
|
||||
|
||||
static int global_enable = 0;
|
||||
|
||||
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state){
|
||||
printf("Bluetooth status: %u\n", state);
|
||||
@ -173,6 +176,19 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
||||
// merge state
|
||||
hci_discoverable_control(clients_require_discoverable());
|
||||
break;
|
||||
case BTSTACK_SET_BLUETOOTH_ENABLED:
|
||||
printf("BTSTACK_SET_BLUETOOTH_ENABLED: %u\n", packet[3]);
|
||||
|
||||
if (packet[3]) {
|
||||
// global enable
|
||||
global_enable = 1;
|
||||
hci_power_control(HCI_POWER_ON);
|
||||
} else {
|
||||
global_enable = 0;
|
||||
clients_clear_power_request();
|
||||
hci_power_control(HCI_POWER_OFF);
|
||||
}
|
||||
break;
|
||||
case L2CAP_CREATE_CHANNEL_MTU:
|
||||
bt_flip_addr(addr, &packet[3]);
|
||||
psm = READ_BT_16(packet, 9);
|
||||
@ -359,6 +375,12 @@ static void power_notification_callback(POWER_NOTIFICATION_t notification){
|
||||
}
|
||||
|
||||
static void daemon_sigint_handler(int param){
|
||||
|
||||
#ifdef USE_BLUETOOL
|
||||
// hack for celeste
|
||||
notify_post("ch.ringwald.btstack.stopped");
|
||||
#endif
|
||||
|
||||
printf(" <= SIGINT received, shutting down..\n");
|
||||
hci_power_control( HCI_POWER_OFF);
|
||||
hci_close();
|
||||
@ -497,6 +519,11 @@ int main (int argc, char * const * argv){
|
||||
#endif
|
||||
socket_connection_register_packet_callback(daemon_client_handler);
|
||||
|
||||
#ifdef USE_BLUETOOL
|
||||
// hack for celeste
|
||||
notify_post("ch.ringwald.btstack.started");
|
||||
#endif
|
||||
|
||||
// go!
|
||||
run_loop_execute();
|
||||
return 0;
|
||||
@ -541,7 +568,18 @@ static client_state_t * client_for_connection(connection_t *connection) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int clients_clear_power_request(){
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) clients; it ; it = it->next){
|
||||
client_state_t * client_state = (client_state_t *) it;
|
||||
client_state->power_mode = HCI_POWER_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
static int clients_require_power_on(){
|
||||
|
||||
if (global_enable) return 1;
|
||||
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) clients; it ; it = it->next){
|
||||
client_state_t * client_state = (client_state_t *) it;
|
||||
|
30
src/hci.c
30
src/hci.c
@ -309,9 +309,15 @@ static void hci_shutdown_connection(hci_connection_t *conn){
|
||||
log_dbg("Connection closed: handle %u, ", conn->con_handle);
|
||||
print_bd_addr( conn->address );
|
||||
log_dbg("\n");
|
||||
|
||||
// cancel all l2cap connections
|
||||
hci_emit_disconnection_complete(conn->con_handle, 0x16); // terminated by local host
|
||||
|
||||
run_loop_remove_timer(&conn->timeout);
|
||||
linked_list_remove(&hci_stack.connections, (linked_item_t *) conn);
|
||||
free( conn );
|
||||
|
||||
// now it's gone
|
||||
hci_emit_nr_connections_changed();
|
||||
}
|
||||
|
||||
@ -843,6 +849,12 @@ void hci_run(){
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
#ifdef USE_BLUETOOL
|
||||
hci_send_cmd(&hci_write_class_of_device, 0x007a020c); // Smartphone
|
||||
break;
|
||||
|
||||
case 7:
|
||||
#endif
|
||||
#endif
|
||||
// done.
|
||||
hci_stack.state = HCI_STATE_WORKING;
|
||||
@ -866,9 +878,6 @@ void hci_run(){
|
||||
|
||||
// send disconnected event right away - causes higher layer connections to get closed, too.
|
||||
hci_shutdown_connection(connection);
|
||||
|
||||
// remove from table
|
||||
hci_stack.connections = connection->item.next;
|
||||
return;
|
||||
}
|
||||
log_dbg("HCI_STATE_HALTING, calling off\n");
|
||||
@ -892,9 +901,6 @@ void hci_run(){
|
||||
|
||||
// send disconnected event right away - causes higher layer connections to get closed, too.
|
||||
hci_shutdown_connection(connection);
|
||||
|
||||
// remove from table
|
||||
hci_stack.connections = connection->item.next;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1015,6 +1021,18 @@ void hci_emit_connection_complete(hci_connection_t *conn){
|
||||
hci_stack.packet_handler(HCI_EVENT_PACKET, event, len);
|
||||
}
|
||||
|
||||
void hci_emit_disconnection_complete(uint16_t handle, uint8_t reason){
|
||||
uint8_t len = 6;
|
||||
uint8_t event[len];
|
||||
event[0] = HCI_EVENT_DISCONNECTION_COMPLETE;
|
||||
event[1] = len - 3;
|
||||
event[2] = 0; // status = OK
|
||||
bt_store_16(event, 3, handle);
|
||||
event[5] = reason;
|
||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, len);
|
||||
hci_stack.packet_handler(HCI_EVENT_PACKET, event, len);
|
||||
}
|
||||
|
||||
void hci_emit_l2cap_check_timeout(hci_connection_t *conn){
|
||||
uint8_t len = 4;
|
||||
uint8_t event[len];
|
||||
|
@ -92,6 +92,9 @@ extern "C" {
|
||||
// enable inquiry scan for this client
|
||||
#define BTSTACK_SET_DISCOVERABLE 0x07
|
||||
|
||||
// set global Bluetooth state
|
||||
#define BTSTACK_SET_BLUETOOTH_ENABLED 0x08
|
||||
|
||||
// create l2cap channel: @param bd_addr(48), psm (16)
|
||||
#define L2CAP_CREATE_CHANNEL 0x20
|
||||
|
||||
@ -270,6 +273,7 @@ uint16_t hci_max_acl_data_packet_length();
|
||||
void hci_emit_state();
|
||||
void hci_emit_connection_complete(hci_connection_t *conn);
|
||||
void hci_emit_l2cap_check_timeout(hci_connection_t *conn);
|
||||
void hci_emit_disconnection_complete(uint16_t handle, uint8_t reason);
|
||||
void hci_emit_nr_connections_changed();
|
||||
void hci_emit_hci_open_failed();
|
||||
void hci_emit_btstack_version();
|
||||
|
@ -295,7 +295,7 @@ OPCODE(OGF_CONTROLLER_BASEBAND, 0x36), "H"
|
||||
};
|
||||
const hci_cmd_t hci_write_link_supervision_timeout = {
|
||||
OPCODE(OGF_CONTROLLER_BASEBAND, 0x37), "H2"
|
||||
// handle, Range for N: 0x0001 – 0xFFFF Time (Range: 0.625ms – 40.9 sec)
|
||||
// handle, Range for N: 0x0001 Ð 0xFFFF Time (Range: 0.625ms Ð 40.9 sec)
|
||||
};
|
||||
const hci_cmd_t hci_write_inquiry_mode = {
|
||||
OPCODE(OGF_CONTROLLER_BASEBAND, 0x45), "1"
|
||||
@ -354,7 +354,10 @@ const hci_cmd_t btstack_set_discoverable = {
|
||||
OPCODE(OGF_BTSTACK, BTSTACK_SET_DISCOVERABLE), "1"
|
||||
};
|
||||
|
||||
|
||||
const hci_cmd_t btstack_set_bluetooth_enabled = {
|
||||
// only used by btstack config
|
||||
OPCODE(OGF_BTSTACK, BTSTACK_SET_BLUETOOTH_ENABLED), "1"
|
||||
};
|
||||
|
||||
const hci_cmd_t l2cap_create_channel = {
|
||||
OPCODE(OGF_BTSTACK, L2CAP_CREATE_CHANNEL), "B2"
|
||||
|
@ -276,8 +276,13 @@ static void h4_statemachine(){
|
||||
static int h4_process(struct data_source *ds) {
|
||||
if (hci_transport_h4->uart_fd == 0) return -1;
|
||||
|
||||
int read_now = bytes_to_read;
|
||||
// if (read_now > 100) {
|
||||
// read_now = 100;
|
||||
// }
|
||||
|
||||
// read up to bytes_to_read data in
|
||||
int bytes_read = read(hci_transport_h4->uart_fd, &hci_packet[read_pos], bytes_to_read);
|
||||
ssize_t bytes_read = read(hci_transport_h4->uart_fd, &hci_packet[read_pos], read_now);
|
||||
// printf("h4_process: bytes read %u\n", bytes_read);
|
||||
if (bytes_read < 0) {
|
||||
return bytes_read;
|
||||
|
@ -44,14 +44,19 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void posix_dump_timer();
|
||||
|
||||
// the run loop
|
||||
static linked_list_t data_sources;
|
||||
static int data_sources_modified;
|
||||
static linked_list_t timers;
|
||||
|
||||
/**
|
||||
* Add data_source to run_loop
|
||||
*/
|
||||
void posix_add_data_source(data_source_t *ds){
|
||||
data_sources_modified = 1;
|
||||
// printf("posix_add_data_source %x with fd %u\n", (int) ds, ds->fd);
|
||||
linked_list_add(&data_sources, (linked_item_t *) ds);
|
||||
}
|
||||
|
||||
@ -59,6 +64,8 @@ void posix_add_data_source(data_source_t *ds){
|
||||
* Remove data_source from run loop
|
||||
*/
|
||||
int posix_remove_data_source(data_source_t *ds){
|
||||
data_sources_modified = 1;
|
||||
// printf("posix_remove_data_source %x\n", (int) ds);
|
||||
return linked_list_remove(&data_sources, (linked_item_t *) ds);
|
||||
}
|
||||
|
||||
@ -68,7 +75,11 @@ int posix_remove_data_source(data_source_t *ds){
|
||||
void posix_add_timer(timer_source_t *ts){
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) &timers; it->next ; it = it->next){
|
||||
if (run_loop_timer_compare( (timer_source_t *) it->next, ts) >= 0) {
|
||||
if ((timer_source_t *) it->next == ts){
|
||||
fprintf(stderr, "run_loop_timer_add error: timer to add already in list!\n");
|
||||
return;
|
||||
}
|
||||
if (run_loop_timer_compare( (timer_source_t *) it->next, ts) > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -83,6 +94,7 @@ void posix_add_timer(timer_source_t *ts){
|
||||
*/
|
||||
int posix_remove_timer(timer_source_t *ts){
|
||||
// printf("Removed timer %x at %u\n", (int) ts, (unsigned int) ts->timeout.tv_sec);
|
||||
// posix_dump_timer();
|
||||
return linked_list_remove(&timers, (linked_item_t *) ts);
|
||||
}
|
||||
|
||||
@ -141,14 +153,19 @@ void posix_execute() {
|
||||
// wait for ready FDs
|
||||
select( highest_fd+1 , &descriptors, NULL, NULL, timeout);
|
||||
|
||||
// process data sources
|
||||
data_source_t *next;
|
||||
for (ds = (data_source_t *) data_sources; ds != NULL ; ds = next){
|
||||
next = (data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself
|
||||
// process data sources very carefully
|
||||
// bt_control.close() triggered from a client can remove a different data source
|
||||
|
||||
// printf("posix_execute: before ds check\n");
|
||||
data_sources_modified = 0;
|
||||
for (ds = (data_source_t *) data_sources; !data_sources_modified && ds != NULL; ds = (data_source_t *) ds->item.next){
|
||||
// printf("posix_execute: check %x with fd %u\n", (int) ds, ds->fd);
|
||||
if (FD_ISSET(ds->fd, &descriptors)) {
|
||||
// printf("posix_execute: process %x with fd %u\n", (int) ds, ds->fd);
|
||||
ds->process(ds);
|
||||
}
|
||||
}
|
||||
// printf("posix_execute: after ds check\n");
|
||||
|
||||
// process timers
|
||||
// pre: 0 <= tv_usec < 1000000
|
||||
@ -157,6 +174,9 @@ void posix_execute() {
|
||||
ts = (timer_source_t *) timers;
|
||||
if (ts->timeout.tv_sec > current_tv.tv_sec) break;
|
||||
if (ts->timeout.tv_sec == current_tv.tv_sec && ts->timeout.tv_usec > current_tv.tv_usec) break;
|
||||
// printf("posix_execute: process times %x\n", (int) ts);
|
||||
|
||||
// remove timer before processing it to allow handler to re-register with run loop
|
||||
run_loop_remove_timer(ts);
|
||||
ts->process(ts);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user