BLE Mesh蓝牙协议学习记录

news2024/10/2 10:33:48

BLE Mesh蓝牙协议学习

文章目录

  • BLE Mesh蓝牙协议学习
    • 前言
    • 概述
      • 一、蓝牙技术整体框架
      • 二、经典蓝牙和低功耗蓝牙
    • mesh协议架构图
        • 承载层(Bearer Layer)
        • 网络层(Network Layer)
        • 底层传输层(Lower Transport Layer)
        • 上层传输层(Upper Transport Layer)
        • 访问层(Access Layer)
        • 基础Model层(Foundation Models Layer)
        • Model层(Model Layer)
    • 网络中的消息传输方式
      • 消息缓存队列和TTL
      • 广播与扫描
      • 发布和订阅
    • 蓝牙mesh网络基本概念
      • 节点和节点分类
        • 元素(elements)
        • 模型(Model)
        • 消息,状态和属性(Messages, States and Properties)
          • 消息
            • 消息操作码
            • acknowledged/unacknowledged 消息
            • 消息安全
            • 消息交换
            • 示例消息序列图
          • 消息,状态和属性的关系
          • 状态绑定(Bound States)
          • 复合状态(composite states)
          • 状态转换(State transitions)
      • 配网(Provisioning)
      • 地址
  • 2023.2.27更新

前言

资料基本都是从网上copy总结的(侵删),总结的比较烂,随便看看即可。

蓝牙MESH基础概念的介绍

B站蓝牙Mesh基础知识介绍讲的很好

解密蓝牙mesh系列 | 第一篇
解密蓝牙mesh系列 | 第二篇
解密蓝牙mesh系列 | 第三篇
解密蓝牙mesh系列 | 第四篇
解密蓝牙mesh系列 | 第五篇
解密蓝牙mesh系列 | 第六篇
解密蓝牙mesh系列 | 第七篇
解密蓝牙mesh系列 | 第八篇
解密蓝牙mesh系列 | 第九篇
解密蓝牙mesh系列 | 第十篇

概述

一、蓝牙技术整体框架

在看蓝牙技术整体框架之前,我们先回忆一下TCP/IP的5层网络模型和它所对应的网络协议集。
image.png
可能不同应用的同学只需要关注在不同层次上的网络协议就可以满足日常工作使用了,像应用开发同学,一般只关注应用层的协议,http,https等等,网络的同学可能只需要关注TCP协议、IP协议以及ARP协议等,WiFi的同学主要focus在802.11协议上。但蓝牙技术不同,它并不处于TCP/IP5层模型中的任何一层,而是覆盖了整个5层TCP/IP模型。有了这个概念之后,让我们来看看下面第一张图。
image.png
在图1中我们可以看到,蓝牙的架构分为Host和Controller两个模块,Host主要是各种业务场景需求的实现,Controller部分主要负责的是蓝牙报文的收发以及蓝牙物理连接的管理这些基本功能。所以通常绝大部分的开发工作都是在Host端进行,Controller部分的工作大都是由专门的蓝牙芯片厂商来负责;Host和Controller分模块的最初设计理念是想让这两个模块单独运行在两颗不同的芯片甚至系统上,之间通过硬件通信端口(串口,USB)使用HCI协议进行连接和通信,这样可以方便替换和升级,例如对于不带蓝牙功能的电脑,我们可以买一个USB蓝牙接收器插到电脑上,就可以支持了蓝牙功能,这个场景下,HOST模块就是运行在电脑系统上,Controller模块就是运行在USB蓝牙接收器上。现在虽然有不少芯片把Host和Controller模块都放在了一颗芯片上,但是基本还是遵循这样的层次结构,只是将HCI协议从硬件通信端口换成了软件端口。
从应用场景来说,蓝牙规范针对了我们日常生活中会碰到的非常多的场景分别定义了不同的场景规范(Profile)来支持这些场景下的需求,在图中我们可以看见,有HFP(Hands Free Profile)来支持蓝牙耳机通话场景,SPP(Serial Port Profile)用于串口传输,OPP(Object Push Profile)用于设备之间的文件传输场景,A2DP(Advanced Audio Distribution Profile)用于蓝牙耳机收听音乐场景,AVRCP(A/V Remote Control Profile)用于蓝牙耳机音乐播放控制场景,PAN(Personal Area Networking Profile)可以让手机作为蓝牙热点提供上网服务。低功耗蓝牙鼠标键盘则是使用HOGP(HID Over GATT Profile)才能让蓝牙鼠标充一次电可以用三个月到半年。当然,图1中只是列出了我们最常会用到的一些蓝牙场景,蓝牙其实还有其他的像打印(Basic Printing Profile),心率(Heart Rate Profile),寻物(Find Me Profile)等等一系列场景规范(Profile)来支持不同的应用场景。

二、经典蓝牙和低功耗蓝牙

蓝牙规范里分为经典蓝牙和低功耗蓝牙,经典蓝牙和低功耗蓝牙虽然都是蓝牙技术,但其实两种方案之间有非常大的差别,一个简单的区分就是看版本,版本低于4.0的都是经典蓝牙,高于4.0的才能支持低功耗蓝牙。在这里我们简单介绍一下两种蓝牙技术的概念和区别。
蓝牙是工作在频率为2400MHz到2483.5MHz的无线通信协议,总共有83.5MHz的带宽资源,在经典蓝牙的定义里,将这83.5MHz总共分为80个频道,每个频道是1MHz带宽,蓝牙连接管理是用连接管理协议(Link Manager Protocol LMP)。而在低功耗蓝牙里,空中只有40个频道,每个频道是2MHz带宽,连接管理使用的是连接层(Link Layer),空中数据包的结构也完全不同。我们可以看到,Controler部分的功能完全是两个独立的路径,也就是说,经典蓝牙和低功耗蓝牙的controller可以独立存在,互相不依赖,所以目前市面上有只支持经典蓝牙的芯片,也有只支持低功耗蓝牙芯片,当然,也有两种蓝牙模式共存的芯片。
在Host端,经典蓝牙和低功耗蓝牙的设计思路也不一样,在经典蓝牙协议里,在逻辑链路控制与适配协议层(Logical Link Control and Adaptation Protocol L2CAP)之上,还根据不同的应用场景定义了不同的传输协议,例如RFCOM, AVDTP,AVCTP,在不同的传输协议之上才定义了不同的Profile,层次结构比较复杂,开发人员学习成本高。而低功耗蓝牙就比较简单,只定义了一个属性协议(Attribute Protocol ATT),基于属性协议定义了一个通用属性场景规范(Generic Attribute Profile GATT)和其他的针对特定业务的场景规范(Profile),开发起来比较简单,整体框架也比较容易实现私有场景的开发。
蓝牙mesh虽然使用了低功耗蓝牙的广播报文和GATT,但可以算是一个半独立模块,蓝牙mesh构建了自己的一套网络寻址和数据传输机制,而且在mesh的协议文档里也强烈推荐使用广播承载(ADV Bearer)的方式而不是GATT承载(GATT Bearer)。
蓝牙协议和规格文档
那么这么多协议分别都是做什么的呢?其实蓝牙规范也是遵循TCP/IP通信模型设计的,让我们把蓝牙协议和TCP/IP网络通信模型对应起来就明白了。

image.png

由于经典蓝牙和低功耗蓝牙大都是点对点直连通信,完全不需要路由功能,所以没有特地定义网络层的协议,简单的寻址功能就在数据链路层的LMP层和LL层实现了,而蓝牙mesh由于是组建了mesh网络,有数据转发和寻址的需求,所以定义了一个Network Layer来做这件事情。

mesh协议架构图

img

承载层(Bearer Layer)

Bearer Layer 定义了Mesh节点怎么传递网络消息的。定义了两种Bearer,广播advertising bearer 和GATT bearer 。

Advertising Bearer 利用的是BLE GAP广播包的advertising 和scanning的功能来传递接收mesh的报文。

The GATT Bearer 允许不支持Advertising Bearer的设备间接的与mesh节点进行通讯。怎么通讯呢?使用前面讲的代理(Proxy Protocol)。Proxy Protocol是封装在GATT里面,当然会用特别定义的GATT characteristics。支持Proxy Feature的Proxy Node也就是代理节点,因为可以同时支持两种Bearer Layer,所以可以作为mesh节点和非mesh节点的中间桥梁。

网络层(Network Layer)

网络层定义了几件事情, 一个是定义了多种网络地址类型,我之前有说过关于Mesh地址的内容。二是定义了网络层的格式,打通传输层(Transport layer)和承载层(Bearer layer);三是定义了一些输入输出Filter,决定哪些消息需要转发,处理还是拒绝。四是定义了网络消息的加密和认证。

底层传输层(Lower Transport Layer)

这层做的事情很简单,就是拆拆拼拼。把太长的传输层的包拆成若干个分给网络层,把短的网络层的包再组成一个长的传输层的PDU(Protocol Data Unit)。

上层传输层(Upper Transport Layer)

上层传输层主要是负责加密,揭秘和应用数据授权。一句话,消息的安全性和机密性就是有这一层负责的。还有就是会定义一些节点间在这一层的一些会话,比如Friend功能,心跳包(Heartbeats)。

访问层(Access Layer)

访问层主要负责:1.定义更高层的应用如何跟upper transport layer通讯。2.定义应用数据的格式。3.定义和控制upper transport layer应用数据的加解密。4.在把应用数据扔到上层之前,会检查校验接收过来的应用数据是否合法。

基础Model层(Foundation Models Layer)

基础model层定义访问层(access layer)的状态,消息,模型配置和mesh网络管理。

Model层(Model Layer)

Model层定义了典型的用户场景标准化操作的相关models(相关的models定义在Bluetooth Mesh Model specification文档中)。更高层次模型规范的例子包括照明和传感器的模型。

网络中的消息传输方式

消息缓存队列和TTL

蓝牙Mesh采用了消息缓存队列TTL的优化方案来避免消息的无限制转发。

消息缓存 Message cache:设备都会缓存收到消息的关键信息,以确定是否已经转发过此消息,如果是就忽略此消息。Message cache至少需要能缓存两条消息
Time to Live(TTL): 每个消息都会包含一个Time to Live(TTL)的值,来限制中继的次数,最大可以中继126次。消息每转发一次TTL的值就减1,TTL值为1就不再转发

广播与扫描

Mesh节点在网络内发送数据不会像普通BLE广播需要等一个固定的广播间隔,而是延迟一小段随机时间后发送,所以为了数据不丢失,节点会启用100%占空比来扫描广播信道,扫描窗口时间=扫描间隔

image-20211118092141205

发布和订阅

与MQTT不同,MQTT是向主题进行发布和订阅,这个是对上面所说的地址进行发布和订阅。(单播那些)

img

在上图中,开关1 发布信息给组播地址”厨房“, 节点灯1, 灯2, 灯3 每个都注册到了”厨房“这个地址上, 因此他们能收到处理发给厨房的消息。换句话说, 灯1,灯2 和灯3 都能被开关1控制开关。 开关2 发布消息到”餐厅“,只有灯3订阅了"餐厅"这个地址,所以只有灯3能被开关2控制。在这个例子里同样说明了每个节点可以订阅多个确切的地址。同样的,你一定也注意到了,开关5和开关6同样都可以发布消息到”花园“。

蓝牙mesh网络基本概念

节点和节点分类

想象一下由数千台设备组成的网络,每台设备均通过低功耗蓝牙(BLE)无线连接进行通信。蓝牙mesh网络中的这些设备被称为节点 (node) 。每个节点都能发送和接收消息。信息能够在节点之间被中继,从而让消息传输至比无线电波正常传输距离更远的位置。这样的节点网络可以被分布在制造工厂、办公楼、购物中心、商业园区以及更多环境中。

在这里插入图片描述

中继功能(Relay):那些使能了此特性的节点可以通过Advertising Bearer接收并转发消息给mesh网络其他设备,它只转发不在消息缓存和TTL的值大于1的消息,转发前会把TTL的值减1。支持中继功能的节点称为中继节点
代理功能(Proxy):为了兼容不支持蓝牙Mesh的BLE设备(比如手机),能够采用BLE GATT Bearer的方式和BLE设备通信,实现mesh广播数据包和GATT通信数据包的转换,支持代理功能的节点称为代理节点
低功耗功能(Low Power):主要是应用在低功耗设备上,减少设备工作时间,大部分时间处于休眠状态,需要配合朋友节点,支持低功耗功能的节点称为低功耗节点
朋友功能(Friend):帮助低功耗功能节点缓存消息,便于低功耗节点唤醒后向其查询消息,支持朋友功能的节点称为朋友节点

mesh 网络中的拓扑结构

元素(elements)

每个节点至少拥有一个元素,称为主元素(Primary Element),同时还可能包含其他多个元素。一些节点的复杂性高于其他节点,由多个称为元素(Element)的独立部分组成。元素由定义节点功能和元素条件的实体组成。例如,一个灯泡内有一个元素, 并具有两种功能:

  • 节点 = 灯泡
  • 一个元素 = 主元素
  • 节点功能
    1. 开/关
    2. 亮度
  • 元素条件/状态
    1. “开”或“关”
    2. 0-10(亮度等级)

在这里插入图片描述

节点中的每个元素都有一个唯一的地址,称为单播地址(unicast address),使每个元素都有址可寻。我们将在地址章节中进一步解释“寻址”

模型(Model)

模型(Model)定义了一个节点的基本功能。一个节点当然可以包含多个Model。一个Model定义了节点所需要的所有的状态。消息会给基于这些状态进行操作,当然也会有相应的行为随之产生。

在这里插入图片描述

在这里插入图片描述

以灯泡为例,该模型的功能是开关和调节亮度。相关的状态分别为“开”/ “关”和0-10:

  • 模型 (节点功能)
    • 开/关
      • 状态 -> “开”或“关”
    • 亮度 (0-10)
      • 状态 -> 0-10

Mesh的应用定义的是使用“发布-订阅(publish-subscribe)”的典型的“服务器-客户端(client-server)的架构”。在Mesh里面,并没有沿用传统的端到端的“Profile”的概念,而是定义了三种不同的模式, Client, ServerControl

  • 服务器模型(Server model): 定义了状态states, 状态转换 state transitions, 状态绑定state bindings 和包含了哪些消息,当然也同样定义了与这些消息,状态,状态转换相关的行为Behaviors。

    • 由至少一个或多个状态跨越一个或多个元素的状态组成
    • 定义模型能够发送/接收的消息,并根据这些消息定义元素的行为
    • 实例:
      • 开/关切换——可以暴露开关状态
      • 传感器——可以暴露传感器的状态(可能为温度值或传感器测量的“满”、“待充”或“空”的结果)
      • 功率级别——可以暴露电源状态(等级1-10)
  • 控制模型 (Control Model):具备client model的功能与其他的server model进行交互,同时也可以有server model功能与其他client model进行交互。内置了逻辑控制层(一套规则和行为在各个与之连接的模型中进行协调交互)。

    • 定义客户端为请求、更改或使用服务器相应状态所使用的消息。
    • 实例:
      • 开/关切换——客户端发送打开或关闭的消息
      • 电源级别——定义电源状态的消息(0-10)
  • 客户端模型(Client Model): 没有定义任何的状态States,但是它定义了要收发哪些消息。定义这些消息是为了GET,SET或者获取在Server models里面定义的状态。

    • 控制模型具有多种功能,同时可能包含一个或多个:
      • 客户端模型 (Server Model)
      • 服务器模型 (Client Model)
      • 控制逻辑(规则和行为)用于协调与其相连模型之间的交互。
    • 实例:控制模型可用在支持机器周围循环的液体冷却剂水泵上。
      • 应用场景——温度传感器会记录机器的温度。如果机器超过设定的温度,冷却泵则会被打开。
      • 冷却泵的控制模块 (Control Module)
        • 与温度传感器相连的客户端(用于接受温度值)
        • 连接到开/关切换的服务器(用于打开或关闭水泵)
        • 控制逻辑(规则和行为)— 负责定义如果温度传感器超过设定值,则打开水泵。

蓝牙技术联盟定义的模型被称为标准模型(SIG Adopted Model),16bit标识,目前SIG定义好的模型包括Generic、Sensors、Time and Scenes、Lighting;由厂商定义的模型称为厂商模型(Vendor Model),32bit标识。

消息,状态和属性(Messages, States and Properties)

消息

蓝牙mesh网络通过消息进行通信。消息可以分为控制消息和接入消息。

  • 控制消息(Control Message) - 与蓝牙mesh网络操作有关的消息,例如心跳(heartbeat)和friend的请求消息。
  • 接入消息(Access Message) - 该类消息允许客户端模型检索或设置服务器模型中的状态值,或被服务器用于报告状态值。

模型可实施并定义节点的功能。元素是节点内唯一可被寻址的实体(节点中可包含一个或多个模型),并由状态(state)定义元素的状况变化。对于每个状态,都有一组服务器模型支持的消息。例如请求状态值或请求改变状态的客户端模型、以及发送状态或状态改变相关消息的服务器模型。

消息操作码

消息可被操作码(opcode)识别,而操作码通常定义成set/get这两种类型,并具有相关参数。操作码可识别消息的操作。示例包括:

Generic OnOff Get – 用于为通用模型识别OnOff状态GenericOnOff Get不具有参数
Generic OnOff Set – 用于设置通用模型的OnOff状态
参数:
OnOff – 目标值(开或关)
TID – 事务标识符(Transaction Identifier)– 消息是新的还是转发的
转换时间(Transition Time)– 元素从一种状态转换到另一种状态所需时长
延迟(Delay)– 消息执行延迟

acknowledged/unacknowledged 消息

接入消息分为两类:经确认的(acknowledged)和未经确认的(unacknowledged)。经确认的消息被发送至每个接收元素,并经其确认。响应通常为状态消息。对于未经确认的消息则不作出响应。例如蓝牙mesh网络的状态消息就是一种未经确认的消息。

消息安全

所有蓝牙mesh网络消息的安全保障都来自网络密钥(NetKey)和应用密钥(AppKey)对消息的加密和验证。NetKey用于网络层通信。假设蓝牙mesh网络没有子网,则该mesh网络内的所有通信都使用相同的网络密钥。

AppKey用于应用程序的数据。网络中的一些节点具有特定应用,并且根据应用的需要对一些潜在敏感数据的访问进行限制。这些节点具有特定的AppKey,并与特定应用相关联。会使用不同AppKey的领域通常包括安全(楼宇门禁、机房门禁和CEO办公室门禁)、照明(制造厂房、外部楼宇照明和人行道)和HVAC系统。

中继节点(relay node)(如灯泡或墙壁开关)通常具有有效的NetKey,能够在网络内中继敏感性消息。然而,这些节点无法访问各种限制区域(如楼宇控制或HVAC系统)的特定AppKey,,亦无法解密应用程序的数据。

消息交换

蓝牙mesh网络使用发布/订阅 (publish/subscribe)模型来进行消息传输。生成消息的节点会发布消息。需要接收消息的节点会订阅它们所需的地址。消息可被发布至单播、群组或虚拟地址。

消息可以作为对其他消息的回复而发送,也可以作为非请求消息(unsolicited messages)被发送。当模型发送回复消息时,使用消息始发处的源地址作为目标地址。发送非请求消息时,模型将使用模型的发布地址作为目标地址。节点中的每个模型都有一个发布地址。

接收消息时,节点内模型(节点中可能存在多个模型)中的每个实例均可通过订阅方式从一个或多个群组或虚拟地址接收消息。

订阅消息的模型使用模型的订阅列表来定义用于接收消息的有效地址。当模型接收到消息时,模型将检查其订阅列表。当订阅列表上的地址设置为模型的元素单播地址或属于该节点的固定群组地址时,则视为一个匹配(match)。下图表示了接入消息的有效源地址和目标地址。

蓝牙mesh实体发布各种节点的状态时,无论其与发送数据的节点位置距离远近,整个蓝牙mesh网络中的系统均可订阅该数据。这就实现了网络一端的设备可通过低功耗无线消息与设施中的其他的管理者进行对话,而不受距离限制。

示例消息序列图
  • Acknowledged get: 下图展示了一个Client使用acknowledged get消息来获取Server的状态,Server使用相应的状态消息回复。

    在这里插入图片描述

  • Acknowledged set: 下图展示了Client使用acknowledged set设置Server的状态,Server使用相应的状态消息回复。然后Server将这条状态消息发布到了模型的发布地址,如果Client订阅了Server模型的发布地址,那么Client会收到2条状态消息。

    在这里插入图片描述

  • Unacknowledged set: 下图展示了Client使用unacknowledged set设置Server的状态,Server收到消息后不会回复状态消息。但是Server会将这条状态消息发布到了模型的发布地址,如果Client订阅了Server模型的发布地址,那么Client会收到这条状态消息。

消息,状态和属性的关系

蓝牙Mesh里面,要进行某种操作,就是调用消息这一基本机制。一个给定的消息类型代表了一个对状态的操作或者对多个状态的采集。所有的消息都可以分成三种简单类型:get 、set 、 status。

GET 顾名思义,就是获取一个节点或者多个节点的给定的状态。当收到GET消息以后,STATUS消息就发出来了。当然,它里面带着的是相对应的状态内容。

SET消息分为有应答和无应答两种。如果是有应答的,就会有STATUS消息跟着出来,如果是无应答的话,那就没有应答包。

STATUS 消息,除上面的两种情况会出现之外,也可以在其他的消息中出现,当然也可以独立出现。比方说某个元素用定时器每隔一段时间发送一次。

在蓝牙mesh里面定义了很多种消息,通过Opcode来区分,还包含了相关联的参数和行为。Opcode可以是单字节,双字节(常见)或者三字节(厂商指定)。

绝大部分的mesh消息都是对状态进行操作的,只有特别的和属性相关的消息,才会对属性进行操作,而且需要制定16位的属性ID。

状态绑定(Bound States)

不同的状态之间可能会有一些关系。比如说一个状态的变化会造成另外状态的触发,这种关系叫做状态绑定。状态的绑定是可以跨Model的,(Model这个重要概念我们马上会提到),也可以在多个元素中。再举个例子,灯光亮度状态和开光状态。当你把亮度状态改到0了,也就触发了开关状态的“关”状态,反之亦然。

复合状态(composite states)

蓝牙mesh支持复合状态,即由两个或多个值组成的状态。变色灯就是这样的一个例子,灯的色彩可以分别由颜色饱和度或者亮度来改变。

状态转换(State transitions)

上面说到了状态的设置和获取,那么在进行状态改变的时候,这种改变可以是立刻发生的,也可以是过一段时间发生的。下图把不同的时间给表示出来了。

img

初始化状态(initial State)是指刚收到SET新的状态值的时间。从收到SET消息到状态改变的时间叫做转换时间。从STATUS消息发出(可以在中间的任何时间点)到目标状态完成这个叫保持时间(Remaining time), 所以当你收到STATUS消息的时候,状态可能还没有变化,在STATUS消息里也可以包含离目标状态的变化还有多少时间。

配网(Provisioning)

配网的全过程包括大概5个步骤,分别是

Step 1. Beaconing;

Step 2. Invitation;

Step 3. Exchanging Public Keys;

Step 4. Authentication;

Step 5. Distribution of the Provisioning Data

其实也很简单,第一步,告诉你我要配网,这里使用的是新定义的AD广播包类型, Mesh AD。第二部, 配网者Provisioner听到了这个Beacon以后,就发一个邀请,这个邀请就是配网邀请PDU(Protocol Data Unit)。要入网的设备收到邀请以后,会把自己的一些配网的能力(Provisioning capabilities)发回来。接下来,既然郎有情妾有意, 就公开交换信物-公钥呗。接下来就会有一个互动随机数的认证流程,这点和原来蓝牙输入0000 的密码很像, 但是会简单一点点。 最后一步,认证完成,从公钥和两个设备的私钥派生出Session Key。后面的配网的信息交互的过程会用这个Session key来加密。配网成功以后,就会根据最后一步里面包含交换的NetKey来加密后面的数据交换。跟加密相关的一些参数例如IV index, 和单播地址,会存在配网者那里。

地址

地址有四种类型,其中的三类用于消息的传送:单播(unicast)、虚拟(virtual)和群组(group)地址。第四种被称为未分配(unassigned)地址。地址长度为16位,并按下述定义进行编码。

在这里插入图片描述

  • 单播地址(unicast):分配给节点中的元素地址,地址范围0x0001~0x7FFF,在“启动配置”(provisioning)期间,启动配置设备(provisioner)会在网络节点的生命周期内为节点中的每个元素分配一个单播地址。单播地址可能出现在消息的源地址字段或目的地址字段中。发送到单播地址的消息只能由一个元素进行处理。

  • 未分配地址(unassigned):即无效地址,固定为0x0000,地址的初始值,常用于屏蔽一个设备

  • 虚拟地址(virtual):用于表示一个或多个节点的多个元素,每一个虚拟地址逻辑上对应一个128-bit的Label UUID,通过对该Label UUID作哈希运算得出虚拟地址的低14位数值,虚拟地址的范围为0x8000~0xBFFF

  • 组播地址(group):用于表示一个或多个节点的多个元素,地址范围0xC000~0xFFFF,其中包含256个固定组播地址

    • 动态分配的地址(Dynamically Assigned) -> 0xC000-0xFEFF
    • 固定地址(Fixed Address) – 由蓝牙技术联盟分配,分为五段:
      • 保留供将来使用 (RFU) –> 0xFF00-0xFFFB
      • All-proxies -> 0xFFFC
        • 发送到启用代理(proxy)功能的所有节点
      • All-friends -> 0xFFFD
        • 发送到启用friend功能的所有节点
      • All-relays -> 0xFFFE
        • 发送到启用中继(relay)功能的所有节点
      • All-nodes -> 0xFFFF
        • 发送到所有节点
        • 发送到固定节点的所有消息都由节点的主元素(primary element)进行处理

后面准备做两个小项目并自己记录一下

1.基于esp32系列的BLE MESH例程学习

2.基于esp32系列通过BLE MESH和天猫精灵实现3孔分控插座的控制(已实现,待整理)

3.基于TLSR825XPHY6212的蓝牙BLE MESH例程学习

4.基于TLSR825XPHY6212通过蓝牙BLE MESH连接天猫精灵实现3孔分控插座的控制

2023.2.27更新

在准备考研,一年多没继续弄了,等这段时间复试忙完来继续更新。

不过现在也差不多忘完了,准备这段时间更新一下,从新写一篇,并记录一下项目时间全过程。

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

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

相关文章

JAVA连接数据库——JDBC的简单使用

JDBC即Java数据库连接.用来实现Java程序对数据库增删查改。 为了对接Java程序和数据库,java.sql提供了很多api包含在java.sql和javax.sql里面 结构: DriverManager接口: 每一个数据库的驱动程序都必须去到DriverManager注册,生成一个Connection Conn…

电商平台的促销活动如何抵御大流量的ddos攻击

每一次活动大促带来的迅猛流量,对技术人而言都是一次严峻考验。如果在活动期间遭受黑产恶意 DDoS 攻击,无疑是雪上加霜。电商的特性是业务常态下通常不会遭受大流量 DDoS 攻击,且对延迟敏感,因此只需要在活动期间按需使用 DDoS 防…

【第五章 AOP概述,底层原理,AOP术语,切入点表达式,AOP操作(基于注解方式,基于xml配置文件)】

第五章 AOP概述,底层原理,AOP术语,切入点表达式,AOP操作(基于注解方式,基于xml配置文件) 1.AOP概述: (1)什么是AOP: ①面向切面编程(…

11-KMP算法

KMP算法是一个字符串匹配算法,总的意义是在给定的字符串A中利用优化的方法快速地找出字符串B的位置,相比于传统匹配算法,它能有效减少匹配时间,提高效率。 前缀和后缀 在我们看KMP算法前我们先考虑一个问题:假如我们…

基于框架的平台总线式开发

一、总线、设备、驱动 硬编码式的驱动开发带来的问题: 1. 垃圾代码太多 2. 结构不清晰 3. 一些统一设备功能难以支持 4. 开发效率低下 1.1 初期解决思路:设备和驱动分离 struct device来表示一个具体设备,主要提供具体设备相关的资源&am…

Telnet 基础实验2: SSH 实验

Telnet 基础实验2: SSH 实验 本实验只能使用 eNSP中 AR 系统的路由器做 拓扑图 SSH : Secure Shell 是一个网络安全协议,基本于 TCP 协议 22 端口传输数据,通过对网络数据的加密,使其能够在一个不安全的网络环境中&a…

网易新财报:游戏养家,教育维稳、音乐快走

配图来自Canva可画 随着互联网流量红利逐渐消退,互联网大厂们也告别高增长时代,逐渐进入稳定增长阶段。近两年,流量焦虑、业务失速等问题更是成为了一团浓雾,笼罩在互联网大厂周围。不过,面对所遭遇的难题&#xff0c…

力扣-换座位

大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:626. 换座位二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总结前言 …

读书笔记——《富爸爸穷爸爸》

《富爸爸穷爸爸》,以前不屑读这种书。这种书就是那种走进书店放在门口展销位的成功学著作,一眼看上去没什么实在的内容,看上去很不靠谱,感觉就是骗一些社会底层又做着暴富梦的人来买的,但是由于自身原因或环境局限根本…

Spring Boot + Vue3 前后端分离 实战 wiki 知识库系统<二>---后端架构完善与接口开发

数据库准备&#xff1a; 在上一次Spring Boot Vue3 前后端分离 实战 wiki 知识库系统<一>---Spring Boot项目搭建已经将SpringBoot相关的配置环境给搭建好了&#xff0c;接下来则需要为咱们的项目创建一个数据库。 1、mysql的安装&#xff1a; 关于mysql的安装这里就…

【C语言每日一题】杨氏矩阵(源码以及改进源码)

【C语言每日一题】—— 杨氏矩阵&#x1f60e;&#x1f60e;&#x1f60e; 目录 &#x1f4a1;前言&#x1f31e;&#xff1a; &#x1f49b;杨氏矩阵题目&#x1f49b; &#x1f4aa; 解题思路的分享&#x1f4aa; &#x1f60a;题目源码的分享&#x1f60a; &#x1f4…

夜天之书 #73 Apache Pulsar 的社群指标

去年十一月&#xff0c;我成为了 Apache Pulsar[1] 社群 Committers 的一员。成为 Committer 之前和之后&#xff0c;我都积极参与了代码仓库上 Issue 和 Pull Request (PR) 的处理回应和评审。去年十二月期间&#xff0c;我把未解决的 Issue 和 PR 数量分别从接近 2000 个和 4…

STM32学习笔记-I2C通信协议

文章目录介绍&#xff1a;两种实现方式&#xff1a;I2C设备的常用连接方式&#xff1a;I2C协议时序&#xff1a;STM32硬件I2C框架图I2C外设通讯过程**I2C读写EEPROM**&#xff08;硬件I2C&#xff09;介绍&#xff1a; 两根通信线SCL&#xff08;时钟线&#xff09;、SDA&#…

C语言中的强制类型转换

强制类型转换是把变量从一种类型转换为另一种数据类型。例如&#xff0c;如果您想存储一个 long 类型的值到一个简单的整型中&#xff0c;您需要把 long 类型强制转换为 int 类型。您可以使用强制类型转换运算符来把值显式地从一种类型转换为另一种类型&#xff0c;如下所示&am…

“ChatGPT之父”Sam Altman:如何成功?

背靠微软&#xff0c;OpenAI能拳打谷歌&#xff0c;脚踢Meta&#xff0c;它背后的男人&#xff0c;必然不简单。 让我们来看一看&#xff0c;Sam Altman是如何一步步成长为今天这个搅动全世界的男人。 山姆奥特曼&#xff08;Sam Altman&#xff09; 成长和创业经历 在YC创始…

代码随想录【Day27】| 39. 组合总和、40. 组合总和 II、131. 分割回文串

39. 组合总和 题目链接 题目描述&#xff1a; 给定一个无重复元素的数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。 说明&#xff1a; 所有数字&#xff08;包括 tar…

JavaScript 高级2 :构造函数和原型 d331702016e84f54b3594ae05e0eeac

JavaScript 高级2 &#xff1a;构造函数和原型 Date: January 16, 2023 Text: 构造函数和原型、继承、ES5中的新增方法 目标 能够使用构造函数创建对象 能够说出原型的作用 能够说出访问对象成员的规则 能够使用 ES5新增的一些方法 构造函数和原型 概述 在典型的 OOP 的…

MySQL之EXPLAIN

使用方法 查询结果分析 id&#xff1a;识别符 select_type&#xff1a;表示查询的类型 table&#xff1a;输出结果集的表 partitions&#xff1a;匹配的分区 type&#xff1a;表示表的连接类型 possible_keys&#xff1a;表示查询时&#xff0c;可能使用的索引 key&#xff1a…

jni-Demo-基于linux(c++ java)

跑一个jni 的最简单的Demo需要提前准备 VsCode 编译器、win10下&#xff0c;vscode中集成linux操作系统、c编译器&#xff08;gcc、g&#xff09;&#xff0c;java编译器&#xff08;jdk1.8&#xff09;参考&#xff1a;https://mangocool.com/1653030123842.htmlJniDemo类&…

【分享】灌溉制度设计小程序VB源代码

说明 根据作物需水特性和当地气候、土壤、农业技术及灌水技术等因素制定的灌水方案。主要内容包括灌水次数、灌水时间、灌水定额和灌溉定额。灌溉制度是规划、设计灌溉工程和进行灌区运行管理的基本资料&#xff0c;是编制和执行灌区用水计划的重要依据。 1—计划湿润土层允…