前言
有时候开发项目,我们希望能通过蓝牙直接读取到设备的信息,例如制造商、固件版本、硬件版本和软件版本等信息。所以,今天我们就直接使用官方提供的服务来实现这个需求。
实验分析
首先,我们需要把官方驱动例程添加到我们的工程(这里使用前面用到的串口例程)目录里面:
路径是:工程目录\components\ble\ble_services\ble_dis
接着,我们去看看官方提供给我们的接口函数:
ble_dis.h:
/**@brief Device Information Service init structure. This contains all possible characteristics * needed for initialization of the service. */ typedef struct { ble_srv_utf8_str_t manufact_name_str; /**< Manufacturer Name String. */ ble_srv_utf8_str_t model_num_str; /**< Model Number String. */ ble_srv_utf8_str_t serial_num_str; /**< Serial Number String. */ ble_srv_utf8_str_t hw_rev_str; /**< Hardware Revision String. */ ble_srv_utf8_str_t fw_rev_str; /**< Firmware Revision String. */ ble_srv_utf8_str_t sw_rev_str; /**< Software Revision String. */ ble_dis_sys_id_t * p_sys_id; /**< System ID. */ ble_dis_reg_cert_data_list_t * p_reg_cert_data_list; /**< IEEE 11073-20601 Regulatory Certification Data List. */ ble_dis_pnp_id_t * p_pnp_id; /**< PnP ID. */ ble_srv_security_mode_t dis_attr_md; /**< Initial Security Setting for Device Information Characteristics. */ } ble_dis_init_t; /**@brief Function for initializing the Device Information Service. * * @details This call allows the application to initialize the device information service. * It adds the DIS service and DIS characteristics to the database, using the initial * values supplied through the p_dis_init parameter. Characteristics which are not to be * added, shall be set to NULL in p_dis_init. * * @param[in] p_dis_init The structure containing the values of characteristics needed by the * service. * * @return NRF_SUCCESS on successful initialization of service. */ uint32_t ble_dis_init(const ble_dis_init_t * p_dis_init);
接下来,我们直接开始应用层的代码实现:
#include "ble_dis.h"
#define MANUFACTURER_NAME "Sam_Man" /**< Manufacturer. Will be passed to Device Information Service. */
#define HARDWARE_REVISION "Sam_Hard"
#define SOFTWARE_REVISION "V2.0"
#define FIRMWARE_REVISION "S110"
将ble_dis.h包含,并宏定义需要显示的字符串。
接下来,修改服务初始化函数:
/**@brief Function for initializing services that will be used by the application.
*/
static void services_init(void)
{
uint32_t err_code;
ble_nus_init_t nus_init;
ble_dis_init_t dis_init;
memset(&nus_init, 0, sizeof(nus_init));
nus_init.data_handler = nus_data_handler;
err_code = ble_nus_init(&m_nus, &nus_init);
APP_ERROR_CHECK(err_code);
// Initialize Device Information Service.
memset(&dis_init, 0, sizeof(dis_init));
ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, (char *)MANUFACTURER_NAME);
ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, (char *)HARDWARE_REVISION);
ble_srv_ascii_to_utf8(&dis_init.sw_rev_str, (char *)SOFTWARE_REVISION);
ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, (char *)FIRMWARE_REVISION);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);
err_code = ble_dis_init(&dis_init);
APP_ERROR_CHECK(err_code);
}
到这里,就完成了所有操作。是不是很简单,就是这么简单。
结果验证
- 手机连接蓝牙,我们可以看到新增一个设备信息服务
- 这个服务包含几个只读的特性
- 把这几个特定都更新一遍,就会发现特征值正是我们定义的字符串
题外话
问:为什么我们定义的私有服务,在调试软件上面显示的名称总是unknown呢?有没有办法让私有服务的名称有意义呢?
答:没有办法实现。因为Battery Service,Heart rate这些服务对应的UUID都是在蓝牙联盟注册过的,全世界通用的,而自己定义服务时定义的uuid肯定是自定义的,并没有注册过,所以必然显示unknown。
总结
通过这个实验,我们学会了如何显示设备的信息。
来源:CSDN
作者:西米爱吃虾米
链接:https://blog.csdn.net/SammySum/article/details/103474125