娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

ESP32學習筆記(33)——BLE GATT客戶端發(fā)現(xiàn)服務和讀寫特征值

發(fā)布者:平和心態(tài)最新更新時間:2025-02-27 來源: jianshu關鍵字:ESP32  BLE  客戶端 手機看文章 掃描二維碼
隨時隨地手機看文章

一、背景

1.1 GATT協(xié)議

GATT(Generic Attributes Profile)的縮寫,中文是通用屬性協(xié)議,是已連接的低功耗藍牙設備之間進行通信的協(xié)議。

一旦兩個設備建立起了連接,GATT 就開始起作用了,這也意味著,你必需完成前面的GAP協(xié)議。

GATT使用了 ATT(Attribute Protocol)協(xié)議,ATT 協(xié)議把 Service,Characteristic 對應的數據保存在一個查找表中,查找表使用 16bit ID 作為每一項的索引。

GATT定義的多層數據結構簡要概括起來就是 服務(Service) 可以包含多個 特征(Characteristic),每個特征包含 屬性(Properties) 和 值(Value),還可以包含多個 描述(Descriptor)。

1.2 屬性協(xié)議(ATT)

屬性協(xié)議層 負責數據檢索,允許一個設備暴露一些數據塊給其他設備,其他設備稱之為“屬性”。

在ATT環(huán)境中,展示屬性的設備稱之為服務器,與它配對的設備稱之為客戶端。鏈路層的主機從機和這里的服務器、客服端是兩種概念,主設備既可以是服務器,也可以是客戶端。從設備毅然。

1.3 GATT通信中角色

從GATT的角度來看,處于連接狀態(tài)時的兩個設備,它們各自充當兩種角色中的一種:
服務端(Server)
包含被GATT客戶端讀取或寫入的特征數據的設備。
客戶端(Client)
從GATT服務器中讀取數據或向GATT服務器寫入數據的設備。

外圍設備(從機)作為 GATT 服務端(Server),它維持了 ATT 的查找表以及 service 和 characteristic 的定義;

客戶端和服務器的GATT角色獨立于外圍設備和中央設備的GAP角色。外圍設備可以是GATT客戶端或GATT服務器,中心可以是GATT客戶端或GATT服務器。

image


1.4 Bluedroid主機架構

在 ESP-IDF 中,使用經過大量修改后的 BLUEDROID 作為藍牙主機 (Classic BT + BLE)。BLUEDROID 擁有較為完善的功能,?持常用的規(guī)范和架構設計,同時也較為復雜。經過大量修改后,BLUEDROID 保留了大多數 BTA 層以下的代碼,幾乎完全刪去了 BTIF 層的代碼,使用了較為精簡的 BTC 層作為內置規(guī)范及 Misc 控制層。修改后的 BLUEDROID 及其與控制器之間的關系如下圖:

二、API說明

以下 GATT 接口位于 bt/host/bluedroid/api/include/api/esp_gattc_api.h

2.1 esp_ble_gattc_search_service

2.2 esp_ble_gattc_get_char_by_uuid

2.3 esp_ble_gattc_get_descr_by_char_handle

2.4 esp_ble_gattc_get_attr_count

2.5 esp_ble_gattc_write_char

2.6 esp_ble_gattc_write_char_descr

2.7 esp_ble_gattc_register_for_notify

三、發(fā)現(xiàn)服務

本篇是關于GATT客戶端發(fā)現(xiàn)服務和讀寫特征值,連接服務端的流程查看 ESP32學習筆記(32)——BLE GAP主機端連接


MTU配置事件還用于開始發(fā)現(xiàn)客戶端剛剛連接到的服務器中可用的服務。要發(fā)現(xiàn)服務,可以使用esp_ble_gattc_search_service()函數。該函數的參數包括GATT接口、應用程序配置文件連接ID和客戶端感興趣的應用程序UUID。


我們正在尋找的服務定義為:


#define REMOTE_SERVICE_UUID        0x00FFstatic esp_bt_uuid_t remote_filter_service_uuid = {

    .len = ESP_UUID_LEN_16,

    .uuid = {.uuid16 = REMOTE_SERVICE_UUID,},};

隨后進行查找服務:


esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);

        break;

找到的服務結果(如果有的話)將從ESP_GATTC_SEARCH_RES_EVT返回。對于找到的每個服務,將觸發(fā)事件來打印所發(fā)現(xiàn)服務的信息,具體取決于UUID的大小:


 case ESP_GATTC_SEARCH_RES_EVT: {

        esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id;

        conn_id = p_data->search_res.conn_id;

        if (srvc_id->id.uuid.len == ESP_UUID_LEN_16 && srvc_id->id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {

        get_server = true;

        gl_profile_tab[PROFILE_A_APP_ID].service_start_handle = p_data->search_res.start_handle;

        gl_profile_tab[PROFILE_A_APP_ID].service_end_handle = p_data->search_res.end_handle;

        ESP_LOGI(GATTC_TAG, 'UUID16: %x', srvc_id->id.uuid.uuid.uuid16);

        }

        break;

如果客戶端找到了它要查找的服務,就將get_server標記設置為true,并保存開始句柄值和結束句柄值,稍后將使用它們來獲得該服務的所有特征。在返回所有服務結果之后,將完成搜索并觸發(fā)ESP_GATTC_SEARCH_CMPL_EVT事件。


四、獲取特征

此示例實現(xiàn)從預定義服務獲取特征數據。我們想要獲得特征的服務UUID是0x00FF,我們感興趣的特征UUID是0xFF01:


#define REMOTE_NOTIFY_CHAR_UUID    0xFF01

使用esp_gatt_srvc_id_t結構定義服務:


/**

 * @brief Gatt id, include uuid and instance id

 */typedef struct {

    esp_bt_uuid_t   uuid;                   /*!< UUID */

    uint8_t         inst_id;                /*!< Instance id */} __attribute__((packed)) esp_gatt_id_t;

在這個例子中,我們定義了我們想要獲取特征的服務:


static esp_gatt_srvc_id_t remote_service_id = {

    .id = {

        .uuid = {

            .len = ESP_UUID_LEN_16,

            .uuid = {.uuid16 = REMOTE_SERVICE_UUID,},

        },

        .inst_id = 0,

    },

    .is_primary = true,};

定義之后,我們可以使用esp_ble_gattc_get_characteristic()函數從該服務獲取特征,該函數在服務搜索完成并且找到了它正在尋找的服務之后,在ESP_GATTC_SEARCH_CMPL_EVT事件中調用。


case ESP_GATTC_SEARCH_CMPL_EVT:

    if (p_data->search_cmpl.status != ESP_GATT_OK){

        ESP_LOGE(GATTC_TAG, 'search service failed, error status = %x', p_data->search_cmpl.status);

        break;

    }

    conn_id = p_data->search_cmpl.conn_id;

    if (get_server){

        uint16_t count = 0;

        esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gattc_if,

                          p_data->search_cmpl.conn_id,ESP_GATT_DB_CHARACTERISTIC,                                                                                                                                           gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,                                                                                              gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,        

                                                                INVALID_HANDLE,                           

                                                                     &count);

        if (status != ESP_GATT_OK){

            ESP_LOGE(GATTC_TAG, 'esp_ble_gattc_get_attr_count error');

        }


        if (count > 0){

            char_elem_result = (esp_gattc_char_elem_t*)malloc                                          (sizeof(esp_gattc_char_elem_t) * count);

            if (!char_elem_result){

                ESP_LOGE(GATTC_TAG, 'gattc no mem');

            }else{

                status = esp_ble_gattc_get_char_by_uuid( gattc_if,

                                                       p_data->search_cmpl.conn_id,                                                                      

                              gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,                                                            

                              gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,

                                                         remote_filter_char_uuid,

                                                         char_elem_result,

                                                         &count);

                if (status != ESP_GATT_OK){

                    ESP_LOGE(GATTC_TAG, 'esp_ble_gattc_get_char_by_uuid error');

                }


                /*  Every service have only one char in our 'ESP_GATTS_DEMO' demo,     

                    so we used first 'char_elem_result' */

                if (count > 0 && (char_elem_result[0].properties                       

                                 &ESP_GATT_CHAR_PROP_BIT_NOTIFY)){

                    gl_profile_tab[PROFILE_A_APP_ID].char_handle =  

                    char_elem_result[0].char_handle;

                    esp_ble_gattc_register_for_notify (gattc_if,   

                                   gl_profile_tab[PROFILE_A_APP_ID].remote_bda, 

                                   char_elem_result[0].char_handle);

[1] [2]
關鍵字:ESP32  BLE  客戶端 引用地址:ESP32學習筆記(33)——BLE GATT客戶端發(fā)現(xiàn)服務和讀寫特征值

上一篇:ESP32學習筆記(34)——BLE一主多從連接
下一篇:ESP32學習筆記(32)——BLE GAP主機端連接

推薦閱讀最新更新時間:2025-06-08 04:18

英特爾前客戶端計算事業(yè)部副總裁加盟ADI
ADI日前宣布,Gregory Bryant 被任命為公司執(zhí)行副總裁兼業(yè)務部門總裁,業(yè)務部門總裁是ADI一個新設職位,Gregory 將領導公司的業(yè)務部門——工業(yè)、汽車、通信、數字醫(yī)療保健和消費者——并將負責繼續(xù)擴大 ADI 快速增長的業(yè)務。將于 3 月 14 日開始工作,直接向 ADI總裁兼首席執(zhí)行官 Vincent Roche 匯報工作。 Gregory擁有三十年的經驗和推動增長的良好記錄。最近,他擔任英特爾客戶端計算事業(yè)部的執(zhí)行副總裁兼總經理,該事業(yè)部是英特爾規(guī)模最大、利潤最高的業(yè)務。在擔任該職位期間,他領導了一個擁有 5000 多人的全球組織,并抓住了 PC 市場的增長機會。 “Gregory 是一位備受尊敬、以客
[模擬電子]
STM32移植lwip之建立tcp客戶端
本篇目標:在之前能ping通pc機的工程基礎上搭建tcp客戶端,并可以主動發(fā)數據給pc機,同時也能與pc機收發(fā)數據,并在網絡調試工具上顯示 材料準備: 基礎工程:修改后能ping通pc機的工程(STM32官方移植lwip修改代碼) 調試工具:用來調試tcp連接下的數據接收(網絡調試助手) 搭建工程:最終搭建好tcp客戶端數據接收的工程(tcp客戶端建立工程) 搭建TCP客戶端 搭建TCP客戶端的過程與上一章TCP服務器也相似,所以盡量把重點的地方加粗顯示來區(qū)別 在搭建TCP客戶端之前可以先理一下概念,客戶端與服務器的區(qū)別: 客戶端:主動建立tcp去連接目標IP 服務器:擁有靜態(tài)IP,能讓其他設備被動連接 因此用STM
[單片機]
STM32移植lwip之建立tcp<font color='red'>客戶端</font>
研華推出可觸摸工業(yè)等級瘦客戶端平板電腦TPC-1550H
研華科技,2013年4月 ——全球領先的創(chuàng)新嵌入式產業(yè)電腦&自動化解決方案提供廠商研華科技推出可觸摸工業(yè)等級瘦客戶端平板電腦TPC-1550H。該系列產品采用英特爾凌動N270處理器,具有無風扇、超薄緊湊型設計,操作系統(tǒng)支持Microsoft? Windows? 7/XPE/WES, Windows CE 5.0/6.0具有Java Script備份,同時支持Linux操作系統(tǒng),并帶有Firefox和Java Script程序。除以上優(yōu)秀品質外,其還具備如下突出特征: 1、具有強大的觸摸功能,便于現(xiàn)場操作; 2、前面板為符合NEMA4/IP65標準的強固型面板,防水、防塵易清潔; 3、配備多種標準通訊接口,支持雙千兆以太網,以及雙
[手機便攜]
研華推出可觸摸工業(yè)等級瘦<font color='red'>客戶端</font>平板電腦TPC-1550H
[nrf51][nrf52][單片機] ble藍牙無限廣播 持續(xù)廣播
1、實現(xiàn)無限非連接廣播 ①BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE改為BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE,廣播超時后,仍能繼續(xù)發(fā)送。 ②APP_ADV_TIMEOUT_IN_SECONDS設置為0
[單片機]
Synaptics推出wi-fi6,藍牙 5.2,BLE音頻,Matter等多標準一身的SoC
Synaptics日前宣布推出 SYN4381 Triple Combo SoC,這是首款將 Wi-Fi 6/6E(802.11ax 與擴展 6 GHz)、藍牙 5.2 (BT 5.2) 與 BLE 音頻、高精度距離測量 (HADM)相結合的產品,以及內置支持 Thread 協(xié)議和 Matter 應用層的 IEEE 802.15.4。SoC 及其支持的 SynFi軟件簡化了產品開發(fā)并縮短了上市時間,同時加速了跨異構物聯(lián)網 (IoT) 網絡的設備之間向無縫、安全和可擴展連接的過渡,無論平臺、OEM 或品牌。 典型的智能家居包括來自多個供應商的具有各種無線接口和通信協(xié)議的設備。設備開發(fā)人員選擇這些是因為它們適合特定功能,例如高速視
[物聯(lián)網]
ESP32玩轉MicroPython(三) 延時、計時 和GPIO操作
一. 延時和計時 使用time模塊: import time time.sleep(1) # sleep for 1 secondtime.sleep_ms(500) # sleep for 500 millisecondstime.sleep_us(10) # sleep for 10 microsecondsstart = time.ticks_ms() # get millisecond counterdelta = time.ticks_diff(time.ticks_ms(), start) # compute time difference 這些延時是阻塞式延時, 后續(xù)程序需要等待其完成
[單片機]
小廣播
設計資源 培訓 開發(fā)板 精華推薦

最新單片機文章

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發(fā)圈

 
機器人開發(fā)圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 和田县| 深泽县| 溧阳市| 台安县| 资兴市| 孟州市| 萨嘎县| 弥勒县| 涿鹿县| 东至县| 昌邑市| 雷州市| 龙门县| 岗巴县| 田林县| 自治县| 交口县| 土默特左旗| 武威市| 准格尔旗| 武平县| 武陟县| 珲春市| 修水县| 长泰县| 休宁县| 河曲县| 车险| 吉木乃县| 稷山县| 莱芜市| 昆山市| 清水县| 兰考县| 开鲁县| 府谷县| 全州县| 平阳县| 财经| 东兴市| 乌兰察布市|