引用自:
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套接字借口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: 偶也在學習中,如有錯誤請多指教。