From de4536005f93059d52135708b725882e5b3807bf Mon Sep 17 00:00:00 2001 From: "matthias.ringwald" Date: Sun, 21 Feb 2010 19:13:34 +0000 Subject: [PATCH] added BTDiscoveryViewController as a cleaner implementation of BTInquiryViewController, split BTstackManagerDelegate into BTstackManagerDelegate and BTstackManagerListener --- CocoaTouch/TestBTstackManager-Info.plist | 2 - .../BTstack/BTDiscoveryViewController.h | 54 +++ CocoaTouch/include/BTstack/BTstackManager.h | 41 ++- CocoaTouch/src/BTDiscoveryViewController.m | 327 ++++++++++++++++++ CocoaTouch/src/BTstackManager.m | 99 ++++-- CocoaTouch/src/TestBTstackManager.h | 5 +- CocoaTouch/src/TestBTstackManager.m | 41 ++- TODO.txt | 3 +- project.xcodeproj/project.pbxproj | 8 +- 9 files changed, 517 insertions(+), 63 deletions(-) create mode 100644 CocoaTouch/include/BTstack/BTDiscoveryViewController.h create mode 100644 CocoaTouch/src/BTDiscoveryViewController.m diff --git a/CocoaTouch/TestBTstackManager-Info.plist b/CocoaTouch/TestBTstackManager-Info.plist index 789bf7877..af9a1cadb 100644 --- a/CocoaTouch/TestBTstackManager-Info.plist +++ b/CocoaTouch/TestBTstackManager-Info.plist @@ -16,7 +16,5 @@ ???? CFBundleVersion 1.0 - NSMainNibFile - MainWindow diff --git a/CocoaTouch/include/BTstack/BTDiscoveryViewController.h b/CocoaTouch/include/BTstack/BTDiscoveryViewController.h new file mode 100644 index 000000000..e00254c1c --- /dev/null +++ b/CocoaTouch/include/BTstack/BTDiscoveryViewController.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#import +#import + +@class BTstackManager; + +typedef enum { + kInquiryInactive, + kInquiryActive, + kInquiryRemoteName +} InquiryState; + +@interface BTDiscoveryViewController : UITableViewController +{ + BTstackManager *bt; + UIActivityIndicatorView *deviceActivity; + UIActivityIndicatorView *bluetoothActivity; + UIFont * deviceNameFont; + UIFont * macAddressFont; + InquiryState inquiryState; + int remoteNameIndex; + BOOL showIcons; +} +@property (nonatomic, assign) BOOL showIcons; +@end diff --git a/CocoaTouch/include/BTstack/BTstackManager.h b/CocoaTouch/include/BTstack/BTstackManager.h index b4cabcbe8..78c03da5a 100644 --- a/CocoaTouch/include/BTstack/BTstackManager.h +++ b/CocoaTouch/include/BTstack/BTstackManager.h @@ -67,12 +67,14 @@ typedef enum { } DiscoveryState; @protocol BTstackManagerDelegate; +@protocol BTstackManagerListener; @interface BTstackManager : NSObject { @private id _delegate; NSMutableDictionary *deviceInfo; - NSMutableArray *discoveredDevices; + NSMutableArray *discoveredDevices; + NSMutableSet *listeners; BOOL connectedToDaemon; ManagerState state; DiscoveryState discoveryState; @@ -82,9 +84,15 @@ typedef enum { // shared instance +(BTstackManager *) sharedInstance; +// listeners +-(void) addListener:(id)listener; +-(void) removeListener:(id)listener; + // Activation -(BTstackError) activate; -(BTstackError) deactivate; +-(BOOL) isActivating; +-(BOOL) isActive; // Discovery -(BTstackError) startDiscovery; @@ -111,8 +119,23 @@ typedef enum { @protocol BTstackManagerDelegate +@optional -// Everything is optional but you should implement all methods of a group +// Activation callbacks +-(BOOL) disableSystemBluetooth; // default: YES + +// Connection events +-(NSString*) pinForAddress:(bd_addr_t)addr; // default: "0000" + +// direct access +-(void) handlePacketWithType:(uint8_t) packet_type + forChannel:(uint16_t) channel + andData:(uint8_t *)packet + withLen:(uint16_t) size; +@end + + +@protocol BTstackManagerListener @optional // Activation events @@ -120,19 +143,12 @@ typedef enum { -(void) activationFailed:(BTstackError)error; -(void) deactivated; -// Activation callbacks --(BOOL) disableSystemBluetooth; // default: YES - // Discovery events: general -(void) deviceInfo:(BTDevice*)device; -(void) discoveryStopped; - -// Discovery events: UI -(void) discoveryInquiry; -(void) discoveryQueryRemoteName:(int)deviceIndex; -// Connection events --(NSString*) pinForAddress:(bd_addr_t)addr; // default: "0000" -(void) l2capChannelCreatedAtAddress:(bd_addr_t)addr withPSM:(uint16_t)psm asID:(uint16_t)channelID; -(void) l2capChannelCreateFailedAtAddress:(bd_addr_t)addr withPSM:(uint16_t)psm error:(BTstackError)error; @@ -145,11 +161,4 @@ typedef enum { -(void) rfcommDataReceivedForConnectionID:(uint16_t)connectionID withData:(uint8_t *)packet ofLen:(uint16_t)size; // TODO add l2cap and rfcomm incoming events - -// direct access --(void) handlePacketWithType:(uint8_t) packet_type - forChannel:(uint16_t) channel - andData:(uint8_t *)packet - withLen:(uint16_t) size; @end - diff --git a/CocoaTouch/src/BTDiscoveryViewController.m b/CocoaTouch/src/BTDiscoveryViewController.m new file mode 100644 index 000000000..549efff3d --- /dev/null +++ b/CocoaTouch/src/BTDiscoveryViewController.m @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2009 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#import +#import + +// fix compare for 3.0 +#ifndef __IPHONE_3_0 +#define __IPHONE_3_0 30000 +#endif + +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_0 +// SDK 30 defines missing in SDK 20 +@interface UITableViewCell (NewIn30) +- (id)initWithStyle:(int)style reuseIdentifier:(NSString *)reuseIdentifier; +@end +#endif + +@implementation BTDiscoveryViewController +@synthesize showIcons; + +- (id) init { + self = [super initWithStyle:UITableViewStyleGrouped]; + macAddressFont = [UIFont fontWithName:@"Courier New" size:[UIFont labelFontSize]]; + deviceNameFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; + inquiryState = kInquiryInactive; + + deviceActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [deviceActivity startAnimating]; + bluetoothActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [bluetoothActivity startAnimating]; + + bt = [BTstackManager sharedInstance]; + + return self; +} + +-(void) reload{ + [[self tableView] reloadData]; +} + +/* +- (id)initWithStyle:(UITableViewStyle)style { + // Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. + if (self = [super initWithStyle:style]) { + } + return self; +} +*/ + +/* +- (void)viewDidLoad { + [super viewDidLoad]; + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem; +} +*/ + +/* +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} +*/ +/* +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} +*/ +/* +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; +} +*/ +/* +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; +} +*/ + +/* +// Override to allow orientations other than the default portrait orientation. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return (interfaceOrientation == UIInterfaceOrientationPortrait); +} +*/ + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + +-(void) activated{ + [self reload]; +} +-(void) activationFailed:(BTstackError)error{ + [self reload]; +}; +-(void) discoveryInquiry { + inquiryState = kInquiryActive; + [self reload]; +} +-(void) discoveryQueryRemoteName:(int)deviceIndex { + inquiryState = kInquiryRemoteName; + remoteNameIndex = deviceIndex; + [self reload]; +} +-(void) deviceInfo:(BTDevice*)device { + [self reload]; +} + + +#pragma mark Table view methods + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ + return @"Devices"; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +// Customize the number of rows in the table view. +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return 1 + [bt numberOfDevicesFound]; +} + + +// Customize the appearance of table view cells. +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"Cell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0 + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; +#else + cell = [[[UITableViewCell alloc] initWithFrame:CGRectNull reuseIdentifier:(NSString *)CellIdentifier] autorelease]; +#endif + } + + // Set up the cell... + NSString *theLabel = nil; + UIImage *theImage = nil; + UIFont *theFont = nil; + + int idx = [indexPath indexAtPosition:1]; + if (idx >= [bt numberOfDevicesFound]) { + if ([bt isActivating]){ + theLabel = @"Activating BTstack..."; + cell.accessoryView = bluetoothActivity; + } else if (![bt isActive]){ + theLabel = @"Bluetooth not accessible!"; + cell.accessoryView = nil; + } else { +#if 0 + if (connectedDevice) { + theLabel = @"Disconnect"; + cell.accessoryView = nil; + } else if (remoteDevice) { + theLabel = @"Connecting..."; + cell.accessoryView = bluetoothActivity; + } else { +#endif + + switch (inquiryState){ + case kInquiryInactive: + if ([bt numberOfDevicesFound] > 0){ + theLabel = @"Find more devices..."; + } else { + theLabel = @"Find devices..."; + } + cell.accessoryView = nil; + break; + case kInquiryActive: + theLabel = @"Searching..."; + cell.accessoryView = bluetoothActivity; + break; + case kInquiryRemoteName: + theLabel = @"Query device names..."; + cell.accessoryView = bluetoothActivity; + break; + } +// } + } + } else { + + BTDevice *dev = [bt deviceAtIndex:idx]; + + // pick font + theLabel = [dev nameOrAddress]; + if ([dev name]){ + theFont = deviceNameFont; + } else { + theFont = macAddressFont; + } + + // pick an icon for the devices + if (showIcons) { + NSString *imageName = @"bluetooth.png"; + // check major device class + switch (([dev classOfDevice] & 0x1f00) >> 8) { + case 0x01: + imageName = @"computer.png"; + break; + case 0x02: + imageName = @"smartphone.png"; + break; + case 0x05: + switch ([dev classOfDevice] & 0xff){ + case 0x40: + imageName = @"keyboard.png"; + break; + case 0x80: + imageName = @"mouse.png"; + break; + case 0xc0: + imageName = @"keyboard.png"; + break; + default: + imageName = @"HID.png"; + break; + } + } + +#ifdef LASER_KB + if ([dev name] && [[dev name] isEqualToString:@"CL800BT"]){ + imageName = @"keyboard.png"; + } + + if ([dev name] && [[dev name] isEqualToString:@"CL850"]){ + imageName = @"keyboard.png"; + } + + // Celluon CL800BT, CL850 have 00-0b-24-aa-bb-cc, COD 0x400210 + uint8_t *addr = (uint8_t *) [dev address]; + if (addr[0] == 0x00 && addr[1] == 0x0b && addr[2] == 0x24){ + imageName = @"keyboard.png"; + } +#endif + theImage = [UIImage imageNamed:imageName]; + } + + // set accessory view + switch ([dev connectionState]) { + case kBluetoothConnectionNotConnected: + case kBluetoothConnectionConnected: + cell.accessoryView = nil; + break; + case kBluetoothConnectionConnecting: + case kBluetoothConnectionRemoteName: + cell.accessoryView = deviceActivity; + break; + } + } +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0 + if (theLabel) cell.textLabel.text = theLabel; + if (theFont) cell.textLabel.font = theFont; + if (theImage) cell.imageView.image = theImage; +#else + if (theLabel) cell.text = theLabel; + if (theFont) cell.font = theFont; + if (theImage) cell.image = theImage; +#endif + return cell; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // Navigation logic may go here. Create and push another view controller. + // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil]; + // [self.navigationController pushViewController:anotherViewController]; + // [anotherViewController release]; +} + +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // if (allowSelection) { + // return indexPath; + //} + return nil; +} + +- (void)dealloc { + [super dealloc]; +} + + +@end + diff --git a/CocoaTouch/src/BTstackManager.m b/CocoaTouch/src/BTstackManager.m index 8acf45786..8b45d99e6 100644 --- a/CocoaTouch/src/BTstackManager.m +++ b/CocoaTouch/src/BTstackManager.m @@ -50,17 +50,19 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe [btstackManager handlePacketWithType:packet_type forChannel:channel andData:packet withLen:size]; } -// dummy implementation of BTstackManagerDelegate protocol to avoid respondsToSelector call -@implementation NSObject (BTstackManagerDelegateDummy) +// dummy implementation of BTstackManagerListener and Delegate protocol to avoid respondsToSelector call +@implementation NSObject (BTstackManagerDummy) +// BTstackManagerDelegate +-(NSString*) pinForAddress:(bd_addr_t)addr { return @"0000"; }; // default: "0000" +-(BOOL) disableSystemBluetooth { return YES; }; // default: YES +// BTstackManagerListener -(void) activated {}; -(void) activationFailed:(BTstackError)error {}; -(void) deactivated {}; --(BOOL) disableSystemBluetooth { return YES; }; // default: YES -(void) deviceInfo:(BTDevice*)device {}; -(void) discoveryStopped {}; -(void) discoveryInquiry{}; -(void) discoveryQueryRemoteName:(int)deviceIndex{}; --(NSString*) pinForAddress:(bd_addr_t)addr { return @"0000"; }; // default: "0000" -(void) l2capChannelCreatedAtAddress:(bd_addr_t)addr withPSM:(uint16_t)psm asID:(uint16_t)channelID {}; -(void) l2capChannelCreateFailedAtAddress:(bd_addr_t)addr withPSM:(uint16_t)psm error:(BTstackError)error{}; -(void) l2capChannelClosedForChannelID:(uint16_t)channelID{}; @@ -85,11 +87,14 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe state = kDeactivated; discoveryState = kInactive; connectedToDaemon = NO; - _delegate = nil; // device discovery discoveredDevices = [[NSMutableArray alloc] init]; + // delegate and listener + _delegate = nil; + listeners = [[NSMutableArray alloc] init]; + // read device database [self readDeviceInfo]; @@ -109,6 +114,15 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe return btstackManager; } +// listeners +-(void) addListener:(id)listener{ + [listeners addObject:listener]; +} + +-(void) removeListener:(id)listener{ + [listeners removeObject:listener]; +} + // Activation -(BTstackError) activate { @@ -133,6 +147,13 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe return 0; } +-(BOOL) isActive { + return state == kActivated; +} + +-(BOOL) isActivating { + return state == kW4Activated; +} // Discovery -(BTstackError) startDiscovery { @@ -200,11 +221,15 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe bt_send_cmd(&btstack_set_system_bluetooth_enabled, 0); } else { state = kDeactivated; - [_delegate activationFailed:BTSTACK_ACTIVATION_FAILED_SYSTEM_BLUETOOTH]; + for (id listener in listeners) { + [listener activationFailed:BTSTACK_ACTIVATION_FAILED_SYSTEM_BLUETOOTH]; + } } } else { state = kDeactivated; - [_delegate activationFailed:BTSTACK_ACTIVATION_FAILED_UNKNOWN]; + for (id listener in listeners) { + [listener activationFailed:BTSTACK_ACTIVATION_FAILED_UNKNOWN]; + } } } else { state = kW4Activated; @@ -218,12 +243,16 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe case BTSTACK_EVENT_STATE: if (packet[2] == HCI_STATE_WORKING){ state = kActivated; - [_delegate activated]; + for (id listener in listeners) { + [listener activated]; + } } break; case BTSTACK_EVENT_POWERON_FAILED: - [_delegate activationFailed:BTSTACK_ACTIVATION_POWERON_FAILED]; state = kDeactivated; + for (id listener in listeners) { + [listener activationFailed:BTSTACK_ACTIVATION_POWERON_FAILED]; + } break; default: break; @@ -234,7 +263,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe if (packet[0] == BTSTACK_EVENT_STATE){ if (packet[2] == HCI_STATE_OFF){ state = kDeactivated; - [_delegate deactivated]; + for (id listener in listeners) { + [listener deactivated]; + } } } break; @@ -258,7 +289,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe // NSLog(@"Get remote name of %@", [BTDevice stringForAddress:addr]); bt_send_cmd(&hci_remote_name_request, addr, device.pageScanRepetitionMode, 0, device.clockOffset | 0x8000); - [_delegate discoveryQueryRemoteName:discoveryDeviceIndex]; + for (id listener in listeners) { + [listener discoveryQueryRemoteName:discoveryDeviceIndex]; + } found = YES; break; } @@ -266,7 +299,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe // printf("Queried all devices, restart.\n"); discoveryState = kInquiry; bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); - [_delegate discoveryInquiry]; + for (id listener in listeners) { + [listener discoveryInquiry]; + } } } @@ -284,7 +319,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe if (packet[0] == HCI_EVENT_COMMAND_COMPLETE && COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) { discoveryState = kInquiry; bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); - [_delegate discoveryInquiry]; + for (id listener in listeners) { + [listener discoveryInquiry]; + } } break; @@ -304,14 +341,19 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe device.classOfDevice = READ_BT_24(packet, 3 + numResponses*(6+1+1+1) + i*3); device.clockOffset = READ_BT_16(packet, 3 + numResponses*(6+1+1+1+3) + i*2) & 0x7fff; device.rssi = 0; +#if 0 // get name from deviceInfo - NSMutableDictionary * deviceDict = [deviceInfo objectForKey:[device addressString]]; + NSString *addrString = [[device addressString] retain]; + NSMutableDictionary * deviceDict = [deviceInfo objectForKey:addrString]; + [addrString release]; if (deviceDict){ device.name = [deviceDict objectForKey:PREFS_REMOTE_NAME]; } +#endif [discoveredDevices addObject:device]; - - [_delegate deviceInfo:device]; + for (id listener in listeners) { + [listener deviceInfo:device]; + } } break; @@ -328,14 +370,19 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe device.classOfDevice = READ_BT_24(packet, 3 + numResponses*(6+1+1) + i*3); device.clockOffset = READ_BT_16(packet, 3 + numResponses*(6+1+1+3) + i*2) & 0x7fff; device.rssi = packet [3 + numResponses*(6+1+1+3+2) + i*1]; +#if 0 // get name from deviceInfo - NSMutableDictionary * deviceDict = [deviceInfo objectForKey:[device addressString]]; + NSString *addrString = [[device addressString] retain]; + NSMutableDictionary * deviceDict = [deviceInfo objectForKey:addrString]; + [addrString release]; if (deviceDict){ device.name = [deviceDict objectForKey:PREFS_REMOTE_NAME]; } +#endif [discoveredDevices addObject:device]; - - [_delegate deviceInfo:device]; + for (id listener in listeners) { + [listener deviceInfo:device]; + } } break; @@ -360,15 +407,21 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe while (nameLen < 248 && packet[9+nameLen]) nameLen++; NSString *name = [[NSString alloc] initWithBytes:&packet[9] length:nameLen encoding:NSUTF8StringEncoding]; device.name = name; +#if 0 // set in device info - NSMutableDictionary *deviceDict = [deviceInfo objectForKey:[device addressString]]; + NSString *addrString = [[device addressString] retain]; + NSMutableDictionary * deviceDict = [deviceInfo objectForKey:addrString]; if (!deviceDict){ deviceDict = [NSMutableDictionary dictionaryWithCapacity:3]; - [deviceInfo setObject:deviceDict forKey:[device addressString]]; + [deviceInfo setObject:deviceDict forKey:addrString]; } [deviceDict setObject:name forKey:PREFS_REMOTE_NAME]; + [addrString release]; +#endif + for (id listener in listeners) { + [listener deviceInfo:device]; + } } - [_delegate deviceInfo:device]; discoveryDeviceIndex++; [self discoveryRemoteName]; } @@ -402,7 +455,6 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe default: break; } - [_delegate handlePacketWithType:packet_type forChannel:channel andData:packet withLen:size]; } @@ -419,6 +471,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe [deviceEntry addEntriesFromDictionary:value]; [deviceInfo setObject:deviceEntry forKey:key]; } + // NSLog(@"store prefs %@", deviceInfo ); } -(void)storeDeviceInfo{ diff --git a/CocoaTouch/src/TestBTstackManager.h b/CocoaTouch/src/TestBTstackManager.h index 89481c775..24ecb0ee6 100644 --- a/CocoaTouch/src/TestBTstackManager.h +++ b/CocoaTouch/src/TestBTstackManager.h @@ -8,9 +8,10 @@ #import @class BTstackManager; - -@interface TestBTstackManager : NSObject{ +@class BTDiscoveryViewController; +@interface TestBTstackManager : NSObject{ BTstackManager *bt; + BTDiscoveryViewController* discoveryView; } @end diff --git a/CocoaTouch/src/TestBTstackManager.m b/CocoaTouch/src/TestBTstackManager.m index 696bef35b..9b361b030 100644 --- a/CocoaTouch/src/TestBTstackManager.m +++ b/CocoaTouch/src/TestBTstackManager.m @@ -6,28 +6,20 @@ #import "TestBTstackManager.h" #import +#import @implementation TestBTstackManager --(void) doTest{ - bt = [BTstackManager sharedInstance]; - [bt setDelegate:self]; - BTstackError err = [bt activate]; - if (err) NSLog(@"activate err 0x%02x!", err); -} - -(void) activated{ NSLog(@"activated!"); [bt startDiscovery]; } - -(void) activationFailed:(BTstackError)error{ NSLog(@"activationFailed error 0x%02x!", error); }; - -(void) discoveryInquiry{ NSLog(@"discoveryInquiry!"); - [bt storeDeviceInfo]; + // [bt storeDeviceInfo]; } -(void) discoveryQueryRemoteName:(int)deviceIndex{ NSLog(@"discoveryQueryRemoteName %u/%u!", deviceIndex+1, [bt numberOfDevicesFound]); @@ -35,18 +27,31 @@ -(void) deviceInfo:(BTDevice*)device { NSLog(@"Device Info: addr %@ name %@ COD 0x%06x", [device addressString], [device name], [device classOfDevice] ); } - +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // create discovery controller + discoveryView = [[BTDiscoveryViewController alloc] init]; + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:discoveryView]; + UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + [window addSubview:nav.view]; + [window makeKeyAndVisible]; + + // BTstack + bt = [BTstackManager sharedInstance]; + [bt setDelegate:self]; + [bt addListener:self]; + [bt addListener:discoveryView]; + + BTstackError err = [bt activate]; + if (err) NSLog(@"activate err 0x%02x!", err); + +} @end int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - - TestBTstackManager * test = [[TestBTstackManager alloc] init]; - [test doTest]; - CFRunLoopRun(); - [test release]; - + int retVal = UIApplicationMain(argc, argv, nil, @"TestBTstackManager"); [pool release]; - return 0; + return retVal; } \ No newline at end of file diff --git a/TODO.txt b/TODO.txt index 79e10a56d..0b5946a1a 100644 --- a/TODO.txt +++ b/TODO.txt @@ -6,7 +6,8 @@ NEXT: - Provide BTstackManager Objective-C class - - create new device discovery view: BTDiscoveryViewController + - cache device names - working but crashes somehow + - support visualization of connections in BTDiscoveryViewController - implement l2cap code - implement rfcomm code diff --git a/project.xcodeproj/project.pbxproj b/project.xcodeproj/project.pbxproj index aaa00a416..9f3f7f480 100644 --- a/project.xcodeproj/project.pbxproj +++ b/project.xcodeproj/project.pbxproj @@ -35,6 +35,7 @@ 9CF3F782112F244C00D081C9 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CF3F781112F244B00D081C9 /* UIKit.framework */; }; 9CF3F95311306FFB00D081C9 /* TestBTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF3F95211306FFB00D081C9 /* TestBTstackManager.m */; }; 9CF3F99F113083F100D081C9 /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C13C9FC10ECED6300B04243 /* BTDevice.m */; }; + 9CF3FB1F113191E400D081C9 /* BTDiscoveryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF3FB1E113191E400D081C9 /* BTDiscoveryViewController.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -125,6 +126,8 @@ 9CF3F95111306FFB00D081C9 /* TestBTstackManager.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = TestBTstackManager.h; path = CocoaTouch/src/TestBTstackManager.h; sourceTree = ""; }; 9CF3F95211306FFB00D081C9 /* TestBTstackManager.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = TestBTstackManager.m; path = CocoaTouch/src/TestBTstackManager.m; sourceTree = ""; }; 9CF3F95A1130702D00D081C9 /* TestBTstackManager-Info.plist */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.plist.xml; name = "TestBTstackManager-Info.plist"; path = "CocoaTouch/TestBTstackManager-Info.plist"; sourceTree = ""; }; + 9CF3FB1E113191E400D081C9 /* BTDiscoveryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BTDiscoveryViewController.m; path = CocoaTouch/src/BTDiscoveryViewController.m; sourceTree = ""; }; + 9CF3FB201131920200D081C9 /* BTDiscoveryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BTDiscoveryViewController.h; path = CocoaTouch/include/BTstack/BTDiscoveryViewController.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -231,8 +234,10 @@ 9C13C9FC10ECED6300B04243 /* BTDevice.m */, 9C13C9FD10ECED6300B04243 /* BTInquiryViewController.h */, 9C13C9FE10ECED6300B04243 /* BTInquiryViewController.m */, - 9C509539112744AA00A30986 /* BTstackManager.m */, 9C50953B112744CD00A30986 /* BTstackManager.h */, + 9C509539112744AA00A30986 /* BTstackManager.m */, + 9CF3FB201131920200D081C9 /* BTDiscoveryViewController.h */, + 9CF3FB1E113191E400D081C9 /* BTDiscoveryViewController.m */, 9CF3F95111306FFB00D081C9 /* TestBTstackManager.h */, 9CF3F95211306FFB00D081C9 /* TestBTstackManager.m */, 9CF3F95A1130702D00D081C9 /* TestBTstackManager-Info.plist */, @@ -437,6 +442,7 @@ 9CF3F776112F241600D081C9 /* BTstackManager.m in Sources */, 9CF3F95311306FFB00D081C9 /* TestBTstackManager.m in Sources */, 9CF3F99F113083F100D081C9 /* BTDevice.m in Sources */, + 9CF3FB1F113191E400D081C9 /* BTDiscoveryViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };