packet-finder.py
· 6.9 KiB · Python
Surowy
#!/usr/bin/env python
import os, math
import collections
ifile = "sample.s" #"sample.s"
ofile = "sample.s.out"#"sample.s.out"
skipi = 0 #4800
'''
Sync Words Phased
0 = 00011010 11001111 11111100 00011101 = 0x1ACFFC1D
1 = 10001111 01100101 01010110 10000100 = 0x8F655684
2 = 11100101 00110000 00000011 11100010 = 0xE53003E2
3 = 01110000 10011010 10101001 01111011 = 0x709AA97B
10001111 01100101 01010110 10000100
01110000 10011010 10101001 01111011
'''
'''
Sync Word in 1/2 k=7 FEC:
1111 1100 1010 0010 1011 0110 0011 1101 1011 0000 0000 1101 1001 0111 1001 0100 0xfca2b63db00d9794
0101 0110 1111 1011 1101 0011 1001 0100 1101 1010 1010 0100 1100 0001 1100 0010 0x56fbd394daa4c1c2
0000 0011 0101 1101 0100 1001 1100 0010 0100 1111 1111 0010 0110 1000 0110 1011 0x035d49c24ff2686b
1010 1001 0000 0100 0010 1100 0110 1011 0010 0101 0101 1011 0011 1110 0011 1101 0xa9042c6b255b3e3d
'''
'''
Frame Size = 1024 bytes (1020 + 4)
Rate = 1/2
Frame Symbol Size = 1024 * 8 * 2
Input = IQ Byte. Symbol = 2 Byte
Frame Input Size = 1024 * 8 * 2 * 2
'''
frameSymbolSize = 1024 * 8
frameInputSize = frameSymbolSize * 2
frameBitSize = frameSymbolSize * 2
syncWordSize = 32
syncWordDoubleSize = 64
UW0 = 0xfca2b63db00d9794
UW1 = 0x56fbd394daa4c1c2
UW2 = 0x035d49c24ff2686b
UW3 = 0xa9042c6b255b3e3d
def processFrame(frameData, n):
'''
Gets the bit array, corrects the phase ambiguity and returns a byte array
frameData = bit array
n = phase number(0 = 0, 1 = 90, 2 = 180, 3 = 270)
'''
# Fix Ambiguity
'''
p0 p1 p2 p3
00 10 11 01
01 00 10 11
11 01 00 10
10 11 01 00
'''
if n == 1 or n == 3: # 90 / 270 phase
# We can just shift to 90 and if its 270 we invert the bits later
for i in range(0, len(frameData), 2):
a = 1 if frameData[i+1] == 0 else 0
b = 0 if frameData[i] == 0 else 1
frameData[i] = a
frameData[i+1] = b
if n == 2 or n == 3: # 180 / 270 is 0 / 90 inverted
frameData = invertBits(frameData)
# Generate byte array
bdata = ""
for i in range(0, len(frameData), 8):
v = 0
for k in range(0, 8):
v = v << 1
v = v | frameData[i+k]
bdata += chr(v)
return bdata
def processFrameBitMap(frameData, n):
'''
Gets the bit array, corrects the phase ambiguity and returns a byte array
frameData = bit array
n = phase number(0 = 0, 1 = 90, 2 = 180, 3 = 270)
'''
# Fix Ambiguity
'''
p0 p1 p2 p3
00 10 11 01
01 00 10 11
11 01 00 10
10 11 01 00
'''
if n == 1 or n == 3: # 90 / 270 phase
# We can just shift to 90 and if its 270 we invert the bits later
for i in range(0, len(frameData), 2):
a = 0 if frameData[i+1] == 0 else 1
b = 1 if frameData[i] == 0 else 0
frameData[i] = a
frameData[i+1] = b
if n == 2 or n == 3: # 180 / 270 is 0 / 90 inverted
frameData = invertBits(frameData)
# Generate byte array
bdata = ""
for i in range(0, len(frameData)):
bdata += chr(0xFF) if frameData[i] == 1 else chr(0x00)
#bdata += chr(0xFF) if frameData[i] == 1 else chr(0x00)
#bdata += chr(0xFF) if frameData[i] == 1 else chr(0x00)
return bdata
def invertBits(frame):
for i in range(0, len(frame)):
frame[i] = 1 if frame[i] == 0 else 0
return frame
def binary(num, length=8):
return format(num, '#0{}b'.format(length + 2))
def binStringToIntArr(b):
if b[1] == 'b':
b = b[2:]
a = []
for i in b:
a.append(int(i))
return a
invertIQ = False
def symbolToBit(symbol):
bdata = []
if not invertIQ:
I = ord(symbol[0]) - 127
Q = ord(symbol[1]) - 127
else:
I = ord(symbol[1]) - 127
Q = ord(symbol[0]) - 127
if I > 0:
bdata.append(1)
else:
bdata.append(0)
if Q > 0:
bdata.append(1)
else:
bdata.append(0)
return bdata
def checkCorrelationInBuffer():
uw0mc = 0 # Highest Correlation Factor for UW0
uw0p = 0 # Highest Correlation Position for UW0
uw1mc = 0
uw1p = 0
uw2mc = 0
uw2p = 0
uw3mc = 0
uw3p = 0
for i in range(0, frameBitSize - syncWordDoubleSize):
uw0c = 0
uw1c = 0
uw2c = 0
uw3c = 0
# To get the highest correlation, we xor with the word. So 180 phase
for k in range(0, syncWordDoubleSize):
uw0c += sbits[i+k] ^ UW0[k]
uw1c += sbits[i+k] ^ UW1[k]
uw2c += sbits[i+k] ^ UW2[k]
uw3c += sbits[i+k] ^ UW3[k]
uw0p = i if uw0c > uw0mc else uw0p
uw1p = i if uw1c > uw1mc else uw1p
uw2p = i if uw2c > uw2mc else uw2p
uw3p = i if uw3c > uw3mc else uw3p
uw0mc = uw0c if uw0c > uw0mc else uw0mc
uw1mc = uw1c if uw1c > uw1mc else uw1mc
uw2mc = uw2c if uw2c > uw2mc else uw2mc
uw3mc = uw3c if uw3c > uw3mc else uw3mc
return uw0p, uw0mc, uw1p, uw1mc, uw2p, uw2mc, uw3p, uw3mc
UW0 = binStringToIntArr(binary(UW0, syncWordDoubleSize))
UW1 = binStringToIntArr(binary(UW1, syncWordDoubleSize))
UW2 = binStringToIntArr(binary(UW2, syncWordDoubleSize))
UW3 = binStringToIntArr(binary(UW3, syncWordDoubleSize))
#f = open("test.s", "r")
f = open(ifile, "r")
fsize = os.path.getsize(ifile)
o = open(ofile, "w")
ob = open(ofile + "bit", "w")
sbits = collections.deque(maxlen=frameBitSize)
count = 0
fcount = 0
f.seek(skipi)
count += skipi
print "Frame Input Size: %s" %frameInputSize
while count < fsize:
'''
Read the data from input to sbits
'''
data = f.read(frameInputSize)
for i in range(0, frameInputSize, 2):
b = symbolToBit(data[i:i+2])
sbits.append(b[0])
sbits.append(b[1])
'''
Search for the sync word using correlation
'''
uw0p, uw0mc, uw1p, uw1mc, uw2p, uw2mc, uw3p, uw3mc = checkCorrelationInBuffer()
mp = max(uw0mc, uw1mc, uw2mc, uw3mc)
print "Frame: #%s" %fcount
print "Max Correlation: %s" %mp
if mp == uw0mc:
print "Max Correlation with 0 degrees Word at %s" % uw0p
n = 0
p = uw0p
elif mp == uw1mc:
print "Max Correlation with 90 degrees Word at %s" % uw1p
n = 1
p = uw1p
elif mp == uw2mc:
print "Max Correlation with 180 degrees Word at %s" % uw2p
n = 2
p = uw2p
elif mp == uw3mc:
print "Max Correlation with 270 degrees Word at %s" % uw3p
n = 3
p = uw3p
if mp < 47:
print "Frame Lock Error"
count += frameInputSize
else:
'''
Read p bits for syncing the Circle Buffer
Each pair of bits come from 2 bytes of the input
So we will read 1 byte per bit
'''
#p -= 12
t = p if p % 2 == 0 else p + 1
data = f.read(t)
for i in range(0, t, 2):
b = symbolToBit(data[i:i+2])
sbits.append(b[0])
sbits.append(b[1])
'''
Now we should have everything in sync
'''
frame = processFrame(list(sbits), n)
o.write(frame)
frameb = processFrameBitMap(list(sbits), n)
ob.write(frameb)
fcount += 1
count += frameInputSize + t
'''
Clean everything
'''
f.close()
o.close()
ob.close()
| 1 | #!/usr/bin/env python |
| 2 | |
| 3 | import os, math |
| 4 | import collections |
| 5 | |
| 6 | ifile = "sample.s" #"sample.s" |
| 7 | ofile = "sample.s.out"#"sample.s.out" |
| 8 | skipi = 0 #4800 |
| 9 | |
| 10 | ''' |
| 11 | Sync Words Phased |
| 12 | |
| 13 | 0 = 00011010 11001111 11111100 00011101 = 0x1ACFFC1D |
| 14 | 1 = 10001111 01100101 01010110 10000100 = 0x8F655684 |
| 15 | 2 = 11100101 00110000 00000011 11100010 = 0xE53003E2 |
| 16 | 3 = 01110000 10011010 10101001 01111011 = 0x709AA97B |
| 17 | |
| 18 | |
| 19 | |
| 20 | 10001111 01100101 01010110 10000100 |
| 21 | 01110000 10011010 10101001 01111011 |
| 22 | |
| 23 | ''' |
| 24 | |
| 25 | ''' |
| 26 | Sync Word in 1/2 k=7 FEC: |
| 27 | |
| 28 | 1111 1100 1010 0010 1011 0110 0011 1101 1011 0000 0000 1101 1001 0111 1001 0100 0xfca2b63db00d9794 |
| 29 | 0101 0110 1111 1011 1101 0011 1001 0100 1101 1010 1010 0100 1100 0001 1100 0010 0x56fbd394daa4c1c2 |
| 30 | 0000 0011 0101 1101 0100 1001 1100 0010 0100 1111 1111 0010 0110 1000 0110 1011 0x035d49c24ff2686b |
| 31 | 1010 1001 0000 0100 0010 1100 0110 1011 0010 0101 0101 1011 0011 1110 0011 1101 0xa9042c6b255b3e3d |
| 32 | ''' |
| 33 | |
| 34 | ''' |
| 35 | Frame Size = 1024 bytes (1020 + 4) |
| 36 | Rate = 1/2 |
| 37 | Frame Symbol Size = 1024 * 8 * 2 |
| 38 | |
| 39 | Input = IQ Byte. Symbol = 2 Byte |
| 40 | Frame Input Size = 1024 * 8 * 2 * 2 |
| 41 | ''' |
| 42 | |
| 43 | frameSymbolSize = 1024 * 8 |
| 44 | frameInputSize = frameSymbolSize * 2 |
| 45 | frameBitSize = frameSymbolSize * 2 |
| 46 | syncWordSize = 32 |
| 47 | syncWordDoubleSize = 64 |
| 48 | |
| 49 | UW0 = 0xfca2b63db00d9794 |
| 50 | UW1 = 0x56fbd394daa4c1c2 |
| 51 | UW2 = 0x035d49c24ff2686b |
| 52 | UW3 = 0xa9042c6b255b3e3d |
| 53 | |
| 54 | def processFrame(frameData, n): |
| 55 | ''' |
| 56 | Gets the bit array, corrects the phase ambiguity and returns a byte array |
| 57 | frameData = bit array |
| 58 | n = phase number(0 = 0, 1 = 90, 2 = 180, 3 = 270) |
| 59 | ''' |
| 60 | # Fix Ambiguity |
| 61 | ''' |
| 62 | p0 p1 p2 p3 |
| 63 | 00 10 11 01 |
| 64 | 01 00 10 11 |
| 65 | 11 01 00 10 |
| 66 | 10 11 01 00 |
| 67 | ''' |
| 68 | |
| 69 | if n == 1 or n == 3: # 90 / 270 phase |
| 70 | # We can just shift to 90 and if its 270 we invert the bits later |
| 71 | for i in range(0, len(frameData), 2): |
| 72 | a = 1 if frameData[i+1] == 0 else 0 |
| 73 | b = 0 if frameData[i] == 0 else 1 |
| 74 | frameData[i] = a |
| 75 | frameData[i+1] = b |
| 76 | |
| 77 | if n == 2 or n == 3: # 180 / 270 is 0 / 90 inverted |
| 78 | frameData = invertBits(frameData) |
| 79 | |
| 80 | # Generate byte array |
| 81 | bdata = "" |
| 82 | for i in range(0, len(frameData), 8): |
| 83 | v = 0 |
| 84 | for k in range(0, 8): |
| 85 | v = v << 1 |
| 86 | v = v | frameData[i+k] |
| 87 | bdata += chr(v) |
| 88 | |
| 89 | return bdata |
| 90 | |
| 91 | |
| 92 | def processFrameBitMap(frameData, n): |
| 93 | ''' |
| 94 | Gets the bit array, corrects the phase ambiguity and returns a byte array |
| 95 | frameData = bit array |
| 96 | n = phase number(0 = 0, 1 = 90, 2 = 180, 3 = 270) |
| 97 | ''' |
| 98 | # Fix Ambiguity |
| 99 | ''' |
| 100 | p0 p1 p2 p3 |
| 101 | 00 10 11 01 |
| 102 | 01 00 10 11 |
| 103 | 11 01 00 10 |
| 104 | 10 11 01 00 |
| 105 | ''' |
| 106 | |
| 107 | if n == 1 or n == 3: # 90 / 270 phase |
| 108 | # We can just shift to 90 and if its 270 we invert the bits later |
| 109 | for i in range(0, len(frameData), 2): |
| 110 | a = 0 if frameData[i+1] == 0 else 1 |
| 111 | b = 1 if frameData[i] == 0 else 0 |
| 112 | frameData[i] = a |
| 113 | frameData[i+1] = b |
| 114 | |
| 115 | if n == 2 or n == 3: # 180 / 270 is 0 / 90 inverted |
| 116 | frameData = invertBits(frameData) |
| 117 | |
| 118 | # Generate byte array |
| 119 | bdata = "" |
| 120 | for i in range(0, len(frameData)): |
| 121 | bdata += chr(0xFF) if frameData[i] == 1 else chr(0x00) |
| 122 | #bdata += chr(0xFF) if frameData[i] == 1 else chr(0x00) |
| 123 | #bdata += chr(0xFF) if frameData[i] == 1 else chr(0x00) |
| 124 | return bdata |
| 125 | |
| 126 | def invertBits(frame): |
| 127 | for i in range(0, len(frame)): |
| 128 | frame[i] = 1 if frame[i] == 0 else 0 |
| 129 | |
| 130 | return frame |
| 131 | |
| 132 | def binary(num, length=8): |
| 133 | return format(num, '#0{}b'.format(length + 2)) |
| 134 | |
| 135 | def binStringToIntArr(b): |
| 136 | if b[1] == 'b': |
| 137 | b = b[2:] |
| 138 | a = [] |
| 139 | for i in b: |
| 140 | a.append(int(i)) |
| 141 | return a |
| 142 | |
| 143 | invertIQ = False |
| 144 | |
| 145 | def symbolToBit(symbol): |
| 146 | bdata = [] |
| 147 | if not invertIQ: |
| 148 | I = ord(symbol[0]) - 127 |
| 149 | Q = ord(symbol[1]) - 127 |
| 150 | else: |
| 151 | I = ord(symbol[1]) - 127 |
| 152 | Q = ord(symbol[0]) - 127 |
| 153 | |
| 154 | if I > 0: |
| 155 | bdata.append(1) |
| 156 | else: |
| 157 | bdata.append(0) |
| 158 | |
| 159 | if Q > 0: |
| 160 | bdata.append(1) |
| 161 | else: |
| 162 | bdata.append(0) |
| 163 | |
| 164 | return bdata |
| 165 | |
| 166 | def checkCorrelationInBuffer(): |
| 167 | uw0mc = 0 # Highest Correlation Factor for UW0 |
| 168 | uw0p = 0 # Highest Correlation Position for UW0 |
| 169 | uw1mc = 0 |
| 170 | uw1p = 0 |
| 171 | uw2mc = 0 |
| 172 | uw2p = 0 |
| 173 | uw3mc = 0 |
| 174 | uw3p = 0 |
| 175 | |
| 176 | for i in range(0, frameBitSize - syncWordDoubleSize): |
| 177 | uw0c = 0 |
| 178 | uw1c = 0 |
| 179 | uw2c = 0 |
| 180 | uw3c = 0 |
| 181 | # To get the highest correlation, we xor with the word. So 180 phase |
| 182 | for k in range(0, syncWordDoubleSize): |
| 183 | uw0c += sbits[i+k] ^ UW0[k] |
| 184 | uw1c += sbits[i+k] ^ UW1[k] |
| 185 | uw2c += sbits[i+k] ^ UW2[k] |
| 186 | uw3c += sbits[i+k] ^ UW3[k] |
| 187 | |
| 188 | uw0p = i if uw0c > uw0mc else uw0p |
| 189 | uw1p = i if uw1c > uw1mc else uw1p |
| 190 | uw2p = i if uw2c > uw2mc else uw2p |
| 191 | uw3p = i if uw3c > uw3mc else uw3p |
| 192 | |
| 193 | uw0mc = uw0c if uw0c > uw0mc else uw0mc |
| 194 | uw1mc = uw1c if uw1c > uw1mc else uw1mc |
| 195 | uw2mc = uw2c if uw2c > uw2mc else uw2mc |
| 196 | uw3mc = uw3c if uw3c > uw3mc else uw3mc |
| 197 | |
| 198 | return uw0p, uw0mc, uw1p, uw1mc, uw2p, uw2mc, uw3p, uw3mc |
| 199 | |
| 200 | |
| 201 | UW0 = binStringToIntArr(binary(UW0, syncWordDoubleSize)) |
| 202 | UW1 = binStringToIntArr(binary(UW1, syncWordDoubleSize)) |
| 203 | UW2 = binStringToIntArr(binary(UW2, syncWordDoubleSize)) |
| 204 | UW3 = binStringToIntArr(binary(UW3, syncWordDoubleSize)) |
| 205 | |
| 206 | #f = open("test.s", "r") |
| 207 | f = open(ifile, "r") |
| 208 | fsize = os.path.getsize(ifile) |
| 209 | o = open(ofile, "w") |
| 210 | ob = open(ofile + "bit", "w") |
| 211 | |
| 212 | sbits = collections.deque(maxlen=frameBitSize) |
| 213 | |
| 214 | count = 0 |
| 215 | fcount = 0 |
| 216 | |
| 217 | f.seek(skipi) |
| 218 | count += skipi |
| 219 | |
| 220 | print "Frame Input Size: %s" %frameInputSize |
| 221 | |
| 222 | while count < fsize: |
| 223 | ''' |
| 224 | Read the data from input to sbits |
| 225 | ''' |
| 226 | data = f.read(frameInputSize) |
| 227 | for i in range(0, frameInputSize, 2): |
| 228 | b = symbolToBit(data[i:i+2]) |
| 229 | sbits.append(b[0]) |
| 230 | sbits.append(b[1]) |
| 231 | |
| 232 | ''' |
| 233 | Search for the sync word using correlation |
| 234 | ''' |
| 235 | |
| 236 | uw0p, uw0mc, uw1p, uw1mc, uw2p, uw2mc, uw3p, uw3mc = checkCorrelationInBuffer() |
| 237 | mp = max(uw0mc, uw1mc, uw2mc, uw3mc) |
| 238 | print "Frame: #%s" %fcount |
| 239 | print "Max Correlation: %s" %mp |
| 240 | if mp == uw0mc: |
| 241 | print "Max Correlation with 0 degrees Word at %s" % uw0p |
| 242 | n = 0 |
| 243 | p = uw0p |
| 244 | elif mp == uw1mc: |
| 245 | print "Max Correlation with 90 degrees Word at %s" % uw1p |
| 246 | n = 1 |
| 247 | p = uw1p |
| 248 | elif mp == uw2mc: |
| 249 | print "Max Correlation with 180 degrees Word at %s" % uw2p |
| 250 | n = 2 |
| 251 | p = uw2p |
| 252 | elif mp == uw3mc: |
| 253 | print "Max Correlation with 270 degrees Word at %s" % uw3p |
| 254 | n = 3 |
| 255 | p = uw3p |
| 256 | if mp < 47: |
| 257 | print "Frame Lock Error" |
| 258 | count += frameInputSize |
| 259 | else: |
| 260 | ''' |
| 261 | Read p bits for syncing the Circle Buffer |
| 262 | Each pair of bits come from 2 bytes of the input |
| 263 | So we will read 1 byte per bit |
| 264 | ''' |
| 265 | #p -= 12 |
| 266 | t = p if p % 2 == 0 else p + 1 |
| 267 | data = f.read(t) |
| 268 | for i in range(0, t, 2): |
| 269 | b = symbolToBit(data[i:i+2]) |
| 270 | sbits.append(b[0]) |
| 271 | sbits.append(b[1]) |
| 272 | |
| 273 | ''' |
| 274 | Now we should have everything in sync |
| 275 | ''' |
| 276 | frame = processFrame(list(sbits), n) |
| 277 | o.write(frame) |
| 278 | frameb = processFrameBitMap(list(sbits), n) |
| 279 | ob.write(frameb) |
| 280 | fcount += 1 |
| 281 | count += frameInputSize + t |
| 282 | |
| 283 | ''' |
| 284 | Clean everything |
| 285 | ''' |
| 286 | |
| 287 | f.close() |
| 288 | o.close() |
| 289 | ob.close() |