0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

你對(duì)藍(lán)牙協(xié)議了解多少?

硬件攻城獅 ? 來(lái)源:CSDN ? 作者:喵吉訶德 ? 2022-11-24 14:12 ? 次閱讀

藍(lán)牙在我們生活中非常普遍,小到手表,大到電視洗衣機(jī)等都有藍(lán)牙的身影。

那么,你對(duì)藍(lán)牙協(xié)議了解多少?

Part101 藍(lán)牙概述

藍(lán)牙技術(shù)起源于愛(ài)立信在1994年提出的方案,旨在解決移動(dòng)電話和其他配件之間進(jìn)行低功耗、低成本的無(wú)線通信連接的方法。

60855804-6bae-11ed-8abf-dac502259ad0.jpg

藍(lán)牙發(fā)展歷史

第一代藍(lán)牙主要是指90年代的V1.0~V1.2版本,是關(guān)于段距離通信的早期探索,此時(shí)還存在許多問(wèn)題,應(yīng)用不是特別廣泛

第二代藍(lán)牙主要是00年中V2.0~V2.1版本,新增了EDR(Enhanced Data Rate)技術(shù)提高傳輸速率,以及體驗(yàn)及安全

第三代藍(lán)牙主要是00年末V3.0版本,新增了802.11 WiFi協(xié)議,引入了AMP(Generic Alternate MAC/PHY)交替射頻技術(shù),極大的提高了傳輸速率并降低功耗

第四代藍(lán)牙是10年以來(lái)的V4.0~V4.2版本,主推LE(Low Energy)低功耗,大約僅消耗十分之一,將三種規(guī)格,包括經(jīng)典藍(lán)牙、高速藍(lán)牙、和藍(lán)牙低功耗,集中在一起形成一套綜合協(xié)議規(guī)范

第五代藍(lán)牙是16年開(kāi)始提出的V5.0版本,主要是為了支持物聯(lián)網(wǎng),在功耗、傳輸速率、有效傳輸距離、數(shù)據(jù)包容量方面都做了極大的提升

下面的分析都是基于V4.1版本,方便入門(mén),可以理解很多核心協(xié)議的設(shè)計(jì)思想

Part202 藍(lán)牙技術(shù)分類

藍(lán)牙技術(shù)包含藍(lán)牙發(fā)展過(guò)程中的兩套技術(shù),但是這兩套原理和實(shí)現(xiàn)都不一樣,也無(wú)法實(shí)現(xiàn)互通

Basic Rate(BR)/AMP

最初的藍(lán)牙技術(shù),包括可選的EDR(Enhanced Data Rate)技術(shù)和交替使用的MAC層和PHY層擴(kuò)展 AMP(Alternate MAC and PHY layer extension)【優(yōu)化傳輸速度的過(guò)程】

解釋:藍(lán)牙誕生之初使用的BR技術(shù),傳輸速率很低,隨著發(fā)展而變得無(wú)法支持,所以引入了EDR,這時(shí)還沒(méi)有修改軟硬件架構(gòu),但是之后又落伍了,所以直接引入了WiFi的底層協(xié)議,也就是MAC/PHY擴(kuò)展,但這部分的實(shí)現(xiàn)就無(wú)法直接更替,所以BR/EDR只能與AMP交替使用

Low Energy(LE)

藍(lán)牙低功耗,則不關(guān)心傳輸速率,而是從降低功耗的角度實(shí)現(xiàn)的另一套技術(shù),跟前面的協(xié)議沒(méi)有絲毫關(guān)系

Part303 藍(lán)牙架構(gòu)

609fb6d6-6bae-11ed-8abf-dac502259ad0.png

structure

藍(lán)牙協(xié)議將藍(lán)牙整體分成了兩層架構(gòu),底層是核心協(xié)議,描述了藍(lán)牙核心技術(shù)的基礎(chǔ)和規(guī)范,應(yīng)用層協(xié)議則基于具體需求,使用核心協(xié)議提供的機(jī)制,實(shí)現(xiàn)不同的功能策略

核心協(xié)議包含兩部分,Host和Controller,這兩部分在不同的藍(lán)牙協(xié)議版本中略有區(qū)別,但大致上是,Controller完成硬件側(cè)的規(guī)范制訂,包括信號(hào)調(diào)制解調(diào),會(huì)抽象出用于通信的邏輯鏈路,可能存在一個(gè)或多個(gè),如LE Controller、BR/EDR Controller;Host則在邏輯鏈路的基礎(chǔ)上完成更友好的封裝,屏蔽掉技術(shù)細(xì)節(jié),方便應(yīng)用層對(duì)數(shù)據(jù)的使用

Part404 藍(lán)牙協(xié)議

藍(lán)牙協(xié)議也采用層次結(jié)構(gòu),自下而上依次為物理層、邏輯層、L2CAP層和應(yīng)用層

60c255e2-6bae-11ed-8abf-dac502259ad0.png

protocol

應(yīng)用層(App Layer)為不同場(chǎng)景定義規(guī)范,提出Profile(一項(xiàng)服務(wù))的概念,實(shí)現(xiàn)各種應(yīng)用功能

L2CAP(Logical Link Control and Adaptation Protocol Layer)

邏輯鏈路控制和適配協(xié)議,負(fù)責(zé)管理邏輯鏈路,使得不同應(yīng)用可共享一個(gè)邏輯鏈路,類似端口的實(shí)現(xiàn)

在邏輯鏈路的基礎(chǔ)上,抽象出與具體技術(shù)無(wú)關(guān)的數(shù)據(jù)傳輸信道,如單/廣播,然后對(duì)上以L2CAP channel endpoints的概念,為不同應(yīng)用程序提供獨(dú)立的傳輸通道

邏輯層(Logical Layer)

提供設(shè)備對(duì)象之間邏輯傳輸,在物理層的基礎(chǔ)上,建立邏輯信道,主要基于傳輸類型來(lái)劃分,包括控制類傳輸(負(fù)責(zé)底層物理鏈路的管理)、用戶類傳輸(負(fù)責(zé)用戶數(shù)據(jù)傳輸)和其他特殊類型的傳輸

不同的邏輯信道(Logical Link)會(huì)在下層對(duì)應(yīng)Logical Transport,實(shí)現(xiàn)流控、應(yīng)答、重傳等機(jī)制

物理層(Physical Layer)

負(fù)責(zé)提供數(shù)據(jù)傳輸?shù)奈锢硗ǖ?/p>

物理鏈路(Physical Link):對(duì)物理信道的進(jìn)一步封裝

物理信道(Physical channel):三種藍(lán)牙技術(shù)都使用相同的頻段和頻率范圍,但是具體實(shí)現(xiàn)都不一樣

Advertisement Broadcast Channel:用于設(shè)備間無(wú)連接廣播通信,包括發(fā)現(xiàn)/連接操作

Piconet channel:用于連接狀態(tài)下通信

Inquiry Scan Physical Channel:用于發(fā)現(xiàn)操作,即搜索/被搜索

Page Scan Physical Channel:用于連接操作,即連接/被連接

Basic Piconet Physical Channel:用于連接狀態(tài)下通信,使用79個(gè)跳頻點(diǎn)

Adapted Piconet Physical Channel:用于連接狀態(tài)下通信,使用較少RF跳頻點(diǎn)

Synchronization Scan Channel:用于無(wú)連接的廣播通信

BR/EDR頻段分成了79個(gè)channel,每個(gè)占1M帶寬;采用跳頻技術(shù)(Hopping),即物理信道隨機(jī)占用某一channel;定義了五種物理信道,每次只能在一種物理信道上通信,采用時(shí)分方式

AMP直接使用WIFI的物理層規(guī)范,只有一個(gè)物理信道,用于已連接設(shè)備之間的高速數(shù)據(jù)通信

LE頻段分成了40個(gè)channel,每個(gè)占2M帶寬;有兩種物理信道,每次只能在一種物理信道上通信,采用時(shí)分方式

Part505 BLE協(xié)議棧

實(shí)現(xiàn)一個(gè)BLE應(yīng)用,需要一個(gè)支持BLE射頻的芯片,然后基于一個(gè)與芯片配套的協(xié)議棧,開(kāi)發(fā)藍(lán)牙應(yīng)用。

協(xié)議棧的作用就是軟件和硬件之間的橋梁,對(duì)應(yīng)用數(shù)據(jù)進(jìn)行封包然后生成可以通過(guò)射頻發(fā)送的空中數(shù)據(jù)包及其逆向過(guò)程。

60de74f2-6bae-11ed-8abf-dac502259ad0.png

BLE-protocol

Physical Layer(PHY)

藍(lán)牙通信系統(tǒng)的物理層,是免費(fèi)ISM頻段,整個(gè)頻帶分成40份,每份帶寬2MHz;此外還定義了RF收發(fā)相關(guān)的特性,如發(fā)射功率、調(diào)制解調(diào)方式等

Link Layer(LL)

解決在有限物理信道上傳輸遠(yuǎn)多實(shí)際信道數(shù)量的數(shù)據(jù),即信道共享,然后為通信實(shí)體創(chuàng)建看似獨(dú)享的邏輯信道,以及解決傳輸過(guò)程中的校驗(yàn)、重傳等問(wèn)題

LL中的信道設(shè)計(jì):BLE系統(tǒng)基于通信場(chǎng)景,在40個(gè)物理信道中選取三個(gè)作為廣播信道,處理數(shù)據(jù)量小、發(fā)送不頻繁、時(shí)延不敏感的場(chǎng)景,存在的問(wèn)題就是不可靠、效率低、不安全;另外的場(chǎng)景則在剩下的37個(gè)信道中選取一個(gè)為雙方建立單獨(dú)信道,并且為了抗干擾采用跳頻技術(shù)

為此,LL為通信雙方實(shí)體定義了以下?tīng)顟B(tài)及切換條件

615f9ed8-6bae-11ed-8abf-dac502259ad0.png

BLE-state

- Standby:初始狀態(tài),不收發(fā)數(shù)據(jù),接受上層協(xié)議命令與其他狀態(tài)切換
- Advertising:通過(guò)廣播發(fā)送數(shù)據(jù)的狀態(tài),建立連接后可進(jìn)入Connection
- Scanning:接收廣播的數(shù)據(jù)的狀態(tài)
- Initiating:特殊的接收狀態(tài),類似Scanning,接收Advertiser廣播的連接數(shù)據(jù),建立連接后進(jìn)入Connection
- Connection:建立連接后擁有單獨(dú)的通道
12345

這里會(huì)使用空中接口協(xié)議(Air Interface Protocol,AIP)來(lái)負(fù)責(zé)實(shí)體之間的數(shù)據(jù)交換和狀態(tài)切換

Host Controller Interface(HCI)

定義Host和Contorller之間的通信協(xié)議,如兩個(gè)芯片之間的串口

L2CAP

邏輯控制和適配協(xié)議的工作就是實(shí)現(xiàn)邏輯信道的多路復(fù)用(multiplexing),對(duì)上層數(shù)據(jù)進(jìn)行分割和重組,以及后續(xù)的流控、錯(cuò)誤控制和重傳等

多路復(fù)用思想:將要發(fā)送的數(shù)據(jù)分割成一個(gè)個(gè)數(shù)據(jù)包(Packet Data Unit,PDU),添加包含特定ID的頭部,接收方解析頭部ID進(jìn)行重組

多路復(fù)用實(shí)現(xiàn)

基于連接:L2CAP會(huì)為每個(gè)邏輯信道分配一個(gè)編號(hào)(Channel ID,CID),有些CID會(huì)有固定用途

基于協(xié)議(略)

Attribute Protocol(ATT)

屬性協(xié)議主要是針對(duì)物聯(lián)網(wǎng)場(chǎng)景,核心思想就是將采集的信息或控制的命令以屬性的形式抽象出來(lái),提供接口供遠(yuǎn)端設(shè)備讀寫(xiě)

采用C/S形式,信息提供方為ATT Server,如傳感器,訪問(wèn)方為ATT Client

為每個(gè)Attribute定義了三個(gè)屬性

Type,即Attribute的類型,使用UUID區(qū)分

Handle,服務(wù)端用來(lái)唯一標(biāo)識(shí)Attribute的16-bit數(shù)值

Value,Attribute的值

為每個(gè)Attribute定義了一系列權(quán)限,方便服務(wù)端控制客戶端的行為,包括訪問(wèn)/加密/認(rèn)證/授權(quán)

對(duì)于不同的Attribute,客戶端對(duì)服務(wù)端的訪問(wèn)方式也不一樣,包括Find/Read/Write

傳輸過(guò)程是在L2CAP的基礎(chǔ)上,使用基于通道的多路復(fù)用,CID為0x0004

Generic Attribute Profile(GATT)

通用屬性配置文件,Attribute只是將信息(或者說(shuō)通信數(shù)據(jù))做一下抽象,但是真正對(duì)抽象的信息做分類管理則是GATT來(lái)完成,形成profile的概念(解決了很多無(wú)線協(xié)議的兼容問(wèn)題),profile可以理解成應(yīng)用場(chǎng)景或者使用方式

GATT提供了這樣一種通用的、信息存儲(chǔ)與共享的profile framework,實(shí)現(xiàn)BLE雙向通信

GATT的層次結(jié)構(gòu)

617eafee-6bae-11ed-8abf-dac502259ad0.jpg

GATT_profile_hierarchy

Profile位于最頂層,不是真正存在的配置文件,而是一個(gè)或多個(gè)場(chǎng)景相關(guān)的service的抽象集合

Service(服務(wù))是一種行為的抽象,具有唯一標(biāo)識(shí)UUID,每個(gè)service包含一個(gè)或多個(gè)Characteristic,也可以通過(guò)include的方式包含其他service

Characteristic(特征)可以理解成一個(gè)屬性,是真正與設(shè)備通信相關(guān)的,數(shù)據(jù)發(fā)送和接收的最基本單位,通過(guò)對(duì)特征的讀寫(xiě)實(shí)現(xiàn)藍(lán)牙雙向通信,它由一個(gè)Propertities(定義Value的使用規(guī)范和Descriptor的訪問(wèn)規(guī)范)、一個(gè)Value(特征的實(shí)際取值)和一個(gè)或多個(gè)Descriptor(Value相關(guān)的描述信息)組成,每個(gè)特征也具有自己的唯一標(biāo)識(shí),但是有三種形式:

16-bit是官方認(rèn)證,收費(fèi),Bluetooth_Base_UUID 為 00000000-0000-1000-8000-00805F9B34FB

16-bit轉(zhuǎn)128-bit,格式為 0000xxxx-0000-1000-8000-00805F9B34FB

32-bit轉(zhuǎn)128-bit,格式為 xxxxxxxx-0000-1000-8000-00805F9B34FB

事實(shí)上,目前幾乎所有的BLE應(yīng)用都基于GATT實(shí)現(xiàn)通信

GATT通信基于C/S模型,外圍設(shè)備作為Server端,維護(hù)ATT結(jié)構(gòu)及產(chǎn)出數(shù)據(jù),中心設(shè)備作為client端,請(qǐng)求連接獲取數(shù)據(jù)

GATT連接對(duì)外圍設(shè)備是獨(dú)占的,即一個(gè)外圍設(shè)備同時(shí)與一個(gè)中心設(shè)備建立連接,一個(gè)中心設(shè)備可同時(shí)與多個(gè)外圍設(shè)備建立連接

Security Manager(SM)

安全管理協(xié)議主要負(fù)責(zé)BLE通信過(guò)程中安全相關(guān)的內(nèi)容,包括認(rèn)證、加密這些過(guò)程

Generic Access Profile(GAP)

通用訪問(wèn)配置文件,定義了藍(lán)牙設(shè)備的通用的訪問(wèn)功能,與GATT的數(shù)據(jù)通信過(guò)程對(duì)應(yīng),處理無(wú)連接連接建立過(guò)程的通信,也就是為廣播、掃描、發(fā)起連接這些過(guò)程定義統(tǒng)一規(guī)范

定義了用戶接口的基本參數(shù),包括藍(lán)牙地址、名稱、pincode、class等概念

定義了設(shè)備的角色:

Broadcaster Role:正在發(fā)送advertising events的設(shè)備

Observer Role:正在接收advertising events的設(shè)備

Peripheral Role:接受Link Layer連接的設(shè)備(對(duì)應(yīng)Link Layer的slave角色)

Central Role,發(fā)起Link Layer連接的設(shè)備(對(duì)應(yīng)Link Layer的master角色)

定義了通信的過(guò)程和操作模式:

Broadcast mode and observation procedure:實(shí)現(xiàn)單向的、無(wú)連接的通信

Discovery modes and procedures:實(shí)現(xiàn)藍(lán)牙設(shè)備的發(fā)現(xiàn)操作

Connection modes and procedures:實(shí)現(xiàn)藍(lán)牙設(shè)備的連接操作

Bonding modes and procedures:實(shí)現(xiàn)藍(lán)牙設(shè)備的配對(duì)操作

Part606 BLE的廣播

使用場(chǎng)景

單向、無(wú)連接的數(shù)據(jù)通信,發(fā)送者使用廣播信道發(fā)送數(shù)據(jù),接受者掃描接收數(shù)據(jù)

連接建立階段

協(xié)議層次

GAP:以應(yīng)用程序角度進(jìn)行功能封裝,提供一套統(tǒng)一的、通用的廣播規(guī)范

HCI:將LL提供的功能抽象成Command/Events的形式,供上層使用

LL:負(fù)責(zé)廣播通信相關(guān)功能的定義和實(shí)現(xiàn),包括信道選擇、鏈路狀態(tài)定義、PDU定義、設(shè)備過(guò)濾機(jī)制等

LL

信道選擇。BLE將藍(lán)牙頻段分成了40個(gè)物理信道,綜合考慮(抗干擾等)后將其中三個(gè)作為廣播信道,頻段為0/12/39,編號(hào)是37-39

鏈路狀態(tài)。參與廣播的BLE設(shè)備,總是處于這三種狀態(tài)之一

Advertising:廣播狀態(tài),周期性地廣播,數(shù)據(jù)發(fā)送方

Scanning:掃描狀態(tài),掃描并接受廣播數(shù)據(jù),數(shù)據(jù)接收方

Initiating:初始化狀態(tài),掃描到可連接的廣播時(shí),發(fā)起連接請(qǐng)求,連接發(fā)起方

PDU(Packet Data Unit)格式

61a73fea-6bae-11ed-8abf-dac502259ad0.png
pdu

Type是指PDU的類型,如不同的狀態(tài)下也有不同的消息類型,TxAdd和RxAdd都是地址類型flag,針對(duì)不同的type有不同的含義,RFU都是保留字段,Length標(biāo)明payload的長(zhǎng)度

Payload內(nèi)容

State Type Descriptions Payload length Descriptions
Advertising ADV_IND 常規(guī)廣播,可連接可掃描 AdvA 6 address of broadcaster
【后續(xù)建立點(diǎn)對(duì)點(diǎn)連接,監(jiān)聽(tīng)CONNECT_REQ請(qǐng)求】 AdvData 0~31 Broadcast data
ADV_NONCONN_IND 同ADV_IND,不可連接不可掃描 AdvA 6 address of broadcaster
【用于定時(shí)傳輸簡(jiǎn)單數(shù)據(jù)】 AdvData 0~31 Broadcast data
ADV_SCAN_IND 同ADV_IND,不可連接可掃描 AdvA 6 address of broadcaster
【用于傳輸額外數(shù)據(jù),監(jiān)聽(tīng)SCAN_REQ請(qǐng)求】 AdvData 0~31 Broadcast data
ADV_DIRECT_IND 點(diǎn)對(duì)點(diǎn)連接,已知雙方藍(lán)牙地址,無(wú)廣播數(shù)據(jù),可被指定設(shè)備連接不可掃描 AdvA 6 address of broadcaster
【快速建立連接,不關(guān)心廣播數(shù)據(jù),監(jiān)聽(tīng)CONNECT_REQ請(qǐng)求】 InitA 6 address of receiver/initiater
Scanning SCAN_REQ 接收ADV_IND/ADV_SCAN_IND后,請(qǐng)求更多信息 ScanA 6 address of scanne r
【接收廣播數(shù)據(jù)后請(qǐng)求更多信息】 AdvA 6 address of broadcaster
SCAN_RSP SCAN_REQ的響應(yīng),返回更多信息 AdvA 6 address of broadcaster
ScanRspData 0~31 response data
Initiating CONNECT_REQ 接收ADV_IND/ADV_DIRECT_IND后,請(qǐng)求建立連接 InitA 6 address of receiver/initiater
【請(qǐng)求建立連接】 AdvA 6 address of broadcaster
LLData 22 parameters of connection

BLE設(shè)備地址類型

Static Device Address:上電生成,46-bit的random+11,斷電后可變

Private Device Address:進(jìn)一步提供定時(shí)更新和地址加密提高可靠行和安全性

Non-resolvable Private Address:按周期定時(shí)更新,46-bit的random+00

Resolvable Private Address:通過(guò)隨機(jī)數(shù)和IRK(Identity Resolving Key)生成,24-bit的hash+22-bit的random+10

Public Device Address:IEEE分配,24-bit的company_id+24-bit的company_assigned,類似MAC

Random Device Address:隨機(jī)生成,解決費(fèi)用和維護(hù)、設(shè)備身份綁定的問(wèn)題

HCI

將Link Layer提供的功能封裝成Command/Event組

Command格式

62336f10-6bae-11ed-8abf-dac502259ad0.png

command

OCF(Opcode Command Field)表示特定的HCI命令,OGF(Opcode Group Field)表示該HCI命令所屬組別,他們共同組成16位操作碼;Parameter Total Length表示所有參數(shù)總長(zhǎng)度

所有BLE相關(guān)的HCI Command的OGF都是0x08

Event格式

624d5e48-6bae-11ed-8abf-dac502259ad0.png

event

這些Command/Event包括廣播、掃描、連接建立的相關(guān)操作,這些都可以通過(guò)hcitool命令進(jìn)行測(cè)試

GAP

會(huì)從應(yīng)用程序角度對(duì)各種狀態(tài)和操作再一次進(jìn)行封裝,包括設(shè)備角色,通信的模式和操作的定義

與GAP廣播通信相關(guān)的是廣播和發(fā)現(xiàn)模式

Broadcast mode and observation procedure,廣播模式及對(duì)應(yīng)的解析過(guò)程,對(duì)應(yīng)狀態(tài)下的角色雙方就是Broadcaster和Observer

Discovery modes and procedures,發(fā)現(xiàn)模式及對(duì)應(yīng)的發(fā)現(xiàn)過(guò)程,對(duì)應(yīng)的角色就是Peripheral和Central

廣播數(shù)據(jù)格式

626f7622-6bae-11ed-8abf-dac502259ad0.png

adv_data

廣播/掃描應(yīng)答數(shù)據(jù),包含有意義部分和無(wú)意義部分(補(bǔ)齊為0),有意義部分是由一個(gè)個(gè)廣播塊(AD Structure)組成,每個(gè)廣播塊包含1字節(jié)長(zhǎng)度(指示數(shù)據(jù)部分長(zhǎng)度)和剩下的數(shù)據(jù)部分,數(shù)據(jù)部分又分為數(shù)據(jù)類型和數(shù)據(jù)內(nèi)容,數(shù)據(jù)類型會(huì)指示真實(shí)Data部分的內(nèi)容,例如0x01表示Data內(nèi)容是描述設(shè)備物理連接狀態(tài),再例如0x08表示Data內(nèi)容是設(shè)備名稱,更多可以參考generic-access-profile

舉個(gè)廣播數(shù)據(jù)的例子

0201060303aafe1716aafe00-10000102030405060708090a0b0e0f00000000
1

02 01 06是一個(gè)AD Structure,數(shù)據(jù)部分長(zhǎng)度為2字節(jié),類型是0x01,描述設(shè)備物理連接狀態(tài),數(shù)據(jù)部分0x06,1字節(jié)8bit,每bit都是一個(gè)標(biāo)志位([預(yù)留]|[預(yù)留]|[預(yù)留]|[同時(shí)支持BLE和BR/EDR(Host)]|[同時(shí)支持BLE和BR/EDR(Controller)]|[不支持BR/EDR]|[普通發(fā)現(xiàn)模式]|[有限發(fā)現(xiàn)模式]),那么這個(gè)廣播就是普通發(fā)現(xiàn)模式,不支持BR/EDR

03 03 aa fe是第二個(gè)AD Structure,數(shù)據(jù)部分長(zhǎng)度為3字節(jié),類型是0x03,表示16-bits的Service UUID

17 16 aa fe 00 -10 00 01 02 03 04 05 06 07 08 09 0a 0b 0e 0f 00 00 00 00是最后一個(gè)AD Structure,數(shù)據(jù)部分長(zhǎng)度為0x17即23字節(jié),類型是0x16,表示服務(wù)數(shù)據(jù)

AD Type Description AD Data
0x01 設(shè)備物理連接狀態(tài) 1字節(jié)8bit,每個(gè)bit都是一個(gè)標(biāo)志位 [預(yù)留]|[預(yù)留]|[預(yù)留]|[同時(shí)支持BLE和BR/EDR(Host)]|[同時(shí)支持BLE和BR/EDR(Controller)]|[不支持BR/EDR]|[普通發(fā)現(xiàn)模式]|[有限發(fā)現(xiàn)模式]
0x02 UUID 非完整的16-bit UUID
0x03 UUID 完整的16-bit UUID
0x04 UUID 非完整的32-bit UUID
0x05 UUID 完整的32-bit UUID
0x06 UUID 非完整的128-bit UUID
0x07 UUID 完整的128-bit UUID
0x08 設(shè)備名稱 縮寫(xiě)設(shè)備名稱
0x09 設(shè)備名稱 完整設(shè)備名稱
0x0a TX Power Level TX Power Level
0xff 廠商數(shù)據(jù) [廠商ID]|[廠商自定義數(shù)據(jù)]

Part707 BLE的連接

經(jīng)典藍(lán)牙中保持連接非常耗費(fèi)資源,但是每次連接建立效率又非常低,為了優(yōu)化體驗(yàn),BLE簡(jiǎn)化了連接過(guò)程(毫秒級(jí)),極大的降低了面向連接通信的代價(jià)

藍(lán)牙通信系統(tǒng)中,對(duì)于連接的定義是:在約定的時(shí)間段內(nèi),雙方都到一個(gè)指定的物理Channel上通信。

LL

角色定義。BLE為處于連接狀態(tài)的兩個(gè)設(shè)備定義了兩個(gè)角色,Master和Slave。Master作為連接發(fā)起方,定義和連接相關(guān)的參數(shù),Slave是連接的接收方,請(qǐng)求連接參數(shù)

PDU(Packet Data Unit)格式

629204a8-6bae-11ed-8abf-dac502259ad0.png

DC_PDU

面向連接的通信使用特定的PDU,稱為Data channel PDU

LLID指示Data Channel傳輸?shù)腜DU類型,傳輸數(shù)據(jù)是LL Data PDU,傳輸控制信息是LL Control PDU,NESN(Next Expected Sequence Number)和SN(Sequence Number)用于數(shù)據(jù)傳輸過(guò)程中的應(yīng)答和流控,MD(More Data)用于關(guān)閉連接,RFU是預(yù)留位,Length指示有效數(shù)據(jù)長(zhǎng)度,包括Payload和MIC

LLID type Description
01b LL Data PDU 空包或未傳輸完成的消息(被拆包)
10b LL Data PDU (不需拆包)完整消息或第一個(gè)包
11b LL Control PDU 用于控制、管理LL連接的數(shù)據(jù)包,此時(shí)Payload為1字節(jié)Opcode和剩余的控制數(shù)據(jù)

建立連接

可連接狀態(tài)的設(shè)備(Advertiser)按照一定周期廣播可連接數(shù)據(jù)包

主動(dòng)連接的設(shè)備(Initiator)收到廣播包后回應(yīng)一個(gè)連接請(qǐng)求(約定時(shí)間點(diǎn)、物理信道等)

Initiator發(fā)送完畢后進(jìn)入連接狀態(tài),成為Master

Advertiser接收到連接請(qǐng)求后也進(jìn)入連接狀態(tài),成為Slave

雙方按照參數(shù)約定,定時(shí)切換到某一物理信道,開(kāi)始依次收發(fā)數(shù)據(jù),直至連接斷開(kāi)

HCI

封裝Link Layer的功能,主要包括連接的建立、關(guān)閉、參數(shù)設(shè)置和管理,以及數(shù)據(jù)封裝和轉(zhuǎn)發(fā)

GAP

定義設(shè)備具有的能力和操作

Part808 BLE安全機(jī)制

White List

白名單就是一組藍(lán)牙地址列表,通過(guò)設(shè)置白名單可以允許掃描、連接特定的藍(lán)牙設(shè)備,以及被掃描、連接

LL Privacy

在白名單的基礎(chǔ)上將設(shè)備地址進(jìn)行加密,轉(zhuǎn)變成Resolvable Private addresses

本地Resolving List需要保存每一對(duì)BLE設(shè)備的key/address信息,格式為:Local IRK|Peer IRK|Peer Device Identity Address|Address Type

LL Privacy機(jī)制在Controller中完成,即加解密操作對(duì)HCI上層是透明的

LL Encryption

數(shù)據(jù)發(fā)送和接收過(guò)程進(jìn)行加解密

加解密操作在Link Layer完成

Host會(huì)保存至少1280bit的LTK(根密鑰),啟動(dòng)加密傳輸時(shí),LL會(huì)首先協(xié)商出一個(gè)128-bit的隨機(jī)數(shù)SDK(Session Key Diversifier)和64-bit的iv,經(jīng)過(guò)Encryption Engine和LTK生成此次通信的會(huì)話密鑰SessionKey

SecurityManager

為BLE設(shè)備提供加密連接相關(guān)的key,包含以下規(guī)范:

定義了配對(duì)(Pairing)的相關(guān)概念及過(guò)程

定義了密碼工具箱,包含配對(duì)、加密所需的各種算法

定義了安全管理協(xié)議(Security Manager Protocol,SMP),實(shí)現(xiàn)配對(duì)、密碼傳輸?shù)炔僮?/p>

SMP規(guī)范中,配對(duì)的定義是,Master和Slave通過(guò)協(xié)商確定用于加密通信的key的過(guò)程,包含三個(gè)階段:

階段一、Pairing Feature Exchange,交換雙方配對(duì)相關(guān)的設(shè)置,如配對(duì)方法、鑒權(quán)方式等

鑒權(quán)方式可以采用交換額外的信息(Out of band,OOB),或者彈窗引入人來(lái)判定,稱為MITM鑒權(quán),還有輸入配對(duì)碼進(jìn)行對(duì)比(Passkey Entry/Numeric Comparison),或者不鑒權(quán)(Just Work)

階段二、通過(guò)SMP協(xié)議進(jìn)行配對(duì)操作,有兩種配對(duì)方案,LE Legacy Pairing和LE Secure Connections

階段三、協(xié)商好密鑰key,建立加密連接,傳輸密鑰信息(可選)

Part909 Android中的BLE應(yīng)用

具體可以參考開(kāi)發(fā)的藍(lán)牙測(cè)試工具:BLETool

BLE,藍(lán)牙低功耗(極低的運(yùn)行和待機(jī)功耗)

Android 4.3(API 18) 開(kāi)始引入 BLE ,即藍(lán)牙4.0

Android 4.3 的 BLE 只支持 Central Role(中心設(shè)備,掃描并連接外圍設(shè)備)

Android 5.0 開(kāi)始同時(shí)支持 Central Role 和 Peripheral Role(外圍設(shè)備,向外廣播發(fā)送數(shù)據(jù))

1、權(quán)限

 

 

 


 


2、開(kāi)啟/關(guān)閉藍(lán)牙

//判斷支持藍(lán)牙功能
if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
//獲取藍(lán)牙管理服務(wù)
BluetoothManagerbluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
//獲取藍(lán)牙適配器
BluetoothAdapterbluetoothAdapter=bluetoothManager.getAdapter();
if(bluetoothAdapter!=null){
//判斷藍(lán)牙是否開(kāi)啟
if(bluetoothAdapter.isEnabled()){
//關(guān)閉藍(lán)牙
bluetoothAdapter.disable();
}else{
//1、靜默開(kāi)啟藍(lán)牙
bluetoothAdapter.enable();
//2、顯式請(qǐng)求開(kāi)啟藍(lán)牙
Intentintent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,REQUEST_BLUETOOTH_ENABLE);
}
}
}

3、掃描與監(jiān)聽(tīng)

if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
//獲取藍(lán)牙管理服務(wù)
BluetoothManagerbluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
//獲取藍(lán)牙適配器
BluetoothAdapterbluetoothAdapter=bluetoothManager.getAdapter();
if(bluetoothAdapter!=null){
//判斷藍(lán)牙是否開(kāi)啟
if(bluetoothAdapter.isEnabled()){
//獲取掃描器實(shí)例
BluetoothLeScannerbluetoothLeScanner=bluetoothAdapter.getBluetoothLeScanner();
booleanisScanning=false;
if(bluetoothLeScanner!=null){
if(isScanning){
//停止掃描
isScanning=false;
bluetoothLeScanner.stopScan(scanCallback);
}else{
//開(kāi)始掃描
isScanning=true;
bluetoothLeScanner.startScan(scanCallback);
}
}
}
}
}

Android 8 開(kāi)始提供一個(gè)后臺(tái)持續(xù)掃描的API,應(yīng)用殺死后也可以繼續(xù)掃描,直到關(guān)閉藍(lán)牙【待驗(yàn)證】

publicintstartScan(Listfilters,ScanSettingssettings,PendingIntentcallbackIntent);

//設(shè)置攔截器和掃描選項(xiàng)
bluetoothLeScanner.startScan(scanFilters,scanSettings,scanCallback);

初始化掃描過(guò)濾器

scanFilters=newArrayList<>();
ScanFilterscanFilter=newScanFilter.Builder()
.setDeviceName("lalala")
.setServiceUuid(newParcelUuid(UUID.randomUUID()))
.build();
scanFilters.add(scanFilter);

初始化掃描設(shè)置

scanSettings=newScanSettings.Builder()
//設(shè)置掃描模式
.setScanMode(ScanSettings.SCAN_MODE_BALANCED)
//設(shè)置回調(diào)類型
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
//設(shè)置配對(duì)模式
.setMatchMode(ScanSettings.MATCH_MODE_STICKY)
//設(shè)置報(bào)告延遲
.setReportDelay(0)
.build();

兩個(gè)類都是通過(guò) Builder 構(gòu)造,提供系列函數(shù)用于參數(shù)設(shè)置,如 setDeviceName()、setScanMode()、setMatchMode() 等

4、掃描回調(diào)

scanCallback=newScanCallback{
@Override
publicvoidonScanResult(intcallbackType,ScanResultresult){
super.onScanResult(callbackType,result);
}

@Override
publicvoidonScanFailed(interrorCode){
super.onScanFailed(errorCode);
}

@Override
publicvoidonBatchScanResults(Listresults){
super.onBatchScanResults(results);
}
}

其中 onBatchScanResults() 是批量返回掃描結(jié)果??赏ㄟ^(guò)下面的接口判斷藍(lán)牙芯片是否支持批處理

Bluetoothadapter.isOffloadedScanBatchingSupported();
1

注意 onScanResult() 和 onBatchScanResults() 是互斥的,ScanSettings 中 setReportDelay() 設(shè)置為0(默認(rèn))則通過(guò) onScanResult() 返回掃描結(jié)果,否則開(kāi)啟批處理掃描模式,并觸發(fā) onBatchScanResults() 回調(diào)。

5、廣播數(shù)據(jù)解析

掃描成功會(huì)返回 ScanResult 廣播數(shù)據(jù)類,然后進(jìn)一步解析

//返回遠(yuǎn)程設(shè)備類
BluetoothDevicedevice=scanResult.getDevice();
//返回掃描記錄,包含廣播和掃描響應(yīng)
ScanRecordscanRecord=scanResult.getScanRecord();
//返回信號(hào)強(qiáng)度,[-127,126]
intrssi=scanResult.getRssi()

BluetoothDevice 是設(shè)備信息類,常用的方法有

//獲取硬件地址
Stringaddress=device.getAddress();
//獲取藍(lán)牙名稱
Stringname=device.getName();
//獲取設(shè)備類型,如DEVICE_TYPE_CLASSIC、DEVICE_TYPE_LE、DEVICE_TYPE_DUAL、DEVICE_TYPE_UNKNOWN
inttype=device.getType();
//獲取綁定狀態(tài),如BOND_NONE、BOND_BONDING、BOND_BONDED
intstate=device.getBondState();

6、連接設(shè)備

掃描返回的廣播消息中可以獲取到遠(yuǎn)程設(shè)備的MAC地址,可用于設(shè)備的連接

if(bluetoothAdapter.isEnabled()){
//獲取遠(yuǎn)程設(shè)備對(duì)象
BluetoothDevicebluetoothDevice=bluetoothAdapter.getRemoteDevice(address);
if(bluetoothDevice!=null){
handler.post(newRunnable(){
@Override
publicvoidrun(){
BluetoothGattbluetoothGatt;
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
//連接遠(yuǎn)程設(shè)備
bluetoothGatt=bluetoothDevice.connectGatt(context,false,bluetoothGattCallback,BluetoothDevice.TRANSPORT_LE);
}else{
bluetoothGatt=bluetoothDevice.connectGatt(context,false,bluetoothGattCallback);
}
}
});
}
}

bluetoothGatt 是藍(lán)牙通用屬性協(xié)議的封裝,定義了BLE通信的一些基本規(guī)則和連接通信操作

7、連接回調(diào)

bluetoothGattCallback 則是 bluetoothGatt 連接的回調(diào)類,通知客戶端連接狀態(tài)和結(jié)果

bluetoothGattCallback=newBluetoothGattCallback{
@Override
publicvoidonConnectionStateChange(BluetoothGattgatt,finalintstatus,finalintnewState){
super.onConnectionStateChange(gatt,status,newState);
}

@Override
publicvoidonServicesDiscovered(BluetoothGattgatt,finalintstatus){
super.onServicesDiscovered(gatt,status);
}

@Override
publicvoidonCharacteristicChanged(BluetoothGattgatt,finalBluetoothGattCharacteristiccharacteristic){
super.onCharacteristicChanged(gatt,characteristic);
}

@Override
publicvoidonCharacteristicRead(BluetoothGattgatt,finalBluetoothGattCharacteristiccharacteristic,finalintstatus){
super.onCharacteristicRead(gatt,characteristic,status);
}

@Override
publicvoidonCharacteristicWrite(BluetoothGattgatt,finalBluetoothGattCharacteristiccharacteristic,finalintstatus){
super.onCharacteristicWrite(gatt,characteristic,status);
}

@Override
publicvoidonDescriptorRead(BluetoothGattgatt,finalBluetoothGattDescriptordescriptor,finalintstatus){
super.onDescriptorRead(gatt,descriptor,status);
}

@Override
publicvoidonDescriptorWrite(BluetoothGattgatt,finalBluetoothGattDescriptordescriptor,finalintstatus){
super.onDescriptorWrite(gatt,descriptor,status);
}
}

連接成功及其他連接狀態(tài)改變都會(huì)調(diào)用 onConnectionStateChange() 方法。status 表示這個(gè)操作的狀態(tài),是 BluetoothGatt.GATT_SUCCESS 或者讀寫(xiě)受限、超過(guò)范圍等其他錯(cuò)誤狀態(tài)。newState 則表示當(dāng)前設(shè)備的連接狀態(tài),連接成功為 BluetoothProfile.STATE_CONNECTED,連接失敗是BluetoothProfile.STATE_DISCONNECTED。

8、發(fā)現(xiàn)服務(wù)

連接成功后就可以開(kāi)始通信,從請(qǐng)求服務(wù)開(kāi)始(Profile只是一系列具有共同業(yè)務(wù)需求的服務(wù)的抽象集合,服務(wù)才是實(shí)體)

bluetoothGatt.discoverServices();
1

發(fā)現(xiàn)服務(wù)后會(huì)觸發(fā) onServicesDiscovered() 回調(diào),然后繼續(xù)獲取服務(wù)

//獲取所有服務(wù)
ListbleServiceList=bluetoothGatt.getServices();
//通過(guò)uuid獲取特定的服務(wù)
BluetoothGattServicebleService=bluetoothGatt.getService(serviceUuid);

BluetoothGattService 是藍(lán)牙服務(wù)類,是與某個(gè)場(chǎng)景相關(guān)的一系列行為的抽象,具有一個(gè)唯一的UUID,然后服務(wù)類型,如SERVICE_TYPE_PRIMARY、SERVICE_TYPE_SECONDARY(主要服務(wù)可以包含二級(jí)服務(wù)),包含的特征列表

9、獲取特征

//獲取所有特征
ListbleCharacteristicList=bleService.getCharacteristics();
//通過(guò)uuid獲取特定的特征
BluetoothGattCharacteristicbleCharacteristic=bleService.getCharacteristic(characteristicUuid);

BluetoothGattCharacteristic 是藍(lán)牙特征類,是通信的基本數(shù)據(jù)單位,包含標(biāo)志特征的唯一的UUID,描述特征訪問(wèn)權(quán)限的特性,如PROPERTY_BROADCAST、PROPERTY_READ、PROPERTY_WRITE等,特征的實(shí)際取值,以及特征的描述

10、讀寫(xiě)特征

//讀取特征
bluetoothGatt.readCharacteristic(bleCharacteristic);
//設(shè)置并寫(xiě)入特征
bleCharacteristic.setValue("XXX");
bluetoothGatt.writeCharacteristic(bleCharacteristic);

這里的讀寫(xiě)特征函數(shù)都是返回布爾類型表示是否操作成功,如果成功真正的值會(huì)在 onCharacteristicRead/onCharacteristicWrite 回調(diào)中讀取/寫(xiě)入

@Override
publicvoidonCharacteristicRead(BluetoothGattgatt,BluetoothGattCharacteristiccharacteristic,intstatus){
switch(status){
caseGATT_SUCCESS:
StringvalueStr=BLEUtils.byte2HexString(characteristic.getValue());
break;
caseGATT_READ_NOT_PERMITTED:
ToastUtils.showShort(context,"GATT_READ_NOT_PERMITTED");
break;
default:
ToastUtils.showShort(context,"CHARACTERISTIC_READ_FAILED");
break;
}
}

@Override
publicvoidonCharacteristicWrite(BluetoothGattgatt,BluetoothGattCharacteristiccharacteristic,intstatus){
switch(status){
caseGATT_SUCCESS:
StringvalueStr=BLEUtils.byte2HexString(characteristic.getValue());
break;
default:
ToastUtils.showShort(context,"CHARACTERISTIC_WRITE_FAILED");
break;
}
}

11、監(jiān)聽(tīng)特征

真正要實(shí)現(xiàn)通信除了單方面讀寫(xiě),還需要對(duì)數(shù)據(jù)變化進(jìn)行監(jiān)聽(tīng),這樣就可以進(jìn)行數(shù)據(jù)交換

//設(shè)置特征監(jiān)聽(tīng)為true,且要求特征具有NOTIFY屬性
bluetoothGatt.setCharacteristicNotification(characteristic,true);

這樣,自己或?qū)Ψ教卣鞲淖儠r(shí)就會(huì)回調(diào)函數(shù)從而獲取改變后的特征值

@Override
publicvoidonCharacteristicChanged(BluetoothGattCharacteristiccharacteristic){
Log.d("bledemo","uuid="+characteristic.getUuid().toString());
Log.d("bledemo","value=0x"+BLEUtils.byte2HexString(characteristic.getValue()));
}

12、獲取描述

//獲取所有描述
ListbleDescriptorList=bleCharacteristic.getDescriptors();
//通過(guò)uuid獲取特定的描述
BluetoothGattDescriptorbleDescriptor=bleCharacteristic.getDescriptor(descriptorUuid);

BluetoothGattDescriptor 是藍(lán)牙特征描述類,包含對(duì)特征的一些額外描述信息

13、讀寫(xiě)描述

//讀取描述
bluetoothGatt.readDescriptor(bleDescriptor);
//設(shè)置并寫(xiě)入描述
bleDescriptor.setValue("XXX");
bluetoothGatt.writeDescriptor(bleDescriptor);

同樣讀寫(xiě)成功會(huì)觸發(fā)onDescriptorRead/onDescriptorWrite 回調(diào)

@Override
publicvoidonDescriptorRead(BluetoothGattDescriptordescriptor,intstatus){
switch(status){
caseGATT_SUCCESS:
StringvalueStr=BLEUtils.byte2HexString(descriptor.getValue());
break;
caseGATT_READ_NOT_PERMITTED:
ToastUtils.showShort(context,"GATT_READ_NOT_PERMITTED");
break;
default:
ToastUtils.showShort(context,"DESCRIPTOR_READ_FAILED");
break;
}
}

@Override
publicvoidonDescriptorWrite(BluetoothGattDescriptordescriptor,intstatus){
switch(status){
caseGATT_SUCCESS:
StringvalueStr=BLEUtils.byte2HexString(descriptor.getValue());
break;
default:
ToastUtils.showShort(context,"DESCRIPTOR_WRITE_FAILED");
break;
}
}

14、斷開(kāi)連接

//斷開(kāi)連接,會(huì)觸發(fā)onConnectionStateChange()回調(diào)
bluetoothGatt.disconnect();
//關(guān)閉連接,不會(huì)觸發(fā)回調(diào)
bluetoothGatt.close();
1234

15、開(kāi)啟/關(guān)閉廣播

if(bluetoothAdapter.isEnabled()){
//設(shè)置廣播設(shè)備的名稱,方便搜索
bluetoothAdapter.setName("XXX");
//獲取廣播類
BluetoothLeAdvertiserbluetoothLeAdvertiser=bluetoothAdapter.getBluetoothLeAdvertiser();
if(bluetoothLeAdvertiser!=null){
if(isAdvertising){
//關(guān)閉廣播
bluetoothLeAdvertiser.stopAdvertising(advertiseCallback);
}else{
//開(kāi)始廣播
bluetoothLeAdvertiser.startAdvertising(advertiseSetting,advertiseData,advertiseCallback);
}
}
}

還可以發(fā)送帶響應(yīng)報(bào)文的廣播包

bluetoothLeAdvertiser.startAdvertising(advertiseSetting,advertiseData,advertiseResData,advertiseCallback);
1

其中 advertiseSetting 為廣播設(shè)置類對(duì)象

advertiseSetting=newAdvertiseSettings.Builder()
//廣播模式,控制廣播功率和延遲
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
//廣播發(fā)射功率級(jí)別
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
//廣播超時(shí)時(shí)間,最大值為3*60*1000毫秒,為0時(shí)禁用超時(shí),默認(rèn)無(wú)限廣播
.setTimeout(advertiseTimeout)
//廣播連接類型
.setConnectable(true)
.build();
12345678910

advertiseData、advertiseResData 為廣播包

advertiseData=newAdvertiseData.Builder()
//廣播是否包含設(shè)備名稱
.setIncludeDeviceName(true)
//廣播是否包含發(fā)射功率
.setIncludeTxPowerLevel(true)
//添加服務(wù)uuid
.addServiceUuid(newParcelUuid(UUID.randomUUID()))
.build();

advertiseResData=newAdvertiseData.Builder()
//添加自定義服務(wù)數(shù)據(jù)
.addServiceData(newParcelUuid(UUID.randomUUID()),newbyte[]{1,2,3,4})
//添加自定義廠商數(shù)據(jù)
.addManufacturerData(0x06,newbyte[]{5,6,7,8})
.build();

16、廣播回調(diào)

advertiseCallback 是廣播回調(diào)

advertiseCallback=newAdvertiseCallback{
@Override
publicvoidonStartSuccess(AdvertiseSettingssettingsInEffect){
super.onStartSuccess(settingsInEffect);
}

@Override
publicvoidonStartFailure(interrorCode){
super.onStartFailure(errorCode);
}
}

17、啟動(dòng)GATT服務(wù)

只有廣播仍然不夠,作為外圍角色的設(shè)備還需要啟動(dòng)GATT服務(wù),等待中心設(shè)備與之建立連接之后就可以通過(guò)服務(wù)通信

//啟動(dòng)Gatt服務(wù)
bluetoothGattServer=bluetoothManager.openGattServer(context,bluetoothGattServerCallback);
12

接下來(lái)可以向啟動(dòng)的GATT服務(wù)中添加Service

//構(gòu)造服務(wù)
BluetoothGattServicebluetoothGattService=newBluetoothGattService(UUID.randomUUID(),BluetoothGattService.SERVICE_TYPE_PRIMARY);

//構(gòu)造特征
BluetoothGattCharacteristicbluetoothGattCharacteristic=newBluetoothGattCharacteristic(UUID.randomUUID(),BluetoothGattCharacteristic.PROPERTY_READ|BluetoothGattCharacteristic.PERMISSION_WRITE|BluetoothGattCharacteristic.PROPERTY_NOTIFY,BluetoothGattCharacteristic.PERMISSION_WRITE|BluetoothGattCharacteristic.PERMISSION_READ);
bluetoothGattCharacteristic.setValue("character_test_value");

//構(gòu)造描述
BluetoothGattDescriptorbluetoothGattDescriptor=newBluetoothGattDescriptor(UUID.randomUUID(),BluetoothGattDescriptor.PERMISSION_READ|BluetoothGattDescriptor.PERMISSION_WRITE);
bluetoothGattDescriptor.setValue("descriptor_test_value".getBytes());

//添加描述到特征中
bluetoothGattCharacteristic.addDescriptor(bluetoothGattDescriptor);
//添加特征到服務(wù)中
bluetoothGattService.addCharacteristic(bluetoothGattCharacteristic);
//添加服務(wù)
bluetoothGattServer.addService(bluetoothGattService);

18、GATT服務(wù)回調(diào)

bluetoothGattServerCallback 是GATT服務(wù)的回調(diào),當(dāng)設(shè)備被連接、通信(讀寫(xiě)特征)時(shí)都會(huì)觸發(fā)響應(yīng)的回調(diào)函數(shù)

bluetoothGattServerCallback=newBluetoothGattServerCallback{
@Override
publicvoidonConnectionStateChange(BluetoothDevicedevice,intstatus,intnewState){
super.onConnectionStateChange(device,status,newState);
}

@Override
publicvoidonServiceAdded(intstatus,BluetoothGattServiceservice){
super.onServiceAdded(status,service);
}

@Override
publicvoidonCharacteristicReadRequest(BluetoothDevicedevice,intrequestId,intoffset,
BluetoothGattCharacteristiccharacteristic){
super.onCharacteristicReadRequest(device,requestId,offset,characteristic);
}

@Override
publicvoidonCharacteristicWriteRequest(BluetoothDevicedevice,intrequestId,
BluetoothGattCharacteristiccharacteristic,
booleanpreparedWrite,booleanresponseNeeded,
intoffset,byte[]value){
super.onCharacteristicWriteRequest(device,requestId,characteristic,preparedWrite,
responseNeeded,offset,value);
}

@Override
publicvoidonDescriptorReadRequest(BluetoothDevicedevice,intrequestId,
intoffset,BluetoothGattDescriptordescriptor){
super.onDescriptorReadRequest(device,requestId,offset,descriptor);
}

@Override
publicvoidonDescriptorWriteRequest(BluetoothDevicedevice,intrequestId,
BluetoothGattDescriptordescriptor,
booleanpreparedWrite,booleanresponseNeeded,
intoffset,byte[]value){
super.onDescriptorWriteRequest(device,requestId,descriptor,preparedWrite,responseNeeded,
offset,value);
}


@Override
publicvoidonNotificationSent(BluetoothDevicedevice,intstatus){
super.onNotificationSent(device,status);
}




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 藍(lán)牙技術(shù)
    +關(guān)注

    關(guān)注

    44

    文章

    336

    瀏覽量

    52745
  • BLE協(xié)議棧
    +關(guān)注

    關(guān)注

    0

    文章

    5

    瀏覽量

    4734
  • EDR
    EDR
    +關(guān)注

    關(guān)注

    0

    文章

    23

    瀏覽量

    1957
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    高通優(yōu)化藍(lán)牙5.0協(xié)議,藍(lán)牙耳機(jī)用戶體驗(yàn)將增加

    雖然藍(lán)牙耳機(jī)使用起來(lái)比有線耳機(jī)更加方便,但音質(zhì)可能稍有欠缺,還得擔(dān)心耳機(jī)的續(xù)航問(wèn)題。但憑借著上周發(fā)布的驍龍845處理器,高通想要對(duì)藍(lán)牙音頻帶來(lái)一些提升。除了支持更穩(wěn)定的藍(lán)牙5.0
    的頭像 發(fā)表于 01-11 09:32 ?7735次閱讀

    程序員必須要了解藍(lán)牙協(xié)議規(guī)范?

    藍(lán)牙規(guī)范包括核心協(xié)議與應(yīng)用框架兩個(gè)文件。一部分協(xié)議規(guī)范還定義了藍(lán)牙各層通信協(xié)議,應(yīng)用框架指的是如何應(yīng)用這些
    發(fā)表于 10-19 18:23

    主流協(xié)議族TCP/IP協(xié)議,對(duì)此了解多少

    主流協(xié)議族TCP/IP協(xié)議,對(duì)此了解多少現(xiàn)在Internet(因特網(wǎng))使用的主流協(xié)議族是TCP/IP協(xié)
    發(fā)表于 08-27 16:13

    詳解那個(gè)不盡知的BLE藍(lán)牙

    提起物聯(lián)網(wǎng)無(wú)線連接技術(shù),相信大家都知道藍(lán)牙,而對(duì)物聯(lián)網(wǎng)領(lǐng)域了解不深的朋友很容易對(duì)傳統(tǒng)藍(lán)牙和低功耗藍(lán)牙(BLE)混淆,甚至以為這兩個(gè)名詞指的是同一事物,其實(shí)不然。本文將分享關(guān)于BLE的一
    發(fā)表于 10-17 17:12

    利用藍(lán)牙技術(shù)實(shí)現(xiàn)的這些功能,了解幾個(gè)?

    `藍(lán)牙是很基本數(shù)據(jù)傳輸工具,可以實(shí)現(xiàn)藍(lán)牙設(shè)備之間的無(wú)線傳輸,但是隨著智能機(jī)的出現(xiàn),很多人覺(jué)得現(xiàn)在的手機(jī)藍(lán)牙功能很雞肋,其實(shí)藍(lán)牙還有很多強(qiáng)大功能,只是
    發(fā)表于 03-07 17:06

    CC2540的應(yīng)用是否需要全面了解藍(lán)牙協(xié)議

    現(xiàn)在打算用這個(gè)IC來(lái)開(kāi)發(fā)一些產(chǎn)品,但是感覺(jué)入門(mén)挺高的,不知如何下手。請(qǐng)各位指導(dǎo)一二!用這個(gè)來(lái)開(kāi)發(fā),是否需要全面了解藍(lán)牙協(xié)議,對(duì)于藍(lán)牙協(xié)議,該
    發(fā)表于 08-19 07:39

    關(guān)于藍(lán)牙協(xié)議棧的應(yīng)用

    新手剛學(xué)藍(lán)牙,想問(wèn)開(kāi)源的藍(lán)牙協(xié)議棧是對(duì)于所有的藍(lán)牙芯片通用嗎?比如我有 ATSAMB11XR/ZR藍(lán)牙芯片,我能使用Btstack
    發(fā)表于 08-01 10:34

    了解下Wi-Fi、Zigbee、Thread 、藍(lán)牙等這些協(xié)議

    了解下Wi-Fi、Zigbee、Thread 、藍(lán)牙等這些協(xié)議都是 2.4 GHz ISM 頻段,為何不是其他的頻段,比如2.8G,3.4G等頻段
    發(fā)表于 10-24 15:00

    聽(tīng)過(guò)藍(lán)牙的知識(shí)產(chǎn)權(quán)嗎?關(guān)于藍(lán)牙的知識(shí)產(chǎn)權(quán)了解多少?

    聽(tīng)過(guò)藍(lán)牙的知識(shí)產(chǎn)權(quán)嗎?關(guān)于藍(lán)牙的知識(shí)產(chǎn)權(quán)了解多少?藍(lán)牙的測(cè)試認(rèn)證可以分為哪幾個(gè)方向?
    發(fā)表于 06-17 08:04

    CAN-FD協(xié)議了解多少

    關(guān)注+星標(biāo)公眾號(hào),不錯(cuò)過(guò)精彩內(nèi)容來(lái)源 |安富萊電子編排 |strongerHuang之前給大家分享過(guò)很多關(guān)于CAN的文章:CANOpen系列教程CAN-FD協(xié)議了解多少?第三代CAN...
    發(fā)表于 08-19 08:13

    藍(lán)牙協(xié)議棧iAP和AAP區(qū)別

    藍(lán)牙協(xié)議棧iAP和AAP區(qū)別一,iAP Profile:iPod Accesory Profile,Apple外設(shè)通訊協(xié)議Brief: 可以理解為蘋(píng)果手機(jī)的SPP協(xié)議,且很多蘋(píng)果手機(jī)特
    發(fā)表于 04-11 09:26

    藍(lán)牙協(xié)議測(cè)試

    藍(lán)牙協(xié)議測(cè)試 “藍(lán)牙質(zhì)量鑒定程序”方面的詳細(xì)協(xié)議測(cè)試對(duì)每個(gè)投放市場(chǎng)的新無(wú)線電模塊來(lái)說(shuō)是絕對(duì)必要的。本文結(jié)合精確設(shè)
    發(fā)表于 09-17 10:56 ?1939次閱讀
    <b class='flag-5'>藍(lán)牙</b><b class='flag-5'>協(xié)議</b>測(cè)試

    使用串口模塊需要了解藍(lán)牙協(xié)議

    家電產(chǎn)品等。未來(lái),隨著價(jià)格便宜、質(zhì)量穩(wěn)定、供貨穩(wěn)定的國(guó)產(chǎn)藍(lán)牙串口模塊的市場(chǎng)占有率逐步提高,必將進(jìn)一步提高整個(gè)電子產(chǎn)品行業(yè)的智能化和物聯(lián)化。關(guān)于藍(lán)牙串口模塊QAQ:使用串口模塊需要了解藍(lán)牙
    的頭像 發(fā)表于 11-15 18:12 ?4032次閱讀

    CAN-FD協(xié)議了解多少 ?

    CAN-FD協(xié)議了解多少?
    的頭像 發(fā)表于 03-08 15:40 ?1.6w次閱讀

    藍(lán)牙協(xié)議版本解析:不同類型的藍(lán)牙協(xié)議及其作用

    藍(lán)牙技術(shù)作為一種無(wú)線通信技術(shù),隨著時(shí)間的推移不斷發(fā)展演進(jìn)。不同的藍(lán)牙協(xié)議版本為各類設(shè)備提供了不同的功能和應(yīng)用特性。本文將深入解析不同類型的藍(lán)牙協(xié)議
    的頭像 發(fā)表于 12-28 11:17 ?1643次閱讀