WINCE为我们提供了便利的函数来建立蓝牙连接,其中就包括建立蓝牙的虚拟串口连接.利用虚拟串口连接,我们可以方便的把以前利用串口连接传输数据的程序改为蓝牙无线传输的程序.这个过程只需要一个步骤,就是在服务端和客户端注册虚拟串口.
       RegisterDevice这个函数就完成了这个功能.通过这个函数建立了串口之后,就可以像操控以往的串口一样用CreateFile,read,write这些系统API来读写.

以下的内容摘自MSDN:

You can create a connection between two Bluetooth devices by using the Microsoft Windows CE 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.

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.

Before you create a connection between two Bluetooth devices, you must have the following information:

1     Address of the Bluetooth device to connect to, stored as a BT_ADDR type (for client ports).
2     RFCOMM channel number (between 1 and 31).
3     COM port number (between 0 and 9) to be assigned for Bluetooth operations.

The Com test sample that ships with Windows CE, contains source code for creating a Bluetooth connection by using a COM port. For more information about this sample, see Virtual COM Port Creation Sample.

To create a virtual COM port

Configure the PORTEMUPortParams structure 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 PORTEMUPortParams members, as the following example shows.

PORTEMUPortParams pp;
memset (&pp, 0, sizeof(pp));
pp.flocal = TRUE;
pp.channel = channel & 0xff;

The preceding example configures PORTEMUPortParams by setting flocal to TRUE. This enables a server COM port to accept incoming connections. The server channel is specified explicitly by setting channel.

Note   To avoid conflicts, when you are selecting the server channel, it is recommended that you set channel to RFCOMM_CHANNEL_MULTIPLE (0xfe). This configures RFCOMM to use the next available channel.
For a client port, set the device, channel, and the uiportflags members of PORTEMUPortParams.

The following example code shows how to set PORTEMUPortParams for a client port.

PORTEMUPortParams pp;
memset (&pp, 0, sizeof(pp));
pp.device = ba;
pp.channel = channel & 0xff;
pp.uiportflags = RFCOMM_PORT_FLAGS_REMOTE_DCB;

In the preceding example, device is set to a BT_ADDR type that stores the remote device address and uiportflags is set to RFCOMM_PORT_FLAGS_REMOTE_DCB to initiate a remote connection over the RFCOMM layer.

If the server channel is not known then the client can specify the UUID of the server in the uuidService member. In this case, an SDP query is performed automatically to retrieve the target channel number.

Register the device by calling the RegisterDevice function, as the following example shows.
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 PORTEMUPortParams structure, created in step 1, in the dwInfo parameter. RegisterDevice registers 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.
WCHAR szComPort[30];
wsprintf (szComPort, L"COM%d:", index);
Open the COM port by calling the CreateFile function.
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 lpFileName parameter 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 ReadFile and WriteFile APIs.

Once the COM port is created, it is a functional equivalent of a serial port. The same APIs can be used to access it.

To remove an existing virtual COM port

Call the CloseHandle function and pass the handle returned by CreateFile, as the following example code shows.
CloseHandle (hCommPort);
To deregister the device, call the DeregisterDevice function and pass the handle returned by RegisterDevice, as the following example code shows.
DeregisterDevice (h);
To use auto-bound channel in port emulation

Set the channel member of PORTEMUPortParams to RFCOMM_CHANNEL_MULTIPLE.
PORTEMUPortParams pp;
memset (&pp, 0, sizeof(pp));
pp.channel = RFCOMM_CHANNEL_MULTIPLE;
Create the virtual COM port by using RegisterDevice and CreateFile.
Determine the assigned RFCOMM channel by using the IOCTL, IOCTL_BLUETOOTH_GET_RFCOMM_CHANNEL.
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


blog comments powered by Disqus

Published

2007-02-13

Categories


Tags