Naposledy aktivní 1 month ago

LRPT Packet Finder

Revize ebaae664deb546a74ef609a645d006a03542c768

packet-finder.py Raw
1#!/usr/bin/env python
2
3import os, math
4import collections
5
6'''
7Sync Words Phased
8
90 = 00011010 11001111 11111100 00011101 = 0x1ACFFC1D
101 = 10001111 01010101 01010110 10000100 = 0x8F555684
112 = 11100101 00110000 00000011 11100010 = 0xE53003E2
123 = 01110000 10101010 10101001 01111011 = 0x70AAA97B
13'''
14
15'''
16Sync Words 1/2 Symbols
170 = 00000011 11001100 11110000 11111111 11111111 11110000 00000011 11110011 = 0x03CCF0FFFFF030F3
181 = 11000000 11111111 00110011 00110011 00110011 00111100 11000000 00110000 = 0xC0FF3333333CC030
192 = 11111100 00110011 00001111 00000000 00000000 00001111 11111100 00001100 = 0xFC33F00000F0FCC0
203 = 00111111 00000000 11001100 11001100 11001100 11000011 00111111 11001111 = 0x3F00CCCCCCC33FCF
21
22 00000011 11001100 11110000 11111111 11111111 11110000 00000011 11110011
23S = 00000011 10010010 11100011 01010100 11100111 10100111 11010100 00010101
24
25 11111100 00110011 00001111 00000000 00000000 00001111 11111100 00001100
26F = 11111100 01101101 00011100 10101011 00011000 01011000 00101011 11101010
27 00000011 10010010 11100011 01010100 11100111 10100111 11010100 00010101
28'''
29
30
31'''
32Frame Size = 1024 bytes (1020 + 4)
33Rate = 1/2
34Frame Symbol Size = 1024 * 8 * 2
35
36Input = IQ Byte. Symbol = 2 Byte
37Frame Input Size = 1024 * 8 * 2 * 2
38'''
39
40frameSymbolSize = 1024 * 8
41frameInputSize = frameSymbolSize * 2
42frameBitSize = frameSymbolSize * 2
43syncWordSize = 32
44syncWordDoubleSize = syncWordSize * 2
45
46UW0 = 0x03CCF0FFFFF030F3
47UW1 = 0xC0FF3333333CC030
48UW2 = 0xFC33F00000F0FCC0
49UW3 = 0x3F00CCCCCCC33FCF
50
51def 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
89def 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
121def 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
127def binary(num, length=8):
128 return format(num, '#0{}b'.format(length + 2))
129
130def 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
138def 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
154def 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
189UW0 = binStringToIntArr(binary(UW0, syncWordDoubleSize))
190UW1 = binStringToIntArr(binary(UW1, syncWordDoubleSize))
191UW2 = binStringToIntArr(binary(UW2, syncWordDoubleSize))
192UW3 = binStringToIntArr(binary(UW3, syncWordDoubleSize))
193
194f = open("test.s", "r")
195fsize = os.path.getsize("test.s")
196o = open("test.s.out", "w")
197ob = open("test.s.outbit", "w")
198
199sbits = collections.deque(maxlen=frameBitSize)
200
201count = 0
202fcount = 0
203
204print "Frame Input Size: %s" %frameInputSize
205
206while 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
270f.close()
271o.close()
272ob.close()