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

GOES Packet Assemble

Версия 41abfc979acce7743ed0c435f387e936a2d5eb07

channelmuxer.py Исходник
1#!/usr/bin/env python
2
3import sys, struct, os, packetmanager
4
5FRAMESIZE = 892
6M_PDUSIZE = FRAMESIZE - 6
7EXPORTCORRUPT = False
8
9tsize = 0
10isCompressed = True
11
12SEQUENCE_FLAG_MAP = {
13 0: "Continued Segment",
14 1: "First Segment",
15 2: "Last Segment",
16 3: "Single Data"
17}
18
19def ParseMSDU(data):
20 o = struct.unpack(">H", data[:2])[0]
21 version = (o & 0xE000) >> 13
22 type = (o & 0x1000) >> 12
23 shf = (o & 0x800) >> 11
24 apid = (o & 0x7FF)
25
26 o = struct.unpack(">H", data[2:4])[0]
27 sequenceflag = (o & 0xC000) >> 14
28 packetnumber = (o & 0x3FFF)
29 packetlength = struct.unpack(">H", data[4:6])[0] -1
30 data = data[6:]
31 return version, type, shf, apid, sequenceflag, packetnumber, packetlength, data
32
33def CalcCRC(data):
34 lsb = 0xFF
35 msb = 0xFF
36 for c in data:
37 x = ord(c) ^ msb
38 x ^= (x >> 4)
39 msb = (lsb ^ (x >> 3) ^ (x << 4)) & 255
40 lsb = (x ^ (x << 5)) & 255
41 return (msb << 8) + lsb
42
43def CheckCRC(data, crc):
44 c = CalcCRC(data)
45 if not c == crc:
46 print " Expected: %s Found %s" %(hex(crc), hex(c))
47 return c == crc
48
49def SavePacket(channelid, packet):
50 global totalCRCErrors
51 global totalSavedPackets
52 global tsize
53 global isCompressed
54
55 #packet["sequenceflag_int"] = 3 # TEST
56 try:
57 os.mkdir("channels/%s" %channelid)
58 except:
59 pass
60
61 if packet["apid"] == 2047:
62 print " Fill Packet. Skipping"
63 return
64
65 datasize = len(packet["data"])
66
67 if not datasize - 2 == packet["size"]: # CRC is the latest 2 bytes of the payload
68 print " WARNING: Packet Size does not match! Expected %s Found: %s" %(packet["size"], len(packet["data"]))
69 if datasize - 2 > packet["size"]:
70 datasize = packet["size"] + 2
71 print " WARNING: Trimming data to %s" % datasize
72
73 data = packet["data"][:datasize-2]
74
75 if packet["sequenceflag_int"] == 1:
76 print "Starting packet %s_%s_%s.lrit" % (packet["apid"], packet["version"], packet["packetnumber"])
77 p = packetmanager.getHeaderData(data[10:])
78 for i in p:
79 if i["type"] == 1 or i["type"] == 129:
80 isCompressed = not i["compression"] == 0
81 elif packet["sequenceflag_int"] == 2:
82 print "Ending packet %s_%s_%s.lrit" % (packet["apid"], packet["version"], packet["packetnumber"])
83 if packet["framesdropped"]:
84 print " WARNING: Some frames has been droped for this packet."
85
86
87 if isCompressed:
88 filename = "channels/%s/%s_%s_%s.lrit" % (channelid, packet["apid"], packet["version"], packet["packetnumber"])
89 else:
90 filename = "channels/%s/%s_%s.lrit" % (channelid, packet["apid"], packet["version"])
91 #print "- Saving packet to %s" %filename
92
93
94 crc = packet["data"][datasize-2:datasize]
95 crc = struct.unpack(">H", crc)[0]
96 crc = CheckCRC(data, crc)
97 if not crc:
98 print " WARNING: CRC does not match!"
99 totalCRCErrors += 1
100
101 if crc or (EXPORTCORRUPT and not crc):
102 firstorsinglepacket = packet["sequenceflag_int"] == 1 or packet["sequenceflag_int"] == 3
103 if not isCompressed:
104 f = open(filename, "wb" if firstorsinglepacket else "ab")
105 else:
106 f = open(filename, "wb")
107
108 f.write(data[10:] if firstorsinglepacket else data) # Remove transport layer size
109 f.close()
110
111 if (packet["sequenceflag_int"] == 2 or packet["sequenceflag_int"] == 3) and not isCompressed:
112 print "File is not compressed. Checking headers."
113 packetmanager.manageFile(filename)
114
115 if firstorsinglepacket:
116 tsize = packet["size"]
117 else:
118 tsize += packet["size"]
119
120 if packet["sequenceflag_int"] == 2:
121 print " Total Size: %s" %tsize
122 totalSavedPackets += 1
123 else:
124 print " Corrupted frame, skipping..."
125
126def CreatePacket(data):
127 while True:
128 if len(data) < 6:
129 return -1, data
130 version, type, shf, apid, sequenceflag, packetnumber, packetlength, data = ParseMSDU(data)
131 pdata = data[:packetlength+2]
132 if apid != 2047:
133 pendingpackets[apid] = {
134 "data": pdata,
135 "version": version,
136 "type": type,
137 "apid": apid,
138 "sequenceflag": SEQUENCE_FLAG_MAP[sequenceflag],
139 "sequenceflag_int": sequenceflag,
140 "packetnumber": packetnumber,
141 "framesdropped": False,
142 "size": packetlength
143 }
144
145 #print "- Creating packet %s Size: %s - %s" % (apid, packetlength, SEQUENCE_FLAG_MAP[sequenceflag])
146 else:
147 apid = -1
148
149 if not packetlength+2 == len(data) and packetlength+2 < len(data): # Multiple packets in buffer
150 SavePacket(sys.argv[1], pendingpackets[apid])
151 del pendingpackets[apid]
152 data = data[packetlength+2:]
153 #print " Multiple packets in same buffer. Repeating."
154 else:
155 break
156 return apid, ""
157
158
159if len(sys.argv) < 2:
160 print "Usage: ./channeldecode.py CHANNELID"
161 print "This will open channels/channel_CHANNELID.bin"
162 exit()
163
164filename = "channels/channel_%s.bin" % sys.argv[1]
165
166f = open(filename, "r")
167fsize = os.path.getsize(filename)
168readbytes = 0
169
170pendingpackets = {}
171
172lastFrameNumber = -1
173totalFrameDrops = 0
174totalCRCErrors = 0
175totalSavedPackets = 0
176lastAPID = -1
177buff = ""
178
179while readbytes < fsize:
180 if fsize - readbytes < FRAMESIZE:
181 print " Some bytes at end of file was not enough for filling a frame. Remaining Bytes: %s - Frame Size: %s" % (fsize-readsize, FRAMESIZE)
182 break
183
184 # Read Data
185 data = f.read(FRAMESIZE)
186 versionNumber = (ord(data[0]) & 0xC0) >> 6
187 scid = (ord(data[0]) & 0x3F) << 2 | (ord(data[1]) & 0xC0) >> 6
188 vcid = (ord(data[1]) & 0x3F)
189
190 counter = struct.unpack(">I", data[2:6])[0]
191 counter &= 0xFFFFFF00
192 counter >>= 8
193
194 # Check for dropped Frames
195 if not lastFrameNumber == -1 and not lastFrameNumber+1 == counter:
196 print " Frames dropped: %s" % (counter-lastFrameNumber-1);
197 totalFrameDrops += counter-lastFrameNumber-1;
198 if not lastAPID == -1: # Fill
199 #pendingpackets[lastAPID]["data"] += "\x00" * 878
200 pendingpackets[lastAPID]["framesdropped"] = True
201
202
203 #print "SC: %s ID: %s Frame Number: %s" % (scid, vcid, counter)
204
205 # Demux M_PDU
206 data = data[6:] # Strip channel header
207 fhp = struct.unpack(">H", data[:2])[0] & 0x7FF
208 data = data[2:] # Strip M_PDU Header
209 #print " First Packet Header: %s" %fhp
210 #data is now TP_PDU
211 if not fhp == 2047: # Frame Contains a new Packet
212 # Data was incomplete on last FHP and another packet starts here.
213 if lastAPID == -1 and len(buff) > 0:
214 #print " Data was incomplete from last FHP. Parsing packet now"
215 if fhp > 0:
216 buff += data[:fhp]
217 lastAPID, data = CreatePacket(buff)
218 if lastAPID == -1:
219 buff = data
220 else:
221 buff = ""
222
223 if not lastAPID == -1: # We are finishing another packet
224 if fhp > 0:
225 pendingpackets[lastAPID]["data"] += data[:fhp]
226 SavePacket(sys.argv[1], pendingpackets[lastAPID])
227 del pendingpackets[lastAPID]
228 lastAPID = -1
229
230 # Try to create a new packet
231 buff += data[fhp:]
232 lastAPID, data = CreatePacket(buff)
233 if lastAPID == -1:
234 buff = data
235 else:
236 buff = ""
237 else:
238 if len(buff) > 0 and lastAPID == -1:
239 #print " Data was incomplete from last FHP. Parsing packet now"
240 buff += data
241 lastAPID, data = CreatePacket(buff)
242 if lastAPID == -1:
243 buff = data
244 else:
245 buff = ""
246 elif len(buff) > 0:
247 print " PROBLEM!"
248 elif lastAPID == -1:
249 buff += data
250 lastAPID, data = CreatePacket(buff)
251 if lastAPID == -1:
252 buff = data
253 else:
254 buff = ""
255 else:
256 #print " Appending %s bytes to %s" % (lastAPID, len(data))
257 pendingpackets[lastAPID]["data"] += data
258
259
260 lastFrameNumber = counter
261 readbytes += FRAMESIZE
262
263# One packet can be still in pending packets
264for i in pendingpackets.keys():
265 SavePacket(sys.argv[1], pendingpackets[lastAPID])
266
267print "\n\nReport:"
268print "\tTotal Frames Dropped: %s" %totalFrameDrops
269print "\tTotal Saved Packets: %s" %totalSavedPackets
270print "\tTotal Packet CRC Fails: %s" %totalCRCErrors
271
272f.close()
packetinfo.py Исходник
1#!/usr/bin/env python
2
3import sys, struct, os
4
5from packetmanager import *
6
7if len(sys.argv) < 2:
8 print "Usage: packetinfo.py filename.lrit"
9 exit(1)
10
11filename = sys.argv[1]
12
13f = open(filename, "r")
14fsize = os.path.getsize(filename)
15readbytes = 0
16t = 0
17
18data = f.read()
19
20headers = getHeaderData(data)
21hsize = 0
22ftype = 0
23for i in headers:
24 if i["type"] == 0:
25 hsize = i["headerlength"]
26 ftype = i["filetypecode"]
27
28printHeaders(headers)
29
30data = data[hsize:]
31
32if ftype == 2:
33 print data
34
35f.close()
packetmanager.py Исходник
1#!/usr/bin/env python
2import os, struct
3
4'''
5 File Type Codes:
6 0 - Image
7 2 - Text
8 130 - DCS Data
9'''
10
11def manageFile(filename):
12 f = open(filename, "r")
13
14 try:
15 k = readHeader(f)
16 print k
17 type, filetypecode, headerlength, datalength = k
18 except:
19 print " Header 0 is corrupted for file %s" %filename
20 return
21
22 newfilename = filename
23 while f.tell() < headerlength:
24 data = readHeader(f)
25 if data[0] == 4:
26 print " Filename is %s" % data[1]
27 newfilename = data[1]
28 break
29 f.close()
30 if filename != newfilename:
31 print " Renaming %s to %s/%s" %(filename, os.path.dirname(filename), newfilename)
32 os.rename(filename, "%s/%s" %(os.path.dirname(filename), newfilename))
33 #os.unlink(filename)
34 else:
35 print " Couldn't find name in %s" %filename
36
37def getHeaderData(data):
38 headers = []
39 while len(data) > 0:
40 type = ord(data[0])
41 size = struct.unpack(">H", data[1:3])[0]
42 o = data[3:size]
43 data = data[size:]
44 td = parseHeader(type, o)
45 headers.append(td)
46 if td["type"] == 0:
47 print "Header Size: %s" % td["headerlength"]
48 data = data[:td["headerlength"]-size]
49 return headers
50
51def parseHeader(type, data):
52 if type == 0:
53 filetypecode, headerlength, datalength = struct.unpack(">BIQ", data)
54 return {"type":type, "filetypecode":filetypecode, "headerlength":headerlength, "datalength":datalength}
55 elif type == 1:
56 bitsperpixel, columns, lines, compression = struct.unpack(">BHHB", data)
57 return {"type":type, "bitsperpixel":bitsperpixel, "columns":columns, "lines":lines, "compression":compression}
58
59 elif type == 2:
60 projname, cfac, lfac, coff, loff = struct.unpack(">32sIIII", data)
61 return {"type":type, "projname":projname, "cfac":cfac, "lfac":lfac, "coff":coff, "loff":loff}
62
63 elif type == 3:
64 return {"type":type, "data":data}
65
66 elif type == 4:
67 return {"type":type, "filename":data}
68
69 elif type == 5:
70 days, ms = struct.unpack(">HI", data[1:])
71 return {"type":type, "days":days, "ms":ms}
72
73 elif type == 6:
74 return {"type":type, "data":data}
75
76 elif type == 7:
77 return {"type":type, "data":data}
78
79 elif type == 128:
80 imageid, sequence, startcol, startline, maxseg, maxcol, maxrow = struct.unpack(">7H", data)
81 return {"type":type, "imageid":imageid, "sequence":sequence, "startcol":startcol, "startline":startline, "maxseg":maxseg, "maxcol":maxcol, "maxrow":maxrow}
82
83 elif type == 129:
84 signature, productId, productSubId, parameter, compression = struct.unpack(">4sHHHB", data)
85 return {"type":type, "signature":signature, "productId":productId, "productSubId":productSubId, "parameter":parameter, "compression":compression}
86
87 elif type == 130:
88 return {"type":type, "data":data}
89
90 elif type == 131:
91 flags, pixel, line = struct.unpack(">HBB", data)
92 return {"type":type, "flags":flags, "pixel":pixel, "line":line}
93
94 elif type == 132:
95 return {"type":type, "data": data}
96 else:
97 return {"type":type}
98
99def readHeader(f):
100 global t
101 type = ord(f.read(1))
102 size = f.read(2)
103 size = struct.unpack(">H", size)[0]
104 data = f.read(size-3)
105
106 if type == 0:
107 filetypecode, headerlength, datalength = struct.unpack(">BIQ", data)
108 return type, filetypecode, headerlength, datalength
109 elif type == 1:
110 bitsperpixel, columns, lines, compression = struct.unpack(">BHHB", data)
111 return type, bitsperpixel, columns, lines, compression
112
113 elif type == 2:
114 projname, cfac, lfac, coff, loff = struct.unpack(">32sIIII", data)
115 return type, projname, cfac, lfac, coff, loff
116
117 elif type == 3:
118 return type, data
119
120 elif type == 4:
121 return type, data
122
123 elif type == 5:
124 days, ms = struct.unpack(">HI", data[1:])
125 return type, days, ms
126
127 elif type == 6:
128 return type, data
129
130 elif type == 7:
131 return type, data
132
133 elif type == 128:
134 imageid, sequence, startcol, startline, maxseg, maxcol, maxrow = struct.unpack(">7H", data)
135 return type, imageid, sequence, startcol, startline, maxseg, maxcol, maxrow
136
137 elif type == 129:
138 signature, productId, productSubId, parameter, compression = struct.unpack(">4sHHHB", data)
139 return type, signature, productId, productSubId, parameter, compression
140
141 elif type == 130:
142 return type, data
143
144 elif type == 131:
145 flags, pixel, line = struct.unpack(">HBB", data)
146 return type, flags, pixel, line
147
148 elif type == 132:
149 return type, data
150
151 else:
152 return type
153
154def printHeaders(headers, showStructuredHeader=False, showImageDataRecord=False):
155 for head in headers:
156 type = head["type"]
157 if type == 0:
158 print "Header type: %s File Type Code: %s Header Length %s Data Field Length: %s" %(type, head["filetypecode"], head["headerlength"], head["datalength"])
159 elif type == 1:
160 print "Image Structure Header: "
161 print " Bits Per Pixel: %s" %head["bitsperpixel"]
162 print " Columns: %s" %head["columns"]
163 print " Lines: %s" %head["lines"]
164 print " Compression: %s" %head["compression"]
165
166 elif type == 2:
167 print "Image Navigation Record"
168 print " Projection Name: %s" %head["projname"]
169 print " Column Scaling Factor: %s" %head["cfac"]
170 print " Line Scaling Factor: %s" %head["lfac"]
171 print " Column Offset: %s" %head["coff"]
172 print " Line Offset: %s" %head["loff"]
173
174 elif type == 3:
175 print "Image Data Function Record"
176 if showImageDataRecord:
177 print " Data: %s" %head["data"]
178 else:
179 print " Data: {HIDDEN}"
180
181 elif type == 4:
182 print "Annotation Record"
183 print " Filename: %s" %head["filename"]
184
185 elif type == 5:
186 print "Timestamp Record"
187 print " Delta from 1 January 1958"
188 print " Days: %s" %head["days"]
189 print " Miliseconds: %s" %head["ms"]
190
191 elif type == 6:
192 print "Ancillary Text"
193 print " Data: "
194 t = head["data"].split(";")
195 for i in t:
196 print " %s" %i
197
198 elif type == 7:
199 print "Key Header"
200 print " Data: %s" %head["data"]
201
202 elif type == 128:
203 print "Segment Identification Header"
204 print " Image Id: %s" %head["imageid"]
205 print " Sequence: %s" %head["sequence"]
206 print " Start Column: %s" %head["startcol"]
207 print " Start Line: %s" %head["startline"]
208 print " Number of Segments: %s" %head["maxseg"]
209 print " Width: %s" %head["maxcol"]
210 print " Height: %s" %head["maxrow"]
211
212 elif type == 129:
213 print "NOAA Specific Header"
214 print " Signature: %s" %head["signature"]
215 print " Product ID: %s" %head["productId"]
216 print " Product SubId: %s" %head["productSubId"]
217 print " Parameter: %s" %head["parameter"]
218 print " Compression: %s" %head["compression"]
219
220 elif type == 130:
221 print "Header Structured Record"
222 if showImageDataRecord:
223 t = head["data"].split("UI")
224 print " Data: "
225 for i in t:
226 print " %s" %i
227 else:
228 print " Data: {HIDDEN}"
229
230 elif type == 131:
231 print "Rice Compression Record"
232 print " Flags: %s" %head["flags"]
233 print " Pixel: %s" %head["pixel"]
234 print " Line: %s" %head["line"]
235
236 elif type == 132: # Got in DCS Data
237 print "DCS Data: "
238 print " Data: %s" %head["data"]
239
240 else:
241 print "Type not mapped: %s" % type
242 print ""