nrf52832 学习笔记(九)蓝牙主机发现服务

服务发现流程

数据如同下表一样存储在服务端,客户端首先要获取表中的Handle和Type列,从而知道服务端中存在哪些数据,以便后面读、写、通知等操作。这个过程叫做发现服务。

服务发现初始化

以SDK中 ble_app_blinky_c 为例

需要添加对应文件及头文件路径信息

然后对服务发现库进行初始化,并定义服务发现函数回调函数 db_disc_handler, 当服务发现完成时会触发该回调函数。

/**@brief Function for handling database discovery events.** @details This function is callback function to handle events from the database discovery module.*          Depending on the UUIDs that are discovered, this function should forward the events*          to their respective services.** @param[in] p_event  Pointer to the database discovery event.*/
static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
{ble_lbs_on_db_disc_evt(&m_ble_lbs_c, p_evt);
}/**@brief Database discovery initialization.*/
static void db_discovery_init(void)
{ble_db_discovery_init_t db_init;memset(&db_init, 0, sizeof(db_init));db_init.evt_handler  = db_disc_handler;db_init.p_gatt_queue = &m_ble_gatt_queue;ret_code_t err_code = ble_db_discovery_init(&db_init);APP_ERROR_CHECK(err_code);
}

主机进行服务发现时不能发现私有服务的128bit UUID,需要对私有UUID进行注册

/**@brief Handles events coming from the LED Button central module.*/
static void lbs_c_evt_handler(ble_lbs_c_t * p_lbs_c, ble_lbs_c_evt_t * p_lbs_c_evt)
{switch (p_lbs_c_evt->evt_type){case BLE_LBS_C_EVT_DISCOVERY_COMPLETE:{ret_code_t err_code;err_code = ble_lbs_c_handles_assign(&m_ble_lbs_c,p_lbs_c_evt->conn_handle,&p_lbs_c_evt->params.peer_db);NRF_LOG_INFO("LED Button service discovered on conn_handle 0x%x.", p_lbs_c_evt->conn_handle);err_code = app_button_enable();APP_ERROR_CHECK(err_code);// LED Button service discovered. Enable notification of Button.err_code = ble_lbs_c_button_notif_enable(p_lbs_c);APP_ERROR_CHECK(err_code);} break; // BLE_LBS_C_EVT_DISCOVERY_COMPLETEcase BLE_LBS_C_EVT_BUTTON_NOTIFICATION:{NRF_LOG_INFO("Button state changed on peer to 0x%x.", p_lbs_c_evt->params.button.button_state);if (p_lbs_c_evt->params.button.button_state){bsp_board_led_on(LEDBUTTON_LED);}else{bsp_board_led_off(LEDBUTTON_LED);}} break; // BLE_LBS_C_EVT_BUTTON_NOTIFICATIONdefault:// No implementation needed.break;}
}
uint32_t ble_lbs_c_init(ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_init_t * p_ble_lbs_c_init)
{uint32_t      err_code;ble_uuid_t    lbs_uuid;ble_uuid128_t lbs_base_uuid = {LBS_UUID_BASE};VERIFY_PARAM_NOT_NULL(p_ble_lbs_c);VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init);VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init->evt_handler);VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init->p_gatt_queue);p_ble_lbs_c->peer_lbs_db.button_cccd_handle = BLE_GATT_HANDLE_INVALID;p_ble_lbs_c->peer_lbs_db.button_handle      = BLE_GATT_HANDLE_INVALID;p_ble_lbs_c->peer_lbs_db.led_handle         = BLE_GATT_HANDLE_INVALID;p_ble_lbs_c->conn_handle                    = BLE_CONN_HANDLE_INVALID;p_ble_lbs_c->evt_handler                    = p_ble_lbs_c_init->evt_handler;p_ble_lbs_c->p_gatt_queue                   = p_ble_lbs_c_init->p_gatt_queue;p_ble_lbs_c->error_handler                  = p_ble_lbs_c_init->error_handler;err_code = sd_ble_uuid_vs_add(&lbs_base_uuid, &p_ble_lbs_c->uuid_type);if (err_code != NRF_SUCCESS){return err_code;}VERIFY_SUCCESS(err_code);lbs_uuid.type = p_ble_lbs_c->uuid_type;lbs_uuid.uuid = LBS_UUID_SERVICE;return ble_db_discovery_evt_register(&lbs_uuid);
}/**@brief LED Button client initialization.*/
static void lbs_c_init(void)
{ret_code_t       err_code;ble_lbs_c_init_t lbs_c_init_obj;lbs_c_init_obj.evt_handler   = lbs_c_evt_handler;lbs_c_init_obj.p_gatt_queue  = &m_ble_gatt_queue;lbs_c_init_obj.error_handler = lbs_error_handler;err_code = ble_lbs_c_init(&m_ble_lbs_c, &lbs_c_init_obj);APP_ERROR_CHECK(err_code);
}

开启服务发现

从机广播,主机扫描到广播后,发出连接请求,主从机连接后就可以开始进行服务发现

这里有个句柄派发函数,主要是nrf52832 支持多连接(一主多从),当给蓝牙协议栈下发命令时,蓝牙协议栈可能正在执行其他连接的命令,因此做了两个消息队列,将连接信息和命令信息分别缓存起来,防止命令信息错乱丢失。

uint32_t ble_lbs_c_handles_assign(ble_lbs_c_t    * p_ble_lbs_c,uint16_t         conn_handle,const lbs_db_t * p_peer_handles)
{VERIFY_PARAM_NOT_NULL(p_ble_lbs_c);p_ble_lbs_c->conn_handle = conn_handle;if (p_peer_handles != NULL){p_ble_lbs_c->peer_lbs_db = *p_peer_handles;}return nrf_ble_gq_conn_handle_register(p_ble_lbs_c->p_gatt_queue, conn_handle);
}

服务发现完成

服务发现完成后会调用 ble_lbs_on_db_disc_evt 回调函数

在回调函数ble_lbs_on_db_disc_evt 中,设置句柄信息

并在函数结束时 调用 p_ble_lbs_c->evt_handler(p_ble_lbs_c, &evt); 函数,也就是 lbs_c_evt_handler 函数,使能 通知(ble_lbs_c_button_notif_enable)

服务端通知

如果客户端使能了服务端的CCCD,服务端通知时会触发客户端回调函数

在 函数 on_hvx 中完成对通知的处理

客户端读

调用客户端读 API,服务端会将对应数据上报上来

uint32_t ble_lbs_led_status_read(ble_lbs_c_t * p_ble_lbs_c)
{VERIFY_PARAM_NOT_NULL(p_ble_lbs_c);if (p_ble_lbs_c->conn_handle == BLE_CONN_HANDLE_INVALID){return NRF_ERROR_INVALID_STATE;}nrf_ble_gq_req_t read_req;memset(&read_req, 0, sizeof(nrf_ble_gq_req_t));read_req.type                        = NRF_BLE_GQ_REQ_GATTC_READ;read_req.error_handler.cb            = gatt_error_handler;read_req.error_handler.p_ctx         = p_ble_lbs_c;read_req.params.gattc_read.handle   = p_ble_lbs_c->peer_lbs_db.led_handle;read_req.params.gattc_read.offset   = 0;return nrf_ble_gq_item_add(p_ble_lbs_c->p_gatt_queue, &read_req, p_ble_lbs_c->conn_handle);
}

上报的数据会触发回调函数

在回调函数中对 读出数据进行处理

客户端写

客户端写和读类似,只不过没有回调函数

nrf52832 学习笔记(九)蓝牙主机发现服务相关推荐

  1. nrf52832学习笔记(1)蓝牙心电例程分析

    对于我这种之前完全不懂蓝牙,接触学习nordic的蓝牙感觉学起来有困难,他那api讲解文档竟然网页版的,而且链接一层又一层,网速又慢,协议栈版本又多= .= 但还是要学啊,就拿着他的例字代码看吧... ...

  2. nrf52832 学习笔记(四)蓝牙主机扫描

    nrf52832 学习笔记(四)蓝牙主机扫描 从机发出广播后就需要主机进行扫描了,主机扫描之前和从机一样,也需要协议栈初始化.GAP初始化.GATT初始化,这些和从机类似,参考 nrf52832 学习 ...

  3. nrf52832 学习笔记(七)蓝牙协议层级理解

    nrf52832 学习笔记(七)蓝牙协议层级理解 本文主要由一下几篇文档摘录汇总而成 ,如有错误欢迎斧正 da14531 蓝牙协议文档 深入浅出低功耗蓝牙(BLE)协议栈 低功耗蓝牙ATT/GATT/ ...

  4. nrf52832 学习笔记(三)蓝牙从机广播

    nrf52832 学习笔记(三)蓝牙从机广播 蓝牙从机要想被主机连接,首先需要发送广播信息,周围主机通过扫描广播信号,根据从机的广播信息,判断是否连接. 蓝牙协议栈初始化 不管是主机还是从机,要想使用 ...

  5. nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新

    nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新 主机连接 nrf52832 SDK中主机连接从机需要使用 sd_ble_gap_connect(ble_gap_addr_t const ...

  6. nrf52832 学习笔记(二)SDK框架分析

    nrf52832 学习笔记(二)SDK框架分析 个人对SDK框架的一些理解,如有错误欢迎斧正. flash 分区 在不包含DFU的情况下,nrf52832 flash划分为: MBR 0x000000 ...

  7. nrf52832 学习笔记(六)配对和绑定

    nrf52832 学习笔记(六)配对和绑定 配对绑定推荐博客低功耗蓝牙配对绑定解读和实践 蓝牙在配对之前都是明文通信的,也就是说主从机之间传输的数据包可以被第三方抓取分析逆向,而且如果没有配对,谁都可 ...

  8. NRF52832学习笔记(38)——修改发射功率

    一.背景 蓝牙接收信号强度 RSSI 的直接影响因素就是蓝牙信号的发射功率.发射功率就是你所使用的设备(开发板.手机)所发射出来给主机或从机设备的信号强度.同时在实际应用当中,时常也需要修改蓝牙的发射 ...

  9. nrf52832 学习笔记(一)开发资料汇总

    nrf52832 学习笔记(一)开发资料汇总 协议栈和SDK下载地址 nordic官方的sdk分为ncs(nRF Connect SDK)和sdk17(nRF5 SDK)两种,区别是: sdk17不会 ...

最新文章

  1. keepalived+nginx实现nginx的高可用
  2. 引入外部化的配置文件
  3. android recyclerview 横向item 宽度,RecyclerView的item宽度不能全屏显示及线性布局与grid布局切换混乱解决方法...
  4. 走,去抖音上发财!抖音承诺未来一年要帮一千万创作者赚到钱
  5. cesium 经纬度绘制点_Cesium经纬度与坐标的问题
  6. 计算机电路基础实验一仪器使用,计算机电路基础(1)实验.pdf
  7. 从零开始搭建ELK+GPE监控预警系统
  8. 红帽Red Hat Linux镜像下载
  9. 国密 GmSSL 版本及安装
  10. 安卓系统如何访问wincc服务器,wincc客户端读取服务器数据库
  11. 《三级医院评审标准(2020年版)》及解读:医疗机构要不断加强信息化建设
  12. good website
  13. ORA-00979 不是 GROUP BY 表达式
  14. STM32学习之路——麒麟座V3.2开发板蜂鸣器发声问题
  15. 企业内部即时通讯系统项目总结
  16. Molecular weight相对分子质量
  17. Ambari-2.7.5.0 + HDP-3.1.5.0网盘地址
  18. 当前流行的智能硬件产品整理
  19. 北交所开通知识测评 测试题答案(海通)
  20. python学习之 re库 正则表达式

热门文章

  1. IE设置浏览器不缓存页面
  2. Redis+Caffeine两级缓存
  3. Fedora18 安装后风扇不停的转
  4. TOM在线与Skype联手推出Tom-Skype
  5. 矩阵分析之 实矩阵分解(1)特征分解与奇异值分解SVD
  6. 数制转换(8进制转化十进制)
  7. excel制表基础:规范的制表理念和思路让效率提升 下篇
  8. 白皮书数据显示,内循环下差旅管控市场下沉趋势或将凸显
  9. vue获取dom元素高度的方法
  10. Python之路,Day12 - 那就做个堡垒机吧