1

我正在尝试编写一个简单的 python 客户端来解码从名为sdrdaemon的程序生成的二进制流。

此处描述了该协议(为方便起见,复制如下)。我的理解是前 42 个字节应该包含我想用 python struct模块读取/解码的元帧。

我从一些非常简单的事情开始。

import select, socket
from struct import *

port = 19090
bufferSize = 512

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('localhost', port))
s.setblocking(0)

i=0
while i<10:
  result = select.select([s],[],[])
  msg = result[0][0].recv(bufferSize)
  # The meta section?
  msg = msg[:42]

  # Log raw bytes
  #print ' '.join('{0:08b}'.format(ord(x), 'b') for x in msg)

  print unpack(">QIxBHIHIIIQ", msg)  # big endian
  i += 1

但是我对这种事情不熟悉,无法理解我将如何同步,所以我解码了正确的部分。下面的描述指向 CRC,但我不确定如何去做。一点指导会很棒。一个 github 问题没有得到回应。

此处给出了该协议的完整解释,但也复制如下:

打包

从硬件设备检索的数据块被分割成 UDP 有效负载大小的块。该块序列在下文中称为“帧”。一个称为“元”块的特殊块在帧之前发送。它用于传达有关帧及其随后数据的“元”数据。对此“元”数据计算 64 位 CRC 并将其附加。它用作验证并从数据块中识别“元”块,从而实现同步。实际上,将其与数据块混合的可能性非常低。

一个压缩流可以把从硬件检索到的多个数据块打包在一帧中,以提高压缩效率。因此,可能会出现元数据在同一帧中从一个“硬件”块到下一个块发生变化的情况。在这种情况下,该帧被拆分,并使用来自元数据已更改的块的起始“元”块构造一个新帧。原始帧的第一部分立即通过 UDP 发送。这确保了数据帧和它的“元”块总是一致的。

元数据块

“元”数据块由以下内容组成(以字节表示的值):

元块 - 无包装

总大小为 42 字节,包括 8 字节 CRC。

数据块

当流未压缩时,有效载荷大小的 UDP 块被填充完整的 I/Q 样本,在块的末尾留下一个可能小于 I/Q 样本的未​​使用间隙。最后一个块仅填充剩余样本。在“元”数据中给出了最后一个块中最大填充块和剩余样本的数量。当然,由于数据流是未压缩的,这些值也可以从样本总数和有效负载大小中计算出来。

当流被压缩时,UDP 块完全被压缩流的字节填充。最后一个块仅用剩余字节填充。完整块和剩余字节的数量在“元”块中给出,否则无法计算这些值。

概要图

未压缩流

硬件块(2 字节 I 或 Q 样本):
|I/Q:I/Q:I/Q:I/Q:I/Q:I/Q:I/Q:I/Q:I/Q:I/Q:I/Q:I/Q:I /问|

UDP 块(22 字节):
|xxxxxxxxxxxxxxxxxxxxxxxx|

框架:
|元:xxxxxxxxxxxxxxxxx|I/Q:I/Q:I/Q:I/Q:I/Q:xx|I/Q:I/Q:I/Q:I/Q:I/Q:xx|I /Q:I/Q:I/Q:xxxxxxxxx|

硬件块中的样本数:13
一帧中的块数............:1(总是在未压缩的情况下)
一帧字节数............:52(4 * 13)
完整块......................:2(计算)
剩余样本.......................:3(计算)

编辑::我在发布后不久就放弃了这种方法(支持 SoapySDR),因此无法再真正发表相关评论。

4

1 回答 1

0

我没有任何示例,但最近几天我遇到了类似的问题,因此我找到了这个库。但这里有一个例子:https ://github.com/construct/construct/tree/master/construct/examples/protocols

如果不行,我也可以删除我的答案。

于 2017-07-05T11:57:01.937 回答