在Windows平台上PAN实现的要点和难点

转帖:http://rick-lei-zhao.blog.hexun.com/2002308_d.html

 

Windows平台上PAN实现的要点和难点

蓝牙PAN ProfileSpec里面的描述是非常简单的, 只是定义了几个角色和基本功能, 大量的工作主要是在各个平台上的实现. 下面我就列举一下BlueSoleilWindows平台上的实现的要点和难点, 以供别人参考.

 

首先我先描述一下PAN的工作原理: PAN Profile定义了3种角色:PANU, GNNAP. PANU连到GN,组成的是一个蓝牙设备之间的ad-hoc Network, 蓝牙设备之间可以互相通信; PANU连到NAP, PANU做为外部网络的一部分, NAP一样是网络中的一个节点. 此外BlueSoleil又实现了NAT, 它实际上等于GNNAP的结合, PANU连接到NAT, PANUNAT组成的是ad-hoc Network, 同时, PANU也可以访问外部网络, NAT使用同一个IP地址. 从数据流上来看, GN不需要考虑外部网络的问题, 它只是简单的把PANU发来的数据包转发给其他PANU. NAP需要把所有PANU发来的数据包全部转发到外部网络中,并且从外部网络中抓取到达全部PANU的数据包再转发给PANU. 因此, PAN的实现的关键是在于如何把数据包在蓝牙网络和外部网络中互相转发. 让我们先搞清楚数据流, 发数据时的数据流如下:App--->PAN Driver--->PAN Profile--->BT Stack--->USB Driver--->Remote Device. 收数据时的数据流:Remote Device--->USB Driver--->BT Stack--->PAN Profile--->PAN Driver--->App. 当做为NAP, PAN Profile会转发从PAN Driver来的数据, 如果这些网络包不是给NAP的那么就全部转发给用于访问外部网络的网卡, 同样, PAN Profile也会从访问外部网络的网卡上侦听数据, 如果是到达PANU的数据包就转发给相应的PANU.

这样看来, PAN的实现还是比较简单, 而难点就是在Windows平台上的异常情况的处理. 我就以BlueSoleil的异常处理为例, 这些异常情况有: 1.Dongle. 2. BlueSoleil运行时拔插Dongle. 3. PAN连接时手动Reset(禁用并启用)蓝牙网卡. 4. 做为NAP并有连接时手动Reset物理网卡. 5. IP地址的实时通知.

下面是各个异常情况的解决办法:

  1. Dongle. 由于蓝牙网卡的MAC地址就是Dongle的蓝牙地址, 因此换了Dongle后出现的问题是MAC地址改变了, 而此时由于并没有重新加载驱动, 因此Windows并不会更新蓝牙网卡的信息. 为了让Windows更新网卡信息, 有两种方法: 一种是调用SetupDi API来重新加载Driver, 但是这样的结果是每次重新加载网卡Driver会导致所有其他蓝牙设备重新加载一遍, 我不清楚具体原因, 请了Microsoft的技术支持也没有搞定. 因为我们还装了10个串口, 串口重新加载时非常耗时间, 而这个APIWIN2000下面是同步的, 因此这种方法不可取. 第二种方法是调用INetConnection接口来重新启动网络连接,  就像手动Disable/Enable网络连接一样, 这种方法不会重新加载其他Driver, 也达到了预期的效果. 仅仅更新MAC地址还是不够的, 因为重新加载了蓝牙网卡的Driver, 那么打开DriverDevice Handle也会改变, 原来的Handle就成为无效的了, 因此在Disable之后要释放这个Handle, 在重新Enable之后再打开Driver, 获得一个新的Handle.
  2. BlueSoleil运行时拔插Dongle. 和换Dongle的区别在于不需要重新启动蓝牙网卡.只要把Handle更新就可以.
  3. PAN连接时手动Reset蓝牙网卡. 这里所遇到的问题就是由于蓝牙网卡重新加载, 而使得Handle无效. 解决办法就是重新获得那个Handle. 此外, 由于只能获取蓝牙网卡的WM_DEVICECHANGE消息, 因此还需要记录上一次蓝牙网卡的状态, 用它和当前状态比较才能知道是禁用消息还是启用消息.
  4. 做为NAP并有连接时手动Reset物理网卡. 因为BlueSoleilNAP时是不用蓝牙网卡的, 用的是接入局域网的物理网卡, 因此重新打开的是物理网卡, 而不是蓝牙网卡.
  5. IP地址的实时通知. 如果你用过IphlpapiNotifyAddrChange应该知道, 这个Callback实际上是不太准确的, 也就是说当IP地址改变并可用的时候和这个callback函数回调的时间并不一致, 为了满足BlueSoleil接口的实用性因此还应该做一个同步操作.也就是说当IP地址的改变成功时, 也就是改变后的IP是马上可用的时候才向上层应用通知.

 

以上是我在BlueSoleil项目中对PAN应用的一些心得, 此外, 再顺便说一下对目前BlueSoleilPAN的不足. 从用户的使用习惯上来讲, 建立一个PAN的连接就相当于在一块实际的物理网卡上插入一根网线, 这个时候网络连接的状态才改变成为Connected, 而现在BlueSoleil的做法是只要启动一个PAN服务, 就把网络连接的状态设为Connected, 这会给用户造成一定的混淆, 而且可能会引起将来上层应用的设计.

 

转帖:http://rick-lei-zhao.blog.hexun.com/2002308_d.html

你可能感兴趣的:(windows,网络,Microsoft,callback,NetWork,平台)