Zephyr NRF7002 实现AppleJuice

BLE的基础知识

在这里插入图片描述

ble的信道和BR/EDR的信道是完全不一样的。但是范围是相同的,差不多也都是2.4Ghz的频道。可以简单理解为空中有40个信道0~39信道。两个设备在相同的信道里面可以进行相互通信。

而这些信道SIG又重新编号:

../../_images/adv_channel2.png

这个编号就是把37 38 39。 3个信道抽出来,作为广播信道,其他都是数据信道。这篇文章主要讲广播,所以基本数据信息都是围绕37 38 39这三个信道上面的通信来讲的。

我们可以看到这3个信道是分散排列的。大家可以思考下为什么。

其实看下面一张图就知道了。

../../_images/wifi_channel.png

数据广播

广播组成部分

广播分为如下几个部分:

  • 广播
  • 扫描请求
  • 扫描响应

在这里插入图片描述

广播的报文格式

在这里插入图片描述

{
    "AD1":{
        "Length":12,
        "Data":{
            "AD_Type":12,
            "AD_Data":"123123"
        }
    },
    "AD2":{
        "Length":12,
        "Data":{
            "AD_Type":12,
            "AD_Data":"123123"
        }
    }
}

记忆要点

每个元素里面有两个要素:1. 长度(length), 2. 数据(data)

  • 每个数据里面又包含两个元素:1. 类型(type), 2. 数据(data)

  • 总结一下就是一个L T V模型(length, type, data)

  • 这个length代表的是后面数据有多长,不包含length的长度。

  • 总的Len一般不超过31字节

参考:

2. BLE 广播和扫描 — bluetoothlover_wiki 0.0.1 文档 (supperthomas-wiki.readthedocs.io)

AD_Type 官方定义

抓包参考:

在这里插入图片描述

APPLE JUICE功能实现

在这里插入图片描述

1.流程梳理

主要需要实现如下功能点:

  • ble 广播开启和关闭
  • ble GAP层各种参数的设置
  • ble MAC地址动态修改

2.Zephyr 中相关接口:

功能接口:

接口名功能描述备注
bt_enable开启BLE功能
bt_le_adv_start开启BLE广播
bt_le_adv_update_data更新BLE广播内容此接口是否实时?未找到对应生效CallBack
bt_le_adv_stop关闭BLE广播
bt_id_create更新广播随机地址

注:

上述接口在执行完成后均会抛出回调:

/*
参数回调注册
*/
void bt_conn_cb_register(struct bt_conn_cb *cb);

struct bt_conn_cb {
    //已建立新连接
	void (*connected)(struct bt_conn *conn, uint8_t err);
	//连接已断开
	void (*disconnected)(struct bt_conn *conn, uint8_t reason);
    //LE 连接参数更新请求
	bool (*le_param_req)(struct bt_conn *conn,
			     struct bt_le_conn_param *param);
	//LE 连接的参数已更新
	void (*le_param_updated)(struct bt_conn *conn, uint16_t interval,
				 uint16_t latency, uint16_t timeout);
#if defined(CONFIG_BT_SMP)
	//远程身份地址通过
	void (*identity_resolved)(struct bt_conn *conn,
				  const bt_addr_le_t *rpa,
				  const bt_addr_le_t *identity);
#endif /* CONFIG_BT_SMP */
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
	//连接的安全级别已更改
	void (*security_changed)(struct bt_conn *conn, bt_security_t level,
				 enum bt_security_err err);
#endif /* defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR) */

#if defined(CONFIG_BT_REMOTE_INFO)
	//远程信息程序已完成
	void (*remote_info_available)(struct bt_conn *conn,
				      struct bt_conn_remote_info *remote_info);
#endif /* defined(CONFIG_BT_REMOTE_INFO) */

#if defined(CONFIG_BT_USER_PHY_UPDATE)
	//连接的 PHY 已更改
	void (*le_phy_updated)(struct bt_conn *conn,
			       struct bt_conn_le_phy_info *param);
#endif /* defined(CONFIG_BT_USER_PHY_UPDATE) */

#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE)
	//连接的数据长度参数已更改
	void (*le_data_len_updated)(struct bt_conn *conn,
				    struct bt_conn_le_data_len_info *info);
#endif /* defined(CONFIG_BT_USER_DATA_LEN_UPDATE) */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
	void (*cte_report_cb)(struct bt_conn *conn,
			      const struct bt_df_conn_iq_samples_report *iq_report);
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */

#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL)
	void (*tx_power_report)(struct bt_conn *conn,
				const struct bt_conn_le_tx_power_report *report);
#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */
	struct bt_conn_cb *_next;
};

bt_data接口

Zephyr 封装好了部分gap填充接口,在编写广播数据(bt_data)数组的时候可以通过以下宏来辅助:


/**
 * @brief Construct a new bt data object
 * 
 * 	_type: GAP字段的类型
 * 	_data: GAP RAW 数据
 * 	_data_len: RAW数据长度
 */
#define BT_DATA(_type, _data, _data_len) \
	{ \
		.type = (_type), \
		.data_len = (_data_len), \
		.data = (const uint8_t *)(_data), \
	}
    
/**
 * @brief Construct a new bt data object
 * 
 * 	_type: GAP字段的类型
 * 	_bytes: GAP RAW 数据
 */    
#define BT_DATA_BYTES(_type, _bytes...) \
	BT_DATA(_type, ((uint8_t []) { _bytes }), \
		sizeof((uint8_t []) { _bytes }))

参考:

5. BLE — BL_MCU_SDK 开发指南 0.3 文档 (gitee.io)

Zephyr API文档:通用访问配置文件(GAP) (zephyrproject.org)

3. 广播数据填充

AD_Data字段:

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_MANUFACTURER_DATA,
				  0x4c, 0x00, 0x07, 0x19, 0x07, 0x0a, 0x20,
				  0x75, 0xaa, 0x30, 0x01, 0x00, 0x00, 0x45,
				  0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00,
				  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
				  0x00)};

开启广播的时候将ad传入,即可完成广播数据设置。

4.随机地址切换

Apple对于相同MAC地址的设备仅会进行一次弹窗,因此如果想要让手机不断的弹出设备提示框就需要定期修改BLE的MAC地址,代码如下:

bt_addr_le_t local_mac_addr;
		size_t localmac_size = 1;
		static bt_addr_le_t myaddr = {
			.type = BT_ADDR_LE_RANDOM,
			/* fixed MAC addres */
			.a = {
				.val = {0x01, 0x02, 0x03, 0x04, 0x05, 0xc6},
			},
		};
		printk("bt_id_create\r\n");
		err = bt_id_create(&myaddr, NULL);
		if (err < 0)
		{
			printk("bt_id_create err!\r\n");
		}

小思考:这里思考了下苹果的设计美学,以AirPods为例。通常情况下设备为了节约电池电量并不会一直进行BLE广播,而是在每次打开电池仓时才唤醒ble芯片,关闭电池仓之后进入超低功耗模式。BLE设备的程序在每次唤醒的时候程序会从新启动,所以MAC地址发生改变。

效果演示

在这里插入图片描述

问题和解决方法

  • 问题描述:使用7002DK开发板运行时出现如下问题。
    在这里插入图片描述

  • 原因分析:默认情况下adv字段允许的最大长度为31字节, 当数据填充超出会出现上述报警。

  • 解决方法:可以开启ble的拓展广播功能来增加最大数据长度。相关配置可以参考Demo periodic_adv,相关Menuconfig修改点如下图所示:

在这里插入图片描述
在这里插入图片描述

完整代码:

/**
 * @file main.c
 * @author Argon
 * @brief  BLE Apple 
 * @version 0.1
 * @date 2024-01-20
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#include <zephyr/types.h>
#include <stddef.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>


//扫描数据段
static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_MANUFACTURER_DATA,
				  0x4c, 0x00, 0x07, 0x19, 0x07, 0x0a, 0x20,
				  0x75, 0xaa, 0x30, 0x01, 0x00, 0x00, 0x45,
				  0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00,
				  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
				  0x00)};

//扫描响应数据段
static const struct bt_data sd[] = {
	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
	BT_DATA_BYTES(BT_DATA_PERIPHERAL_INT_RANGE, 0x20, 0x00, 0x40, 0x00),
	BT_DATA_BYTES(BT_DATA_TX_POWER, 0x09),
};

//设备名
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)


int main(void)
{
	int err;

	printk("BLE Starting\n");

	/* Initialize the Bluetooth Subsystem */
	err = bt_enable(NULL);
	if (err)
	{
		printk("Ble init failed (err %d)\n", err);
		return 0;
	}

	printk("Ble initialized\n");

	do
	{
		//开启广播
		printk("Ble adv start\r\n");
		err = bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad),
							  sd, ARRAY_SIZE(sd));
		if (err)
		{
			printk("Advertising failed to start (err %d)\n", err);
			return 0;
		}
		k_sleep(K_SECONDS(4));

		//广播广播
		printk("Ble adv stop\r\n");
		err = bt_le_adv_stop();
		if (err)
		{
			printk("Advertising failed to stop (err %d)\n", err);
			return 0;
		}

		//更新MAC
		bt_addr_le_t local_mac_addr;
		static bt_addr_le_t myaddr = {
			.type = BT_ADDR_LE_RANDOM,
			/* fixed MAC addres */
			.a = {
				.val = {0x01, 0x02, 0x03, 0x04, 0x05, 0xc6},
			},
		};

		printk("Ble update MAC address\r\n");
		err = bt_id_create(&myaddr, NULL);
		if (err < 0)
		{
			printk("bt_id_create err!\r\n");
		}
		k_sleep(K_SECONDS(4));
	} while (1);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/374390.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

「HarmonyOS」CustomDialogController自定义弹窗使用方法

需求背景&#xff1a; 在开发的过程中&#xff0c;总会遇到一些功能需要使用到弹窗进行信息的输入和修改&#xff0c;如用户个人信息的修改&#xff1b;在UI设计上每个App通常都会有各自的样式&#xff0c;而不是使用系统的标准样式&#xff0c;所以通常我们需要进行自定义弹窗…

C++学习Day04之常函数和常对象

目录 一、程序及输出1.1 常函数1.1.1 不能修改对象的成员变量1.1.2 常函数可以被常对象和非常对象调用 1.2 常对象1.2.1 对象的成员变量不能被修改1.2.2 只能调用常函数&#xff0c;不能调用非常函数1.2.3 const_cast 调用非常函数 1.3 常函数中或常对象修改成员变量 二、分析与…

DevOps落地笔记-17|度量指标:寻找真正的好指标?

前面几个课时端到端地介绍了软件开发全生命周期中涉及的最佳实践&#xff0c;经过上面几个步骤&#xff0c;企业在进行 DevOps 转型时技术方面的问题解决了&#xff0c;这个时候我们还缺些什么呢&#xff1f;事实上很多团队和组织在实施 DevOps 时都专注于技术&#xff0c;而忽…

zxxxxczzvdsgbhfdb

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 磁盘满的本质分析 专栏&#xff1a;《Linux从小白到大神》 | 系统学习Linux开发、VIM/GCC/GDB/Make工具…

【Docker】.NET Core 6.0 webapi 发布上传到Docker Desktop并启动运行访问,接口返回数据乱码解决方法

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Docker容器》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…

进程控制(Linux)

进程控制 一、进程创建1. 再识fork2. 写时拷贝 二、进程终止前言——查看进程退出码1. 退出情况正常运行&#xff0c;结果不正确异常退出 2. 退出码strerror和errno系统中设置的错误码信息perror异常信息 3. 退出方法exit和_exit 三、进程等待1. 解决等待的三个问题2. 系统调用…

使用pandas将excel转成json格式

1.Excel数据 2.我们想要的JSON格式 {"0": {"raw_data1": "Sam","raw_data2": "Wong","raw_data3": "Good","layer": "12v1"},"1": {"raw_data1": "Lucy…

外汇天眼:大量的平庸操作无济于事,少数的杰出操作改变人生

回顾我们的人生&#xff0c;道路虽然漫长&#xff0c;经历虽然众多&#xff0c;但紧要处其实只有关键的几步。 在关键时刻处理得最好的人就会拥有最成功的事业; 回顾我们所交过的朋友&#xff0c;虽然数量像天上的繁星&#xff0c;但真正对自己的人生有重大影响的&#xff0c;不…

NUUO 网络摄像头命令执行漏洞

一、设备简介 NUUO NVR是中国台湾省NUUO公司旗下的一款网络视频记录器&#xff0c;该设备存在远程命令执行漏洞&#xff0c;攻击者可利用该漏洞执行任意命令&#xff0c;进而获取服务器的权限。 网络视频记录器的CPU为Marvell Kirkwood 88F6281&#xff0c;CPU架构为基于ARMv5…

LLM(大语言模型)——大模型简介

目录 概述 发展历程 大语言模型的概念 LLM的应用和影响 大模型的能力、特点 大模型的能力 涌现能力&#xff08;energent abilities&#xff09; 作为基座模型支持多元应用的能力 支持对话作为统一入口的能力 大模型的特点 常见大模型 闭源LLM&#xff08;未公开源…

GADM 4.1 全球国家行政区划下载

扫描文末二维码&#xff0c;关注微信公众号&#xff1a;ThsPool 后台回复g004&#xff0c;领取最新 GADM 4.1 全球国家行政区划 GADM概述 GADM&#xff0c;全称 Database of Global Administrative Areas&#xff0c;是一个开放获取的全球行政区划数据库&#xff0c;包含各国、…

智慧城市与数字孪生:技术驱动下的城市治理与生活变革

一、引言 随着科技的飞速发展&#xff0c;智慧城市和数字孪生已经成为现代城市发展的重要趋势。它们通过运用先进的信息通信技术&#xff0c;提升了城市的治理效率和居民的生活品质。本文将探讨智慧城市与数字孪生如何共同推动城市治理与生活的变革&#xff0c;以及面临的挑战…

Webpack源码浅析

webpack启动方式 webpack有两种启动方式&#xff1a; 通过webpack-cli脚手架来启动&#xff0c;即可以在Terminal终端直接运行&#xff1b; webpack ./debug/index.js --config ./debug/webpack.config.js通过require(webpack)引入包的方式执行&#xff1b;其实第一种方式最终…

踩坑了,MySQL数据库生成大量奇怪的大文件

作者&#xff1a;田逸&#xff08;formyz&#xff09; 一大早就收到某个数据库服务器磁盘满的报警信息&#xff0c;其中数据盘使用率超过90%&#xff0c;如下图所示。 这是一台刚上线不久的MySQL从库服务器&#xff0c;数据盘的总容量是300G。先登录系统&#xff0c;查看主从同…

一般系统的请求认证授权思路【gateway网关+jwt+redis+请求头httpheader】

gateway&#xff1a;网关&#xff0c;我们都知道网关的作用就是对系统的所有请求&#xff0c;网关都会进行拦截&#xff0c;然后做一些操作&#xff08;例如&#xff1a;设置每个请求的请求头httpHeader&#xff0c;身份认证等等&#xff09;此时一般会使用到网关过滤器&#x…

感悟笔记——2024年2月5日

今日阅读了一篇挺有深度的文章&#xff0c;主要阐述进入职场后的大部分人&#xff0c;是怎么逐渐沦为螺丝钉的?即使起点巨高的优等生&#xff0c;也不可避免。文章指路&#xff1a; 「优等生思维」正在将你变成「螺丝钉」和「老黄牛」从小到大&#xff0c;我一直都是那个「别…

随记-Java项目处理SQL注入问题

现象&#xff1a;http://10.xx.xx.xx:xx/services/xxService 存在SQL注入情况 加固意见&#xff1a; 需要对网站所有参数中提交的数据进行过滤&#xff0c;禁止输入“"、"xor"、"or"、”--“、”#“、”select“、”and“等特殊字符&#xff1b;所有…

专业排版设计软件:QuarkXPress 2024 for mac中文激活版

QuarkXPress 2024 for Mac是一款功能强大、易于使用、高质量输出的专业排版软件。无论您是出版业的专家还是初学者&#xff0c;都可以通过QuarkXPress 2024轻松创建出令人惊叹的出版物。 软件下载&#xff1a;QuarkXPress 2024 for mac中文激活版下载 QuarkXPress 2023 for Mac…

游戏后端如何实现服务器之间的负载均衡?

在当今的游戏行业中&#xff0c;随着游戏用户数量的不断增加&#xff0c;如何实现服务器之间的负载均衡成为了一个亟待解决的问题。游戏后端作为游戏的重要组成部分&#xff0c;承载着游戏逻辑处理和数据存储等功能&#xff0c;因此游戏后端的负载均衡问题尤为重要。本文将详细…

FINN: 使用神经网络对网络流进行指纹识别

文章信息 论文题目&#xff1a;FINN: Fingerprinting Network Flows using Neural Networks 期刊&#xff08;会议&#xff09;&#xff1a;Annual Computer Security Applications Conference 时间&#xff1a;2021 级别&#xff1a;CCF B 文章链接&#xff1a;https://dl.ac…