implement wiiuse_os_connect for mac
This commit is contained in:
143
src/os_mac.m
143
src/os_mac.m
@@ -39,8 +39,6 @@
|
|||||||
#import "events.h"
|
#import "events.h"
|
||||||
#import "os.h"
|
#import "os.h"
|
||||||
|
|
||||||
|
|
||||||
#define BLUETOOTH_VERSION_USE_CURRENT
|
|
||||||
#import <IOBluetooth/IOBluetoothUtilities.h>
|
#import <IOBluetooth/IOBluetoothUtilities.h>
|
||||||
#import <IOBluetooth/objc/IOBluetoothDevice.h>
|
#import <IOBluetooth/objc/IOBluetoothDevice.h>
|
||||||
#import <IOBluetooth/objc/IOBluetoothHostController.h>
|
#import <IOBluetooth/objc/IOBluetoothHostController.h>
|
||||||
@@ -51,8 +49,78 @@
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark connect, disconnect
|
#pragma mark connect, disconnect
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Connect to a wiimote with a known address.
|
||||||
|
*
|
||||||
|
* @param wm Pointer to a wiimote_t structure.
|
||||||
|
*
|
||||||
|
* @see wiimote_os_connect()
|
||||||
|
* @see wiimote_os_find()
|
||||||
|
*
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
static short wiiuse_os_connect_single(struct wiimote_t* wm) {
|
||||||
|
// Skip if already connected or device not found
|
||||||
|
if(!wm) {
|
||||||
|
WIIUSE_ERROR("No Wiimote given.");
|
||||||
|
return 0;
|
||||||
|
} else if(wm && (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_DEV_FOUND) || wm->device == NULL)) {
|
||||||
|
WIIUSE_ERROR("Tried to connect Wiimote without an address.");
|
||||||
|
return 0;
|
||||||
|
} else if(WIIMOTE_IS_CONNECTED(wm)) {
|
||||||
|
WIIUSE_WARNING("Wiimote [id %i] is already connected.", wm->unid);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
WIIUSE_DEBUG("Connecting to Wiimote [id %i].", wm->unid);
|
||||||
|
|
||||||
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
short result = 0;
|
||||||
|
|
||||||
|
// connect
|
||||||
|
WiiuseWiimote* objc_wm = [[WiiuseWiimote alloc] initWithPtr: wm];
|
||||||
|
if([objc_wm connect] == kIOReturnSuccess) {
|
||||||
|
WIIUSE_INFO("Connected to Wiimote [id %i].", wm->unid);
|
||||||
|
|
||||||
|
// save the connect structure to retrieve data later on
|
||||||
|
wm->objc_wm = (void*)objc_wm;
|
||||||
|
|
||||||
|
// save the connection status
|
||||||
|
WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
|
||||||
|
|
||||||
|
// Do the handshake
|
||||||
|
wiiuse_handshake(wm, NULL, 0);
|
||||||
|
wiiuse_set_report_type(wm);
|
||||||
|
|
||||||
|
result = 1;
|
||||||
|
} else {
|
||||||
|
[objc_wm release];
|
||||||
|
}
|
||||||
|
|
||||||
|
[pool drain];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int wiiuse_os_connect(struct wiimote_t** wm, int wiimotes) {
|
int wiiuse_os_connect(struct wiimote_t** wm, int wiimotes) {
|
||||||
return 0;
|
int connected = 0;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < wiimotes; ++i) {
|
||||||
|
if(wm[i] == NULL) {
|
||||||
|
WIIUSE_ERROR("Trying to connect to non-initialized Wiimote.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND) || !wm[i]->device) {
|
||||||
|
// If the device is not set, skip it
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wiiuse_os_connect_single(wm[i]))
|
||||||
|
++connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wiiuse_os_disconnect(struct wiimote_t* wm) {
|
void wiiuse_os_disconnect(struct wiimote_t* wm) {
|
||||||
@@ -87,11 +155,80 @@ int wiiuse_os_write(struct wiimote_t* wm, byte* buf, int len) {
|
|||||||
|
|
||||||
void wiiuse_init_platform_fields(struct wiimote_t* wm) {
|
void wiiuse_init_platform_fields(struct wiimote_t* wm) {
|
||||||
wm->device = NULL;
|
wm->device = NULL;
|
||||||
|
wm->objc_wm = NULL;
|
||||||
|
wm->controlChannel = NULL;
|
||||||
|
wm->interruptChannel = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) {
|
void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) {
|
||||||
[WIIUSE_IOBluetoothDeviceRef_to_IOBluetoothDevice(wm->device) release];
|
[WIIUSE_IOBluetoothDeviceRef_to_IOBluetoothDevice(wm->device) release];
|
||||||
wm->device = NULL;
|
wm->device = NULL;
|
||||||
|
|
||||||
|
[((WiiuseWiimote*) wm->objc_wm) release];
|
||||||
|
wm->objc_wm = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark WiiuseWiimote
|
||||||
|
|
||||||
|
@implementation WiiuseWiimote
|
||||||
|
|
||||||
|
- (id) initWithPtr: (wiimote*) wm_ {
|
||||||
|
self = [super init];
|
||||||
|
if(self) {
|
||||||
|
wm = wm_;
|
||||||
|
disconnectNotification = nil;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc {
|
||||||
|
wm = NULL;
|
||||||
|
|
||||||
|
[disconnectNotification release];
|
||||||
|
disconnectNotification = nil;
|
||||||
|
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IOReturn) connect {
|
||||||
|
IOBluetoothDevice* device = WIIUSE_IOBluetoothDeviceRef_to_IOBluetoothDevice(wm->device);
|
||||||
|
if(!device) {
|
||||||
|
WIIUSE_ERROR("Missing device.");
|
||||||
|
return kIOReturnBadArgument;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open channels
|
||||||
|
IOBluetoothL2CAPChannel* controlChannel = nil, *interruptChannel = nil;
|
||||||
|
if ([device openL2CAPChannelSync:&controlChannel withPSM:WM_OUTPUT_CHANNEL delegate:self] != kIOReturnSuccess) {
|
||||||
|
WIIUSE_ERROR("Unable to open L2CAP control channel [id %i].", wm->unid);
|
||||||
|
[device closeConnection];
|
||||||
|
return kIOReturnNotOpen;
|
||||||
|
} else if([device openL2CAPChannelSync:&interruptChannel withPSM:WM_INPUT_CHANNEL delegate:self] != kIOReturnSuccess) {
|
||||||
|
WIIUSE_ERROR("Unable to open L2CAP interrupt channel [id %i].", wm->unid);
|
||||||
|
[controlChannel closeChannel];
|
||||||
|
[device closeConnection];
|
||||||
|
return kIOReturnNotOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// register for device disconnection
|
||||||
|
disconnectNotification = [device registerForDisconnectNotification:self selector:@selector(disconnected:fromDevice:)];
|
||||||
|
if(!disconnectNotification) {
|
||||||
|
WIIUSE_ERROR("Unable to register disconnection handler [id %i].", wm->unid);
|
||||||
|
[interruptChannel closeChannel];
|
||||||
|
[controlChannel closeChannel];
|
||||||
|
[device closeConnection];
|
||||||
|
return kIOReturnNotOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// retain channels, and save them to the C struct
|
||||||
|
[controlChannel retain]; [interruptChannel retain];
|
||||||
|
wm->controlChannel = WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef(controlChannel);
|
||||||
|
wm->interruptChannel = WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef(interruptChannel);
|
||||||
|
|
||||||
|
return kIOReturnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|||||||
@@ -34,7 +34,12 @@
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
|
||||||
|
#define BLUETOOTH_VERSION_USE_CURRENT
|
||||||
|
|
||||||
#import <IOBluetooth/objc/IOBluetoothDevice.h>
|
#import <IOBluetooth/objc/IOBluetoothDevice.h>
|
||||||
|
#import <IOBluetooth/objc/IOBluetoothL2CAPChannel.h>
|
||||||
|
|
||||||
|
#import "../wiiuse_internal.h"
|
||||||
|
|
||||||
|
|
||||||
#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
|
#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
|
||||||
@@ -62,5 +67,34 @@
|
|||||||
[IOBluetoothDevice withDeviceRef: (ref)]
|
[IOBluetoothDevice withDeviceRef: (ref)]
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef
|
||||||
|
#if WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE
|
||||||
|
#define WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef(channel) \
|
||||||
|
((IOBluetoothL2CAPChannelRef) (channel))
|
||||||
|
#else
|
||||||
|
#define WIIUSE_IOBluetoothL2CAPChannel_to_IOBluetoothL2CAPChannelRef(channel) \
|
||||||
|
[(channel) getL2CAPChannelRef]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// WIIUSE_IOBluetoothL2CAPChannelRef_to_IOBluetoothL2CAPChannel
|
||||||
|
#if WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE
|
||||||
|
#define WIIUSE_IOBluetoothL2CAPChannelRef_to_IOBluetoothL2CAPChannel(ref) \
|
||||||
|
((IOBluetoothL2CAPChannel*) (ref))
|
||||||
|
#else
|
||||||
|
#define WIIUSE_IOBluetoothL2CAPChannelRef_to_IOBluetoothL2CAPChannel(ref) \
|
||||||
|
[IOBluetoothL2CAPChannel withChanneleRef: (ref)]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@interface WiiuseWiimote : NSObject<IOBluetoothL2CAPChannelDelegate> {
|
||||||
|
wiimote* wm; // reference to the C wiimote struct
|
||||||
|
IOBluetoothUserNotification* disconnectNotification;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithPtr: (wiimote*) wm;
|
||||||
|
- (IOReturn) connect;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|||||||
@@ -39,8 +39,6 @@
|
|||||||
#import "../events.h"
|
#import "../events.h"
|
||||||
#import "../os.h"
|
#import "../os.h"
|
||||||
|
|
||||||
|
|
||||||
#define BLUETOOTH_VERSION_USE_CURRENT
|
|
||||||
#import <IOBluetooth/IOBluetoothUtilities.h>
|
#import <IOBluetooth/IOBluetoothUtilities.h>
|
||||||
#import <IOBluetooth/objc/IOBluetoothDevice.h>
|
#import <IOBluetooth/objc/IOBluetoothDevice.h>
|
||||||
#import <IOBluetooth/objc/IOBluetoothHostController.h>
|
#import <IOBluetooth/objc/IOBluetoothHostController.h>
|
||||||
@@ -48,7 +46,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark find
|
#pragma mark WiiuseDeviceInquiry
|
||||||
|
|
||||||
@interface WiiuseDeviceInquiry : NSObject<IOBluetoothDeviceInquiryDelegate> {
|
@interface WiiuseDeviceInquiry : NSObject<IOBluetoothDeviceInquiryDelegate> {
|
||||||
wiimote** wiimotes;
|
wiimote** wiimotes;
|
||||||
@@ -122,6 +120,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger) collectResultsOf: (IOBluetoothDeviceInquiry*) inquiry {
|
- (NSUInteger) collectResultsOf: (IOBluetoothDeviceInquiry*) inquiry {
|
||||||
|
// stop the inquiry
|
||||||
|
if(![inquiry stop])
|
||||||
|
WIIUSE_ERROR("Unable to stop bluetooth device inquiry.");
|
||||||
|
|
||||||
// read found device information
|
// read found device information
|
||||||
NSArray* devices = [inquiry foundDevices];
|
NSArray* devices = [inquiry foundDevices];
|
||||||
for(NSUInteger i = 0; i < [devices count]; i++) {
|
for(NSUInteger i = 0; i < [devices count]; i++) {
|
||||||
@@ -168,6 +170,8 @@
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark IOBluetoothDeviceInquiryDelegate
|
||||||
|
|
||||||
- (void) deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry *) inquiry device:(IOBluetoothDevice *) device {
|
- (void) deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry *) inquiry device:(IOBluetoothDevice *) device {
|
||||||
|
|
||||||
WIIUSE_DEBUG("Found a wiimote");
|
WIIUSE_DEBUG("Found a wiimote");
|
||||||
@@ -175,8 +179,6 @@
|
|||||||
_foundDevices++;
|
_foundDevices++;
|
||||||
if(_foundDevices >= maxDevices) {
|
if(_foundDevices >= maxDevices) {
|
||||||
// reached maximum number of devices
|
// reached maximum number of devices
|
||||||
if(![inquiry stop])
|
|
||||||
WIIUSE_ERROR("Unable to stop bluetooth device inquiry.");
|
|
||||||
_inquiryComplete = YES;
|
_inquiryComplete = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,6 +198,9 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark public interface
|
||||||
|
|
||||||
int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
|
int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
|||||||
@@ -723,7 +723,10 @@ typedef struct wiimote_t {
|
|||||||
#ifdef WIIUSE_MAC
|
#ifdef WIIUSE_MAC
|
||||||
/** @name Mac OS X-specific members */
|
/** @name Mac OS X-specific members */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
WCONST IOBluetoothDeviceRef device; /** Device reference object */
|
WCONST IOBluetoothDeviceRef device; /** Device reference */
|
||||||
|
WCONST void* objc_wm; /** WiiuseWiimote* as opaque pointer */
|
||||||
|
WCONST IOBluetoothL2CAPChannelRef controlChannel; /** control channel reference */
|
||||||
|
WCONST IOBluetoothL2CAPChannelRef interruptChannel; /** interrupt channel reference */
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user