added BTDiscoveryViewController as a cleaner implementation of BTInquiryViewController, split BTstackManagerDelegate into BTstackManagerDelegate and BTstackManagerListener

This commit is contained in:
matthias.ringwald 2010-02-21 19:13:34 +00:00
parent b2c95ae948
commit de4536005f
9 changed files with 517 additions and 63 deletions

View File

@ -16,7 +16,5 @@
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>NSMainNibFile</key>
<string>MainWindow</string>
</dict> </dict>
</plist> </plist>

View File

@ -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 <UIKit/UIKit.h>
#import <BTstack/BTstackManager.h>
@class BTstackManager;
typedef enum {
kInquiryInactive,
kInquiryActive,
kInquiryRemoteName
} InquiryState;
@interface BTDiscoveryViewController : UITableViewController<BTstackManagerListener>
{
BTstackManager *bt;
UIActivityIndicatorView *deviceActivity;
UIActivityIndicatorView *bluetoothActivity;
UIFont * deviceNameFont;
UIFont * macAddressFont;
InquiryState inquiryState;
int remoteNameIndex;
BOOL showIcons;
}
@property (nonatomic, assign) BOOL showIcons;
@end

View File

@ -67,12 +67,14 @@ typedef enum {
} DiscoveryState; } DiscoveryState;
@protocol BTstackManagerDelegate; @protocol BTstackManagerDelegate;
@protocol BTstackManagerListener;
@interface BTstackManager : NSObject { @interface BTstackManager : NSObject {
@private @private
id<BTstackManagerDelegate> _delegate; id<BTstackManagerDelegate> _delegate;
NSMutableDictionary *deviceInfo; NSMutableDictionary *deviceInfo;
NSMutableArray *discoveredDevices; NSMutableArray *discoveredDevices;
NSMutableSet *listeners;
BOOL connectedToDaemon; BOOL connectedToDaemon;
ManagerState state; ManagerState state;
DiscoveryState discoveryState; DiscoveryState discoveryState;
@ -82,9 +84,15 @@ typedef enum {
// shared instance // shared instance
+(BTstackManager *) sharedInstance; +(BTstackManager *) sharedInstance;
// listeners
-(void) addListener:(id<BTstackManagerListener>)listener;
-(void) removeListener:(id<BTstackManagerListener>)listener;
// Activation // Activation
-(BTstackError) activate; -(BTstackError) activate;
-(BTstackError) deactivate; -(BTstackError) deactivate;
-(BOOL) isActivating;
-(BOOL) isActive;
// Discovery // Discovery
-(BTstackError) startDiscovery; -(BTstackError) startDiscovery;
@ -111,8 +119,23 @@ typedef enum {
@protocol BTstackManagerDelegate @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 @optional
// Activation events // Activation events
@ -120,19 +143,12 @@ typedef enum {
-(void) activationFailed:(BTstackError)error; -(void) activationFailed:(BTstackError)error;
-(void) deactivated; -(void) deactivated;
// Activation callbacks
-(BOOL) disableSystemBluetooth; // default: YES
// Discovery events: general // Discovery events: general
-(void) deviceInfo:(BTDevice*)device; -(void) deviceInfo:(BTDevice*)device;
-(void) discoveryStopped; -(void) discoveryStopped;
// Discovery events: UI
-(void) discoveryInquiry; -(void) discoveryInquiry;
-(void) discoveryQueryRemoteName:(int)deviceIndex; -(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) 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) 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; -(void) rfcommDataReceivedForConnectionID:(uint16_t)connectionID withData:(uint8_t *)packet ofLen:(uint16_t)size;
// TODO add l2cap and rfcomm incoming events // 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 @end

View File

@ -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 <BTstack/BTDiscoveryViewController.h>
#import <BTstack/BTDevice.h>
// 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

View File

@ -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]; [btstackManager handlePacketWithType:packet_type forChannel:channel andData:packet withLen:size];
} }
// dummy implementation of BTstackManagerDelegate protocol to avoid respondsToSelector call // dummy implementation of BTstackManagerListener and Delegate protocol to avoid respondsToSelector call
@implementation NSObject (BTstackManagerDelegateDummy) @implementation NSObject (BTstackManagerDummy)
// BTstackManagerDelegate
-(NSString*) pinForAddress:(bd_addr_t)addr { return @"0000"; }; // default: "0000"
-(BOOL) disableSystemBluetooth { return YES; }; // default: YES
// BTstackManagerListener
-(void) activated {}; -(void) activated {};
-(void) activationFailed:(BTstackError)error {}; -(void) activationFailed:(BTstackError)error {};
-(void) deactivated {}; -(void) deactivated {};
-(BOOL) disableSystemBluetooth { return YES; }; // default: YES
-(void) deviceInfo:(BTDevice*)device {}; -(void) deviceInfo:(BTDevice*)device {};
-(void) discoveryStopped {}; -(void) discoveryStopped {};
-(void) discoveryInquiry{}; -(void) discoveryInquiry{};
-(void) discoveryQueryRemoteName:(int)deviceIndex{}; -(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) 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) l2capChannelCreateFailedAtAddress:(bd_addr_t)addr withPSM:(uint16_t)psm error:(BTstackError)error{};
-(void) l2capChannelClosedForChannelID:(uint16_t)channelID{}; -(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; state = kDeactivated;
discoveryState = kInactive; discoveryState = kInactive;
connectedToDaemon = NO; connectedToDaemon = NO;
_delegate = nil;
// device discovery // device discovery
discoveredDevices = [[NSMutableArray alloc] init]; discoveredDevices = [[NSMutableArray alloc] init];
// delegate and listener
_delegate = nil;
listeners = [[NSMutableArray alloc] init];
// read device database // read device database
[self readDeviceInfo]; [self readDeviceInfo];
@ -109,6 +114,15 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
return btstackManager; return btstackManager;
} }
// listeners
-(void) addListener:(id<BTstackManagerListener>)listener{
[listeners addObject:listener];
}
-(void) removeListener:(id<BTstackManagerListener>)listener{
[listeners removeObject:listener];
}
// Activation // Activation
-(BTstackError) activate { -(BTstackError) activate {
@ -133,6 +147,13 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
return 0; return 0;
} }
-(BOOL) isActive {
return state == kActivated;
}
-(BOOL) isActivating {
return state == kW4Activated;
}
// Discovery // Discovery
-(BTstackError) startDiscovery { -(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); bt_send_cmd(&btstack_set_system_bluetooth_enabled, 0);
} else { } else {
state = kDeactivated; state = kDeactivated;
[_delegate activationFailed:BTSTACK_ACTIVATION_FAILED_SYSTEM_BLUETOOTH]; for (id<BTstackManagerListener> listener in listeners) {
[listener activationFailed:BTSTACK_ACTIVATION_FAILED_SYSTEM_BLUETOOTH];
}
} }
} else { } else {
state = kDeactivated; state = kDeactivated;
[_delegate activationFailed:BTSTACK_ACTIVATION_FAILED_UNKNOWN]; for (id<BTstackManagerListener> listener in listeners) {
[listener activationFailed:BTSTACK_ACTIVATION_FAILED_UNKNOWN];
}
} }
} else { } else {
state = kW4Activated; state = kW4Activated;
@ -218,12 +243,16 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
case BTSTACK_EVENT_STATE: case BTSTACK_EVENT_STATE:
if (packet[2] == HCI_STATE_WORKING){ if (packet[2] == HCI_STATE_WORKING){
state = kActivated; state = kActivated;
[_delegate activated]; for (id<BTstackManagerListener> listener in listeners) {
[listener activated];
}
} }
break; break;
case BTSTACK_EVENT_POWERON_FAILED: case BTSTACK_EVENT_POWERON_FAILED:
[_delegate activationFailed:BTSTACK_ACTIVATION_POWERON_FAILED];
state = kDeactivated; state = kDeactivated;
for (id<BTstackManagerListener> listener in listeners) {
[listener activationFailed:BTSTACK_ACTIVATION_POWERON_FAILED];
}
break; break;
default: default:
break; 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[0] == BTSTACK_EVENT_STATE){
if (packet[2] == HCI_STATE_OFF){ if (packet[2] == HCI_STATE_OFF){
state = kDeactivated; state = kDeactivated;
[_delegate deactivated]; for (id<BTstackManagerListener> listener in listeners) {
[listener deactivated];
}
} }
} }
break; 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]); // NSLog(@"Get remote name of %@", [BTDevice stringForAddress:addr]);
bt_send_cmd(&hci_remote_name_request, addr, bt_send_cmd(&hci_remote_name_request, addr,
device.pageScanRepetitionMode, 0, device.clockOffset | 0x8000); device.pageScanRepetitionMode, 0, device.clockOffset | 0x8000);
[_delegate discoveryQueryRemoteName:discoveryDeviceIndex]; for (id<BTstackManagerListener> listener in listeners) {
[listener discoveryQueryRemoteName:discoveryDeviceIndex];
}
found = YES; found = YES;
break; 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"); // printf("Queried all devices, restart.\n");
discoveryState = kInquiry; discoveryState = kInquiry;
bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0);
[_delegate discoveryInquiry]; for (id<BTstackManagerListener> 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) ) { if (packet[0] == HCI_EVENT_COMMAND_COMPLETE && COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) {
discoveryState = kInquiry; discoveryState = kInquiry;
bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0);
[_delegate discoveryInquiry]; for (id<BTstackManagerListener> listener in listeners) {
[listener discoveryInquiry];
}
} }
break; 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.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.clockOffset = READ_BT_16(packet, 3 + numResponses*(6+1+1+1+3) + i*2) & 0x7fff;
device.rssi = 0; device.rssi = 0;
#if 0
// get name from deviceInfo // get name from deviceInfo
NSMutableDictionary * deviceDict = [deviceInfo objectForKey:[device addressString]]; NSString *addrString = [[device addressString] retain];
NSMutableDictionary * deviceDict = [deviceInfo objectForKey:addrString];
[addrString release];
if (deviceDict){ if (deviceDict){
device.name = [deviceDict objectForKey:PREFS_REMOTE_NAME]; device.name = [deviceDict objectForKey:PREFS_REMOTE_NAME];
} }
#endif
[discoveredDevices addObject:device]; [discoveredDevices addObject:device];
for (id<BTstackManagerListener> listener in listeners) {
[_delegate deviceInfo:device]; [listener deviceInfo:device];
}
} }
break; 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.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.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]; device.rssi = packet [3 + numResponses*(6+1+1+3+2) + i*1];
#if 0
// get name from deviceInfo // get name from deviceInfo
NSMutableDictionary * deviceDict = [deviceInfo objectForKey:[device addressString]]; NSString *addrString = [[device addressString] retain];
NSMutableDictionary * deviceDict = [deviceInfo objectForKey:addrString];
[addrString release];
if (deviceDict){ if (deviceDict){
device.name = [deviceDict objectForKey:PREFS_REMOTE_NAME]; device.name = [deviceDict objectForKey:PREFS_REMOTE_NAME];
} }
#endif
[discoveredDevices addObject:device]; [discoveredDevices addObject:device];
for (id<BTstackManagerListener> listener in listeners) {
[_delegate deviceInfo:device]; [listener deviceInfo:device];
}
} }
break; 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++; while (nameLen < 248 && packet[9+nameLen]) nameLen++;
NSString *name = [[NSString alloc] initWithBytes:&packet[9] length:nameLen encoding:NSUTF8StringEncoding]; NSString *name = [[NSString alloc] initWithBytes:&packet[9] length:nameLen encoding:NSUTF8StringEncoding];
device.name = name; device.name = name;
#if 0
// set in device info // set in device info
NSMutableDictionary *deviceDict = [deviceInfo objectForKey:[device addressString]]; NSString *addrString = [[device addressString] retain];
NSMutableDictionary * deviceDict = [deviceInfo objectForKey:addrString];
if (!deviceDict){ if (!deviceDict){
deviceDict = [NSMutableDictionary dictionaryWithCapacity:3]; deviceDict = [NSMutableDictionary dictionaryWithCapacity:3];
[deviceInfo setObject:deviceDict forKey:[device addressString]]; [deviceInfo setObject:deviceDict forKey:addrString];
} }
[deviceDict setObject:name forKey:PREFS_REMOTE_NAME]; [deviceDict setObject:name forKey:PREFS_REMOTE_NAME];
[addrString release];
#endif
for (id<BTstackManagerListener> listener in listeners) {
[listener deviceInfo:device];
}
} }
[_delegate deviceInfo:device];
discoveryDeviceIndex++; discoveryDeviceIndex++;
[self discoveryRemoteName]; [self discoveryRemoteName];
} }
@ -402,7 +455,6 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
default: default:
break; break;
} }
[_delegate handlePacketWithType:packet_type forChannel:channel andData:packet withLen:size]; [_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]; [deviceEntry addEntriesFromDictionary:value];
[deviceInfo setObject:deviceEntry forKey:key]; [deviceInfo setObject:deviceEntry forKey:key];
} }
// NSLog(@"store prefs %@", deviceInfo );
} }
-(void)storeDeviceInfo{ -(void)storeDeviceInfo{

View File

@ -8,9 +8,10 @@
#import <BTstack/BTstackManager.h> #import <BTstack/BTstackManager.h>
@class BTstackManager; @class BTstackManager;
@class BTDiscoveryViewController;
@interface TestBTstackManager : NSObject<BTstackManagerDelegate>{ @interface TestBTstackManager : NSObject<BTstackManagerDelegate,BTstackManagerListener>{
BTstackManager *bt; BTstackManager *bt;
BTDiscoveryViewController* discoveryView;
} }
@end @end

View File

@ -6,28 +6,20 @@
#import "TestBTstackManager.h" #import "TestBTstackManager.h"
#import <BTstack/BTDevice.h> #import <BTstack/BTDevice.h>
#import <BTstack/BTDiscoveryViewController.h>
@implementation TestBTstackManager @implementation TestBTstackManager
-(void) doTest{
bt = [BTstackManager sharedInstance];
[bt setDelegate:self];
BTstackError err = [bt activate];
if (err) NSLog(@"activate err 0x%02x!", err);
}
-(void) activated{ -(void) activated{
NSLog(@"activated!"); NSLog(@"activated!");
[bt startDiscovery]; [bt startDiscovery];
} }
-(void) activationFailed:(BTstackError)error{ -(void) activationFailed:(BTstackError)error{
NSLog(@"activationFailed error 0x%02x!", error); NSLog(@"activationFailed error 0x%02x!", error);
}; };
-(void) discoveryInquiry{ -(void) discoveryInquiry{
NSLog(@"discoveryInquiry!"); NSLog(@"discoveryInquiry!");
[bt storeDeviceInfo]; // [bt storeDeviceInfo];
} }
-(void) discoveryQueryRemoteName:(int)deviceIndex{ -(void) discoveryQueryRemoteName:(int)deviceIndex{
NSLog(@"discoveryQueryRemoteName %u/%u!", deviceIndex+1, [bt numberOfDevicesFound]); NSLog(@"discoveryQueryRemoteName %u/%u!", deviceIndex+1, [bt numberOfDevicesFound]);
@ -35,18 +27,31 @@
-(void) deviceInfo:(BTDevice*)device { -(void) deviceInfo:(BTDevice*)device {
NSLog(@"Device Info: addr %@ name %@ COD 0x%06x", [device addressString], [device name], [device classOfDevice] ); 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 @end
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"TestBTstackManager");
TestBTstackManager * test = [[TestBTstackManager alloc] init];
[test doTest];
CFRunLoopRun();
[test release];
[pool release]; [pool release];
return 0; return retVal;
} }

View File

@ -6,7 +6,8 @@
NEXT: NEXT:
- Provide BTstackManager Objective-C class - 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 l2cap code
- implement rfcomm code - implement rfcomm code

View File

@ -35,6 +35,7 @@
9CF3F782112F244C00D081C9 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CF3F781112F244B00D081C9 /* UIKit.framework */; }; 9CF3F782112F244C00D081C9 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CF3F781112F244B00D081C9 /* UIKit.framework */; };
9CF3F95311306FFB00D081C9 /* TestBTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF3F95211306FFB00D081C9 /* TestBTstackManager.m */; }; 9CF3F95311306FFB00D081C9 /* TestBTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF3F95211306FFB00D081C9 /* TestBTstackManager.m */; };
9CF3F99F113083F100D081C9 /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C13C9FC10ECED6300B04243 /* BTDevice.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 */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase 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 = "<group>"; }; 9CF3F95111306FFB00D081C9 /* TestBTstackManager.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = TestBTstackManager.h; path = CocoaTouch/src/TestBTstackManager.h; sourceTree = "<group>"; };
9CF3F95211306FFB00D081C9 /* TestBTstackManager.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = TestBTstackManager.m; path = CocoaTouch/src/TestBTstackManager.m; sourceTree = "<group>"; }; 9CF3F95211306FFB00D081C9 /* TestBTstackManager.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = TestBTstackManager.m; path = CocoaTouch/src/TestBTstackManager.m; sourceTree = "<group>"; };
9CF3F95A1130702D00D081C9 /* TestBTstackManager-Info.plist */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.plist.xml; name = "TestBTstackManager-Info.plist"; path = "CocoaTouch/TestBTstackManager-Info.plist"; sourceTree = "<group>"; }; 9CF3F95A1130702D00D081C9 /* TestBTstackManager-Info.plist */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.plist.xml; name = "TestBTstackManager-Info.plist"; path = "CocoaTouch/TestBTstackManager-Info.plist"; sourceTree = "<group>"; };
9CF3FB1E113191E400D081C9 /* BTDiscoveryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BTDiscoveryViewController.m; path = CocoaTouch/src/BTDiscoveryViewController.m; sourceTree = "<group>"; };
9CF3FB201131920200D081C9 /* BTDiscoveryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BTDiscoveryViewController.h; path = CocoaTouch/include/BTstack/BTDiscoveryViewController.h; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -231,8 +234,10 @@
9C13C9FC10ECED6300B04243 /* BTDevice.m */, 9C13C9FC10ECED6300B04243 /* BTDevice.m */,
9C13C9FD10ECED6300B04243 /* BTInquiryViewController.h */, 9C13C9FD10ECED6300B04243 /* BTInquiryViewController.h */,
9C13C9FE10ECED6300B04243 /* BTInquiryViewController.m */, 9C13C9FE10ECED6300B04243 /* BTInquiryViewController.m */,
9C509539112744AA00A30986 /* BTstackManager.m */,
9C50953B112744CD00A30986 /* BTstackManager.h */, 9C50953B112744CD00A30986 /* BTstackManager.h */,
9C509539112744AA00A30986 /* BTstackManager.m */,
9CF3FB201131920200D081C9 /* BTDiscoveryViewController.h */,
9CF3FB1E113191E400D081C9 /* BTDiscoveryViewController.m */,
9CF3F95111306FFB00D081C9 /* TestBTstackManager.h */, 9CF3F95111306FFB00D081C9 /* TestBTstackManager.h */,
9CF3F95211306FFB00D081C9 /* TestBTstackManager.m */, 9CF3F95211306FFB00D081C9 /* TestBTstackManager.m */,
9CF3F95A1130702D00D081C9 /* TestBTstackManager-Info.plist */, 9CF3F95A1130702D00D081C9 /* TestBTstackManager-Info.plist */,
@ -437,6 +442,7 @@
9CF3F776112F241600D081C9 /* BTstackManager.m in Sources */, 9CF3F776112F241600D081C9 /* BTstackManager.m in Sources */,
9CF3F95311306FFB00D081C9 /* TestBTstackManager.m in Sources */, 9CF3F95311306FFB00D081C9 /* TestBTstackManager.m in Sources */,
9CF3F99F113083F100D081C9 /* BTDevice.m in Sources */, 9CF3F99F113083F100D081C9 /* BTDevice.m in Sources */,
9CF3FB1F113191E400D081C9 /* BTDiscoveryViewController.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };