diff --git a/CocoaTouch/include/BTstack/BTstackManager.h b/CocoaTouch/include/BTstack/BTstackManager.h index 21dd02afe..8ad7a8f1c 100644 --- a/CocoaTouch/include/BTstack/BTstackManager.h +++ b/CocoaTouch/include/BTstack/BTstackManager.h @@ -64,6 +64,10 @@ typedef enum { kW4InquiryMode, kInquiry, kRemoteName, + // stopping + kW4InquiryModeBeforeStop, + kW4InquiryStop, + kW4RemoteNameBeforeStop, } DiscoveryState; @protocol BTstackManagerDelegate; @@ -99,6 +103,7 @@ typedef enum { -(BTstackError) stopDiscovery; -(int) numberOfDevicesFound; -(BTDevice*) deviceAtIndex:(int)index; +-(BOOL) isDiscoveryActive; // Connections -(BTstackError) createL2CAPChannelAtAddress:(bd_addr_t) address withPSM:(uint16_t)psm authenticated:(BOOL)authentication; diff --git a/CocoaTouch/src/BTDiscoveryViewController.m b/CocoaTouch/src/BTDiscoveryViewController.m index c98f06f95..06565717b 100644 --- a/CocoaTouch/src/BTDiscoveryViewController.m +++ b/CocoaTouch/src/BTDiscoveryViewController.m @@ -145,6 +145,10 @@ remoteNameIndex = deviceIndex; [self reload]; } +-(void) discoveryStopped { + inquiryState = kInquiryInactive; + [self reload]; +} -(void) deviceInfo:(BTDevice*)device { [self reload]; } diff --git a/CocoaTouch/src/BTstackManager.m b/CocoaTouch/src/BTstackManager.m index ede64152c..6e1400368 100644 --- a/CocoaTouch/src/BTstackManager.m +++ b/CocoaTouch/src/BTstackManager.m @@ -158,6 +158,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe -(BOOL) isActivating { return state == kW4Activated; } +-(BOOL) isDiscoveryActive { + return state == kActivated && (discoveryState != kInactive); +} // Discovery -(BTstackError) startDiscovery { @@ -166,7 +169,36 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe bt_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI return 0; }; +-(void) sendDiscoveryStoppedEvent { + for (id listener in listeners) { + [listener discoveryStopped]; + } +} -(BTstackError) stopDiscovery{ + if (state != kActivated) return BTSTACK_NOT_ACTIVATED; + switch (discoveryState){ + case kInactive: + state = kDeactivated; + [self sendDiscoveryStoppedEvent]; + break; + case kW4InquiryMode: + discoveryState = kW4InquiryModeBeforeStop; + break; + case kInquiry: + discoveryState = kW4InquiryStop; + bt_send_cmd(&hci_inquiry_cancel); + break; + case kRemoteName: { + discoveryState = kW4RemoteNameBeforeStop; + BTDevice *device = [discoveredDevices objectAtIndex:discoveryDeviceIndex]; + bt_send_cmd(&hci_remote_name_request_cancel, [device address]); + break; + } + default: + NSLog(@"[BTstackManager stopDiscovery] invalid discoveryState %u", discoveryState); + [self sendDiscoveryStoppedEvent]; + break; + } return 0; }; @@ -431,7 +463,30 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe } } break; - + + case kW4InquiryModeBeforeStop: + if (packet[0] == HCI_EVENT_COMMAND_COMPLETE && COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) { + discoveryState = kInactive; + [self sendDiscoveryStoppedEvent]; + } + break; + + case kW4InquiryStop: + if (packet[0] == HCI_EVENT_INQUIRY_COMPLETE + || packet[0] == HCI_EVENT_COMMAND_COMPLETE && COMMAND_COMPLETE_EVENT(packet, hci_inquiry_cancel)) { + discoveryState = kInactive; + [self sendDiscoveryStoppedEvent]; + } + break; + + case kW4RemoteNameBeforeStop: + if (packet[0] == HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE + || packet[0] == HCI_EVENT_COMMAND_COMPLETE && COMMAND_COMPLETE_EVENT(packet, hci_remote_name_request_cancel)){ + discoveryState = kInactive; + [self sendDiscoveryStoppedEvent]; + } + break; + default: break; } @@ -455,7 +510,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe case kActivated: if (packet_type == HCI_EVENT_PACKET) [self discoveryHandleEvent:packet withLen:size]; break; - + default: break; } diff --git a/CocoaTouch/src/TestBTstackManager.h b/CocoaTouch/src/TestBTstackManager.h index e9245aaa5..51d8999f2 100644 --- a/CocoaTouch/src/TestBTstackManager.h +++ b/CocoaTouch/src/TestBTstackManager.h @@ -13,6 +13,7 @@ @interface TestBTstackManager : NSObject{ BTstackManager *bt; BTDiscoveryViewController* discoveryView; + BTDevice *selectedDevice; } @end diff --git a/CocoaTouch/src/TestBTstackManager.m b/CocoaTouch/src/TestBTstackManager.m index 10c8f1c4a..a9ceeba15 100644 --- a/CocoaTouch/src/TestBTstackManager.m +++ b/CocoaTouch/src/TestBTstackManager.m @@ -12,7 +12,7 @@ -(void) activated{ NSLog(@"activated!"); - [bt startDiscovery]; + // [bt startDiscovery]; } -(void) activationFailed:(BTstackError)error{ NSLog(@"activationFailed error 0x%02x!", error); @@ -21,6 +21,9 @@ NSLog(@"discoveryInquiry!"); [bt storeDeviceInfo]; } +-(void) discoveryStopped{ + NSLog(@"discoveryStopped!"); +} -(void) discoveryQueryRemoteName:(int)deviceIndex{ NSLog(@"discoveryQueryRemoteName %u/%u!", deviceIndex+1, [bt numberOfDevicesFound]); } @@ -28,15 +31,24 @@ NSLog(@"Device Info: addr %@ name %@ COD 0x%06x", [device addressString], [device name], [device classOfDevice] ); } - (BOOL)willSelectDeviceAtIndex:(int)deviceIndex { - BTDevice *device = [bt deviceAtIndex:deviceIndex]; + if (selectedDevice) return NO; + selectedDevice = [bt deviceAtIndex:deviceIndex]; + BTDevice *device = selectedDevice; NSLog(@"Device selected: addr %@ name %@ COD 0x%06x", [device addressString], [device name], [device classOfDevice] ); + [bt stopDiscovery]; return NO; } -(void)statusCellSelected{ + if (![bt isDiscoveryActive]) { + selectedDevice = nil; + [bt startDiscovery]; + } NSLog(@"statusCellSelected!"); } - (void)applicationDidFinishLaunching:(UIApplication *)application { + selectedDevice = nil; + // create discovery controller discoveryView = [[BTDiscoveryViewController alloc] init]; [discoveryView setDelegate:self]; diff --git a/TODO.txt b/TODO.txt index c5e589663..d829dd64b 100644 --- a/TODO.txt +++ b/TODO.txt @@ -7,7 +7,6 @@ NEXT: - Provide BTstackManager Objective-C class - implement l2cap code - implement rfcomm code - - figure out how to receive iPhone System Power IONotifications (in BTdaemon) to detect, when phone gets locked - some trick - use Cocoa run loop for background app?