引用自:
http://www.sf.org.cn/Article/symbiandev/200509/183.html
如何尋找和連接到遠(yuǎn)程設(shè)備
當(dāng)一個(gè)應(yīng)用程序連接到遠(yuǎn)程設(shè)備以便應(yīng)用其某個(gè)服務(wù)時(shí),我們需要幾個(gè)步驟:首先看看是否有想要與之通信的設(shè)備。然后察看所需要的服務(wù)是否可用。最后,應(yīng)用程序需要進(jìn)行連接,另外可能還需要進(jìn)行些安全措施
下面幾個(gè)主題將依次介紹相關(guān)步驟:
選擇遠(yuǎn)程設(shè)備的方法
如何查詢(xún)遠(yuǎn)程設(shè)備
如何查詢(xún)遠(yuǎn)程設(shè)備上的服務(wù)
如何同遠(yuǎn)程設(shè)備連接和傳輸數(shù)據(jù)
如何在外連的套接字上應(yīng)用安全措施
選擇遠(yuǎn)程設(shè)備的方法
一個(gè)應(yīng)用程序能通過(guò)下列方法決定哪個(gè)遠(yuǎn)程設(shè)備是他通信的對(duì)象:
· 固定的連接
· 實(shí)現(xiàn)存儲(chǔ)的配置
· 由用戶(hù)選擇
· 程序自動(dòng)決定
上面每一個(gè)都可能由它合適的情況。前兩個(gè)方法中,遠(yuǎn)端設(shè)備的地址只需要簡(jiǎn)單的從存儲(chǔ)出取出。而第三種方法則普遍在藍(lán)牙UI中提供。
最后一種程序自動(dòng)選擇遠(yuǎn)程設(shè)備中,可能在下列情況中應(yīng)用:
· 為用戶(hù)提供可定制的設(shè)備選擇UI
· 在某些特別情況下選擇設(shè)備,比如“選擇最空閑的LAN接入點(diǎn)”
如何查詢(xún)遠(yuǎn)程設(shè)備
每個(gè)藍(lán)牙設(shè)備在其硬件中都有唯一的48位地址。一個(gè)范圍內(nèi)基本的設(shè)備查詢(xún)將返回零或幾個(gè)此類(lèi)地址。
除了這個(gè)地址,藍(lán)牙設(shè)備也還有一個(gè)文本名字顯示給用戶(hù)。如果你希望顯示可用設(shè)備的列表給用戶(hù),你也要獲取這些名字以便顯示。
如果底層硬件支持,地址和名字也可以同時(shí)被查詢(xún)。否則,地址的查詢(xún)必須在名字查詢(xún)請(qǐng)求發(fā)送前完成
泛化套接字類(lèi)RhostResolver用來(lái)完成地址和設(shè)備名的查詢(xún)。另外TinquirySockAddr為專(zhuān)門(mén)的藍(lán)牙套接字地址類(lèi),里面封裝了藍(lán)牙地址,查詢(xún)?nèi)肟诖a,用來(lái)提供相關(guān)查詢(xún)的服務(wù)和設(shè)備類(lèi)。
獲得遠(yuǎn)程設(shè)備的地址
下面步驟用來(lái)查詢(xún)遠(yuǎn)程設(shè)備的地址:
1. 連接到套接字服務(wù)器(RSocketServ),然后用RSocketServ::FindProtocol()選擇使用的協(xié)議。由于名字和地址的查詢(xún)由堆棧的BTLinkManager協(xié)議層支持,所以選擇它。
2. 創(chuàng)建并初始化一個(gè)RhostResolver對(duì)象。
3. 設(shè)置TinquirySockAddr參數(shù)以便查詢(xún):對(duì)于地址查詢(xún), KHostResInquiry標(biāo)志需要通過(guò)TInquirySockAddr::SetAction()設(shè)置好。
然后可以通過(guò)RHostResolver::GetByAddress()開(kāi)始查詢(xún)。
如何查詢(xún)遠(yuǎn)程設(shè)備的服務(wù)
一個(gè)遠(yuǎn)程設(shè)備可以有一個(gè)或者多個(gè)藍(lán)牙服務(wù)提供者。服務(wù)的廣泛指示器可以從設(shè)備的類(lèi)中讀出。這樣可以用來(lái)選擇合適的設(shè)備圖標(biāo)現(xiàn)實(shí)給用戶(hù)。這個(gè)設(shè)備的類(lèi)可以在查詢(xún)地址后用TInquirySockAddr::MajorClassOfDevice()獲得。
在特定環(huán)境,設(shè)備的類(lèi)提供的粗級(jí)別的服務(wù)發(fā)現(xiàn)并不能滿足對(duì)設(shè)備的選擇條件。這樣,這樣,服務(wù)發(fā)現(xiàn)請(qǐng)求可以用來(lái)判斷是否為適合的選擇。但只有在必需的時(shí)后才應(yīng)該應(yīng)用,因?yàn)樗枰恍╊~外時(shí)間來(lái)對(duì)每個(gè)設(shè)備進(jìn)行SDP請(qǐng)求。SDP請(qǐng)求通過(guò)藍(lán)牙發(fā)現(xiàn)代理API來(lái)進(jìn)行。
如何同遠(yuǎn)程設(shè)備連接和傳輸數(shù)據(jù)
一旦設(shè)備和服務(wù)確定了,你就能夠連接到遠(yuǎn)程設(shè)備并開(kāi)始使用了
通過(guò)泛化的Symbian OS套接字借口Rsocket的Connect()函數(shù)連接到設(shè)備。藍(lán)牙套接字可以用L2CAP和RFCOMM協(xié)議打開(kāi)。對(duì)于一個(gè)L2CAP藍(lán)牙套接字,端口(port)是用來(lái)連接的協(xié)議/服務(wù)多路復(fù)用器 (PSM);對(duì)于RFCOMM,端口是服務(wù)器頻道。如果這些值不知道,可以通過(guò)讀取服務(wù)屬性ProtocolDescriptorList來(lái)獲得。詳情參見(jiàn)使用藍(lán)牙服務(wù)發(fā)現(xiàn)代理
你能夠通過(guò)套接字使用目標(biāo)服務(wù)期望的格式讀寫(xiě)數(shù)據(jù)(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();
注意:
· 對(duì)于RFCOMM和L2CAP協(xié)議,沒(méi)有數(shù)據(jù)可以在Connect() 和Shutdown() 調(diào)用中送出,否則會(huì)導(dǎo)致獲得額外數(shù)據(jù)的錯(cuò)誤。
· RFCOMM使用流套接字類(lèi)型(KSockStream)。
· L2CAP使用序列包的套接字類(lèi)型 (KsockSeqPacket)。
如何在外連的套接字上應(yīng)用安全措施
對(duì)于一個(gè)外連接(outgoing connection),默認(rèn)情況下藍(lán)牙堆棧不會(huì)由具體的安全措施。如果遠(yuǎn)程設(shè)備需要認(rèn)證或編碼連接,那堆棧會(huì)直接體現(xiàn)到應(yīng)用程序。
有時(shí)候,本地程序也需要保證認(rèn)證或編碼連接。可以對(duì)RSocket用控制操作(ioctls)來(lái)認(rèn)證(ioctl KHCIAuthRequestIoctl) 或者編碼 (KHCIEncryptIoctl) 連接。
舉例
下面的例子就將對(duì)認(rèn)證請(qǐng)求應(yīng)用了ioctl
// Assume have an opened L2CAP RSocket object, socket
socket.Ioctl(KHCIAuthRequestIoctl, status, NULL, KSolBtHCI);
User::WaitForRequest(status);
if (status==KErrNone)
{
\\ Success...
ps: 偶也在學(xué)習(xí)中,如有錯(cuò)誤請(qǐng)多指教。