// Converter for Ubees-Tracker package main import ( "bufio" "bytes" "encoding/binary" "flag" "fmt" "io" "log" "os" "regexp" "strconv" "time" ) type data struct { Time uint32 Msec uint16 Latitude int32 Longitude int32 Checksum uint16 } const bytesPerLine = 128 var inputFileName string var outputFileName string func init() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [OPTION] FILE\n", os.Args[0]) flag.PrintDefaults() } flag.StringVar(&outputFileName, "o", "", "Specify output file path. Default is FILE.out") flag.Parse() if flag.NArg() == 0 { flag.Usage() os.Exit(2) } inputFileName = flag.Arg(0) if outputFileName == "" { outputFileName = inputFileName + ".out" } } func main() { fileIn, err := os.Open(inputFileName) check(err) defer fileIn.Close() fileOut, err := os.OpenFile(outputFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) check(err) defer fileOut.Close() b := parse(fileIn) print(b, fileOut) } func check(err error) { if err != nil { log.Fatal(err) } } func parse(r io.Reader) *bytes.Buffer { b := bytes.NewBuffer(nil) rLine := regexp.MustCompile(`:.*\|`) rByte := regexp.MustCompile(`[0-9A-Fa-f]{2}`) br := bufio.NewReader(r) for { l, _, err := br.ReadLine() if err != nil { if err == io.EOF { return b } log.Fatal(err) } mLine := rLine.Find(l) if mLine == nil { log.Printf("Line not matched %#v", string(l)) continue } if bytes.HasPrefix(mLine, []byte(":FF")) { continue } mBytes := rByte.FindAll(mLine, -1) if len(mBytes) != bytesPerLine { log.Printf("Length not matched %v %#v\n", len(mBytes), string(l)) } for _, mByte := range mBytes { i, err := strconv.ParseUint(string(mByte), 16, 8) check(err) b.WriteByte(byte(i)) } } } func print(r io.Reader, w io.Writer) { bw := bufio.NewWriter(w) defer bw.Flush() var d data for { err := binary.Read(r, binary.LittleEndian, &d) if err != nil { if err == io.EOF { return } log.Fatal(err) } t := time.Unix(int64(d.Time), int64(d.Msec)*1e6) bw.WriteString(fmt.Sprintf("%v, %.4f, %.4f\n", t.Format("2006-01-02 15:04:05.000"), float64(d.Latitude)/10000, float64(d.Longitude)/10000)) } }