Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/wiimote/src/external/wiicpp/wiic/io_mac.m @ 10255

Last change on this file since 10255 was 9780, checked in by georgr, 11 years ago

WiiCpp library successfully (?) added - won't work without libbluetooth-dev

  • Property svn:executable set to *
File size: 19.4 KB
RevLine 
[9780]1/*
2 *      io_mac.m
3 *
4 *      Written By:
5 *              Gabriele Randelli       
6 *              Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it >
7 *
8 *      Copyright 2010
9 *
10 *      This file is part of wiiC.
11 *
12 *      This program is free software; you can redistribute it and/or modify
13 *      it under the terms of the GNU General Public License as published by
14 *      the Free Software Foundation; either version 3 of the License, or
15 *      (at your option) any later version.
16 *
17 *      This program is distributed in the hope that it will be useful,
18 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
19 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 *      GNU General Public License for more details.
21 *
22 *      You should have received a copy of the GNU General Public License
23 *      along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 *
25 *      $Header$
26 *
27 */
28
29/**
30 *      @file
31 *      @brief Handles device I/O for Mac.
32 */
33#ifdef __APPLE__
34
35#import "io_mac.h"
36
37// Used just to retrieve max num of wiimotes in handler functions
38static int max_num_wiimotes = 0;
39
40@implementation WiiSearch
41
42#pragma mark -
43#pragma mark WiiSearch
44- (id) init
45{
46        self = [super init];
47        foundWiimotes = 0;
48        isDiscovering = NO;
49        if (self != nil) {
50                /*
51                 * Calling IOBluetoothLocalDeviceAvailable has two advantages:
52                 * 1. it sets up a event source in the run loop (bug for C version of the bluetooth api)
53                 * 2. it checks for the availability of the BT hardware
54                 */
55                if (![IOBluetoothHostController defaultController])
56                {
57                        [self release];
58                        self = nil;
59                }               
60        }
61
62        return self;
63}
64
65- (void) dealloc
66{       
67        inquiry = 0;
68        WIIC_DEBUG("Wiimote Discovery released");
69        [super dealloc];
70}
71
72- (BOOL) isDiscovering
73{
74        return isDiscovering;
75}
76
77- (void) setDiscovering:(BOOL) flag
78{
79        isDiscovering = flag;
80}
81
82- (void) setWiimoteStruct:(wiimote**) wiimote_struct
83{
84        wiimotes = wiimote_struct;
85}
86
87- (int) getFoundWiimotes
88{
89        return foundWiimotes;
90}
91
92- (IOReturn) start:(unsigned int) timeout maxWiimotes:(unsigned int) wiimotesNum
93{
94        if (![IOBluetoothHostController defaultController]) {
95                WIIC_ERROR("Unable to find any bluetooth receiver on your host.");
96                return kIOReturnNotAttached;
97        }
98       
99        // If we are currently discovering, we can't start a new discovery right now.
100        if ([self isDiscovering]) {
101                WIIC_INFO("Wiimote search is already in progress...");
102                return kIOReturnSuccess;
103        }
104       
105        [self close];
106        maxWiimotes = wiimotesNum;
107        foundWiimotes = 0;
108
109        inquiry = [IOBluetoothDeviceInquiry inquiryWithDelegate:self];
110        // We set the search timeout
111        if(timeout == 0)
112                [inquiry setInquiryLength:5];
113        else if(timeout < 20)
114                [inquiry setInquiryLength:timeout];
115        else
116                [inquiry setInquiryLength:20];
117        [inquiry setSearchCriteria:kBluetoothServiceClassMajorAny majorDeviceClass:WM_DEV_MAJOR_CLASS minorDeviceClass:WM_DEV_MINOR_CLASS];
118        [inquiry setUpdateNewDeviceNames:NO];
119
120        IOReturn status = [inquiry start];
121        if (status == kIOReturnSuccess) {
122                [inquiry retain];
123        } else {
124                [self close];
125                WIIC_ERROR("Unable to search for bluetooth devices.");
126        }
127       
128        return status;
129}
130
131- (IOReturn) stop
132{
133        return [inquiry stop];
134}
135
136- (IOReturn) close
137{
138        IOReturn ret = kIOReturnSuccess;
139       
140        ret = [inquiry stop];
141        [inquiry release];
142        inquiry = nil;
143       
144        WIIC_DEBUG(@"Discovery closed");
145        return ret;
146}
147
148#pragma mark -
149#pragma mark IOBluetoothDeviceInquiry delegates
150//*************** HANDLERS FOR WIIC_FIND FOR MACOSX *******************/
151- (void) retrieveWiimoteInfo:(IOBluetoothDevice*) device
152{       
153        // We set the device reference (we must retain it to use it after the search)
154        wiimotes[foundWiimotes]->device = [[device retain] getDeviceRef];
155        wiimotes[foundWiimotes]->address = (CFStringRef)[[device getAddressString] retain];
156       
157        // C String (common for Mac and Linux)
158        CFStringGetCString(wiimotes[foundWiimotes]->address,wiimotes[foundWiimotes]->bdaddr_str,18,kCFStringEncodingMacRoman);
159       
160        WIIMOTE_ENABLE_STATE(wiimotes[foundWiimotes], WIIMOTE_STATE_DEV_FOUND);
161        WIIC_INFO("Found Wiimote (%s) [id %i].",CFStringGetCStringPtr(wiimotes[foundWiimotes]->address, kCFStringEncodingMacRoman),wiimotes[foundWiimotes]->unid);
162        ++foundWiimotes;
163}
164
165- (void) deviceInquiryStarted:(IOBluetoothDeviceInquiry*) sender
166{
167        [self setDiscovering:YES];
168}
169
170- (void) deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry *) sender device:(IOBluetoothDevice *) device
171{
172        if(foundWiimotes < maxWiimotes)
173                [self retrieveWiimoteInfo:device];
174        else
175                [inquiry stop];
176}
177
178- (void) deviceInquiryComplete:(IOBluetoothDeviceInquiry*) sender error:(IOReturn) error aborted:(BOOL) aborted
179{       
180        // The inquiry has completed, we can now process what we have found
181        [self setDiscovering:NO];
182
183        // We stop the search because of errors
184        if ((error != kIOReturnSuccess) && !aborted) {
185                foundWiimotes = 0;
186                [self close];
187                WIIC_ERROR("Search not completed, because of unexpected errors. This error can be due to a short search timeout.");
188                return;
189        }
190       
191        foundWiimotes = [[inquiry foundDevices] count];
192}
193
194@end
195
196@implementation WiiConnect
197#pragma mark -
198#pragma mark WiiConnect
199- (id) init
200{
201        self = [super init];
202        receivedMsg = [[NSData alloc] init];
203        msgLength = 0;
204        _wm = 0;
205        isReading = NO;
206        timeout = NO;
207        disconnecting = NO;
208        return self;
209}
210
211- (void) dealloc
212{       
213        WIIC_DEBUG("Wiimote released");
214        if(receivedMsg)
215                [receivedMsg release];
216        receivedMsg = 0;
217        _wm = 0;
218        [super dealloc];
219}
220
221- (byte*) getNextMsg
222{
223        if(!receivedMsg)
224                return 0;
225
226        return (byte*)[receivedMsg bytes];
227}
228
229- (void) deleteMsg
230{
231        if(receivedMsg) {
232                [receivedMsg release];
233                msgLength = 0;
234        }
235}
236
237- (BOOL) isDisconnecting
238{
239        return disconnecting;
240}
241
242- (BOOL) isReading
243{
244        return isReading;
245}
246
247- (void) setReading:(BOOL) flag
248{
249        isReading = flag;
250}
251
252- (BOOL) isTimeout
253{
254        return timeout;
255}
256
257- (void) setTimeout:(BOOL) flag
258{
259        timeout = flag;
260}
261
262- (void) startTimerThread
263{
264        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
265       
266        // Timer
267        sleep(1);
268       
269        [pool drain];
270}
271
272- (void) wakeUpMainThreadRunloop:(id)arg
273{
274    // This method is executed on main thread!
275    // It doesn't need to do anything actually, just having it run will
276    // make sure the main thread stops running the runloop
277}
278
279
280- (IOBluetoothL2CAPChannel*) openL2CAPChannelWithPSM:(BluetoothL2CAPPSM) psm device:(IOBluetoothDevice*) device delegate:(id) delegate
281{
282        IOBluetoothL2CAPChannel* channel = nil;
283       
284        if ([device openL2CAPChannelSync:&channel withPSM:psm delegate:delegate] != kIOReturnSuccess)
285                channel = nil;
286       
287        return channel;
288}
289
290- (IOReturn) connectToWiimote:(wiimote*) wm
291{
292        IOBluetoothDevice* device = [IOBluetoothDevice withDeviceRef:wm->device];
293        IOBluetoothL2CAPChannel* outCh = nil;
294        IOBluetoothL2CAPChannel* inCh = nil;
295       
296        if(!device) {
297                WIIC_ERROR("Non existent device or already connected.");
298                return kIOReturnBadArgument;
299        }
300       
301        outCh = [self openL2CAPChannelWithPSM:WM_OUTPUT_CHANNEL device:device delegate:self];
302        if (!outCh) {
303                WIIC_ERROR("Unable to open L2CAP output channel (id %i).", wm->unid);
304                [device closeConnection];
305                return kIOReturnNotOpen;
306        }
307        wm->outputCh = [[outCh retain] getL2CAPChannelRef];
308        usleep(20000);
309       
310        inCh = [self openL2CAPChannelWithPSM:WM_INPUT_CHANNEL device:device delegate:self];
311        if (!inCh) {
312                WIIC_ERROR("Unable to open L2CAP input channel (id %i).", wm->unid);
313                [device closeConnection];
314                return kIOReturnNotOpen;
315        }
316        wm->inputCh = [[inCh retain] getL2CAPChannelRef];
317        usleep(20000);
318       
319        IOBluetoothUserNotification* disconnectNotification = [device registerForDisconnectNotification:self selector:@selector(disconnected:fromDevice:)];
320        if(!disconnectNotification) {
321                WIIC_ERROR("Unable to register disconnection handler (id %i).", wm->unid);
322                [device closeConnection];
323                return kIOReturnNotOpen;
324        }
325       
326        // We store the reference to its relative structure (Used for completing the handshake step)
327        _wm = wm;
328       
329        return kIOReturnSuccess;
330}
331
332#pragma mark -
333#pragma mark IOBluetoothL2CAPChannel delegates
334- (void) disconnected:(IOBluetoothUserNotification*) notification fromDevice:(IOBluetoothDevice*) device
335{
336        [self deleteMsg];
337        [self setReading:NO];
338        disconnecting = YES;
339               
340        // The wiimote_t struct must be re-initialized due to the disconnection
341        wiic_disconnected(_wm) ;       
342}
343
344//*************** HANDLERS FOR WIIC_IO_READ FOR MACOSX *******************/
345- (void) l2capChannelData:(IOBluetoothL2CAPChannel*) channel data:(byte *) data length:(NSUInteger) length
346{
347        // This is done in case the output channel woke up this handler
348        if(!data) {
349            [self setReading:NO];
350                length = 0;
351                return;
352        }
353
354        /*
355         * This is called if we are receiving data before completing
356         * the handshaking, hence before calling wiic_poll
357         */
358        if(WIIMOTE_IS_SET(_wm, WIIMOTE_STATE_HANDSHAKE))
359                propagate_event(_wm, data[1], data+2);
360
361        receivedMsg = [[NSData dataWithBytes:data length:length] retain];
362        msgLength = length;
363       
364    // This is done when a message is successfully received. Stop the main loop after reading
365    [self setReading:NO];
366}
367
368- (unsigned int) getMsgLength
369{
370        return msgLength;
371}
372
373- (void) l2capChannelReconfigured:(IOBluetoothL2CAPChannel*) l2capChannel
374{
375      //NSLog(@"l2capChannelReconfigured");
376}
377
378- (void) l2capChannelWriteComplete:(IOBluetoothL2CAPChannel*) l2capChannel refcon:(void*) refcon status:(IOReturn) error
379{
380      //NSLog(@"l2capChannelWriteComplete");
381}
382
383- (void) l2capChannelQueueSpaceAvailable:(IOBluetoothL2CAPChannel*) l2capChannel
384{
385      //NSLog(@"l2capChannelQueueSpaceAvailable");
386}
387
388- (void) l2capChannelOpenComplete:(IOBluetoothL2CAPChannel*) l2capChannel status:(IOReturn) error
389{
390        //NSLog(@"l2capChannelOpenComplete (PSM:0x%x)", [l2capChannel getPSM]);
391}
392
393
394@end
395
396#pragma mark -
397#pragma mark Wiiuse
398/**
399 *      @brief Find a wiimote or wiimotes.
400 *
401 *      @param wm                       An array of wiimote_t structures.
402 *      @param max_wiimotes     The number of wiimote structures in \a wm.
403 *      @param timeout          The number of seconds before the search times out.
404 *
405 *      @return The number of wiimotes found.
406 *
407 *      @see wiimote_connect()
408 *
409 *      This function will only look for wiimote devices.                                               \n
410 *      When a device is found the address in the structures will be set.               \n
411 *      You can then call wiimote_connect() to connect to the found                             \n
412 *      devices.
413 */
414int wiic_find(struct wiimote_t** wm, int max_wiimotes, int timeout)
415{
416        int found_wiimotes = 0;
417
418        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
419        WiiSearch* search = [[WiiSearch alloc] init];
420        [search setWiimoteStruct:wm];
421       
422        if(timeout) { // Single search
423                [search start:timeout maxWiimotes:max_wiimotes];
424       
425                NSRunLoop *theRL = [NSRunLoop currentRunLoop];
426                while ([search isDiscovering] && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
427       
428                found_wiimotes = [search getFoundWiimotes];
429        }
430        else { // Unlimited search
431                found_wiimotes = 0;
432                while(!found_wiimotes) {
433                        [search start:timeout maxWiimotes:max_wiimotes];
434       
435                        NSRunLoop *theRL = [NSRunLoop currentRunLoop];
436                        while ([search isDiscovering] && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
437       
438                        found_wiimotes = [search getFoundWiimotes];     
439                }
440        }
441       
442        WIIC_INFO("Found %i Wiimote device(s).", found_wiimotes);
443       
444        [search release];
445        [pool drain];
446       
447        return found_wiimotes;
448}
449
450
451//*************** HANDLERS FOR WIIC_DISCONNECT FOR MACOSX *******************/
452/**
453 *      @brief Disconnect a wiimote.
454 *
455 *      @param wm               Pointer to a wiimote_t structure.
456 *
457 *      @see wiic_connect()
458 *
459 *      Note that this will not free the wiimote structure.
460 */
461void wiic_disconnect(struct wiimote_t* wm)
462{
463        IOReturn error;
464
465    if (!wm || !WIIMOTE_IS_CONNECTED(wm))
466            return;
467
468        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
469
470        // Input Channel
471        if(wm->inputCh) {
472                IOBluetoothL2CAPChannel* inCh = [IOBluetoothL2CAPChannel withL2CAPChannelRef:wm->inputCh];
473                error = [inCh closeChannel];
474                [inCh setDelegate:nil];
475                if(error != kIOReturnSuccess)
476                        WIIC_ERROR("Unable to close input channel (id %i).", wm->unid);                 
477                usleep(10000);
478                [inCh release];
479                inCh = nil;
480                wm->inputCh = 0;
481        }
482       
483        // Output Channel
484        if(wm->outputCh) {
485                IOBluetoothL2CAPChannel* outCh = [IOBluetoothL2CAPChannel withL2CAPChannelRef:wm->outputCh];
486                error = [outCh closeChannel];
487                [outCh setDelegate:nil];
488                if(error != kIOReturnSuccess)
489                        WIIC_ERROR("Unable to close output channel (id %i).", wm->unid);                       
490                usleep(10000);
491                [outCh release];
492                outCh = nil;
493                wm->outputCh = 0;
494        }
495       
496        // Device
497        if(wm->device) {
498                IOBluetoothDevice* device = [IOBluetoothDevice withDeviceRef:wm->device];
499                error = [device closeConnection];
500
501                if(error != kIOReturnSuccess)
502                        WIIC_ERROR("Unable to close the device connection (id %i).", wm->unid);                 
503                usleep(10000);
504                [device release];
505                device = nil;
506                wm->device = 0;
507        }
508       
509        [pool drain];
510       
511        wm->event = WIIC_NONE;
512
513    WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
514    WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
515}
516
517/**
518 *      @brief Connect to a wiimote with a known address.
519 *
520 *      @param wm               Pointer to a wiimote_t structure.
521 *      @param address  The address of the device to connect to.
522 *                                      If NULL, use the address in the struct set by wiic_find().
523 *  @param autoreconnect        Re-connects the device in case of unexpected disconnection.
524 *
525 *      @return 1 on success, 0 on failure
526 */
527int wiic_connect_single(struct wiimote_t* wm, char* address, int autoreconnect)
528{
529        // Skip if already connected or device not found
530        if(!wm || WIIMOTE_IS_CONNECTED(wm) || wm->device == 0) {
531                WIIC_ERROR("Non existent device or already connected.");
532                return 0;       
533        }
534
535        // Convert the IP address
536        // FIXME - see if it is possible
537
538        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
539        WiiConnect* connect = [[[WiiConnect alloc] init] autorelease];
540        if([connect connectToWiimote:wm] == kIOReturnSuccess) {
541                WIIC_INFO("Connected to wiimote [id %i].", wm->unid);
542                // This is stored to retrieve incoming data
543                wm->connectionHandler = (void*)([connect retain]);
544
545                // Do the handshake
546                WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
547                wiic_handshake(wm, NULL, 0);
548                wiic_set_report_type(wm);
549               
550                /* autoreconnect flag */
551                wm->autoreconnect = autoreconnect;
552               
553                [pool drain];
554        }
555        else {
556                [pool drain];
557                return 0;
558        }
559       
560        return 1;
561}
562
563/**
564 *      @brief Connect to a wiimote or wiimotes once an address is known.
565 *
566 *      @param wm                       An array of wiimote_t structures.
567 *      @param wiimotes         The number of wiimote structures in \a wm.
568 *      @param autoreconnect    Re-connect to the device in case of unexpected disconnection.
569 *
570 *      @return The number of wiimotes that successfully connected.
571 *
572 *      @see wiic_find()
573 *      @see wiic_connect_single()
574 *      @see wiic_disconnect()
575 *
576 *      Connect to a number of wiimotes when the address is already set
577 *      in the wiimote_t structures.  These addresses are normally set
578 *      by the wiic_find() function, but can also be set manually.
579 */
580int wiic_connect(struct wiimote_t** wm, int wiimotes, int autoreconnect)
581{
582        int connected = 0;
583        int i = 0;
584       
585        for (; i < wiimotes; ++i) {
586                if(!(wm[i])) {
587                        WIIC_ERROR("Trying to connect more Wiimotes than initialized");
588                        return;
589                }
590               
591                if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND))
592                        // If the device address is not set, skip it
593                        continue;
594
595                if (wiic_connect_single(wm[i], NULL, autoreconnect))
596                        ++connected;
597        }
598
599        return connected;
600}
601
602/**
603 *      @brief Load Wii devices registered in the wiimotes.config file.
604 *
605 *      @param wm                       An array of wiimote_t structures.
606 *
607 *      @return The number of wiimotes successfully loaded.
608 *
609 *      @see wiic_find()
610 *  @see wiic_connect()
611 *      @see wiic_connect_single()
612 *      @see wiic_disconnect()
613 *
614 *      From version 0.53, it is possible to register the MAC address of your
615 *  Wii devices. This allows to automatically load them, without waiting for any
616 *  search timeout. To register a new device, go to: <HOME_DIR>/.wiic/ and
617 *  edit the file wiimotes.config, by adding the MAC address of the device
618 *  you want to register (one line per MAC address).
619 */
620int wiic_load(struct wiimote_t** wm)
621{
622        int loaded = 0;
623        int i = 0;
624        char str[200];
625        char configPath[100];
626        char* tmp = 0;
627       
628        // Retrieve the HOME environment variable
629        tmp = getenv("HOME");
630        strcpy(configPath,tmp);
631        strncat(configPath,"/.wiic/wiimotes.config",22);
632
633        // Open the config file
634        FILE* fd = 0;
635        fd = fopen(configPath,"r");
636        if(!fd)
637                return loaded;
638
639        // Read line by line
640        while(fgets(str,sizeof(str),fd) != NULL && loaded < 1) {
641                int len = strlen(str)-1;
642        if(str[len] == '\n')
643                str[len] = 0;
644                loaded++;
645        }
646       
647        // We initialize the device structure
648        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
649        for (; i < loaded; ++i) {
650                NSString* string = [NSString stringWithCString:str encoding:[NSString defaultCStringEncoding]];
651                BluetoothDeviceAddress deviceAddr;
652                IOBluetoothNSStringToDeviceAddress(string, &deviceAddr);
653                IOBluetoothDevice* device = [IOBluetoothDevice withAddress:&deviceAddr];
654                wm[i]->device = [[device retain] getDeviceRef];
655                wm[i]->address = (CFStringRef)[[device getAddressString] retain];
656                WIIMOTE_ENABLE_STATE(wm[i], WIIMOTE_STATE_DEV_FOUND);
657                WIIC_INFO("Loaded Wiimote (%s) [id %i].",CFStringGetCStringPtr(wm[i]->address, kCFStringEncodingMacRoman),wm[i]->unid);
658        }
659        [pool drain];
660
661        return loaded;
662}
663
664int wiic_io_read(struct wiimote_t* wm)
665{
666    if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED))
667            return 0;
668
669    /* If this wiimote is not connected, skip it */
670    if (!WIIMOTE_IS_CONNECTED(wm))
671            return 0;
672                       
673        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
674
675        WiiConnect* deviceHandler = 0;
676        deviceHandler = (WiiConnect*)(wm->connectionHandler);
677
678        /* If this wiimote is disconnecting, skip it */
679        if (!deviceHandler || [deviceHandler isDisconnecting]) {
680                [pool drain];
681                return 0;
682        }
683
684    // Run the main loop to get bt data
685        [deviceHandler setReading:YES];
686        [deviceHandler setTimeout:NO];
687
688        // We start the thread which manages the timeout to implement a non-blocking read
689        [NSThread detachNewThreadSelector:@selector(startTimerThread) toTarget:deviceHandler withObject:nil];
690
691        NSRunLoop *theRL = [NSRunLoop currentRunLoop];
692        // Two possible events: we receive and incoming message or there is a timeout
693        while([deviceHandler isReading] && ![deviceHandler isTimeout]) {
694                NSAutoreleasePool *pool_loop = [[NSAutoreleasePool alloc] init]; // This is used for fast release of NSDate, otherwise it leaks
695                [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
696                [pool_loop drain];
697        }
698       
699        // In this case we have no incoming data (TIMEOUT)
700        if([deviceHandler isTimeout]) {
701                [pool drain];
702                return 0;
703        }
704
705        if(!(wm->connectionHandler)) {
706                WIIC_ERROR("Unable to find the connection handler (id %i).", wm->unid);
707                [pool drain];
708                return 0;
709        }
710
711        // Read next message
712        byte* buffer = 0;
713        unsigned int length = 0;
714        if(![deviceHandler isDisconnecting]) {
715                buffer = [deviceHandler getNextMsg];
716                length = [deviceHandler getMsgLength];
717        }
718
719        if(!buffer || !length) {
720                [pool drain];
721                return 0;
722        }
723
724        // Forward to WiiC
725        if(length < sizeof(wm->event_buf))
726                memcpy(wm->event_buf,buffer,length);
727        else {
728                WIIC_DEBUG("Received data are more than the buffer.... strange! (id %i)", wm->unid);
729                memcpy(wm->event_buf,buffer,sizeof(wm->event_buf));
730        }
731
732        // Release the consumed message
733        [deviceHandler deleteMsg];
734
735        [pool drain];
736               
737    return 1;
738}
739
740
741int wiic_io_write(struct wiimote_t* wm, byte* buf, int len)
742{
743        unsigned int length = (unsigned int)len;
744       
745        // Small check before writing
746        if(!wm || !(wm->outputCh)) {
747                WIIC_ERROR("Attempt to write over non-existent channel (id %i).", wm->unid);
748                perror("Error Details");
749                return 0;
750        }
751
752    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
753
754        IOBluetoothL2CAPChannel* channel = [IOBluetoothL2CAPChannel withL2CAPChannelRef:wm->outputCh];
755    IOReturn error = [channel writeSync:buf length:length];
756        if (error != kIOReturnSuccess)
757                WIIC_ERROR("Unable to write over the output channel (id %i).", wm->unid);               
758    usleep(10000);
759       
760    [pool drain];
761
762        return (error == kIOReturnSuccess ? len : 0);
763}
764
765#endif
Note: See TracBrowser for help on using the repository browser.