diff --git a/CocoaTouch/BTstackCocoa.xcodeproj/project.pbxproj b/CocoaTouch/BTstackCocoa.xcodeproj/project.pbxproj index 361d4499e..b27fe9e5c 100755 --- a/CocoaTouch/BTstackCocoa.xcodeproj/project.pbxproj +++ b/CocoaTouch/BTstackCocoa.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 9C04BB18107E9AD8002A63D0 /* BTstackCocoaAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C04BB15107E9AD8002A63D0 /* BTstackCocoaAppDelegate.m */; }; 9C04BB1F107E9B05002A63D0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C04BB1E107E9B05002A63D0 /* main.m */; }; 9C04BB2B107E9BF1002A63D0 /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C04BB2A107E9BF1002A63D0 /* logo.png */; }; + 9C04BBFF10824CDD002A63D0 /* libBTstack.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C04BBFE10824CDD002A63D0 /* libBTstack.dylib */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -32,6 +33,7 @@ 9C04BB1A107E9AEF002A63D0 /* BTInquiryViewController.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = BTInquiryViewController.h; path = include/BTstack/BTInquiryViewController.h; sourceTree = ""; }; 9C04BB1E107E9B05002A63D0 /* main.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = main.m; path = src/main.m; sourceTree = ""; }; 9C04BB2A107E9BF1002A63D0 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = logo.png; path = ../resources/logo.png; sourceTree = SOURCE_ROOT; }; + 9C04BBFE10824CDD002A63D0 /* libBTstack.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libBTstack.dylib; path = ../src/libBTstack.dylib; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -42,6 +44,7 @@ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 9C04BBFF10824CDD002A63D0 /* libBTstack.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,6 +62,7 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( + 9C04BBFE10824CDD002A63D0 /* libBTstack.dylib */, 9C04BB11107E9AC0002A63D0 /* Classes */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97317FDCFA39411CA2CEA /* Resources */, @@ -182,6 +186,10 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = BTstackCocoa_Prefix.pch; INFOPLIST_FILE = "BTstackCocoa-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../src\"", + ); PRODUCT_NAME = BTstackCocoa; }; name = Debug; @@ -194,6 +202,10 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = BTstackCocoa_Prefix.pch; INFOPLIST_FILE = "BTstackCocoa-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../src\"", + ); PRODUCT_NAME = BTstackCocoa; }; name = Release; @@ -202,12 +214,14 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = /Projects/iPhone/btstack/include; PREBINDING = NO; - SDKROOT = iphoneos3.0; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos2.0; }; name = Debug; }; @@ -215,12 +229,14 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = /Projects/iPhone/btstack/include; PREBINDING = NO; - SDKROOT = iphoneos3.0; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos2.0; }; name = Release; }; diff --git a/CocoaTouch/include/BTstack/BTDevice.h b/CocoaTouch/include/BTstack/BTDevice.h index 9cc6ea727..2cd057e1c 100644 --- a/CocoaTouch/include/BTstack/BTDevice.h +++ b/CocoaTouch/include/BTstack/BTDevice.h @@ -6,6 +6,7 @@ // #import +#include #define kCODHID 0x2540 #define kCODZeeMote 0x584 @@ -27,17 +28,25 @@ typedef enum { } BluetoothConnectionState; @interface BTDevice : NSObject { - NSString * address; + bd_addr_t address; NSString * name; + uint8_t pageScanRepetitionMode; + uint16_t clockOffset; uint32_t classOfDevice; BluetoothConnectionState connectionState; } +- (void) setAddress:(bd_addr_t *)addr; +- (bd_addr_t *) address; +- (NSString *) toString; ++ (NSString *) stringForAddress:(bd_addr_t *) address; + @property (readonly) BluetoothDeviceType deviceType; @property (readonly) NSString * nameOrAddress; -@property (nonatomic, copy) NSString * address; @property (nonatomic, copy) NSString * name; @property (nonatomic, assign) uint32_t classOfDevice; +@property (nonatomic, assign) uint16_t clockOffset; +@property (nonatomic, assign) uint8_t pageScanRepetitionMode; @property (nonatomic, assign) BluetoothConnectionState connectionState; @end diff --git a/CocoaTouch/include/BTstack/BTInquiryViewController.h b/CocoaTouch/include/BTstack/BTInquiryViewController.h index c905c3d40..25420a359 100644 --- a/CocoaTouch/include/BTstack/BTInquiryViewController.h +++ b/CocoaTouch/include/BTstack/BTInquiryViewController.h @@ -6,13 +6,7 @@ #import -typedef enum { - kBluetoothStateUnknown, - kBluetoothStateOn, - kBluetoothStateOff, - kBluetoothStateInitializing, - kBluetoothStateStopping -} BluetoothState; +#include // for HCI_STATE typedef enum { kInquiryInactive, @@ -22,11 +16,16 @@ typedef enum { @interface BTInquiryViewController : UITableViewController { NSMutableArray *devices; - BluetoothState bluetoothState; + HCI_STATE bluetoothState; InquiryState inquiryState; UIActivityIndicatorView *deviceActivity; + UIActivityIndicatorView *bluetoothActivity; + UIFont * deviceNameFont; + UIFont * macAddressFont; } +- (void) setBluetoothState:(HCI_STATE)state; +- (void) setInquiryState:(InquiryState)state; +- (InquiryState) inquiryState; +- (HCI_STATE) bluetoothState; @property (nonatomic, retain) NSMutableArray *devices; -@property (nonatomic, assign) BluetoothState bluetoothState; -@property (nonatomic, assign) InquiryState inquiryState; @end diff --git a/CocoaTouch/src/BTDevice.m b/CocoaTouch/src/BTDevice.m index edf4b2a79..97ebc9c72 100644 --- a/CocoaTouch/src/BTDevice.m +++ b/CocoaTouch/src/BTDevice.m @@ -9,21 +9,36 @@ @implementation BTDevice @synthesize name; -@synthesize address; @synthesize classOfDevice; @synthesize connectionState; +@synthesize pageScanRepetitionMode; +@synthesize clockOffset; - (BTDevice *)init { name = NULL; - address = @"00:00:00:00:00:00"; + bzero(&address, 6); classOfDevice = kCODInvalid; connectionState = kBluetoothConnectionNotConnected; return self; } +- (void) setAddress:(bd_addr_t *)newAddr{ + BD_ADDR_COPY( &address, newAddr); +} + +- (bd_addr_t *) address{ + return &address; +} + ++ (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[4], addr[5], addr[6]]; +} + - (NSString *) nameOrAddress{ if (name) return name; - return address; + return [BTDevice stringForAddress:&address]; } - (BluetoothDeviceType) deviceType{ @@ -36,10 +51,12 @@ return kBluetoothDeviceTypeGeneric; } } +- (NSString *) toString{ + return [NSString stringWithFormat:@"Device addr %@ name %@ COD %x", [BTDevice stringForAddress:&address], name, classOfDevice]; +} - (void)dealloc { [name release]; - [address release]; [super dealloc]; } diff --git a/CocoaTouch/src/BTInquiryViewController.m b/CocoaTouch/src/BTInquiryViewController.m index e9ca05cf1..bf3853507 100644 --- a/CocoaTouch/src/BTInquiryViewController.m +++ b/CocoaTouch/src/BTInquiryViewController.m @@ -10,20 +10,23 @@ @implementation BTInquiryViewController @synthesize devices; -@synthesize bluetoothState; -@synthesize inquiryState; -#define MOCKUP +// #define MOCKUP int mock_state = 0; - (id) init { self = [super initWithStyle:UITableViewStyleGrouped]; - bluetoothState = kBluetoothStateUnknown; + bluetoothState = HCI_STATE_OFF; inquiryState = kInquiryInactive; + + macAddressFont = [UIFont fontWithName:@"Courier New" size:[UIFont labelFontSize]]; + deviceNameFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; deviceActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; [deviceActivity startAnimating]; + bluetoothActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [bluetoothActivity startAnimating]; return self; } @@ -89,7 +92,7 @@ int mock_state = 0; // Customize the number of rows in the table view. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { int rows = 1; // 1 for status line - if (bluetoothState == kBluetoothStateOn) { + if (bluetoothState == HCI_STATE_WORKING) { rows += [devices count]; } return rows; @@ -103,17 +106,17 @@ int mock_state = 0; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { - cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; + cell = [[[UITableViewCell alloc] initWithStyle:/* UITableViewCellStyleDefault = */0 reuseIdentifier:CellIdentifier] autorelease]; // cell.selectionStyle = UITableViewCellSelectionStyleNone; } // Set up the cell... NSString *label = nil; int idx = [indexPath indexAtPosition:1]; - if (bluetoothState != kBluetoothStateOn || idx >= [devices count]) { - if (bluetoothState == kBluetoothStateInitializing){ + if (bluetoothState != HCI_STATE_WORKING || idx >= [devices count]) { + if (bluetoothState == HCI_STATE_INITIALIZING){ label = @"Activating BTstack..."; - cell.accessoryView = deviceActivity; + cell.accessoryView = bluetoothActivity; } else { switch (inquiryState){ case kInquiryInactive: @@ -126,17 +129,22 @@ int mock_state = 0; break; case kInquiryActive: label = @"Searching..."; - cell.accessoryView = deviceActivity; + cell.accessoryView = bluetoothActivity; break; case kInquiryRemoteName: label = @"Query device names..."; - cell.accessoryView = deviceActivity; + cell.accessoryView = bluetoothActivity; break; } } } else { BTDevice *dev = [devices objectAtIndex:idx]; label = [dev nameOrAddress]; + if ([dev name]){ + cell.font = deviceNameFont; + } else { + cell.font = macAddressFont; + } switch ([dev connectionState]) { case kBluetoothConnectionNotConnected: case kBluetoothConnectionConnected: @@ -148,7 +156,7 @@ int mock_state = 0; break; } } - [cell.textLabel setText:label]; + cell.text = label; return cell; } @@ -159,11 +167,12 @@ int mock_state = 0; // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil]; // [self.navigationController pushViewController:anotherViewController]; // [anotherViewController release]; + #ifdef MOCKUP switch (mock_state) { case 0: - bluetoothState = kBluetoothStateOn; + bluetoothState = HCI_STATE_WORKING; [tableView reloadData]; mock_state++; break; @@ -176,7 +185,8 @@ int mock_state = 0; case 2: case 3: { BTDevice * dev = [[BTDevice alloc] init]; - [dev setAddress:[NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x:", mock_state, mock_state, mock_state, mock_state, mock_state, mock_state]]; + bd_addr_t addr = { mock_state, mock_state, mock_state, mock_state, mock_state, mock_state}; + [dev setAddress:&addr]; [devices addObject:dev]; [tableView reloadData]; mock_state++; @@ -214,8 +224,25 @@ int mock_state = 0; } } #endif + } +- (void) setBluetoothState:(HCI_STATE)state { + bluetoothState = state; + [[self tableView] reloadData]; +} +- (void) setInquiryState:(InquiryState)state { + inquiryState = state; + [[self tableView] reloadData]; +} +- (InquiryState) inquiryState { + return inquiryState; +} +- (HCI_STATE) bluetoothState { + return bluetoothState; +} + + - (void)dealloc { [super dealloc]; diff --git a/CocoaTouch/src/BTstackCocoaAppDelegate.h b/CocoaTouch/src/BTstackCocoaAppDelegate.h index 5558f217a..0dea35d66 100644 --- a/CocoaTouch/src/BTstackCocoaAppDelegate.h +++ b/CocoaTouch/src/BTstackCocoaAppDelegate.h @@ -1,18 +1,25 @@ // // BTstackCocoaAppDelegate.h -// BTstackCocoa // // Created by Matthias Ringwald on 10/8/09. -// Copyright Dybuster AG 2009. All rights reserved. // #import +#import "BTInquiryViewController.h" + @interface BTstackCocoaAppDelegate : NSObject { UIWindow *window; + BTInquiryViewController *inqView; + bool inqActive; + NSMutableArray *devices; + uint8_t remoteNameIndex; } -@property (nonatomic, retain) IBOutlet UIWindow *window; +- (void) handlePacketWithType:(uint8_t) packetType data:(uint8_t*)data len:(uint16_t)len; +- (void) startInquiry; + +@property (nonatomic, retain) UIWindow *window; @end diff --git a/CocoaTouch/src/BTstackCocoaAppDelegate.m b/CocoaTouch/src/BTstackCocoaAppDelegate.m index f4e20623d..754123789 100644 --- a/CocoaTouch/src/BTstackCocoaAppDelegate.m +++ b/CocoaTouch/src/BTstackCocoaAppDelegate.m @@ -1,19 +1,166 @@ // // BTstackCocoaAppDelegate.m -// BTstackCocoa // // Created by Matthias Ringwald on 10/8/09. -// Copyright Dybuster AG 2009. All rights reserved. // #import "BTstackCocoaAppDelegate.h" -#import "BTInquiryViewController.h" #import "BTDevice.h" + +#include +#include +#include +#include + +#include +#include +#include + +// forward packet to Objective C method +void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ + [ ((BTstackCocoaAppDelegate *)[[UIApplication sharedApplication] delegate]) handlePacketWithType:packet_type data:packet len:size]; +} + @implementation BTstackCocoaAppDelegate @synthesize window; +- (BTDevice *) getDeviceForAddress:(bd_addr_t *)addr { + uint8_t j; + for (j=0; j<[devices count]; j++){ + BTDevice *dev = [devices objectAtIndex:j]; + if (BD_ADDR_CMP(addr, [dev address]) == 0){ + return dev; + } + } + return nil; +} + +- (bool) getNextRemoteName{ + BTDevice *remoteDev = nil; + for (remoteNameIndex = 0; remoteNameIndex < [devices count] ; remoteNameIndex++){ + BTDevice *dev = [devices objectAtIndex:remoteNameIndex]; + if (![dev name]){ + remoteDev = dev; + break; + } + } + if (remoteDev) { + [inqView setInquiryState:kInquiryRemoteName]; + [remoteDev setConnectionState:kBluetoothConnectionRemoteName]; + bt_send_cmd(&hci_remote_name_request, [remoteDev address], [remoteDev pageScanRepetitionMode], 0, [remoteDev clockOffset] | 0x8000); + } else { + [inqView setInquiryState:kInquiryInactive]; + // inquiry done. + } + return remoteDev; +} + +- (void) startInquiry { + if ([inqView inquiryState] != kInquiryInactive) { + NSLog(@"Inquiry already active"); + return; + } + NSLog(@"Inquiry started"); + [inqView setInquiryState:kInquiryActive]; + bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, 15, 0); +} + +- (void) handlePacketWithType:(uint8_t) packetType data:(uint8_t*) data len:(uint16_t) len { + + static bool inquiryDone = 0; + bd_addr_t event_addr; + switch (packetType) { + + case HCI_EVENT_PACKET: + + switch (data[0]){ + + case BTSTACK_EVENT_STATE: + // bt stack activated + [inqView setBluetoothState:data[2] ]; + + // set BT state + if (!inquiryDone && data[2] == HCI_STATE_WORKING) { + inquiryDone = true; + [self startInquiry]; + } + break; + + case HCI_EVENT_INQUIRY_RESULT: + case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: + { + int numResponses = data[2]; + int i; + for (i=0; i