Search code examples
pythonstructnestedunpack

Unpacking nested C structs in Python


I am trying to unpack a C struct that is handed to my Python program in binary form and includes another nested struct. The relevant part of the C header looks like this:

typedef struct {
    uint8_t seq;
    uint8_t type;
    uint16_t flags;
    uint16_t upTimestamp;
}__attribute__ ((packed)) mps_packet_header;

typedef struct {
    mps_packet_header header;
    int16_t x[6];
    int16_t y[6];
    int16_t z[6];
    uint16_t lowTimestamp[6];
}__attribute__((packed)) mps_acc_packet_t;
typedef mps_acc_packet_t accpacket_t;

Now, in my Python program, I want to use struct.unpack to unpack an accpacket. However, I don't know what the format string for the unpack should be as the accpacket contains a nested mps_packet_header. I have tried just inserting the format string for the mps_packet_header at the beginning and then continuing with the rest of the accpacket:

s = struct.Struct('= B B H H 6h 6h 6h H')
seq, _type, flags, upTimestamp, x, y, z, lowTimestamp = s.unpack(packet_data)

However, this is apparently not correct; the format string has a calcsize of 44, while the struct itself has a size of 54.

How do I formulate a correct format string for this struct?


Solution

    1. You Struct format does not match with C structure. (final H should be 6H)
    2. struct.unpack(6h, ..) does return 6 fields. (not one with 6 elements)

    So your code should looks like ..

    s = struct.Struct('= B B H H 6h 6h 6h 6H')
    fields = s.unpack(packet_data)
    seq, _type, flags, upTimestamp = fields[:4]
    x = fields[4:10]
    y = fields[10:16]
    z = fields[16:22]
    lowTimestamp = fields[22:]