蓝牙GAP(通用访问配置文件)学习
芯片:nrf52832
SDK版本:nRF5_SDK_15.3.0_59ac345
一. GAP的作用
- 通用访问配置文件,该profile是保证不同蓝牙产品可以互相发现对方和建立连接的.
- 定义蓝牙设备如何发现和建立与其他设备的安全(或不安全)连接.
- 处理业务:询问、命名、搜索、链路建立、信道和连接建立.
- 它是所有其他配置文件的基础,它定义了在蓝牙设备间建立基带链路的通用方法.
- 必须在所有蓝牙设备中实施的功能.
- 发现和链接设备的通用步骤.
- 基本用户界面术语.
二. 查看软件代码实例
- 下面找到NRF52832蓝牙样例,分析下GAP初始化函数gap_params_init, 结合代码深入理解蓝牙协议.
/**@brief Function for the GAP initialization.
*
* @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
* device including the device name, appearance, and the preferred connection parameters.
*/
static void gap_params_init(void)
{
ret_code_t err_code;
ble_gap_conn_params_t gap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;
// 1. 安全模式,安全权限设置
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // 连接模式,是否需要加密
// 2. 设备名称设置
err_code = sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *)DEVICE_NAME,
strlen(DEVICE_NAME));
APP_ERROR_CHECK(err_code);
// 3. 应用图标设置,若没有图标可以不配置
/* YOUR_JOB: Use an appearance value matching the application's use case.
err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_);
APP_ERROR_CHECK(err_code); */
memset(&gap_conn_params, 0, sizeof(gap_conn_params));
// 4. 连接参数配置
gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
gap_conn_params.slave_latency = SLAVE_LATENCY;
gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
// 5. 连接参数配置,主要是连接时间间隔设置
err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
APP_ERROR_CHECK(err_code);
}
以上初始化代码主要完成3个任务:
- 设置连接安全模式.
- 设置蓝牙名称和应用图片.
- 设置连接间隔.
- 下面来看看这3个任务具体如何配置和介绍.
首先来介绍安全设置.
- 安全模式0水平0: 不允许连接
- 安全模式1水平1: 无安全要求(又称为直接打开链接)
- 安全模式1水平2: 需要加密链接,无MITM保护
- 安全模式1水平3: 加密链接和MITM保护
- 安全模式1水平4: LESC加密链接和MITM保护
- 安全模式2水平1: 签名或者加密,无MITM保护
- 安全模式2水平2: MITM保护签名或者加密链接
// 几种安全模式对应的函数如下:
/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters
*
* See @ref ble_gap_conn_sec_mode_t.
* @{ */
/**@brief Set sec_mode pointed to by ptr to have no access rights.*/
#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0)
/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/
#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0)
/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/
#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0)
/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/
#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0)
/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/
#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0)
/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/
#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0)
/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/
#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0)
/**@} */
紧接着介绍蓝牙名的设置
设置蓝牙名字和安全模式,蓝牙名会通过广播发出,名称显示形式可以在广播结构体中定义.
// softedevices中实现的API,无法查看源码只能查看帮助文档,所有带sd前缀的函数都是softdevices中实现的函数.
SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len));
/**@brief Set GAP device name.
*
* @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t),
* it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned.
*
* @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t.
* @param[in] p_dev_name Pointer to a UTF-8 encoded, <b>non NULL-terminated</b> string.
* @param[in] len Length of the UTF-8, <b>non NULL-terminated</b> string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN).
*
* @retval ::NRF_SUCCESS GAP device name and permissions set successfully.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
* @retval ::NRF_ERROR_FORBIDDEN Device name is not writable.
*/
uint32_t sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len);
广播蓝牙名称1类型
- 广播数据中不包含蓝牙名称,若需要读蓝牙名称可以通过GAP接口获取蓝牙名称2
- 广播数据中包含蓝牙简称
- 广播数据中包含蓝牙全称
/**@brief Advertising data name type. This enumeration contains the options available for the device name inside
* the advertising data. */
typedef enum
{
BLE_ADVDATA_NO_NAME, /**< Include no device name in advertising data. */
BLE_ADVDATA_SHORT_NAME, /**< Include short device name in advertising data. */
BLE_ADVDATA_FULL_NAME /**< Include full device name in advertising data. */
} ble_advdata_name_type_t;
// 更改成简称的时候需要备注简称长度
/**@brief Function for initializing the Advertising functionality.
*/
static void advertising_init(void)
{
uint32_t err_code;
ble_advertising_init_t init;
memset(&init, 0, sizeof(init));
init.advdata.name_type = BLE_ADVDATA_SHORT_NAME;
init.advdata.short_name_len = 6; // 设置简称时候需要设置长度
init.advdata.include_appearance = false;
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
init.srdata.uuids_complete.p_uuids = m_adv_uuids;
init.config.ble_adv_fast_enabled = true;
init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
init.config.ble_adv_fast_timeout = APP_ADV_DURATION;
init.evt_handler = on_adv_evt;
err_code = ble_advertising_init(&m_advertising, &init);
APP_ERROR_CHECK(err_code);
ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}
蓝牙图标设置,SIG联盟设置了一些常用的图标
我们可以通过SDK中API设置3,设置不同类型的图标
/** @defgroup BLE_APPEARANCES Bluetooth Appearance values
* @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
* @{ */
#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */
#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */
#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */
#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */
#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */
#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */
#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */
#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */
#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */
#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */
#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */
#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */
#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */
#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */
#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */
#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */
#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */
#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */
#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */
#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */
#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */
#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */
#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */
#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */
#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */
#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */
#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */
#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */
#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */
#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */
#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */
#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */
#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */
#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */
#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */
#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */
#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */
#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */
#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */
#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */
#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */
#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */
/** @} */
GAP初始化设置连接间隔
- 连接间隔4,连接间隔6(7.5ms)~3200(4s),单位是1.25ms;连接间隔越大功耗越低5,可能会导致数据发送数据不及时,需要下一个连接事件才发出.
- 从机潜伏周期6,可以选择跳过连接事件,并保持睡眠.也可以从设备延迟,从设备可以忽略主设备的链接事件的最大值;
- 监督超时7,最小时间10(10ms)到最大3200(32.0s),同时超市时间必须大于有效连接事件8.
- 短连接间隔,高功耗,高数据吞吐量,发送等待时间短;
- 长连接间隔,低功耗,低数据吞吐量,发送等待时间长;
- 低或者0潜伏值,从机在没有数据发送的情况下高功耗,从机可以快速的收到主机的数据;
- 高潜伏值,从机在没有数据发送的情况下可以低功耗,从机无法及时收到主机数据,但是主机能及时收到从机的数据;
GAP层负责处理设备的接入方式和过程,包括设备发现,链路建立,链路终止,启动安全功能,设备配置;
GAP层扮演的四种角色;
- 广播者,广告发送者,不是可连接的设备;
- 观察者,扫描广告,不能启动连接;
- 外围设备,广告发送者,是可以连接的设备,在单一链路层连接时作为从机;
- 中央设备,扫描广告启动连接,在单一或者多链路层连接时作为主机,支持三个同时连接;
typedef struct
{
uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ //最小连接间隔
uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ //最大连接间隔
uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ //从机潜伏周期
uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ //连接超时监督
} ble_gap_conn_params_t;
APP显示的名称; ↩︎
可以通过函数读取 sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len); ↩︎
可以通过函数设置 uint32_t, sd_ble_gap_appearance_set(uint16_t appearance); ↩︎
保持主从设备通过交换链路层数据数据保持链接; ↩︎
两个连接事件之间蓝牙睡眠更长时间; ↩︎
从机跳过连接事件的次数; ↩︎
两个成功的连接事件之间的间隔最大值,若超过这个时间还未出现成功的连接事件,那么设备将会考虑失去连接,返还未连接状态; ↩︎
有效连接事件时间 = 连接间隔 * (1 + 从机延迟值); ↩︎