Created
September 4, 2022 00:54
-
-
Save pgaskin/ef2a4ca33b760db2972b90604e020d21 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.pgaskin.kl125gesture; | |
import org.json.JSONException; | |
import org.json.JSONObject; | |
import java.io.Closeable; | |
import java.io.DataInputStream; | |
import java.io.DataOutputStream; | |
import java.io.IOException; | |
import java.net.DatagramPacket; | |
import java.net.DatagramSocket; | |
import java.net.InetAddress; | |
import java.net.InetSocketAddress; | |
import java.net.Socket; | |
import java.net.SocketException; | |
import java.net.UnknownHostException; | |
import java.nio.charset.StandardCharsets; | |
public class SimpleLinkieClient implements Closeable { | |
private InetSocketAddress addr; | |
private final int timeout; | |
private final DatagramSocket udp; | |
public SimpleLinkieClient(String host) throws SocketException { | |
this(host, 1000); | |
} | |
public SimpleLinkieClient(String host, int timeout) throws SocketException { | |
this.addr = new InetSocketAddress(host, 9999); | |
this.timeout = timeout; | |
this.udp = new DatagramSocket(); | |
try { | |
this.udp.setTrafficClass(0x04 | 0x10); | |
} catch (Exception ex) { | |
// ignored | |
} | |
} | |
@Override | |
public void close() { | |
this.udp.close(); | |
} | |
public InetSocketAddress getAddr() throws UnknownHostException { | |
if (this.addr.isUnresolved()) { | |
InetAddress addr = InetAddress.getByName(this.addr.getHostString()); | |
this.addr = new InetSocketAddress(addr, 9999); | |
} | |
return this.addr; | |
} | |
public void send(JSONObject obj) throws IOException, UnknownHostException { | |
this.send(obj.toString()); | |
} | |
public void send(String req) throws IOException, UnknownHostException { | |
this.send(req.getBytes(StandardCharsets.UTF_8)); | |
} | |
private void send(byte[] req) throws IOException, UnknownHostException { | |
DatagramPacket pkt = new DatagramPacket(req, req.length, this.getAddr()); | |
this.encrypt(req); | |
this.udp.send(pkt); | |
} | |
public JSONObject sendChecked(JSONObject req) throws IOException, UnknownHostException, JSONException { | |
return this.sendChecked(req.toString()); | |
} | |
public JSONObject sendChecked(JSONObject req, int timeout) throws IOException, UnknownHostException, JSONException { | |
return this.sendChecked(req.toString(), timeout); | |
} | |
public JSONObject sendChecked(String req) throws IOException, UnknownHostException, JSONException { | |
return this.sendChecked(req.getBytes(StandardCharsets.UTF_8), this.timeout); | |
} | |
public JSONObject sendChecked(String req, int timeout) throws IOException, UnknownHostException, JSONException { | |
return this.sendChecked(req.getBytes(StandardCharsets.UTF_8), timeout); | |
} | |
private JSONObject sendChecked(byte[] req, int timeout) throws IOException, UnknownHostException, JSONException { | |
try (Socket tcp = new Socket()) { | |
tcp.connect(this.getAddr(), timeout); | |
try { | |
tcp.setTrafficClass(0x04 | 0x10); | |
} catch (Exception ex) { | |
// ignored | |
} | |
try { | |
tcp.setTcpNoDelay(true); | |
} catch (Exception ex) { | |
// ignored | |
} | |
DataOutputStream out = new DataOutputStream(tcp.getOutputStream()); | |
this.encrypt(req); | |
byte[] enc = new byte[req.length + 4]; | |
enc[0] = ((byte) ((req.length >> 24) & 0xFF)); | |
enc[1] = ((byte) ((req.length >> 16) & 0xFF)); | |
enc[2] = ((byte) ((req.length >> 8) & 0xFF)); | |
enc[3] = ((byte) (req.length & 0xFF)); | |
System.arraycopy(req, 0, enc, 4, req.length); | |
out.write(enc); | |
DataInputStream in = new DataInputStream(tcp.getInputStream()); | |
tcp.setSoTimeout(this.timeout); | |
byte[] lenb = new byte[4]; | |
in.readFully(lenb); | |
int len = lenb[3] | (lenb[2] << 8) | (lenb[1] << 16) | (lenb[0] << 24); | |
if (len < 0 || len > 16384) | |
throw new IOException("Invalid response length " + len); | |
byte[] buf = new byte[len]; | |
in.readFully(buf); | |
this.decrypt(buf); | |
return new JSONObject(new String(buf, StandardCharsets.UTF_8)); | |
} | |
} | |
private void encrypt(byte[] buf) { | |
byte key = (byte) 0xAB; | |
for (int i = 0; i < buf.length; i++) { | |
buf[i] = key = (byte) (buf[i] ^ key); | |
} | |
} | |
private void decrypt(byte[] buf) { | |
byte key = (byte) 0xAB; | |
for (int i = 0; i < buf.length; i++) { | |
byte x = buf[i]; | |
buf[i] = (byte)(x^key); | |
key = x; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment