Wake on LAN MIDlet

Wake On LAN Mob is a J2ME application for mobile devices.

When I first posted Wake on LAN Java MIDlet on my website I received various e-mails asking me for some extra features, modifications and source code requests. I didn't expect so much interest at all so I decided to provide the source code.

Tested on Nokia 6630, Nokia N95 8GB, Nokia E65, HTC Touch, HTC TyTN II.
Screenshots: 1, 2, 3

Here is my simple implementation, enjoy!// © J@mBeL.net
import java.util.Vector;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;

public class WakeOnLan extends MIDlet implements CommandListener {

    private Display display;
    private Form mainScr;

    private Command OKCommand;
    private Command ClearCommand;
    private Command exitCommand;

    private static TextField tfIP;
    private static TextField tfMAC;

    private Alert alert;

    private static final int PORT = 9;

    public WakeOnLan() {
        display = Display.getDisplay(this);
        mainScr = new Form("WakeOnLan Mob");
        tfIP = new TextField("IP Address:\n", "", 16, 0);
        tfMAC = new TextField("MAC Address:\n", "", 17, 0);
        mainScr.append(tfIP);
        mainScr.append(tfMAC);
        mainScr.append("© 2007 jambel.net");
        OKCommand = new Command("Send", Command.OK, 1);
        ClearCommand = new Command("Clear", Command.ITEM, 1);
        exitCommand = new Command("Exit", Command.EXIT, 1);
        mainScr.addCommand(OKCommand);
        mainScr.addCommand(ClearCommand);
        mainScr.addCommand(exitCommand);
        mainScr.setCommandListener(this);
    }

    private class SendPacket implements Runnable {
        public void run(){
            SendStr(tfIP.getString(), tfMAC.getString());
        }

        private void SendStr(String ipStr, String macStr) {
            if(ipStr.length() == 0 || macStr.length() == 0) {
                alert = new Alert("Please fill IP and MAC address fields.");
                display.setCurrent(alert, mainScr);
                return;
            }
            else {
                try {
                    byte[] macBytes = getMacBytes();
                    byte[] bytes = new byte[6 + 16 * macBytes.length];
                    for (int i = 0; i < 6; i++) {
                        bytes[i] = (byte) 0xff;
                    }
                    for (int i = 6; i < bytes.length; i += macBytes.length) {
                        System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
                    }

                    String address = "datagram://" + ipStr + ":" + PORT;
                    DatagramConnection packet = (DatagramConnection)Connector.open(address);
                    Datagram dgram = packet.newDatagram(bytes, bytes.length, address);
                    packet.send(dgram);
                    packet.close();

                    alert = new Alert("Wake-on-LAN packet sent.");
                    display.setCurrent(alert, mainScr);
                }
                catch (Exception e) {
                    alert = new Alert("Failed to send Wake-on-LAN packet: " + e);
                    display.setCurrent(alert, mainScr);
                    return;
                    //System.exit(1);
                }
            }
        }
    }

    private byte[] getMacBytes() throws IllegalArgumentException {
        byte[] bytes = new byte[6];
        String sep;
            if(tfMAC.getString().indexOf(":") > 0)
                sep=":";
            else
                sep="-";
                String[] hex = split(tfMAC.getString(),sep);
            if (hex.length != 6) {
                throw new IllegalArgumentException("Invalid MAC address.");
            }
            try {
                for (int i = 0; i < 6; i++) {
                    bytes[i] = (byte) Integer.parseInt(hex[i], 16);
                }
            }
            catch (NumberFormatException e) {
                throw new IllegalArgumentException("Invalid hex digit in MAC address.");
            }
        return bytes;
    }

    private static String[] split(String original, String separator) {
        Vector nodes = new Vector();

        // Parse nodes into vector
        int index = original.indexOf(separator);
        while(index>=0) {
            nodes.addElement( original.substring(0, index) );
            original = original.substring(index+separator.length());
            index = original.indexOf(separator);
        }
        // Get the last node
        nodes.addElement( original );

        // Create splitted string array
        String[] result = new String[ nodes.size() ];
        if( nodes.size()>0 ) {
            for(int loop=0; loop < nodes.size(); loop++)
                result[loop] = (String)nodes.elementAt(loop);
            }
        return result;
    }

    public void commandAction(Command c, Displayable d) {
        if (c == OKCommand) {
            if (d == mainScr) {
                SendPacket doIt = new SendPacket();
                Thread myThread = new Thread( doIt );
                myThread.start();
            } else {
                display.setCurrent(mainScr);
            }
        } else if (c == ClearCommand) {
            tfIP.setString("");
            tfMAC.setString("");
        } else if (c == exitCommand) {
            destroyApp(false);
            notifyDestroyed();
        }
    }

    public void startApp() {
    Display.getDisplay(this).setCurrent(mainScr);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
}
You can download it here.

You can freely distribute it as you wish and if you like just add a reference on me.
Also you can e-mail me your modifications just to notify me.

0 comments: