1

I'm setting a value (PID) in the 13 bits allocated as per the mask.. i'm trying to set a flag on bit 4 as well as keeping the original value in the 13 bit mask..

enter image description here

Thoughts??

header =    0x0

pid_mask =  0x1fff
TP_mask =   0x2000
PID =       0x1FFe #8190
TP =        0x1

header = ((header & pid_mask) | (PID << 8))

print(bin(header))
print(hex(header))
print(int(header))

header = ((header & TP_mask) | (TP << 12))


print(bin(header))
print(hex(header))
print(int(header))

And this is my output

This part is good (first print statements)

0b111111111111000000000
0x1ffe00
2096640

This part I expect to be the above + the additional bit flip (second print statements)

0b11000000000000
0x3000
12288

Update

I was being a total Muppet, thanks to @Lesiak for all his help

Here is the updated code

def createHeader(pid,tei,pusi,tranportPriority,tsc,afc,cc):

header = pid << 8

if tei == 1:
    header = header | (0x1 << (22 + 1))
    print(bin(header))
if pusi == 1:
    header = header | (0x1 << (21 + 1))
    print(bin(header))
if tranportPriority == 1:
    header = header | (0x1 << (8 + 13))
    print(bin(header))


    header = header | (tsc << 6)
    print(bin(header))
    header = header | (afc << 4)
    print(bin(header))
    header = header | (cc << 0)
    print(bin(header))

print(hex(header))

return header


header = (createHeader(pid,1,1,1,0x1,0x1,0x2))

The only problem I have is a have to slice off the last byte header[1:4] as it returns 4 bytes not 3. Not sure why....

Neil Bernard
  • 131
  • 2
  • 9

1 Answers1

1

You are constructing a new packet from scratch. There is no sense in using a bitmask for that. Just place the appropriate chunks of the packet in their respective places. To determine the right place, check your protocol definition and calculate the number of bits in the fields fill the less-significant bits.

PID =       0x1FFe #8190
TP =        0x1

header = PID << 8

print(bin(header))
print(hex(header))
print(int(header))

header = header | (TP << (8 + 13))


print(bin(header))
print(hex(header))
print(int(header))

You should use bitmask in the inversed scenario: you received a packet and want to extract data out of it.

Update

How I arrived to 8 bit shift for PID and 21 for TP? Look at the protocol definition: There are 8 bits that go after PID (they are on less significant bits)

  • 4 for Continuity Counter
  • 2 for Adaptation field control
  • 2 for Transport scrambling control

For TP:

  • 8 bits from the list above
  • 13 bits for PID
Lesiak
  • 22,088
  • 2
  • 41
  • 65
  • Thanks @Lesiak, Thats working but i dont quite understand the maths? How did you come to 8+13? – Neil Bernard Oct 27 '19 at 08:28
  • ' pid = 0x1FFe #8190 def createHeader(pid,tei,pusi,tranportPriority): header = pid << 8 if tei == 1: header = header | (0x1 << (10 + 13)) if pusi == 1: header = header | (0x1 << (9 + 13)) if tranportPriority == 1: header = header | (0x1 << (8 + 13)) return header print(hex(createHeader(pid,1,0,1))) print(hex(createHeader(pid,0,0,1))) ' – Neil Bernard Oct 27 '19 at 08:35
  • Above is the code I got working, not sure why the code formatting isn't working... So I really no just need to understand the maths (sorry i'm in the slow learners group) – Neil Bernard Oct 27 '19 at 08:37
  • Hi Lesaik and thanks for your patience, you probably think im a bit of a Muppet, ive updated my code on the original post (i dont know how to get it working in comments...) I think im starting to understand.... I dont though understand how to deal with the first 8 bytes...specifically the first 4 bits..... – Neil Bernard Oct 27 '19 at 11:27
  • your brilliant thanks! If you know why I get 4 bytes instead of 3 though let me know :) – Neil Bernard Oct 27 '19 at 13:47
  • I'm a bit lost. How come your header is now subscriptable? It used to be a number. Have you converted it to a byte array? How? – Lesiak Oct 27 '19 at 14:47
  • Oh I see I had to use a function to turn it into bytes so that then i could use a byte array. https://www.dropbox.com/s/om8zxc5hqarvywm/MPEG2_NULL_GEN.py?dl=0 if your interested in seeing what I did.... I appologise im not a software guy :( – Neil Bernard Oct 27 '19 at 16:56
  • This is the more comprehensive project https://www.dropbox.com/s/4awd2h6ncnqq0gx/MPEG_IMPAIRMENT_GEN.py?dl=0 – Neil Bernard Oct 27 '19 at 17:02
  • you receive 4 bytes as you return a number, and that number fills 4 bytes. Why dont you set syncByte in createHeader? Then: header.to_bytes(4, byteorder='big') is already implemented. You also have a bug after if transportPriority, indentation matters in python. For style: reorder your statements so that fields are set according to layout in packet. Name magic numbers (like PID_OFFSET = 8 etc) – Lesiak Oct 27 '19 at 17:46
  • Thank for responding ;) I will def run through the code and see if I can find the bug...and tidy up the magic numbers ;) the reason the sync byte is a variable is because I need to change it... The idea is that I generate various transport stream impairments to see how hard ware that I'm testing handles it. – Neil Bernard Oct 29 '19 at 07:46
  • I have a similar but new question: https://stackoverflow.com/questions/58657928/python-need-help-understanding-bit-wise-and-byte-manipulation-unexpected-behavio in case anyone can help – Neil Bernard Nov 01 '19 at 10:55