---
# System prepended metadata

title: Bluetooth LE Study Notes
tags: [HID, Bluetooth LE, BLE]

---

# Bluetooth LE Study Notes
![](https://i.imgur.com/BsaRqrY.jpg)


內容都是自己K書看來的，有錯請告知，謝謝。 :smile::laughing::smiley:

1. LeetCode解題心得：https://app.gitbook.com/@stanley7342/s/programming/
2. FreeRTOS筆記：https://hackmd.io/@stanley7342/freertos_note
3. G3-PLC筆記：https://hackmd.io/@stanley7342/g3plc_note

# Table of Contents
[TOC]

# Overview
![](https://i.imgur.com/JUWMBGH.jpg)
* 低功耗藍牙分為三個部分：應用(Application)、主機(Host)、控制器(Controller)。
* 應用(Application)通常是某種應用服務的規範，舉個例子，如果是要做心率應用就需要看Heart Rate Profile，如果是要做低功耗藍芽鍵盤滑鼠就要看HID Over GATT Profile等。
* 主機(Host)包含Generic Access Profile(GAP)、Generic Attribute Profile(GATT)、Attribute Protocol(ATT)、Logical Link Control and Adaptation Protocol(L2CAP)及Security Manager(SM)。
* 控制器(Controller)包含Link Layer(LL)和Physical Layer。
* 在主機和控制器之間的介面叫作Host Controller Interface(HCI)。
# HID Over GATT Profile
## Specification Reference
* HID Over GATT Profile specification v1.0
* HID Service specification v1.0
* Battery Service specification v1.0
* Device Information Service specification v1.0
* Scan Parameters Service specification v1.0
* Scan Parameters Profile specification v1.0
* Device Class Deifnition for Human Interface Devices (HID) v1.11
* HID Usage Tables v1.12
* Bluetooth Core specification version 4.2

## Introduction
* 定義了3種Roles
    * HID Device為GATT Server (GAP Peripheral)
    * Boot Host為GATT Client (GAP Central)
    * Report Host為GATT Client (GAP Central)
* Boot Protocol和Report Protocol的區別：
以USB HID協議來說，如果你的HID裝置是鍵盤或滑鼠，那麼是可以設置Boot Protocol Mode，這樣PC在啟動後，運行到BIOS時，就可以識別你的鍵盤或滑鼠，而不用等到整個作業系統啟動後，在透過USB Emulation來識別裝置，因為Boot Protocol不需要解析Report Descriptor，它的數據格式是固定的，按照它的格式發送數據就可以直接被解析為滑鼠的指標在移動或是按下鍵盤的按鍵，當作業系統啟動後，PC就會重置USB設備，設置為Report Protocol Mode，因為USB Host的Emulation就會解析HID裝置的Report Descriptor，這個時候就可以依照自定義的格式來傳輸滑鼠或鍵盤的數據，而不是用Boot Protocol固定的數據格式。

## Service UUIDs
Service Declaration
* HID Service - <0x1812>
* Battery Service - <0x180F>
* Device Information Service - <0x180A>
* ~~Scan Parameter Service - <0x1813>~~
* Generic Access Profile - <0x1800>
* Generic Attribute Protocol - <0x1801>

首先Host用Read By Group Type Request來查找Service Declaration。
![](https://i.imgur.com/mDKTZAH.png)

因此得到了Generic Access Profile、Generic Attribute Protocol及Device Information Service。
![](https://i.imgur.com/o0ilrVl.png)

以此類推，一樣又得到了Battery Service和HID Service。
![](https://i.imgur.com/u7vImMG.png)

## Characteristic UUIDs
HID Characteristic Declaration
![](https://i.imgur.com/XFWUCWk.png)
* Protocol Mode - <0x2A4E>
* Report - <0x2A4D>
* Report Map - <0x2A4B>
* Boot Keyboard Input Report - <0x2A22>
* Boot Keyboard Output Report - <0x2A32>
* Boot Mouse Input Report - <0x2A33>
* HID Information - <0x2A4A>
* HID Control Point - <0x2A4C>
    
HID Host (GATT Client)對HID Device (GATT Server)傳送Read By Type Request，尋找Handle範圍0x0014-0xFFFF之間有什麼Characteristic Declaration，Characteristic的UUID為0x2803。
![](https://i.imgur.com/eaFTKvr.png)

HID Device (GATT Server)對HID Host (GATT Client)回應Read By Type Response，其中帶有三個Characteristic，但是因為ATT_MTU大小有限(預設23 octets)，所以會分很多回合來查找。
![](https://i.imgur.com/ma3oKri.png)

分析如何看Attribute Value，以Wireshark Byte Order排列的方式是LSB先。
* Characteristic Properties (1 octet)
![](https://i.imgur.com/e8SUZLq.png)

* Characteristic Value Handle (2 octets)
* Characteristic UUID (2 octets)

來看一下Specification的描述
![](https://i.imgur.com/aRG3bHJ.png)
![](https://i.imgur.com/T3lA4Wh.png)

上面有找到Handle 0x0016為Protocol Mode Characteristic，Host使用Read Request來讀取Attribute。
![](https://i.imgur.com/gqiOzhC.png)

因此可以看到HID Device回應的Read Response，其中Characteristic Value是0x01
![](https://i.imgur.com/ttXe7jI.png)

由下圖可知，我們可以看到Protocol Mode，0x00為Boot Protocol Mode，0x01為Report Protocol Mode，所以目前使用的是Report Protocol Mode，之後Host應該會跟Device要Report Map。
![](https://i.imgur.com/k3FzxG9.png)

我們知道在之前有發現Handle 0x0018為Report Characteristic，以HID Service Specification規範來說，可以猜測接下來會有Client Characteristic Configuration的Characteristic Descriptor和Report Reference Descriptor，Host使用Find Information Request對Handle 0x0019和Handle 0x001a尋找。
![](https://i.imgur.com/ZaVaWy9.png)

得知Handle 0x0019為Client Characteristic Configuration，Handle 0x001a為Report Reference。
![](https://i.imgur.com/Es0hlRO.png)

Host得知Handle 0x001a後，使用Read Request來讀取值。
![](https://i.imgur.com/xxTxnS8.png)

由HID Service Specification得知Report Type
* 0x01: Input Report
* 0x02: Output Report
* 0x03: Feature Report
![](https://i.imgur.com/nuk0ULH.png)

因為Wireshark是以LSB先的Byte Order呈現，因此得到結果為Input Report。
![](https://i.imgur.com/EdbXIlS.png)

在前面一樣有發現另一個Report Characteristic，其Handle為0x001c，因此一樣會得到另一個Report Reference Descriptor，但是沒有Client Characteristic Configuration Descriptor，通常要有Notify的property的Characteristic才會有。
![](https://i.imgur.com/mLL5Fip.png)

得到另一個Report為Output Report。
![](https://i.imgur.com/kDKMJd0.png)

同樣的方法，我們找到另一組Report、Report Map和Boot Keyboard Input Report。
![](https://i.imgur.com/JsAgJNj.png)

然而，又可以找到Boot Keyboard Output Report、HID Information和HID Control Point。
![](https://i.imgur.com/YmUou3n.png)

一樣去讀取Handle 0x0029，可以得到HID Information的數據。
![](https://i.imgur.com/FETqVTs.png)

分析一下HID Information有哪些欄位。
![](https://i.imgur.com/nhWEzWR.png)
* bcdHID可以知道是HID specification的版本。
* bCountryCode是在哪個國家，硬體通常是0x00。
* Flags
    * Bit 0用來表示設備是否支援Remote Wake up功能。
    * Bit 1用來表示當設備綁定過但沒有處於連線狀態時，是否使用一般正常廣播模式。

至於HID Control Point功能沒有範例，因為手邊沒有Sniffer分析儀之類的設備，但是按照我的理解是，用來通知設備進入Suspend或Resume。
![](https://i.imgur.com/KsO9U5i.png)
* 如果PC進入休眠，通知滑鼠鍵盤進入Suspend，
* 如果PC被喚醒，通知滑鼠鍵盤退出Suspend (Resume)。

然而一般消費類設備不可能只存在一種Service，其他的Service也離不開這些協定，只要搞懂這些，依然可以解析出來這些Attribute的功用是什麼。

## GATT Sub-Procedure Requirements
如果只是要實現HID設備(GATT Server)，最少的GATT協定需求如下，GATT層的Specification會說明GATT Sub-Procedure相對應的Attribute Protocol。
![](https://i.imgur.com/cqVQxjO.png)

## Report Map (Nordic nRF52840)
來分析一下Nordic nRF52840 HID Keyboard sample code中的Report Map，這邊是定義鍵盤的規格，如何跟PC溝通，使用多少資訊跟PC溝通，以及設備上有支援那些功能，這邊沒定義好的話，在Windows上會顯示驅動錯誤。
![](https://i.imgur.com/MHBh1yD.jpg)

```c=87
static uint8_t report_map_data[] =
{
  0x05, 0x01,       // Usage Page (Generic Desktop)
  0x09, 0x06,       // Usage (Keyboard)
  0xA1, 0x01,       // Collection (Application)
  0x05, 0x07,       // Usage Page (Key Codes)
  0x19, 0xe0,       // Usage Minimum (224)
  0x29, 0xe7,       // Usage Maximum (231)
  0x15, 0x00,       // Logical Minimum (0)
  0x25, 0x01,       // Logical Maximum (1)
  0x75, 0x01,       // Report Size (1)
  0x95, 0x08,       // Report Count (8)
  0x81, 0x02,       // Input (Data, Variable, Absolute)
  0x95, 0x01,       // Report Count (1)
  0x75, 0x08,       // Report Size (8)
  0x81, 0x01,       // Input (Constant) reserved byte(1)
  0x95, 0x05,       // Report Count (5)
  0x75, 0x01,       // Report Size (1)
  0x05, 0x08,       // Usage Page (Page# for LEDs)
  0x19, 0x01,       // Usage Minimum (1)
  0x29, 0x05,       // Usage Maximum (5)
  0x91, 0x02,       // Output (Data, Variable, Absolute), Led report
  0x95, 0x01,       // Report Count (1)
  0x75, 0x03,       // Report Size (3)
  0x91, 0x01,       // Output (Data, Variable, Absolute), Led report padding
  0x95, 0x06,       // Report Count (6)
  0x75, 0x08,       // Report Size (8)
  0x15, 0x00,       // Logical Minimum (0)
  0x25, 0x65,       // Logical Maximum (101)
  0x05, 0x07,       // Usage Page (Key codes)
  0x19, 0x00,       // Usage Minimum (0)
  0x29, 0x65,       // Usage Maximum (101)
  0x81, 0x00,       // Input (Data, Array) Key array(6 bytes)
  0x09, 0x05,       // Usage (Vendor Defined)
  0x15, 0x00,       // Logical Minimum (0)
  0x26, 0xFF, 0x00, // Logical Maximum (255)
  0x75, 0x08,       // Report Size (8 bit)
  0x95, 0x02,       // Report Count (2)
  0xB1, 0x02,       // Feature (Data, Variable, Absolute)
  0xC0              // End Collection (Application)
};
```
先前有找到Handle 0x0022為Report Map Characteristic，因此Host可以使用Read Request搭配Read Blob Request來讀取全部的Report Map，因為Report Map通常都是很長的一串數據，而且ATT_MTU預設為23 otects，所以要讀取長的Characteristic Descriptor，必須使用Read Blob Request，理論上讀回來的數據應該跟上面提供的代碼一致。
![](https://i.imgur.com/NLlW8ny.png)

因為ATT_MTU為23 octets，因此只讀回opcode佔1 octet和value佔22 octets。
![](https://i.imgur.com/GIznbO4.png)

對應代碼為，第1個byte至第22個byte。
```c=89
  0x05, 0x01,       // Usage Page (Generic Desktop)
  0x09, 0x06,       // Usage (Keyboard)
  0xA1, 0x01,       // Collection (Application)
  0x05, 0x07,       // Usage Page (Key Codes)
  0x19, 0xe0,       // Usage Minimum (224)
  0x29, 0xe7,       // Usage Maximum (231)
  0x15, 0x00,       // Logical Minimum (0)
  0x25, 0x01,       // Logical Maximum (1)
  0x75, 0x01,       // Report Size (1)
  0x95, 0x08,       // Report Count (8)
  0x81, 0x02,       // Input (Data, Variable, Absolute)
```

接下來要讀取的數據是要銜接先前的佔了22 octets的數據，而數據第一個byte是從0開始，因此需要使用Read Blob Request然後offset從22開始，也就是從23 byte開始讀取。
![](https://i.imgur.com/94LLzby.png)

收到Read Blob Response。
![](https://i.imgur.com/eT0bePe.png)

對應代碼為，第23個byte至第44個byte。
```c=+
  0x95, 0x01,       // Report Count (1)
  0x75, 0x08,       // Report Size (8)
  0x81, 0x01,       // Input (Constant) reserved byte(1)
  0x95, 0x05,       // Report Count (5)
  0x75, 0x01,       // Report Size (1)
  0x05, 0x08,       // Usage Page (Page# for LEDs)
  0x19, 0x01,       // Usage Minimum (1)
  0x29, 0x05,       // Usage Maximum (5)
  0x91, 0x02,       // Output (Data, Variable, Absolute), Led report
  0x95, 0x01,       // Report Count (1)
  0x75, 0x03,       // Report Size (3)
```

接下來的數據，以此類推。
![](https://i.imgur.com/oPhphcx.png)

對應代碼為，第45個byte至第66個byte。
```c=+
  0x91, 0x01,       // Output (Data, Variable, Absolute), Led report padding
  0x95, 0x06,       // Report Count (6)
  0x75, 0x08,       // Report Size (8)
  0x15, 0x00,       // Logical Minimum (0)
  0x25, 0x65,       // Logical Maximum (101)
  0x05, 0x07,       // Usage Page (Key codes)
  0x19, 0x00,       // Usage Minimum (0)
  0x29, 0x65,       // Usage Maximum (101)
  0x81, 0x00,       // Input (Data, Array) Key array(6 bytes)
  0x09, 0x05,       // Usage (Vendor Defined)
  0x15, 0x00,       // Logical Minimum (0)
```

接下來的數據，以此類推。
![](https://i.imgur.com/JIIh8tK.png)

對應代碼為，第67個byte至第76個byte。
```c=+
  0x26, 0xFF, 0x00, // Logical Maximum (255)
  0x75, 0x08,       // Report Size (8 bit)
  0x95, 0x02,       // Report Count (2)
  0xB1, 0x02,       // Feature (Data, Variable, Absolute)
  0xC0              // End Collection (Application)
```
# Link Layer (LL)
Link Layer定義了兩個設備如何利用RF傳輸訊息，包含Advertising Channel PDU、Data Channel PDU定義，也規定如何發現其他設備的流程、廣播的數據、連接的建立、連接的管理及連接中的數據傳輸。
## Frequency Bands
有別於Classic Bluetooth，Bluetooth LE一樣使用2.4 GHz ISM頻段，但分為40個RF Channels，每個Channel頻寬為2 MHz

| Regulatory Range | RF Channels                          | 
| ---------------- | ------------------------------------ | 
| 2.400-2.4835 GHz | f = 2402 + k * 2 MHz, k = 0, ..., 39 | 

## Link Layer States
* Standby State
* Advertising State
* Scanning State State
    * Active Scanning
    * Passive Scanning 
* Initiating State
* Connection State
    * Master
    * Slave
![](https://i.imgur.com/k16XbAj.png)

## Physical Channel
40個RF Channels又分為兩種Physical Channels
* Advertising Physical Channel
    * discovering devices
    * initiating a connection
    * broadcasting data
* Data Physical Channel
    * communication between connected devices

## Advertising and Data Channel Indices
以下是RF Channel及Avertising Channel、Data Channel對應
![](https://i.imgur.com/ukomTyQ.png)
* Data Channel index為0-36
* Advertising Channel index為37、38、39

![](https://i.imgur.com/c9w8DRN.png)
* Advertising Channel index選擇點原則上是為了避開Wi-Fi接入點的干擾，Wi-Fi接入點通常是Channel 1、Channel 6和Channel 11，這幾個接入點的中心頻率分別為2412MHz、2437MHz、2462MHz，頻寬為20MHz，這表示說Channel 1佔據了2402MHz~2422MHz，Channel 6佔據了2427MHz~2447MHz，Channel 11佔據了2452MHz~2472MHz。
## Packet Format
* Bluetooth LE Link Layer只有一種封包格式，可以用在
    * Advertising Channel Packet
    * Data Channel Packet
* 封包格式的欄位分別為，Preamble、Access Address、PDU、CRC
![](https://i.imgur.com/cUuW7ZG.png)

### Preamble
* 主要是讓Receiver用於
    * Frequency Synchronization
    * Symbol Timing Estimation
    * Automatic Gain Control
* Advertising Channel Packet的Preamble應該用10101010~b~
* Data Channel Packet的Preamble要取決於Access Address
    * 如果Access Address的LSB為1，Preamble就為01010101~b~
    * 如果Access Address的LSB為0，Preamble就為10101010~b~

### Access Address
* 所有的Advertising Channel Packet的Access Address都要為0x8E89BED6
![](https://i.imgur.com/2MHCRb8.png)

* Data Channel Packet的Access Address在Initiator State產生，並由CONNECT_REQ送出，須遵守以下規則
    * 不能超過6個連續的0或1
    * 不能跟Advertising Channel Packet的Access Address一樣
    * 也不能跟Advertising Channel Packet的Access Address只差1個bit
    * Access Address的4個byte不能是一樣的
    * 沒看懂！

### PDU
* 可分為Advertising Channel PDU和Data Channel PDU
* 在Advertising Physical Channel傳送的封包要使用Advertising Channel PDU
* 在Data Physical Channel傳送的封包要使用Data Channel PDU

### CRC
* 24-bit CRC
* CRC從PDU欄位開始計算
* 如果PDU有使用加密，CRC應該在加密之後才計算
* Polynomial格式為x^24^+x^10^+x^9^+x^6^+x^4^+x^3^+x+1

## Advertising Channel PDU
* Advertising Channel PDU格式
![](https://i.imgur.com/lOCtROj.png)

* 其Advertising Channel PDU Header格式
![](https://i.imgur.com/6cLSwuN.png)

* PDU Type有以下
![](https://i.imgur.com/a5lrH3p.png)

* RFU為Reserved for Future Use
* TxAdd為發送端的位址類型，如果是0為Public Address，1為Random Address
* RxAdd為接收端的位址類型，如果是0為Public Address，1為Random Address
* Length為Payload長度，有效範圍為6至37位元組

### Advertising PDUs
分別有四種Advertising PDUs，以及相對應的Events和Payload
* ADV_IND
    * 使用在connectable undirected advertising event
    * Payload欄位有AdvA、AdvData
    * AdvA為Advertiser的位址，如果TxAdd為0，則為Public Address，如果TxAdd為1，則為Random Address
    * AdvData為Advertising Data
![](https://i.imgur.com/UcpvUsi.png)

* ADV_DIRECT_IND
    * 使用在connectable directed advertising event
    * Payload欄位有AdvA、InitA
    * AdvA為Advertiser的位址，如果TxAdd為0，則為Public Address，如果TxAdd為1，則為Random Address
    * InitA為Initiator的位址，如果RxAdd為0，則為Public Address，如果RxAdd為1，則為Random Address
![](https://i.imgur.com/byOKprx.png)

* ADV_NONCONN_IND
    * 使用在non-connectable undirected advertising event
    * Payload欄位有AdvA、AdvData
    * AdvA為Advertiser的位址，如果TxAdd為0，則為Public Address，如果TxAdd為1，則為Random Address
    * AdvData為Advertising Data
![](https://i.imgur.com/UcpvUsi.png)

* ADV_SCAN_IND
    * 使用在scannable undirected advertising event
    * Payload欄位有AdvA、AdvData
    * AdvA為Advertiser的位址，如果TxAdd為0，則為Public Address，如果TxAdd為1，則為Random Address
    * AdvData為Advertising Data
![](https://i.imgur.com/UcpvUsi.png)

### Scanning PDUs
分別有兩種Scanning PDUs
* SCAN_REQ
    * 由Scanner發送出，Advertiser接收
    * Payload欄位有ScanA、AdvA
    * ScanA為Scanner的位址，如果TxAdd為0，則為Public Address，如果TxAdd為1，則為Random Address
    * AdvA為Advertiser的位址，如果RxAdd為0，則為Public Address，如果RxAdd為1，則為Random Address
![](https://i.imgur.com/3cxOzmn.png)

* SCAN_RSP
    * 由Advertiser發送出，Scanner接收
    * Payload欄位有AdvA、ScanRspData
    * AdvA為Advertiser的位址，如果TxAdd為0，則為Public Address，如果TxAdd為1，則為Random Address
    * ScanRspData
![](https://i.imgur.com/blGXT4n.png)

### Initiating PDUs
只有一種Initiating PDU
* CONNECT_REQ
    * 由Initiator發送出，Advertiser接收
    * Payload欄位有InitA、AdvA、LLData
    * InitA為Initiator的位址，如果TxAdd為0，則為Public Address，如果TxAdd為1，則為Random Address
    * AdvA為Advertiser的位址，如果RxAdd為0，則為Public Address，如果RxAdd為1，則為Random Address
    * LLData為建立連線時所需要的參數
![](https://i.imgur.com/a7QR84m.png)

    * LLData分別有以下
![](https://i.imgur.com/Tz7qdR6.png)
        * AA
        * CRCInit
        * WinSize
        * WinOffset
        * Interval
        * Latency
        * Timeout
        * ChM
        * Hop
        * SCA

## Data Channel PDU
Data Channel PDU格式
* 除了跟Advertising Channel PDU一樣有Header、Payload欄位外，多了MIC欄位。
* MIC欄位不能用在未加密的LL連結上，或者是Payload長度為0的Data Channel PDU上
![](https://i.imgur.com/j356DmD.png)

* 其Data Channel PDU Header格式
![](https://i.imgur.com/kOC7lR3.png)

* 其Data Channel PDU Header格式描述
![](https://i.imgur.com/PeES3bj.png)

### LL Data PDU
用來傳送L2CAP的資料

### LL Control PDU
用來控制Link Layer連線
* 其中Payload格式為Opcode、CtrData
![](https://i.imgur.com/Ug0oUZK.png)

* 其中Opcode有
![](https://i.imgur.com/dDGS2RT.png)
![](https://i.imgur.com/jyBFQ8u.png)

* LL_CONNECTION_UPDATE_REQ
![](https://i.imgur.com/uoVjt2S.png)

* LL_CHANNEL_MAP_REQ
![](https://i.imgur.com/CpGqhx6.png)

* LL_TERMINATE_IND
![](https://i.imgur.com/EjasYYs.png)

* LL_ENC_REQ
![](https://i.imgur.com/Tqal7Vh.png)

* LL_ENC_RSP
![](https://i.imgur.com/GXk5kOd.png)

* LL_START_ENC_REQ

* LL_START_ENC_RSP

* LL_UNKNOWN_RSP
![](https://i.imgur.com/dsVIpzD.png)

* LL_FEATURE_REQ
![](https://i.imgur.com/HoLj0Xp.png)

* LL_FEATURE_RSP
![](https://i.imgur.com/HoLj0Xp.png)

* LL_PAUSE_ENC_REQ
* LL_PAUSE_ENC_RSP

* LL_VERSION_IND
![](https://i.imgur.com/eLLRNG2.png)

* LL_VERSION_IND
![](https://i.imgur.com/BHPAdqu.png)

* LL_REJECT_IND
![](https://i.imgur.com/buDsEBY.png)

* LL_SLAVE_FEATURE_REQ
![](https://i.imgur.com/gs3xQoz.png)

* LL_CONNECTION_PARAM_REQ
![](https://i.imgur.com/6noNMrl.png)

* LL_CONNECTION_PARAM_RSP
![](https://i.imgur.com/QQH5GZJ.png)

* LL_REJECT_IND_EXT
![](https://i.imgur.com/hV0KdTh.png)

* LL_PING_REQ
* LL_PING_RSP

* LL_LENGTH_REQ
![](https://i.imgur.com/n1CrAdM.png)

* LL_LENGTH_RSP
![](https://i.imgur.com/n1CrAdM.png)

# Host Controller Interface (HCI)
HCI為Host與Controller之間的接口，主要有兩個任務：
1. Host發送命令給Controller和Host接收來自Controller的事件。
2. 發送和接收另一個設備的數據。

藍牙規範中，定義了四種HCI介面：UART、3-Wire UART、USB、SDIO。


# Security Manager (SM)
## Introduction
為了確保Bluetooth LE的安全性，必續完成兩個程序，首先，設備需要互相配對，其次，連接一旦加密，設備就必須分配用來加密、保障隱私和資料驗證的密鑰，只要密鑰保存下來，設備就處於綁定的狀態了，而Security Manager就是在定義設備之間配對綁定的流程。

配對過程包含了三個程序
* Phase 1: Pairing Feature Exchange
* Phase 2 (LE legacy pairing): Short Term Key (STK) Generation
* Phase 2 (LE Secure Connections): Long Term Key (LTK) Genration
* Phase 3: Transport Specific Key Distribution

![](https://i.imgur.com/jtpWKXX.png)

## Pairing Methods
Pairing Feature Exchange是用來交換IO capabilities的資訊、OOB authentication data availability的資訊、authentication requirement的資訊、key size requirement的資訊和哪個transport specific key需要分配的資訊，其中，IO capabilities、OOB authentication data availability和authentication requirement是用來判斷Phase 2要用哪種方法來產生Key。

# Attribute Protocol (ATT)
## Introduction
* 屬性協議定義了兩種Roles：Client、Server。
* 讓Server可以暴露一組屬性讓Client可以利用屬性協議來存取屬性。
* 屬性的結構可以分為
![](https://i.imgur.com/CqaEAhV.png)
    * Attribute Handle
    * Attribute Type
    * Attribute Value
    * Attribute Permissions
    
## Attribute Handle
一台設備可以有很多的屬性，例如溫度Sensor可能包含溫度屬性、電池電量屬性和設備名稱屬性，乍看之下好像可以透過屬性類型就能判斷是哪種屬性，但是如果設備包含兩種溫度屬性，有一個室內溫度Sensor和一個室外溫度Sensor的話，就無法直接讀取溫度Sensor，而是要讀取室外溫度屬性或是室內溫度屬性，這時候就會用Attribute Handle來區分是哪一個屬性，Attribute Handle為16 bit的值，有效範圍為0x0001-0xFFFF。

## Attribute Type
可被公開的數據有很多種類型：溫度、時間、充電狀態等，為了區分這麼多種的屬性類型使用了128-bit的UUID(Universally Unique Identifier)，為了提高效率，藍牙技術聯盟(Bluetooth SIG)定義了"藍牙UUID基數"的128-bit通用唯一識別碼，使得設備之間傳輸時可以只發送較短的16-bit數據。
* 藍牙UUID基數：
00000000-0000-1000-8000-00805F9B34FB

## Attribute Value
:lock: 

## Attribute Permissions
組成：
* Access Permissions
    * Readable
    * Writeable
    * Readable and writeable
* Encryption Permissions
    * Encryption required
    * No encryption required
* Authentication Permissions
    * Authentication required
    * No authentication required
* Authorization Permissions
    * Authorization required
    * No authorization required
 
## Attribute PDU
* 有六種的的基本操作
    * Request
    * Response
    * Command
    * Notification
    * Indication
    * Confirmation

* Attribute PDU Format
![](https://i.imgur.com/sK5r1YS.png)
    * 只有Write Command才可能包含Authentication Signature 

* Client端向Server端發送Request，以要求Server端執行相關操作並回應Response
![](https://i.imgur.com/7rbNVSE.png)

* Client端向Server端發送Command，不需要Server端任何回應
![](https://i.imgur.com/0Aa7UFz.png)

* Server端向Client端發送Indication，等待Client端回應Confirmation
![](https://i.imgur.com/c3WLHOg.png)

* Server端向Client端發送Notification，不需要Client端任何回應
![](https://i.imgur.com/cap69jq.png)

## Attribute Protocol PDUs
### Error Handling
* Error Response
    * Error Response用來回應不能正確執行的Request，以及提供其理由。
    * Write Command不會產生Error Response。
    * Error Response format
![](https://i.imgur.com/eVABt0z.png)
        * Request Opcode In Error是用來表示產生錯誤的Request的Opcode。
        * Attribute Handle In Error是用來表示產生錯誤的Request的Handle。
        * 如果原始的Request沒有Attribute Handle或是此Request不支援，Attribute Handle In Error欄位設定0x0000。
        * Error Code設定錯誤的理由。
    * Error Codes
![](https://i.imgur.com/Lu6RbSl.png)
![](https://i.imgur.com/fUYhEs0.png)

### MTU Exchange
* Exchange MTU Request
    * Client端用來通知Server端Client端的Rx可以接收的最大的MTU大小，然後要求Server也要回應。
    * Client端的Rx MTU大小應該大於或等於ATT_MTU。
    * Exchange MTU Request format
![](https://i.imgur.com/4OlXCbJ.png)

* Exchange MTU Response
    * Server端用來回應Client端Server端的Rx可以接收的最大MTU大小。
    * Server端的Rx MTU大小應該大於或等於ATT_MTU。
    * Exchange MTU Response format
![](https://i.imgur.com/uw3tXqC.png)

### Find Information
* Find Information Request
    * Cient端利用給定的Attribute Handle範圍來尋找相對應的Attribute Type。
    * Find Information Request format
![](https://i.imgur.com/pke6QEK.png)

* Example
![](https://i.imgur.com/6wE4AvG.png)

* Find Information Response
    * Server端利用Client端所提供的Attribute Handle範圍來回應相對應的Attribute Type。
    * Find Information Response format
![](https://i.imgur.com/8CwOSJ2.png)
![](https://i.imgur.com/Rkcustt.png)
        * 其中Format值如果為0x01，則Information Data為
![](https://i.imgur.com/oRikkgC.png)

        * 其中Format值如果為0x02，則Information Data為
 ![](https://i.imgur.com/zkjmXhI.png)
 
 * Example
 ![](https://i.imgur.com/xvV8SwY.png)

* Find By Type Value Request
    * Client端利用給定的Attribute Type和Attribute Value來尋找相對應的Attribute Handle。
    * Find By Type Value Request format
![](https://i.imgur.com/w8zICQu.png)
    
* Find By Type Value Response
    * Server端利用Client端所提供的Attribute Type和Attribute Value的值來回應相對應的Attribute Handle。
    * Find By Type Value Response format
![](https://i.imgur.com/cxXRKNX.png)
        * Handles Information format
![](https://i.imgur.com/ynGtTrL.png)
        

### Reading Attributes
* Read By Type Request
* Read By Type Response
* Read Request
* Read Response
* Read Blob Request
* Read Blob Response
* Read Multiple Request
* Read Multiple Response
* Read By Group Type Request
* Read By Group Type Response
### Writing Attributes
* Write Request
* Write Response
* Write Command
* Signed Write Command
### Queued Writes
* Prepare Write Request
* Prepare Write Response
* Execute Write Request
* Execute Write Response
### Server Initiated
* Handle Value Notification
* Handle Value Indication
* Handle Value Confirmation

# Generic Attribute Profile (GATT)
## GATT Profile Hierarchy
## GATT Feature Requirements
* Sever Configuration
* Primary Service Discovery
* Relationship Discovery
* Characteristic Discovery
* Characteristic Descriptor Discovery
* Characteristic Value Read
* Characteristic Value Write
* Characteristic Value Notification
* Characteristic Value Indication
* Characteristic Descriptor Value Read
* Characteristic Descriptor Value Write
# Generic Access Profile (GAP)
## GAP roles
* Broadcaster
* Observer
* Peripheral
* Central

### Broadcaster
扮演Broadcaster角色的設備，可能只傳送Advertising events。

### Observer 
扮演Observer角色的設備，可能只接收Advertising events。

### Peripheral
扮演Peripheral角色的設備，可以接受連線的建立。

### Central
扮演Central角色的設備，可以發起連線的建立。

GAP四種角色分別會用哪些Physical Layer和Link Layer功能
![](https://i.imgur.com/eMyyIFk.png)
![](https://i.imgur.com/dv8Vtp4.png)

### Bluetooth Parameters
* Bluetooth Device Address (BD_ADDR)
BD_ADDR是藍牙設備的位址，48 bits表示，舉例來說都會用這種形式表示(00:0C:3E:3A:4B:69)，從左到右分別是MSB到LSB。
* Bluetooth Device Name
用來顯示設備名稱。
* Bluetooth Passkey (Bluetooth PIN)
在建立連線期間，用來驗證兩台設備的身分六位數的數字。
* Class of Device
* Appearance Characteristic

## Modes & Procedures
在GAP有兩個基本概念用來描述設備的行為，即為mode和procedure，舉個例子，當一個設備正在進行廣播時，稱為Broadcast mode，廣播往往會持續較長時間，也許是該設備唯一的用途，而當一個設備正在尋找廣播者時，稱為Observation proceudre，觀察往往持續一段較短的時間，用來建構用戶介面或尋找需要的訊息，GAP定義了4種模式和規程：
* Broadcast mode and observation procedure
* Discovery modes and procedures
* Connection modes and procedures
* Bonding modes and procedures

## Broadcast Mode & Observation Procdure
Broadcast mode和observation procedure允許兩個裝置使用undirectional connectionless的方式來通訊，其中只有GAP某些角色可以使用Broadcast mode和Observation procedure
![](https://i.imgur.com/KTk4WZl.png)
'M' for mandatory
'E' for exclude

* Broadcast Mode
提供裝置在advertising event中傳送connectionless data的方法，應該使用non-connectable undirected advertising event或者是scannable undirected advertising event，Advertising Data(AD)type flag應該設定LE General Discoverable Mode或者是LE Limited Discoverable Mode。

* Observation Procedure
提供裝置接收connectionless data的方法，可以使用主動掃描或者是被動掃描來接收advertising event。

## Discovery Modes & Procedures
所有的裝置應該是non-discoverable mode或是discoverable mode其中一種，discoverable mode應該是general discoverable mode或者是limited discoverable mode，

* Non-Discoverable Mode
* Limited Discoverable Mode
* General Discoverable Mode
* Limited Discovery Procedure
* General Discovery Procedure
* Name Discovery Procedure

## Connection Modes & Procedures
* Non-Connectable Mode
* Directed Connectable Mode
* Undirected Connectable Mode
* Auto Connection Establishment Procedure
* General Connection Establishment Procedure
* Selective Connection Establishment Procedure
* Direct Connection Establishment Procedure
* Connection Parameter Update Procedure
* Terminate Connection Procedure

## Bonding Modes & Procedures
* Non-Bondable mode
* Bondable Mode
* Bonding Procedure

## Security Aspects

###### tags: `Bluetooth LE` `BLE` `HID`