site_archiver@lists.apple.com Delivered-To: bluetooth-dev@lists.apple.com Hi, bool StartBlueTooth() { bool returnValue = FALSE; IOBluetoothSDPServiceRecordRef serviceRecord; IOBluetoothServiceBrowserControllerRef serviceBrowser; IOReturn result; if ( (result == kIOReturnSuccess) && (serviceRecord != NULL) ) { UInt8 rfcommChannelID; if ( result == kIOReturnSuccess ) { IOBluetoothDeviceRef device; // Get the device from the service record device = IOBluetoothSDPServiceRecordGetDevice( serviceRecord ); .... Thanks to anyone that can help. Christian Martin #include <CoreFoundation/CoreFoundation.h> //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// IOBluetoothRFCOMMChannelRef mRFCOMMChannelRef; _______________________________________________ Do not post admin requests to the list. They will be ignored. Bluetooth-dev mailing list (Bluetooth-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/bluetooth-dev/site_archiver%40lists.a... This email sent to site_archiver@lists.apple.com I am trying to work with a bluetooth device which offers SPP (serial port service). I used the RFCOMM client application sample provided by apple and modified the code for my purposes (I use C and not Objective C (my application is too simple to get there)). Everything is working fine until I get to get call: IOBluetoothDeviceOpenRFCOMMChannelAsync (...). It returns to me -536870179 which is general error (not very informative). Any clues ? Possible bug in the framework ? Here is part of the code: serviceBrowser = IOBluetoothServiceBrowserControllerCreate( kIOBluetoothServiceBrowserControllerOptionsNone ); result = IOBluetoothServiceBrowserControllerDiscover(serviceBrowser, &serviceRecord); result = IOBluetoothSDPServiceRecordGetRFCOMMChannelID(serviceRecord, &rfcommChannelID); if ( ( device != NULL ) && ( IOBluetoothDeviceOpenConnection(device, NULL, NULL) == kIOReturnSuccess ) ) { // Open channel and registers our callback for RFCOMM Events: result = IOBluetoothDeviceOpenRFCOMMChannelAsync(device, &mRFCOMMChannelRef, rfcommChannelID, rfcommEventListener, NULL); /// Call back fctn void rfcommEventListener (IOBluetoothRFCOMMChannelRef rfcommChannel, void *refCon, IOBluetoothRFCOMMChannelEvent *event) { .... } I also noticed that there is quite a bit of memory leaking when I start the application. Any reason ? // Serial headers #include <stdio.h> #include <string.h> #include <termios.h> // Bluetooth #include <IOBluetooth/IOBluetoothUserLib.h> #include <IOBluetoothUI/IOBluetoothUIUserLib.h> #include <CoreServices/CoreServices.h> //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Hold the original termios attributes so we can reset them void rfcommEventListener (IOBluetoothRFCOMMChannelRef rfcommChannel, void *refCon, IOBluetoothRFCOMMChannelEvent *event) { } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void TerminateBluetooth() { if ( mRFCOMMChannelRef != NULL ) { // This will close the RFCOMM channel and start an inactivity timer that will close the baseband connection if no other // channels (L2CAP or RFCOMM) are open after a set period of time. IOBluetoothRFCOMMChannelCloseChannel( mRFCOMMChannelRef ); // This close connection call signals to the system that we are done with the baseband connection. If no other // channels are open, it will immediately close the baseband connection. IOBluetoothDeviceCloseConnection( IOBluetoothRFCOMMChannelGetDevice( mRFCOMMChannelRef ) ); // Since we are done with the RFCOMM channel ref, we need to release it. IOBluetoothObjectRelease( mRFCOMMChannelRef ); mRFCOMMChannelRef = NULL; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool StartBlueTooth() { bool returnValue = FALSE; IOBluetoothSDPServiceRecordRef serviceRecord; //CFArrayRef serviceArray; //IOBluetoothSDPUUIDRef chatUUID; IOBluetoothServiceBrowserControllerRef serviceBrowser; IOReturn result; // NOTE: Ideally, we'd use the IOBluetoothDeviceSelectorController instead of the service selector so that // the user doesn't have to know anything about the service that we are using. However currently the API // on the device selector to add allowed UUIDs that it uses to validate that the selected device has the proper // service only exists in ObjC form. There will be C versions in a future release as well as support for using // the C UI API from a Carbon application. For now, this example will use the service selector, but see the // ObjC version of the example for the more appropriate way to provide UI to the user. // First, we create a service browser controller which will allow us to put up a panel to allow the user // to select a device and service. serviceBrowser = IOBluetoothServiceBrowserControllerCreate( kIOBluetoothServiceBrowserControllerOptionsNone ); // This call will return kIOReturnSuccess if the user has successfully selected a device and service that matches the // specified serviceArray. result = IOBluetoothServiceBrowserControllerDiscover(serviceBrowser, &serviceRecord); if ( (result == kIOReturnSuccess) && (serviceRecord != NULL) ) { UInt8 rfcommChannelID; // To connect we need a device to connect and an RFCOMM channel ID to open on the device: result = IOBluetoothSDPServiceRecordGetRFCOMMChannelID(serviceRecord, &rfcommChannelID); if ( result == kIOReturnSuccess ) { IOBluetoothDeviceRef device; // The service record contains all the useful information about the service the user selected // Just for fun we log its name and RFCOMM Channel ID //NSLog( @"Service selected '%@' - RFCOMM Channel ID = %d\n", (NSString*)IOBluetoothSDPServiceRecordGetServiceName( serviceRecord ), rfcommChannelID ); // Get the device from the service record device = IOBluetoothSDPServiceRecordGetDevice( serviceRecord ); // We must first open the baseband connection to the device before we can open the RFCOMM channel. The RFCOMM Channel // open API should probably do this automatically, but for now we have to do it manually. if ( ( device != NULL ) && ( IOBluetoothDeviceOpenConnection(device, NULL, NULL) == kIOReturnSuccess ) ) { // Open channel and registers our callback for RFCOMM Events: result = IOBluetoothDeviceOpenRFCOMMChannelAsync(device, &mRFCOMMChannelRef, rfcommChannelID, rfcommEventListener, NULL); printf("result = %d\n", result); if ( result == kIOReturnSuccess ) returnValue = TRUE; } } } return returnValue; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Send Data method // returns TRUE if all the data was sent: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool sendData(void* buffer, UInt32 length) { if ( mRFCOMMChannelRef != nil ) { UInt32 numBytesRemaining; IOReturn result; BluetoothRFCOMMMTU rfcommChannelMTU; result = kIOReturnSuccess; numBytesRemaining = length; // Get the RFCOMM Channel's MTU. Each write can only contain up to the MTU size // number of bytes. rfcommChannelMTU = IOBluetoothRFCOMMChannelGetMTU( mRFCOMMChannelRef ); while ( ( result == kIOReturnSuccess ) && ( numBytesRemaining > 0 ) ) { // finds how many bytes I can send: UInt32 numBytesToSend = ( ( numBytesRemaining > rfcommChannelMTU ) ? rfcommChannelMTU : numBytesRemaining ); // This function won't return until the buffer has been passed to the Bluetooth hardware // to be sent to the remote device. // Alternatively, the asynchronous version of this function could be used which would queue // up the buffer and return immediately. result = IOBluetoothRFCOMMChannelWriteSync( mRFCOMMChannelRef, buffer, numBytesToSend ); // Updates the position in the buffer: numBytesRemaining -= numBytesToSend; buffer += numBytesToSend; } // We are successful only if all the data was sent: if ( ( numBytesRemaining == 0 ) && ( result == kIOReturnSuccess ) ) { return TRUE; } } return FALSE; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main() { printf("Starting the application\n"); bool ret = StartBlueTooth(); if (ret != TRUE) { printf("Failed to start\n"); goto kill1; } CFRunLoopRun(); kill1: TerminateBluetooth(); return 0; }