views:

169

answers:

1

I am trying to build a fixed length packet in python for an ATSC PSIP generator. This is probably very simple but so far I can't seem to get it to work. I am trying to build a packet with fields similar to the following:

table_id = 0xCB
syntax = 0b1
reserved = 0b11
table_ext = 0xFF

the end goal would be the following in binary

'1100101111111111111'

I have tried a dozen different things and can't get the results I would expect. I am going to send this via sockets so I believe it needs to end up in a string.

+3  A: 

You can use the struct module to build binary strings from arbitrary layouts.

That can only generate byte-aligned structures, but you'll need to be byte aligned to send on the network socket anyway.

EDIT:

So the format you're generating really does have non-aligned bits 8-1-1-2-12-16 etc.

In order to send on a socket you'll need to be byte aligned, but I guess that the protocol handles that some how. (maybe with padding bits somewhere?)

My new suggestion would be to build up a bit string, then chop it up into 8-bit blocks and convert from there:

input_binary_string = "110010111111111111101010" ## must be a multiple of 8
out = []
while len(input_binary_string) >= 8:
    byte = input_binary_string[:8]
    input_binary_string = input_binary_string[8:]
    b = int(byte,2)
    c = chr(b)
    out.append(c)
## Better not have a bits left over
assert len(input_binary_string) == 0
outString = "".join(out)

print [ ord(c) for c in out ]
Douglas Leeder
Struct can't seem to handle adding just one bit... am I missing something?
RogueFalcon
the smallest unit of data that can be used with the struct module and with sockets is 1 byte
Steg
I assume then that means the struct module doesn't help me.
RogueFalcon
When you send on a socket you're going to need byte aligned blocks.All protocols I've ever seen are byte-aligned - are you sure ATSC PSIP isn't?
Douglas Leeder
I checked out ATSC PSIP (http://www.atsc.org/standards/a_65cr1_with_amend_1.pdf) and it looks like the data structures you need to send around are all byte aligned blocks - its just that, in each block, specific bits can correspond to different fields. so, struct won't get you 100% of the way. For a particular byte within a block that is split into, say, 3 fields, you would have to construct the value of that byte using standard bit-wise operations (http://docs.python.org/library/stdtypes.html#bit-string-operations-on-integer-types) and then set that byte in the block using the struct module.
Steg
Thanks Douglas! I started working on a similar approach but your method is much cleaner. I really appreciate it.
RogueFalcon