mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-22 12:33:02 +00:00
93 lines
2.7 KiB
Java
93 lines
2.7 KiB
Java
package com.limelight.nvstream.wol;
|
|
|
|
import java.io.IOException;
|
|
import java.net.DatagramPacket;
|
|
import java.net.DatagramSocket;
|
|
import java.net.InetAddress;
|
|
import java.net.UnknownHostException;
|
|
import java.util.Scanner;
|
|
|
|
import com.limelight.LimeLog;
|
|
import com.limelight.nvstream.http.ComputerDetails;
|
|
|
|
public class WakeOnLanSender {
|
|
private static final int[] PORTS_TO_TRY = new int[] {
|
|
7, 9, // Standard WOL ports
|
|
47998, 47999, 48000 // Ports opened by GFE
|
|
};
|
|
|
|
public static void sendWolPacket(ComputerDetails computer) throws IOException {
|
|
DatagramSocket sock = new DatagramSocket(0);
|
|
byte[] payload = createWolPayload(computer);
|
|
IOException lastException = null;
|
|
boolean sentWolPacket = false;
|
|
|
|
try {
|
|
// Try all resolved remote and local addresses
|
|
for (String unresolvedAddress : new String[] {computer.localAddress, computer.remoteAddress}) {
|
|
try {
|
|
for (InetAddress resolvedAddress : InetAddress.getAllByName(unresolvedAddress)) {
|
|
// Try all the ports for each resolved address
|
|
for (int port : PORTS_TO_TRY) {
|
|
DatagramPacket dp = new DatagramPacket(payload, payload.length);
|
|
dp.setAddress(resolvedAddress);
|
|
dp.setPort(port);
|
|
sock.send(dp);
|
|
sentWolPacket = true;
|
|
}
|
|
}
|
|
} catch (IOException e) {
|
|
// We may have addresses that don't resolve on this subnet,
|
|
// but don't throw and exit the whole function if that happens.
|
|
// We'll throw it at the end if we didn't send a single packet.
|
|
e.printStackTrace();
|
|
lastException = e;
|
|
}
|
|
}
|
|
} finally {
|
|
sock.close();
|
|
}
|
|
|
|
// Propagate the DNS resolution exception if we didn't
|
|
// manage to get a single packet out to the host.
|
|
if (!sentWolPacket && lastException != null) {
|
|
throw lastException;
|
|
}
|
|
}
|
|
|
|
private static byte[] macStringToBytes(String macAddress) {
|
|
byte[] macBytes = new byte[6];
|
|
@SuppressWarnings("resource")
|
|
Scanner scan = new Scanner(macAddress).useDelimiter(":");
|
|
for (int i = 0; i < macBytes.length && scan.hasNext(); i++) {
|
|
try {
|
|
macBytes[i] = (byte) Integer.parseInt(scan.next(), 16);
|
|
} catch (NumberFormatException e) {
|
|
LimeLog.warning("Malformed MAC address: "+macAddress+" (index: "+i+")");
|
|
break;
|
|
}
|
|
}
|
|
scan.close();
|
|
return macBytes;
|
|
}
|
|
|
|
private static byte[] createWolPayload(ComputerDetails computer) {
|
|
byte[] payload = new byte[102];
|
|
byte[] macAddress = macStringToBytes(computer.macAddress);
|
|
int i;
|
|
|
|
// 6 bytes of FF
|
|
for (i = 0; i < 6; i++) {
|
|
payload[i] = (byte)0xFF;
|
|
}
|
|
|
|
// 16 repetitions of the MAC address
|
|
for (int j = 0; j < 16; j++) {
|
|
System.arraycopy(macAddress, 0, payload, i, macAddress.length);
|
|
i += macAddress.length;
|
|
}
|
|
|
|
return payload;
|
|
}
|
|
}
|