最后活跃于 1 month ago

GOES Packet Assemble

修订 e9ff35127f396a8e3006a7e9a8d414d1e1c18151

channeldecoder.py 原始文件
1#!/usr/bin/env python
2
3import sys, struct, os, packetmanager
4
5FRAMESIZE = 892
6M_PDUSIZE = FRAMESIZE - 6
7EXPORTCORRUPT = False
8
9SEQUENCE_FLAG_MAP = {
10 0: "Continued Segment",
11 1: "First Segment",
12 2: "Last Segment",
13 3: "Single Data"
14}
15
16def ParseMSDU(data):
17 o = struct.unpack(">H", data[:2])[0]
18 version = (o & 0xE000) >> 13
19 type = (o & 0x1000) >> 12
20 shf = (o & 0x800) >> 11
21 apid = (o & 0x7FF)
22
23 o = struct.unpack(">H", data[2:4])[0]
24 sequenceflag = (o & 0xC000) >> 14
25 packetnumber = (o & 0x3FFF)
26 packetlength = struct.unpack(">H", data[4:6])[0] -1
27 data = data[6:]
28 return version, type, shf, apid, sequenceflag, packetnumber, packetlength, data
29
30def CalcCRC(data):
31 lsb = 0xFF
32 msb = 0xFF
33 for c in data:
34 x = ord(c) ^ msb
35 x ^= (x >> 4)
36 msb = (lsb ^ (x >> 3) ^ (x << 4)) & 255
37 lsb = (x ^ (x << 5)) & 255
38 return (msb << 8) + lsb
39
40def CheckCRC(data, crc):
41 c = CalcCRC(data)
42 if not c == crc:
43 print " Expected: %s Found %s" %(hex(crc), hex(c))
44 return c == crc
45
46def SavePacket(channelid, packet):
47 global totalCRCErrors
48 global totalSavedPackets
49 try:
50 os.mkdir("channels/%s" %channelid)
51 except:
52 pass
53
54 if packet["apid"] == 2047:
55 print " Fill Packet. Skipping"
56 return
57
58 filename = "channels/%s/%s_%s.lrit" % (channelid, packet["apid"], packet["version"])
59 print "- Saving packet to %s" %filename
60
61 if packet["framesdropped"]:
62 print " WARNING: Some frames has been droped for this packet."
63
64 datasize = len(packet["data"])
65
66 if not datasize - 2 == packet["size"]: # CRC is the latest 2 bytes of the payload
67 print " WARNING: Packet Size does not match! Expected %s Found: %s" %(packet["size"], len(packet["data"]))
68 if datasize - 2 > packet["size"]:
69 datasize = packet["size"] + 2
70 print " WARNING: Trimming data to %s" % datasize
71
72 data = packet["data"][:datasize-2]
73
74 crc = packet["data"][datasize-2:datasize]
75 crc = struct.unpack(">H", crc)[0]
76 crc = CheckCRC(data, crc)
77 if not crc:
78 print " WARNING: CRC does not match!"
79 totalCRCErrors += 1
80
81 if crc or (EXPORTCORRUPT and not crc):
82 firstorsinglepacket = packet["sequenceflag_int"] == 1 or packet["sequenceflag_int"] == 3
83 f = open(filename, "w" if firstorsinglepacket else "a")
84 f.write(data[10:] if firstorsinglepacket else data) # Remove transport layer size
85 f.close()
86 if packet["sequenceflag_int"] == 2 or packet["sequenceflag_int"] == 3:
87 packetmanager.manageFile(filename)
88 totalSavedPackets += 1
89 else:
90 print " Corrupted frame, skipping..."
91
92def CreatePacket(data):
93 while True:
94 if len(data) < 6:
95 return -1, data
96 version, type, shf, apid, sequenceflag, packetnumber, packetlength, data = ParseMSDU(data)
97 pdata = data[:packetlength+2]
98 if apid != 2047:
99 pendingpackets[apid] = {
100 "data": pdata,
101 "version": version,
102 "type": type,
103 "apid": apid,
104 "sequenceflag": SEQUENCE_FLAG_MAP[sequenceflag],
105 "sequenceflag_int": sequenceflag,
106 "packetnumber": packetnumber,
107 "framesdropped": False,
108 "size": packetlength
109 }
110
111 print "- Creating packet %s Size: %s - %s" % (apid, packetlength, SEQUENCE_FLAG_MAP[sequenceflag])
112 else:
113 apid = -1
114
115 if not packetlength+2 == len(data) and packetlength+2 < len(data): # Multiple packets in buffer
116 SavePacket(sys.argv[1], pendingpackets[apid])
117 del pendingpackets[apid]
118 data = data[packetlength+2:]
119 #print " Multiple packets in same buffer. Repeating."
120 else:
121 break
122 return apid, ""
123
124
125if len(sys.argv) < 2:
126 print "Usage: ./channeldecode.py CHANNELID"
127 print "This will open channels/channel_CHANNELID.bin"
128 exit()
129
130filename = "channels/channel_%s.bin" % sys.argv[1]
131
132f = open(filename, "r")
133fsize = os.path.getsize(filename)
134readbytes = 0
135
136pendingpackets = {}
137
138lastFrameNumber = -1
139totalFrameDrops = 0
140totalCRCErrors = 0
141totalSavedPackets = 0
142lastAPID = -1
143buff = ""
144
145while readbytes < fsize:
146 if fsize - readbytes < FRAMESIZE:
147 print " Some bytes at end of file was not enough for filling a frame. Remaining Bytes: %s - Frame Size: %s" % (fsize-readsize, FRAMESIZE)
148 break
149
150 # Read Data
151 data = f.read(FRAMESIZE)
152 versionNumber = (ord(data[0]) & 0xC0) >> 6
153 scid = (ord(data[0]) & 0x3F) << 2 | (ord(data[1]) & 0xC0) >> 6
154 vcid = (ord(data[1]) & 0x3F)
155
156 counter = struct.unpack(">I", data[2:6])[0]
157 counter &= 0xFFFFFF00
158 counter >>= 8
159
160 # Check for dropped Frames
161 if not lastFrameNumber == -1 and not lastFrameNumber+1 == counter:
162 print " Frames dropped: %s" % (counter-lastFrameNumber-1);
163 totalFrameDrops += counter-lastFrameNumber-1;
164 if not lastAPID == -1: # Fill
165 pendingpackets[lastAPID]["data"] += "\x00" * 878
166 pendingpackets[lastAPID]["framesdropped"] = True
167
168
169 #print "SC: %s ID: %s Frame Number: %s" % (scid, vcid, counter)
170
171 # Demux M_PDU
172 data = data[6:] # Strip channel header
173 fhp = struct.unpack(">H", data[:2])[0] & 0x7FF
174 data = data[2:] # Strip M_PDU Header
175 #print " First Packet Header: %s" %fhp
176 #data is now TP_PDU
177 if not fhp == 2047: # Frame Contains a new Packet
178 # Data was incomplete on last FHP and another packet starts here.
179 if lastAPID == -1 and len(buff) > 0:
180 #print " Data was incomplete from last FHP. Parsing packet now"
181 if fhp > 0:
182 buff += data[:fhp]
183 lastAPID, data = CreatePacket(buff)
184 if lastAPID == -1:
185 buff = data
186 else:
187 buff = ""
188
189 if not lastAPID == -1: # We are finishing another packet
190 if fhp > 0:
191 pendingpackets[lastAPID]["data"] += data[:fhp]
192 SavePacket(sys.argv[1], pendingpackets[lastAPID])
193 del pendingpackets[lastAPID]
194 lastAPID = -1
195
196 # Try to create a new packet
197 buff += data[fhp:]
198 lastAPID, data = CreatePacket(buff)
199 if lastAPID == -1:
200 buff = data
201 else:
202 buff = ""
203 else:
204 if len(buff) > 0 and lastAPID == -1:
205 #print " Data was incomplete from last FHP. Parsing packet now"
206 buff += data
207 lastAPID, data = CreatePacket(buff)
208 if lastAPID == -1:
209 buff = data
210 else:
211 buff = ""
212 elif len(buff) > 0:
213 print " PROBLEM!"
214 elif lastAPID == -1:
215 buff += data
216 lastAPID, data = CreatePacket(buff)
217 if lastAPID == -1:
218 buff = data
219 else:
220 buff = ""
221 else:
222 #print " Appending %s bytes to %s" % (lastAPID, len(data))
223 pendingpackets[lastAPID]["data"] += data
224
225
226 lastFrameNumber = counter
227 readbytes += FRAMESIZE
228
229# One packet can be still in pending packets
230for i in pendingpackets.keys():
231 SavePacket(sys.argv[1], pendingpackets[lastAPID])
232
233print "\n\nReport:"
234print "\tTotal Frames Dropped: %s" %totalFrameDrops
235print "\tTotal Saved Packets: %s" %totalSavedPackets
236print "\tTotal Packet CRC Fails: %s" %totalCRCErrors
237
238f.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 ""