引用自:http://www.sf.org.cn/Article/symbiandev/200509/183.html

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

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

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

选择远程设备的方法
如何查询远程设备

如何查询远程设备上的服务

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

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

选择远程设备的方法

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

·         固定的连接

·         实现存储的配置

·         由用户选择

·         程序自动决定

上面每一个都可能由它合适的情况。前两个方法中,远端设备的地址只需要简单的从存储出取出。而第三种方法则普遍在蓝牙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套接字借口RsocketConnect()函数连接到设备。蓝牙套接字可以用L2CAPRFCOMM协议打开。对于一个L2CAP蓝牙套接字,端口(port)是用来连接的协议/服务多路复用器 (PSM);对于RFCOMM,端口是服务器频道。如果这些值不知道,可以通过读取服务属性ProtocolDescriptorList来获得。详情参见使用蓝牙服务发现代理

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

举例:
// 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();

注意:
·         对于RFCOMML2CAP协议,没有数据可以在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: 偶也在学习中,如有错误请多指教。

posted on 2006-02-25 05:15 移动开发 阅读(679) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理