一、背景
链路层(LL)控制设备的射频状态,有五个设备状态:待机、广播、扫描、初始化和连接。
广播 为广播数据包,而 扫描 则是监听广播。
GAP通信中角色,中心设备(Central - 主机)用来扫描和连接 外围设备(Peripheral - 从机)。
大部分情况下外围设备通过广播自己来让中心设备发现自己,并建立 GATT 连接,从而进行更多的数据交换。
也有些情况是不需要连接的,只要外设广播自己的数据即可,用这种方式主要目的是让外围设备,把自己的信息发送给多个中心设备。
在蓝牙 4.x 的协议中,广播包的大小为 31 个字节,如果主机有主动扫描,还有一个 31 字节大小的扫描响应包,也就是说如果是蓝牙 4.x 模式,最大可实现 62 个字节大小的广播内容。
在蓝牙 5.0 中,把广播信道抽象为两类,一种叫主广播信道(primary advertisement channels),另一种叫次广播信道,或者第二广播信道(secondary advertising packets)。
所谓的主广播类似于蓝牙 4.x 的广播,只工作在 37、38、39 三个信道,最大广播字节为 31 字节。而次广播允许蓝牙在除开 37、38、39 三个信道之外的其他 37 个信道上发送长度介于 0-255 字节的数据。次广播信道(0-36 channel)广播 255 字节数据。
二、广播内容参数
advdata:广播数据包
srdata:扫描响应包
————————————————
原文链接:https://blog.csdn.net/qq_36347513/article/details/104289279
一、蓝牙广播包的分类:
BEL蓝牙广播,有四种基本类型的广播包(也有扩展的),总结如下
(1)可连接、非定向的广播
这种广播,可以接受对方的扫描请求(如果对方是主动扫描),可以接受对方的连接请求。
简单说,只要收到广播包,谁都可以发送扫描请求和连接请求。
(2)可连接、定向广播
这种广播,不接受对方的扫描请求,只接受对方的连接请求。通常这种广播包报文仅含广播者的地址和连接发起者的地址,对方收到地址后,可以快速建立连接。
简单说,这种广播只针对特定地址的设备。
(3)不可连接、非定向的广播
这种广播,不接受对方的扫描请求、不接受对方的连接请求。这个与原始的含义相近。
(4)可扫描、非定向广播
这种广播,可以接受对方的扫描请求,以便对方能够通过扫描请求获取到更多的信息。但是也仅此而已,不接受对方的连接请求。
ps: 什么是主动扫描,什么是被动扫描,两者区别?
主动扫描,指的是打开扫描窗口,接收到广播包之后, 会再发起一个扫描请求。而被动扫描,则不会发起扫描请求。
设备受到扫描请求之后,会回复scan_response。当广播包不足以表示完整信息时,可以通过scan_response来进行补充。
对方可以通过scan_request来进一步获取更多信息。
————————————————
版权声明:本文为CSDN博主「liuxin_ph」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liuxin_ph/article/details/106603189
二、蓝牙广播包的结构
蓝牙广播包的结构:<len> <type> <data>,
len:占1个字节,是后面type和data的长度之和
type:占1个字节,数据的类型。见下图,常用的有0x01(发现标记),0x03(16位服务UUID),0x16(服务数据,16位UUID), 0xFF(厂家指定数据,苹果的ibeacon用的就是0xFF)
data:具体的数据
总长31个字节,可以包含多个 (len + type + data)
!!!注意:
(1)如果广播包是可连接的,包结构里面一定要包含type为1的标记数据,不然APP会连接不上
(2)扫描响应包里面不要加type为1的标记数据
继续
--dialog
cmd->op.code = GAPM_ADV_UNDIRECT;
/// Set advertising mode Command
struct gapm_start_advertise_cmd
{
/// GAPM requested operation:
/// - GAPM_ADV_NON_CONN: Start non connectable advertising
/// - GAPM_ADV_UNDIRECT: Start undirected connectable advertising
/// - GAPM_ADV_DIRECT: Start directed connectable advertising
/// - GAPM_ADV_DIRECT_LDC: Start directed connectable advertising using Low Duty Cycle
struct gapm_air_operation op;
看一下我dialog的代码 type
/****************************************************************************************
* Advertising Data types.
* See https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
****************************************************************************************/
#define ADV_TYPE_FLAGS --must-- "\x01" /* Flags */
#define ADV_TYPE_INCOMPLETE_LIST_16BIT_SERVICE_IDS "\x02" /* Incomplete list of 16-bit Service IDs */
#define ADV_TYPE_COMPLETE_LIST_16BIT_SERVICE_IDS --uuid-- "\x03" /* Complete list of 16-bit Service IDs */
#define ADV_TYPE_INCOMPLETE_LIST_32BIT_SERVICE_IDS "\x04" /* Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
#define ADV_TYPE_COMPLETE_LIST_32BIT_SERVICE_IDS "\x05" /* Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
#define ADV_TYPE_INCOMPLETE_LIST_128BIT_SERVICE_IDS "\x06" /* Incomplete list of 128-bit Service IDs */
#define ADV_TYPE_COMPLETE_LIST_128BIT_SERVICE_IDS "\x07" /* Complete list of 128-bit Service IDs */
#define ADV_TYPE_SHORTENED_LOCAL_NAME "\x08" /* Shortened Local Name */
#define ADV_TYPE_COMPLETE_LOCAL_NAME "\x09" /* Complete Local Name */
#define ADV_TYPE_TX_POWER_LEVEL "\x0A" /* TX Power Level (in dBm) */
#define ADV_TYPE_CLASS_OF_DEVICE "\x0D" /* Class of Device */
#define ADV_TYPE_SIMPLE_PAIRING_HASH_C "\x0E" /* Simple Pairing Hash C */
#define ADV_TYPE_SIMPLE_PAIRING_RANDOM_R "\x0F" /* Simple Pairing Randomizer R */
#define ADV_TYPE_DEVICE_ID "\x10" /* Device ID */
#define ADV_TYPE_SECURITY_MAN_OUT_OF_BAND_FLAGS "\x11" /* Security Manager Out of Band Flags */
#define ADV_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE "\x12" /* Slave Connection Interval Range */
#define ADV_TYPE_LIST_16BIT_SOLICITATION_UUIDS "\x14" /* List of 16-bit Service Solicitation UUIDs */
#define ADV_TYPE_LIST_32BIT_SOLICITATION_UUIDS "\x1F" /* List of 32-bit Service Solicitation UUIDs */
#define ADV_TYPE_LIST_128BIT_SOLICITATION_UUIDS "\x15" /* List of 128-bit Service Solicitation UUIDs */
#define ADV_TYPE_SERVICE_DATA_16BIT_UUID "\x16" /* Service Data - 16-bit UUID */
#define ADV_TYPE_SERVICE_DATA_32BIT_UUID "\x20" /* Service Data - 32-bit UUID */
#define ADV_TYPE_SERVICE_DATA_128BIT_UUID "\x21" /* Service Data - 128-bit UUID */
#define ADV_TYPE_LE_SECURE_CON_CONFIRM_VAL "\x22" /* LE Secure Connections Confirmation Value */
#define ADV_TYPE_LE_SECURE_CON_RANDOM_VAL "\x23" /* LE Secure Connections Random Value */
#define ADV_TYPE_PUBLIC_TARGET_ADDRESS "\x17" /* Public Target Address */
#define ADV_TYPE_RANDOM_TARGET_ADDRESS "\x18" /* Random Target Address */
#define ADV_TYPE_APPEARANCE "\x19" /* Appearance */
#define ADV_TYPE_ADVERTISING_INTERVAL "\x1A" /* Advertising Interval */
#define ADV_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS -- MAC --- "\x1B" /* LE Bluetooth Device Address */
#define ADV_TYPE_LE_ROLE "\x1C" /* LE Role */
#define ADV_TYPE_SIMPLE_PAIRING_HASH_C256 "\x1D" /* Simple Pairing Hash C-256 */
#define ADV_TYPE_SIMPLE_PAIRING_RANDOM_C256 "\x1E" /* Simple Pairing Randomizer R-256 */
#define ADV_TYPE_URI "\x24" /* Uniform Resource Identifier */
#define ADV_TYPE_INFO_DATA_3D "\x3D" /* 3D Information Data */
#define ADV_TYPE_MANUFACTURER_SPECIFIC_DATA "\xFF" /* Manufacturer Specific Data */
/****************************************************************************************
* AD Type Flag - Bit set.
****************************************************************************************/
#define ADV_FLAG_LE_LIMITED_DISCOVERABLE "\x01" /* LE Limited Discoverable Mode */
#define ADV_FLAG_LE_GENERAL_DISCOVERABLE "\x02" /* LE General Discoverable Mode */
#define ADV_FLAG_BREDR_NOT_SUPPORTED "\x04" /* BR/EDR Not Supported */
#define ADV_FLAG_SIMULTANEOUS_LE_BREDR_C "\x08" /* Simultaneous LE and BR/EDR to Same Device Capable (Controller) */
#define ADV_FLAG_SIMULTANEOUS_LE_BREDR_H "\x10" /* Simultaneous LE and BR/EDR to Same Device Capable (Host) */
可以调试下面函数
struct gapm_start_advertise_cmd AAAAA={0};
static struct gapm_start_advertise_cmd* app_easy_gap_undirected_advertise_start_create_msg(void)
{
// Allocate a message for GAP
if (adv_cmd == NULL)
{
ASSERT_ERROR(USER_ADVERTISE_DATA_LEN <= (ADV_DATA_LEN - 3)); // The Flags data type are added by the ROM
ASSERT_ERROR(USER_ADVERTISE_SCAN_RESPONSE_DATA_LEN <= SCAN_RSP_DATA_LEN);
struct gapm_start_advertise_cmd *cmd;
cmd = app_advertise_start_msg_create();
adv_cmd = cmd;
cmd->op.code = GAPM_ADV_UNDIRECT;
cmd->op.addr_src = user_adv_conf.addr_src;
cmd->intv_min = user_adv_conf.intv_min;
cmd->intv_max = user_adv_conf.intv_max;
cmd->channel_map = user_adv_conf.channel_map;
cmd->info.host.mode = user_adv_conf.mode;
cmd->info.host.adv_filt_policy = user_adv_conf.adv_filt_policy;
adv_cmd->info.host.adv_data_len = USER_ADVERTISE_DATA_LEN;
memcpy(&(cmd->info.host.adv_data[0]), USER_ADVERTISE_DATA, USER_ADVERTISE_DATA_LEN);
adv_cmd->info.host.scan_rsp_data_len = USER_ADVERTISE_SCAN_RESPONSE_DATA_LEN;
memcpy(&(cmd->info.host.scan_rsp_data[0]), USER_ADVERTISE_SCAN_RESPONSE_DATA, USER_ADVERTISE_SCAN_RESPONSE_DATA_LEN);
memcpy(&AAAAA, adv_cmd, sizeof(struct gapm_start_advertise_cmd));
#if (USER_CFG_ADDRESS_MODE == APP_CFG_CNTL_PRIV_RPA_RAND)
// Local Address has been added to RAL. Use this entry to advertise with RPA
memcpy(cmd->info.host.peer_info.addr.addr, &(gapm_env.addr), BD_ADDR_LEN * sizeof(uint8_t));
cmd->info.host.peer_info.addr_type = ((GAPM_F_GET(gapm_env.cfg_flags, ADDR_TYPE) == GAPM_CFG_ADDR_PUBLIC) ? ADDR_PUBLIC : ADDR_RAND);
#elif (USER_CFG_ADDRESS_MODE == APP_CFG_CNTL_PRIV_RPA_PUB)
// If there is at least one bond device in Bond Database, use its address to advertise with RPA, else use Public address
uint8_t bdb_size;
bool bonded_dev_found = false;
struct gap_ral_dev_info bonded_dev_info;
// Get Bond Database size
bdb_size = app_easy_security_bdb_get_size();
for (uint8_t bdb_slot = 0; bdb_slot < bdb_size; bdb_slot++)
{
bonded_dev_found = app_easy_security_bdb_get_device_info_from_slot(bdb_slot, &bonded_dev_info);
if (bonded_dev_found)
{
// Add peer device identity found in advertising command.
memcpy(cmd->info.host.peer_info.addr.addr, &bonded_dev_info.addr, BD_ADDR_LEN * sizeof(uint8_t));
cmd->info.host.peer_info.addr_type = bonded_dev_info.addr_type;
break;
}
}
#endif
// Place the Device Name in the Advertising Data or in the Scan Response Data
if (USER_DEVICE_NAME_LEN > 0)
{
// Get remaining space in the Advertising Data ( plus 2 bytes are used for the length and flag bytes of the Device Name and 3 bytes for the AD type flags)
uint16_t total_adv_space = 3 + adv_cmd->info.host.adv_data_len + 2 + USER_DEVICE_NAME_LEN;
// Get remaining space in the Scan Response Data ( plus 2 bytes are used for the length and flag bytes of the Device Name)
uint16_t total_scan_space = adv_cmd->info.host.scan_rsp_data_len + 2 + USER_DEVICE_NAME_LEN;
if (total_adv_space <= ADV_DATA_LEN)
{
append_device_name(&cmd->info.host.adv_data_len,
USER_DEVICE_NAME_LEN,
&(cmd->info.host.adv_data[cmd->info.host.adv_data_len]),
USER_DEVICE_NAME);
}
else if (total_scan_space <= SCAN_RSP_DATA_LEN)
{
append_device_name(&cmd->info.host.scan_rsp_data_len,
USER_DEVICE_NAME_LEN,
&(cmd->info.host.scan_rsp_data[cmd->info.host.scan_rsp_data_len]),
USER_DEVICE_NAME);
}
}
}
memcpy(&AAAAA, adv_cmd, sizeof(struct gapm_start_advertise_cmd));
return adv_cmd;
}
kan'dao看到看到广播有2个 我们自己的TLV 回答一个TLV是在后面memcpy的 但是0X01 0XFF这2个广播type是我们没有写的 可能是ROM自己搞的
最后 的if else 是广播放不放的下 放得下就广播 放不下就去sck里面放
WHY 还有OXFF
原理是用户这里啊
/// GAP Advertising Flags
enum gap_ad_type
{
/// Flag
GAP_AD_TYPE_FLAGS = 0x01,
/// Use of more than 16 bits UUID
GAP_AD_TYPE_MORE_16_BIT_UUID = 0x02,
/// Complete list of 16 bit UUID
GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID = 0x03,
/// Use of more than 32 bit UUD
GAP_AD_TYPE_MORE_32_BIT_UUID = 0x04,
/// Complete list of 32 bit UUID
GAP_AD_TYPE_COMPLETE_LIST_32_BIT_UUID = 0x05,
/// Use of more than 128 bit UUID
GAP_AD_TYPE_MORE_128_BIT_UUID = 0x06,
/// Complete list of 128 bit UUID
GAP_AD_TYPE_COMPLETE_LIST_128_BIT_UUID = 0x07,
/// Shortened device name
GAP_AD_TYPE_SHORTENED_NAME = 0x08,
/// Complete device name
GAP_AD_TYPE_COMPLETE_NAME = 0x09,
/// Transmit power
GAP_AD_TYPE_TRANSMIT_POWER = 0x0A,
/// Class of device
GAP_AD_TYPE_CLASS_OF_DEVICE = 0x0D,
/// Simple Pairing Hash C
GAP_AD_TYPE_SP_HASH_C = 0x0E,
/// Simple Pairing Randomizer
GAP_AD_TYPE_SP_RANDOMIZER_R = 0x0F,
/// Temporary key value
GAP_AD_TYPE_TK_VALUE = 0x10,
/// Out of Band Flag
GAP_AD_TYPE_OOB_FLAGS = 0x11,
/// Slave connection interval range
GAP_AD_TYPE_SLAVE_CONN_INT_RANGE = 0x12,
/// Require 16 bit service UUID
GAP_AD_TYPE_RQRD_16_BIT_SVC_UUID = 0x14,
/// Require 32 bit service UUID
GAP_AD_TYPE_RQRD_32_BIT_SVC_UUID = 0x1F,
/// Require 128 bit service UUID
GAP_AD_TYPE_RQRD_128_BIT_SVC_UUID = 0x15,
/// Service data 16-bit UUID
GAP_AD_TYPE_SERVICE_16_BIT_DATA = 0x16,
/// Service data 32-bit UUID
GAP_AD_TYPE_SERVICE_32_BIT_DATA = 0x20,
/// Service data 128-bit UUID
GAP_AD_TYPE_SERVICE_128_BIT_DATA = 0x21,
/// Public Target Address
GAP_AD_TYPE_PUB_TGT_ADDR = 0x17,
/// Random Target Address
GAP_AD_TYPE_RAND_TGT_ADDR = 0x18,
/// Appearance
GAP_AD_TYPE_APPEARANCE = 0x19,
/// Advertising Interval
GAP_AD_TYPE_ADV_INTV = 0x1A,
/// LE Bluetooth Device Address
GAP_AD_TYPE_LE_BT_ADDR = 0x1B,
/// LE Role
GAP_AD_TYPE_LE_ROLE = 0x1C,
/// Simple Pairing Hash C-256
GAP_AD_TYPE_SPAIR_HASH = 0x1D,
/// Simple Pairing Randomizer R-256
GAP_AD_TYPE_SPAIR_RAND = 0x1E,
/// Uniform Resource Identifier
GAP_AD_TYPE_URI = 0x24,
/// 3D Information Data
GAP_AD_TYPE_3D_INFO = 0x3D,
/// Manufacturer specific data
GAP_AD_TYPE_MANU_SPECIFIC_DATA = 0xFF,
};
app_add_ad_struct(cmd, &mnf_data, sizeof(struct mnf_specific_data_ad_structure), 1);
其实也不是flag 是一个比较抠门的写法 因为mnf_data_index是个比较小31-28的数据 0X80最高位不会被用到 就当一个flag吧
看这句话 再次说明是LTV结构
memcpy(mnf_data_storage + (mnf_data_index & 0x7F), &mnf_data, sizeof(struct mnf_specific_data_ad_structure));
直接把mnf_data全部放进来 那么他就是L--T--V
其中T是OXFF
L 是sizeof-1 明白吧 需要把自己减掉
接一句 mnf_data.proprietary_data[0]++; 看到广播的数据在变化了
测试一下 不可连接的ble dialog没有这样的sdk 函数接口不同的 不是修改一个type即可 需要换函数的
user_app_adv_start
app_easy_gap_undirected_advertise_get_active -- app_easy_gap_non_connectable_advertise_get_active
app_easy_gap_undirected_advertise_start_create_msg
struct gapm_start_advertise_cmd *cmd;
/// Set advertising mode Command
struct gapm_start_advertise_cmd
{
/// GAPM requested operation:
/// - GAPM_ADV_NON_CONN: Start non connectable advertising
/// - GAPM_ADV_UNDIRECT: Start undirected connectable advertising
/// - GAPM_ADV_DIRECT: Start directed connectable advertising
/// - GAPM_ADV_DIRECT_LDC: Start directed connectable advertising using Low Duty Cycle
void app_easy_gap_non_connectable_advertise_start(void)
{
struct gapm_start_advertise_cmd* cmd;
cmd = app_easy_gap_non_connectable_advertise_start_create_msg();
名字
https://blog.csdn.net/Lanal11/article/details/98473626
广播设备信息
app_add_ad_struct(cmd, &mnf_data, sizeof(struct mnf_specific_data_ad_structure), 1);
mnf_data_update();
static void mnf_data_init()
在这里明白了0XFF这个部分了内容 也就是TYPE
static void append_device_name(uint8_t *len,
const uint8_t name_length,
uint8_t *data,
const void *name_data)
type是9
*/
D:\BaiduNetdiskDownload\mCube_mc36xx_data_notifcation_DA14585\6.0.10.511\sdk\app_modules\src\app_common\app.c(372) :
memcpy(&(cmd->info.host.adv_data[0]), USER_ADVERTISE_DATA, USER_ADVERTISE_DATA_LEN);
#define USER_ADVERTISE_DATA ("\x03"\
ADV_TYPE_COMPLETE_LIST_16BIT_SERVICE_IDS\
ADV_UUID_DEVICE_INFORMATION_SERVICE\
"\x11"\
ADV_TYPE_COMPLETE_LIST_128BIT_SERVICE_IDS\
"\x2F\x2A\x93\xA6\xBD\xD8\x41\x52\xAC\x0B\x10\x99\x2E\xC6\xFE\xED")
/// Advertising data length - maximum 28 bytes, 3 bytes are reserved to set
#define USER_ADVERTISE_DATA_LEN (sizeof(USER_ADVERTISE_DATA)-1)
#define USER_ADVERTISE_DATA ("\x03"\---length 3
"\x03"\ ----type 3
"\x0A\x18"\
"\x11"\ -----length 17
"\x07"\ ---type 7
"\x2F\x2A\x93\xA6\xBD\xD8\x41\x52\xAC\x0B\x10\x99\x2E\xC6\xFE\xED")
这里明白了2个TYPE
那么TYPE是9的 猜一猜是名字
https://www.fedte.cc/ascii
DLG-ACCL
68,76,71,45,65,67,67,76
在哪里加入广播的呢?
gapm_start_advertise_cmd
uint8_t adv_data[ADV_DATA_LEN];
小姐:
**********************************************************************************
static struct gapm_start_advertise_cmd* app_easy_gap_undirected_advertise_start_create_msg(void)
{
adv_cmd->info.host.adv_data_len = USER_ADVERTISE_DATA_LEN;
memcpy(&(cmd->info.host.adv_data[0]), USER_ADVERTISE_DATA, USER_ADVERTISE_DATA_LEN);---看到2个部分
append_device_name(&cmd->info.host.adv_data_len,---看到设备名字在广播部分
USER_DEVICE_NAME_LEN,
&(cmd->info.host.adv_data[cmd->info.host.adv_data_len]),
USER_DEVICE_NAME);
}
#define USER_ADVERTISE_DATA ("\x09"\
ADV_TYPE_COMPLETE_LIST_16BIT_SERVICE_IDS\----- "\x03"
ADV_UUID_LINK_LOSS_SERVICE\-----"\x03\x18" /* Link Loss */
ADV_UUID_IMMEDIATE_ALERT_SERVICE\------ "\x02\x18" /* Immediate Alert */
ADV_UUID_TX_POWER_SERVICE\----- "\x04\x18" /* Tx Power */
ADV_UUID_SUOTAR_SERVICE\----- "\xF5\xFE" /* SUOTAR Service */
"\x10"\
ADV_TYPE_URI\---- "\x24" /* Uniform Resource Identifier */
"\x16\x2F\x2F\x77\x77\x77\x2E\x69\x61\x6E\x61\x2E\x6F\x72\x67")
\x09\x03\x03\x18x02\x18\x04\x1\xF5\xFE---x10x24\x16\x2F\x2F\x77\x77\x77\x2E\x69\x61\x6E\x61\x2E\x6F\x72\x67
struct gapm_adv_host AAAA={0};
static struct gapm_start_advertise_cmd* app_easy_gap_undirected_advertise_start_create_msg(void)
{
memcpy(&AAAA,&(cmd->info.host),sizeof(struct gapm_adv_host));
看到就这样
append_device_name(&cmd->info.host.adv_data_len,
append_device_name(&cmd->info.host.scan_rsp_data_len,
这2个数组 都是在广播里面的!!!!!
&(cmd->info.host.adv_data[cmd->info.host.adv_data_len]),
&(cmd->info.host.scan_rsp_data[cmd->info.host.scan_rsp_data_len]),
#define USER_ADVERTISE_SCAN_RESPONSE_DATA "\x0a"\
ADV_TYPE_MANUFACTURER_SPECIFIC_DATA\
ADV_DIALOG_MANUFACTURER_CODE\
"DLG-BLE"
继续 在广播的时候 已经把UUID广播出去了 就是它的服务有哪些!!!
https://blog.csdn.net/bi_jian/article/details/82927904 不错
自己增加一个广播
D:\git\dialog\6.0.10.511\projects\target_apps\ble_examples\mCube_mc36xx_data_notifcation\src\user_app\user_accelerometer.c
第一步 搞一个LTV
#define APP_URL_MSD_DATA_LEN 9
struct mnf_specific_data_url_structure
{
uint8_t url_structure_size;
uint8_t url_structure_type;
uint8_t url_webset[APP_URL_MSD_DATA_LEN];
};
这里我的结构体是11 因为AD用完了 在扫描应答31中已经用了22 还有11个空余的
// Retained variables
struct mnf_specific_data_ad_structure mnf_data __attribute__((section("retention_mem_area0"), zero_init)); //@RETENTION MEMORY
struct mnf_specific_data_url_structure url_data __attribute__((section("retention_mem_area0"), zero_init)); //@RETENTION MEMORY
在init
static void mnf_data_init()
{
mnf_data.ad_structure_size = sizeof(struct mnf_specific_data_ad_structure ) - sizeof(uint8_t); // minus the size of the ad_structure_size field
mnf_data.ad_structure_type = GAP_AD_TYPE_MANU_SPECIFIC_DATA;
mnf_data.company_id[0] = APP_AD_MSD_COMPANY_ID & 0xFF; // LSB
mnf_data.company_id[1] = (APP_AD_MSD_COMPANY_ID >> 8 )& 0xFF; // MSB
mnf_data.proprietary_data[0] = 0;
mnf_data.proprietary_data[1] = 0;
url_data.url_structure_size = sizeof(struct mnf_specific_data_url_structure ) - sizeof(uint8_t);
url_data.url_structure_type = GAP_AD_TYPE_URI;
memcpy(url_data.url_webset,"www.baidu.com",APP_URL_MSD_DATA_LEN);
}
再就是去追加了
void user_app_adv_start(void)
{
// Schedule the next advertising data update
app_adv_data_update_timer_used = app_easy_timer(APP_ADV_DATA_UPDATE_TO, adv_data_update_timer_cb);
struct gapm_start_advertise_cmd* cmd;
cmd = app_easy_gap_undirected_advertise_get_active();
// Add manufacturer data to initial advertising or scan response data, if there is enough space
app_add_ad_struct(cmd, &mnf_data, sizeof(struct mnf_specific_data_ad_structure), 1);
app_add_ad_struct(cmd, &url_data, sizeof(struct mnf_specific_data_url_structure), 1);
app_easy_gap_undirected_advertise_start();
}
这时候就好了
但是手机APP看到有点问题
这里需要del
static void adv_data_update_timer_cb()
{
// If mnd_data_index has MSB set, manufacturer data is stored in scan response
uint8_t *mnf_data_storage = (mnf_data_index & 0x80) ? stored_scan_rsp_data : stored_adv_data;
// Update manufacturer data
mnf_data_update();
// Update the selected fields of the advertising data (manufacturer data)
// memcpy(mnf_data_storage + (mnf_data_index & 0x7F), &mnf_data, sizeof(struct mnf_specific_data_ad_structure));
// memcpy(mnf_data_storage + (mnf_data_index & 0x7F), &url_data, sizeof(struct mnf_specific_data_url_structure));
// Update advertising data on the fly
app_easy_gap_update_adv_data(stored_adv_data, stored_adv_data_len, stored_scan_rsp_data, stored_scan_rsp_data_len);
// Restart timer for the next advertising update
app_adv_data_update_timer_used = app_easy_timer(APP_ADV_DATA_UPDATE_TO, adv_data_update_timer_cb);
}
因为追加的时候 我们搞了2次 逻辑有点混乱 我们app_add_ad_struct这个函数是套用的
后面周期性修改 出问题了