1

我正在尝试使用 python 的位串来解释传入的数据包并将其分解为可读的部分。数据包将包含一个标头(Source(8bits),Destination(8bits),NS(3bits),NR(3bits),RSV(1bit),LST(1bit),OPcode(8bits),LEN(8bits)),有效负载介于 0 和 128 字节之间(由标头中的 LEN 确定)和 16 位的 CRC。

数据将通过 com 端口以大数据包的形式到达。数据来自一个微控制器,该微控制器将数据打包并将其发送给用户,这就是 python 发挥作用的地方。

由于我不确定如何在解析之前存储它,因此我没有任何代码。

我是 python 新手,需要一点帮助才能开始。

谢谢,埃里克

编辑

我目前有一段代码启动并运行,但它并没有产生我需要的东西......这是我启动并运行的代码段......

def packet_make(ser):
    src = 10
    p = 0
    lst = 0
    payload_make = 0
    crc = '0x0031'
    ns = 0
    nr = 0
    rsv = 0
    packet_timeout = 0

    top = 256
    topm = 255

    #os.system(['clear','cls'][os.name == 'nt'])
    print("\tBatts:   1 \t| Berry:   2 \t| Bessler: 3")
    print("\tCordell: 4 \t| Dave:    5 \t| Gold:    6")
    print("\tYen:     7   \t| Erik:    8 \t| Tommy:   9")
    print("\tParsons: 10 \t| JP:     11 \t| Sucess: 12")
    dst = raw_input("Please select a destination Adderss: ")

    message = raw_input("Please type a message: ")



    #################### Start Making packet#################
    p_msg = message
    message = message.encode("hex")
    ln = (len(message)/2)
    #print (ln)
    ln_hex = (ln * 2)
    message = list(message)
    num_of_packets = ((ln/128) + 1)
    #print (num_of_packets)

    message = "".join(message)

    src = hex(src)
    dst = hex(int(dst))
    #print (message)

    print("\n########Number of packets = "+str(num_of_packets) + " ############\n\n")

    for p in range (num_of_packets):
        Ack_rx = 0


        if( (p + 1) == (num_of_packets)):
            lst = 1
        else:
            lst = 0

        header_info = 0b00000000

        if ((p % 2) > 0):
            ns = 1
        else:
            ns = 0  


        header_info = (header_info | (ns << 5)) 
        header_info = (header_info | (nr << 2))
        header_info = (header_info | (rsv << 1))
        header_info = (header_info | (lst))
        header_info = hex(header_info)
        #print (header_info)
        op_code = '0x44'

        if (lst == 1):
            ln_packet = ((ln_hex - (p * 256)) % 256)
            if (p > 0):
                ln_packet = (ln_packet + 2)
            else:
                ln_packet = ln_packet
            ln_packet = (ln_packet / 2)
        #   print (ln_packet)
        #   print()
        else:
            ln_packet = 128
        #   print(ln_packet)
        #   print()

        #ll = (p * 128)
        #print(ll)
        #ul = ((ln - ll) % 128)
        #print(ul)
        #print (message[ll:ul])

        if ((p == 0)&(ln_hex > 256)):
            ll = (p * 255)
        #   print(ll)
            payload_make = (message[ll:256])
        #   print (payload_make)
        elif ((p > 0) & ((ln_hex - (p*256)) > 256)):
            ll = (p * 256)
        #   print(ll)
            ll = (ll - 2)
            ul = (ll + 256)
        #   print (ul)

            payload_make = (message[ll:ul])
        #   print(payload_make)
        elif ((p > 0) & ((ln_hex - (p*256)) < 257)):
            ll = (p * 256)
        #   print(ll)
            ll = (ll - 2)
            ul = ((ln_hex - ll) % 256)

            ul = (ll + (ul))
            ul = ul + 2
            print()
            print(ul)
            print(ln_hex)
            print(ln_packet)
            print()
        #   print(ul)
            payload_make = (message[ll:ul])
        #   print(payload)
        elif ((p == 0) & (ln_hex < 257)):
            ll = (p * 255)
            ul = ln_hex
            payload_make = (message[ll:ul])

        print(payload_make)

        packet_m = BitStream()  
########################HEADER#########################
        packet_m.append('0x0')
        packet_m.append(src)                        #src
        packet_m.append('0x0')  
        packet_m.append(dst)                        #dst
        if(int(header_info,16) < 16):
            packet_m.append('0x0')
        packet_m.append(header_info)                # Ns, Nr, RSV, Lst
        packet_m.append(op_code)                    #op Code
        #if(ln_packet < 16):
            #packet_m.append('0x0')
        packet_m.append((hex(ln_packet)))           #Length
###################END OF HEADER#######################     
        packet_m.append(("0x"+payload_make))    #Payload
        #packet_m.append(BitArray(p_msg))   #Payload
        packet_m.append(crc)                    #CRC    
        #print()
        #print(packet)
        temp_ack = '0x00'
        print(packet_m)
        print(ln_packet)
        while((Ack_rx == 0) & (packet_timeout <= 5)):
            try: 
                ###### Send the packet
                #ser.write(chr(0x31))

                str_pack = list(str(packet_m)[2:])
                "".join(str_pack)

                ser.write(chr(0x02))
                #ser.write((str(packet_m)[2:]))
                for i in range (len(str_pack)):
                    t = ord(str_pack[i])
                    ser.write(chr(t))
                    print(chr(t))


                ser.write(chr(0x04))
                ser.write(chr(0x10))

                ack_packet = BitStream(ser.read())
                if((len(ack_packet) > 3)):
                    temp_ack = ACK_parse(ack_packet)
                else:
                    packet_timeout = (packet_timeout + 1)
                    print "why so serious\n\n"
                if(temp_ack == '0x41'):
                    Ack_rx = 1
                elif (temp_ack == '0x4E'):
                    Ack_rx = 0
                else:
                    Acl_rx = 0 

            except serial.SerialTimeoutException: #if timeout occurs increment counter and resend last packet
                Ack_rx = 0
                packet_timeout = (packet_timeout + 1)


            except serial.SerialException:
                print "Error ... is not Active!!!", port

当 source 和 payload 都为 1 时,打印到终端的输出如下:

#######Number of packets = 1 #######

31
0x0a0101441310031
1
0
.... etc..

串行另一端的微读:0a0101441310031 当它应该读到 1 1 44 1 31 0031

Python 将每个值作为单独的字符发送,而不是将其作为一个字符发送。当它被附加到数据包中而不是存储到正确的长度和数据类型中时,它似乎已将十六进制分成 2 个 8 位位置而不是 1 个 8 位位置......

在读取确认数据包时,我从 Micro 读取的 Python 代码部分完美无缺。我没有用数据尝试过,但我认为这不会是一个问题。C 端无法从 python 端读取 ACK,因为它将十六进制值分成 2 个字符,而不是仅传输 8 位值......

有任何想法吗???谢谢

4

1 回答 1

6

您的确切问题有点模糊,但我应该能够帮助解决它的位串部分。

您可能已经将您的有效负载分析为一个str(或者可能bytes如果您使用的是 Python 3 但不要担心 - 它的工作方式相同)。如果你还没有那么远,那么你将不得不问一个更基本的问题。我将制作一些数据进行分析(所有这些都是通过交互式 Python 会话完成的):

>>> from bitstring import BitStream
>>> packet_data = '(2\x06D\x03\x124V\x03\xe8'
>>> b = BitStream(bytes=packet_data)

现在,您可以解压或使用 BitStream 上的读取来提取您需要的内容。例如:

>>> b.read('uint:8')
40
>>> b.read('uint:8')
50
>>> b.readlist('uint:3, uint:3')
[0, 1]
>>> b.readlist('2*bool')
[True, False]
>>> b.readlist('2*uint:8')
[68, 3]
>>> b.read('bytes:3')
'\x124V'

这只是解析字节并将块解释为无符号整数、布尔值或字节。查看手册了解更多详细信息。

如果你只想要有效载荷,那么你可以提取长度然后通过切片来获取它:

>>> length = b[32:40].uint
>>> b[40:40 + length*8]
BitStream('0x123456')

如果你想要它作为 Python str 回来,那么使用字节解释:

>>> b[40:40 + 3*8].bytes
'\x124V'

你也可以做一些更高级的事情,但是开始使用 Python 的一个好方法通常是打开一个交互式会话并尝试一些事情。

于 2012-03-30T12:22:07.040 回答