寻找和连接到远程设备的方法

寻找和连接到远程设备的方法

如何寻找和连接到远程设备

当一个应用程序连接到远程设备以便应用其某个服务时,我们需要几个步骤:首先看看是否有想要与之通信的设备。然后察看所需要的服务是否可用。最后,应用程序需要进行连接,另外可能还需要进行些安全措施

下面几个主题将依次介绍相关步骤:

  • 选择远程设备的方法
  • 如何查询远程设备
  • 如何查询远程设备上的服务
  • 如何同远程设备连接和传输数据
  • 如何在外连的套接字上应用安全措施

选择远程设备的方法

一个应用程序能通过下列方法决定哪个远程设备是他通信的对象:

· 固定的连接

· 实现存储的配置

· 由用户选择

· 程序自动决定

上面每一个都可能由它合适的情况。前两个方法中,远端设备的地址只需要简单的从存储出取出。而第三种方法则普遍在蓝牙UI中提供。

最后一种程序自动选择远程设备中,可能在下列情况中应用:

· 为用户提供可定制的设备选择UI

· 在某些特别情况下选择设备,比如“选择最空闲的LAN接入点”

如何查询远程设备

每个蓝牙设备在其硬件中都有唯一的48位地址。一个范围内基本的设备查询将返回零或几个此类地址。

除了这个地址,蓝牙设备也还有一个文本名字显示给用户。如果你希望显示可用设备的列表给用户,你也要获取这些名字以便显示。

如果底层硬件支持,地址和名字也可以同时被查询。否则,地址的查询必须在名字查询请求发送前完成

泛化套接字类RhostResolver用来完成地址和设备名的查询。另外TinquirySockAddr为专门的蓝牙套接字地址类,里面封装了蓝牙地址,查询入口代码,用来提供相关查询的服务和设备类。

获得远程设备的地址

下面步骤用来查询远程设备的地址:

1. 连接到套接字服务器(RSocketServ),然后用RSocketServ::FindProtocol()选择使用的协议。由于名字和地址的查询由堆栈的BTLinkManager协议层支持,所以选择它。

2. 创建并初始化一个RhostResolver对象。

3. 设置TinquirySockAddr参数以便查询:对于地址查询, KHostResInquiry标志需要通过TInquirySockAddr::SetAction()设置好。

然后可以通过RHostResolver::GetByAddress()开始查询。

如何查询远程设备的服务

一个远程设备可以有一个或者多个蓝牙服务提供者。服务的广泛指示器可以从设备的类中读出。这样可以用来选择合适的设备图标现实给用户。这个设备的类可以在查询地址后用TInquirySockAddr::MajorClassOfDevice()获得。

在特定环境,设备的类提供的粗级别的服务发现并不能满足对设备的选择条件。这样,这样,服务发现请求可以用来判断是否为适合的选择。但只有在必需的时后才应该应用,因为它需要一些额外时间来对每个设备进行SDP请求。SDP请求通过蓝牙发现代理API来进行。

如何同远程设备连接和传输数据

一旦设备和服务确定了,你就能够连接到远程设备并开始使用了

通过泛化的Symbian OS套接字借口Rsocket的Connect()函数连接到设备。蓝牙套接字可以用L2CAP和RFCOMM协议打开。对于一个L2CAP蓝牙套接字,端口(port)是用来连接的协议/服务多路复用器 (PSM);对于RFCOMM,端口是服务器频道。如果这些值不知道,可以通过读取服务属性ProtocolDescriptorList来获得。详情参见使用蓝牙服务发现代理

你能够通过套接字使用目标服务期望的格式读写数据(AT指令,文本,HTTP,PPP等)

举例:

// Assume have a TInquirySockAddr object, addr, with relevant device info

// Connect an L2CAP socket
RSocket socket;
TRequestStatus status;
User::LeaveIfError(socket.Open(socketServ,KBTAddrFamily,KSockSeqPacket,KL2CAP));
User::LeaveIfError(socket.Connect(addr,status));
User::WaitForRequest(status);

if (status == KErrNone)

{
// Write some simple data
_LIT8(KDataToWrite,"01234");
socket.Write(KDataToWrite,status);
User::WaitForRequest(status);
}

// Close socket
socket.Close();

注意:

· 对于RFCOMM和L2CAP协议,没有数据可以在Connect()Shutdown() 调用中送出,否则会导致获得额外数据的错误。

· RFCOMM使用流套接字类型(KSockStream)。

· L2CAP使用序列包的套接字类型 (KsockSeqPacket)。

如何在外连的套接字上应用安全措施

对于一个外连接(outgoing connection),默认情况下蓝牙堆栈不会由具体的安全措施。如果远程设备需要认证或编码连接,那堆栈会直接体现到应用程序。

有时候,本地程序也需要保证认证或编码连接。可以对RSocket用控制操作(ioctls)来认证(ioctl KHCIAuthRequestIoctl) 或者编码 (KHCIEncryptIoctl) 连接。

举例

下面的例子就将对认证请求应用了ioctl

// Assume have an opened L2CAP RSocket object, socket
socket.Ioctl(KHCIAuthRequestIoctl, status, NULL, KSolBtHCI);
User::WaitForRequest(status);
if (status==KErrNone)

{
// Success...

ps: 偶也在学习中,如有错误请多指教。