Problem with call: IOBluetoothDeviceOpenRFCOMMChannelAsync
Problem with call: IOBluetoothDeviceOpenRFCOMMChannelAsync
- Subject: Problem with call: IOBluetoothDeviceOpenRFCOMMChannelAsync
- From: "Christian Martin" <email@hidden>
- Date: Fri, 29 Oct 2004 16:56:08 -0400
Hi,
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:
bool StartBlueTooth()
{
bool returnValue = FALSE;
IOBluetoothSDPServiceRecordRef serviceRecord;
IOBluetoothServiceBrowserControllerRef serviceBrowser;
IOReturn result;
serviceBrowser = IOBluetoothServiceBrowserControllerCreate(
kIOBluetoothServiceBrowserControllerOptionsNone );
result = IOBluetoothServiceBrowserControllerDiscover(serviceBrowser,
&serviceRecord);
if ( (result == kIOReturnSuccess) && (serviceRecord != NULL) )
{
UInt8 rfcommChannelID;
result = IOBluetoothSDPServiceRecordGetRFCOMMChannelID(serviceRecord,
&rfcommChannelID);
if ( result == kIOReturnSuccess )
{
IOBluetoothDeviceRef device;
// Get the device from the service record
device = IOBluetoothSDPServiceRecordGetDevice( serviceRecord );
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 ?
Thanks to anyone that can help.
Christian Martin
// Serial headers
#include <stdio.h>
#include <string.h>
#include
<termios.h>
#include <CoreFoundation/CoreFoundation.h>
// Bluetooth
#include <IOBluetooth/IOBluetoothUserLib.h>
#include
<IOBluetoothUI/IOBluetoothUIUserLib.h>
#include
<CoreServices/CoreServices.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
IOBluetoothRFCOMMChannelRef mRFCOMMChannelRef;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
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;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Bluetooth-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden