日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux下Bluez的编程实现

發布時間:2023/12/15 linux 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下Bluez的编程实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>


藍牙的各個協議棧的簡介?2

1.1、藍牙技術?2

1.1、藍牙協議棧?2

1.2、藍牙技術的特點?4

1.2.1、藍牙協議棧體系結構?4

1.2.2、藍牙協議棧低層模塊?5

1.2.3、軟件模塊?5

1.3、藍牙的一些Profile 6

2BluezD-Bus 8

2.1BluezD-Bus體系結構?8

2.2D-Bus介紹?10

2.3Bluez的安全接口?14

2.4Bluez適配器接口?19

2.5Bluez配對?19

2.6Bluez綁定?20

3Bluez編程實現?21

3.1、藍牙開發關鍵技術剖析?21

3.1.1、連接機制分析?21

3.1.2、自動連接?21

3.1.3、時鐘設計?22

3.1.4、配對列表管理?23

3.1.5、藍牙文件傳輸模式?23

3.2hci層介紹?23

3.2.1hci層介紹?23

3.2.2hci層編程?24

3.3L2CAP層編程?28

3.3.1L2CAP協議簡介?28

3.3.2L2CAP編程方法?29

3.4SDP協議簡介?30

4Openobex 31

4.1Openobex簡介?31

4.2Openobexbluez編程實現?33

Obexftp 35

5.1obexftp簡介?35

5.2、基于Obexftp的應用程序開發?35

6、參考資料?35

?

藍牙的各個協議棧的簡介

1.1、藍牙技術

??藍牙(Bluetooth)技術是由EricssonIBMIntelNokiaToshiba公司于19985月共同提出開發的,并聯合成立了藍牙特殊利益小組(SIG),負責開發無線協議規范并設定交互操作的需求。其本質是設備間的無線鏈接,意在于代替有線電纜。

1.1、藍牙協議棧

協議棧是指一組協議的集合,舉個例子,把大象裝到冰箱里,總共要3步。每步就是一個協議,3步組成一個協議棧。把應用層數據包發出去,也要好幾步,TCP/UDP頭,IP頭,ether頭,每步也是一個協議。另外每層都有一些特殊的協議。所有這些統稱協議棧。藍牙協議棧就是SIG定義的一組協議的規范,目標是允許遵循規范的藍牙應用能夠進行相互間操作,如圖1.1藍牙協議棧

?

1.1?藍牙協議棧

在藍牙協議體系中,底層、中間層、應用層按序排列構成了藍牙協議棧,如左圖所示。底層(硬件層)和中間協議層(軟件層)之間?的接口使用主機控制器接口(HCI)HCI是軟硬件之間必不可少的接口,其功能是解釋并傳遞兩層之間的消息和數據。軟件通過HCI調用底層LMP/BBRF等硬件。HCI以下的功能由藍牙設備實施;HCI以上的功能由軟件運行,在主機上實現。HCI對于上、下兩層數據的傳輸都是透明的。

在藍牙協議棧中,最主要的是藍牙核心協議,包括基帶協議(BP)、鏈路管理協議(LMP)、鏈接控制和適配協議(L2CAP)、服務發現協議(SDP)等。藍牙設備基本上都需要核心協議,其他協議則按藍牙設備的需要而選定。

?

1.2、藍牙技術的特點

1.2.1、藍牙協議棧體系結構

整個藍牙協議體系結構可分為底層硬件模塊、中間協議層和高端應用層三大部分。鏈路管理層(LMP)、基帶層(BBP)和藍牙無線電信道構成藍牙的底層模塊。BBP層負責跳頻和藍牙數據及信息幀的傳輸。

LMP層:負責連接的建立和拆除以及鏈路的安全和控制,它們為上層軟件模塊提供了不同的訪問人口,但是兩個模塊接口之間的消息和數據傳遞必須通過藍牙主機控制器接口的解釋才能進行。也就是說,中間協議層包括邏輯鏈路控制與適配協議(L2CAP)、服務發現協議(SDP)、串口仿真協議(RFCOMM)和電話控制協議規范(TCS)

L2CAP:完成數據拆裝、服務質量控制、協議復用和組提取等功能,是其他上層協議實現的基礎,因此也是藍牙協議棧的核心部分。

SDP:為上層應用程序提供一種機制來發現網絡中可用的服務及其特性。在藍牙協議棧的最上部是高端應用層,它對應于各種應用模型的剖面,是剖面的一部分。目前定義了13種剖面。

1.2.2藍牙協議棧低層模塊

藍牙的低層模塊是藍牙技術的核心,是任何藍牙設備都必須包括的部分。

  藍牙工作在2.4GHZISM頻段。采用了藍牙結束的設備講能夠提供高達720kbit/s?的數據交換速率。

  藍牙支持電路交換和分組交換兩種技術,分別定義了兩種鏈路類型,即面向連接的同步鏈路(SCO)和面向無連接的異步鏈路(ACL)

  為了在很低的功率狀態下也能使藍牙設備處于連接狀態,藍牙規定了三種節能狀態,即停等(Park)狀態、保持(Hold)狀態和呼吸(Sniff)狀態。這幾種工作模式按照節能效率以升序排依次是:Sniff模式、Hold模式、Park模式。

  藍牙采用三種糾錯方案:1/3前向糾錯(FEC)2/3前向糾錯和自動重發(ARQ)。前向糾錯的目的是減少重發的可能性,但同時也增加了額外開銷。然而在一個合理的無錯誤率環境中,多余的投標會減少輸出,故分組定義的本身也保持靈活的方式,因此,在軟件中可定義是否采用FEC。一般而言,在信道的噪聲干擾比較大時藍牙系統會使用前向糾錯方案,以保證通信質量:對于SCO鏈路,使用1/3前向糾錯;對于ACL鏈路,使用2/3前向糾錯。在無編號的自動請求重發方案中,一個時隙傳送的數據必須在下一個時隙得到收到的確認。只有數據在收端通過了報頭錯誤檢測和循環冗余校驗(CRC)后認為無錯時,才向發端發回確認消息,否則返回一個錯誤消息。

藍牙系統的移動性和開放性使得安全問題變得及其重要。雖然藍牙系統所采用的調頻技術就已經提供了一定的安全保障,但是藍牙系統仍然需要鏈路層和應用層的安全管理。在鏈路層中,藍牙系統提供了認證、加密和密鑰管理等功能。每個用戶都有一個個人標識碼(PIN),它會被譯成128bit的鏈路密鑰(Link Key)來進行單雙向認證。一旦認證完畢,鏈路就會以不同長度的密碼(Encryphon Key)來加密(此密碼以shit為單位增減,最大的長度為128bit)鏈路層安全機制提供了大量的認證方案和一個靈活的加密方案(即允許協商密碼的長度)。當來自不同國家的設備互相通信時,這種機制是極其重要的,因為某些國家會指定最大密碼長度。藍牙系統會選取微微網中各個設備的最小的最大允許密碼長度。例如,美國允許128bit的密碼長度,而西班牙僅允許48bit,這樣當兩國的設備互通時,將選擇48bit來加密。藍牙系統也支持高層協議棧的不同應用體內的特殊的安全機制。例如兩臺計算機在進行商業卡信息交流時,一臺計算機就只能訪問另一臺計算機的該項業務,而無權訪問其他業務。藍牙安全機制依賴PIN在設備間建立信任關系,一旦這種關系建立起來了,這些PIN就可以存儲在設備中以便將來更快捷地連接。

1.2.3、軟件模塊

L2CAP是數據鏈路層的一部分,位于基帶協議之上。L2CAP向上層提供面向連接的和無連接的數據服務,它的功能包括:協議的復用能力、分組的分割和重新組裝(Segmentation And Reaassembly)以及提取(Group Abstraction)L2CAP允許高層協議和應用發送和接受高達64K Byte的數據分組。

  SDP為應用提供了一個發現可用協議和決定這些可用協議的特性的方法。藍牙環境下的服務發現與傳統的網絡環境下的服務發現有很大的不同,在藍牙環境下,移動的RF環境變化很大,因此業務的參數也是不斷變換的。SDP將強調藍牙環境的獨特的特性。藍牙使用基于客戶/服務器機制定義了根據藍牙服務類型和屬性發現服務的方法,還提供了服務瀏覽的方法。

  RFCOMM是射頻通信協議,它可以仿真串行電纜接口協議,符合ETSI0710串口仿真協議。通過RFCOMM,藍牙可以在無線環境下實現對高層協議,如PPPTCP/IPWAP等的支持。另外,RFCOMM可以支持AT命令集,從而可以實現移動電話機和傳真機及調制解調器之間的無線連接。

  藍牙對語音的支持是它與WLAN相區別的一個重要的標志。藍牙電話控制規范是一個基于ITU-T建議Q.931的采用面向比特的洗衣,它定義了用于藍牙設備間建立語音和數據呼叫的呼叫控制信令以及用于處理藍牙TCS設備的移動性管理過程。

1.3、藍牙的一些Profile

藍牙里面profile的定義,profile既是配置文件,配置文件定義了可能的應用,藍牙配置文件表達了一般行為,藍牙設備可以通過這些行為與其它設備進行通信。藍牙技術定義了廣泛的配置文件,描述了許多不同類型的使用案例。按照藍牙規格中提供的指導,開發商可以創建應用程序以與其它符合藍牙規格的設備協同工作。 到目前為止,藍牙一共有22profile,在www.bluetooth.com§上有詳細的文檔說明。

已經實現了的協議棧:

Widcomm:?第一個windows上的協議棧,由Widcomm公司開發,也就是現在的Broadcom .

Microsoft Windows stack: Windows XP SP2中包括了這個內建的協議棧,開發者也可以調用其API開發第三方軟件。

Toshiba stack:?它也是基于Windows的,不支持第三方開發,但它把協議棧授權給一些laptop商)。它支持的Profile有:?SPP, DUN, FAX, LAP, OPP, FTP, HID, HCRP, PAN, BIP, HSP, HFP , A2DP, AVRCP, GAVDP

BlueSoleil:?著名的IVT公司的產品,這個應該是個中國公司。該產品可以用于桌面和嵌入式,他也支持第三方開發,DUN, FAX, HFP, HSP, LAP, OBEX, OPP, PAN SPP, AV, BIP, FTP, GAP, HID, SDAP, and SYNC

Bluez: Linux官方協議棧,該協議棧的上層用Socket封裝,便于開發者使用,通過DBUS與其它應用程序通信。

Affix: NOKIA公司的協議棧,在Symbian系統上運行。

BlueDragon:東軟公司產品,支持的ProfileSDPSerial-DevBAVCTPAVRCP-ControllerAVRCP-TargetHeadset-AGHeadset-HSOPP-ClientOPP-ServerCT-GWCT-TermIntercomFT-ServerFT-ClientGAPSDAPSerial-DevAAVDTPGAVDPA2DP-SourceA2DP-Sink

BlueMagic:美國Open Interface?公司for portable embedded divce的協議棧,iphone(apple)nav-u(sony)等很多電子產品都用該商業的協議棧,BlueMagic 3.0是第一個通過bluetooth?協議棧1.1認證的協議棧,那么我現在就在用它,那么該棧用起來簡單,API清晰明了。實現了的profile:HCI,L2CAP,RFCOMM,A/V,Remote,Control,A/V,Streaming,BIP,BPP,DUN,FAX,FTP,GAP,Hands-Free,and,Headset,HCRP,HID,OBEX,OPP,PAN,BNEP,PBAP,SAP,SPP,Synchronization,SyncML,Telephony,XML.

BCHS-Bluecore Host Software:?藍牙芯片CSR的協議棧,同時他也提供了一些上層應用的Profile的庫。

Windows CE:微軟給Windows CE開發的協議棧,但是windows ce本身也支持其它的協議棧。

BlueLetIVT公司for embedded product的清量級協議棧。

2BluezD-Bus

2.1BluezD-Bus體系結構

?

The?BlueZ?D-Bus?interfaces aim to provide seamless Bluetooth technology integration into the desktop. A central Bluetooth daemon "hcid"(planned to be renamed to bluetoothd) is responsible for take care of all tasks that can’t or shouldn’t be handled inside the Linux kernel. These jobs include PIN code and link key management for the authentication and encryption, caching of device names and services and also central control of the Bluetooth hardware. The interface exported allows to abstract the internals of GNOME, KDE,Maemo,?OpenMoko, ... applications from any technical details of the Bluetooth specification. Even other application will get access to the Bluetooth technology without any hassle.

BluezD-bus接口,提供了藍牙技術和桌面系統的完美集成。藍牙的中心守護進程hcid的職責就是處理那些不能被linux內核處理的任務,包括處理為鑒權和加密過程中需要的PIN碼和密鑰、緩存設備的名稱和服務類型,同時也是藍牙硬件的控制中心。

The BlueZ?D-Bus?services are exported through the system message bus. Every D-Bus enabled desktop has a system message bus instance running. This bus is used to broadcast system events, such as new hardware devices, network connection status, and so forth. The session message bus is not suitable for this architecture since the Bluetooth hardware/connections are shared by all desktop sessions.

BluezD-bus服務通過系統消息總線提供。每個D - Bus使桌面有一個系統消息總線實例運行。這個bus是用來廣播系統時間,如新的硬件設備、網絡連接狀態等等。會話消息總線對這種體系結構是不適合的,因為藍牙硬件/連接被所有桌面會話共享。

The BlueZ D-Bus Architecture goal are:

  • Abstract Bluetooth HCI commands/events

  • Provide an easy interface to setup Bluetooth adapter and manage the services

BluezD-bus體系結構的目標:

  • 抽象hci層命令和事件。

  • 提供簡單的接口來啟動藍牙適配器和管理藍牙服務。

The hcid is the main entity of the architecture. It implements methods to setup the Bluetooth adapters, retrieve remote device properties, control the pairing procedure and control the services registration/searches. The following figure shows a high level relationship between the entities.

Hcid是該體系結構的主體。它實現啟動藍牙適配器的方法、獲取遠端設備屬性、控制配對過程和控制服務的注冊和搜索。下圖顯示了一個高層次的實體之間的關系。

?

2.2D-Bus介紹

什么是D-Bus

D-BUS?是一種進程間通信的方式,從架構上來說,分為三層:

  • 一個庫,libdbus,允許2個進程間交換信息。

  • 一個消息總線守護進程, 它使用libdbus庫。其他進程都可以與它連接。它可以將消息從一個進程發給另外任意數量的其他進程。現在有一些基于特定應用框架的dbus庫函數封裝,例如libdbus-glib?libdbus-qt,也有與一些語言綁定的形式,例如Python等。這些封裝的API旨在令D-BUS編程更加簡單,libdbus傾向于提供更低層次的調用。很多libdbus API只在綁定的組件中可用。

  • libdbus僅支持一對一的連接,就像原始?socket通訊方式一樣。但它傳遞的不是以字節為單位的數據流,而是具有一定意義的消息包。消息的消息頭部表示消息種類,消息體用來裝載數據。Libdbus也可以允許實現特定的傳輸通道,從而來完成比如像認證之類的應用細節(libdbus also abstracts the exact transport used (sockets vs. whatever else), and handles details such as authentication.)。

  • 消息總線守護進程將D-bus上連接的所有程序構成一個輪形hubLibdbus為中心,它和應用程序建立一對一的連接。每個應用程序通過通道發送消息到消息總線,然后總線進程將消息轉發到其他連接到hub的應用程序。可以把消息總線理解為一個路由器。Dbus服務在一個操作系統中存在多個進程。第一個進程是一個全局進程,就如sendmail?Apache?的系統守護進程一樣。這個進程具有高度的安全限制,一般用于系統進程間的通訊。其他的dbus進程都是用戶進程,針對于每個登錄的用戶建立。這些實例允許用戶會話中的應用程序相互通信。Dbus全局進程和用戶進程是相互獨立的,他們并沒有內在的依賴關系。

    D-Bus應用

    有很多種IPC或者網絡通信系統,如:CORBADCEDCOMDCOPXML-RPCSOAPMBUSICE等。Dbus的目的主要是下面兩點:

  • 在同一個桌面會話中,進行桌面應用程序之間的通訊。

  • 桌面程序和內核或者守護進程之間通信。

  • D-Bus概念

    對象路徑(Native Objects and Object Paths):D-Bus的底層接口,和libdbus相關,它提供一種叫對象路徑(object path),用于讓高層接口綁定到各個對象中去,允許遠端應用程序指向他們。Object path就像一個文件路徑。

    方法和信號(Methods and Signals):每個對象都有一些成員,有兩種成員:方法(methods)和信號(signals),在對象中,方法可以被調用。信號會被廣播,感興趣的對象可以處理這個信號,同時信號中也可以帶有相關的數據。

    接口(Interfaces):每個對象都有一個或者多個接口,一個接口就是多個方法和信號的集合。這個概念和Glib, Qt或者Java中的是一致的。接口定義了對象實例的類型。dbus使用簡單的命名空間字符串來表示接口,如org.freedesktop.Introspectable。可以說dbus接口相當于C++中的純虛類。

    代理(Proxies):使用代理對象就是讓調用者感覺在直接使用遠程對象一樣。d-bus的底層接口完成了一些比較低級和繁瑣的調用過程,比如必須先調用創建方法形成消息包,然后發送,然后等待接受和處理返回的消息。所以,高層的接口就可以使用代理對象提供的接口屏蔽這些細節。所以,當調用代理對象的方法時,代理內部會轉換成dbus的方法調用,等待消息返回,對返回結果解包,返回給相應的方法。可以看看下面的例子,使用dbus底層接口編寫的代碼:

    Message message = new Message(”/remote/object/path”, “MethodName”, arg1, arg2);
    Connection connection = getBusConnection();
    connection.send(message);
    Message reply = connection.waitForReply(message);
    if (reply.isError()) {

    } else {
    Object returnValue = reply.getReturnValue();
    }

    使用代理對象編寫的代碼:

    Proxy proxy = new Proxy(getBusConnection(), “/remote/object/path”);
    Object returnValue = proxy.MethodName(arg1, arg2);

    客戶端代碼減少很多。

    總線名稱(Bus Names):當一個應用程序連接上bus daemon時,daemon會分配一個唯一的名字給它。以冒號(:)開始,這些名字在daemon的生命周期中是不會改變的,可以認為這些名字就是一個?IP地址。當這個名字映射到應用程序的連接上時,應用程序可以說擁有這個名字。同時應用可以聲明額外的容易理解的名字,比如可以取一個名字?com.mycompany.TextEditor,可以認為這些名字就是一個域名。其他應用程序可以往這個名字發送消息,執行各種方法。

    名字還有第二個重要的用途,可以用于跟蹤應用程序的生命周期。當應用退出(或者崩潰)時,與bus的連接將被OS內核關掉,bus將會發送通知,告訴剩余的應用程序,該程序已經丟失了它的名字。名字還可以檢測應用是否已經啟動,這可以用來實現單實例啟動程序。

    地址(Addresses):使用d-bus的應用程序既可以是server也可以是clientserver監聽到來的連接,client連接到server,一旦連接建立,消息就可以流轉。如果使用dbus daemon,所有的應用程序都是clientdaemon監聽所有的連接,應用程序初始化連接到daemondbus地址指明server將要監聽的地方,client將要連接的地方,例如,地址:unix:path=/tmp/abcdef表明?server將在/tmp/abcdef路徑下監聽unix域的socketclient也將連接到這個socket。一個地址也可以指明是TCP /IPsocket,或者是其他的。

    當使用bus daemon時,libdbus會從環境變量中(DBUS_SESSION_BUS_ADDRESS)自動認識“會話daemon”的地址。如果是系統?daemon,它會檢查指定的socket路徑獲得地址,也可以使用環境變量(DBUS_SESSION_BUS_ADDRESS)進行設定。當dbus中不使用daemon時,需要定義哪一個應用是server,哪一個應用是client,同時要指明server的地址,這不是很通常的做法。

    D-bus工作原理

    Calling a Method – Behind the Scenes
    dbus中調用一個方法包含了兩條消息,進程A向進程B發送方法調用消息,進程B向進程A發送應答消息。所有的消息都由daemon進行分派,每個調用的消息都有一個不同的序列號,返回消息包含這個序列號,以方便調用者匹配調用消息與應答消息。調用消息包含一些參數,應答消息可能包含錯誤標識,或者包含方法的返回數據。

    方法調用的一般流程:

    1.使用不同語言綁定的dbus高層接口,都提供了一些代理對象,調用其他進程里面的遠端對象就像是在本地進程中的調用一樣。應用調用代理上的方法,代理將構造一個方法調用消息給遠端的進程。

    2.DBUS的底層接口中,應用需要自己構造方法調用消息(method call message),而不能使用代理。

    3.方法調用消息里面的內容有:目的進程的bus name,方法的名字,方法的參數,目的進程的對象路徑,以及可選的接口名稱。

    4.方法調用消息是發送到bus daemon中的。

    5.bus daemon查找目標的bus name,如果找到,就把這個方法發送到該進程中,否則,daemon會產生錯誤消息,作為應答消息給發送進程。

    6.目標進程解開消息,在dbus底層接口中,會立即調用方法,然后發送方法的應答消息給daemon。在dbus高層接口中,會先檢測對象路徑,接口,方法名稱,然后把它轉換成對應的對象(如GObjectQT中的QObject等)的方法,然后再將應答結果轉換成應答消息發給daemon

    7.bus daemon接受到應答消息,將把應答消息直接發給發出調用消息的進程。

    8.應答消息中可以包容很多返回值,也可以標識一個錯誤發生,當使用綁定時,應答消息將轉換為代理對象的返回值,或者進入異常。

    bus daemon不對消息重新排序,如果發送了兩條消息到同一個進程,他們將按照發送順序接受到。接受進程并需要按照順序發出應答消息,例如在多線程中處理這些消息,應答消息的發出是沒有順序的。消息都有一個序列號可以與應答消息進行配對。

    Emitting a Signal – Behind the Scenes
    dbus中一個信號包含一條信號消息,一個進程發給多個進程。也就是說,信號是單向的廣播。信號可以包含一些參數,但是作為廣播,它是沒有返回值的。

    信號觸發者是不了解信號接受者的,接受者向daemon注冊感興趣的信號,注冊規則是”match rules”,記錄觸發者名字和信號名字。daemon只向注冊了這個信號的進程發送信號。

    信號的一般流程如下:

  • 當使用dbus底層接口時,信號需要應用自己創建和發送到daemon,使用dbus高層接口時,可以使用相關對象進行發送,如Glib里面提供的信號觸發機制。

  • 信號包含的內容有:信號的接口名稱,信號名稱,發送進程的bus name,以及其他參數。

  • 任何進程都可以依據”match rules”注冊相關的信號,daemon有一張注冊的列表。

  • daemon檢測信號,決定哪些進程對這個信號感興趣,然后把信號發送給這些進程

  • 每個進程收到信號后,如果是使用了dbus高層接口,可以選擇觸發代理對象上的信號。如果是dbus底層接口,需要檢查發送者名稱和信號名稱,然后決定怎么做。

  • 2.3Bluez的安全接口

    pin_helper concept has been removed starting with bluez-utils 3.X. and has been replaced with a feature called passkey agents. An application that wants to handle passkey requests must use the "hcid" security interface to register a passkey agent. Currently, two types of passkey agents are supported: default and device specific. A "specific" passkey agent handles all passkey requests for a given remote device while a default handles all requests for which a specific agent was not found. "specific" passkey agents are useful to address pre-defined passkey values or environments where the user interaction is not allowed/difficult.

    When the?CreateBonding?method is called the "hcid" daemon will verify if there is a link key stored in the file system. If it is available an error is returned, and if not, a D-Bus message is sent to the registered passkey agent asking for a passkey.

    Each Passkey Agent is represented by a D-Bus object path. The "hcid" distinguishes the agents based on their unique bus names and their object paths.

    Pin_help的理念在bluez-util 3.x時已經被移除,并被密鑰代理所代替。任何想處理密鑰請求的應用程序必須使用hcid安全接口來注冊密鑰代理。現在支持兩種類型的密鑰代理:默認和設備特定。一個"特定"的密鑰代理處理所有遠端的密鑰請求,一個默認的密鑰代理,處理特定的代理所沒有發現的所有密鑰請求。"特定"的密鑰代理對處理那些和用戶交互困難或者不允許用戶交互的設備的預定義的密鑰值或環境非常有用。

    CreateBonding方法被調用時,hcid守護進程將確認當前的文件系統中是否保存了鏈接密鑰,若可以找到,就返回一個錯誤。若找不到,D-Bus消息將被發出來為密鑰請求的設備,注冊一個密鑰代理。每個密鑰代理被D-Bus對象路徑所體現,hcid依據唯一的總線名稱和對象路徑來區分代理。

    Architecture

    • Step 1: Represents the passkey agent registration

    • Step 2: Represents a client calling?CreateBonding

    • Step 3: Represents the hcid asking for a passkey valu

    體系結構

    • 第一步:表示密鑰代理注冊

    • 第二步:表示客戶調用CreateBonding

    • 第三步:代表hcid請求密鑰值。


    Message Flow

    In the following figure, the "CreateBonding" method call is hidden. The "PIN Request" HCI event is generated when there is not a link available in the file system. In this case "Link Key Request Negative Reply" command is sent triggering the "Pin Request" event.

    在下面得圖表中,CreateBonding方法的調用被隱藏。當沒有一個可用鏈接時,"PIN Request"HCI層事件被產生,在這種情況下,"Link Key Request Negative Reply"命令被發送來回應"Pin Request"?事件。

    • Step 1: Represents the D-Bus message sent to register the default/device specific passkey agent.

    • Step 2: Represents the HCI "PIN Request" event sent by the Bluetooth Host Controller.

    • Step 3: Represents the D-Bus message sent to the default/device speficic passkey agent requesting a passkey.

    • Step 4: Represents the "Auth Complete" event where the status contains "LMP Response Timeout"(The remote didn't type the passkey).

    • Step 5: Represents the "hcid" issuing a "Cancel" to a previous Request call.

    • Step 6: Represents the D-Bus message sent to release the passkey agent: basically sent when the hcid exits.

    • 第一步:D-Bus發送消息來注冊默認的或者特定的密鑰代理。

    • 第二步:藍牙主機控制器發送HCI?"PIN Request"事件。

    • 第三步:D-Bus發送消息到默認的或者特定的密鑰代理,請求密鑰。

    • 第四步:"Auth Complete"完成事件,如果這種狀態包含"LMP Response Timeout"

    • 第五步:hcid發出“Cancel”命令給D-Bus

    • 第六步:當hcid退出時,D - Bus的信息發送到釋放密鑰代理


    2.4Bluez適配器接口

    Description?

    The "Adapter" interface provides methods to setup the local adapter(s), search remote devices, pairing and search for services.

    This interface is considered stable and no change is planned.

    For each available adapter the hcid register an adapter object instance provided in the path "/org/bluez/hci{0, 1, 2, ...}".

    適配器接口提供,啟動適配器、搜索設別、配對、和搜索服務的方法。這個接口被認為是穩定的,沒有改變計劃。對每個可用的適配器,hcid為其注冊一個適配器對象實例,在路徑?"/org/bluez/hci{0, 1, 2, ...}"里。

    2.5Bluez配對

    Description

    Services that need ask the user to accept/reject an operation such as accept OBEX objects or accept an incoming connection can use the?Security?API to request the userspace registered authorization agent responsible.

    Development warnings/recommendations

  • Just one Authorization request per time is allowed.

  • NotConnected error is returned if a connection is not found between the devices is not found.

  • Trusted Devices

    The BlueZ daemon keeps a list of trusted devices. Trusted means that authorization is not required to accept incoming connections or other operations that need the user response. Once a given device is added to the list, the BlueZ daemon will reply authorized without call the Authorization agent.

    Authorization Agent

    Authorization agents are applications responsible for address authorization requests. For more information check the BlueZ D-Bus API and implementation references:

    • utils/daemon/auth-agent.c is a authorization agent implementation able to handle device specific and default

    • bluez-gnome?passkey/authorization agent implementation distributed by the BlueZ community

    Canceling

    For security reason, only the requestor can cancel a pending authorization operation.

    2.6Bluez綁定

    Description

    The purpose of bonding is to create a relation between two Bluetooth devices based on a common link key (a bond). The link key is created and exchanged(pairing) during the bonding procedure and is expected to be stored by both Bluetooth devices, to be used for future authentication[definition from Bluetooth Core Spec].

    The Bonding procedure is done through the BlueZ?Adapter?interface.

    Development warnings/recommendations

  • Just one Bonding request per time is allowed.

  • Bonding is not allowed if there is a discovery running.

  • Pending remote name is canceled if a CreateBonding message is received.

  • The Bonding takes some seconds, therefore it is recommended set a D-Bus callback to handle the message reply for this operation.

  • Passkey Agent

    Currently, two types of passkey agents are supported:

  • Device Specific: handles all passkey requests for a given remote device

  • Default: Handles the remaining requests(not addressed by device specific agents)

  • For more information check the BlueZ D-Bus API and implementation references:

    • utils/daemon/passkey-agent.c is a passkey agent implementation able to handle device specific and default

    • bluez-gnome?passkey agent implementation distributed by the BlueZ community=

    3Bluez編程實現

    3.1、藍牙開發關鍵技術剖析

    3.1.1、連接機制分析

    物理信道(physical channel)是藍牙系統的最底層結構,通過偽隨機跳頻序列、發送時槽定時、接入碼及幀頭編碼來表征。藍牙針對不同應用定義了一系列物理信道,包括用于匹克網內設通信的匹克網物理信道、用于尋呼設備的尋呼掃描物理信道和用于查找設備的查找掃描物理信道。兩臺設備必須采用相同的物理信道才能進行通信。

    主從設備建立連接的過程就是建立相同匹克網信道的過程,該過程確保主從設備以同樣的定時和次序進行載波頻率的跳變,進行數據傳輸,同時可以根據匹克網接入碼和幀頭編碼進行數據過濾和解析,避免和其他設備在同一個頻段上的相撞。

    尋呼掃描物理信道(page scan physical channel)用于主設備尋呼從設備,是設備建立連接的必經階段。尋呼掃描跳頻序列和尋呼請求幀的設備接入碼(DAC)是由從設備物理地址運算,處于可被連接模式的從設備以固定的周期(page scan interval決定)在一個固定的時間窗(page scan window決定)內以某個跳頻頻率監聽主設備的尋呼請求。

    3.1.2、自動連接

    為了方便用戶的使用,大多藍牙設備都實現了自動連接功能,根據以上對藍牙連接機制的分析,設計自動連接方案時必須考慮設備在不同的工作狀態下采用不同的物理信道和跳頻序列,而不能按照人為的邏輯隨意設置,否則會給用戶帶來不便。

    以車載免提裝置為例,上電自動連接對駕駛員來說可以提高使用車載免提的自覺性,降低行車期間通話帶來的風險。采用搜索方式判斷設備是否在有效范圍內,按照優先級從低到高連接,最后一次連接的手機為優先級最高的,然后按照配對列表的逆序而優先級依次降低。鏈路丟失后的自動連接只針對最后一部手機,這樣可以實現服務的連續性。

    3.1.3、時鐘設計

    藍牙核心規范要求時鐘頻率精度為±20ppm,如果載波頻率不穩定,則會發生“過零點”錯誤(zero-cross)。載波頻率由本地時鐘(晶振)做為PLL的參考時鐘倍頻產生。一般說來,藍牙設備的時鐘設計便是指晶振電路的設計及微調。決定晶振工作精度的兩個重要參數是制造公差和溫度穩定度,如果選擇有源晶振作為本地時鐘,需要滿足:制造公差+溫度穩定度≤±20ppm,有源晶振內部集成晶體和相應的振蕩電路,匹配精確,頻率穩定性高,而且抗干擾性能好,缺點是成本較高。§
    1?????震蕩電路設計

    本文自行設計的振蕩電路如圖1所示。

    選擇溫度穩定性高、制造公差低的高精度晶體,通過振蕩電路設計實現諧振頻率的精確調整,這是由晶體負載電容的匹配及可調實現的。負載電容是指CRY_INCRY_OUT兩端的電容值,在晶體的CRY_IN引腳上并聯一個可調電容,調整該電容便可以對諧振頻率進行精密微調。晶體負載電容計算公式如下:
    Cload=Cint+(Cin+Ctrim)×Cout/(Cin+Ctrim+Cout)

    Cint包括IC內部電容(一般為固定值)以及PCB雜散電容(3pF~5pF)

    3.1.4、配對列表管理

    為了保證鏈路級的安全,藍牙通信要求設備在連接建立前進行“雙向認證”。認證成功的前提是設備雙方存儲了相同的鏈路密鑰Kab,配對是產生初始密鑰Kint的階段,KintPIN碼、從設備藍牙地址和主設備發給從設備的一個隨機數由一套固定的算法計算出來,只要PIN碼一致,主從設備生成的的Kint也是一致的。鏈路密鑰的輸入是主從設備的藍牙地址和主從設備各一隨機數,只要主從設備能互換隨機數,便能得到一致的Kab。主設備將隨機數RandAKint異或的結果發給從設備,從設備只將該結果與Kint異或便得到RandA,即
    §

    配對列表的管理包括添加、替代及刪除,添加配對設備是在非易失性存儲中存儲該設備的藍牙地址及Kab。刪除配對設備需要謹慎處理,如果存在連接,需要先斷開連接然后刪除,因為如果刪掉該設備而有一種應用的連接沒有斷開,會存在臨時密鑰用于當前應用,這時不經配對也可以連接上其他應用,違反了藍牙安全性要求

    3.1.5、藍牙文件傳輸模式

    文件傳輸的目的是使兩個終端之間的數據交換成為可能,傳輸時使用的協議如圖3.1所示,可傳送的文件有docjpgpptxlswav等文件,還包括遠端文件夾瀏覽功能。傳輸文件的設備可歸結成C/S結構。客戶可從服務器下載文件,或向服務器上傳文件。服務器是一種使用對象交換協議(OBEX)文件夾列表格式的遠端藍牙設備,其支持目標交換服務、文件夾瀏覽功能,還允許客戶修改、創建文件或文件夾。

    3.2hci層介紹

    3.2.1hci層介紹

    Host Controller Interface(HCI)?就是用來溝通HostModuleHost通常就是PC,?Module則是以各種物理連接形式(USB,serial,pc-card等)連接到PC上的bluetooth DongleHCI則比較特殊,它一部分在軟件中實現,用來給上層協議和程序提供訪問接口(Bluez,hci.c hci_usb.chci_sock.c等).另一部分也是在Firmware中實現,用來將軟件部分的指令等用底層協議明白的方式傳遞給底層。

    居于PC的上層程序與協議和居于Modules的下層協議之間通過HCI溝通,有4種不同形式的傳輸:Commands, Event, ACL Data, SCO/eSCO Data.

    HCI CommandHCI CommandHostModules發送命令的一種方式。

    HCI EventModulesHost發送一些信息,使用HCI Event

    3.2.2hci層編程

    對本地dongle進行操作:

  • 得到Host上插入Dongle數目以及Dongle信息

  • 實現步驟如下:

    // 0.?分配一個空間給?hci_dev_list_req。這里面將放所有Dongle信息。

    struct hci_dev_list_req *dl;

    struct hci_dev_req *dr;

    struct hci_dev_info di;

    int i;

    if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) {

    perror("Can't allocate memory");

    exit(1);

    }

    dl->dev_num = HCI_MAX_DEV;

    dr = dl->dev_req;

    //1.?打開一個HCI socket.

    if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {

    perror("Can't open HCI socket.");

    exit(1);

    }

    // 2.?使用HCIGETDEVLIST,得到所有dongleDevice ID。存放在dl中。

    if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) {

    perror("Can't get device list");

    exit(1);

    }

    // 3?使用HCIGETDEVINFO,得到對應Device IDDongle信息。

    di.dev_id = (dr+i)->dev_id;

    ioctl(ctl, HCIGETDEVINFO, (void *) &di)

    這樣就能得到所有Dongle信息。

    ?

    struct hci_dev_info {

    uint16_t dev_id; //dongle Device ID

    char name[8]; //Dongle name

    ?

    bdaddr_t bdaddr; //Dongle bdaddr

    ?

    uint32_t flags; //Dongle Flags:如:UPRUNINGDown等。

    uint8_t type; //Dongle連接方式:如USBPC CardUARTRS232等。

    ?

    uint8_t features[8];

    ?

    uint32_t pkt_type;

    uint32_t link_policy;

    uint32_t link_mode;

    ?

    uint16_t acl_mtu;

    uint16_t acl_pkts;

    uint16_t sco_mtu;

    uint16_t sco_pkts;

    ?

    struct hci_dev_stats stat; //Dongle的數據信息,如發送多少個ACL Packet,正確多少,錯誤多少,等等。

    };

  • 打開一個HCI Socket---int hci_open_dev(int dev_id)

  • 這個function用來打開一個HCI Socket。它首先打開一個HCI protocolSocket(房間),并將此Socketdevice ID=參數dev_idDongle綁定起來。只有bind后,它才將Socket句柄與Dongle對應起來

    注意,所有的HCI Command發送之前,都需要使用?hci_open_dev打開并綁定

  • 關閉一個HCI Socket

  • int hci_close_dev(int dd) //簡單的關閉使用hci_open_dev打開的Socket

  • HCI Socket(對應一個Dongle)發送?request

  • int hci_send_req(int dd, struct hci_request *r, int to)

    BlueZ提供這個function非常有用,它可以實現一切HostModules發送Command的功能。

    參數1HCI Socket

    參數2Command內容。

    參數3:以milliseconds為單位的timeout.

    下面詳細解釋此function和用法:

    當應用程序需要向Dongle(對應為一個bind后的Socket)發送Command時,調用此function.

    其中,參數一dd對應一個使用hci_open_dev()打開的SocketDongle)。

    參數三to則為等待Dongle執行并回復命令結果的timeout.以毫秒為單位。

    參數二hci_request * r?最為重要,首先看它的結構:

    struct hci_request {

    uint16_t ogf; //Opcode Group

    uint16_t ocf; //Opcode Command

    int event; //Command產生的Event類型。

    void *cparam; //Command?參數

    int clen; //Command參數長度

    void *rparam; //Response?參數

    int rlen; //Response?參數長度

    };

    ogf,ocf不用多說,對應前面的圖就明白這是Group CodeCommand Code。這兩項先確定下來,然后可以查HCI Spec。察看輸入參數(cparam)以及輸出參數(rparam)含義。至于他們的結構以及參數長度,則在~/include/net/bluetooth/hci.h中有定義。

    ?

    1:得到某個連接的Policy Setting.

    HCI Spec以及~/include/net/bluetooth/hci.h中均可看到,OGF=OGF_LINK_POLICY(0x02). OCF=OCF_READ_LINK_POLICY(0x0C).

    因為這個Command用來讀取某個ACL連接的Policy Setting。所以輸入參數即為此連接Handle.

    返回參數則包含3部分,statusCommand是否順利執行),?handle(連接Handle)。?policy(得到的policy值)

    這就又引入了一個新問題,如何得到某個ACL連接的Handle

    可以使用ioctl HCIGETCONNINFO得到ACL?連接Handle

    ioctl(dd, HCIGETCONNINFO, (unsigned long) cr)

    Connect_handle = htobs(cr->conn_info->handle);

    所以完整的過程如下:

    ?

    struct hci_request HCI_Request;

    read_link_policy_cp Command_Param;

    read_link_policy_rp Response_Param;

    // 1.得到ACL Connect Handle

    if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0)

    {

    return -1

    }

    Connect_handle = htobs(cr->conn_info->handle);

    memset(&HCI_Request, 0, sizeof(HCI_Request));

    memset(&Command_Param, 0 , sizeof(Command_Param));

    memset(&Response_Param, 0 , sizeof(Response_Param));

    // 2.填寫Command輸入參數

    Command_Param.handle = Connect_handle;

    HCI_Request.ogf = OGF_LINK_POLICY; //CommandID

    HCI_Request.ocf = OCF_READ_LINK_POLICY; //Command ID

    HCI_Request.cparam = &Command_Param;

    HCI_Request.clen = READ_LINK_POLICY_CP_SIZE;

    HCI_Request.rparam = &Response_Param;

    HCI_Request.rlen = READ_LINK_POLICY_RP_SIZE;

    if (hci_send_req(dd, &HCI_Request, to) < 0)

    {

    perror("\nhci_send_req()");

    return -1;

    }

    //如果返回值狀態不對

    if (Response_Param.status) {

    return -1;

    }

    //得到當前policy

    *policy = Response_Param.policy;

  • 幾個更基礎的function

  • static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src) //bdaddr copy

    static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2)//bdaddr?比較

  • 得到指定Dongle BDAddr

  • int hci_read_bd_addr(int dd, bdaddr_t *bdaddr, int to)

    參數1HCI Socket,使用hci_open_dev()打開的SocketDongle)。

    參數2:輸出參數,其中會放置bdaddr.

    參數3:以milliseconds為單位的timeout.

  • 讀寫Dongle Name

  • int hci_read_local_name(int dd, int len, char *name, int to)

    int hci_write_local_name(int dd, const char *name, int to)

    參數1HCI Socket,使用hci_open_dev()打開的SocketDongle)。

    參數2:讀取或設置Name

    參數3:以milliseconds為單位的timeout.

    注意:這里的NameIOCTL HCIGETDEVINFO?得到hci_dev_info中的name不同

  • 得到HCI Version

  • int hci_read_local_version(int dd, struct hci_version *ver, int to)

  • 得到已經UPDongle BDaddr

  • int hci_devba(int dev_id, bdaddr_t *bdaddr)

    dev_id: Dongle Device ID.

    bdaddr:輸出參數,指定Dongle如果UP, 則放置其BDAddr

  • 得到BDADDR不等于參數bdaddrDongle Device ID

  • int hci_get_route(bdaddr_t *bdaddr)

    ?

    查找Dongle,發現Dongle Bdaddr不等于參數bdaddr的第一個Dongle,則返回此Dongle Device ID

    ?

    所以,如果: int hci_get_route(NULL),則得到第一個可用的Dongle Device ID

  • BDADDR轉換為字符串

  • int ba2str(const bdaddr_t *ba, char *str)

    對遠程dongle進行操作:

  • inquiry?遠程Bluetooth Device

  • int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info **ii, long flags)

    hci_inquiry()用來命令指定的Dongle去搜索周圍所有bluetooth device.并將搜索到的Bluetooth Device bdaddr?傳遞回來。

    參數1dev_id:指定Dongle Device ID。如果此值小于0,則會使用第一個可用的Dongle

    參數2len:?此次inquiry的時間長度(每增加1,則增加1.25秒時間)

    參數3nrsp:此次搜索最大搜索數量,如果給0。則此值會取255

    參數4lap:BDADDRLAP部分,Inquiry時這塊值缺省為0X9E8B33.通常使用NULL。則自動設置。

    參數5ii:存放搜索到Bluetooth Device的地方。給一個存放inquiry_info指針的地址,它會自動分配空間。并把那個空間頭地址放到其中。

    參數6flags:搜索flags.使用IREQ_CACHE_FLUSH,則會真正重新inquiry。否則可能會傳回上次的結果。

    返回值是這次Inquiry到的Bluetooth Device?數目。

    注意:如果*ii不是自己分配的,而是讓hci_inquiry()自己分配的,則需要調用bt_free()來幫它釋放空間。

  • 得到指定BDAddrreomte device Name

  • int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to)

    參數1:使用hci_open_dev()打開的Socket

    參數2:對方BDAddr.

    參數3name?長度。

    參數4(out)放置name的位置。

    參數5:等待時間。

  • 讀取連接的信號強度

  • int hci_read_rssi(int dd, uint16_t handle, int8_t *rssi, int to)

    注意,所有對連接的操作,都會有一個參數,handle.這個參數是連接的Handle?前面講過如何得到連接Handle的。

    3.3L2CAP層編程

    3.3.1L2CAP協議簡介

    Logical Link Control and Adaptation Protocol(L2CAP)邏輯連接控制和適配協議為上層協議提供面向連接和無連接的數據服務,并提供多協議功能和分割重組操作。L2CAP?充許上層協議和應用軟件傳輸和接收最大長度為?64K?L2CAP?數據包。

    L2CAP?基于通道(channel)?的概念。 通道?(Channel)?是位于基帶?(baseband)?連接之上的邏輯連接。每個通道以多對一的方式綁定一個單一協議?(single protocol)。多個通道可以綁定同一個協議,但一個通道不可以綁定多個協議。 每個在通道里接收到的?L2CAP?數據包被傳到相應的上層協議。 多個通道可共享同一個基帶連接。也就是說,所有L2CAP數據均通過HCI傳輸到Remote Device。且上層協議的數據,大都也通過L2CAP來傳送。L2CAP可以發送Command。例如連接,斷連等等。

    3.3.2L2CAP編程方法

    L2CAP編程非常重要,它和HCI基本就是Linux Bluetooth編程的基礎了。幾乎所有協議的連接,斷連,讀寫都是用L2CAP連接來做的。

    1.創建L2CAP Socket

    socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP);

    domain=PF_BLUETOOTH, type可以是多種類型。protocol=BTPROTO_L2CAP.

    2.綁定:

    // Bind to local address

    memset(&addr, 0, sizeof(addr));

    addr.l2_family = AF_BLUETOOTH;

    bacpy(&addr.l2_bdaddr, &bdaddr); //bdaddr為本地Dongle BDAddr

    if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {

    perror("Can't bind socket");

    goto error;

    }

    3.連接

    ?

    memset(&addr, 0, sizeof(addr));

    addr.l2_family = AF_BLUETOOTH;

    bacpy(addr.l2_bdaddr, src);

    addr.l2_psm = xxx;

    if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {

    perror("Can't connect");

    goto error;

    }

    ?

    注意:

    struct sockaddr_l2 {

    sa_family_t l2_family; //必須為?AF_BLUETOOTH

    unsigned short l2_psm; //與前面PSM對應,這一項很重要

    bdaddr_t l2_bdaddr; //Remote Device BDADDR

    unsigned short l2_cid;

    };

    4.?發送數據到Remote Device

    send()write()都可以。

    5.?接收數據:

    revc()?read()

    以下為實例:

    注:在Bluetooth下,主動去連接的一端作為主機端。被動等別人連接的作為Client端。

    背景知識1Bluetooth設備的狀態

    之前HCI編程時,是用?ioctl(HCIGETDEVINFO)得到某個Device Infohci_dev_info).其中flags當時解釋的很簡單。其實它存放著Bluetooth Device(例如:USB Bluetooth Dongle)的當前狀態:

    其中,UP,Down狀態表示此Device是否啟動起來。可以使用ioctl(HCIDEVUP)等修改這些狀態。

    另外:就是Inquiry Scan, PAGE Scan這些狀態:Inquiry Scan狀態表示設備可被inquiry. Page Scan狀態表示設備可被連接。

    參考:L2CAP編程,http://blog.csdn.net/baozhongchao/archive/2009/10/26/4728751.aspx

    3.4SDP協議簡介

    Service Discovery Protocol(SDP)提供一種能力,讓應用程序有方法發現哪種服務可用以及這種服務的特性。服務發現協議(SDPBluetooth SDP)在藍牙協議棧中對藍牙環境中的應用程序有特殊的含意,發現哪個服務是可用的和確定這些可用服務的特征。SDP定義了bluetooth client發現可用bluetooth server服務和它們的特征的方法。這個協議定義了客戶如何能夠尋找基于特定屬性的服務而不讓客戶知道可用服務的任何知識。SDP提供發現新服務的方法,在當客戶登錄到正在操作的藍牙服務器的一個區域時是可用的時。

    Service discovery機制提供client應用程序偵測server應用程序提供的服務的能力,并且能夠得到服務的特性。服務的品質包含服務type或服務classSDP也提供SDP serverSDP client之間的通訊。SDP server維護著一個服務條目(service record)列表.每個服務條目描述一個單獨的服務屬性。?SDP client可以通過發送SDP request來得到服務條目。如果一個client或者依附于client之上的應用程序決定使用某個service.?它創建一個單獨的連接到service提供者。?SDP?只提供偵測Service的機制,但不提供如何利用這些Service的機制。這里其實是說:SDP只提供偵測Service的辦法,但如何用,SDP不管。每個Bluetooth Device最多只能擁有一個SDP Server。如果一個Bluetooth Device只擔任Client,那它不需要SDP Server。但一個Bluetooth Device可以同時擔當SDP ServerSDP client.

    Service Record(Service?條目)

    一個service是一個實體為另一個實體提供信息,執行動作或控制資源。一個service可以由軟件,硬件或軟硬件結合提供。所有的Service信息都包含于一個Service Record內。一個Service Record?包含一個Service attribute(Service屬性) list在一個SDP Server內,每個Service Record擁有一個32-bit的唯一性數據。通常,這個唯一性只是在每個SDP Server內部。 如果SDP Server S1?SDP Server S2擁有同樣的一個Service Record。那他們在不同SDP Sever內的獨特數值并不一定相同。SDPSDP Server增加或減少Service Record時,并不會通知SDP client.

    Service Attribute(Service?屬性)

    每個Service屬性描述servcie的特性.一個Service Attribute2部分:

    Attribute ID + Attribute Value

    Attribute ID16-bit無符號整數,用于區別一個Service Record內的其它屬性。

    Attribute ValueAttribute值。

    Service Class

    每個Service?都是某個Service Class的實例. Service Class定義了Service Record中包含的Service?屬性。屬性ID,屬性值都被定義好了。每個Service Class也有一個獨特ID。這個Service Class標識符包含在屬性值ServiceClassIDList屬性中。并描繪為UUID。自從Service Record中的屬性格式以及含義依賴于Service Class后,ServiceClassIDList屬性變得非常重要。

    Searching For Service:

    Service Search transaction(事務?)允許client得到Service Record Handle。一旦SDP Client得到Service Record Handle,它就可以請求這個Record內具體屬性的值。

    如果某個屬性值UUID,則可以通過查找UUID查到這個屬性。

    UUID:?universally unique identifier.(唯一性標識符)

    SDP協議棧使用request/response模式工作,每個傳輸過程包括一個request protocol data unit(PDU)和一個response PDU. SDP使用L2CAP連接傳輸數據。在發送Request PDU但未收到Response PDU之前,不能向同一個server再發送Request PDU

    PDUprotocol Data unit

    PDU ID:用來識別PDU

    TransactionID:

    用來識別Request PUD以及Response PUD。并用來對比某個Response PUD是否對應著Request PUD

    4Openobex

    4.1Openobex簡介

    Welcome to the Open OBEX project. The overall goal of this project is to make an open source implementation of the Object Exchange (OBEX) protocol. OBEX is a session protocol and can best be described as a binary HTTP protocol. OBEX is optimised for ad-hoc wireless links and can be used to exchange all kind of objects like files, pictures, calendar entries (vCal) and business cards (vCard).

    OBEX was specified by the IrDA? (Infrared Data Association), and although the protocol is very good for Infrared connections, it is not limited to it. In fact OBEX does not specify the top or bottom API making it very flexible and can run over most transports like TCP/IP and Bluetooth. Therefore OBEX is also called IrOBEX when used over the Infrared medium. There are some transport modules for serial links (cable OBEX) too.

    Today, OBEX is builtin in many devices e.g. PDA's like the?Palm§?Pilot, and mobile phones like theSony Ericsson§?R320, R520, T68, T610, T630, K700 and many later phones,?Siemens§?S25, S35, S45, S55, S65?Nokia§?NM207 and Nokia 9110 Communicator. The HP?Scanner?§?CapShare 920 can also talk OBEX in addition to JetSend.?Microsoft§?Windows2000 has also builtin OBEX support.

    Link types currently supported by OpenOBEX are:

    INFRARED DATA ASSOCIATION ? (IrDA)?http://www.irda.org§

    USB-IF, Inc.?http://www.usb.org§

    Bluetooth(TM)?http://www.bluetooth.com§

    Support for TCP/IP links, file descriptors and custom transports is also provided.

    OBEX全稱為Object Exchange,中文對象交換,所以稱之為對象交換協議。它在此軟件當中有著核心地位,文件傳輸和IrMC同步都會使用到它。OBEX協議構建在IrDA架構的上層. OBEX協議通過簡單的使用“PUT”和“GET”命令實現在不同的設備、不同的平臺之間方便、高效的交換信息。支持的設備廣泛,例如PCPDA,電話,攝像頭,自動答錄機,計算器,數據采集器,手表等等。OBEX協議定義了一種柔性的概念——objects。也即是對象。這些對象可以包括文件,診斷信息,電子商務卡片,銀行的存款等等。Objects在這里沒有高級的技術含義,而是視你的應用而定。OBEX協議小到可作“命令和控制”功能,例如對電視機,錄像機等的操作。大道可以做很復雜的操作,例如數據庫的事務處理和同步。

    OBEX能夠具有以下幾個特點:

    1、??友好的應用——可實現快速開發。

    2、??緊縮——可用在資源有限的小型設備上。

    3、??跨平臺

    4、??柔性的數據支持。

    5、??方便的作為其他Internet傳輸協議的上層協議。

    6、??可擴展性——提供了對未來需求的擴充支持而不影響以存在的實現。例如可擴展安全,數據壓縮等。

    7、? 可測試可調試。

    4.2Openobexbluez編程實現

    如下表:基于OBEXBlueZ的數據傳輸的步驟

    步驟

    函數

    意義

    1

    OBEX_Init()

    用于初始化一個obex instance handle

    arg1:OBEX_TRANS_BLUETOOTH用于聲明傳輸協議為bluetooth

    arg2:callback function

    arg3:flag=OBEX_FL_KEEPSERVER,接收到請求后,服務器可以繼續接收其他客戶端的請求;

    2

    OBEX_SetUserData()

    設置用戶自己的變量,該函數的使用完全取決于用戶自己;

    3

    BtOBEX_ServerRegister()

    一個專用于藍牙協議的服務端函數,用于監聽客戶端發送的請求。該函數內部創建了一個?socket(調用socket(AF_BLUETOOTH,SOCK_STREAM,BTPROTO_RFCOMM)),bindsocket到本地藍牙地址,將該socket轉化為監聽sockt,之后該socket才能夠監聽端口上來自客戶端的連接請求;

    4

    OBEX_HandleInput()

    函數用于讀取并處理接收到的數據,如果沒有數據到達,該函數將會阻塞;該函數內部調用了selet()函數,向系統登記了參數handle的客戶端sockt與服務端sockt,讓系

    ?

    統監聽socket上的事件,如果是服務端socket上有數據到達,則調用accept()函數為客戶端創建一個新的sockt,如果OBEX_Init()flag不是設置為OBEX_FL_KEEPSERVER,則關掉服務端socket,禁止其他客戶端的連接請求;

    5

    CALLBACK?

    (OBEX_EV_ACCEPTHINT)

    ?

    6

    OBEX_ServerAccept()

    該函數返回上述客戶端的socket

    函數內部重新創建了一個obex instance handle,并將上述服務器handle的參數復制到該handle,獲得服務器handlefdaccept為客戶端創建的socket)后,清除服務器本身的fd

    該函數同時也為新創建的obex instance handle設置callback functionUserdata;至此,已經為客戶端創建了一個與服務端完全獨立的obex instance handle,此后該服務端的操作都由該handle標識,而服務器的socket則繼續監聽其他客戶端的連接請求。

    7

    CALLBACK?

    OBEX_EV_REQDONE

    OBEX_CMD_CONNECT

    8

    CALLBACK?

    OBEX_EV_REQHINT

    一個請求即將到來。

    調用OBEX_ObjectSetRsp(object,OBEX_RSP_CONTINUE,OBEX_RSP_SUCCESS)設置響應操作碼

    9

    CALLBACK?

    OBEX_EV_REQCHECK

    第一個接收到的請求包已經被解析

    10

    CALLBACK?

    OBEX_EV_PROGRESS

    收到n個此事件,說明客戶端正在傳輸文件內容

    11

    CALLBACK?

    OBEX_EV_REQ

    OBEX_CMD_PUT

    OBEX_ObjectSetRsp(object,OBEX_RSP_CONTINUE,OBEX_RSP_SUCCESS)設置響應操作碼;此時,客戶端文件傳輸完畢,需進行處理:

    OBEX_ObjectGetNextHeader()分別取得文件的名稱與內容;

    12

    CALLBACK?

    OBEX_EV_REQDONE

    OBEX_CMD_PUT

    13

    CALLBACK?

    OBEX_EV_REQHINT

    一個請求即將到來

    14

    CALLBACK?

    OBEX_EV_REQ

    OBEX_CMD_DISCONNECT

    OBEX_ObjectSetRsp(object,OBEX_RSP_SUCCESS,OBEX_RSP_SUCCESS)設置響應操作碼

    15

    CALLBACK?

    OBEX_EV_REQDONE

    OBEX_CMD_DISCONNECT;

    OBEX_TransportDisconnect(handle)斷開連接;

    注意:該函數只是將socket關閉,并沒有釋放handle所占用的資源,所以在應用時需要釋放handle占用的資源;

    16

    OBEX_Cleanup()

    關掉obex handle并釋放該handle占用的資源。

    (該函數同樣關閉了客戶端及服務端socket

    ?

    如下表:OpenOBEX的代碼說明:

    ?

    文件編號

    文件名

    作用

    1

    obex_connect.c/.h

    處理CONNECT PDU,打包和解包

    2

    obex_header.c/.h

    PDU處理的公共函數及數據類型定義

    3

    obex_object.c/.h

    對象處理函數,客戶端和服務器公用代碼

    4

    obex_server.c/.h

    服務器端處理代碼

    5

    obex_client.c/.h

    客戶端處理代碼

    6

    obex_transport.c/.h

    傳輸接口的抽象

    7

    irobex.c/.h

    基于紅外的傳輸方式

    8

    usbobex.c/.h

    基于USB的傳輸方式

    9

    inobex.c/.h

    基于TCP/IP的傳輸方式

    10

    btobex.c/.h

    基于藍牙的傳輸方式

    ?

    Obexftp

    5.1obexftp簡介

    The main goal of this project is to make mobile devices that feature the OBEX protocol and that adhere to the OBEX FTP standard accessible using an open source implementation.

    ObexFTP is a library bundling everything needed for OBEX transfers and exposing it via a simple interface. Quite a number of language bindings are provided using SWIG or other means. There is a sample command line client "obexftp" and a server "obexftpd" included. Besides FTP the ObexFTP library provides access to the PUSH, GOEP and SYNCH services. It runs on Linux, FreeBSD, NetBSD and Win32.

    5.2、基于Obexftp的應用程序開發

    參考代碼

    6、參考資料

    D-bus官網,http://dbus.freedesktop.org/doc/dbus-tutorial.html§

    D-bus中文介紹http://blog.sina.com.cn/s/blog_5412ede60100eml7.html§

    Bluetooth官網www.bluetooth.com§

    Openobex官網,http://dev.zuckschwerdt.org/openobex/wiki/ObexIntroduction§

    Openobex APIhttp://dev.zuckschwerdt.org/openobex/doxygen/

    轉載于:https://my.oschina.net/u/994235/blog/113213

    總結

    以上是生活随笔為你收集整理的Linux下Bluez的编程实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    婷婷国产精品 | 国产福利在线不卡 | 色资源网在线观看 | v片在线看 | 免费色视频网址 | 99精品国产免费久久久久久下载 | 免费观看性生交 | 欧美成人黄 | 免费观看的黄色 | 日韩小视频 | 日本在线精品视频 | 天天干天天插 | 91桃色在线观看视频 | 欧美另类高清 | 婷婷色5月 | 国产午夜三级一区二区三桃花影视 | 亚洲精品动漫成人3d无尽在线 | 欧美一级电影免费观看 | 久久国产精品免费视频 | av在线播放亚洲 | 日韩精品专区 | 中文字幕一区三区 | 看片网站黄 | 日韩成人在线免费观看 | 91视频啪| 免费碰碰 | 久久久亚洲影院 | 一本一道久久a久久精品 | 99精品免费在线 | 午夜在线观看一区 | 成人久久国产 | 亚洲国产成人精品在线观看 | 欧美日韩天堂 | 国产 日韩 欧美 中文 在线播放 | 在线国产中文 | 粉嫩av一区二区三区免费 | 欧美日韩一区二区在线观看 | 国产一区黄色 | 久久精精品 | 精品免费国产一区二区三区四区 | 亚洲最大av网站 | 天天天天天天天操 | 色美女在线 | 69视频网站 | 免费在线播放 | 婷婷开心久久网 | 欧亚日韩精品一区二区在线 | 亚洲国产中文字幕在线 | 91久久精品一区二区三区 | 久久九九国产视频 | 日韩精品中字 | 日韩免费播放 | 欧美成人精品在线 | 欧美成人影音 | 99精品国产免费久久久久久下载 | 五月天激情视频在线观看 | 亚洲精品五月天 | 欧美成人黄色片 | 久久久免费看片 | 欧美日在线观看 | av一二三区| 国产一区二区日本 | 天天干天天在线 | 亚洲国产精品一区二区久久,亚洲午夜 | 日本高清免费中文字幕 | 日韩在线网址 | 久久精品视频播放 | 日韩二区三区 | 91久久精品一区二区二区 | 麻豆久久久久久久 | 欧美激情综合色 | 国产成人不卡 | 伊人色综合久久天天 | 区一区二区三区中文字幕 | 国产成人一级 | 精品久久久久久电影 | 黄色字幕网 | 视频成人永久免费视频 | 99精品免费观看 | 激情av综合 | 九九久久久久久久久激情 | 亚洲第一中文字幕 | 五月婷婷激情网 | 四虎亚洲精品 | 国产人成在线视频 | 精品久久久久亚洲 | 韩国av在线 | 中文字幕九九 | 国产私拍在线 | 亚洲.www | 日本成人免费在线观看 | 麻豆影视在线播放 | 国产一级免费在线观看 | 欧美一级淫片videoshd | 在线 影视 一区 | 久久精品国产亚洲精品2020 | 高清不卡一区二区三区 | 久久精品一区二区三区四区 | 91在线视频观看免费 | 成人亚洲综合 | 香蕉看片| 成年人免费观看在线视频 | 色www精品视频在线观看 | 国产成人av网站 | 日本高清xxxx | 国产精品亚州 | 久久深夜 | 久久久免费看 | 国产一区精品在线 | 国产夫妻性生活自拍 | 最近2019中文免费高清视频观看www99 | 色天天天 | 亚洲视频电影在线 | 成人av在线资源 | 99在线观看免费视频精品观看 | 99久久精品国产网站 | 97国产超碰在线 | 黄色在线网站噜噜噜 | 婷婷在线视频观看 | 国色综合| 91精品老司机久久一区啪 | 高清免费在线视频 | 亚洲人成影院在线 | 在线观看中文字幕一区 | 波多野结衣在线视频一区 | 日韩欧美精品在线 | av日韩av| 亚洲人人爱| 国产一区视频在线播放 | 天天操天天摸天天爽 | www色网站| 日韩视频免费在线 | 久久久天天操 | 久久久男人的天堂 | 69国产盗摄一区二区三区五区 | 久久人网 | 久久综合中文色婷婷 | 深夜视频久久 | 丁香婷婷成人 | 午夜婷婷在线观看 | 黄在线免费看 | 日韩综合精品 | 在线播放亚洲激情 | .国产精品成人自产拍在线观看6 | 日本中文字幕在线观看 | 97在线观看 | 黄色的视频网站 | 中文字幕免费 | 激情视频免费在线观看 | 911免费视频 | 国产精品色 | 狠狠躁夜夜躁人人爽超碰91 | 最近中文字幕大全中文字幕免费 | 91av电影 | 国产99久久久久 | 色97在线 | 黄色特级一级片 | 激情综合色图 | 91新人在线观看 | 99久久er热在这里只有精品66 | 五月天婷亚洲天综合网精品偷 | 91看片淫黄大片在线播放 | 中文字幕在线日本 | 激情欧美一区二区三区 | 国产资源| av.com在线 | 国产激情小视频在线观看 | 成年人av在线播放 | 狠狠操狠狠干2017 | 亚洲免费一级 | 激情丁香久久 | 91精品啪啪 | 国产精品久久久久亚洲影视 | 成人理论电影 | 在线观看免费黄色 | 91最新网址在线观看 | 久久精品久久精品 | av电影免费 | 91视频麻豆 | 国产精品一区二区在线观看 | 精品久久网站 | 午夜少妇av| 九九免费观看视频 | 中文字幕中文字幕在线中文字幕三区 | 96精品高清视频在线观看软件特色 | 深爱激情综合网 | 国产精品激情偷乱一区二区∴ | 久久激情视频免费观看 | 97精品国产97久久久久久久久久久久 | www.久热 | 视频99爱| 人成午夜视频 | 麻豆传媒在线视频 | 久久精品视频免费播放 | 在线观看免费视频你懂的 | 黄a网| 亚洲天天摸日日摸天天欢 | 最近中文字幕大全中文字幕免费 | 色婷婷99 | 久九视频 | 天天干天天看 | 九九免费观看全部免费视频 | 久久96| 尤物九九久久国产精品的分类 | 日韩免费一级a毛片在线播放一级 | 日本久久91| www色综合| 久操综合| 99久久婷婷国产精品综合 | 成人久久18免费网站麻豆 | 国产精品欧美一区二区 | 在线观看91视频 | 五月激情站 | 久久精品站 | 欧美日韩高清一区二区三区 | 五月天婷婷丁香花 | 亚洲精品免费观看视频 | 免费久久99精品国产婷婷六月 | 日本性生活一级片 | 午夜免费电影院 | 久久国产精品免费观看 | 欧美久久久影院 | 久久久黄色av| 五月天婷婷在线观看视频 | 丁香婷婷在线 | 亚洲国产精品资源 | 91丨九色丨蝌蚪丰满 | 91亚洲精品久久久 | 午夜资源站 | a久久免费视频 | 日韩高清av在线 | 操操操人人人 | 久草在线视频在线观看 | 毛片a级片 | 99久久精品国产免费看不卡 | 天天舔夜夜操 | 91亚色视频在线观看 | 69av免费视频| 久久ww| 久草在线手机观看 | 欧美午夜理伦三级在线观看 | 日韩三级.com | 国内精品美女在线观看 | 国产亚洲综合精品 | 欧美日韩国产一区二区三区在线观看 | 亚洲婷婷综合色高清在线 | 天天干天天干天天操 | 丁香婷婷基地 | 成人黄色电影视频 | 国产一区二区三区高清播放 | 天天射天天爽 | 九九免费观看视频 | 国产成人精品在线 | 免费久久网 | 久久看片网站 | 日批视频国产 | 国产在线精品国自产拍影院 | 日韩欧美在线综合网 | 精品国产一区二区三区久久久 | 99久久网站| 日韩一级黄色av | 欧美成人a在线 | 国产精品18久久久久久不卡孕妇 | 国产高清在线视频 | 在线观看免费av网站 | 国产日本亚洲 | 99久久精品免费看 | 精品成人网 | 国产一级二级三级在线观看 | 亚洲国产精品人久久电影 | 黄免费网站 | 丁香婷婷深情五月亚洲 | 色婷婷99| 天天操天天操天天干 | 久久国产品 | 成人黄色大片网站 | 黄色网在线免费观看 | 久久精品欧美日韩精品 | 99久久精品免费看国产四区 | 九九视频在线 | www国产亚洲精品 | 九九九九免费视频 | www久久99| 美女视频网站久久 | 日韩视频免费 | 免费看三级 | 国产精品久久久网站 | 97人人精品| 91精品在线观看视频 | 九九综合九九 | 天天视频色 | 夜夜骑日日 | 欧美在线视频一区二区 | 天天操天天操天天操 | 中文字幕资源网 | 亚洲精品午夜久久久 | av成人亚洲 | 免费视频一级片 | 国产精品国内免费一区二区三区 | 久久久久成人精品免费播放动漫 | 日韩欧美视频在线 | 久久a级片 | 国产视频二 | 国产高清免费视频 | 日韩精品免费在线播放 | 成人av地址| 麻豆精品传媒视频 | 国产a级免费 | 天天操天天舔天天爽 | 欧美日韩在线免费视频 | 欧美日韩国产一区二区三区在线观看 | 欧美影院久久 | 国产精品99久久久久久人免费 | 日韩精品久久久久久久电影竹菊 | 中文字幕在线观看三区 | 99色在线观看视频 | 91大神免费在线观看 | 久草在线免 | 一区二区免费不卡在线 | 久操视频在线观看 | 亚洲午夜大片 | 日韩电影一区二区三区在线观看 | 日韩欧美xx | 国产明星视频三级a三级点| av先锋影音少妇 | 国产日韩欧美自拍 | 国产手机精品视频 | 五月天婷婷在线播放 | 国产综合精品久久 | 热re99久久精品国产66热 | 在线观看一区视频 | 欧美激情综合网 | av视屏在线 | 精品电影一区二区 | 激情偷乱人伦小说视频在线观看 | 久久视精品 | 婷婷色狠狠 | 国产在线视频一区二区 | 国产 一区二区三区 在线 | 国产精品1区 | 97视频精品 | 在线观看av大片 | 久草资源在线 | 极品久久久久 | 国产在线观看你懂得 | 在线视频观看国产 | 日日夜操 | 国产精品女人网站 | 久久国产欧美日韩精品 | 欧美激情精品久久 | 欧美久久久久久久久久久久久 | 五月婷婷开心中文字幕 | 手机在线观看国产精品 | 在线亚洲人成电影网站色www | 日本久久综合网 | av色综合网 | 免费观看国产视频 | 色九九影院| 91在线精品秘密一区二区 | 午夜精品成人一区二区三区 | 99热精品免费观看 | 高清av中文字幕 | 亚洲男男gaygayxxxgv | 国产精品第2页 | 激情图片qvod| 亚洲人成在线电影 | 日本精品一区二区在线观看 | 欧美日韩在线观看一区二区三区 | 69久久久 | 欧产日产国产69 | 国产精品麻豆果冻传媒在线播放 | 日本少妇视频 | 国产日韩欧美在线观看 | 欧美日韩国产精品一区二区三区 | 国产午夜三级 | 婷婷综合视频 | 91精品中文字幕 | 天天射综合网站 | 日韩欧美精品一区二区 | 亚洲黄色在线观看 | 黄网站免费久久 | 精品亚洲成人 | 天天干天天搞天天射 | 精品国产免费一区二区三区五区 | 午夜精品久久久久久99热明星 | 日韩一区二区三免费高清在线观看 | 激情五月六月婷婷 | 国产麻豆精品95视频 | 91中文视频 | 久久久国产精品一区二区三区 | 超碰在线中文字幕 | 国产在线视频在线观看 | 二区三区视频 | 香蕉日日| 91精品一区二区三区蜜臀 | 国产91免费在线观看 | 亚洲男女精品 | 国产精品成久久久久 | 午夜久久福利影院 | 久久久久亚洲国产精品 | 国产精品一区在线播放 | 日本中文乱码卡一卡二新区 | 夜夜夜影院 | 免费网站观看www在线观看 | 婷婷开心久久网 | 在线国产日本 | 亚洲精品va| 日韩精品大片 | 福利一区在线视频 | 国产精品美女久久久久aⅴ 干干夜夜 | 99热这里只有精品在线观看 | 国产高清在线看 | 精品人人爽| 国产精品高潮呻吟久久久久 | 91在线看视频 | 亚洲专区中文字幕 | 欧美性粗大hdvideo | 欧美极品少妇xbxb性爽爽视频 | 91成人在线观看高潮 | 日韩欧美一区二区三区在线 | 日韩视频区 | 色婷婷久久一区二区 | 亚洲天堂网在线视频观看 | 日日夜夜草 | 丁香激情网 | 久久久香蕉视频 | 9在线观看免费高清完整版 玖玖爱免费视频 | 日躁夜躁狠狠躁2001 | 免费一级特黄录像 | 综合天堂av久久久久久久 | 国产爽妇网 | 97在线观看视频 | 人人爽人人爽人人片av | 极品美女被弄高潮视频网站 | 黄色免费在线视频 | 人人干狠狠干 | 96亚洲精品久久 | 亚洲精品中文字幕在线 | 鲁一鲁影院 | 色天天综合久久久久综合片 | 成人亚洲欧美 | 久久久久国产精品一区二区 | 久久久久久久久久久久久影院 | 国产精品久久在线观看 | 亚洲视频在线免费看 | 91大神在线观看视频 | 国产成人精品一区在线 | 久草a在线 | 99免费在线播放99久久免费 | 91大神免费在线观看 | 日韩精品中文字幕有码 | 国产成人精品综合久久久 | 2020天天干天天操 | 夜添久久精品亚洲国产精品 | av在线中文 | 免费看成人a | 69国产盗摄一区二区三区五区 | 久草在线99 | 国产在线一区二区 | 韩国av免费观看 | 精品久久久久一区二区国产 | 国产精品午夜在线观看 | 国产在线久草 | 在线观看精品黄av片免费 | 欧美性生活小视频 | 五月天婷亚洲天综合网鲁鲁鲁 | 久久国产香蕉视频 | 激情婷婷亚洲 | 国产精品久久久精品 | 黄网站色视频免费观看 | 96av视频| 久久tv视频| av电影在线免费观看 | 91av免费看| av免费看网站 | 日韩精品免费一区二区在线观看 | 黄色午夜 | 久久久久久综合网天天 | 在线观看欧美成人 | 亚洲免费在线观看视频 | 97夜夜澡人人双人人人喊 | 成人免费在线视频观看 | 69精品| 四虎永久精品在线 | 国产亚洲综合在线 | 久热这里有精品 | 久久 精品一区 | 欧美色综合久久 | 国产精品美女www爽爽爽视频 | 激情文学综合丁香 | 99精品国产一区二区三区麻豆 | 在线播放视频一区 | 色就是色综合 | 日本午夜在线观看 | 中文字幕一区二区三区四区久久 | 欧美日韩在线免费观看视频 | 91av视频在线观看免费 | 成人黄性视频 | 午夜精品一区二区三区免费 | av免费看网站 | 色 中文字幕 | 91九色在线视频 | 国产成人一区二区啪在线观看 | 亚洲蜜桃在线 | 99久久精品费精品 | 国产色综合天天综合网 | 亚洲va欧美 | 91黄色小视频 | av线上看 | 亚洲成人黄色在线 | 精品96久久久久久中文字幕无 | 久久人人爽人人爽人人 | 欧美视频不卡 | 久久久国产精品麻豆 | 一区二区三区精品久久久 | 曰本三级在线 | 亚洲精品麻豆视频 | 9999在线| 激情丁香5月 | 亚洲日韩中文字幕在线播放 | 成人久久18免费网站图片 | 色噜噜狠狠狠狠色综合久不 | 欧美成人在线网站 | 国产欧美精品在线观看 | 九九免费视频 | 日韩欧在线 | 久久99热精品 | 91在线看视频 | 四虎影视成人永久免费观看视频 | 精品久久精品 | 天天操操操操操操 | 久久蜜桃av | 亚洲精品综合一二三区在线观看 | 久草电影免费在线观看 | 久久综合射 | 996久久国产精品线观看 | 色是在线视频 | 在线网址你懂得 | 亚洲成人资源在线观看 | 久操操| 开心激情五月网 | 五月激情久久 | 夜夜夜夜爽 | 精品久久久久久国产 | 999久久久国产精品 高清av免费观看 | 国产精品久久久久久久久搜平片 | 公开超碰在线 | 东方av在线免费观看 | 久久99亚洲热视 | 亚洲视频一级 | 色综合久久综合中文综合网 | 国产高清视频免费在线观看 | 午夜精品久久久 | 免费的成人av | 久久久国产精品麻豆 | 久草精品视频在线看网站免费 | 亚洲精品欧美精品 | 亚洲黄色一级视频 | 午夜久久影视 | 日批视频在线观看免费 | 91精品国产高清自在线观看 | 国产99久久精品 | 日韩av中文 | 国产精品区一区 | 色婷婷亚洲 | 激情网在线观看 | 久久伊人八月婷婷综合激情 | 午夜男人影院 | 国产视频久久久 | 西西人体www444 | 婷婷五天天在线视频 | 日本美女xx | 欧美另类xxxx| 美女网站色在线观看 | 成人av一区二区在线观看 | av一级一片 | 99精品一级欧美片免费播放 | 国产黄大片 | 久久久国产一区二区三区 | 成人免费在线看片 | 久久一区91 | av成人黄色 | 国产精品淫| 免费视频成人 | 亚洲精品综合一区二区 | 久久久久国产成人免费精品免费 | 久草在线视频中文 | 久久r精品 | 成人av免费网站 | 草久热 | 成人精品一区二区三区中文字幕 | 中文字幕丝袜制服 | 亚洲欧美日韩精品久久奇米一区 | 国产精品久久久久久爽爽爽 | 欧美日韩性视频在线 | 成人aⅴ视频 | 中文字幕中文中文字幕 | 91av视频导航 | 成人a大片 | 天堂在线视频免费观看 | 国产精品第二十页 | 伊人超碰在线 | 国产原创中文在线 | 日韩高清国产精品 | 97香蕉超级碰碰久久免费软件 | 狠狠狠色丁香婷婷综合久久88 | 亚洲国产成人在线观看 | 色午夜 | 国产精品美女视频网站 | 天天射成人 | 国产精品成人久久 | 在线观看成人毛片 | 久久综合九色综合久久久精品综合 | 久久av中文字幕片 | 国产午夜激情视频 | 日韩精品一区二区三区免费视频观看 | 99久久久国产精品美女 | 精品免费一区二区三区 | 久久综合精品国产一区二区三区 | 国产精品理论在线观看 | 亚洲免费视频观看 | www.色爱 | 中文字幕二区 | 久草在线视频看看 | 国产91国语对白在线 | 免费国产在线视频 | 99久久久久国产精品免费 | 一区二区三区在线免费观看视频 | 黄污视频网站大全 | 国产一级特黄毛片在线毛片 | 中文在线中文资源 | www看片网站| 成人国产一区二区 | 国产精品久久久久久久电影 | 中文字幕亚洲精品在线观看 | 国产麻豆精品免费视频 | 福利片免费看 | 超碰个人在线 | aaa日本高清在线播放免费观看 | 亚洲成a人片77777kkkk1在线观看 | 天天天综合 | 一级黄色av | 亚洲 欧美 综合 在线 精品 | 久久久久免费观看 | 麻豆手机在线 | 亚洲欧美va| 99夜色| 99精品在线免费观看 | 日韩视频在线不卡 | 国产精品久久久久久电影 | 久久最新网址 | 久久精品视频网站 | 蜜臀久久99精品久久久酒店新书 | 欧美a级在线播放 | 婷婷色在线资源 | 久久99精品久久久久婷婷 | 国产成人综合在线观看 | 成人免费网视频 | 国产精品免费视频网站 | 欧美亚洲久久 | 久久伊人精品一区二区三区 | 国产三级视频在线 | 精品亚洲va在线va天堂资源站 | 久草视频在线观 | 成人免费一级 | 久久成人综合视频 | 黄网站色欧美视频 | 日本狠狠干 | 亚洲成av人片 | 福利一区二区在线 | av网站在线观看免费 | 久久综合亚洲鲁鲁五月久久 | 亚洲精品国产综合久久 | 亚洲日日射 | 成人免费xyz网站 | 在线免费看片 | 国产精品一区二区三区久久 | www黄| 免费h漫在线观看 | 久久久久亚洲精品中文字幕 | 成人91在线 | 亚洲 欧美 日韩 综合 | 日日躁天天躁 | 日韩高清黄色 | 亚洲国产精品久久久久婷婷884 | 亚洲国产片 | 日韩免费观看视频 | 日本中文乱码卡一卡二新区 | 五月天中文字幕mv在线 | 亚洲无吗av | 国产精品不卡在线观看 | 一区二区视频电影在线观看 | 毛片网站在线看 | 在线观看你懂的网址 | aaa日本高清在线播放免费观看 | 久久久久久久国产精品 | www.香蕉视频在线观看 | 91九色蝌蚪国产 | 五月婷婷丁香在线观看 | 手机av在线网站 | 中文字幕在线观看2018 | 亚洲视频观看 | 国产视频精品网 | 美女福利视频 | 久久99精品久久久久久久久久久久 | 色a在线观看 | 激情开心 | 欧美一级在线 | 国产成人一区二区三区电影 | 国产尤物视频在线 | 中文字幕一区二区三区久久蜜桃 | 日韩中文字幕视频在线观看 | 久久久久久毛片精品免费不卡 | 特级片免费看 | 日韩精品一区二区三区视频播放 | 国产国语在线 | 中文字幕在线观看视频免费 | 999热视频 | 日韩激情视频在线观看 | 91在线免费视频观看 | 久久久av免费 | 高清av在线免费观看 | 亚洲男男gⅴgay双龙 | 国产精品国产三级在线专区 | 亚洲三级毛片 | 国产精品激情偷乱一区二区∴ | 最近日本中文字幕a | 超碰久热| 亚洲精品在线视频播放 | 91.精品高清在线观看 | 手机看片福利 | 日韩欧美在线第一页 | 精品伊人久久久 | av三级在线看| 国产免费嫩草影院 | 色婷婷午夜 | 不卡av在线免费观看 | 国产一区二区在线观看免费 | 国产日产亚洲精华av | 日韩欧美在线观看一区二区 | 狠狠干2018 | av成人资源 | 国产精品久久久久久久久久ktv | 成人理论在线观看 | 日本h视频在线观看 | 久久精品艹 | 99精品在线看 | 一区二区成人国产精品 | 九九热在线视频免费观看 | 亚洲免费在线观看视频 | 日本公妇色中文字幕 | 国产亚洲精品美女久久 | 一区二区三区电影 | 91精品人成在线观看 | av大片免费在线观看 | 九九爱免费视频 | 久青草电影 | 国产中文字幕在线免费观看 | 黄色av电影在线观看 | 又污又黄网站 | 丝袜美女在线观看 | 久久国产免费 | 久久精品伊人 | 国产精品中文字幕在线观看 | 国产又粗又猛又黄 | 91亚洲精品国偷拍自产在线观看 | 天天夜夜狠狠操 | 亚洲永久精品在线观看 | 青青河边草免费视频 | 精品国产一区二区三区久久久蜜月 | 色九九视频 | 中国精品一区二区 | 精品a级片| 狠狠干五月天 | 日韩一区二区免费播放 | 久久免费a | 久久久久国产成人精品亚洲午夜 | 亚洲 综合 国产 精品 | 欧美在线视频日韩 | 精品视频999 | 国产精品99久久免费黑人 | 天天翘av | av电影在线观看完整版一区二区 | 国产午夜免费视频 | 我要色综合天天 | av久久在线 | av 一区 二区 久久 | 又黄又爽又刺激 | 国产91成人在在线播放 | wwwav视频 | 一区二区精 | 国产精选在线 | 97国产在线视频 | 国产一级二级在线播放 | 午夜国产福利在线 | 国产99久久久久久免费看 | 高清av免费一区中文字幕 | av黄色在线播放 | 国产999精品久久久久久麻豆 | 青草视频在线 | 久久亚洲在线 | 日本特黄特色aaa大片免费 | 日韩国产精品久久久久久亚洲 | 国内精品在线一区 | 色综合久久中文字幕综合网 | 91在线免费看片 | 人人干天天射 | 91看片看淫黄大片 | 日韩天堂网 | 99在线观看 | 免费日韩av电影 | 久久伦理视频 | 一区二区三区四区在线 | 91精选在线观看 | 久久不射电影网 | 激情五月在线视频 | 国色天香在线 | 国产69精品久久99的直播节目 | 日韩免费三区 | 国产原创91| 亚洲成a人片77777kkkk1在线观看 | 国产精品成人在线观看 | 国产精品久久9 | 欧美精品第一 | 日韩免费网址 | 欧美日韩久久久 | 中文字幕在线观看你懂的 | 人人干狠狠操 | 欧美九九九 | 最新av在线播放 | 国产视频黄 | 精品99999| 人人爽人人爽人人 | 精品国产一区二区三区久久影院 | 日韩免费在线观看视频 | 国产涩涩在线观看 | 亚洲精品高清一区二区三区四区 | 国内精品中文字幕 | 美女久久久久久久 | 99视频精品免费观看, | 日韩,精品电影 | 亚洲日本va午夜在线影院 | 四虎免费在线观看视频 | 91中文在线观看 | 午夜免费久久看 | 国产精品久久二区 | 欧美另类美少妇69xxxx | 精品在线观| 麻豆视频在线看 | 中文字幕在线播放一区 | 国产在线播放一区二区三区 | 国产日产精品久久久久快鸭 | 亚洲精品乱码久久久久久按摩 | 国产视频二区三区 | 伊人天堂网 | 狠狠干天天操 | 91探花在线 | 91看片淫黄大片91 | 91香蕉视频黄色 | 亚洲一级片在线观看 | 国产二区视频在线观看 | 亚洲2019精品 | 在线观看的av | 麻豆精品视频在线 | 二区三区在线 | 日韩av视屏在线观看 | www.人人草| 国内久久久久 | 午夜久久电影网 | 91刺激视频| 久久久久欧美精品 | 视频高清| 日韩激情中文字幕 | 99国产一区二区三精品乱码 | 最新中文字幕 | 91精品国产成人www | 一级黄色片在线免费看 | 久草精品视频在线观看 | 久久久久久久久久久久国产精品 | 国产三级国产精品国产专区50 | 欧美日韩中文字幕在线视频 | 中文字幕有码在线观看 | 欧美大片在线观看一区 | 973理论片235影院9 | 国产黄色大片免费看 | 欧美日韩首页 | 91精彩视频在线观看 | 黄色小说免费观看 | 免费人人干 | 国产视频九色蝌蚪 | 亚洲人人av| 日韩在线视 | 久久免费国产视频 | 韩日成人av | 九九热精品视频在线观看 | 一区二区三区视频网站 | 国产一级免费视频 | 亚洲第一久久久 | 99精彩视频| 中文字幕中文字幕中文字幕 | 久久九九国产视频 | 天天操天天操天天操天天 | 欧美另类高清 | 久久99最新地址 | 91精品免费在线 | 黄色av电影免费观看 | 东方av在 | 日韩高清免费电影 | 99色99| 国产精品午夜久久 | 久久在线免费视频 | 免费日韩av片| 在线观看av黄色 | 久久不卡免费视频 | 久草久| 黄色app网站在线观看 | 亚洲涩涩网 | 欧美精品在线观看免费 | 色偷偷网站视频 | 91精品国自产在线观看 | 91插插视频 | 亚洲天堂网在线视频 | 欧美久久成人 | 国产精品成人在线 | 亚洲综合色站 | 色综合天天综合在线视频 | 99久久99久久免费精品蜜臀 | 国产精品原创av片国产免费 | 国产日产精品一区二区三区四区的观看方式 | 婷婷视频在线 | 99中文在线 | 在线观看中文字幕视频 | 天天色天天射天天综合网 | 日本丰满少妇免费一区 | 狠狠干2018 | 久久精品电影网 | 91麻豆免费视频 | 国产三级精品三级在线观看 | 亚洲视频中文 | 精品视频9999 | 亚洲精品欧美视频 | 色综合天天狠天天透天天伊人 | 97电影手机| 亚洲丁香久久久 | 久久精品aaa| 国产专区欧美专区 | 天天天天天操 | 午夜资源站 | 欧美a√在线 | 日本性动态图 | 99成人精品 | 天天爱天天操天天射 | 中文字幕在线播放一区二区 | 日韩中文字幕免费视频 | 九色在线视频 | 在线观看v片 | 伊人电影天堂 | 五月黄色 | 亚洲精品美女免费 | 射久久| 欧美日韩亚洲精品在线 | 日韩高清精品免费观看 | 天天爱天天射天天干天天 | 免费看污网站 | 国产美女无遮挡永久免费 | 国产激情小视频在线观看 | 岛国大片免费视频 | 99精品久久久久久久 | 国产精品美女在线观看 | 国产精品一区二区麻豆 | 五月综合久久 | 国产高清日韩 | 激情婷婷久久 | 一本一本久久a久久精品综合妖精 | 天天插天天干天天操 | 久久综合九色综合欧美就去吻 | 中国一级片在线观看 | 精品国产乱码久久久久久1区二区 | 日韩av网页 | av网站免费线看精品 | www.久久久精品 | 毛片激情永久免费 | 亚洲精品国产成人av在线 | 玖玖999 | 亚洲精品乱码久久 | 国产丝袜网站 | 久久精精品视频 | 中文字幕一二 | 日韩理论电影网 | 黄色av网站在线免费观看 | 久久久国产99久久国产一 | 在线观看亚洲免费视频 | 精品久久久久久久久久 | 日韩高清黄色 | 激情久久婷婷 | av电影免费在线 | 九九热免费视频在线观看 | 成人黄色电影在线观看 |