blob: 246749aebe35e54535fdee9c838df41fba9a3357 (
plain) (
tree)
|
|
package org.openslx.taskmanager.tasks;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openslx.satserver.util.Util;
import org.openslx.taskmanager.api.AbstractTask;
import com.google.gson.annotations.Expose;
public class WakeOnLan extends AbstractTask
{
private static final Pattern RE_IPv4 =
Pattern.compile( "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$" );
private static final Pattern RE_MAC =
Pattern.compile( "^([0-9a-f]{2})[:-]([0-9a-f]{2}+)[:-]([0-9a-f]{2}+)[:-]([0-9a-f]{2}+)[:-]([0-9a-f]{2}+)[:-]([0-9a-f]{2}+)$",
Pattern.CASE_INSENSITIVE );
@Expose
private String[] macs;
@Expose
private String ip;
@Expose
private String password;
@Expose
private int port;
private StatusObject status;
private byte[] buffer;
@Override
protected boolean initTask()
{
status = new StatusObject();
this.setStatusObject( status );
if ( macs == null || macs.length == 0 ) {
status.addMsg( "Macs empty" );
}
if ( Util.isEmpty( ip ) ) {
status.addMsg( "IP empty" );
}
int pwlen = 0;
Matcher m = null;
if ( !Util.isEmpty( password ) ) {
m = RE_IPv4.matcher( password );
if ( m.matches() ) {
pwlen = 4;
} else {
m = RE_MAC.matcher( password );
if ( m.matches() ) {
pwlen = 6;
}
}
if ( pwlen == 0 ) {
status.addMsg( "Invalid password format: " + password );
}
}
if ( !Util.isEmpty( status.messages ) )
return false;
buffer = new byte[ 17 * 6 + pwlen ];
if ( pwlen != 0 ) {
try {
for ( int i = 0; i < pwlen; ++i ) {
int x = Integer.parseInt( m.group( i + 1 ), pwlen == 4 ? 10 : 16 );
buffer[17 * 6 + i] = (byte)x;
}
} catch ( Throwable t ) {
status.addMsg( "Invalid octet in password" );
return false;
}
}
if ( this.port == 0 ) {
this.port = 9;
} else if ( this.port > 65535 || this.port < 0 ) {
status.addMsg( "Invalid port: " + this.port );
return false;
}
return true;
}
@Override
protected boolean execute()
{
DatagramSocket sock = null;
try {
try {
sock = new DatagramSocket();
sock.setBroadcast( true );
} catch ( SocketException e ) {
status.addMsg( "Cannot create UDP socket" );
return false;
}
// Sync bytes
for ( int i = 0; i < 6; ++i ) {
buffer[i] = -1;
}
// Repeat three times
for ( int reps = 0; reps < 3; ++reps ) {
if ( reps != 0 ) {
try {
Thread.sleep( 600 );
} catch ( InterruptedException t ) {
Thread.currentThread().interrupt();
break;
}
}
// For each MAC
for ( int mi = 0; mi < macs.length; ++mi ) {
Matcher m = RE_MAC.matcher( macs[mi] );
if ( !m.matches() ) {
status.addMsg( "Cannot parse MAC address " + macs[mi] );
continue;
}
try {
for ( int i = 0; i < 6; ++i ) {
byte x = (byte)Integer.parseInt( m.group( i + 1 ), 16 );
for ( int offset = 0; offset < 16; ++offset ) {
buffer[6 + offset * 6 + i] = x;
}
}
} catch ( NumberFormatException e ) {
status.addMsg( "Invalid octet in MAC address: " + macs[mi] );
continue;
}
DatagramPacket dp = new DatagramPacket( buffer, buffer.length, InetAddress.getByName( ip ), this.port );
try {
sock.send( dp );
status.addMsg( "Sent packet to " + macs[mi] );
} catch ( IOException e ) {
status.addMsg( "Error sending UDP packet to " + ip + "/" + macs[mi] + ": " + e.toString() );
}
}
}
} catch ( UnknownHostException e ) {
status.addMsg( "Cannot resolve " + ip );
return false;
} finally {
Util.multiClose( sock );
}
return true;
}
class StatusObject
{
private String messages = "";
public void addMsg( String str )
{
messages = messages + "\n" + str;
}
}
}
|