示例#1
0
文件: skypi.go 项目: skypies/pi
// readMsgFromSocket will pull basestation (and extended basestation)
// formatted messages from the socket, and send them down the channel.
// It will retry the connection on failure.
func readMsgFromSocket(wg *sync.WaitGroup, hostport string, msgChan chan<- *adsb.Msg) {
	nTimeMismatches := 0
	lastBackoff := time.Second

	wg.Add(1)

outerLoop:
	for {
		if weAreDone() {
			break
		} // outer

		conn, err := net.Dial("tcp", hostport)
		if err != nil {
			Log.Printf("connect '%s': err %s; trying again in %s ...", hostport, err, lastBackoff*2)
			time.Sleep(lastBackoff)
			if lastBackoff < time.Minute*5 {
				lastBackoff *= 2
			}
			continue
		}

		lastBackoff = time.Second
		Log.Printf("connected to '%s'", hostport)

		// a net.Conn implements io.Reader
		scanner := bufio.NewScanner(conn)
		for scanner.Scan() { // This can block indefinitely ...
			if weAreDone() {
				break outerLoop
			}

			if err := scanner.Err(); err != nil {
				Log.Printf("killing connection, scanner err: %v\n", err)
				conn.Close()
				break // inner
			}

			msg := adsb.Msg{}
			text := scanner.Text()
			if err := msg.FromSBS1(text); err != nil {
				Log.Printf("killing connection, SBS  input:%q, parse fail: %v", text, err)
				break // inner
			}

			// If there is significant clock skew, we should bail. But, it seems
			// that sometimes we pick up stale data from dump1090; so wait to see
			// if it passes.
			offset := time.Since(msg.GeneratedTimestampUTC)
			if offset > time.Minute*30 || offset < time.Minute*-30 {
				nTimeMismatches++
				if nTimeMismatches < 100 {
					continue // do not process this message
				} else {
					Log.Fatalf("100 bad msgs; set -timeloc ?\nNow = %s\nmsg = %s\n", time.Now(),
						msg.GeneratedTimestampUTC)
				}
			}

			// If the message is flagged as one we should mask, honor that
			if msg.IsMasked() {
				continue
			}

			msgChan <- &msg
		}
	}

	wg.Done()
	Log.Printf(" ---- readMsgFromSocket, clean shutdown\n")
}