你可以利用Microsoft Windows CE的串口模拟器在两个蓝牙设备间建立连接。串口模拟器处于蓝牙协议栈的顶层,在虚拟串口的基础上提供连接RFCOMM的通路。它没有暴露栈的接口,而是提供了一个API层来向远程蓝牙设备开放连接。


Microsoft® Windows® CE 的蓝牙实现允许你建立一个piconet。按照蓝牙规范,一个主设备可以同时与7个从设备连接。要了解更多关于piconet的信息,请参见Official Bluetooth Wireless Info Web site上的蓝牙核心规范


当准备好蓝牙栈中的这一层时,就可以创建一个虚拟的服务端或客户端串口来接受或者发起RFCOMM连接。


在你在两个设备间建立连接之前,你必须先知道以下信息:


Ø


Ø


Ø


创建虚拟串口


通过配置PORTEMUPortParams结构体来设置虚拟串口的属性。这个结构体储存了诸如通道和地址等蓝牙详细信息。


PORTEMUPortParams的成员。


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


flocal设为TRUE,使得服务器串口端口能接受传入的连接。服务器通道设置为channel的值。


注意 为了消除冲突,建议你在选择服务器通道时将channel设置为RFCOMM_CHANNEL_MULTIPLE(0xfe),让RFCOMM使用下一个可用的通道。


PORTEMUPortParams中的device、channel和uiportflags。

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


device赋值成一个存有远程设备地址的BT_ADDR型变量,将uiportflags设置为RFCOMM_PORT_FLAGS_REMOTE_DCB通过RFCOMM层初始化一个远程的链接。


uuidService成员中指定服务器的UUID。在这种条件下,SDP查询将自动执行并返回目标通道编号。


2. 通过条用 RegisterDevice


HANDLE h = RegisterDevice (L"COM", index, L"btd.dll", (DWORD)&pp);


上述示例将端口类型定义为COM,端口号、设备驱动DLL名称如参数所示。同时也在dwInfo参数位置传入在第一步创建的PORTEMUPortParams结构体的地址。RegisterDevice将虚拟串口注册到蓝牙协议栈上。


创建一个字符串来储存串口的端口名称,如下例所示,你必须在名称后添加一个冒号


WCHAR szComPort[30];
 
wsprintf (szComPort, L"COM%d:", index);


4. 通过调用 CreateFile

HANDLE hCommPort = CreateFile (szComPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

对于客户端端口,只有在the device is open with read or write access by using CreateFile时才能建立物理连接,当第一个具有读或写权限的句柄关闭的时候服务器和客户端的端口的物理连接都将中止。


WaitCommEvent所使用,而不能与ReadFile和WriteFile一起使用。


一旦串口创建好了,它就等价于一个真实的串口,能调用同样的API来操作它。


删除现有的虚拟串口


1. 调用 CloseHandle 函数,将 CreateFile

CloseHandle (hCommPort);


2. 要注销设备,调用 DeregisterDevice 函数并将 RegisterDevice


DeregisterDevice (h);


在端口模拟中使用“自动通道绑定”


PORTEMUPortParams中的channel 设置为RFCOMM_CHANNEL_MULTIPLE。


PORTEMUPortParams pp;
 
memset (&pp, 0, sizeof(pp));
 
pp.channel = RFCOMM_CHANNEL_MULTIPLE;


使用RegisterDeviceCreateFile创建一个虚拟串口 。


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
 
}