1
+ import java.io.PrintWriter
2
+ import java.net.ServerSocket
3
+ import java.net.Socket
4
+ import java.text.SimpleDateFormat
5
+ import java.util.*
6
+
7
+ class SBSServer {
8
+
9
+ private val clients = mutableListOf<Socket >()
10
+
11
+ fun start () {
12
+ val serverSocket = ServerSocket (30003 )
13
+ Thread {
14
+ while (true ) {
15
+ val socket = serverSocket.accept()
16
+ clients.add(socket)
17
+ }
18
+ }.start()
19
+ }
20
+
21
+ fun sendData (data : ADSBData ) {
22
+ Thread {
23
+ val iterator = clients.iterator()
24
+ while (iterator.hasNext()) {
25
+ val socket = iterator.next()
26
+ try {
27
+ val outputStream = socket.getOutputStream()
28
+ val writer = PrintWriter (outputStream)
29
+ data.ac.forEachIndexed { id, ac ->
30
+ if (ac.alt_baro.toIntOrNull() != null ) {
31
+ writer.println (
32
+ createMessage(
33
+ " MSG" ,
34
+ 3 ,
35
+ 5 ,
36
+ 0 ,
37
+ ac.hex,
38
+ ac.flight,
39
+ ac.flight,
40
+ ac.getAltitude(),
41
+ ac.gs,
42
+ ac.track,
43
+ ac.lat,
44
+ ac.lon,
45
+ ac.squawk
46
+ )
47
+ )
48
+ writer.flush()
49
+ }
50
+ }
51
+ } catch (e: Exception ) {
52
+ // we don't care
53
+ }
54
+ }
55
+ }.start()
56
+ }
57
+
58
+ /* *
59
+ * DOCS: http://woodair.net/SBS/Article/Barebones42_Socket_Data.htm
60
+ * Example: MSG,3,5,211,4CA2D6,10057,2008/11/28,14:53:50.594,2008/11/28,14:58:51.153,,37000,,,51.45735,-1.02826,,,0,0,0,0
61
+ */
62
+ private fun createMessage (
63
+ messageType : String = "MSG ",
64
+ transmissionType : Int = 3,
65
+ sessionId : Int = 5,
66
+ aircraftId : Int = 0,
67
+ hex : String = "",
68
+ flightId : String = "",
69
+ callSign : String = "",
70
+ altitude : Int ,
71
+ groundSpeed : Double ,
72
+ track : Double ,
73
+ lat : Double ,
74
+ lon : Double ,
75
+ squawk : String
76
+ ): String {
77
+ val builder = StringBuilder ()
78
+ // The below basic data fields are standard for all messages (Field 2 used only for MSG)
79
+ builder.append(" $messageType ," )
80
+ builder.append(" $transmissionType ," )
81
+ builder.append(" $sessionId ," )
82
+ builder.append(" $aircraftId ," )
83
+ builder.append(" $hex ," )
84
+ builder.append(" $flightId ," )
85
+ builder.append(" ${getDate()} ," )
86
+ builder.append(" ${getTime()} ," )
87
+ builder.append(" ${getDate()} ," )
88
+ builder.append(" ${getTime()} ," )
89
+ // The fields below contain specific aircraft information
90
+ builder.append(" ${callSign} ," )
91
+ builder.append(" ${altitude} ," )
92
+ builder.append(" ${groundSpeed} ," )
93
+ builder.append(" ${track} ," )
94
+ builder.append(" ${formatCoordinate(lat)} ," )
95
+ builder.append(" ${formatCoordinate(lon)} ," )
96
+ builder.append(" ," ) // vertical rate
97
+ builder.append(" ${squawk} ," )
98
+ builder.append(" ," ) // alert
99
+ builder.append(" ," ) // emergency
100
+ builder.append(" ," ) // SPI
101
+ builder.append(" 0" ) // isOnGround
102
+
103
+ val message = builder.toString()
104
+ println (message)
105
+ return message
106
+ }
107
+
108
+ private fun getDate () = SimpleDateFormat (" yyyy/MM/dd" ).format(Calendar .getInstance().time)
109
+
110
+ private fun getTime () = SimpleDateFormat (" HH:mm:ss" ).format(Calendar .getInstance().time)
111
+
112
+ private fun formatCoordinate (coordinate : Double ): String {
113
+ return String .format(" %.5f" , coordinate)
114
+ }
115
+ }
0 commit comments