listener_hub.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2017 Martin Hebnes Pedersen (LA5NTA). All rights reserved.
  2. // Use of this source code is governed by the MIT-license that can be
  3. // found in the LICENSE file.
  4. package main
  5. import (
  6. "log"
  7. "net"
  8. "sync"
  9. "time"
  10. )
  11. type TransportListener interface {
  12. Init() (net.Listener, error)
  13. Name() string
  14. CurrentFreq() (Frequency, bool)
  15. }
  16. type Beaconer interface {
  17. BeaconStop()
  18. BeaconStart() error
  19. }
  20. type Listener struct {
  21. t TransportListener
  22. hub *ListenerHub
  23. mu sync.Mutex
  24. isClosed bool
  25. err error
  26. ln net.Listener
  27. }
  28. func NewListener(t TransportListener) *Listener { return &Listener{t: t} }
  29. func (l *Listener) Err() error {
  30. l.mu.Lock()
  31. defer l.mu.Unlock()
  32. return l.err
  33. }
  34. func (l *Listener) Close() error {
  35. l.mu.Lock()
  36. defer l.mu.Unlock()
  37. if l.isClosed {
  38. return l.err
  39. }
  40. l.isClosed = true
  41. // If l.err is not nil, then the last attempt to open the listener failed and we don't have anything to close
  42. if l.err != nil {
  43. return l.err
  44. }
  45. return l.ln.Close()
  46. }
  47. func (l *Listener) listenLoop() {
  48. var silenceErr bool
  49. for {
  50. l.mu.Lock()
  51. if l.isClosed {
  52. l.mu.Unlock()
  53. break
  54. }
  55. // Try to init the TNC
  56. l.ln, l.err = l.t.Init()
  57. if l.err != nil {
  58. l.mu.Unlock()
  59. if !silenceErr {
  60. log.Printf("Listener %s failed: %s", l.t.Name(), l.err)
  61. log.Printf("Will try to re-establish listener in the background...")
  62. silenceErr = true
  63. websocketHub.UpdateStatus()
  64. }
  65. time.Sleep(time.Second)
  66. continue
  67. }
  68. l.mu.Unlock()
  69. if silenceErr {
  70. log.Printf("Listener %s re-established", l.t.Name())
  71. silenceErr = false
  72. websocketHub.UpdateStatus()
  73. }
  74. if b, ok := l.t.(Beaconer); ok {
  75. b.BeaconStart()
  76. }
  77. // Run the accept loop until an error occures
  78. if err := l.acceptLoop(); err != nil {
  79. log.Printf("Accept %s failed: %s", l.t.Name(), err)
  80. }
  81. if b, ok := l.t.(Beaconer); ok {
  82. b.BeaconStop()
  83. }
  84. }
  85. }
  86. type RemoteCaller interface {
  87. RemoteCall() string
  88. }
  89. func (l *Listener) acceptLoop() error {
  90. for {
  91. conn, err := l.ln.Accept()
  92. if err != nil {
  93. return err
  94. }
  95. remoteCall := conn.RemoteAddr().String()
  96. if c, ok := conn.(RemoteCaller); ok {
  97. remoteCall = c.RemoteCall()
  98. }
  99. freq, _ := l.t.CurrentFreq()
  100. eventLog.LogConn("accept", freq, conn, nil)
  101. log.Printf("Got connect (%s:%s)", l.t.Name(), remoteCall)
  102. err = exchange(conn, remoteCall, true)
  103. if err != nil {
  104. log.Printf("Exchange failed: %s", err)
  105. } else {
  106. log.Println("Disconnected.")
  107. }
  108. }
  109. }
  110. type ListenerHub struct {
  111. mu sync.Mutex
  112. listeners map[string]*Listener
  113. }
  114. func NewListenerHub() *ListenerHub {
  115. return &ListenerHub{
  116. listeners: map[string]*Listener{},
  117. }
  118. }
  119. func (h *ListenerHub) Active() []TransportListener {
  120. h.mu.Lock()
  121. defer h.mu.Unlock()
  122. slice := make([]TransportListener, 0, len(h.listeners))
  123. for _, l := range h.listeners {
  124. if l.Err() != nil {
  125. continue
  126. }
  127. slice = append(slice, l.t)
  128. }
  129. return slice
  130. }
  131. func (h *ListenerHub) Enable(t TransportListener) {
  132. h.mu.Lock()
  133. defer func() {
  134. h.mu.Unlock()
  135. websocketHub.UpdateStatus()
  136. }()
  137. l := NewListener(t)
  138. if _, ok := h.listeners[t.Name()]; ok {
  139. return
  140. }
  141. h.listeners[t.Name()] = l
  142. go l.listenLoop()
  143. }
  144. func (h *ListenerHub) Disable(name string) (bool, error) {
  145. h.mu.Lock()
  146. defer func() {
  147. h.mu.Unlock()
  148. websocketHub.UpdateStatus()
  149. }()
  150. l, ok := h.listeners[name]
  151. if !ok {
  152. return false, nil
  153. }
  154. delete(h.listeners, name)
  155. return true, l.Close()
  156. }
  157. func (h *ListenerHub) Close() {
  158. h.mu.Lock()
  159. defer func() {
  160. h.mu.Unlock()
  161. websocketHub.UpdateStatus()
  162. }()
  163. for k, l := range h.listeners {
  164. l.Close()
  165. delete(h.listeners, k)
  166. }
  167. }