diff --git a/src/daemon.c b/src/daemon.c index 1ab02577c..60accc89f 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -91,6 +91,7 @@ static void daemon_no_connections_timeout(){ #ifdef USE_LAUNCHD printf("No connection for %u seconds -> POWER OFF and quit\n", DAEMON_NO_CONNECTION_TIMEOUT); hci_power_control( HCI_POWER_OFF); + hci_close(); exit(0); #else printf("No connection for %u seconds -> POWER OFF\n", DAEMON_NO_CONNECTION_TIMEOUT); @@ -283,6 +284,7 @@ static void daemon_packet_handler(void * connection, uint8_t packet_type, uint16 static void daemon_sigint_handler(int param){ printf(" <= SIGINT received, shutting down..\n"); hci_power_control( HCI_POWER_OFF); + hci_close(); printf("Good bye, see you.\n"); exit(0); } @@ -336,7 +338,8 @@ int main (int argc, char * const * argv){ } bt_control_t * control = NULL; - + remote_device_db_t * remote_device_db = NULL; + #ifdef HAVE_TRANSPORT_H4 transport = hci_transport_h4_instance(); config.device_name = UART_DEVICE; @@ -357,6 +360,10 @@ int main (int argc, char * const * argv){ bluetooth_status_handler = platform_iphone_status_handler; #endif +#ifdef REMOTE_DEVICE_DB + remote_device_db = &REMOTE_DEVICE_DB; +#endif + run_loop_init(RUN_LOOP_POSIX); // @TODO: allow configuration per HCI CMD @@ -366,7 +373,7 @@ int main (int argc, char * const * argv){ // hci_dump_open(NULL, HCI_DUMP_STDOUT); // init HCI - hci_init(transport, &config, control); + hci_init(transport, &config, control, remote_device_db); // init L2CAP l2cap_init(); @@ -375,7 +382,7 @@ int main (int argc, char * const * argv){ // init SDP sdp_init(); - + #ifdef USE_LAUNCHD socket_connection_create_launchd(); #else diff --git a/src/hci.c b/src/hci.c index 3bc71b2e2..c8f025c29 100644 --- a/src/hci.c +++ b/src/hci.c @@ -481,7 +481,7 @@ void hci_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *p hci_stack.packet_handler = handler; } -void hci_init(hci_transport_t *transport, void *config, bt_control_t *control){ +void hci_init(hci_transport_t *transport, void *config, bt_control_t *control, remote_device_db_t * remote_device_db){ // reference to use transport layer implementation hci_stack.hci_transport = transport; @@ -501,13 +501,23 @@ void hci_init(hci_transport_t *transport, void *config, bt_control_t *control){ // higher level handler hci_stack.packet_handler = dummy_handler; - // no link key db yet - hci_stack.remote_device_db = NULL; + // store and open remote device db + hci_stack.remote_device_db = remote_device_db; + if (hci_stack.remote_device_db) { + hci_stack.remote_device_db->open(); + } // register packet handlers with transport transport->register_packet_handler(&packet_handler); } +void hci_close(){ + // close remote device db + if (hci_stack.remote_device_db) { + hci_stack.remote_device_db->close(); + } +} + int hci_power_control(HCI_POWER_MODE power_mode){ if (power_mode == HCI_POWER_ON && hci_stack.state == HCI_STATE_OFF) { diff --git a/src/hci.h b/src/hci.h index 87d829b52..15b3db426 100644 --- a/src/hci.h +++ b/src/hci.h @@ -223,9 +223,10 @@ uint16_t hci_create_cmd(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, ...); uint16_t hci_create_cmd_internal(uint8_t *hci_cmd_buffer, const hci_cmd_t *cmd, va_list argptr); // set up HCI -void hci_init(hci_transport_t *transport, void *config, bt_control_t *control); +void hci_init(hci_transport_t *transport, void *config, bt_control_t *control, remote_device_db_t * remote_device_db); void hci_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)); - +void hci_close(); + // power control int hci_power_control(HCI_POWER_MODE mode); diff --git a/src/remote_device_db.h b/src/remote_device_db.h index 0fa7a947d..b2b775a6d 100644 --- a/src/remote_device_db.h +++ b/src/remote_device_db.h @@ -36,6 +36,11 @@ #include typedef struct { + + // management + void (*open)(); + void (*close)(); + // link key int (*get_link_key)(bd_addr_t *bd_addr, link_key_t *link_key); void (*put_link_key)(bd_addr_t *bd_addr, link_key_t *key); diff --git a/src/remote_device_db_iphone.m b/src/remote_device_db_iphone.m index 7ce88e371..c1b7075fa 100644 --- a/src/remote_device_db_iphone.m +++ b/src/remote_device_db_iphone.m @@ -29,13 +29,81 @@ * */ #include "remote_device_db.h" +#import +#define BTdaemonID @"ch.ringwald.btdaemon" +#define PREFS_REMOTE_NAME @"RemoteName" +#define PREFS_LINK_KEY @"LinkKey" + +static NSMutableDictionary *remote_devices = nil; + +// Device info +static void db_open(){ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSDictionary * dict = [defaults persistentDomainForName:BTdaemonID]; + remote_devices = [NSMutableDictionary dictionaryWithCapacity:([dict count]+5)]; + + // copy entries + for (id key in dict) { + NSDictionary *value = [dict objectForKey:key]; + NSMutableDictionary *deviceEntry = [NSMutableDictionary dictionaryWithCapacity:[value count]]; + [deviceEntry addEntriesFromDictionary:value]; + [remote_devices setObject:deviceEntry forKey:key]; + } + NSLog(@"read prefs %@", remote_devices ); +} + +static void db_close(){ + NSLog(@"store prefs %@", remote_devices ); + + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setPersistentDomain:remote_devices forName:BTdaemonID]; + [defaults synchronize]; + + [remote_devices release]; + remote_devices = nil; +} + +static NSString * stringForAddress(bd_addr_t* address) { + uint8_t *addr = (uint8_t*) *address; + return [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], + addr[3], addr[4], addr[5]]; +} + static int get_link_key(bd_addr_t *bd_addr, link_key_t *link_key) { + // get link key from deviceInfo + NSString *devAddress = stringForAddress(bd_addr); + NSMutableDictionary * deviceDict = [remote_devices objectForKey:devAddress]; + NSData *linkKey = nil; + if (deviceDict){ + linkKey = [deviceDict objectForKey:PREFS_LINK_KEY]; + if ([linkKey length] == LINK_KEY_LEN){ + NSLog(@"Link key for %@, value %@", devAddress, linkKey); + memcpy(link_key, [linkKey bytes], LINK_KEY_LEN); + return 1; + } + } + NSLog(@"Link key for %@ not found", devAddress); return 0; } + static void put_link_key(bd_addr_t *bd_addr, link_key_t *link_key){ + NSString *devAddress = stringForAddress(bd_addr); + NSMutableDictionary * deviceDict = [remote_devices objectForKey:devAddress]; + NSData *linkKey = [NSData dataWithBytes:link_key length:16]; + if (!deviceDict){ + deviceDict = [NSMutableDictionary dictionaryWithCapacity:3]; + [remote_devices setObject:deviceDict forKey:devAddress]; + } + [deviceDict setObject:linkKey forKey:PREFS_LINK_KEY]; + NSLog(@"Adding link key for %@, value %@", devAddress, linkKey); } + static void delete_link_key(bd_addr_t *bd_addr){ + NSString *devAddress = stringForAddress(bd_addr); + NSMutableDictionary * deviceDict = [remote_devices objectForKey:devAddress]; + [deviceDict removeObjectForKey:PREFS_LINK_KEY]; + NSLog(@"Removing link key for %@", devAddress); } static int get_name(bd_addr_t *bd_addr, device_name_t *device_name) { @@ -47,7 +115,13 @@ static void delete_name(bd_addr_t *bd_addr){ } remote_device_db_t remote_device_db_iphone = { - get_link_key, put_link_key, delete_link_key, - get_name, put_name, delete_name + db_open, + db_close, + get_link_key, + put_link_key, + delete_link_key, + get_name, + put_name, + delete_name };