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