一、简介

iBeacon 是苹果公司2013年9月发布的移动设备用 OS(iOS7)上配备的新功能。其工作方式是,配备有 低功耗蓝牙(BLE) 通信功能的设备使用 BLE 技术向周围发送自己特有的 ID,接收到该 ID 的应用软件会根据该 ID 采取一些行动。比如,在店铺里设置 iBeacon 通信模块的话,便可让 iPhone 和 iPad 上运行一资讯告知服务器,或者由服务器向顾客发送折扣券及进店积分。此外,还可以在家电发生故障或停止工作时使用 iBeacon 向应用软件发送资讯。

二、iBeacon格式

iBeacon 使用的是 BLE 技术,具体而言,利用的是 BLE 中名为“通告帧”(Advertising)的广播帧。通告帧是定期发送的帧,只要是支持 BLE 的设备就可以接收到。iBeacon 通过在这种通告帧的有效负载部分嵌入苹果自主格式的数据来实现。

AD Field Length Type Company ID iBeacon Type iBeacon Length UUID Major Minor TX Power

AD Field Length: Advertisement Data 的长度,表示有用的广播信息长度
Type: 广播类型
Company ID: 数据字段以两字节的公司 ID 码开始。SIG 将这些 ID 码发放给公司,其中 0x004C 代表的是Apple id(只有这个 ID,设备才会叫 iBeacon)
iBeacon Type: 字节 0x02 代表这个设备是 Beacon
iBeacon Length: 剩下字段的长度
UUID: 规定为 ISO/IEC11578:1996 标准的 128 位标识符
Major、Minor: 由 iBeacon 发布者自行设定,都是 16 位的标识符。比如,连锁店可以在 Major 写入区域资讯,可在 Minor 中写入个别店铺的 ID 等。另外,在家电中嵌入 iBeacon 功能时,可以用 Major 表示产品型号,用 Minor 表示错误代码,用来向外部通知故障
TX Power: APP 通过 iBeacon 发送信号强度估算出的在 1 米的时候 RSSI 强度

三、示例代码

首先我们先定义 beacon 相关的数据,其中我们用户需要关注的主要有3个参数,UUID、Major 以及 Minor,其他的参数大家可以理解为固定的格式(格式固定,但数据内容不固定,可能有不同的厂商信息)。另外还有一个值得我们关注的数据,那就是 APP_COMPANY_IDENTIFIER,如果我们定义此参数为 0x004C(也就是 Apple id),那么我们的基站设备就被成为 iBeacon。

#define ESP_UUID    {0xFD, 0xA5, 0x06, 0x93, 0xA4, 0xE2, 0x4F, 0xB1, 0xAF, 0xCF, 0xC6, 0xEB, 0x07, 0x64, 0x78, 0x25}
#define ESP_MAJOR   10167
#define ESP_MINOR   61958typedef struct {uint8_t flags[3];uint8_t length;uint8_t type;uint16_t company_id;uint16_t beacon_type;
}__attribute__((packed)) esp_ble_ibeacon_head_t;typedef struct {uint8_t proximity_uuid[16];uint16_t major;uint16_t minor;int8_t measured_power;
}__attribute__((packed)) esp_ble_ibeacon_vendor_t;typedef struct {esp_ble_ibeacon_head_t ibeacon_head;esp_ble_ibeacon_vendor_t ibeacon_vendor;
}__attribute__((packed)) esp_ble_ibeacon_t;/* For iBeacon packet format, please refer to Apple "Proximity Beacon Specification" doc */
/* Constant part of iBeacon data */
esp_ble_ibeacon_head_t ibeacon_common_head = {.flags = {0x02, 0x01, 0x06},.length = 0x1A,.type = 0xFF,.company_id = 0x004C,.beacon_type = 0x1502
};/* Vendor part of iBeacon data*/
esp_ble_ibeacon_vendor_t vendor_config = {.proximity_uuid = ESP_UUID,.major = ENDIAN_CHANGE_U16(ESP_MAJOR), //Major=ESP_MAJOR.minor = ENDIAN_CHANGE_U16(ESP_MINOR), //Minor=ESP_MINOR.measured_power = 0xC5
};

对于 iBeacon 的数据,通过广播形式广播出去,那么其主要设置就是主函数里配置广播内容 esp_ble_gap_config_adv_data_raw()

在 GAP 事件回调中,触发设置原始广告数据完成事件 ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT,调用 esp_ble_gap_start_advertising() 启动广播后,就可以实现广播信息的发出,也就是信标的广播包的广播。

根据 esp-idf\examples\bluetooth\bluedroid\ble\ble_ibeacon 中的例程修改

#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "nvs_flash.h"#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#include "esp_gattc_api.h"
#include "esp_gatt_defs.h"
#include "esp_bt_main.h"
#include "esp_bt_defs.h"
#include "esp_ibeacon_api.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"static const char* DEMO_TAG = "IBEACON_DEMO";
extern esp_ble_ibeacon_vendor_t vendor_config;///Declare static functions
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);static esp_ble_adv_params_t ble_adv_params = {.adv_int_min        = 0x20,.adv_int_max        = 0x40,.adv_type           = ADV_TYPE_NONCONN_IND,.own_addr_type      = BLE_ADDR_TYPE_PUBLIC,.channel_map        = ADV_CHNL_ALL,.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{esp_err_t err;switch (event) {case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:{esp_ble_gap_start_advertising(&ble_adv_params);break;}case ESP_GAP_BLE_ADV_START_COMPLETE_EVT://adv start complete event to indicate adv start successfully or failedif ((err = param->adv_start_cmpl.status) != ESP_BT_STATUS_SUCCESS) {ESP_LOGE(DEMO_TAG, "Adv start failed: %s", esp_err_to_name(err));}break;case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:if ((err = param->adv_stop_cmpl.status) != ESP_BT_STATUS_SUCCESS){ESP_LOGE(DEMO_TAG, "Adv stop failed: %s", esp_err_to_name(err));}else {ESP_LOGI(DEMO_TAG, "Stop adv successfully");}break;default:break;}
}void ble_ibeacon_appRegister(void)
{esp_err_t status;ESP_LOGI(DEMO_TAG, "register callback");//register the scan callback function to the gap moduleif ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) {ESP_LOGE(DEMO_TAG, "gap register error: %s", esp_err_to_name(status));return;}}void ble_ibeacon_init(void)
{esp_bluedroid_init();       // 初始化蓝牙栈bluedroid stackesp_bluedroid_enable();     // 使能蓝牙栈ble_ibeacon_appRegister();
}void app_main(void)
{ESP_ERROR_CHECK(nvs_flash_init());          // 初始化NVSESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); // 释放经典蓝牙在控制器中内存esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();esp_bt_controller_init(&bt_cfg);            // 初始化蓝牙控制器esp_bt_controller_enable(ESP_BT_MODE_BLE);  // 使能蓝牙控制器ble_ibeacon_init();esp_ble_ibeacon_t ibeacon_adv_data;esp_err_t status = esp_ble_config_ibeacon_data (&vendor_config, &ibeacon_adv_data);if (status == ESP_OK){esp_ble_gap_config_adv_data_raw((uint8_t*)&ibeacon_adv_data, sizeof(ibeacon_adv_data));}else {ESP_LOGE(DEMO_TAG, "Config iBeacon data failed: %s\n", esp_err_to_name(status));}
}

查看打印:

查看广播:


• 由 Leung 写于 2021 年 7 月 6 日

ESP32学习笔记(29)——BLE iBeacon广播相关推荐

  1. ESP32学习笔记(27)——BLE GAP主机端扫描

    一.背景 1.1 低功耗蓝牙(BLE)协议栈 链路层(LL) 控制设备的射频状态,有五个设备状态:待机.广播.扫描.初始化和连接. 广播 为广播数据包,而 扫描 则是监听广播. GAP通信中角色,中心 ...

  2. ESP32学习笔记(30)——BLE GATT服务端自定义服务和特征

    一.简介 1.1 低功耗蓝牙(BLE)协议栈 链路层(LL) 控制设备的射频状态,有五个设备状态:待机.广播.扫描.初始化和连接. 广播 为广播数据包,而 扫描 则是监听广播. GAP通信中角色,中心 ...

  3. 关于esp32蓝牙模块的使用——esp32学习笔记

    关于esp32蓝牙模块的使用--esp32学习笔记 关于esp32蓝牙模块的使用--esp32学习笔记 关于esp32蓝牙模块的使用--esp32学习笔记 零.前言 一.经典蓝牙BT 二.低功耗蓝牙B ...

  4. ESP32学习笔记(7)——SmartConfig接口使用(ESP-Touch和AirKiss)

    一.概述 SmartConfig是TI开发的一种配置技术,用于将新的Wi-Fi设备连接到Wi-Fi网络.它使用移动应用程序将网络凭据从智能手机或平板电脑广播到未配置的Wi-Fi设备. 该技术的优点是设 ...

  5. ESP32学习笔记(1)——搭建环境、编译烧写(Windows+VS Code)

    Espressif-IDE 环境搭建参看 ESP32学习笔记(50)--搭建环境.编译烧写(Windows+Espressif-IDE) 一.搭建环境 1.1 官方资料 ESP-IDF 编程指南 1. ...

  6. ESP32学习笔记(七) 复位和时钟

    ESP32学习笔记(七) 复位和时钟 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介绍 ...

  7. ESP32学习笔记(49)——RFID RC522使用

    一.简介 MF RC522 是应用于 13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员.是 NXP 公司针对"三表"应用推出的一款低电压.低成本.体积小的非接触式读写 ...

  8. ESP32学习笔记(20)——SPI(从机)接口使用

    一.SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC.LCD ...

  9. ESP32学习笔记(一) 芯片型号介绍

    ESP32学习笔记(一) 芯片型号介绍 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介 ...

  10. ESP32学习笔记(19)——SPI(主机)接口使用

    一.SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC.LCD ...

最新文章

  1. 漫谈云计算、虚拟化、容器化--云平台技术栈05
  2. 史上最快! 10小时大数据入门实战(五)-分布式计算框架MapReduce
  3. 使用Throwable获得栈信息
  4. 新的C库Bionic的介绍
  5. python定义一个_Python,包括定义一个类
  6. 一行代码没写,凭啥被尊为“第一位程序员”?
  7. 多年前写的一个ASP.NET网站管理系统,到现在有些公司在用
  8. 安全还是效率? 移动化的两难抉择
  9. FastDFS同ip同机器迁移存储位置
  10. KVM虚拟化技术实践
  11. Drupal 建站
  12. c++中的 trivial destructor
  13. mm游戏大全HTML5小游戏,HTML5小游戏——看你有多色(示例代码)
  14. 地图配色及网络地图比较
  15. Spring AOP组合使用多个切入点表达式
  16. BP神经网络隐含层节点数的确定
  17. html怎样使得链接在新窗口中打开
  18. 数据预处理与特征工程—12.常见的数据预处理与特征工程手段总结
  19. FFMpeg 实现视频编码、解码
  20. icloud安装错误怎么办_怎么办?iCloud云备份失败该如何解决?

热门文章

  1. 用Python带大家写个自动生成艺术签名的小工具哟~
  2. php限制选择图片数量,ImagePicker组件,限制选择图片数量上限(selectable={images.length 3} )失败...
  3. 自然语言处理基于java实现(1) 之 中文分词
  4. 晶振旁的电阻(并联与串联)
  5. Object中的同步机制[转]
  6. 微信小程序中 scroll-view滚动条始终在最底部
  7. MongoDB实验练习题
  8. 淘宝双11大数据分析(Spark 分析篇)
  9. python 全栈开发是什么意思_我为什么说Python是全栈式开发语言?
  10. “esxcli software vib” commands to patch an ESXi 5.x/6.x host (2008939)