00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 import sys
00018 import os
00019
00020 from pymavlink import mavutil
00021
00022 from construct import ULInt16, Struct, Byte, Bytes, Const
00023 from construct.core import FieldError
00024 from argparse import ArgumentParser, FileType
00025
00026
00027 MAVLINK_MAGIC = 0xfe
00028 write_junk = True
00029
00030
00031 MAVLINK_MESSAGE_CRCS = (50, 124, 137, 0, 237, 217, 104, 119, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 214, 159, 220, 168, 24, 23, 170, 144, 67, 115, 39, 246, 185, 104, 237, 244, 242, 212, 9, 254, 230, 28, 28, 132, 221, 232, 11, 153, 41, 39, 214, 223, 141, 33, 15, 3, 100, 24, 239, 238, 30, 240, 183, 130, 130, 0, 148, 21, 0, 243, 124, 0, 0, 0, 20, 0, 152, 143, 0, 0, 127, 106, 0, 0, 0, 0, 0, 0, 0, 231, 183, 63, 54, 0, 0, 0, 0, 0, 0, 0, 175, 102, 158, 208, 56, 93, 0, 0, 0, 0, 235, 93, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 241, 15, 134, 219, 208, 188, 84, 22, 19, 21, 134, 0, 78, 68, 189, 127, 111, 21, 21, 144, 1, 234, 73, 181, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 49, 170, 44, 83, 46, 0)
00032
00033
00034 import __builtin__
00035 import struct
00036
00037
00038 class pcap:
00039 """
00040 Used under the terms of GNU GPL v3.
00041 Original author: Neale Pickett
00042 see http://dirtbags.net/py-pcap.html
00043 """
00044 _MAGIC = 0xA1B2C3D4
00045 def __init__(self, stream, mode='rb', snaplen=65535, linktype=1):
00046 try:
00047 self.stream = __builtin__.open(stream, mode)
00048 except TypeError:
00049 self.stream = stream
00050 try:
00051
00052 hdr = self.stream.read(24)
00053 except IOError:
00054 hdr = None
00055
00056 if hdr:
00057
00058 self._endian = pcap.None
00059 for endian in '<>':
00060 (self.magic,) = struct.unpack(endian + 'I', hdr[:4])
00061 if self.magic == pcap._MAGIC:
00062 self._endian = endian
00063 break
00064 if not self._endian:
00065 raise IOError('Not a pcap file')
00066 (self.magic, version_major, version_minor,
00067 self.thiszone, self.sigfigs,
00068 self.snaplen, self.linktype) = struct.unpack(self._endian + 'IHHIIII', hdr)
00069 if (version_major, version_minor) != (2, 4):
00070 raise IOError('Cannot handle file version %d.%d' % (version_major,
00071 version_minor))
00072 else:
00073
00074 self._endian = '='
00075 self.magic = pcap._MAGIC
00076 version_major = 2
00077 version_minor = 4
00078 self.thiszone = 0
00079 self.sigfigs = 0
00080 self.snaplen = snaplen
00081 self.linktype = linktype
00082 hdr = struct.pack(self._endian + 'IHHIIII',
00083 self.magic, version_major, version_minor,
00084 self.thiszone, self.sigfigs,
00085 self.snaplen, self.linktype)
00086 self.stream.write(hdr)
00087 self.version = (version_major, version_minor)
00088
00089 def read(self):
00090 hdr = self.stream.read(16)
00091 if not hdr:
00092 return
00093 (tv_sec, tv_usec, caplen, length) = struct.unpack(self._endian + 'IIII', hdr)
00094 datum = self.stream.read(caplen)
00095 return ((tv_sec, tv_usec, length), datum)
00096
00097 def write(self, packet):
00098 (header, datum) = packet
00099 (tv_sec, tv_usec, length) = header
00100 hdr = struct.pack(self._endian + 'IIII', tv_sec, tv_usec, length, len(datum))
00101 self.stream.write(hdr)
00102 self.stream.write(datum)
00103
00104 def __iter__(self):
00105 while True:
00106 r = self.read()
00107 if not r:
00108 break
00109 yield r
00110
00111
00112 def find_next_frame(data):
00113 """
00114 find a potential start of frame
00115 """
00116 return data.find('\xfe')
00117
00118
00119 def parse_header(data):
00120 """
00121 split up header information (using construct)
00122 """
00123 mavlink_header = Struct('header',
00124 Const(Byte('magic'), MAVLINK_MAGIC),
00125 Byte('plength'),
00126 Byte('sequence'),
00127 Byte('sysid'),
00128 Byte('compid'),
00129 Byte('msgid'),
00130 )
00131 return mavlink_header.parse(data[0:6])
00132
00133
00134 def write_packet(number, data, flags, pkt_length):
00135 pcap_header = (number, flags, pkt_length)
00136 pcap_file.write((pcap_header, data))
00137
00138
00139 def convert_file(mavlink_file, pcap_file):
00140
00141 data = mavlink_file.read()
00142
00143 i=0
00144 done = False
00145 skipped_char = None
00146 junk = ''
00147 cnt_ok = 0
00148 cnt_junk = 0
00149 cnt_crc = 0
00150
00151 while not done:
00152 i+=1
00153
00154 next_sof = find_next_frame(data)
00155 if next_sof > 0:
00156 print("skipped " + str(next_sof) + " bytes")
00157 if write_junk:
00158 if skipped_char != None:
00159 junk = skipped_char + data[:next_sof]
00160 skipped_char = None
00161 write_packet(i, junk, 0x03, len(junk))
00162 data = data[next_sof:]
00163 data[:6]
00164 cnt_junk += 1
00165
00166
00167 header = parse_header(data)
00168 payload_len = header['plength']
00169 pkt_length = 6 + payload_len + 2
00170 try:
00171 pkt_crc = ULInt16('crc').parse(data[pkt_length-2:pkt_length])
00172 except FieldError:
00173
00174 done = True
00175 continue
00176
00177
00178 try:
00179 cc = mavutil.x25crc(data[1:6+payload_len])
00180 cc.accumulate(chr(MAVLINK_MESSAGE_CRCS[header['msgid']]))
00181 x25_crc = cc.crc
00182 if x25_crc != pkt_crc:
00183 crc_flag = 0x1
00184 else:
00185 crc_flag = 0
00186 next_magic = data[pkt_length]
00187 if chr(MAVLINK_MAGIC) != next_magic:
00188
00189 print("packet %d has invalid length, crc error: %d" % (i, crc_flag))
00190
00191
00192 skipped_char = data[0]
00193 data = data[1:]
00194 continue
00195
00196
00197 pkt = data[:pkt_length]
00198 write_packet(i, pkt, crc_flag, len(pkt))
00199 print("packet %d ok, crc error: %d" % (i, crc_flag))
00200 data = data[pkt_length:]
00201
00202 if crc_flag:
00203 cnt_crc += 1
00204 else:
00205 cnt_ok += 1
00206
00207
00208 except IndexError:
00209
00210 done = True
00211 print("converted %d valid packets, %d crc errors, %d junk fragments (total %f%% of junk)" % (cnt_ok, cnt_crc, cnt_junk, 100.*float(cnt_junk+cnt_crc)/(cnt_junk+cnt_ok+cnt_crc)))
00212
00213
00214
00215 parser = ArgumentParser()
00216 parser.add_argument("input_file", type=FileType('rb'))
00217 parser.add_argument("output_file", type=FileType('wb'))
00218 args = parser.parse_args()
00219
00220
00221 mavlink_file = args.input_file
00222 args.output_file.close()
00223 pcap_file = pcap(args.output_file.name, args.output_file.mode, linktype=147)
00224
00225 convert_file(mavlink_file, pcap_file)
00226
00227 mavlink_file.close()
00228