#!/usr/bin/ruby require 'stringio' $: << File::join(File::dirname(__FILE__), '..', '..', 'common', 'ruby') require 'util' require 'gnuplot_support' if RUBY_VERSION >= "1.9.0" Encoding.default_external = 'ASCII-8BIT' else class String def getbyte(index) return self[index] end end end options = { :sylphide => true, } ARGV.reject!{|arg| if arg =~ /--([^=]+)=?/ then options[$1.to_sym] = $' true else false end } options[:sylphide] = (options[:sylphide] == "true") if options[:sylphide].kind_of? String $stderr.print "options: " $stderr.puts options.inspect src = (ARGV.empty? or ARGV.first == '-') ? $stdin : open(ARGV.shift) dst = open(options[:out], 'w') rescue $stdout src.binmode rescue nil dst.binmode rescue nil binr_protocol = /\x10((?:[^\x10]+|\x10\x10)+)(?:\x10\xFF..)?\x10\x03/ =begin a = "\x10\x21\x01\x10\x03" a += "\x10\x21\x10\x10\x10\x10\x10\x10\x10\x03" a.scan(binr_protocol){|match| p match } exit =end buf = StringIO::new if options[:sylphide] then while !src.eof? page = src.read(32) next unless page[0] == ?C buf.print page[1..-1] end else buf.print src.read end #dst.print buf.string #buf = StringIO::new("\x10\x21\x01\x10\x03\x10\x60\x0B\x09\xF9\x41\x12\x3F\x58\x80\x5A\x3F\x10\xFF\x47\xB3\x10\x03\x10\x21\x01\x10\x03") buf.rewind state = :READY packet_buf = nil data_buf = nil crc_error = 0 packets = {} #count = 0 while !buf.eof? #$stderr.puts "#{state} => #{packet_buf.string.inspect rescue ''}" #exit if (count += 1) > 500 case state when :READY state = :FIRST_DLE if buf.getc == ?\x10 when :FIRST_DLE packet_buf = StringIO::new data_buf = StringIO::new packet_buf.putc(?\x10) c = buf.getc case c when ?\x10 state = :FIRST_DLE when ?\x03, ?\xFF state = :READY else packet_buf.putc(c) state = :ON_DATA end when :ON_DATA c = buf.getc packet_buf.putc(c) data_buf.putc(c) state = :ON_DATA_PREVIOUS_DLE if c == ?\x10 when :ON_DATA_PREVIOUS_DLE case buf.getc when ?\x10 packet_buf.putc(?\x10) state = :ON_DATA when ?\x03 #EXT state = :PACKET_END when ?\xFF #CS trailer = buf.read(4) if !trailer then break elsif trailer[2] == ?\x10 and trailer[3] == ?\x03 then if CRC16::crc16(packet_buf.string[1..-2]) == trailer[0..1].unpack('v').first then state = :PACKET_END else crc_error += 1 state = :READY end else buf.pos -= 4 state = :READY end else buf.pos -= 1 state = :FIRST_DLE end when :PACKET_END packet_buf.putc(?\x03) str = packet_buf.string dst.print str k = str.getbyte(1) packets[k] ||= [] packets[k] << data_buf.string[0..-2] # delete trailing ?\x10 state = :READY end end total_packets = crc_error packet_size_list = Hash[*packets.keys.collect{|k| data_size = {} packets[k].each{|packet| data_size[packet.size] ||= 0 data_size[packet.size] += 1 } total_packets += packets[k].size [sprintf("%02X", k), data_size] }.flatten] $stderr.puts packet_size_list.keys.sort{|a, b| a <=> b}.inspect $stderr.puts packet_size_list.inspect $stderr.puts "CRC Error: #{crc_error} / Total #{total_packets} => #{sprintf('%5.2f', crc_error * 100.0 / total_packets)}%" # check satellites satellites_states = {} packets[0x52].each{|packet| next unless packet.length % 7 == 0 (packet.length / 7).times{|i| index = i * 7 sat = ([nil, 'G', 'R', nil, 'S'][packet.getbyte(index)] + sprintf('%02d', packet.getbyte(index + 1))).to_sym index += 3; elv = packet.getbyte(index) index += 1; azm = packet[index..(index + 1)].unpack('v').first index += 2; sn = packet.getbyte(index) satellites_states[sat] ||= {:elv => [], :azm => [], :sn => []} satellites_states[sat][:elv] << elv satellites_states[sat][:azm] << azm satellites_states[sat][:sn] << sn } } Plotter::plot_basic('satellites.eps'){|plot| plot.set('size square') plot.set('angles degrees') plot.set('polar') plot.set('grid polar 90.') plot.unset('border') plot.unset('param') plot.set('trange [0:360]') plot.set('rrange [-90:0]') plot.set('xrange [-90:90]') plot.set('yrange [-90:90]') plot.set('xtics axis') plot.set('xtics scale 0') plot.set('xtics ("" -90, "" -60, "" -30, "" 0)') #plot.set('nottics') plot.set('rtics scale 0') plot.set('rtics ("" -90, "" -60, "" -30, "" 0)') plot.set('ytics axis') plot.set('ytics ("90" -90, "60" -60, "30" -30, "0" 0)') plot.set("label 'N' at 0, 100 center font ',18'") plot.set("label 'E' at 100, 0 center font ',18'") plot.set("label 'S' at 0, -100 center font ',18'") plot.set("label 'W' at -100, 0 center font ',18'") items = [] satellites_states.each{|sat, states| plot_data = [ states[:azm].collect{|v| -v + 90}, states[:elv].collect{|v| -v}].transpose.uniq.transpose items << Gnuplot::DataSet::new(plot_data){|ds| ds.with = "point ps 0.5" #"lines lw 2" # rgb var ds.notitle #ds.title = sat.to_s } } plot.data = items }