On Dec 1, 2006, at 2:50 AM, Martin Elich wrote: Hi Members,
I want to develop some command line based bluetooth applications using C and IOBluetooth.framework. I want to use functions from IOBluetoothUtilities.h, I succeeded at using functions, which return value directly after calling, but I can't get to work for example IOBluetoothDeviceInquiryGetFoundDevices(..), which I think is running in different thread for several seconds. I tried using CFRunLoopRuInMode and registring callback for IOBluetoothDeviceInquiryGetFoundDevices(..) but it is never called during the loop. What should be used instead CFRunLoop? or where is the mistake? Can
Hi Martin,
well, there are a couple of issues here:
1. we screwed up the C API for 10.4 for inquiries, and omitted the extremely important Start/Stop methods. Without calling Start(), the inquiry never actually gets off the ground. We fixed this problem in 10.4.3 or later. The obj-c API does not have this issue. 2. the inquiry API doesn't cause an event source to get set up, so the runloop will immediately exit. Calling IOBluetoothLocalDeviceAvailable() will rectify that problem. 3. extra note - Bluetooth activity must be done on the main thread, so make sure you don't take this code and go crazy with threads, or things will break. Make sure you perform all Bluetooth calls back on the main thread.
I've attached a sample project and source code that will do inquiries on 10.4.3 or later using the C API.
jason
=======================================================
#include <CoreFoundation/CoreFoundation.h> #include <IOBluetooth/IOBluetoothUserLib.h>
//=========================================================================================================================== // DeviceNamePrinterFunction //===========================================================================================================================
void DeviceNamePrinterFunction( const void *value, void *context ) { IOBluetoothDeviceRef deviceRef = (IOBluetoothDeviceRef) value; if( deviceRef ) { CFShow( IOBluetoothDeviceGetNameOrAddress( deviceRef ) ); } }
//=========================================================================================================================== // inquiryDeviceFound //===========================================================================================================================
void inquiryDeviceFound(void *userRefCon,IOBluetoothDeviceInquiryRef inquiryRef, IOBluetoothDeviceRef deviceRef) { CFArrayRef resultsArray; static int i = 0;
resultsArray = IOBluetoothDeviceInquiryGetFoundDevices( inquiryRef ); if( resultsArray ) { printf( "=========== Results Set %d ===========\n", ++i ); CFArrayApplyFunction( resultsArray, CFRangeMake(0, CFArrayGetCount( resultsArray) ), &DeviceNamePrinterFunction, NULL ); printf( "\n" ); } }
//=========================================================================================================================== // inquiryComplete //===========================================================================================================================
void inquiryComplete( void * userRefCon, IOBluetoothDeviceInquiryRef inquiryRef, IOReturn error, Boolean aborted ) { printf( "inquiryComplete!\n" ); CFRunLoopStop( CFRunLoopGetCurrent() ); }
//=========================================================================================================================== // main //===========================================================================================================================
int main (int argc, const char * argv[]) { IOBluetoothDeviceInquiryRef theInquiry; IOReturn error;
error = kIOReturnNoDevice; require( IOBluetoothLocalDeviceAvailable(), exit );
theInquiry = IOBluetoothDeviceInquiryCreateWithCallbackRefCon(NULL); require_action( theInquiry, exit, error = kIOReturnNoResources );
error = IOBluetoothDeviceInquirySetDeviceFoundCallback(theInquiry, inquiryDeviceFound); require_noerr( error, exit );
error = IOBluetoothDeviceInquirySetCompleteCallback(theInquiry, inquiryComplete); require_noerr( error, exit );
// not necessary to call this, but if you want to get some [raw] results fast, don't get names.
error = IOBluetoothDeviceInquirySetUpdateNewDeviceNames( theInquiry, false );
error = IOBluetoothDeviceInquiryStart(theInquiry); require_noerr( error, exit );
CFRunLoopRun();
exit:
if( theInquiry ) { IOBluetoothDeviceInquiryDelete( theInquiry ); }
return 0; }
|