寻找和连接到远程设备的方法
寻找和连接到远程设备的方法
如何寻找和连接到远程设备
当一个应用程序连接到远程设备以便应用其某个服务时,我们需要几个步骤:首先看看是否有想要与之通信的设备。然后察看所需要的服务是否可用。最后,应用程序需要进行连接,另外可能还需要进行些安全措施
下面几个主题将依次介绍相关步骤:
- 选择远程设备的方法
- 如何查询远程设备
- 如何查询远程设备上的服务
- 如何同远程设备连接和传输数据
- 如何在外连的套接字上应用安全措施
选择远程设备的方法
一个应用程序能通过下列方法决定哪个远程设备是他通信的对象:
· 固定的连接
· 实现存储的配置
· 由用户选择
· 程序自动决定
上面每一个都可能由它合适的情况。前两个方法中,远端设备的地址只需要简单的从存储出取出。而第三种方法则普遍在蓝牙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: 偶也在学习中,如有错误请多指教。