迷你5207专属论坛

注册

 

发新话题 回复该主题

[WinCE] 蓝牙通信模块开发(.net) [复制链接]

发表者
来至:http://www.cnblogs.com/Caiqinghua/archive/2009/02/23/1396189.html

      在Windows Mobile软件开发中.Net正扮演着日益重要的角色,我们已经可以看到很多用.NetCF开发的软件,这些软件涉及到了日常应用的方方面面。在智能设备的软件开发中,无线互联是一个相当重要的一块,我们可以看到,红外几乎是所有智能设备的标配,而蓝牙也日益在越来越多的智能设备上出现,有了硬件,显然要有相应的软件相关的应用。
  一.关于蓝牙
  做蓝牙通信模块开发,自然先要知道蓝牙通信是怎么一回事。在我看来,蓝牙通信应该和红外通信模块类似,当然我是从开发者的角度来讲,抽象化以后应该就是这样,当然蓝牙和红外通信也有很多不一样的地方。关于蓝牙开发的文章,很多人在.netCF开发中把蓝牙通信当作一个串行通信来处理,这也是不错的,这样做的话,并不是针对蓝牙来开发的,换言之,在使用过程中,需要先手动开启蓝牙,配对,连接,建立串行通道,然后开启应用程序使用,你还要在应用程序中设置串行端口,对最终用户来讲,这是非常麻烦的。
  在红外通信中,设备的DeviceID是一个Byte数组,然而蓝牙设备的DeviceID是一串以“:”分隔的16进制数字。
  红外通信中,一般而言红外并没有开启、关闭之类的状态,但是蓝牙有开启、关闭、可发现三种状态。
  红外没有安全设置,而蓝牙有安全设置,所以我们需要对蓝牙设备进行配对,而红外通信这部需要。
  在.net的Socket地址族里有IrDA,却没有蓝牙相关的地址族,这是我们需要解决的问题。
  三. 获取设备ID
  1.获取本地设备的ID
  在Window CE 4.2的SDK文档中得知获取本地设备ID的函数是BthReadLocalAddr,在btdrt.dll中。
  首先封装本地托管函数:
[DllImport("Btdrt.dll", SetLastError=true)]
static extern int BthReadLocalAddr(byte pba[]);
  这个函数得到的本地DeviceID也是一组byte数组,为了向人们显示出来,我们要把它变为String:
CString strDeviceID;
strDeviceID.Empty();
for(int i=5;i>=0;i--)
{
    strDeviceID.Format(_T("%s%X2),strDeviceID, pba);
}
return strDeviceID;
  2.获取远程设备的ID
      获取远程设备的ID需要先发现远程设备,可以用三个WinsockAPI,分别是WSALookupServiceBegin、WSALookupServiceNext和WSALookupServiceEnd来发现远程设备,具体在Windows CE 4.2的SDK有详细说明。
  WSALookupServiceBegin的函数原形是这样的:
INT WSALookupServiceBegin(
LPWSAQUERYSET lpqsRestrictions,
DWORD dwControlFlags,
LPHANDLE lphLookup
);
  我们用托管代码进行包装:
[DllImport("ws2.dll", EntryPoint="WSALookupServiceBegin", SetLastError=true)]
static extern int CeLookupServiceBegin(byte pQuerySet[] , LookupFlags dwFlags, int &lphLookup);
  可以看到,本来lpqsRestrictions是一个struct,经过包装后在托管代码中成为了byte[],我们计算好该struct大概要占用多少个byte,struct中每一个成员在byte数组中的位置是怎样的,装配出来就好了。
  由于是针对蓝牙作的开发,所以我们要查看一下这些参数应该是哪些值。Windows CE 4.2的SDK中说,蓝牙开发时,struct LPWSAQUERYSET中的如下成员应当为这些值:
The dwSize member must be sizeof(WSAQUERYSET).
The lpBlob member (itself a pointer to a BLOB structure) isoptional, but if used, the device inquire parameters valid forLUP_FLUSHCACHE are the following:
The cbSize member of the BLOB structure must be sizeof(BTH_QUERY_DEVICE).
The pBlobData member is a pointer to a BTH_QUERY_DEVICE structure,for which the LAP member is the Bluetooth inquiry access code, and thelength member is the length of the inquiry, in seconds.
The dwNameSpace member must be NS_BTH.
All other WSAQUERYSET members are ignored.
  我们这样装配pQuerySet:
byte bufferByte[0x400];
meset(bufferByte,0,60);
GCHandle gcHandle = GCHandle.Alloc(blob.ToByteArray(), GCHandleType.Pinned);
IntPtr ptr = gcHandle .AddrOfPinnedObject();
meset(bufferByte,0,4+(int)ptr,0x38);
另外的两个API也照类似方法调用即可。
  在调用了WSALookupServiceNext之后,bytes数组pQuerySet中便包含了远程设备的地址信息,下面我们需要把它找出来。通过阅读SDK中WSAQUERYSET结构的说明和计算每个成员的位置之后,我们写出如下代码:
int num5 = BitConverter.ToInt32(bufferByte, 0x30);
int num6 = Marshal.ReadInt32((IntPtr) num5, 8);
int num7 = Marshal.ReadInt32((IntPtr) num5, 12);
SocketAddress address1 = new SocketAddress(AddressFamily.Unspecified, num7);
  因为.net框架的地址族里面没有蓝牙,所以我们这里用的是AddressFamily.Unspecified。
  然后的工作就是从中获取远程设备的ID了:
  前面我们已经计算出,这个Address里面的前六个字节是byte数组形式的设备ID,第七到第二十二个字节是蓝牙的Service Guid,在后面四个字节是端口号,所以我们只需要分别提取出来即可。
分享 转发
相信与不相信都是矛盾的.  5207宣!欢迎您来到点滴论坛
TOP
发新话题 回复该主题