From 334583ce44eb2dcda01ba528c5e1eb71d59f7382 Mon Sep 17 00:00:00 2001 From: Nonoo Date: Sun, 25 Oct 2020 10:53:46 +0100 Subject: [PATCH] Move pkt0 out of the control stream module --- controlstream.go | 43 +++++++++++++---------------- pkt0.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ streamcommon.go | 2 ++ 3 files changed, 92 insertions(+), 24 deletions(-) create mode 100644 pkt0.go diff --git a/controlstream.go b/controlstream.go index 506c582..75cb571 100644 --- a/controlstream.go +++ b/controlstream.go @@ -18,7 +18,6 @@ type controlStream struct { deinitNeededChan chan bool deinitFinishedChan chan bool - authSendSeq uint16 authInnerSendSeq uint16 authID [6]byte @@ -31,9 +30,12 @@ type controlStream struct { } func (s *controlStream) sendPktLogin() error { + s.common.pkt0.sendSeqLock() + defer s.common.pkt0.sendSeqUnlock() + // The reply to the auth packet will contain a 6 bytes long auth ID with the first 2 bytes set to our ID. authStartID := []byte{0x63, 0x00} - p := []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, byte(s.authSendSeq), byte(s.authSendSeq >> 8), + p := []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, byte(s.common.pkt0.sendSeq), byte(s.common.pkt0.sendSeq >> 8), byte(s.common.localSID >> 24), byte(s.common.localSID >> 16), byte(s.common.localSID >> 8), byte(s.common.localSID), byte(s.common.remoteSID >> 24), byte(s.common.remoteSID >> 16), byte(s.common.remoteSID >> 8), byte(s.common.remoteSID), 0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, byte(s.authInnerSendSeq), @@ -57,7 +59,7 @@ func (s *controlStream) sendPktLogin() error { return err } - s.authSendSeq++ + s.common.pkt0.sendSeq++ s.authInnerSendSeq++ return nil } @@ -79,7 +81,11 @@ func (s *controlStream) sendPktAuth(magic byte) error { // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - p := []byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, byte(s.authSendSeq), byte(s.authSendSeq >> 8), + + s.common.pkt0.sendSeqLock() + defer s.common.pkt0.sendSeqUnlock() + + p := []byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, byte(s.common.pkt0.sendSeq), byte(s.common.pkt0.sendSeq >> 8), byte(s.common.localSID >> 24), byte(s.common.localSID >> 16), byte(s.common.localSID >> 8), byte(s.common.localSID), byte(s.common.remoteSID >> 24), byte(s.common.remoteSID >> 16), byte(s.common.remoteSID >> 8), byte(s.common.remoteSID), 0x00, 0x00, 0x00, 0x30, 0x01, magic, 0x00, byte(s.authInnerSendSeq), @@ -94,25 +100,17 @@ func (s *controlStream) sendPktAuth(magic byte) error { if err := s.common.send(p); err != nil { return err } - s.authSendSeq++ + s.common.pkt0.sendSeq++ s.authInnerSendSeq++ return nil } -func (s *controlStream) sendPkt0() error { - p := []byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00, byte(s.authSendSeq), byte(s.authSendSeq >> 8), - byte(s.common.localSID >> 24), byte(s.common.localSID >> 16), byte(s.common.localSID >> 8), byte(s.common.localSID), - byte(s.common.remoteSID >> 24), byte(s.common.remoteSID >> 16), byte(s.common.remoteSID >> 8), byte(s.common.remoteSID)} - if err := s.common.send(p); err != nil { - return err - } - s.authSendSeq++ - return nil -} - func (s *controlStream) sendRequestSerialAndAudio() error { + s.common.pkt0.sendSeqLock() + defer s.common.pkt0.sendSeqUnlock() + log.Print("requesting serial and audio stream") - p := []byte{0x90, 0x00, 0x00, 0x00, 0x00, 0x00, byte(s.authSendSeq), byte(s.authSendSeq >> 8), + p := []byte{0x90, 0x00, 0x00, 0x00, 0x00, 0x00, byte(s.common.pkt0.sendSeq), byte(s.common.pkt0.sendSeq >> 8), byte(s.common.localSID >> 24), byte(s.common.localSID >> 16), byte(s.common.localSID >> 8), byte(s.common.localSID), byte(s.common.remoteSID >> 24), byte(s.common.remoteSID >> 16), byte(s.common.remoteSID >> 8), byte(s.common.remoteSID), 0x00, 0x00, 0x00, 0x80, 0x01, 0x03, 0x00, byte(s.authInnerSendSeq), @@ -138,7 +136,7 @@ func (s *controlStream) sendRequestSerialAndAudio() error { return err } - s.authSendSeq++ + s.common.pkt0.sendSeq++ s.authInnerSendSeq++ return nil @@ -241,8 +239,9 @@ func (s *controlStream) handleRead(r []byte) error { func (s *controlStream) loop() { startTime := time.Now() + s.common.pkt0.startPeriodicSend(&s.common) + s.secondAuthTimer = time.NewTimer(time.Second) - pkt0SendTicker := time.NewTicker(100 * time.Millisecond) reauthTicker := time.NewTicker(60 * time.Second) statusLogTicker := time.NewTicker(3 * time.Second) @@ -259,10 +258,6 @@ func (s *controlStream) loop() { reportError(err) } } - case <-pkt0SendTicker.C: - if err := s.sendPkt0(); err != nil { - reportError(err) - } case <-reauthTicker.C: log.Print("sending auth") if err := s.sendPktAuth(0x05); err != nil { @@ -299,7 +294,7 @@ func (s *controlStream) start() error { return err } - s.authSendSeq = 1 + s.common.pkt0.sendSeq = 1 if err := s.sendPktLogin(); err != nil { return err } diff --git a/pkt0.go b/pkt0.go new file mode 100644 index 0000000..099e2ab --- /dev/null +++ b/pkt0.go @@ -0,0 +1,71 @@ +package main + +import ( + "sync" + "time" +) + +type pkt0Type struct { + sendSeq uint16 + mutex sync.Mutex + + sendTicker *time.Ticker + + periodicStopNeededChan chan bool + periodicStopFinishedChan chan bool +} + +func (p *pkt0Type) sendSeqLock() { + p.mutex.Lock() +} + +func (p *pkt0Type) sendSeqUnlock() { + p.mutex.Unlock() +} + +func (p *pkt0Type) send(s *streamCommon) error { + p.sendSeqLock() + defer p.sendSeqUnlock() + + d := []byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00, byte(p.sendSeq), byte(p.sendSeq >> 8), + byte(s.localSID >> 24), byte(s.localSID >> 16), byte(s.localSID >> 8), byte(s.localSID), + byte(s.remoteSID >> 24), byte(s.remoteSID >> 16), byte(s.remoteSID >> 8), byte(s.remoteSID)} + if err := s.send(d); err != nil { + return err + } + p.sendSeq++ + return nil +} + +func (p *pkt0Type) loop(s *streamCommon) { + for { + select { + case <-p.sendTicker.C: + if err := p.send(s); err != nil { + reportError(err) + } + case <-p.periodicStopNeededChan: + p.periodicStopFinishedChan <- true + return + } + } +} + +func (p *pkt0Type) startPeriodicSend(s *streamCommon) { + p.sendTicker = time.NewTicker(100 * time.Millisecond) + + p.periodicStopNeededChan = make(chan bool) + p.periodicStopFinishedChan = make(chan bool) + go p.loop(s) +} + +func (p *pkt0Type) stopPeriodicSend() { + if p.sendTicker == nil { // Periodic send has not started? + return + } + + p.periodicStopNeededChan <- true + <-p.periodicStopFinishedChan + + p.sendTicker.Stop() +} diff --git a/streamcommon.go b/streamcommon.go index 6e0d9ba..ecbcbf6 100644 --- a/streamcommon.go +++ b/streamcommon.go @@ -23,6 +23,7 @@ type streamCommon struct { readerCloseNeededChan chan bool readerCloseFinishedChan chan bool + pkt0 pkt0Type pkt7 pkt7Type } @@ -170,6 +171,7 @@ func (s *streamCommon) init(name string, portNumber int) error { } func (s *streamCommon) deinit() { + s.pkt0.stopPeriodicSend() s.pkt7.stopPeriodicSend() if s.gotRemoteSID && s.conn != nil { _ = s.sendDisconnect()