bthome协议分析及esp32上的实现

news2024/12/23 16:35:47

前言

最近自己搞了些智能家居的小节点,但由于wifi入网方式功耗太高,于是关注起了蓝牙

bthome是一种灵活的低功耗BLE数据格式协议,用于广播传感器数据,此协议支持数据加密,目前最新为v2版本。在home assistant中也支持协议,这意味着自己DIY的传感器采集节点,通过BLE广播数据时只要遵守此协议,该节点就能被HA探测到并解析传感器数据。

协议官方说明见https://bthome.io/format/,但我在阅读过程中由于我个人阅读理解能力有限,感觉其文档术语混乱,结构混乱,所以根据自己理解写下这篇文章

协议分析

此协议只是对蓝牙数据包中PDU中数据格式的规定,蓝牙Link Layer层数据包格式如下
请添加图片描述

bthome对payload中的数据格式作出了规定。

bthome协议分析

bthome协议支持对传感器数据加密,根据是否加密与否,其数据结构也稍有不同,本文将其简称为非加密结构和加密结构

1. 非加密结构

请添加图片描述

  • head

    头部长度3字节,对于bthome来说是固定的:0x02 0x01 0x06

  • local name

    长度为type+name长度,type分为Shortened local name (0x08)、Complete local name (0x09)

    name部分为字符的ASCII码

  • len

    service data长度计算为service flag+UUID+device info+BThome data,也就是len位之后所有数据的长度

  • service flag

    此部分名称官方没有明确的表述,我暂且称其为service flag,对于此协议固定为0x16

  • UUID

    对于此协议固定为0xfcd2,但由于UUID需要按字节反向读取,所以在数据包中需要写入0xd2 0xfc

  • device info

    长度为1字节,其各位含义如下,对于非加密数据包为0x40

    • bit 0: “Encryption flag”,0表示传感器数据没有加密,反之加密
    • bit 1-4: “Reserved for future use”
    • bit 5-7: “BTHome Version”,目前协议版本是V2所以其二进制为010
  • sensor data

    此部分是存放传感器数据,也是启用加密时的加密对象,此部分定义参考https://bthome.io/format/

2. 加密结构

加密结构前面部分与非加密结构相同,因此本小节只描述加密相关结构

请添加图片描述

bthome协议对数据的加密采用AES-CCM,AES-CCM在加密数据的同时输出数据摘要(tag、digest),摘要可用于校验数据完整性。被加密部分为sensor data,加密完成后需要在数据包中写入加密时的counter、tag以供对端解密数据。

下面以mbedtls中的加密api来进行讲解

在进行加密前需要调用mbedtls_ccm_setkey设置加密密匙

int mbedtls_ccm_setkey	(	mbedtls_ccm_context * 	ctx,
                            mbedtls_cipher_id_t 	cipher,
                            const unsigned char * 	key,  //密匙数据指针
                            unsigned int 	keybits       //密匙数据长度(bit长度)
)	

再调用mbedtls中的mbedtls_ccm_encrypt_and_tag函数来进行加密,其定义和解释如下

int mbedtls_ccm_encrypt_and_tag	(	mbedtls_ccm_context * 	ctx,
                                    size_t 	length,              //被加密数据长度
                                    const unsigned char * 	iv,  //nonce数据指针
                                    size_t 	iv_len,              //nonce数据长度
                                    const unsigned char * 	add, //额外数据
                                    size_t 	add_len,             //额外数据长度
                                    const unsigned char * 	input,//被加密数据指针
                                    unsigned char * 	output,   //存放输出密文的数据指针
                                    unsigned char * 	tag,      //存放输出tag(digest)的数据指针
                                    size_t 	tag_len               //指定输出tag的长度,必须为4, 6, 8, 10, 14 或 16
)	

对于nonce的结构为 [mac addr] + [UUID] + [device info] + [counter] 总长度为13字节

  • mac addr长度为6字节
  • UUID长度为2字节
  • device info长度1字节
  • counter长度4字节,初始值可以自己设置,在每次发送包后对其加一

对于bthome协议,tag长度需要为4字节。

所以在加密中输入为nonce、密匙、counter、明文,输出为密文、tag(digest)。将密文、counter、tag加密到数据包中即可组成完整的数据包。

下面是对一个bthome数据包的解析,以供参考

02 01 06  [HEAD]
04 09 65 6e 66 [Complete name size: 0x4] 
12 [service data len 0x12]
|	16  [service flag]
|	d2 fc [UUID ]
|	41 [device info]
|     2f 0a fa 54 37 e3  [sensor data]|
|	00 11 22 33  [counter]
|	b8 ed 87 a7  [tag]

下面是我在开源项目基础上完善了bthome协议在esp32上的实现,并使用此协议采集传感器数据的demo

https://github.com/junchao98/bthome-weather-station

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

( “树” 之 BST) 108. 将有序数组转换为二叉搜索树 ——【Leetcode每日一题】

108. 将有序数组转换为二叉搜索树 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 示例 1: 输入…

【pytorch函数笔记】torch.split

官方文档:https://pytorch.org/docs/stable/generated/torch.split.html?highlightsplit torch.split(tensor, split_size_or_sections, dim0) Splits the tensor into chunks. Each chunk is a view of the original tensor. If split_size_or_sections is an in…

栈的基本操作(C语言实现)创建,销毁,入栈,出栈

前言 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的…

Linux网络编程服务端的创建

文章目录 前言一、编程前的准备1.相关函数的了解二、accept函数特别注意点三、具体函数的实现四、运行客户端和服务端进行通信验证总结前言 上篇文章讲解了如何创建一个客户端,这篇文章将创建一个服务端用来和上篇文章的客户端进行通信。 一、编程前的准备 1.相关函数的了解…

服务(第九篇)tomcat的部署和优化

tomcat的介绍: 免费的、开放源代码的Web应用服务器(用java开发的) Apache软件基金会(Apache Software Foundation)Jakarta项目中的一个核心项目 由Apache、Sun和一些公司及个人共同开发而成 深受Java爱好者的喜爱,并得到部分软…

干货|实验操作难入门?快来看JoVE视频网站!

Hello,大家好! 这里是壹脑云科研圈,我是喵君姐姐~ 当导师要求我们学习、模仿一些学术大神所做的心理学实验,尤其是采用脑影像、脑电技术等高端仪器的实验时,我们往往会因为缺少对具体操作细节的了解而感到困惑或困难。…

【python视图2】基于networkx的10个绘图技巧

一、说明 networkx在02年5月产生,是用python语言编写的软件包,便于用户对复杂网络进行创建、操作和学习。利用networkx可以以标准化和非标准化的数据格式存储网络、生成多种随机网络和经典网络、分析网络结构、建立网络模型、设计新的网络算法、进行网络…

MIPI摄像头工程=7系列FPGA + OV5640(MIPI) + 15 分钟 + VITIS

项目使用东西 硬件 Spartan-7 SP701 FPGA 7系列FPGA电阻网络实现的MIPI接口 OV5640 MIPI接口 软件 AMD Vivado 2020 版本以上 AMD Vitis 2020 介绍 MIPI 接口现在非常流行,国产FPGA目前基本都带MIPI接口,而AMD-Xilinx是从U系列开始支持MIPI电平&#x…

使用CMake的CPack工具打包项目

为了介绍如何使用CMake的CPack工具进行项目打包,这里使用了前文CMake项目使用ctestgtest进行单元测试中的示例。 为了更接近实际开发中项目的情况,自行下载gtest并进行源码编译来模拟实际项目中的依赖项;在实际的开发中,可能会有…

chatgpt智能提效职场办公-ppt怎么压缩文件大小

作者:虚坏叔叔 博客:https://xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 压缩PPT文件大小有以下几种方法: 压缩图片大小:在PPT当中,图片是占用存储空间最大的部分&#xff0…

物联网多协议、多场景自定义测试|XMeter Cloud 更新

近日,全球首个物联网 MQTT 负载测试云服务 XMeter Cloud 推出了自定义场景测试功能。 该功能将满足用户自主定义测试场景和测试更广泛协议的需求,实现对除 MQTT 以外的 TCP、WebSocket、HTTP 等其他网络协议的测试,帮助用户构建更复杂的测试…

mybatis模糊查询以及结果封装详解

mybatis模糊查询以及结果封装详解 创建maven项目&#xff1a;项目结构如图所示 准备数据库表&#xff1a; 准备pom.xml所需的依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0…

程序地址空间(下)

目录 &#xff1a; 1.接上部分内容再谈谈地址空间是什么&#xff1f;&#xff1f; 2.页表MMU&#xff08;硬件设备&#xff09; 3.为什么要搞个虚拟地址映射到物理地址 4.解释为什么最开始的问题&#xff1f;&#xff1f;&#xff1f; ---------------------------------------…

Spring 的 IoC(控制反转)

IoC 是 Inversion of Control 的简写&#xff0c;译为“控制反转”&#xff0c;它不是一门技术&#xff0c;而是一种设计思想&#xff0c;也是一个概念&#xff0c;同时是一个重要的面向对象编程法则&#xff0c;能够指导我们如何设计出松耦合、更优良的程序。 在这里说 IoC 之…

Java ---包装类

&#xff08;一&#xff09;包装类概念 官方说法&#xff1a; Java是面向对象的语言&#xff0c;但是为了便于开发者的使用&#xff0c;Java中却沿用了C语言的基本数据类型&#xff0c;在进行基本的数据计算时&#xff0c;开发者可以直接使用基础类。但是当需要和Java其他对象…

如何理解ThreadLocal

ThreadLocal的基本概念 在并发编程中&#xff0c;多个线程访问同一个变量&#xff0c;可能会出现线程安全问题、为了保证在多线程环境下访问共享变量的安全性&#xff0c;通常在访问共享变量的时候加锁&#xff0c;以实现线程同步的效果。 使用同步锁机制保证多线程访问共享变…

ChatGPT | 一文详解ChatGPT(学习必备)

本文概要 本篇文章主要介绍ChatGPT的产生和使用体验&#xff0c;适合不了解ChatGPT或者了解不够透彻的小伙伴&#xff0c;文中的描述非常详细&#xff0c;干货满满&#xff0c;感兴趣的小伙伴快来一起学习吧&#xff01; &#x1f31f;个人简介 ☀️大家好&#xff01;我是新人…

信息的相关性和冗余度:信息在整个文明中的作用

文章目录 I 古埃及的象形文字1.1 罗塞塔石碑1.2 古埃及文字音节和希腊字母的对应表1.3 破解古埃及文字 I 古埃及的象形文字 1.1 罗塞塔石碑 这个石碑是在公元前196年埃及国王托勒密五世加冕一周年的诏书。 在此前大约一百年&#xff0c;埃及已经被来自希腊北方城邦的亚历山大…

C++------引用

一、 引用概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。 类型& 引用变量名(对象名) 引用实体&#xff1b; int main() {//一个变量可以有多个引用…

LWIP协议与TCP/IP

1. 学习一个东西&#xff0c;先了解这个东西是干什么用的&#xff0c;哪些场景会用到它&#xff0c;与自己已经掌握的其他知识的联系 a. 例如&#xff1a;LWIP这个东西是干什么用的&#xff1a;他就是一个裁剪后保持大部分TCP/IP功能的协议。用少量的资源消耗实现一个较为完整的…