From f73511baa0c8798e45c1f6bdf1b4e649274f72a8 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 28 Feb 2013 18:38:49 -0500 Subject: [PATCH] ios: Update WiiMote code using newer features from BTstack. Probably some bugs, so I recommend sticking with the nobtstack builds for now. --- ios/RetroArch.xcodeproj/project.pbxproj | 20 +- ios/RetroArch/BTStack/BTDevice.h | 25 +- ios/RetroArch/BTStack/BTDevice.m | 53 +- ...ntroller.h => BTDiscoveryViewController.h} | 65 +- .../BTStack/BTDiscoveryViewController.m | 351 +++++++++++ .../BTStack/BTInquiryViewController.m | 592 ------------------ ios/RetroArch/BTStack/BTstackManager.h | 188 ++++++ ios/RetroArch/BTStack/BTstackManager.m | 590 +++++++++++++++++ ios/RetroArch/BTStack/WiiMoteHelper.h | 17 +- ios/RetroArch/BTStack/WiiMoteHelper.m | 588 +++++++---------- ios/RetroArch/BTStack/btstack/btstack.h | 5 +- ios/RetroArch/BTStack/btstack/hci_cmds.h | 151 ++++- ios/RetroArch/BTStack/btstack/linked_list.h | 3 +- ios/RetroArch/BTStack/btstack/run_loop.h | 56 +- ios/RetroArch/BTStack/btstack/sdp_util.h | 37 +- ios/RetroArch/BTStack/btstack/utils.h | 28 +- ios/RetroArch/BTStack/wiimote.c | 202 +----- ios/RetroArch/BTStack/wiimote.h | 2 - ios/RetroArch/RetroArch_iOS.m | 2 +- ios/RetroArch/ios_input.m | 8 +- 20 files changed, 1695 insertions(+), 1288 deletions(-) rename ios/RetroArch/BTStack/{BTInquiryViewController.h => BTDiscoveryViewController.h} (55%) create mode 100644 ios/RetroArch/BTStack/BTDiscoveryViewController.m delete mode 100644 ios/RetroArch/BTStack/BTInquiryViewController.m create mode 100644 ios/RetroArch/BTStack/BTstackManager.h create mode 100644 ios/RetroArch/BTStack/BTstackManager.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index ed8e0023e8..1b23d66ec3 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -8,10 +8,11 @@ /* Begin PBXBuildFile section */ 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */; }; + 960DB2C416E0193D00F977E3 /* BTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 960DB2C216E0193D00F977E3 /* BTstackManager.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 960DB2C716E0197600F977E3 /* BTDiscoveryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 960DB2C616E0197600F977E3 /* BTDiscoveryViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 9614C6BB16DD7C00000B36EF /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6AE16DD7C00000B36EF /* BTDevice.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 9614C6BC16DD7C00000B36EF /* BTInquiryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6B016DD7C00000B36EF /* BTInquiryViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 9614C6BD16DD7C00000B36EF /* libBTstack.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9614C6B816DD7C00000B36EF /* libBTstack.dylib */; }; - 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */; }; 9614C6C116DD7D54000B36EF /* wiimote.c in Sources */ = {isa = PBXBuildFile; fileRef = 9614C6BF16DD7D54000B36EF /* wiimote.c */; }; 9614C6C416DDC018000B36EF /* autosave.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAE9D16C1D9A9009DE44C /* autosave.c */; }; 9614C6C516DDC018000B36EF /* cheats.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEA016C1D9A9009DE44C /* cheats.c */; }; @@ -176,10 +177,12 @@ /* Begin PBXFileReference section */ 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfoList.m; sourceTree = ""; }; + 960DB2C216E0193D00F977E3 /* BTstackManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTstackManager.m; sourceTree = ""; }; + 960DB2C316E0193D00F977E3 /* BTstackManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTstackManager.h; sourceTree = ""; }; + 960DB2C516E0197500F977E3 /* BTDiscoveryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDiscoveryViewController.h; sourceTree = ""; }; + 960DB2C616E0197600F977E3 /* BTDiscoveryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDiscoveryViewController.m; sourceTree = ""; }; 9614C6AD16DD7C00000B36EF /* BTDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTDevice.h; sourceTree = ""; }; 9614C6AE16DD7C00000B36EF /* BTDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTDevice.m; sourceTree = ""; }; - 9614C6AF16DD7C00000B36EF /* BTInquiryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTInquiryViewController.h; sourceTree = ""; }; - 9614C6B016DD7C00000B36EF /* BTInquiryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTInquiryViewController.m; sourceTree = ""; }; 9614C6B216DD7C00000B36EF /* btstack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = btstack.h; sourceTree = ""; }; 9614C6B316DD7C00000B36EF /* hci_cmds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hci_cmds.h; sourceTree = ""; }; 9614C6B416DD7C00000B36EF /* linked_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linked_list.h; sourceTree = ""; }; @@ -382,8 +385,10 @@ 9614C6B116DD7C00000B36EF /* btstack */, 9614C6AD16DD7C00000B36EF /* BTDevice.h */, 9614C6AE16DD7C00000B36EF /* BTDevice.m */, - 9614C6AF16DD7C00000B36EF /* BTInquiryViewController.h */, - 9614C6B016DD7C00000B36EF /* BTInquiryViewController.m */, + 960DB2C516E0197500F977E3 /* BTDiscoveryViewController.h */, + 960DB2C616E0197600F977E3 /* BTDiscoveryViewController.m */, + 960DB2C216E0193D00F977E3 /* BTstackManager.m */, + 960DB2C316E0193D00F977E3 /* BTstackManager.h */, 9614C6B816DD7C00000B36EF /* libBTstack.dylib */, 9614C6B916DD7C00000B36EF /* WiiMoteHelper.h */, 9614C6BA16DD7C00000B36EF /* WiiMoteHelper.m */, @@ -957,9 +962,10 @@ 96C19C3016D7045700FE8D5A /* RAConfig.m in Sources */, 965AE29E16D9BF94001D7667 /* ios_input.m in Sources */, 9614C6BB16DD7C00000B36EF /* BTDevice.m in Sources */, - 9614C6BC16DD7C00000B36EF /* BTInquiryViewController.m in Sources */, 9614C6BE16DD7C00000B36EF /* WiiMoteHelper.m in Sources */, 9614C6C116DD7D54000B36EF /* wiimote.c in Sources */, + 960DB2C416E0193D00F977E3 /* BTstackManager.m in Sources */, + 960DB2C716E0197600F977E3 /* BTDiscoveryViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/BTStack/BTDevice.h b/ios/RetroArch/BTStack/BTDevice.h index 43d018cce5..aa404ef6be 100644 --- a/ios/RetroArch/BTStack/BTDevice.h +++ b/ios/RetroArch/BTStack/BTDevice.h @@ -31,7 +31,6 @@ // // BTDevice.h -// BT-Keyboard // // Created by Matthias Ringwald on 3/30/09. // @@ -59,25 +58,35 @@ typedef enum { } BluetoothConnectionState; @interface BTDevice : NSObject { - bd_addr_t address; + + bd_addr_t _address; + NSString * name; + uint32_t classOfDevice; + uint8_t pageScanRepetitionMode; uint16_t clockOffset; - uint32_t classOfDevice; - BluetoothConnectionState connectionState; + + uint8_t rssi; + + // deprecated + BluetoothConnectionState connectionState; } -- (void) setAddress:(bd_addr_t *)addr; -- (bd_addr_t *) address; +- (void) setAddress:(bd_addr_t*)addr; +- (BOOL) setAddressFromString:(NSString *) addressString; +- (bd_addr_t*) address; - (NSString *) toString; -+ (NSString *) stringForAddress:(bd_addr_t *) address; - +- (NSString *) addressString; ++ (NSString *) stringForAddress:(bd_addr_t*) address; ++ (BOOL) address:(bd_addr_t *) address fromString:(NSString *) addressString; @property (readonly) BluetoothDeviceType deviceType; @property (readonly) NSString * nameOrAddress; @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) uint8_t rssi; @property (nonatomic, assign) BluetoothConnectionState connectionState; @end diff --git a/ios/RetroArch/BTStack/BTDevice.m b/ios/RetroArch/BTStack/BTDevice.m index 57fbc6df17..dbb14ebbb6 100644 --- a/ios/RetroArch/BTStack/BTDevice.m +++ b/ios/RetroArch/BTStack/BTDevice.m @@ -44,32 +44,67 @@ @synthesize connectionState; @synthesize pageScanRepetitionMode; @synthesize clockOffset; +@synthesize rssi; - (BTDevice *)init { name = NULL; - bzero(&address, 6); + memset(&_address, 0, 6); classOfDevice = kCODInvalid; connectionState = kBluetoothConnectionNotConnected; return self; } -- (void) setAddress:(bd_addr_t *)newAddr{ - BD_ADDR_COPY( &address, newAddr); +- (void) setAddress:(bd_addr_t*)newAddr{ + BD_ADDR_COPY( &_address, newAddr); } -- (bd_addr_t *) address{ - return &address; +- (BOOL) setAddressFromString:(NSString *) addressString{ + return [BTDevice address:&_address fromString:addressString]; } -+ (NSString *) stringForAddress:(bd_addr_t *) address { - uint8_t * addr = (uint8_t*) address; +- (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[3], addr[4], addr[5]]; } ++ (BOOL) address:(bd_addr_t *)address fromString:(NSString *) addressString{ + // support both : and - or NOTHING as separator + addressString = [addressString stringByReplacingOccurrencesOfString:@":" withString:@""]; + addressString = [addressString stringByReplacingOccurrencesOfString:@"-" withString:@""]; + if ([addressString length] != 12) return NO; + + unsigned int bd_addr_buffer[BD_ADDR_LEN]; //for sscanf, integer needed + // reset result buffer + int i; + for (i = 0; i < BD_ADDR_LEN; i++) { + bd_addr_buffer[i] = 0; + } + + // parse + int result = sscanf([addressString UTF8String], "%2x%2x%2x%2x%2x%2x", &bd_addr_buffer[0], &bd_addr_buffer[1], &bd_addr_buffer[2], + &bd_addr_buffer[3], &bd_addr_buffer[4], &bd_addr_buffer[5]); + // store + if (result == 6){ + for (i = 0; i < BD_ADDR_LEN; i++) { + (*address)[i] = (uint8_t) bd_addr_buffer[i]; + } + return YES; + } + return NO; +} + - (NSString *) nameOrAddress{ if (name) return name; - return [BTDevice stringForAddress:&address]; + return [self addressString]; +} + +- (NSString *) addressString{ + return [BTDevice stringForAddress:&_address]; } - (BluetoothDeviceType) deviceType{ @@ -83,7 +118,7 @@ } } - (NSString *) toString{ - return [NSString stringWithFormat:@"Device addr %@ name %@ COD %x", [BTDevice stringForAddress:&address], name, classOfDevice]; + return [NSString stringWithFormat:@"Device addr %@ name %@ COD %x", [BTDevice stringForAddress:&_address], name, classOfDevice]; } - (void)dealloc { diff --git a/ios/RetroArch/BTStack/BTInquiryViewController.h b/ios/RetroArch/BTStack/BTDiscoveryViewController.h similarity index 55% rename from ios/RetroArch/BTStack/BTInquiryViewController.h rename to ios/RetroArch/BTStack/BTDiscoveryViewController.h index b8638e142b..ab030db32a 100644 --- a/ios/RetroArch/BTStack/BTInquiryViewController.h +++ b/ios/RetroArch/BTStack/BTDiscoveryViewController.h @@ -28,20 +28,11 @@ * SUCH DAMAGE. * */ - -// -// BTInquiryViewController.h -// -// Created by Matthias Ringwald on 10/8/09. -// - #import +#import "BTstackManager.h" -#include "btstack/hci_cmds.h" // for HCI_STATE -#include "btstack/utils.h" - -@class BTDevice; -@protocol BTInquiryDelegate; +@class BTstackManager; +@protocol BTDiscoveryDelegate; typedef enum { kInquiryInactive, @@ -49,46 +40,28 @@ typedef enum { kInquiryRemoteName } InquiryState; -@interface BTInquiryViewController : UITableViewController +@interface BTDiscoveryViewController : UITableViewController { - NSMutableArray *devices; - HCI_STATE bluetoothState; - InquiryState inquiryState; + BTstackManager *bt; + NSObject * _delegate; UIActivityIndicatorView *deviceActivity; UIActivityIndicatorView *bluetoothActivity; UIFont * deviceNameFont; UIFont * macAddressFont; - id delegate; - bool allowSelection; - bool showIcons; - - // hacks - bool stopRemoteNameGathering; - bool restartInquiry; - BTDevice *remoteNameDevice; // device for which remote name request is pending - BTDevice *remoteDevice; // device for which connection is pending - BTDevice *connectedDevice; // device to which we're connected - bool notifyDelegateOnInquiryStopped; - + InquiryState inquiryState; + int remoteNameIndex; + BOOL showIcons; + int connectingIndex; + NSString *customActivityText; } - -- (void) startInquiry; -- (void) stopInquiry; - -- (void) showConnecting:(BTDevice *) device; -- (void) showConnected:(BTDevice *) device; - -- (void) removeDeviceForAddress:(bd_addr_t *)addr; - -@property (nonatomic, assign) bool allowSelection; -@property (nonatomic, assign) bool showIcons; -@property (nonatomic, retain) NSMutableArray *devices; -@property (nonatomic, retain) id delegate; +-(void) markConnecting:(int)index; // use -1 for no connection active +@property (nonatomic, assign) NSObject * delegate; +@property (nonatomic, assign) BOOL showIcons; +@property (nonatomic, retain) NSString *customActivityText; @end -@protocol BTInquiryDelegate -+ (void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) device; -+ (void) deviceDetected:(BTInquiryViewController *) inqView device:(BTDevice*) device; -+ (void) disconnectDevice:(BTInquiryViewController *) inqView device:(BTDevice*) device; -+ (void) inquiryStopped; +@protocol BTDiscoveryDelegate +@optional +-(BOOL) discoveryView:(BTDiscoveryViewController*)discoveryView willSelectDeviceAtIndex:(int)deviceIndex; // returns NO to ignore selection +-(void) statusCellSelectedDiscoveryView:(BTDiscoveryViewController*)discoveryView; @end diff --git a/ios/RetroArch/BTStack/BTDiscoveryViewController.m b/ios/RetroArch/BTStack/BTDiscoveryViewController.m new file mode 100644 index 0000000000..e79986c010 --- /dev/null +++ b/ios/RetroArch/BTStack/BTDiscoveryViewController.m @@ -0,0 +1,351 @@ +/* + * 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 "BTDiscoveryViewController.h" +#import "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 +@interface UIDevice (privateAPI) +-(BOOL) isWildcat; +@end + +@implementation BTDiscoveryViewController +@synthesize showIcons; +@synthesize delegate = _delegate; +@synthesize customActivityText; + +- (id) init { + self = [super initWithStyle:UITableViewStyleGrouped]; + macAddressFont = [UIFont fontWithName:@"Courier New" size:[UIFont labelFontSize]]; + deviceNameFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; + inquiryState = kInquiryInactive; + connectingIndex = -1; + + deviceActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [deviceActivity startAnimating]; + bluetoothActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [bluetoothActivity startAnimating]; + + bt = [BTstackManager sharedInstance]; + _delegate = nil; + 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. +} + */ + + +// BTstackManagerListenerDelegate +-(void) activatedBTstackManager:(BTstackManager*) manager{ + [self reload]; +} +-(void) btstackManager:(BTstackManager*)manager activationFailed:(BTstackError)error { + [self reload]; +} +-(void) discoveryInquiryBTstackManager:(BTstackManager*) manager { + inquiryState = kInquiryActive; + [self reload]; +} +-(void) btstackManager:(BTstackManager*)manager discoveryQueryRemoteName:(int)deviceIndex { + inquiryState = kInquiryRemoteName; + remoteNameIndex = deviceIndex; + [self reload]; +} +-(void) discoveryStoppedBTstackManager:(BTstackManager*) manager { + inquiryState = kInquiryInactive; + [self reload]; +} +-(void) btstackManager:(BTstackManager*)manager deviceInfo:(BTDevice*)device { + [self reload]; +} + +-(void) markConnecting:(int)index; { + connectingIndex = index; + [self reload]; +} + +-(void) setCustomActivityText:(NSString*) text{ + [text retain]; + [customActivityText release]; + customActivityText = text; + [self reload]; +} + +// 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 (customActivityText) { + theLabel = customActivityText; + cell.accessoryView = bluetoothActivity; + } else 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; + } +#endif + + if (connectingIndex >= 0) { + theLabel = @"Connecting..."; + cell.accessoryView = bluetoothActivity; + } else { + 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 + if (idx == connectingIndex){ + cell.accessoryView = deviceActivity; + } else { + cell.accessoryView = nil; + } + } +#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; +} + + +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if (!_delegate) return nil; + int index = [indexPath indexAtPosition:1]; + if (index >= [bt numberOfDevicesFound]){ + if ([_delegate respondsToSelector:@selector(statusCellSelectedDiscoveryView:)]){ + [_delegate statusCellSelectedDiscoveryView:self]; + return nil; + } + } + if ([_delegate respondsToSelector:@selector(discoveryView:willSelectDeviceAtIndex:)] && [_delegate discoveryView:self willSelectDeviceAtIndex:index]){ + return indexPath; + } + return nil; +} + +// Override to allow orientations other than the default portrait orientation. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + UIDevice * uiDevice = [UIDevice currentDevice]; + return [uiDevice respondsToSelector:@selector(isWildcat)] && [uiDevice isWildcat]; +} + +- (void)dealloc { + [super dealloc]; +} + + +@end + diff --git a/ios/RetroArch/BTStack/BTInquiryViewController.m b/ios/RetroArch/BTStack/BTInquiryViewController.m deleted file mode 100644 index d274a6a7d9..0000000000 --- a/ios/RetroArch/BTStack/BTInquiryViewController.m +++ /dev/null @@ -1,592 +0,0 @@ -/* - * 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. - * - */ - -// -// BTInquiryViewController.m -// -// Created by Matthias Ringwald on 10/8/09. -// - -#import "BTInquiryViewController.h" -#import "BTDevice.h" -#import - -#include "btstack/btstack.h" -//#include "wiimote.h" - -#define INQUIRY_INTERVAL 3 - -unsigned myosd_num_of_joys = 0; - -static BTInquiryViewController *inqView; -static btstack_packet_handler_t clientHandler; -static uint8_t remoteNameIndex; - -@interface BTInquiryViewController (Private) -- (void) handlePacket:(uint8_t) packet_type channel:(uint16_t) channel packet:(uint8_t*) packet size:(uint16_t) size; -- (BTDevice *) getDeviceForAddress:(bd_addr_t *)addr; -- (void) getNextRemoteName; -- (void) startInquiry; -@end - -static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ - if (inqView) { - [inqView handlePacket:packet_type channel:channel packet:packet size:size]; - } -} - -@implementation BTInquiryViewController - - -@synthesize devices; -@synthesize delegate; -@synthesize allowSelection; -@synthesize showIcons; - -- (id) init { - self = [super initWithStyle:UITableViewStyleGrouped]; - bluetoothState = HCI_STATE_OFF; - inquiryState = kInquiryInactive; - allowSelection = false; - showIcons = false; - remoteDevice = nil; - restartInquiry = true; - notifyDelegateOnInquiryStopped = false; - - 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]; - - devices = [[NSMutableArray alloc] init]; - inqView = self; - return self; -} - -- (void) myStartInquiry{ - if (inquiryState != kInquiryInactive) { - NSLog(@"Inquiry already active"); - return; - } - NSLog(@"Inquiry started"); - - stopRemoteNameGathering = false; - restartInquiry = true; - - inquiryState = kInquiryActive; - [[self tableView] reloadData]; - - bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); -} - -- (void) handlePacket:(uint8_t) packet_type channel:(uint16_t) channel packet:(uint8_t*) packet size:(uint16_t) size { - bd_addr_t event_addr; - switch (packet_type) { - - case HCI_EVENT_PACKET: - - switch (packet[0]){ - - case BTSTACK_EVENT_STATE: - { - // bt stack activated - bluetoothState = (HCI_STATE)packet[2]; - [[self tableView] reloadData]; - - // set BT state -/* - if (bluetoothState == HCI_STATE_WORKING) { - [self myStartInquiry]; - } -*/ - break; - } - case BTSTACK_EVENT_POWERON_FAILED: - { - bluetoothState = HCI_STATE_OFF; - [[self tableView] reloadData]; - - UIAlertView* alertView = [[UIAlertView alloc] init]; - alertView.title = @"Bluetooth not accessible!"; - alertView.message = @"Hardware initialization failed!\n" - "Make sure you have turned off Bluetooth in the System Settings."; - NSLog(@"Alert: %@ - %@", alertView.title, alertView.message); - [alertView addButtonWithTitle:@"Dismiss"]; - [alertView show]; - break; - } - case HCI_EVENT_INQUIRY_RESULT: - case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: - { - int numResponses = packet[2]; - int i; - for (i=0; i adding %@", [dev toString] ); - [devices addObject:dev]; - if (delegate) { - [delegate deviceDetected:self device:dev]; - } - } - - [[inqView tableView] reloadData]; - NSLog(@"bye" ); - break; - } - case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: - { - bt_flip_addr(event_addr, &packet[3]); - BTDevice *dev = [inqView getDeviceForAddress:&event_addr]; - if (!dev) break; - [dev setConnectionState:kBluetoothConnectionNotConnected]; - if (packet[2] == 0) { - [dev setName:[NSString stringWithUTF8String:(const char *) &packet[9]]]; - if (delegate) { - [delegate deviceDetected:self device:dev]; - } - } - [[self tableView] reloadData]; - remoteNameIndex++; - [self getNextRemoteName]; - break; - } - case HCI_EVENT_COMMAND_COMPLETE: - { - if (COMMAND_COMPLETE_EVENT(packet, hci_inquiry_cancel)){ - // inquiry canceled - NSLog(@"Inquiry cancelled successfully"); - inquiryState = kInquiryInactive; - [[self tableView] reloadData]; - if (notifyDelegateOnInquiryStopped){ - notifyDelegateOnInquiryStopped = false; - if (delegate) { - [delegate inquiryStopped]; - } - } - } - if (COMMAND_COMPLETE_EVENT(packet, hci_remote_name_request_cancel)){ - // inquiry canceled - NSLog(@"Remote name request cancelled successfully"); - inquiryState = kInquiryInactive; - [[self tableView] reloadData]; - if (notifyDelegateOnInquiryStopped){ - notifyDelegateOnInquiryStopped = false; - if (delegate) { - [delegate inquiryStopped]; - } - } - } - - break; - } - case HCI_EVENT_INQUIRY_COMPLETE: - { - NSLog(@"Inquiry complete"); - // reset name check - remoteNameIndex = 0; - [self getNextRemoteName]; - break; - } - default: - break; - - // hexdump(packet, size); - //break; - } - - default: - break; - } - // forward to client app - (*clientHandler)(packet_type, channel, packet, size); -} - -- (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; -} - - -- (void) removeDeviceForAddress:(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){ - NSLog(@"--> removed %@", [dev toString] ); - [devices removeObject:dev]; - [[self tableView] reloadData]; - return; - } - } - -} - -- (void) getNextRemoteName{ - - // stopped? - if (stopRemoteNameGathering) { - inquiryState = kInquiryInactive; - [[self tableView] reloadData]; - - if (notifyDelegateOnInquiryStopped){ - notifyDelegateOnInquiryStopped = false; - if (delegate) { - [delegate inquiryStopped]; - } - } - return; - } - - remoteNameDevice = nil; - - for (remoteNameIndex = 0; remoteNameIndex < [devices count]; remoteNameIndex++){ - BTDevice *dev = [devices objectAtIndex:remoteNameIndex]; - if (![dev name]){ - remoteNameDevice = dev; - break; - } - } - if (remoteNameDevice) { - inquiryState = kInquiryRemoteName; - [remoteNameDevice setConnectionState:kBluetoothConnectionRemoteName]; - bt_send_cmd(&hci_remote_name_request, [remoteNameDevice address], [remoteNameDevice pageScanRepetitionMode], 0, [remoteNameDevice clockOffset] | 0x8000); - } else { - inquiryState = kInquiryInactive; - // inquiry done. - if (restartInquiry) { - [self myStartInquiry]; - } - } - [[self tableView] reloadData]; -} - -- (void) startInquiry { - //static int b = 0; - //if(!b) - //{ - //b=1; - // put into loop - - // @TODO: cannot be called a second time! - clientHandler = bt_register_packet_handler(packet_handler); - - bluetoothState = HCI_STATE_INITIALIZING; - [[self tableView] reloadData]; - - stopRemoteNameGathering = false; - restartInquiry = true; - - bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON ); - //} -} - -- (void) stopInquiry { - - NSLog(@"stop inquiry called, state %u", inquiryState); - restartInquiry = false; - stopRemoteNameGathering = true; - bool immediateNotify = true; - - switch (inquiryState) { - case kInquiryActive: - // just stop inquiry - immediateNotify = false; - bt_send_cmd(&hci_inquiry_cancel); - break; - case kInquiryInactive: - NSLog(@"stop inquiry called although inquiry inactive?"); - break; - case kInquiryRemoteName: - if (remoteNameDevice) { - // just stop remote name request - immediateNotify = false; - bt_send_cmd(&hci_remote_name_request_cancel, [remoteNameDevice address]); - } - break; - default: - break; - } - if (immediateNotify && delegate){ - [delegate inquiryStopped]; - } else { - notifyDelegateOnInquiryStopped = true; - } -} - -- (void) showConnecting:(BTDevice *) device { - remoteDevice = device; - [[self tableView] reloadData]; -} - -- (void) showConnected:(BTDevice *) device { - connectedDevice = device; - [[self tableView] reloadData]; -} - -/* -- (void)loadView { - - [super loadView]; - -} -*/ -/* -- (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; - //return NO; - //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 { - // Release any retained subviews of the main view. - // e.g. self.myOutlet = nil; -} - -- (void)dealloc { - // unregister self - bt_register_packet_handler(clientHandler); - // done - [super dealloc]; -} - - -#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 { - int rows = 1; // 1 for status line - if (bluetoothState == HCI_STATE_WORKING) { - rows += [devices count]; - } - return rows; -} - - -// 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) { - cell = [[[UITableViewCell alloc] initWithStyle:/* UITableViewCellStyleDefault = */(UITableViewCellStyle)0 reuseIdentifier:CellIdentifier] autorelease]; - // cell.selectionStyle = UITableViewCellSelectionStyleNone; - } - - // Set up the cell... - NSString *label = nil; - int idx = [indexPath indexAtPosition:1]; - if (bluetoothState != HCI_STATE_WORKING || idx >= [devices count]) { - if (bluetoothState == HCI_STATE_INITIALIZING){ - label = @"Activating BTstack..."; - cell.accessoryView = bluetoothActivity; - } else if (bluetoothState == HCI_STATE_OFF){ - label = @"Bluetooth not accessible!"; - cell.accessoryView = nil; - } else { - if (connectedDevice) { - label = @"Disconnect"; - cell.accessoryView = nil; - } else if (remoteDevice) { - label = @"Connecting..."; - cell.accessoryView = bluetoothActivity; - } else { - switch (inquiryState){ - case kInquiryInactive: - if (myosd_num_of_joys==4) - { - label = @"Maximun devices connected!"; - } - else if ([devices count] > 0){ - label = @"Press here to find more devices..."; - } else { - label = @"Press here to find first device..."; - } - cell.accessoryView = nil; - break; - case kInquiryActive: - //label = @"Searching..."; - label = @"Press 1 and 2 on the WiiMote to sync"; - cell.accessoryView = bluetoothActivity; - break; - case kInquiryRemoteName: - label = @"Query device names..."; - cell.accessoryView = bluetoothActivity; - break; - } - } - } - } else { - BTDevice *dev = [devices objectAtIndex:idx]; - label = [dev nameOrAddress]; - if ([dev name]){ - cell.font = deviceNameFont; - } else { - cell.font = macAddressFont; - } - // pick an icon for the devices - if (showIcons) { - int major = ([dev classOfDevice] & 0x1f00) >> 8; - if (major == 0x01) { - cell.image = [UIImage imageNamed:@"computer.png"]; - } else if (major == 0x02) { - cell.image = [UIImage imageNamed:@"smartphone.png"]; - } else if ( major == 0x05 && ([dev classOfDevice] & 0xff) == 0x40){ - cell.image = [UIImage imageNamed:@"keyboard.png"]; - } else { - cell.image = [UIImage imageNamed:@"bluetooth.png"]; - } - } - switch ([dev connectionState]) { - case kBluetoothConnectionNotConnected: - case kBluetoothConnectionConnected: - cell.accessoryView = nil; - break; - case kBluetoothConnectionConnecting: - case kBluetoothConnectionRemoteName: - cell.accessoryView = deviceActivity; - break; - } - } - cell.text = label; - return cell; -} - - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - NSLog(@"didSelectRowAtIndexPath %@", 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]; - - // valid selection? - - - int idx = [indexPath indexAtPosition:1]; - //printf("sleccion %d\n",idx); - if (bluetoothState == HCI_STATE_WORKING) { - if (delegate) { - if (idx < [devices count]){ - [delegate deviceChoosen:self device:[devices objectAtIndex:idx]]; - } else if (idx == [devices count]) { - //printf("seleccionado %d %d\n",idx,connectedDevice); - if (connectedDevice) { - // DISCONNECT button - [delegate disconnectDevice:self device:connectedDevice]; - } else if (myosd_num_of_joys<4){ - // Find more devices - [self myStartInquiry]; - } - } - } - } else { - [tableView deselectRowAtIndexPath:indexPath animated:TRUE]; - } - -} - -- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (allowSelection) { - return indexPath; - } - return nil; -} - -@end - diff --git a/ios/RetroArch/BTStack/BTstackManager.h b/ios/RetroArch/BTStack/BTstackManager.h new file mode 100644 index 0000000000..cb1c4d8545 --- /dev/null +++ b/ios/RetroArch/BTStack/BTstackManager.h @@ -0,0 +1,188 @@ +/* + * 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. + * + */ + +#pragma once + +#import +#import +#import "btstack/btstack.h" + +#define PREFS_REMOTE_NAME @"RemoteName" +#define PREFS_LINK_KEY @"LinkKey" +#define BTstackManagerID @"ch.ringwald.btstack" + +@class BTDevice; + +/* + * Information on devices is stored in a system-wide plist + * it is maintained by BTstackManager + * this includes the link keys + */ + +// TODO enumerate BTstackError type +typedef int BTstackError; + +typedef enum { + kDeactivated = 1, + kW4SysBTState, + kW4SysBTDisabled, + kW4Activated, + kActivated, + kW4Deactivated, + kSleeping, +#if 0 + kW4DisoveryStopped, + kW4AuthenticationEnableCommand +#endif +} ManagerState; + +typedef enum { + kInactive = 1, + kW4InquiryMode, + kInquiry, + kRemoteName, + // stopping + kW4InquiryModeBeforeStop, + kW4InquiryStop, + kW4RemoteNameBeforeStop, +} DiscoveryState; + +@protocol BTstackManagerDelegate; +@protocol BTstackManagerListener; + +@interface BTstackManager : NSObject { +@private + NSObject* _delegate; + NSMutableArray *discoveredDevices; + NSMutableSet *listeners; + BOOL connectedToDaemon; + ManagerState state; + DiscoveryState discoveryState; + int discoveryDeviceIndex; +#if 0 + // current connection - kind a ugly + uint8_t connType; // 0 = L2CAP, 1 = RFCOMM + bd_addr_t connAddr; + uint16_t connPSM; + uint16_t connChan; + uint8_t connAuth; +#endif +} + +// 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; +-(BTstackError) stopDiscovery; +-(int) numberOfDevicesFound; +-(BTDevice*) deviceAtIndex:(int)index; +-(BOOL) isDiscoveryActive; + +// Link Key Management +-(void) dropLinkKeyForAddress:(bd_addr_t*) address; + +// Connections +-(BTstackError) createL2CAPChannelAtAddress:(bd_addr_t*) address withPSM:(uint16_t)psm authenticated:(BOOL)authentication; +-(BTstackError) closeL2CAPChannelWithID:(uint16_t) channelID; +-(BTstackError) sendL2CAPPacketForChannelID:(uint16_t)channelID; + +-(BTstackError) createRFCOMMConnectionAtAddress:(bd_addr_t*) address withChannel:(uint16_t)channel authenticated:(BOOL)authentication; +-(BTstackError) closeRFCOMMConnectionWithID:(uint16_t) connectionID; +-(BTstackError) sendRFCOMMPacketForChannelID:(uint16_t)connectionID; + + +// TODO add l2cap and rfcomm incoming commands +@property (nonatomic, assign) NSObject* delegate; +@property (nonatomic, retain) NSMutableArray *discoveredDevices; +@property (nonatomic, retain) NSMutableSet *listeners; +@end + + +@protocol BTstackManagerDelegate +@optional + +// Activation callbacks +-(BOOL) disableSystemBluetoothBTstackManager:(BTstackManager*) manager; // default: YES + +// Connection events +-(NSString*) btstackManager:(BTstackManager*) manager pinForAddress:(bd_addr_t)addr; // default: "0000" + +// direct access +-(void) btstackManager:(BTstackManager*) manager + handlePacketWithType:(uint8_t) packet_type + forChannel:(uint16_t) channel + andData:(uint8_t *)packet + withLen:(uint16_t) size; +@end + + +@protocol BTstackManagerListener +@optional + +// Activation events +-(void) activatedBTstackManager:(BTstackManager*) manager; +-(void) btstackManager:(BTstackManager*)manager activationFailed:(BTstackError)error; +-(void) deactivatedBTstackManager:(BTstackManager*) manager; + +// Power management events +-(void) sleepModeEnterBTstackManager:(BTstackManager*) manager; +-(void) sleepModeExtitBTstackManager:(BTstackManager*) manager; + +// Discovery events: general +-(void) btstackManager:(BTstackManager*)manager deviceInfo:(BTDevice*)device; +-(void) btstackManager:(BTstackManager*)manager discoveryQueryRemoteName:(int)deviceIndex; +-(void) discoveryStoppedBTstackManager:(BTstackManager*) manager; +-(void) discoveryInquiryBTstackManager:(BTstackManager*) manager; + +// Connection +-(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; +-(void) l2capDataReceivedForChannelID:(uint16_t)channelID withData:(uint8_t *)packet ofLen:(uint16_t)size; + +-(void) rfcommConnectionCreatedAtAddress:(bd_addr_t)addr forChannel:(uint16_t)channel asID:(uint16_t)connectionID; +-(void) rfcommConnectionCreateFailedAtAddress:(bd_addr_t)addr forChannel:(uint16_t)channel error:(BTstackError)error; +-(void) rfcommConnectionClosedForConnectionID:(uint16_t)connectionID; +-(void) rfcommDataReceivedForConnectionID:(uint16_t)connectionID withData:(uint8_t *)packet ofLen:(uint16_t)size; + +// TODO add l2cap and rfcomm incoming events +@end diff --git a/ios/RetroArch/BTStack/BTstackManager.m b/ios/RetroArch/BTStack/BTstackManager.m new file mode 100644 index 0000000000..301f5be4b8 --- /dev/null +++ b/ios/RetroArch/BTStack/BTstackManager.m @@ -0,0 +1,590 @@ +/* + * 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 "BTstackManager.h" + +#import "btstack/btstack.h" +#import "BTDevice.h" + +#define INQUIRY_INTERVAL 3 + +static BTstackManager * btstackManager = nil; + +@interface BTstackManager (privat) +- (void)handlePacketWithType:(uint8_t) packet_type forChannel:(uint16_t) channel andData:(uint8_t *)packet withLen:(uint16_t) size; +@end + +// needed for libBTstack +static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + [btstackManager handlePacketWithType:packet_type forChannel:channel andData:packet withLen:size]; +} + +@implementation BTstackManager + +@synthesize delegate = _delegate; +@synthesize listeners; +@synthesize discoveredDevices; + +-(BTstackManager *) init { + self = [super init]; + if (!self) return self; + + state = kDeactivated; + discoveryState = kInactive; + connectedToDaemon = NO; + + // device discovery + [self setDiscoveredDevices: [[NSMutableArray alloc] init]]; + + // delegate and listener + _delegate = nil; + [self setListeners:[[NSMutableSet alloc] init]]; + + // Use Cocoa run loop + run_loop_init(RUN_LOOP_COCOA); + + // our packet handler + bt_register_packet_handler(packet_handler); + + return self; +} + ++(BTstackManager *) sharedInstance { + if (!btstackManager) { + btstackManager = [[BTstackManager alloc] init]; + } + return btstackManager; +} + +// listeners +-(void) addListener:(id)listener{ + [listeners addObject:listener]; +} + +-(void) removeListener:(id)listener{ + [listeners removeObject:listener]; +} + +// send events +-(void) sendActivated { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(activatedBTstackManager:)]){ + [listener activatedBTstackManager:self]; + } + } +} +-(void) sendActivationFailed:(BTstackError)error { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(btstackManager:activationFailed:)]){ + [listener btstackManager:self activationFailed:error]; + } + } +} +-(void) sendDeactivated { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(deactivatedBTstackManager:)]){ + [listener deactivatedBTstackManager:self]; + } + } +} +-(void) sendSleepEnter { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(sleepModeEnterBTstackManager:)]){ + [listener sleepModeEnterBTstackManager:self]; + } + } +} +-(void) sendSleepExit { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(sleepModeExtitBTstackManager:)]){ + [listener sleepModeExtitBTstackManager:self]; + } + } +} +-(void) sendDiscoveryStoppedEvent { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(discoveryStoppedBTstackManager:)]){ + [listener discoveryStoppedBTstackManager:self]; + } + } +} +-(void) sendDiscoveryInquiry{ + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(discoveryInquiryBTstackManager:)]){ + [listener discoveryInquiryBTstackManager:self]; + } + } +} +-(void) sendDiscoveryQueryRemoteName:(int)index { + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(btstackManager:discoveryQueryRemoteName:)]){ + [listener btstackManager:self discoveryQueryRemoteName:index]; + } + } +} +-(void) sendDeviceInfo:(BTDevice*) device{ + for (NSObject* listener in listeners) { + if ([listener respondsToSelector:@selector(btstackManager:deviceInfo:)]){ + [listener btstackManager:self deviceInfo:device]; + } + } +} + + +// Activation +-(BTstackError) activate { + + BTstackError err = 0; + if (!connectedToDaemon) { + err = bt_open(); + if (err) return BTSTACK_CONNECTION_TO_BTDAEMON_FAILED; + } + connectedToDaemon = YES; + + // check system BT + state = kW4SysBTState; + bt_send_cmd(&btstack_get_system_bluetooth_enabled); + + return err; +} + +-(BTstackError) deactivate { + if (!connectedToDaemon) return BTSTACK_CONNECTION_TO_BTDAEMON_FAILED; + state = kW4Deactivated; + bt_send_cmd(&btstack_set_power_mode, HCI_POWER_OFF); + return 0; +} + +-(BOOL) isActive { + return state == kActivated; +} + +-(BOOL) isActivating { + switch (state){ + case kW4SysBTState: + case kW4SysBTDisabled: + case kW4Activated: + return YES; + default: + return NO; + } +} +-(BOOL) isDiscoveryActive { + return state == kActivated && (discoveryState != kInactive); +} + +// Discovery +-(BTstackError) startDiscovery { + if (state < kActivated) return BTSTACK_NOT_ACTIVATED; + + discoveryState = kW4InquiryMode; + bt_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI + return 0; +}; + +-(BTstackError) stopDiscovery{ + if (state < kActivated) return BTSTACK_NOT_ACTIVATED; + switch (discoveryState){ + case kInactive: + [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; +}; + +-(int) numberOfDevicesFound{ + return [discoveredDevices count]; +}; + +-(BTDevice*) deviceAtIndex:(int)index{ + return (BTDevice*) [discoveredDevices objectAtIndex:index]; +}; + +-(BTDevice*) deviceForAddress:(bd_addr_t*) address{ + for (BTDevice *device in discoveredDevices){ + // NSLog(@"compare %@ to %@", [BTDevice stringForAddress:address], [device addressString]); + if ( BD_ADDR_CMP(address, [device address]) == 0){ + return device; + } + } + return nil; +} + +- (void) activationHandleEvent:(uint8_t *)packet withLen:(uint16_t) size { + switch (state) { + + case kW4SysBTState: + case kW4SysBTDisabled: + + // BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED + if ( packet[0] == BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED){ + if (packet[2]){ + // system bt on - first time try to disable it + if ( state == kW4SysBTState) { + if (_delegate == nil + || ![_delegate respondsToSelector:@selector(disableSystemBluetoothBTstackManager:)] + || [_delegate disableSystemBluetoothBTstackManager:self]){ + state = kW4SysBTDisabled; + bt_send_cmd(&btstack_set_system_bluetooth_enabled, 0); + } else { + state = kDeactivated; + [self sendActivationFailed:BTSTACK_ACTIVATION_FAILED_SYSTEM_BLUETOOTH]; + } + } else { + state = kDeactivated; + [self sendActivationFailed:BTSTACK_ACTIVATION_FAILED_UNKNOWN]; + } + } else { + state = kW4Activated; + bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON); + } + } + break; + + case kW4Activated: + switch (packet[0]){ + case BTSTACK_EVENT_STATE: + if (packet[2] == HCI_STATE_WORKING) { + state = kActivated; + [self sendActivated]; + } + break; + case BTSTACK_EVENT_POWERON_FAILED: + state = kDeactivated; + [self sendActivationFailed:BTSTACK_ACTIVATION_POWERON_FAILED]; + break; + + default: + break; + } + break; + + case kW4Deactivated: + if (packet[0] != BTSTACK_EVENT_STATE && packet[2] == HCI_STATE_OFF){ + state = kDeactivated; + [self sendDeactivated]; + } + break; + + case kActivated: + if (packet[0] != BTSTACK_EVENT_STATE && packet[2] == HCI_STATE_FALLING_ASLEEP){ + state = kSleeping; + [self sendSleepEnter]; + } + break; + + case kSleeping: + if (packet[0] != BTSTACK_EVENT_STATE && packet[2] == HCI_STATE_WORKING){ + state = kActivated; + [self sendSleepExit]; + } + break; + + default: + break; + } +} + +-(void) discoveryRemoteName{ + BOOL found = NO; + while ( discoveryDeviceIndex < [discoveredDevices count]){ + BTDevice *device = [discoveredDevices objectAtIndex:discoveryDeviceIndex]; + if (device.name) { + discoveryDeviceIndex ++; + continue; + } + bt_send_cmd(&hci_remote_name_request, [device address], device.pageScanRepetitionMode, + 0, device.clockOffset | 0x8000); + [self sendDiscoveryQueryRemoteName:discoveryDeviceIndex]; + found = YES; + break; + } + if (!found) { + // printf("Queried all devices, restart.\n"); + discoveryState = kInquiry; + bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); + [self sendDiscoveryInquiry]; + } +} + +- (NSString *) createRemoteNameFromRemoteNameEvent:(uint8_t *) packet { + // get lenght: first null byte or max 248 chars + int nameLen = 0; + while (nameLen < 248 && packet[9+nameLen]) nameLen++; + // Bluetooth specification mandates UTF-8 encoding... + NSString *name = [[NSString alloc] initWithBytes:&packet[9] length:nameLen encoding:NSUTF8StringEncoding]; + // but fallback to latin-1 for non-standard products like old Microsoft Wireless Presenter + if (!name){ + name = [[NSString alloc] initWithBytes:&packet[9] length:nameLen encoding:NSISOLatin1StringEncoding]; + } + return name; +} + +- (void) handleRemoteNameCached: (uint8_t *) packet { + bd_addr_t addr; + bt_flip_addr(addr, &packet[3]); + // NSLog(@"Get remote name done for %@", [BTDevice stringForAddress:&addr]); + BTDevice* device = [self deviceForAddress:&addr]; + if (!device) return; + + [device setName:[self createRemoteNameFromRemoteNameEvent:packet]]; + [self sendDeviceInfo:device]; +} + +- (void) handleRemoteName: (uint8_t *) packet { + bd_addr_t addr; + bt_flip_addr(addr, &packet[3]); + // NSLog(@"Get remote name done for %@", [BTDevice stringForAddress:&addr]); + BTDevice* device = [self deviceForAddress:&addr]; + if (!device) return; + + [device setName:[self createRemoteNameFromRemoteNameEvent:packet]]; + [self sendDeviceInfo:device]; + + discoveryDeviceIndex++; + [self discoveryRemoteName]; +} + +-(void) discoveryHandleEvent:(uint8_t *)packet withLen:(uint16_t) size { + bd_addr_t addr; + int i; + int numResponses; + + switch (discoveryState) { + + case kInactive: + break; + + case kW4InquiryMode: + 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); + [self sendDiscoveryInquiry]; + } + break; + + case kInquiry: + + switch (packet[0]){ + case HCI_EVENT_INQUIRY_RESULT: + numResponses = packet[2]; + for (i=0; i -#import "BTInquiryViewController.h" - -@interface WiiMoteHelper : NSObject -{ -} - -+ (void)startwiimote:(UIViewController *)controller; -+ (void)endwiimote; -+ (void)cancelWiiMoteSearch; +#import "BTDiscoveryViewController.h" +@interface WiiMoteHelper : NSObject ++ (WiiMoteHelper*)get; +- (void)showDiscovery; @end - - - - diff --git a/ios/RetroArch/BTStack/WiiMoteHelper.m b/ios/RetroArch/BTStack/WiiMoteHelper.m index 8898040797..83ce023447 100644 --- a/ios/RetroArch/BTStack/WiiMoteHelper.m +++ b/ios/RetroArch/BTStack/WiiMoteHelper.m @@ -37,391 +37,241 @@ #import "WiiMoteHelper.h" #import "BTDevice.h" -#import "BTInquiryViewController.h" +#import "BTstackManager.h" +#import "BTDiscoveryViewController.h" #import "btstack/btstack.h" #import "btstack/run_loop.h" #import "btstack/hci_cmds.h" -bool btOK = false; -bool initLoop = false; -BTDevice *device; -uint16_t wiiMoteConHandle = 0; -bool conected = false; -bool activated = false; - -BTInquiryViewController *inqViewControl; - -void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ - bd_addr_t event_addr; - - - switch (packet_type) { - - case L2CAP_DATA_PACKET://0x06 - { - struct wiimote_t *wm = NULL; - - wm = wiimote_get_by_source_cid(channel); - - if(wm!=NULL) - { - - byte* msg = packet + 2; - byte event = packet[1]; - - switch (event) { - case WM_RPT_BTN: - { - /* button */ - wiimote_pressed_buttons(wm, msg); - break; - } - case WM_RPT_READ: - { - /* data read */ - - if(WIIMOTE_DBG)printf("WM_RPT_READ data arrive!\n"); - - wiimote_pressed_buttons(wm, msg); - - byte err = msg[2] & 0x0F; - - if (err == 0x08) - printf("Unable to read data - address does not exist.\n"); - else if (err == 0x07) - printf("Unable to read data - address is for write-only registers.\n"); - else if (err) - printf("Unable to read data - unknown error code %x.\n", err); - - unsigned short offset = BIG_ENDIAN_SHORT(*(unsigned short*)(msg + 3)); - - byte len = ((msg[2] & 0xF0) >> 4) + 1; - - byte *data = (msg + 5); - - if(WIIMOTE_DBG) - { - int i = 0; - printf("Read: 0x%04x ; ",offset); - for (; i < len; ++i) - printf("%x ", data[i]); - printf("\n"); - } - - if(wiimote_handshake(wm,WM_RPT_READ,data,len)) - { - //btUsed = 1; - [inqViewControl showConnected:nil]; - [inqViewControl showConnecting:nil]; - //Create UIAlertView alert - [inqViewControl showConnecting:nil]; - - UIAlertView* alert = - [[UIAlertView alloc] initWithTitle:@"Connection detected!" - message: [NSString stringWithFormat:@"%@ '%@' connection sucessfully completed!", - (wm->exp.type != EXP_NONE ? @"Classic Controller" : @"WiiMote"), - [NSNumber numberWithInt:(wm->unid)+1]] - delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; - [alert show]; - //[alert dismissWithClickedButtonIndex:0 animated:TRUE]; - [alert release]; - - if(device!=nil) - { - [device setConnectionState:kBluetoothConnectionConnected]; - device = nil; - } - - } - - return; - } - case WM_RPT_CTRL_STATUS: - { - wiimote_pressed_buttons(wm, msg); - - /* find the battery level and normalize between 0 and 1 */ - if(WIIMOTE_DBG) - { - wm->battery_level = (msg[5] / (float)WM_MAX_BATTERY_CODE); - - printf("BATTERY LEVEL %f\n", wm->battery_level); - } - - //handshake stuff! - if(wiimote_handshake(wm,WM_RPT_CTRL_STATUS,msg,-1)) - { - //btUsed = 1; - [inqViewControl showConnected:nil]; - [inqViewControl showConnecting:nil]; - UIAlertView* alert = - [[UIAlertView alloc] initWithTitle:@"Connection detected!" - message: [NSString stringWithFormat:@"WiiMote '%@' connection sucessfully completed!",[NSNumber numberWithInt:(wm->unid)+1]] - delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; - [alert show]; - //[alert dismissWithClickedButtonIndex:0 animated:TRUE]; - [alert release]; - [device setConnectionState:kBluetoothConnectionConnected]; - - if(device!=nil) - { - [device setConnectionState:kBluetoothConnectionConnected]; - device = nil; - } - } - - return; - } - case WM_RPT_BTN_EXP: - { - /* button - expansion */ - wiimote_pressed_buttons(wm, msg); - wiimote_handle_expansion(wm, msg+2); - - break; - } - case WM_RPT_WRITE: - { - /* write feedback - safe to skip */ - break; - } - default: - { - printf("Unknown event, can not handle it [Code 0x%x].", event); - return; - } - } - } - break; - } - case HCI_EVENT_PACKET://0x04 - { - switch (packet[0]){ - - case L2CAP_EVENT_CHANNEL_OPENED: - - // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) - if (packet[2] == 0) { - - // inform about new l2cap connection - bt_flip_addr(event_addr, &packet[3]); - uint16_t psm = READ_BT_16(packet, 11); - uint16_t source_cid = READ_BT_16(packet, 13); - wiiMoteConHandle = READ_BT_16(packet, 9); - NSLog(@"Channel successfully opened: handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x", - wiiMoteConHandle, psm, source_cid, READ_BT_16(packet, 15)); - - if (psm == 0x13) { - - // interupt channel openedn succesfully, now open control channel, too. - if(WIIMOTE_DBG)printf("open control channel\n"); - bt_send_cmd(&l2cap_create_channel, event_addr, 0x11); - struct wiimote_t *wm = NULL; - wm = &joys[myosd_num_of_joys]; - memset(wm, 0, sizeof(struct wiimote_t)); - wm->unid = myosd_num_of_joys; - wm->i_source_cid = source_cid; - memcpy(&wm->addr,&event_addr,BD_ADDR_LEN); - if(WIIMOTE_DBG)printf("addr %02x:%02x:%02x:%02x:%02x:%02x\n", wm->addr[0], wm->addr[1], wm->addr[2],wm->addr[3], wm->addr[4], wm->addr[5]); - if(WIIMOTE_DBG)printf("saved 0x%02x 0x%02x\n",source_cid,wm->i_source_cid); - wm->exp.type = EXP_NONE; - - } else { - - //inicializamos el wiimote! - struct wiimote_t *wm = NULL; - wm = &joys[myosd_num_of_joys]; - wm->wiiMoteConHandle = wiiMoteConHandle; - wm->c_source_cid = source_cid; - wm->state = WIIMOTE_STATE_CONNECTED; - myosd_num_of_joys++; - if(WIIMOTE_DBG)printf("Devices Number: %d\n",myosd_num_of_joys); - wiimote_handshake(wm,-1,NULL,-1); - } - } - break; - case L2CAP_EVENT_CHANNEL_CLOSED: - { - // data: event (8), len(8), channel (16) - uint16_t source_cid = READ_BT_16(packet, 2); - NSLog(@"Channel successfully closed: cid 0x%02x",source_cid); - - bd_addr_t addr; - int unid = wiimote_remove(source_cid,&addr); - if(unid!=-1) - { - [inqViewControl removeDeviceForAddress:&addr]; - UIAlertView* alert = - [[UIAlertView alloc] initWithTitle:@"Disconnection!" - message:[NSString stringWithFormat:@"WiiMote '%@' disconnection detected.\nIs battery drainned?",[NSNumber numberWithInt:(unid+1)]] - delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; - [alert show]; - - [alert release]; - } - - } - break; - - default: - break; - } - break; - } - default: - break; - } -} +static BTDevice *device; +static uint16_t wiiMoteConHandle = 0; +static bool btOK; +static WiiMoteHelper* instance; @implementation WiiMoteHelper - -+(void) startwiimote:(UIViewController *)controller{ - - if(!initLoop) - { - run_loop_init(RUN_LOOP_COCOA); - initLoop = true; - } - if(!btOK ) - { - if (bt_open() ){ - // Alert user? - } else { - bt_register_packet_handler(packet_handler); - btOK = true; - } - } - - if (btOK) - { - // create inq controller - if(inqViewControl==nil) - { - inqViewControl = [[BTInquiryViewController alloc] init]; - - struct CGRect rect = controller.view.frame; - - CGFloat navBarWidht = rect.size.width; - CGFloat navBarHeight = 45; - - UINavigationBar *navBar = [ [ UINavigationBar alloc ] initWithFrame: CGRectMake(0, 0, navBarWidht , navBarHeight)]; - [navBar autorelease]; - [navBar setDelegate: inqViewControl ]; - - UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - [button setFrame:CGRectMake(rect.size.width-70,5,60,35)]; - [button setTitle:@"Done" forState:UIControlStateNormal]; - button.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; - [button addTarget:self action:@selector(cancelWiiMoteSearch) forControlEvents:UIControlEventTouchUpInside]; - - [navBar addSubview:button]; - - UILabel *navLabel = [[UILabel alloc] initWithFrame:CGRectMake(40,0,300, navBarHeight)]; - navLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; - navLabel.text = @"WiiMote Sync"; - navLabel.backgroundColor = [UIColor clearColor]; - navLabel.textColor = [UIColor blackColor]; - navLabel.font = [UIFont systemFontOfSize: 18]; - navLabel.textAlignment = UITextAlignmentLeft; - [navBar addSubview:navLabel]; - [navLabel release]; - - [[inqViewControl tableView] setTableHeaderView:navBar]; - [navBar release]; - - } - - if(!activated) - { - - - UIAlertView* alertView=[[UIAlertView alloc] initWithTitle:nil - message:@"are you sure you to activate BTstack?" - delegate:self cancelButtonTitle:nil - otherButtonTitles:@"Yes",@"No",nil]; - - [alertView show]; - [alertView release]; - } - - [controller presentModalViewController:inqViewControl animated:YES]; - - } - -} - -+ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex ++ (WiiMoteHelper*)get { - - if(buttonIndex == 0 ) - { - [inqViewControl setDelegate:self]; - [inqViewControl setAllowSelection:true]; - activated = true; - [inqViewControl startInquiry]; - } - else - { - [inqViewControl dismissModalViewControllerAnimated:YES]; - } + if (!instance) + { + instance = [WiiMoteHelper new]; + } + + return instance; } -+(void) cancelWiiMoteSearch { - [inqViewControl stopInquiry]; - [inqViewControl dismissModalViewControllerAnimated:YES]; -} - - -+(void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) deviceChoosen; +- (id)init { - NSLog(@"deviceChoosen %@", [device toString]); + if (!btOK) + { + BTstackManager* bt = [BTstackManager sharedInstance]; + [bt setDelegate:self]; + [bt addListener:self]; + + btOK = [bt activate] == 0; + } + + return self; } -+ (void) deviceDetected:(BTInquiryViewController *) inqView device:(BTDevice*) selectedDevice { +- (void)dealloc +{ + // TODO: Any other cleanup needed + [[BTstackManager sharedInstance] deactivate]; +} - NSLog(@"deviceDetected %@", [device toString]); - if ([selectedDevice name] && [[selectedDevice name] caseInsensitiveCompare:@"Nintendo RVL-CNT-01"] == NSOrderedSame){ - NSLog(@"WiiMote found with address %@", [BTDevice stringForAddress:[selectedDevice address]]); - device = selectedDevice; - +- (void)showDiscovery +{ + BTDiscoveryViewController* vc = [BTDiscoveryViewController new]; + [vc setDelegate:self]; + + [[BTstackManager sharedInstance] addListener:vc]; + + [[RetroArch_iOS get] pushViewController:vc isGame:NO]; +} + +// BTStackManagerListener +-(void) activatedBTstackManager:(BTstackManager*) manager +{ + [[BTstackManager sharedInstance] startDiscovery]; +} + +-(void) btstackManager:(BTstackManager*)manager deviceInfo:(BTDevice*)newDevice +{ + if ([newDevice name] && [[newDevice name] hasPrefix:@"Nintendo RVL-CNT-01"]) + { + device = newDevice; + [[BTstackManager sharedInstance] stopDiscovery]; + } +} + +-(void) discoveryStoppedBTstackManager:(BTstackManager*) manager +{ + bt_send_cmd(&hci_write_authentication_enable, 0); +} + +// BTStackManagerDelegate +-(void) btstackManager:(BTstackManager*) manager + handlePacketWithType:(uint8_t) packet_type + forChannel:(uint16_t) channel + andData:(uint8_t *)packet + withLen:(uint16_t) size +{ + bd_addr_t event_addr; + + switch (packet_type) + { + case L2CAP_DATA_PACKET://0x06 + { + struct wiimote_t *wm = wiimote_get_by_source_cid(channel); - [inqViewControl stopInquiry]; + if (wm != NULL) + { + byte* msg = packet + 2; + byte event = packet[1]; + + switch (event) + { + case WM_RPT_BTN: + { + wiimote_pressed_buttons(wm, msg); + break; + } + + case WM_RPT_READ: + { + /* data read */ + wiimote_pressed_buttons(wm, msg); + + byte len = ((msg[2] & 0xF0) >> 4) + 1; + byte *data = (msg + 5); + + if(wiimote_handshake(wm, WM_RPT_READ, data, len)) + { + if (device != nil) + { + [device setConnectionState:kBluetoothConnectionConnected]; + device = nil; + } + } + + return; + } + + case WM_RPT_CTRL_STATUS: + { + wiimote_pressed_buttons(wm, msg); + + //handshake stuff! + if(wiimote_handshake(wm,WM_RPT_CTRL_STATUS,msg,-1)) + { + [device setConnectionState:kBluetoothConnectionConnected]; + + if (device != nil) + { + [device setConnectionState:kBluetoothConnectionConnected]; + device = nil; + } + } + + return; + } + + case WM_RPT_BTN_EXP: + { + /* button - expansion */ + wiimote_pressed_buttons(wm, msg); + wiimote_handle_expansion(wm, msg+2); + + break; + } - [inqViewControl showConnecting:device]; + case WM_RPT_WRITE: + { + /* write feedback - safe to skip */ + break; + } - // connect to device - [device setConnectionState:kBluetoothConnectionConnecting]; - [[inqViewControl tableView] reloadData]; - bt_send_cmd(&l2cap_create_channel, [device address], 0x13); - - - } + default: + { + printf("Unknown event, can not handle it [Code 0x%x].", event); + return; + } + } + } + break; + } + + case HCI_EVENT_PACKET://0x04 + { + switch (packet[0]) + { + case HCI_EVENT_COMMAND_COMPLETE: + { + if (COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable)) + bt_send_cmd(&l2cap_create_channel, [device address], PSM_HID_INTERRUPT); + break; + } + + case HCI_EVENT_PIN_CODE_REQUEST: + { + bt_flip_addr(event_addr, &packet[2]); + if (BD_ADDR_CMP([device address], event_addr)) break; + + // inform about pin code request + NSLog(@"HCI_EVENT_PIN_CODE_REQUEST\n"); + bt_send_cmd(&hci_pin_code_request_reply, event_addr, 6, &packet[2]); // use inverse bd_addr as PIN + break; + } + + case L2CAP_EVENT_CHANNEL_OPENED: + { + // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) + if (packet[2] == 0) + { + // inform about new l2cap connection + bt_flip_addr(event_addr, &packet[3]); + uint16_t psm = READ_BT_16(packet, 11); + uint16_t source_cid = READ_BT_16(packet, 13); + wiiMoteConHandle = READ_BT_16(packet, 9); + + if (psm == 0x13) + { + // interupt channel openedn succesfully, now open control channel, too. + bt_send_cmd(&l2cap_create_channel, event_addr, 0x11); + struct wiimote_t *wm = &joys[myosd_num_of_joys]; + memset(wm, 0, sizeof(struct wiimote_t)); + wm->unid = myosd_num_of_joys; + wm->i_source_cid = source_cid; + memcpy(&wm->addr,&event_addr,BD_ADDR_LEN); + wm->exp.type = EXP_NONE; + } + else + { + //inicializamos el wiimote! + struct wiimote_t *wm = &joys[myosd_num_of_joys]; + wm->wiiMoteConHandle = wiiMoteConHandle; + wm->c_source_cid = source_cid; + wm->state = WIIMOTE_STATE_CONNECTED; + myosd_num_of_joys++; + wiimote_handshake(wm,-1,NULL,-1); + } + } + + break; + } + + case L2CAP_EVENT_CHANNEL_CLOSED: + { + // data: event (8), len(8), channel (16) + uint16_t source_cid = READ_BT_16(packet, 2); + + bd_addr_t addr; + wiimote_remove(source_cid,&addr); + break; + } + } + } + } } - -+ (void) inquiryStopped{ -} - -+ (void) disconnectDevice:(BTInquiryViewController *) inqView device:(BTDevice*) selectedDevice { -} - -+ (void)endwiimote { - - if(btOK) - { - int i=0; - while(i!=myosd_num_of_joys){ - [inqViewControl removeDeviceForAddress:&joys[i].addr]; - i++; - } - - myosd_num_of_joys=0; - bt_send_cmd(&btstack_set_power_mode, HCI_POWER_OFF ); - bt_close(); - activated= false; - btOK = false; - } -} - @end - diff --git a/ios/RetroArch/BTStack/btstack/btstack.h b/ios/RetroArch/BTStack/btstack/btstack.h index 04a2e146f4..03c02a0fb2 100644 --- a/ios/RetroArch/BTStack/btstack/btstack.h +++ b/ios/RetroArch/BTStack/btstack/btstack.h @@ -64,10 +64,10 @@ typedef void (*btstack_packet_handler_t) (uint8_t packet_type, uint16_t channel, void bt_use_tcp(const char * address, uint16_t port); // init BTstack library -int bt_open(); +int bt_open(void); // stop using BTstack library -int bt_close(); +int bt_close(void); // send hci cmd packet int bt_send_cmd(const hci_cmd_t *cmd, ...); @@ -79,6 +79,7 @@ btstack_packet_handler_t bt_register_packet_handler(btstack_packet_handler_t han void bt_send_acl(uint8_t * data, uint16_t len); void bt_send_l2cap(uint16_t local_cid, uint8_t *data, uint16_t len); +void bt_send_rfcomm(uint16_t rfcom_cid, uint8_t *data, uint16_t len); #if defined __cplusplus } diff --git a/ios/RetroArch/BTStack/btstack/hci_cmds.h b/ios/RetroArch/BTStack/btstack/hci_cmds.h index cfb36cc7a1..a6e6bf4ea9 100644 --- a/ios/RetroArch/BTStack/btstack/hci_cmds.h +++ b/ios/RetroArch/BTStack/btstack/hci_cmds.h @@ -53,13 +53,23 @@ extern "C" { // extension for client/server communication #define DAEMON_EVENT_PACKET 0x05 - + // L2CAP data #define L2CAP_DATA_PACKET 0x06 // RFCOMM data -#define RFCOMM_DATA_PACKET 0x07 +#define RFCOMM_DATA_PACKET 0x07 +// Attribute protocol data +#define ATT_DATA_PACKET 0x08 + +// Security Manager protocol data +#define SM_DATA_PACKET 0x09 + +// debug log messages +#define LOG_MESSAGE_PACKET 0xfc + + // Fixed PSM numbers #define PSM_SDP 0x01 #define PSM_RFCOMM 0x03 @@ -74,7 +84,7 @@ extern "C" { #define HCI_EVENT_DISCONNECTION_COMPLETE 0x05 #define HCI_EVENT_AUTHENTICATION_COMPLETE_EVENT 0x06 #define HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE 0x07 -#define HCI_EVENT_ENCRIPTION_CHANGE 0x08 +#define HCI_EVENT_ENCRYPTION_CHANGE 0x08 #define HCI_EVENT_CHANGE_CONNECTION_LINK_KEY_COMPLETE 0x09 #define HCI_EVENT_MASTER_LINK_KEY_COMPLETE 0x0A #define HCI_EVENT_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE 0x0B @@ -97,12 +107,21 @@ extern "C" { #define HCI_EVENT_PACKET_TYPE_CHANGED 0x1D #define HCI_EVENT_INQUIRY_RESULT_WITH_RSSI 0x22 #define HCI_EVENT_EXTENDED_INQUIRY_RESPONSE 0x2F +#define HCI_EVENT_LE_META 0x3E #define HCI_EVENT_VENDOR_SPECIFIC 0xFF +#define HCI_SUBEVENT_LE_CONNECTION_COMPLETE 0x01 +#define HCI_SUBEVENT_LE_ADVERTISING_REPORT 0x02 +#define HCI_SUBEVENT_LE_CONNECTION_UPDATE_COMPLETE 0x03 +#define HCI_SUBEVENT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +#define HCI_SUBEVENT_LE_LONG_TERM_KEY_REQUEST 0x05 + // last used HCI_EVENT in 2.1 is 0x3d // events 0x50-0x5f are used internally +// BTSTACK DAEMON EVENTS + // events from BTstack for application/client lib #define BTSTACK_EVENT_STATE 0x60 @@ -118,25 +137,61 @@ extern "C" { // data: system bluetooth on/off (bool) #define BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED 0x64 -// data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) +// data: event (8), len(8), status (8) == 0, address (48), name (1984 bits = 248 bytes) +#define BTSTACK_EVENT_REMOTE_NAME_CACHED 0x65 + +// data: discoverable enabled (bool) +#define BTSTACK_EVENT_DISCOVERABLE_ENABLED 0x66 + +// L2CAP EVENTS + +// data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16), local_mtu(16), remote_mtu(16) #define L2CAP_EVENT_CHANNEL_OPENED 0x70 // data: event (8), len(8), channel (16) #define L2CAP_EVENT_CHANNEL_CLOSED 0x71 -// data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) +// data: event (8), len(8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) #define L2CAP_EVENT_INCOMING_CONNECTION 0x72 // data: event(8), len(8), handle(16) #define L2CAP_EVENT_TIMEOUT_CHECK 0x73 -// data: event(8), len(8), handle(16) +// data: event(8), len(8), local_cid(16), credits(8) #define L2CAP_EVENT_CREDITS 0x74 -// data: event(8), len(8), service_record_handle(32) -#define SDP_SERVICE_REGISTERED 0x80 +// data: event(8), len(8), status (8), psm (16) +#define L2CAP_EVENT_SERVICE_REGISTERED 0x75 +// RFCOMM EVENTS + +// data: event(8), len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16) +#define RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE 0x80 + +// data: event(8), len(8), rfcomm_cid(16) +#define RFCOMM_EVENT_CHANNEL_CLOSED 0x81 + +// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) +#define RFCOMM_EVENT_INCOMING_CONNECTION 0x82 + +// data: event (8), len(8), rfcommid (16), ... +#define RFCOMM_EVENT_REMOTE_LINE_STATUS 0x83 + +// data: event(8), len(8), rfcomm_cid(16), credits(8) +#define RFCOMM_EVENT_CREDITS 0x84 + +// data: event(8), len(8), status (8), rfcomm server channel id (8) +#define RFCOMM_EVENT_SERVICE_REGISTERED 0x85 + +// data: event(8), len(8), status (8), rfcomm server channel id (8) +#define RFCOMM_EVENT_PERSISTENT_CHANNEL 0x86 + + +// data: event(8), len(8), status(8), service_record_handle(32) +#define SDP_SERVICE_REGISTERED 0x90 + + // last error code in 2.1 is 0x38 - we start with 0x50 for BTstack errors #define BTSTACK_CONNECTION_TO_BTDAEMON_FAILED 0x50 @@ -145,6 +200,8 @@ extern "C" { #define BTSTACK_ACTIVATION_FAILED_UNKNOWN 0x53 #define BTSTACK_NOT_ACTIVATED 0x54 #define BTSTACK_BUSY 0x55 +#define BTSTACK_MEMORY_ALLOC_FAILED 0x56 +#define BTSTACK_ACL_BUFFERS_FULL 0x57 // l2cap errors - enumeration by the command that created them #define L2CAP_COMMAND_REJECT_REASON_COMMAND_NOT_UNDERSTOOD 0x60 @@ -161,7 +218,14 @@ extern "C" { #define L2CAP_CONFIG_RESPONSE_RESULT_UNACCEPTABLE_PARAMS 0x67 #define L2CAP_CONFIG_RESPONSE_RESULT_REJECTED 0x68 #define L2CAP_CONFIG_RESPONSE_RESULT_UNKNOWN_OPTIONS 0x69 +#define L2CAP_SERVICE_ALREADY_REGISTERED 0x6a + +#define RFCOMM_MULTIPLEXER_STOPPED 0x70 +#define RFCOMM_CHANNEL_ALREADY_REGISTERED 0x71 +#define RFCOMM_NO_OUTGOING_CREDITS 0x72 +#define SDP_HANDLE_ALREADY_REGISTERED 0x80 + /** * Default INQ Mode */ @@ -171,7 +235,8 @@ extern "C" { */ typedef enum { HCI_POWER_OFF = 0, - HCI_POWER_ON + HCI_POWER_ON, + HCI_POWER_SLEEP } HCI_POWER_MODE; /** @@ -181,7 +246,9 @@ typedef enum { HCI_STATE_OFF = 0, HCI_STATE_INITIALIZING, HCI_STATE_WORKING, - HCI_STATE_HALTING + HCI_STATE_HALTING, + HCI_STATE_SLEEPING, + HCI_STATE_FALLING_ASLEEP } HCI_STATE; /** @@ -200,9 +267,12 @@ extern const hci_cmd_t btstack_set_acl_capture_mode; extern const hci_cmd_t btstack_get_version; extern const hci_cmd_t btstack_get_system_bluetooth_enabled; extern const hci_cmd_t btstack_set_system_bluetooth_enabled; - +extern const hci_cmd_t btstack_set_discoverable; +extern const hci_cmd_t btstack_set_bluetooth_enabled; // only used by btstack config + extern const hci_cmd_t hci_accept_connection_request; extern const hci_cmd_t hci_authentication_requested; +extern const hci_cmd_t hci_change_connection_link_key; extern const hci_cmd_t hci_create_connection; extern const hci_cmd_t hci_create_connection_cancel; extern const hci_cmd_t hci_delete_stored_link_key; @@ -217,25 +287,64 @@ extern const hci_cmd_t hci_pin_code_request_negative_reply; extern const hci_cmd_t hci_qos_setup; extern const hci_cmd_t hci_read_bd_addr; extern const hci_cmd_t hci_read_buffer_size; +extern const hci_cmd_t hci_read_le_host_supported; extern const hci_cmd_t hci_read_link_policy_settings; extern const hci_cmd_t hci_read_link_supervision_timeout; +extern const hci_cmd_t hci_read_local_supported_features; +extern const hci_cmd_t hci_read_num_broadcast_retransmissions; +extern const hci_cmd_t hci_reject_connection_request; extern const hci_cmd_t hci_remote_name_request; extern const hci_cmd_t hci_remote_name_request_cancel; extern const hci_cmd_t hci_reset; extern const hci_cmd_t hci_role_discovery; extern const hci_cmd_t hci_set_event_mask; +extern const hci_cmd_t hci_set_connection_encryption; +extern const hci_cmd_t hci_sniff_mode; extern const hci_cmd_t hci_switch_role_command; extern const hci_cmd_t hci_write_authentication_enable; extern const hci_cmd_t hci_write_class_of_device; extern const hci_cmd_t hci_write_extended_inquiry_response; extern const hci_cmd_t hci_write_inquiry_mode; +extern const hci_cmd_t hci_write_le_host_supported; extern const hci_cmd_t hci_write_link_policy_settings; extern const hci_cmd_t hci_write_link_supervision_timeout; extern const hci_cmd_t hci_write_local_name; +extern const hci_cmd_t hci_write_num_broadcast_retransmissions; extern const hci_cmd_t hci_write_page_timeout; extern const hci_cmd_t hci_write_scan_enable; extern const hci_cmd_t hci_write_simple_pairing_mode; +extern const hci_cmd_t hci_le_add_device_to_whitelist; +extern const hci_cmd_t hci_le_clear_white_list; +extern const hci_cmd_t hci_le_connection_update; +extern const hci_cmd_t hci_le_create_connection; +extern const hci_cmd_t hci_le_create_connection_cancel; +extern const hci_cmd_t hci_le_encrypt; +extern const hci_cmd_t hci_le_long_term_key_negative_reply; +extern const hci_cmd_t hci_le_long_term_key_request_reply; +extern const hci_cmd_t hci_le_rand; +extern const hci_cmd_t hci_le_read_advertising_channel_tx_power; +extern const hci_cmd_t hci_le_read_buffer_size ; +extern const hci_cmd_t hci_le_read_channel_map; +extern const hci_cmd_t hci_le_read_remote_used_features; +extern const hci_cmd_t hci_le_read_supported_features; +extern const hci_cmd_t hci_le_read_supported_states; +extern const hci_cmd_t hci_le_read_white_list_size; +extern const hci_cmd_t hci_le_receiver_test; +extern const hci_cmd_t hci_le_remove_device_from_whitelist; +extern const hci_cmd_t hci_le_set_advertise_enable; +extern const hci_cmd_t hci_le_set_advertising_data; +extern const hci_cmd_t hci_le_set_advertising_parameters; +extern const hci_cmd_t hci_le_set_event_mask; +extern const hci_cmd_t hci_le_set_host_channel_classification; +extern const hci_cmd_t hci_le_set_random_address; +extern const hci_cmd_t hci_le_set_scan_enable; +extern const hci_cmd_t hci_le_set_scan_parameters; +extern const hci_cmd_t hci_le_set_scan_response_data; +extern const hci_cmd_t hci_le_start_encryption; +extern const hci_cmd_t hci_le_test_end; +extern const hci_cmd_t hci_le_transmitter_test; + extern const hci_cmd_t l2cap_accept_connection; extern const hci_cmd_t l2cap_create_channel; extern const hci_cmd_t l2cap_create_channel_mtu; @@ -247,7 +356,25 @@ extern const hci_cmd_t l2cap_unregister_service; extern const hci_cmd_t sdp_register_service_record; extern const hci_cmd_t sdp_unregister_service_record; - +// accept connection @param bd_addr(48), rfcomm_cid (16) +extern const hci_cmd_t rfcomm_accept_connection; +// create rfcomm channel: @param bd_addr(48), channel (8) +extern const hci_cmd_t rfcomm_create_channel; +// create rfcomm channel: @param bd_addr(48), channel (8), mtu (16), credits (8) +extern const hci_cmd_t rfcomm_create_channel_with_initial_credits; +// decline rfcomm disconnect,@param bd_addr(48), rfcomm cid (16), reason(8) +extern const hci_cmd_t rfcomm_decline_connection; +// disconnect rfcomm disconnect, @param rfcomm_cid(8), reason(8) +extern const hci_cmd_t rfcomm_disconnect; +// register rfcomm service: @param channel(8), mtu (16) +extern const hci_cmd_t rfcomm_register_service; +// register rfcomm service: @param channel(8), mtu (16), initial credits (8) +extern const hci_cmd_t rfcomm_register_service_with_initial_credits; +// unregister rfcomm service, @param service_channel(16) +extern const hci_cmd_t rfcomm_unregister_service; +// request persisten rfcomm channel for service name: serive name (char*) +extern const hci_cmd_t rfcomm_persistent_channel_for_service; + #if defined __cplusplus } #endif diff --git a/ios/RetroArch/BTStack/btstack/linked_list.h b/ios/RetroArch/BTStack/btstack/linked_list.h index 2518094876..d9d4fba554 100644 --- a/ios/RetroArch/BTStack/btstack/linked_list.h +++ b/ios/RetroArch/BTStack/btstack/linked_list.h @@ -54,8 +54,9 @@ int linked_list_empty(linked_list_t * list); void linked_list_add(linked_list_t * list, linked_item_t *item); // <-- add item to list as first element void linked_list_add_tail(linked_list_t * list, linked_item_t *item); // <-- add item to list as last element int linked_list_remove(linked_list_t * list, linked_item_t *item); // <-- remove item from list +linked_item_t * linked_list_get_last_item(linked_list_t * list); // <-- find the last item in the list -void test_linked_list(); +void test_linked_list(void); #if defined __cplusplus } diff --git a/ios/RetroArch/BTStack/btstack/run_loop.h b/ios/RetroArch/BTStack/btstack/run_loop.h index ea2673d5d4..5ff6a9c76f 100644 --- a/ios/RetroArch/BTStack/btstack/run_loop.h +++ b/ios/RetroArch/BTStack/btstack/run_loop.h @@ -37,9 +37,16 @@ #pragma once +//#include "config.h" +#define HAVE_TIME + #include "linked_list.h" +#include + +#ifdef HAVE_TIME #include +#endif #if defined __cplusplus extern "C" { @@ -59,27 +66,56 @@ typedef struct data_source { typedef struct timer { linked_item_t item; +#ifdef HAVE_TIME struct timeval timeout; // <-- next timeout +#endif +#ifdef HAVE_TICK + uint32_t timeout; // timeout in system ticks +#endif void (*process)(struct timer *ts); // <-- do processing } timer_source_t; -// init must be called before any other run_loop call -void run_loop_init(RUN_LOOP_TYPE type); -// add/remove data_source -void run_loop_add_data_source(data_source_t *dataSource); -int run_loop_remove_data_source(data_source_t *dataSource); +// Set timer based on current time in milliseconds. +void run_loop_set_timer(timer_source_t *a, uint32_t timeout_in_ms); -// set timer based on current time -void run_loop_set_timer(timer_source_t *a, int timeout_in_ms); +// Set callback that will be executed when timer expires. +void run_loop_set_timer_handler(timer_source_t *ts, void (*process)(timer_source_t *_ts)); -// add/remove timer_source +// Add/Remove timer source. void run_loop_add_timer(timer_source_t *timer); int run_loop_remove_timer(timer_source_t *timer); -// execute configured run_loop -void run_loop_execute(); +// Init must be called before any other run_loop call. +// Use RUN_LOOP_EMBEDDED for embedded devices. +void run_loop_init(RUN_LOOP_TYPE type); +// Set data source callback. +void run_loop_set_data_source_handler(data_source_t *ds, int (*process)(data_source_t *_ds)); + + +// Add/Remove data source. +void run_loop_add_data_source(data_source_t *dataSource); +int run_loop_remove_data_source(data_source_t *dataSource); + + +// Execute configured run loop. This function does not return. +void run_loop_execute(void); + +// hack to fix HCI timer handling +#ifdef HAVE_TICK +// Sets how many miliseconds has one tick. +uint32_t embedded_ticks_for_ms(uint32_t time_in_ms); +// Queries the current time in ticks. +uint32_t embedded_get_ticks(void); +#endif +#ifdef EMBEDDED +// Sets an internal flag that is checked in the critical section +// just before entering sleep mode. Has to be called by the interupt +// handler of a data source to signal the run loop that a new data +// is available. +void embedded_trigger(void); +#endif #if defined __cplusplus } #endif diff --git a/ios/RetroArch/BTStack/btstack/sdp_util.h b/ios/RetroArch/BTStack/btstack/sdp_util.h index fb91038f2e..0ebb219766 100644 --- a/ios/RetroArch/BTStack/btstack/sdp_util.h +++ b/ios/RetroArch/BTStack/btstack/sdp_util.h @@ -79,30 +79,59 @@ typedef enum { #define SDP_ClientExecutableURL 0x000b #define SDP_IconURL 0x000c #define SDP_AdditionalProtocolDescriptorList 0x000d +#define SDP_SupportedFormatsList 0x0303 + +// SERVICE CLASSES +#define SDP_OBEXObjectPush 0x1105 +#define SDP_OBEXFileTransfer 0x1106 +#define SDP_PublicBrowseGroup 0x1002 + +// PROTOCOLS +#define SDP_SDPProtocol 0x0001 +#define SDP_UDPProtocol 0x0002 +#define SDP_RFCOMMProtocol 0x0003 +#define SDP_OBEXProtocol 0x0008 +#define SDP_L2CAPProtocol 0x0100 // OFFSETS FOR LOCALIZED ATTRIBUTES - SDP_LanguageBaseAttributeIDList #define SDP_Offest_ServiceName 0x0000 #define SDP_Offest_ServiceDescription 0x0001 #define SDP_Offest_ProviderName 0x0002 +// OBEX +#define SDP_vCard_2_1 0x01 +#define SDP_vCard_3_0 0x02 +#define SDP_vCal_1_0 0x03 +#define SDP_iCal_2_0 0x04 +#define SDP_vNote 0x05 +#define SDP_vMessage 0x06 +#define SDP_OBEXFileTypeAny 0xFF -#pragma mark DateElement +// MARK: DateElement void de_dump_data_element(uint8_t * record); int de_get_len(uint8_t *header); de_size_t de_get_size_type(uint8_t *header); de_type_t de_get_element_type(uint8_t *header); +int de_get_header_size(uint8_t * header); void de_create_sequence(uint8_t *header); +void de_store_descriptor_with_len(uint8_t * header, de_type_t type, de_size_t size, uint32_t len); uint8_t * de_push_sequence(uint8_t *header); void de_pop_sequence(uint8_t * parent, uint8_t * child); void de_add_number(uint8_t *seq, de_type_t type, de_size_t size, uint32_t value); void de_add_data( uint8_t *seq, de_type_t type, uint16_t size, uint8_t *data); int de_get_data_size(uint8_t * header); +void de_add_uuid128(uint8_t * seq, uint8_t * uuid); -#pragma mark SDP -int sdp_append_attributes_in_attributeIDList(uint8_t *record, uint8_t *attributeIDList, uint16_t startIndex, uint16_t maxBytes, uint8_t *buffer); +// MARK: SDP +uint16_t sdp_append_attributes_in_attributeIDList(uint8_t *record, uint8_t *attributeIDList, uint16_t startOffset, uint16_t maxBytes, uint8_t *buffer); uint8_t * sdp_get_attribute_value_for_attribute_id(uint8_t * record, uint16_t attributeID); -int sdp_record_matches_service_search_pattern(uint8_t *record, uint8_t *serviceSearchPattern); +uint8_t sdp_set_attribute_value_for_attribute_id(uint8_t * record, uint16_t attributeID, uint32_t value); +int sdp_record_matches_service_search_pattern(uint8_t *record, uint8_t *serviceSearchPattern); +int spd_get_filtered_size(uint8_t *record, uint8_t *attributeIDList); +int sdp_filter_attributes_in_attributeIDList(uint8_t *record, uint8_t *attributeIDList, uint16_t startOffset, uint16_t maxBytes, uint16_t *usedBytes, uint8_t *buffer); + +void sdp_create_spp_service(uint8_t *service, int service_id, const char *name); #if defined __cplusplus } diff --git a/ios/RetroArch/BTStack/btstack/utils.h b/ios/RetroArch/BTStack/btstack/utils.h index 39064f370b..3fea5d5158 100644 --- a/ios/RetroArch/BTStack/btstack/utils.h +++ b/ios/RetroArch/BTStack/btstack/utils.h @@ -39,12 +39,13 @@ #pragma once -#include #if defined __cplusplus extern "C" { #endif - + +#include + /** * @brief hci connection handle type */ @@ -62,6 +63,13 @@ typedef uint8_t bd_addr_t[BD_ADDR_LEN]; #define LINK_KEY_LEN 16 typedef uint8_t link_key_t[LINK_KEY_LEN]; +/** + * @brief The device name type + */ +#define DEVICE_NAME_LEN 248 +typedef uint8_t device_name_t[DEVICE_NAME_LEN+1]; + + // helper for BT little endian format #define READ_BT_16( buffer, pos) ( ((uint16_t) buffer[pos]) | (((uint16_t)buffer[pos+1]) << 8)) #define READ_BT_24( buffer, pos) ( ((uint32_t) buffer[pos]) | (((uint32_t)buffer[pos+1]) << 8) | (((uint32_t)buffer[pos+2]) << 16)) @@ -77,6 +85,10 @@ typedef uint8_t link_key_t[LINK_KEY_LEN]; // check if command complete event for given command #define COMMAND_COMPLETE_EVENT(event,cmd) ( event[0] == HCI_EVENT_COMMAND_COMPLETE && READ_BT_16(event,3) == cmd.opcode) +#define COMMAND_STATUS_EVENT(event,cmd) ( event[0] == HCI_EVENT_COMMAND_STATUS && READ_BT_16(event,4) == cmd.opcode) + +// Code+Len=2, Pkts+Opcode=3; total=5 +#define OFFSET_OF_DATA_IN_COMMAND_COMPLETE 5 // ACL Packet #define READ_ACL_CONNECTION_HANDLE( buffer ) ( READ_BT_16(buffer,0) & 0x0fff) @@ -96,19 +108,19 @@ void net_store_32(uint8_t *buffer, uint16_t pos, uint32_t value); void hexdump(void *data, int size); void printUUID(uint8_t *uuid); -void print_bd_addr(bd_addr_t addr); -int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr); +// @deprecated please use more convenient bd_addr_to_str +void print_bd_addr( bd_addr_t addr); +char * bd_addr_to_str(bd_addr_t addr); + +int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr); + uint8_t crc8_check(uint8_t *data, uint16_t len, uint8_t check_sum); uint8_t crc8_calc(uint8_t *data, uint16_t len); #define BD_ADDR_CMP(a,b) memcmp(a,b, BD_ADDR_LEN) #define BD_ADDR_COPY(dest,src) memcpy(dest,src,BD_ADDR_LEN) -#ifdef EMBEDDED -void bzero(void *s, uint32_t n); -#endif - #if defined __cplusplus } #endif diff --git a/ios/RetroArch/BTStack/wiimote.c b/ios/RetroArch/BTStack/wiimote.c index 9a6576989f..6f468e648b 100644 --- a/ios/RetroArch/BTStack/wiimote.c +++ b/ios/RetroArch/BTStack/wiimote.c @@ -47,7 +47,7 @@ #include "btstack/btstack.h" #include "wiimote.h" -//int num_of_joys = 0; +int myosd_num_of_joys = 0; struct wiimote_t joys[4]; extern int g_pref_wii_DZ_value; #define STICK4WAY (myosd_waysStick == 4 && myosd_inGame) @@ -506,7 +506,6 @@ void calc_joystick_state(struct joystick_t* js, float x, float y); * @return Returns 1 if handshake was successful, 0 if not. */ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len) { - int i; int offset = 0; cc->btns = 0; @@ -581,7 +580,7 @@ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte * @param msg The message specified in the event packet. */ void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg) { - int i, lx, ly, rx, ry; + int lx, ly, rx, ry; byte l, r; /* decrypt data */ @@ -691,200 +690,3 @@ void calc_joystick_state(struct joystick_t* js, float x, float y) { js->ry = ry; } - -//////////////////////////////////////////////////////////// - -extern float joy_analog_x[4]; -extern float joy_analog_y[4]; - -int iOS_wiimote_check (struct wiimote_t *wm) -{ - return wm->btns; -} -#if 0 - joy_analog_x[wm->unid]=0.0f; - joy_analog_y[wm->unid]=0.0f; - if (1) { - if (wm->exp.type == EXP_CLASSIC) { - - float deadZone; - - switch(g_pref_wii_DZ_value) - { - case 0: deadZone = 0.12f;break; - case 1: deadZone = 0.15f;break; - case 2: deadZone = 0.17f;break; - case 3: deadZone = 0.2f;break; - case 4: deadZone = 0.3f;break; - case 5: deadZone = 0.4f;break; - } - - //printf("deadzone %f\n",deadZone); - - struct classic_ctrl_t* cc = (classic_ctrl_t*)&wm->exp.classic; - - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_ZL)) joyExKey |= MYOSD_R1; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_B)) joyExKey |= MYOSD_X; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_Y)) joyExKey |= MYOSD_A; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_A)) joyExKey |= MYOSD_B; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_X)) joyExKey |= MYOSD_Y; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_ZR)) joyExKey |= MYOSD_L1; - - - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_UP)){ - if(!STICK2WAY && - !(STICK4WAY && (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT) || - (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT))))) - joyExKey |= MYOSD_UP; - } - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_DOWN)){ - if(!STICK2WAY && - !(STICK4WAY && (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT) || - (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT))))) - joyExKey |= MYOSD_DOWN; - } - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT)) joyExKey |= MYOSD_LEFT; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT)) joyExKey |= MYOSD_RIGHT; - - - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_FULL_L)) joyExKey |= MYOSD_L1; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_MINUS)) joyExKey |= MYOSD_SELECT; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_HOME)) {//myosd_exitGame = 0;usleep(50000); - myosd_exitGame = 1;} - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_PLUS)) joyExKey |= MYOSD_START; - if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_FULL_R)) joyExKey |= MYOSD_R1; - - if(cc->ljs.mag >= deadZone) - { - joy_analog_x[wm->unid] = ( cc->ljs.rx > 1.0 ) ? 1.0 : ( cc->ljs.rx < -1.0 ) ? -1.0 : cc->ljs.rx; - joy_analog_y[wm->unid] = ( cc->ljs.ry > 1.0 ) ? 1.0 : ( cc->ljs.ry < -1.0 ) ? -1.0 : cc->ljs.ry; - - float v = cc->ljs.ang; - - if(STICK2WAY) - { - if( v < 180){ - joyExKey |= MYOSD_RIGHT; - //printf("Right\n"); - } - else if ( v >= 180){ - joyExKey |= MYOSD_LEFT; - //printf("Left\n"); - } - } - else if(STICK4WAY) - { - if(v >= 315 || v < 45){ - joyExKey |= MYOSD_UP; - //printf("Up\n"); - } - else if (v >= 45 && v < 135){ - joyExKey |= MYOSD_RIGHT; - //printf("Right\n"); - } - else if (v >= 135 && v < 225){ - joyExKey |= MYOSD_DOWN; - //printf("Down\n"); - } - else if (v >= 225 && v < 315){ - joyExKey |= MYOSD_LEFT; - //printf("Left\n"); - } - } - else - { - if( v >= 330 || v < 30){ - joyExKey |= MYOSD_UP; - //printf("Up\n"); - } - else if ( v >= 30 && v <60 ) { - joyExKey |= MYOSD_UP;joyExKey |= MYOSD_RIGHT; - //printf("UpRight\n"); - } - else if ( v >= 60 && v < 120 ){ - joyExKey |= MYOSD_RIGHT; - //printf("Right\n"); - } - else if ( v >= 120 && v < 150 ){ - joyExKey |= MYOSD_RIGHT;joyExKey |= MYOSD_DOWN; - //printf("RightDown\n"); - } - else if ( v >= 150 && v < 210 ){ - joyExKey |= MYOSD_DOWN; - //printf("Down\n"); - } - else if ( v >= 210 && v < 240 ){ - joyExKey |= MYOSD_DOWN;joyExKey |= MYOSD_LEFT; - //printf("DownLeft\n"); - } - else if ( v >= 240 && v < 300 ){ - joyExKey |= MYOSD_LEFT; - //printf("Left\n"); - } - else if ( v >= 300 && v < 330 ){ - joyExKey |= MYOSD_LEFT; - joyExKey |= MYOSD_UP; - //printf("LeftUp\n"); - } - } - } - - if(cc->rjs.mag >= deadZone) - { - float v = cc->rjs.ang; - - if( v >= 330 || v < 30){ - joyExKey |= MYOSD_Y; - //printf("Y\n"); - } - else if ( v >= 30 && v <60 ) { - joyExKey |= MYOSD_Y;joyExKey |= MYOSD_B; - //printf("Y B\n"); - } - else if ( v >= 60 && v < 120 ){ - joyExKey |= MYOSD_B; - //printf("B\n"); - } - else if ( v >= 120 && v < 150 ){ - joyExKey |= MYOSD_B;joyExKey |= MYOSD_X; - //printf("B X\n"); - } - else if ( v >= 150 && v < 210 ){ - joyExKey |= MYOSD_X; - //printf("X\n"); - } - else if ( v >= 210 && v < 240 ){ - joyExKey |= MYOSD_X;joyExKey |= MYOSD_A; - //printf("X A\n"); - } - else if ( v >= 240 && v < 300 ){ - joyExKey |= MYOSD_A; - //printf("A\n"); - } - else if ( v >= 300 && v < 330 ){ - joyExKey |= MYOSD_A;joyExKey |= MYOSD_Y; - //printf("A Y\n"); - } - } -/* - printf("classic L button pressed: %f\n", cc->l_shoulder); - printf("classic R button pressed: %f\n", cc->r_shoulder); - - printf("classic left joystick angle: %f\n", cc->ljs.ang); - printf("classic left joystick magnitude: %f\n", cc->ljs.mag); - printf("classic left joystick rx: %f\n", cc->ljs.rx); - printf("classic left joystick ry: %f\n", cc->ljs.ry); - - printf("classic right joystick angle: %f\n", cc->rjs.ang); - printf("classic right joystick magnitude: %f\n", cc->rjs.mag); - printf("classic right rx: %f\n", cc->rjs.rx); - printf("classic right ry: %f\n", cc->rjs.ry); -*/ - } - return joyExKey; - } else { - joyExKey = 0; - return joyExKey; - } -} -#endif diff --git a/ios/RetroArch/BTStack/wiimote.h b/ios/RetroArch/BTStack/wiimote.h index ba58a97659..43f52002f3 100644 --- a/ios/RetroArch/BTStack/wiimote.h +++ b/ios/RetroArch/BTStack/wiimote.h @@ -276,8 +276,6 @@ extern "C" { extern int myosd_num_of_joys; -//devuelve un int haciendo polling de lo guardado en el wiimote -int iOS_wiimote_check (struct wiimote_t *wm); int wiimote_remove(uint16_t source_cid, bd_addr_t *addr); struct wiimote_t* wiimote_get_by_source_cid(uint16_t source_cid); int wiimote_handshake(struct wiimote_t* wm, byte event, byte* data, unsigned short len); diff --git a/ios/RetroArch/RetroArch_iOS.m b/ios/RetroArch/RetroArch_iOS.m index 7d65312d86..cc9febac1e 100644 --- a/ios/RetroArch/RetroArch_iOS.m +++ b/ios/RetroArch/RetroArch_iOS.m @@ -353,7 +353,7 @@ - (IBAction)showWiiRemoteConfig { #ifdef WIIMOTE - [WiiMoteHelper startwiimote:_navigator]; + [[WiiMoteHelper get] showDiscovery]; #endif } diff --git a/ios/RetroArch/ios_input.m b/ios/RetroArch/ios_input.m index 723b64c91b..2e77d11166 100644 --- a/ios/RetroArch/ios_input.m +++ b/ios/RetroArch/ios_input.m @@ -165,10 +165,10 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u case RETRO_DEVICE_ID_JOYPAD_B: return IS_PRESSED(wm, WIIMOTE_BUTTON_ONE); case RETRO_DEVICE_ID_JOYPAD_START: return IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS); case RETRO_DEVICE_ID_JOYPAD_SELECT: return IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS); - case RETRO_DEVICE_ID_JOYPAD_UP: return IS_PRESSED(wm, WIIMOTE_BUTTON_UP); - case RETRO_DEVICE_ID_JOYPAD_DOWN: return IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN); - case RETRO_DEVICE_ID_JOYPAD_LEFT: return IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT); - case RETRO_DEVICE_ID_JOYPAD_RIGHT: return IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT); + case RETRO_DEVICE_ID_JOYPAD_UP: return IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT); + case RETRO_DEVICE_ID_JOYPAD_DOWN: return IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT); + case RETRO_DEVICE_ID_JOYPAD_LEFT: return IS_PRESSED(wm, WIIMOTE_BUTTON_UP); + case RETRO_DEVICE_ID_JOYPAD_RIGHT: return IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN); } } #endif