Nordic系列芯片讲解十(修改nordic系列芯片的广播名)

修改nordic系列芯片广播名

一、local name 和device name的区别

关于local name 和device name,很多人可能有疑惑,为什么蓝牙有两个名字。可以这样简单地区分:
1.Local Name是广播出来的。Device Name是GATT service中的一个特性,需要连接后才能读或写。。
2.Local Name不能过长,因为广播包数据长度有限。Local Name有两类short和long。具体长度可以自己设置。Device Name的最长为248byte。Local Name最长能到达29bytes。

3.Local Name和Device Name要求保持一致性。Local Name必须是Device Name的开始连续的一部分或全部。例如Device Name是"BT_DEVICE",则Local Name可以是"BT_D"或 “BT_DEVICE”。

二、举例

1.如何用代码实现的

我们看看nordic sdk15.0的代码是如何去设置这两个名字的。
在这里插入图片描述

整个工程我们只看到“DEVICE_NAME”的宏定义。只找到设置Device Name,找不到设置local name的代码,其实是隐藏起来了。我们找到下面这个函数ble_advdata_encode,最后一段
在这里插入图片描述
这里是编码,把所有的adv data组合起来,用于广播的。我们再看深一层,看看name_encode这个函数。在这个函数里找到获取宏定义DEVICE_NAME里函数。

 // Get GAP device name and length
 err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) +AD_DATA_OFFSET],  &actual_length);

2.验证

既然我们找到了,我们一起来修改这两个变量试试:
把DEVICE_NAME改成这样

#define DEVICE_NAME                         "Nordic_HRM__Nordic_HRM__Nordic_HRM__Nordic_HRM__Nordic_HRM__Nordic_HRM__Nordic_HRM__"                            /**< Name of device. Will be included in the advertising data. */

然后运行一下,发现出错了。(晕)
我们再看看是哪里出现的问题,device name的长度最长是248,local name的长度看广播了多少东西,但是这个name_encode这个函数帮我们截断,不用我们担心。
看看出错的地方:
[外链图片转存失败(img-0ETZ0al8-1564398878266)(en-resource://database/1644:0)]
就是下面这个函数出现的问题。这个函数是API,我们看不到里面的代码。

    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                          (const uint8_t *)DEVICE_NAME,
                                          strlen(DEVICE_NAME));

看看注释

/**@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.
 */
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));

还是看不到什么东西,再看看这个类型 ble_gap_cfg_device_name_t

/**
 * @brief Device name and its properties, set with @ref sd_ble_cfg_set.
 *
 * @note  If the device name is not configured, the default device name will be
 *        @ref BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be
 *        @ref BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name
 *        will have no write access.
 *
 * @note  If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK,
 *        the attribute table size must be increased to have room for the longer device name (see
 *        @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t).
 *
 * @note  If vloc is @ref BLE_GATTS_VLOC_STACK :
 *        - p_value must point to non-volatile memory (flash) or be NULL.
 *        - If p_value is NULL, the device name will initially be empty.
 *
 * @note  If vloc is @ref BLE_GATTS_VLOC_USER :
 *        - p_value cannot be NULL.
 *        - If the device name is writable, p_value must point to volatile memory (RAM).
 *
 * @retval ::NRF_ERROR_INVALID_PARAM  One or more of the following is true:
 *                                    - Invalid device name location (vloc).
 *                                    - Invalid device name security mode.
 * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
 *                                    - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN).
 *                                    - The device name length is too long for the given Attribute Table.
 * @retval ::NRF_ERROR_NOT_SUPPORTED  Device name security mode is not supported.
 */
typedef struct
{
  ble_gap_conn_sec_mode_t  write_perm;   /**< Write permissions. */
  uint8_t                  vloc:2;       /**< Value location, see @ref BLE_GATTS_VLOCS.*/
  uint8_t                 *p_value;      /**< Pointer to where the value (device name) is stored or will be stored. */
  uint16_t                 current_len;  /**< Current length in bytes of the memory pointed to by p_value.*/
  uint16_t                 max_len;      /**< Maximum length in bytes of the memory pointed to by p_value.*/
} ble_gap_cfg_device_name_t;

好了,找到了BLE_GAP_DEVNAME_DEFAULT_LEN只有31,原来是我的设备名写得太长了。
怎么改呢,直接修改了BLE_GAP_DEVNAME_DEFAULT_LEN好像没用,因为这个函数没被调用,大家不要觉得协议栈能用到这个变量,协议栈的调用方式我之前介绍过,都是通过svc和swi的,就是中断服务函数,协议栈的变量不可能被应用层调用,反过来也是不可能的。

那怎么解决这个问题呢:
一、改短设备名的长度,小于31就没问题了。
二、上面的问题是因为分配的栈不足,那么怎么增大栈呢。
仔细看看nrf_sdh_ble_default_cfg_set这个函数,里面有很多分配stack的代码,我们依样画葫芦就好。在nrf_sdh_ble_default_cfg_set函数的最后增加下面的代码就可以了。


    // BLE_GAP_CFG_DEVICE_NAME.
    memset(&ble_cfg, 0x00, sizeof(ble_cfg));
    ble_cfg.gap_cfg.device_name_cfg.max_len = 248;
    ble_cfg.gap_cfg.device_name_cfg.vloc = BLE_GATTS_VLOC_STACK;
    ret_code = sd_ble_cfg_set(BLE_GAP_CFG_DEVICE_NAME, &ble_cfg, *p_ram_start);
    if (ret_code != NRF_SUCCESS)
    {
        NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GAP_CFG_DEVICE_NAME.",
                      nrf_strerror_get(ret_code));
    }

欢迎关注个人公众号“低功耗蓝牙技术研究及推广”
在这里插入图片描述

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值