Последняя активность 1 month ago

LRPT Packet Finder

Версия 208217d43e7ef9391a31aaff10dbc04e4785b5b9

packet-finder.py Исходник
1#!/usr/bin/env python
2
3import os, math
4import collections
5
6ifile = "sample.s" #"sample.s"
7ofile = "sample.s.out"#"sample.s.out"
8skipi = 0 #4800
9
10'''
11Sync Words Phased
12
130 = 00011010 11001111 11111100 00011101 = 0x1ACFFC1D
141 = 10001111 01100101 01010110 10000100 = 0x8F655684
152 = 11100101 00110000 00000011 11100010 = 0xE53003E2
163 = 01110000 10011010 10101001 01111011 = 0x709AA97B
17
18
19
2010001111 01100101 01010110 10000100
2101110000 10011010 10101001 01111011
22
23'''
24
25'''
26Sync Word in 1/2 k=7 FEC:
27
281111 1100 1010 0010 1011 0110 0011 1101 1011 0000 0000 1101 1001 0111 1001 0100 0xfca2b63db00d9794
290101 0110 1111 1011 1101 0011 1001 0100 1101 1010 1010 0100 1100 0001 1100 0010 0x56fbd394daa4c1c2
300000 0011 0101 1101 0100 1001 1100 0010 0100 1111 1111 0010 0110 1000 0110 1011 0x035d49c24ff2686b
311010 1001 0000 0100 0010 1100 0110 1011 0010 0101 0101 1011 0011 1110 0011 1101 0xa9042c6b255b3e3d
32'''
33
34'''
35Frame Size = 1024 bytes (1020 + 4)
36Rate = 1/2
37Frame Symbol Size = 1024 * 8 * 2
38
39Input = IQ Byte. Symbol = 2 Byte
40Frame Input Size = 1024 * 8 * 2 * 2
41'''
42
43frameSymbolSize = 1024 * 8
44frameInputSize = frameSymbolSize * 2
45frameBitSize = frameSymbolSize * 2
46syncWordSize = 32
47syncWordDoubleSize = 64
48
49UW0 = 0xfca2b63db00d9794
50UW1 = 0x56fbd394daa4c1c2
51UW2 = 0x035d49c24ff2686b
52UW3 = 0xa9042c6b255b3e3d
53
54def 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
92def 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
126def 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
132def binary(num, length=8):
133 return format(num, '#0{}b'.format(length + 2))
134
135def 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
143invertIQ = False
144
145def 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
166def 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
201UW0 = binStringToIntArr(binary(UW0, syncWordDoubleSize))
202UW1 = binStringToIntArr(binary(UW1, syncWordDoubleSize))
203UW2 = binStringToIntArr(binary(UW2, syncWordDoubleSize))
204UW3 = binStringToIntArr(binary(UW3, syncWordDoubleSize))
205
206#f = open("test.s", "r")
207f = open(ifile, "r")
208fsize = os.path.getsize(ifile)
209o = open(ofile, "w")
210ob = open(ofile + "bit", "w")
211
212sbits = collections.deque(maxlen=frameBitSize)
213
214count = 0
215fcount = 0
216
217f.seek(skipi)
218count += skipi
219
220print "Frame Input Size: %s" %frameInputSize
221
222while 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
287f.close()
288o.close()
289ob.close()