简单的BLE服务,用于通过BLE读取和写入文件
项目描述
简介
这是一个简单的BLE服务,用于通过BLE读取和写入文件。该BLE服务针对向运行该服务的设备传输文件而设计。协议的核心部分是空闲空间响应,这样服务器就可以是一个内存有限的设备。空闲空间响应允许使用小的缓冲区大小,不会因客户端而超负荷。
依赖项
此驱动程序依赖于
请确保所有依赖项都可在CircuitPython文件系统中使用。这可以通过下载Adafruit库和驱动程序捆绑包或使用circup安装单个库来实现。
从PyPI安装
在支持GNU/Linux系统(如Raspberry Pi)上,您可以从PyPI本地安装驱动程序。要为当前用户安装
pip3 install adafruit-circuitpython-ble-file-transfer
要全局安装(在某些情况下可能需要)
sudo pip3 install adafruit-circuitpython-ble-file-transfer
在当前项目中的虚拟环境中安装
mkdir project-name && cd project-name
python3 -m venv .venv
source .venv/bin/activate
pip3 install adafruit-circuitpython-ble-file-transfer
使用示例
请参阅examples/ble_file_transfer_simpletest.py以获取客户端示例。占位符服务器实现位于examples/ble_file_transfer_stub_server.py。
协议
文件传输协议旨在简单且易于实现。它使用可用空间计数作为限制文件内容数据传输速率的方式。所有多字节数字都是使用最低有效字节首先编码的(在CPython的struct模块中为“<”)。
GATT 服务
该服务的UUID为 0xfebb,是Adafruit的16位服务UUID。
在特性中使用的基UUID是 ADAFxxxx-4669-6C65-5472-616E73666572。下面的16位数字将替换到 xxxx 部分。
该服务有两个特性
版本(0x0100)- 简单的无符号32位整数版本号。可能是1-4。
原始传输(0x0200)- 带有自定义协议的双向链路。客户端将 WRITE_NO_RESPONSE 发送到特性,然后服务器通过 NOTIFY 进行回复。(这类似于Nordic UART服务,但仅在单个特性上,而不是两个。)传输特性上的命令是无操作性和无状态的。命令期间的断开将重置状态。
时间分辨率
时间分辨率根据文件系统类型而变化。FATFS在1980年之后只能降低到2秒的界限。Littlefs可以在1970年1月1日之后进行64位纳秒。
为了解决这个问题,协议使用1970年1月1日之后的64位纳秒来表示时间。然而,服务器将响应一个可能被截断的版本,该版本是存储的值。
此外,请注意,提供文件传输协议的设备可能没有自己的时钟,因此不要依赖时间顺序。任何内部写入都可能设置时间不正确。因此,我们只建议将其用作缓存键。
命令
命令始终以一个固定的头开始。第一个条目总是命令编号本身,编码在一个字节中。头部的后续条目数量将根据命令而变化。整个头部必须作为一个单位发送,因此将特性设置为完整的头部数据包。只要整个头部在数据包中,就可以将多个命令组合成一个写入。
路径使用 / 作为分隔符,完整路径必须以 / 开始。
所有数字都是无符号的。
所有值都相对于数据包的开始对齐。
状态字节是 0x01 表示正常,0x02 表示错误。除 0x01 之外的所有值都是错误。 0x00 不应用于特定错误,但仍被视为错误。 0x05 是尝试修改只读文件系统的错误。
0x10 - 读取文件
给定完整路径,返回文件的全部内容。
头部有四个固定条目和一个可变长度的路径
命令:单字节。总是 0x10。
1 字节保留用于填充。
路径长度:16位数字,表示路径字符串的编码长度。
块偏移:32位数字,表示文件中第一个块的偏移。
块大小:32位数字,表示客户端在第一个回复中可以处理的数据量。
路径:UTF-8编码的字符串,不是空终止的。(我们发送长度。)
服务器将响应
命令:单字节。总是 0x11。
状态:单字节。
2 字节保留用于填充。
块偏移:32位数字,表示此块在文件中的偏移。
总长度:32位数字,表示总文件长度。
块长度:32位数字,表示读取数据长度,直到提供的块大小。
从当前位置开始的文件块长度内容。
如果块长度小于总长度,则客户端将通过发送
命令:单字节。始终为0x12。
状态:单字节。目前始终为OK。
2 字节保留用于填充。
块偏移量:32位数字,表示文件中下一个块开始的偏移量。
块大小:32位数字,表示要读取的字节数。可能不同于原始大小。不需要受总大小的限制。
在服务器回复所有数据后,事务完成。(客户端不需要确认。)
0x20 - 写入文件
将内容写入给定的完整路径。如果文件存在,则将其覆盖。内容可能按接收方式写入,因此中断的传输可能导致文件截断。
大于现有文件大小的偏移量将在间隙中引入零。
头部有四个固定条目和一个可变长度的路径
命令:单字节。始终为0x20。
1 字节保留用于填充。
路径长度:16位数字,表示路径字符串的编码长度。
偏移量:32位数字,表示写入的起始偏移量。
当前时间:64位数字,表示自1970年1月1日以来的纳秒数。用作文件修改时间。不是所有系统都支持完整的分辨率。请使用截断的时间响应值进行缓存。
总大小:32位数字,表示文件内容的总长度。
路径:UTF-8编码的字符串,不是空终止的。(我们发送长度。)
服务器将重复响应,直到总长度已通过以下方式传输
命令:单字节。始终为0x21。
状态:单字节。如果OK,则为0x01。如果文件系统为只读,则为0x05。如果任何父目录不存在或为文件,则为0x02。
2 字节保留用于填充。
偏移量:32位数字,表示写入的起始偏移量。(应与之前的0x20或0x22消息中的偏移量匹配)
截断时间:64位数字,表示自1970年1月1日以来由文件系统存储的纳秒数。分辨率可能低于协议。它被发送回去以在主机端进行缓存。
可用空间:32位数字,表示客户端可以发送的数据量。
客户端将重复响应,直到总长度已通过以下方式传输
命令:单字节。始终为0x22。
状态:单字节。始终为0x01。
2 字节保留用于填充。
偏移量:32位数字,表示写入的偏移量。
数据大小:32位数字,表示客户端发送的数据量。
数据
在服务器接收所有数据并回复状态为0可用空间且偏移量设置为内容长度后,事务完成。
注意:当前时间是在版本3中添加的。其余的包保持不变。
0x30 - 删除文件或目录
删除给定完整路径上的文件或目录。非空目录的内容也将被删除。
头部是两个固定条目和一个可变长度路径
命令:单字节。始终为0x30。
1 字节保留用于填充。
路径长度:16位数字,表示路径字符串的编码长度。
路径:UTF-8编码的字符串,不是空终止的。(我们发送长度。)
服务器将回复
命令:单字节。始终为0x31。
状态:单字节。如果文件或目录被删除,则为0x01。如果文件系统为只读,则为0x05。如果路径不存在,则为0x02。
注意:在版本2中,此命令现在还删除目录的内容。它不会出错。
0x40 - 创建目录
在给定的完整路径上创建新的目录。如果父目录不存在,则也将创建它。如果任何名称与现有文件冲突,则将返回错误。
头部是两个固定条目和一个可变长度路径
命令:单字节。总是 0x40。
1 字节保留用于填充。
路径长度:16位数字,表示路径字符串的编码长度。
4字节用于填充。
当前时间:64位数字,表示自1970年1月1日以来的纳秒数。用作文件修改时间。不是所有系统都支持完整的分辨率。请使用截断的时间响应值进行缓存。
路径:UTF-8编码的字符串,不是空终止的。(我们发送长度。)
服务器将回复
命令:单字节。总是 0x41。
状态:单字节。如果目录创建成功则为 0x01,如果文件系统为只读则为 0x05,如果路径的任何父目录是现有文件则为 0x02。
6字节用于填充。
截断时间:64位数字,表示自1970年1月1日以来由文件系统存储的纳秒数。分辨率可能低于协议。它被发送回去以在主机端进行缓存。
0x50 - 列出目录
列出给定完整路径下的目录中所有内容。返回的路径与给定路径 相对,以减少重复。
头部是两个固定条目和一个可变长度路径
命令:单字节。总是 0x50。
1 字节保留用于填充。
路径长度:16位数字,表示路径字符串的编码长度。
路径:UTF-8编码的字符串,不是空终止的。(我们发送长度。)
对于有n个文件的目录,服务器将回复n+1个条目
命令:单字节。总是 0x51。
状态:单字节。如果目录存在则为 0x01,如果不存在则为 0x02。
路径长度:16位数字,表示路径字符串的编码长度。
条目编号:32位数字表示条目编号。
总条目数:32位数字表示总条目数。
标志:32位数字表示关于条目的数据。
位0:当条目是目录时设置
位1-7:保留
修改时间:自1970年1月1日起的纳秒数。 然而,文件修改者可能没有准确的时钟,因此不要假设它是正确的。相反,仅用它来确定缓存性与本地副本。
文件大小:32位数字表示文件的大小。对于目录忽略。值可能更改。
路径:UTF-8编码的字符串,不包含空终止符。(我们发送长度。)这些路径是相对的,因此不会包含 /。
当服务器从服务器发送最后一个条目时,事务完成。它将具有条目编号等于总条目数,标志、文件大小和路径长度为零。
0x60 - 移动文件或目录
将给定路径的文件或目录移动到不同的路径。也可以用于重命名。两个路径由一个字节分开,以便服务器可以自己空终止字符串。客户端可以发送任何内容。
头部是两个固定条目和一个可变长度路径
命令:单字节。总是 0x60。
1 字节保留用于填充。
旧路径长度:16位数字表示路径字符串的编码长度。
新路径长度:16位数字表示路径字符串的编码长度。
旧路径:UTF-8编码的字符串,不包含空终止符。(我们发送长度。)
一个填充字节。这可以用来空终止旧路径字符串。
新路径:UTF-8编码的字符串,不包含空终止符。(我们发送长度。)
服务器将回复
命令:单字节。总是 0x61。
状态:单字节。成功时为 0x01,只读时为 0x05,其他错误时为 0x02。
注意:这是在版本4中添加的。
版本
版本2
将删除改为自动删除非空目录的内容。
版本3
添加修改时间。* 将当前时间添加到文件写入命令。* 将当前时间添加到创建目录命令。* 将修改时间添加到目录列表条目。
版本4
添加移动命令。
添加0x05错误,用于只读文件系统。这通常是USB正在编辑相同的文件系统。
删除目录路径必须以/结尾的要求。
贡献
欢迎贡献!在为该项目做出贡献之前,请阅读我们的行为准则,以帮助保持项目的友好氛围。
文档
有关构建库文档的信息,请参阅本指南。
项目详情
哈希(adafruit-circuitpython-ble-file-transfer-4.0.7.tar.gz)
算法 | 哈希摘要 | |
---|---|---|
SHA256 | c2de567c4fb439a8766d98146507c8d8f127a5617fdb5671da6f94009d345737 |
|
MD5 | ef8d1ee7a735eaa92659a851318b7177 |
|
BLAKE2b-256 | 0df1e8479f9d7ceced4b5734677299d6cf19d0df303436e74931d5ccbaf69045 |
哈希(adafruit_circuitpython_ble_file_transfer-4.0.7-py3-none-any.whl)
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 46bfcf6a7b2057ec982c223c70c91f77ef48c2d931819657785f10db89e1f310 |
|
MD5 | c0bf4ff40c177dcf52244b0d14c7450c |
|
BLAKE2b-256 | 565d4fb91d0b38eadca916e0275b9726cff05baee48ae027bacbdf62ff3707d9 |