support for prefsbundle, bug fixes, other stuff

This commit is contained in:
matthias.ringwald 2011-04-30 20:11:20 +00:00
parent f6b3c2766c
commit 3c4d4b9093
11 changed files with 133 additions and 16 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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];

View File

@ -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();

View File

@ -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"

View File

@ -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;

View File

@ -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);
}