-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConnenctor.kt
133 lines (104 loc) · 3.89 KB
/
Connenctor.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*******************************************
* Window blinds
* April, 2022
*
* Author: Piotr J. Węgrzyn
* Email: piotrwegrzyn@protonmail.com
*******************************************/
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
class Module(
var ipAddress: InetAddress,
var id: Short,
var phr: Byte,
var ser: Byte) {
override fun toString(): String {
return "Module IP: %s, ID: 0x%X, PHR: 0x%02X, SER: 0x%02X".format(this.ipAddress.toString(), this.id, this.phr, this.ser)
}
}
fun buildID(byte1: Byte, byte2: Byte): Short {
return ((byte1.toInt() shl 8 and 0xFF00) or (byte2.toInt() and 0xFF)).toShort()
}
fun receiveBroadcastModules(timeoutMilis: Int, socket: DatagramSocket): Map<InetAddress, Module> {
val startTime = System.currentTimeMillis()
val modules = mutableMapOf<InetAddress, Module>()
while (true) {
val packetBuffer = ByteArray(5) { 0.toByte() }
val packet = DatagramPacket(packetBuffer, packetBuffer.size)
socket.receive(packet)
packet.getAddress()?.apply {
if (!modules.containsKey(packet.getAddress())) {
modules[packet.getAddress()] = Module(packet.getAddress(), buildID(packetBuffer[1], packetBuffer[2]), packetBuffer[3], packetBuffer[4])
}
}
if (System.currentTimeMillis() > startTime + timeoutMilis) {
break
}
}
return modules
}
fun sendPacket(ipAddress: InetAddress, socket: DatagramSocket, port: Int, message: ByteArray) {
val packet = DatagramPacket(message, message.size, ipAddress, port)
socket.send(packet)
}
fun getRequest(module: Module, socket: DatagramSocket, port: Int, timeoutMilis: Int): Module {
val message = ByteArray(5) { 0.toByte() }
message[0] = 0x02
sendPacket(module.ipAddress, socket, port, message)
Thread.sleep(timeoutMilis.toLong())
val startTime = System.currentTimeMillis()
while (true) {
val remoteBuffer = ByteArray(5) { 0.toByte() }
val packet = DatagramPacket(remoteBuffer, remoteBuffer.size)
socket.receive(packet)
packet.getAddress()?.apply {
if (module.ipAddress == packet.getAddress() && remoteBuffer[0] == 0x10.toByte()) {
module.id = buildID(remoteBuffer[1], remoteBuffer[2])
module.phr = remoteBuffer[3]
module.ser = remoteBuffer[4]
return module
}
}
if (System.currentTimeMillis() > startTime + timeoutMilis) {
break
}
}
return module
}
fun setRequest(module: Module, socket: DatagramSocket, port: Int, newID: Short? = null, newSER: Byte? = null) {
val setArray = ByteArray(5, {0.toByte()})
setArray[0] = 0x01
if (newID != null ){
setArray[1] = (setArray[1].toInt() or 0x10).toByte()
setArray[2] = (newID.toInt() shr 8).toByte()
setArray[3] = (newID.toInt() and 0xFF).toByte()
}
if (newSER != null ){
setArray[1] = (setArray[1].toInt() or 0x1).toByte()
setArray[4] = newSER
}
sendPacket(module.ipAddress, socket, port, setArray)
}
fun main() {
val port = 4210
val timeout = 1000
val newID: Short = 0x1234.toShort()
val newSER: Byte = 0xAB.toByte()
val socket = DatagramSocket(port)
val modulesMap = receiveBroadcastModules(timeout, socket)
val sampleElement = modulesMap.keys.first()
modulesMap[sampleElement]?.apply {
var module = this
println("Broadcast:")
println(module)
module = getRequest(module, socket, port, 5 * timeout)
println("getRequest before setRequest")
println(module)
setRequest(module, socket, port, newID=newID, newSER=newSER)
module = getRequest(module, socket, port, 5 * timeout)
println("getRequest after setRequest")
println(module)
}
socket.close()
}