From 95259d4b8673a72f00acd1f21be2b4b2fae86ce5 Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 22 Mar 2013 09:47:04 -0400 Subject: [PATCH] (iOS) Move all bluetooth processing to WiiMoteHelper.m; delete BTstackManager.m --- ios/RetroArch.xcodeproj/project.pbxproj | 6 - ios/RetroArch/input/BTStack/BTstackManager.h | 188 ------ ios/RetroArch/input/BTStack/BTstackManager.m | 592 ------------------- ios/RetroArch/input/BTStack/WiiMoteHelper.h | 4 +- ios/RetroArch/input/BTStack/WiiMoteHelper.m | 357 +++++------ 5 files changed, 186 insertions(+), 961 deletions(-) delete mode 100644 ios/RetroArch/input/BTStack/BTstackManager.h delete mode 100644 ios/RetroArch/input/BTStack/BTstackManager.m diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 1221bd5b91..56f421b2d0 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -21,7 +21,6 @@ 963F5AC316CC522F009BBD19 /* RASettingsList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABF16CC522F009BBD19 /* RASettingsList.m */; }; 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; }; 966B9CA216E418B7005B61E1 /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9116E418B7005B61E1 /* BTDevice.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 966B9CA416E418B7005B61E1 /* BTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9C16E418B7005B61E1 /* BTstackManager.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 966B9CA616E418B7005B61E1 /* wiimote.c in Sources */ = {isa = PBXBuildFile; fileRef = 966B9C9E16E418B7005B61E1 /* wiimote.c */; }; 966B9CA716E418B7005B61E1 /* WiiMoteHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CA116E418B7005B61E1 /* WiiMoteHelper.m */; }; 966B9CAE16E41C07005B61E1 /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAA16E41C07005B61E1 /* browser.m */; }; @@ -73,8 +72,6 @@ 966B9C9816E418B7005B61E1 /* run_loop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = run_loop.h; sourceTree = ""; }; 966B9C9916E418B7005B61E1 /* sdp_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sdp_util.h; sourceTree = ""; }; 966B9C9A16E418B7005B61E1 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; }; - 966B9C9B16E418B7005B61E1 /* BTstackManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTstackManager.h; sourceTree = ""; }; - 966B9C9C16E418B7005B61E1 /* BTstackManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTstackManager.m; sourceTree = ""; }; 966B9C9E16E418B7005B61E1 /* wiimote.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wiimote.c; sourceTree = ""; }; 966B9C9F16E418B7005B61E1 /* wiimote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wiimote.h; sourceTree = ""; }; 966B9CA016E418B7005B61E1 /* WiiMoteHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WiiMoteHelper.h; sourceTree = ""; }; @@ -158,8 +155,6 @@ 966B9C9016E418B7005B61E1 /* BTDevice.h */, 966B9C9116E418B7005B61E1 /* BTDevice.m */, 966B9C9416E418B7005B61E1 /* btstack */, - 966B9C9B16E418B7005B61E1 /* BTstackManager.h */, - 966B9C9C16E418B7005B61E1 /* BTstackManager.m */, 966B9C9E16E418B7005B61E1 /* wiimote.c */, 966B9C9F16E418B7005B61E1 /* wiimote.h */, 966B9CA016E418B7005B61E1 /* WiiMoteHelper.h */, @@ -404,7 +399,6 @@ 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */, 96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */, 966B9CA216E418B7005B61E1 /* BTDevice.m in Sources */, - 966B9CA416E418B7005B61E1 /* BTstackManager.m in Sources */, 966B9CA616E418B7005B61E1 /* wiimote.c in Sources */, 966B9CA716E418B7005B61E1 /* WiiMoteHelper.m in Sources */, 966B9CAE16E41C07005B61E1 /* browser.m in Sources */, diff --git a/ios/RetroArch/input/BTStack/BTstackManager.h b/ios/RetroArch/input/BTStack/BTstackManager.h deleted file mode 100644 index cb1c4d8545..0000000000 --- a/ios/RetroArch/input/BTStack/BTstackManager.h +++ /dev/null @@ -1,188 +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. - * - */ - -#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/input/BTStack/BTstackManager.m b/ios/RetroArch/input/BTStack/BTstackManager.m deleted file mode 100644 index 89b648231a..0000000000 --- a/ios/RetroArch/input/BTStack/BTstackManager.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. - * - */ - -#include "btdynamic.h" - -#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_ptr(RUN_LOOP_COCOA); - - // our packet handler - bt_register_packet_handler_ptr(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_ptr(); - if (err) return BTSTACK_CONNECTION_TO_BTDAEMON_FAILED; - } - connectedToDaemon = YES; - - // check system BT - state = kW4SysBTState; - bt_send_cmd_ptr(btstack_get_system_bluetooth_enabled_ptr); - - return err; -} - --(BTstackError) deactivate { - if (!connectedToDaemon) return BTSTACK_CONNECTION_TO_BTDAEMON_FAILED; - state = kW4Deactivated; - bt_send_cmd_ptr(btstack_set_power_mode_ptr, 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_ptr(hci_write_inquiry_mode_ptr, 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_ptr(hci_inquiry_cancel_ptr); - break; - case kRemoteName: { - discoveryState = kW4RemoteNameBeforeStop; - BTDevice *device = [discoveredDevices objectAtIndex:discoveryDeviceIndex]; - bt_send_cmd_ptr(hci_remote_name_request_cancel_ptr, [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_ptr(btstack_set_system_bluetooth_enabled_ptr, 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_ptr(btstack_set_power_mode_ptr, 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_ptr(hci_remote_name_request_ptr, [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_ptr(hci_inquiry_ptr, 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_ptr(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_ptr(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_ptr)) ) { - discoveryState = kInquiry; - bt_send_cmd_ptr(hci_inquiry_ptr, 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 "BTstackManager.h" - -@interface WiiMoteHelper : NSObject +@interface WiiMoteHelper : NSObject + (BOOL)haveBluetooth; + (void)startBluetooth; + (BOOL)isBluetoothRunning; diff --git a/ios/RetroArch/input/BTStack/WiiMoteHelper.m b/ios/RetroArch/input/BTStack/WiiMoteHelper.m index d8765270ac..d2d66616b9 100644 --- a/ios/RetroArch/input/BTStack/WiiMoteHelper.m +++ b/ios/RetroArch/input/BTStack/WiiMoteHelper.m @@ -38,198 +38,105 @@ #import "WiiMoteHelper.h" #import "BTDevice.h" -#import "BTstackManager.h" static WiiMoteHelper* instance; -static BTDevice *device; static bool btstackOpen; static bool btOK; -@implementation WiiMoteHelper -+ (BOOL)haveBluetooth -{ - if (!btstackOpen) - btstackOpen = load_btstack(); - - return btstackOpen; -} +static BTDevice* discoveredDevice; -+ (void)startBluetooth -{ - if (btstackOpen) - { - instance = instance ? instance : [WiiMoteHelper new]; - - if (!btOK) - { - BTstackManager* bt = [BTstackManager sharedInstance]; - [bt setDelegate:instance]; - [bt addListener:instance]; - - btOK = [bt activate] == 0; - } - } -} - -+ (BOOL)isBluetoothRunning -{ - return btstackOpen && btOK; -} - -+ (void)stopBluetooth -{ - if (btstackOpen) - { - myosd_num_of_joys = 0; - - if (btOK) - { - BTstackManager* bt = [BTstackManager sharedInstance]; - - [bt deactivate]; - [bt setDelegate:nil]; - [bt removeListener:instance]; - btOK = false; - } - - instance = nil; - } -} - -// 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_ptr(hci_write_authentication_enable_ptr, 0); -} - -// BTStackManagerDelegate --(void) btstackManager:(BTstackManager*) manager - handlePacketWithType:(uint8_t)packet_type - forChannel:(uint16_t)channel - andData:(uint8_t*)packet - withLen:(uint16_t)size +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 = wiimote_get_by_source_cid(channel); - - 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; - } - - 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 + // Connection + case HCI_EVENT_PACKET: { switch (packet[0]) { - case HCI_EVENT_COMMAND_COMPLETE: + // Bluetooth is active, search for remote + case BTSTACK_EVENT_STATE: { - if (COMMAND_COMPLETE_EVENT(packet, (*hci_write_authentication_enable_ptr))) - bt_send_cmd_ptr(l2cap_create_channel_ptr, [device address], PSM_HID_INTERRUPT); - break; + if (packet[2] == HCI_STATE_WORKING) + bt_send_cmd_ptr(hci_inquiry_ptr, HCI_INQUIRY_LAP, 3, 0); + break; } - case HCI_EVENT_PIN_CODE_REQUEST: + // Identifies devices found during inquiry, does not signal the end of the inquiry. + case HCI_EVENT_INQUIRY_RESULT: { - bt_flip_addr_ptr(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_ptr(hci_pin_code_request_reply_ptr, event_addr, 6, &packet[2]); // use inverse bd_addr as PIN + for (int i = 0; i != packet[2]; i ++) + { + if (!discoveredDevice) + { + bt_flip_addr_ptr(event_addr, &packet[3 + i * 6]); + discoveredDevice = [[BTDevice alloc] init]; + [discoveredDevice setAddress:&event_addr]; + } + + // update + discoveredDevice.pageScanRepetitionMode = packet [3 + packet[2] * (6) + i*1]; + discoveredDevice.classOfDevice = READ_BT_24(packet, 3 + packet[2] * (6+1+1+1) + i*3); + discoveredDevice.clockOffset = READ_BT_16(packet, 3 + packet[2] * (6+1+1+1+3) + i*2) & 0x7fff; + discoveredDevice.rssi = 0; + } + + break; + } + + // The inquiry has ended + case HCI_EVENT_INQUIRY_COMPLETE: + { + // If we a device, ask for its name + if (discoveredDevice) + bt_send_cmd_ptr(hci_remote_name_request_ptr, [discoveredDevice address], discoveredDevice.pageScanRepetitionMode, + 0, discoveredDevice.clockOffset | 0x8000); + // Keep looking + else + bt_send_cmd_ptr(hci_inquiry_ptr, HCI_INQUIRY_LAP, 3, 0); + break; } + // Received the name of a device + case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: + { + bt_flip_addr_ptr(event_addr, &packet[3]); + + if (discoveredDevice && BD_ADDR_CMP(event_addr, discoveredDevice.address) == 0) + { + char cname[249]; + strncpy(cname, (const char*)&packet[9], 248); + cname[248] = 0; + + NSString* name = [NSString stringWithUTF8String:cname]; + [discoveredDevice setName:name]; + + // We found a WiiMote, pair with it + if ([name hasPrefix:@"Nintendo RVL-CNT-01"]) + bt_send_cmd_ptr(l2cap_create_channel_ptr, [discoveredDevice address], PSM_HID_INTERRUPT); + } + + break; + } + + // Send PIN for pairing + case HCI_EVENT_PIN_CODE_REQUEST: + { + bt_flip_addr_ptr(event_addr, &packet[2]); + + if (discoveredDevice && BD_ADDR_CMP(event_addr, discoveredDevice.address) == 0) + { + // WiiMote: Use inverse bd_addr as PIN + if (discoveredDevice.name && [discoveredDevice.name hasPrefix:@"Nintendo RVL-CNT-01"]) + bt_send_cmd_ptr(hci_pin_code_request_reply_ptr, event_addr, 6, &packet[2]); + } + break; + } + + // WiiMote connections case L2CAP_EVENT_CHANNEL_OPENED: { // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16) @@ -273,11 +180,117 @@ static bool btOK; uint16_t source_cid = READ_BT_16(packet, 2); bd_addr_t addr; - wiimote_remove(source_cid,&addr); + wiimote_remove(source_cid, &addr); break; } } } + + // WiiMote handling + case L2CAP_DATA_PACKET: + { + struct wiimote_t *wm = wiimote_get_by_source_cid(channel); + if (wm) + { + byte* msg = packet + 2; + + switch (packet[1]) + { + case WM_RPT_BTN: + { + wiimote_pressed_buttons(wm, msg); + break; + } + + case WM_RPT_READ: + { + wiimote_pressed_buttons(wm, msg); + + byte len = ((msg[2] & 0xF0) >> 4) + 1; + byte *data = (msg + 5); + + wiimote_handshake(wm, WM_RPT_READ, data, len); + return; + } + + case WM_RPT_CTRL_STATUS: + { + wiimote_pressed_buttons(wm, msg); + wiimote_handshake(wm,WM_RPT_CTRL_STATUS,msg,-1); + + return; + } + + case WM_RPT_BTN_EXP: + { + wiimote_pressed_buttons(wm, msg); + wiimote_handle_expansion(wm, msg+2); + break; + } + } + } + break; + } } } + + + +@implementation WiiMoteHelper ++ (BOOL)haveBluetooth +{ + if (!btstackOpen) + { + btstackOpen = load_btstack(); + + if (btstackOpen) + { + run_loop_init_ptr(RUN_LOOP_COCOA); + bt_register_packet_handler_ptr(packet_handler); + } + } + + return btstackOpen; +} + ++ (void)startBluetooth +{ + if (btstackOpen) + { + instance = instance ? instance : [WiiMoteHelper new]; + + if (!btOK) + { + if (bt_open_ptr()) + { + btOK = false; + return; + } + + bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_ON); + + btOK = true; + } + } +} + ++ (BOOL)isBluetoothRunning +{ + return btstackOpen && btOK; +} + ++ (void)stopBluetooth +{ + if (btstackOpen) + { + myosd_num_of_joys = 0; + + if (btOK) + bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_OFF); + + btOK = false; + instance = nil; + } +} + @end