mirror of
https://github.com/Maschell/HIDtoVPADNetworkClient.git
synced 2024-11-22 05:59:16 +01:00
Updated the TCP Handshake to also negotiate a protocol version. +Formatting etc.
This commit is contained in:
parent
857c5d397d
commit
8197db4d86
@ -41,8 +41,6 @@ import lombok.Getter;
|
||||
import net.ash.HIDToVPADNetworkClient.manager.ControllerManager;
|
||||
import net.ash.HIDToVPADNetworkClient.network.NetworkManager;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Settings;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
|
||||
public final class GuiInputControls extends JPanel {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@ -133,7 +131,6 @@ public final class GuiInputControls extends JPanel {
|
||||
add(autoActivateWrap);
|
||||
add(Box.createVerticalGlue());
|
||||
|
||||
|
||||
add(Box.createVerticalGlue());
|
||||
|
||||
connectButton.addActionListener(new ActionListener() {
|
||||
|
@ -25,6 +25,7 @@ package net.ash.HIDToVPADNetworkClient.hid;
|
||||
public interface HidDevice {
|
||||
/**
|
||||
* Opens the HidDevice for usage.
|
||||
*
|
||||
* @return true on success, false when it failed.
|
||||
*/
|
||||
boolean open();
|
||||
@ -36,31 +37,35 @@ public interface HidDevice {
|
||||
|
||||
/**
|
||||
* Returns the VendorID of the HidDevice
|
||||
*
|
||||
* @return vendorID
|
||||
*/
|
||||
short getVendorId();
|
||||
|
||||
/**
|
||||
* Returns the ProductID of the HidDevice
|
||||
*
|
||||
* @return productID
|
||||
*/
|
||||
short getProductId();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the latest data.
|
||||
*
|
||||
* @return An byte array containing the latest data. If no data is present, it'll return a empty byte array
|
||||
*/
|
||||
byte[] getLatestData();
|
||||
|
||||
/**
|
||||
* Retuns the Usage of this HID-Device
|
||||
*
|
||||
* @return usage
|
||||
*/
|
||||
short getUsage();
|
||||
|
||||
/**
|
||||
* Returns the path of this HidDevice
|
||||
*
|
||||
* @return path
|
||||
*/
|
||||
String getPath();
|
||||
|
@ -43,6 +43,7 @@ public class HidManager {
|
||||
|
||||
for (HidDevice info : backend.enumerateDevices()) {
|
||||
if (isGamepad(info)) {
|
||||
|
||||
// Skip Xbox controller under windows. We should use XInput instead.
|
||||
if (isXboxController(info) && Settings.isWindows()) {
|
||||
continue;
|
||||
@ -61,17 +62,17 @@ public class HidManager {
|
||||
|
||||
private static boolean isPlaystationController(HidDevice info) {
|
||||
if (info == null) return false;
|
||||
return (info.getVendorId() == 0x054c);
|
||||
return (info.getVendorId() == (short) 0x054c);
|
||||
}
|
||||
|
||||
private static boolean isNintendoController(HidDevice info) {
|
||||
if (info == null) return false;
|
||||
return (info.getVendorId() == 0x57e);
|
||||
return (info.getVendorId() == (short) 0x57e);
|
||||
}
|
||||
|
||||
private static boolean isXboxController(HidDevice info) {
|
||||
if (info == null) return false;
|
||||
return (info.getVendorId() == 0x045e) && ((info.getProductId() == 0x02ff) || (info.getProductId() == 0x02a1));
|
||||
return (info.getVendorId() == (short) 0x045e) && ((info.getProductId() == (short) 0x02ff) || (info.getProductId() == (short) 0x02a1));
|
||||
}
|
||||
|
||||
static {
|
||||
@ -81,13 +82,13 @@ public class HidManager {
|
||||
backend = new PureJavaHidManagerBackend();
|
||||
} else if (Settings.isLinux()) {
|
||||
backend = new Hid4JavaHidManagerBackend();
|
||||
} else{
|
||||
} else {
|
||||
backend = null;
|
||||
}
|
||||
log.info("Plattform: " + System.getProperty("os.name"));
|
||||
if(backend != null){
|
||||
log.info("Backend: " + backend.getClass().getSimpleName());
|
||||
}else{
|
||||
if (backend != null) {
|
||||
log.info("Backend: " + backend.getClass().getSimpleName());
|
||||
} else {
|
||||
log.info("No Backend loaded =(");
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class Hid4JavaHidDevice implements HidDevice {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Hid4JavaHidDevice [myDevice=" + myDevice + ", data=" + Arrays.toString(data) + "]";
|
||||
return "Hid4JavaHidDevice [vid= " + getVendorId() + ", pid= " + getProductId() + ", data=" + Arrays.toString(data) + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -89,4 +89,10 @@ class PureJavaHidDevice implements HidDevice, InputReportListener {
|
||||
public String getPath() {
|
||||
return myDeviceInfo.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PureJavaHidDevice [vid= " + String.format("%04X", getVendorId()) + ", pid= " + String.format("%04X", getProductId()) + ", path= " + getPath()
|
||||
+ ", data=" + Arrays.toString(currentData) + "]";
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import lombok.Synchronized;
|
||||
import lombok.extern.java.Log;
|
||||
import net.ash.HIDToVPADNetworkClient.controller.Controller;
|
||||
import net.ash.HIDToVPADNetworkClient.manager.ActiveControllerManager;
|
||||
import net.ash.HIDToVPADNetworkClient.network.Protocol.HandshakeReturnCode;
|
||||
import net.ash.HIDToVPADNetworkClient.util.MessageBox;
|
||||
import net.ash.HIDToVPADNetworkClient.util.MessageBoxManager;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Settings;
|
||||
@ -163,7 +164,7 @@ public final class NetworkManager implements Runnable {
|
||||
try {
|
||||
pong = tcpClient.recvByte();
|
||||
if (pong == Protocol.TCP_CMD_PONG) {
|
||||
log.info("Ping...Pong!");
|
||||
if (Settings.DEBUG_TCP_PING_PONG) log.info("Ping...Pong!");
|
||||
} else {
|
||||
log.info("Got no valid response to a Ping. Disconnecting.");
|
||||
disconnect();
|
||||
@ -344,13 +345,18 @@ public final class NetworkManager implements Runnable {
|
||||
boolean result = false;
|
||||
log.info("Trying to connect to: " + ip);
|
||||
try {
|
||||
tcpClient.connect(ip);
|
||||
log.info("TCP Connected!");
|
||||
udpClient = UDPClient.createUDPClient(ip);
|
||||
if (udpClient != null) {
|
||||
result = true;
|
||||
HandshakeReturnCode tcpresult = tcpClient.connect(ip);
|
||||
if (tcpresult == HandshakeReturnCode.GOOD_HANDSHAKE) {
|
||||
log.info("TCP Connected!");
|
||||
udpClient = UDPClient.createUDPClient(ip);
|
||||
if (udpClient != null) {
|
||||
result = true;
|
||||
}
|
||||
} else {
|
||||
String error = "Error while connecting.";
|
||||
log.info(error);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (IOException e) {
|
||||
String error = "Error while connecting: " + e.getMessage();
|
||||
log.info(error);
|
||||
MessageBoxManager.addMessageBox(error, MessageBox.MESSAGE_WARNING);
|
||||
|
@ -28,13 +28,22 @@ import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.extern.java.Log;
|
||||
import net.ash.HIDToVPADNetworkClient.manager.ActiveControllerManager;
|
||||
import net.ash.HIDToVPADNetworkClient.util.MessageBox;
|
||||
import net.ash.HIDToVPADNetworkClient.util.MessageBoxManager;
|
||||
|
||||
@Log
|
||||
final class Protocol {
|
||||
private static ProtocolVersion currentProtocol = ProtocolVersion.MY_VERSION;
|
||||
static final int TCP_PORT = 8112;
|
||||
static final int UDP_PORT = 8113;
|
||||
|
||||
static final byte TCP_HANDSHAKE = 0x12;
|
||||
static final byte TCP_HANDSHAKE_VERSION_1 = 0x12;
|
||||
static final byte TCP_HANDSHAKE_VERSION_2 = 0x13;
|
||||
static final byte TCP_HANDSHAKE_ABORT = 0x30;
|
||||
|
||||
static final byte TCP_HANDSHAKE = TCP_HANDSHAKE_VERSION_2; // default version.
|
||||
|
||||
static final byte TCP_SAME_CLIENT = 0x20;
|
||||
static final byte TCP_NEW_CLIENT = 0x21;
|
||||
|
||||
@ -96,4 +105,85 @@ final class Protocol {
|
||||
return bos.toByteArray();
|
||||
}
|
||||
|
||||
public static HandshakeReturnCode doHandshake(TCPClient tcpClient) throws IOException {
|
||||
Protocol.currentProtocol = ProtocolVersion.MY_VERSION;
|
||||
HandshakeReturnCode resultHandshake = HandshakeReturnCode.BAD_HANDSHAKE;
|
||||
ProtocolVersion wiiuProtocolVersion = ProtocolVersion.getEnumByValue(tcpClient.recvByte());
|
||||
|
||||
/**
|
||||
* Handshake 1. At first the server (WiiU) sends his protocol version 2. The network clients answers with his preferred version (which needs to be
|
||||
* equals or lower the version the server (WiiU) sent him) or an abort command. 3a. If the client sent a abort, close the connection and wait for
|
||||
* another connection 3b. If the client sent his highest supported version, the server confirm that he is able to use this version (by sending the
|
||||
* version back) or sending a abort command to disconnect.
|
||||
**/
|
||||
|
||||
if (wiiuProtocolVersion == ProtocolVersion.UNKOWN) {
|
||||
log.info("Connected to a WiiU with an unsupported protocol version. It may support an older though");
|
||||
tcpClient.send(ProtocolVersion.MY_VERSION.getVersionByte());
|
||||
} else if (wiiuProtocolVersion == ProtocolVersion.Version1) {
|
||||
// Do nothing.
|
||||
} else if (wiiuProtocolVersion == ProtocolVersion.Version2) {
|
||||
// We want to do version 2!
|
||||
tcpClient.send(ProtocolVersion.Version2.getVersionByte());
|
||||
}
|
||||
|
||||
if (wiiuProtocolVersion == ProtocolVersion.Version1) {
|
||||
Protocol.currentProtocol = ProtocolVersion.Version1;
|
||||
resultHandshake = HandshakeReturnCode.GOOD_HANDSHAKE;
|
||||
} else {
|
||||
ProtocolVersion finalProtocolVersion = ProtocolVersion.getEnumByValue(tcpClient.recvByte());
|
||||
if (finalProtocolVersion == ProtocolVersion.Abort) {
|
||||
String message = "The HIDtoVPAD version is not supported. Try to use the newest version of HIDtoVPAD and this network client.";
|
||||
log.info(message);
|
||||
MessageBoxManager.addMessageBox(message, MessageBox.MESSAGE_ERROR);
|
||||
resultHandshake = HandshakeReturnCode.BAD_HANDSHAKE;
|
||||
} else if (finalProtocolVersion == ProtocolVersion.UNKOWN) {
|
||||
String message = "Something stranged happend while connecting. Try to use the newest version of HIDtoVPAD and this network client.";
|
||||
log.info(message);
|
||||
MessageBoxManager.addMessageBox(message, MessageBox.MESSAGE_ERROR);
|
||||
resultHandshake = HandshakeReturnCode.BAD_HANDSHAKE;
|
||||
} else {
|
||||
Protocol.currentProtocol = finalProtocolVersion;
|
||||
resultHandshake = HandshakeReturnCode.GOOD_HANDSHAKE;
|
||||
}
|
||||
}
|
||||
|
||||
if (resultHandshake == HandshakeReturnCode.GOOD_HANDSHAKE) {
|
||||
ActiveControllerManager.getInstance().attachAllActiveControllers();
|
||||
log.info("Handshake was successful! Using protocol version " + (currentProtocol.getVersionByte() - TCP_HANDSHAKE_VERSION_1 + 1));
|
||||
return resultHandshake;
|
||||
} else {
|
||||
log.info("[TCP] Handshaking failed");
|
||||
return resultHandshake;
|
||||
}
|
||||
// return false;
|
||||
}
|
||||
|
||||
public enum ProtocolVersion {
|
||||
MY_VERSION((byte) TCP_HANDSHAKE), Version1((byte) TCP_HANDSHAKE_VERSION_1), Version2((byte) TCP_HANDSHAKE_VERSION_2), Abort(
|
||||
(byte) TCP_HANDSHAKE_ABORT), UNKOWN((byte) 0x00);
|
||||
private final byte versionByte;
|
||||
|
||||
private ProtocolVersion(byte versionByte) {
|
||||
this.versionByte = versionByte;
|
||||
}
|
||||
|
||||
public static ProtocolVersion getEnumByValue(byte value) {
|
||||
switch (value) {
|
||||
case TCP_HANDSHAKE_VERSION_1:
|
||||
return ProtocolVersion.Version1;
|
||||
case TCP_HANDSHAKE_VERSION_2:
|
||||
return ProtocolVersion.Version2;
|
||||
case TCP_HANDSHAKE_ABORT:
|
||||
return ProtocolVersion.Abort;
|
||||
default:
|
||||
return ProtocolVersion.UNKOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public byte getVersionByte() {
|
||||
return versionByte;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.Synchronized;
|
||||
import lombok.extern.java.Log;
|
||||
import net.ash.HIDToVPADNetworkClient.manager.ActiveControllerManager;
|
||||
import net.ash.HIDToVPADNetworkClient.network.Protocol.HandshakeReturnCode;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Settings;
|
||||
|
||||
@ -53,23 +52,18 @@ final class TCPClient {
|
||||
}
|
||||
|
||||
@Synchronized("lock")
|
||||
void connect(String ip) throws Exception {
|
||||
HandshakeReturnCode connect(String ip) throws IOException {
|
||||
sock = new Socket();
|
||||
sock.connect(new InetSocketAddress(ip, Protocol.TCP_PORT), 2000);
|
||||
in = new DataInputStream(sock.getInputStream());
|
||||
out = new DataOutputStream(sock.getOutputStream());
|
||||
|
||||
HandshakeReturnCode resultHandshake = HandshakeReturnCode.GOOD_HANDSHAKE;
|
||||
if (recvByte() != Protocol.TCP_HANDSHAKE) resultHandshake = HandshakeReturnCode.BAD_HANDSHAKE;
|
||||
|
||||
if (resultHandshake == HandshakeReturnCode.GOOD_HANDSHAKE) {
|
||||
ActiveControllerManager.getInstance().attachAllActiveControllers();
|
||||
HandshakeReturnCode result = Protocol.doHandshake(this);
|
||||
if (result == HandshakeReturnCode.GOOD_HANDSHAKE) {
|
||||
this.ip = ip;
|
||||
shouldRetry = 0;
|
||||
} else {
|
||||
log.info("[TCP] Handshaking failed");
|
||||
throw new Exception();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Synchronized("lock")
|
||||
@ -112,6 +106,10 @@ final class TCPClient {
|
||||
send(ByteBuffer.allocate(4).putInt(value).array());
|
||||
}
|
||||
|
||||
public void send(byte _byte) throws IOException {
|
||||
send(ByteBuffer.allocate(1).put(_byte).array());
|
||||
}
|
||||
|
||||
@Synchronized("lock")
|
||||
byte recvByte() throws IOException {
|
||||
return in.readByte();
|
||||
|
@ -49,6 +49,7 @@ public final class Settings {
|
||||
public static boolean SCAN_AUTOMATICALLY_FOR_CONTROLLERS = true;
|
||||
|
||||
public static boolean DEBUG_UDP_OUTPUT = false;
|
||||
public static boolean DEBUG_TCP_PING_PONG = false;
|
||||
public static boolean SEND_DATA_ONLY_ON_CHANGE = false;
|
||||
public static boolean AUTO_ACTIVATE_CONTROLLER = false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user