diff --git a/TODO.txt b/TODO.txt index 3842ff31a..6bcfd01b8 100644 --- a/TODO.txt +++ b/TODO.txt @@ -3,8 +3,6 @@ Last milestone reached: BTdaemon automatically started by launchd on Mac and iPhone NEXT: -- deal with Apple stack - - detect if it is running and return appropriate error events - create a SpringBoardAccess MobileSubstrate Extension - put MobileSubstrate header and lib into 3rdparty folder - in SpringBoard hook, start datagram Unix domain or mach port server @@ -15,6 +13,10 @@ NEXT: - create script to build APT package - create pgp key and sign APT package - provide test version at http://btstack.ringwald.ch +- decide on error reporting + - command_status_event with custom errors + - hci open failed + - btstack error == Release Version 0.1 - implement rest of L2CAP state machine - incoming connections diff --git a/example/test.c b/example/test.c index 356bec8a0..d9767c0cc 100644 --- a/example/test.c +++ b/example/test.c @@ -36,6 +36,12 @@ void data_handler(uint8_t *packet, uint16_t size){ } void event_handler(uint8_t *packet, uint16_t size){ + // handle HCI init failure + if (packet[0] == HCI_EVENT_POWERON_FAILED){ + printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n"); + exit(1); + } + // bt stack activated, get started - set local name if (packet[0] == HCI_EVENT_BTSTACK_WORKING || (packet[0] == HCI_EVENT_BTSTACK_STATE && packet[2] == HCI_STATE_WORKING)) { diff --git a/src/bt_control_iphone.c b/src/bt_control_iphone.c index 6a8cf8c4d..b1a8e89ad 100644 --- a/src/bt_control_iphone.c +++ b/src/bt_control_iphone.c @@ -63,7 +63,7 @@ static int iphone_valid(void *config){ char * machine = get_machine_name(); if (!strncmp("iPhone", machine, strlen("iPhone" ))) return 1; if (!strncmp("iPod2,1", machine, strlen("iPod2,1"))) return 1; - if (!strncmp("iPod3,1", machine, strlen("iPod2,1"))) return 1; + if (!strncmp("iPod3,1", machine, strlen("iPod3,1"))) return 1; return 0; } @@ -249,12 +249,13 @@ static int iphone_write_initscript (void *config, int output){ } static int iphone_on (void *config){ + int err = 0; #if 0 // use tmp file for testing int output = open("/tmp/bt.init", O_WRONLY | O_CREAT | O_TRUNC); iphone_write_initscript(config, output); close(output); - system ("BlueTool < /tmp/bt.init"); + err = system ("BlueTool < /tmp/bt.init"); #else // modify original script on the fly FILE * outputFile = popen("BlueTool", "r+"); @@ -270,12 +271,12 @@ static int iphone_on (void *config){ if (singlechar == EOF) break; printf("%c", singlechar); }; - pclose(outputFile); + err = pclose(outputFile); #endif // if we sleep for about 3 seconds, we miss a strage packet... but we don't care // sleep(3); - return 0; + return err; } static int iphone_off (void *config){ diff --git a/src/hci.c b/src/hci.c index af0b665e5..e7d5cbdcb 100644 --- a/src/hci.c +++ b/src/hci.c @@ -265,19 +265,28 @@ void hci_init(hci_transport_t *transport, void *config, bt_control_t *control){ int hci_power_control(HCI_POWER_MODE power_mode){ if (power_mode == HCI_POWER_ON && hci_stack.state == HCI_STATE_OFF) { + // power on + int err = hci_stack.control->on(hci_stack.config); + if (err){ + fprintf(stderr, "POWER_ON failed"); + hci_emit_hci_open_failed(); + return err; + } + + // open low-level device + err = hci_stack.hci_transport->open(hci_stack.config); + if (err){ + fprintf(stderr, "HCI_INIT failed, turning Bluetooth off again"); + hci_stack.control->off(hci_stack.config); + hci_emit_hci_open_failed(); + return err; + } + // set up state machine hci_stack.num_cmd_packets = 1; // assume that one cmd can be sent hci_stack.state = HCI_STATE_INITIALIZING; hci_stack.substate = 0; - // power on - hci_stack.control->on(hci_stack.config); - - // open low-level device - hci_stack.hci_transport->open(hci_stack.config); - - // create internal event - } else if (power_mode == HCI_POWER_OFF && hci_stack.state == HCI_STATE_WORKING){ // close low-level device @@ -290,6 +299,7 @@ int hci_power_control(HCI_POWER_MODE power_mode){ hci_stack.state = HCI_STATE_OFF; } + // create internal event hci_emit_state(); // trigger next/first action @@ -436,3 +446,11 @@ void hci_emit_nr_connections_changed(){ hci_dump_packet( HCI_EVENT_PACKET, 0, event, len); hci_stack.event_packet_handler(event, len); } + +void hci_emit_hci_open_failed(){ + uint8_t len = 1; + uint8_t event[len]; + event[0] = HCI_EVENT_POWERON_FAILED; + hci_dump_packet( HCI_EVENT_PACKET, 0, event, len); + hci_stack.event_packet_handler(event, len); +} diff --git a/src/hci.h b/src/hci.h index 7e06022d1..74f7a7087 100644 --- a/src/hci.h +++ b/src/hci.h @@ -122,3 +122,4 @@ 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_nr_connections_changed(); +void hci_emit_hci_open_failed(); diff --git a/src/hci_cmds.h b/src/hci_cmds.h index 69052a23e..e3f6aab46 100644 --- a/src/hci_cmds.h +++ b/src/hci_cmds.h @@ -96,6 +96,9 @@ // data: event(8), len(8), nr hci connections #define HCI_EVENT_NR_CONNECTIONS_CHANGED 0x85 +// data: none +#define HCI_EVENT_POWERON_FAILED 0x86 + // data: event(8) #define DAEMON_CONNECTION_CLOSED 0xc0