我试图编写一个简单的python客户端来解码从名为sdrdaemon的程序生成的二进制流。
协议为described here(为方便起见,下面复制)。我的理解是前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问题没有得到回复。
协议的完整说明是here,但也复制如下:
从硬件设备检索的数据块被切成UDP有效载荷大小的块。这个块序列称为&#34;帧&#34;在下面的。一个叫做&#34; meta&#34;的特殊块块在帧之前发送。它用于传达&#34; meta&#34;有关框架及其数据的数据。在这个&#34; meta&#34;上计算64位的CRC。数据并附加到它。它可以作为验证,也可以识别&#34; meta&#34;阻止数据块从而实现同步。将数据块与数据块混合的可能性非常低。
压缩流可以在一帧中打包从硬件检索的多个数据块,以提高压缩效率。因此可能出现这样的情况:元数据的变化发生在一个硬件上。阻止到同一帧中的下一个。在这种情况下,框架被拆分,并且新的框架被构造成具有起始的&#34; meta&#34;从元数据已更改的块中阻止。原始帧的第一部分通过UDP立即发送。这确保了数据框及其“元”#34;块总是一致的。
&#34; meta&#34;数据由以下内容组成(以字节表示的值):
总大小为42字节,包括8字节CRC。
当流是未压缩的时,有效载荷大小的UDP块填充有完整的I / Q样本,留下可能未使用的间隙小于块末尾的I / Q样本。最后一个块仅用剩余样本填充。最后一个块中的最大填充块和剩余样本的数量在&#34; meta&#34;中给出。数据。当然,由于数据流是未压缩的,因此也可以根据样本总数和有效负载大小计算这些值。
当压缩流时,UDP块完全填充压缩流的字节。最后一个块只用剩余字节填充。完整块和剩余字节的数量在&#34; meta&#34;中给出。阻止,否则无法计算这些值。
未压缩的流
hardware block (2 byte I or Q samples): |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| UDP block (22 bytes): |xxxxxxxxxxxxxxxxxxxxxx| Frame: |Meta: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:xxxxxxxxxx| Number of samples in a hardware block: 13 Number of blocks in a frame..........: 1 (always if uncompressed) Number of bytes in a frame...........: 52 (4 * 13) Complete blocks......................: 2 (calculated) Remainder samples....................: 3 (calculated)
编辑::我在发布后不久就放弃了这种方法(支持SoapySDR),因此无法再发表相关评论。
答案 0 :(得分:0)
我没有任何例子,但我在最后几天遇到了类似的问题,因此我找到了这个lib。但这是一个例子:https://github.com/construct/construct/tree/master/construct/examples/protocols
如果不行,我也可以删除我的答案。