Important: |
---|
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. |
You can create a connection between two Bluetooth devices by using the Windows Mobile COM Port emulator facility. The COM Port emulator is the top most layer of the Bluetooth Protocol Stack and provides access to RFCOMM based on a virtual COM port. It does not expose stack interfaces but provides an API layer for opening connections to remote Bluetooth devices.
The Windows Mobile implementation of Bluetooth allows you to
create a piconet. As per the Bluetooth specification, a master
device can connect with seven active slave devices. For more
information about piconet, see the
Bluetooth Core Specificationat this
When this layer is present in the Bluetooth stack, a virtual server or client COM port can be created to accept incoming or create outgoing RFCOMM connections.
Note: |
---|
Microsoft recommends that you use Winsock APIs to create connections. For more information, see Creating a Connection to a Remote Device Using Winsock. |
Before you create a connection between two Bluetooth devices, you must have the following information:
- Address of the Bluetooth device to connect to, stored as a
BT_ADDRtype (for client ports).
- RFCOMM channel number (between 1 and 31).
- COM port number (between 0 and 9) to be assigned for Bluetooth
operations.
The Comtest sample that ships with Windows Mobile, contains source code for creating a Bluetooth connection by using a COM port.
-
Configure the PORTEMUPortParamsstructure to specify attributes for the virtual COM port. This structure stores Bluetooth specific information, such as the channel and Bluetooth address information.
- For a server port, set
flocaland
channel, as the following example shows.
Copy Code PORTEMUPortParams pp; memset (&pp, 0, sizeof(pp)); pp.flocal = TRUE; pp.channel = channel & 0xff;
Note: To avoid conflicts, when you are selecting the server channel, it is recommended that you set channelto RFCOMM_CHANNEL_MULTIPLE (0xfe). This configures RFCOMM to use the next available channel. - For a client port, set the
device,
channel, and the
uiportflagsmembers of
PORTEMUPortParamsas the following example shows.
Copy Code PORTEMUPortParams pp; memset (&pp, 0, sizeof(pp)); pp.device = ba; pp.channel = channel & 0xff;
If the server channel is not known then the client can specify the UUID of the server in the uuidServicemember. In this case, an SDP query is performed automatically to retrieve the target channel number used on the remote device based on the service UUID.
- For a server port, set
flocaland
channel, as the following example shows.
-
Register the device by calling the RegisterDevicefunction, as the following example shows.
Copy Code HANDLE h = RegisterDevice (L"COM", index, L"btd.dll", (DWORD)&pp);
The preceding example specifies the port type as COM, port number, and the name of the device driver DLL, as parameters to RegisterDevice. Also, pass the address of PORTEMUPortParamsstructure, created in step 1, in the dwInfoparameter. RegisterDeviceregisters the Bluetooth Protocol stack with the virtual COM port.
-
Create a null-terminated string to store the name of the COM port. You must include a colon after the port name, as the following example shows.
Copy Code WCHAR szComPort[30]; wsprintf (szComPort, L"COM%d:", index);
-
Open the COM port by calling the CreateFilefunction.
Copy Code HANDLE hCommPort = CreateFile (szComPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
To specify the port name, pass the string created in step 3, in the lpFileNameparameter of CreateFile.
For client ports, the physical connection is created only when the device is open with read or write access by using CreateFile. The physical connection is terminated for both server and client ports when the first handle with read or write access is closed.
Up to four open handles can be outstanding for each virtual port created. Every handle maintains its own set of communication event masks. If a file is open with a 0 access mask, it can only be used for WaitCommEvent, but not with ReadFileand WriteFileAPIs.
Once the COM port is created, it is a functional equivalent of a serial port. The same APIs can be used to access it.
-
Call the CloseHandlefunction and pass the handle returned by CreateFile, as the following example code shows.
Copy Code CloseHandle (hCommPort);
-
To deregister the device, call the DeregisterDevicefunction and pass the handle returned by RegisterDevice, as the following example code shows.
Copy Code DeregisterDevice (h);
-
Set the channelmember of PORTEMUPortParamsto RFCOMM_CHANNEL_MULTIPLE.
Copy Code PORTEMUPortParams pp; memset (&pp, 0, sizeof(pp)); pp.channel = RFCOMM_CHANNEL_MULTIPLE;
-
Create the virtual COM port by using RegisterDeviceand CreateFile.
-
Determine the assigned RFCOMM channel by using the IOCTL, IOCTL_BLUETOOTH_GET_RFCOMM_CHANNEL.
Copy Code DWORD port = 0; DWORD dwSizeOut = 0; HANDLE hFile; if (!DeviceIoControl (hFile, IOCTL_BLUETOOTH_GET_RFCOMM_CHANNEL, NULL, 0, &port, sizeof(port), &dwSizeOut, NULL)) { // Perform error handling }
The following functions are supported:
-
ClearCommError
-
EscapeCommFunction
-
GetCommMask
-
GetCommModemStatus
-
GetCommProperties
-
GetCommState
-
GetCommTimeouts
-
SetCommMask
-
SetCommState
-
SetCommTimeouts
-
WaitCommEvent