/* * Copyright (C) 2008 Manish Pandya, [manish at meetamanish dot com] * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * */ package org.hooliguns.ninja.telnet; import java.net.InetAddress; import java.net.UnknownHostException; import java.text.ParseException; /** * A helper utility that parses command line arguments and provides answers to * questions about requested options at invocation. * * @author Manish Pandya (July 1 2008) * */ class CommandLineArgumentParser { /** * The default port at which the server is listening for commands */ private int commandPort = 3487; /** * The default port at which the server is listening for status requests */ private int statusPort = 3488; /** * Place holder for requested command socket IP address */ private InetAddress commandIPAddress = null; /** * Place holder for requested status socket IP address */ private InetAddress statusIPAddress = null; /** * Flag to indicate status server availability */ private boolean statusServerDisabled = false; /** * Flag to indicate if ramping is disabled */ private boolean rampingDisabled = false; /** * Indicates if usage help is requested on command line */ private boolean usageHelpRequested = false; /** * If the Ninja connected is modded using teensyninja firmware */ private boolean teensyNinjaModImplRequested = false; /** * The serial port at which the teensyninja modded Ninja is hooked */ private String teensyNinjaModSerialPort = null; /** * If the Ninja connected is modded using PhiPi's instructions and firmware */ private boolean phiPiModImplRequested = false; /** * The serial port at which the PhiPi modded Ninja is hooked */ private String phiPiModSerialPort = null; /** * Boolean flag that indicates wether to initiate comm port */ private boolean comPortDisabled = false; /** * A method that parses command line arguments and sets up the flags/ports/ips * * @param args * command line arguments * @throws ParseException * when requested arguments don't make sence */ void parse(String[] args) throws ParseException { for (int i = 0; i < args.length; i++) { if (args[i].equals("-p")) { i++; if (i == args.length) { throw new ParseException("missing port number after argument \"-p\"", i); } try { commandPort = Integer.parseInt(args[i]); } catch (NumberFormatException e) { throw new ParseException("\"" + args[i] + "\" is not a valid port number.", i); } if (commandPort < 0 || commandPort > 65534) { throw new ParseException("\"" + commandPort + "\" is not a valid port number.", i); } } else if (args[i].equals("-sp")) { i++; if (i == args.length) { throw new ParseException( "missing port number after argument \"-sp\"", i); } try { statusPort = Integer.parseInt(args[i]); } catch (NumberFormatException e) { throw new ParseException("\"" + args[i] + "\" is not a valid port number.", i); } if (statusPort < 0 || statusPort > 65534) { throw new ParseException("\"" + statusPort + "\" is not a valid port number.", i); } } else if (args[i].equals("-i")) { i++; if (i == args.length) { throw new ParseException("missing IP address after argument \"-i\"", i); } try { commandIPAddress = InetAddress.getByName(args[i]); } catch (UnknownHostException e) { throw new ParseException("\"" + args[i] + "\" is not a valid IP address.", i); } if (commandIPAddress == null) { throw new ParseException("\"" + commandIPAddress + "\" is not a valid IP address.", i); } } else if (args[i].equals("-si")) { i++; if (i == args.length) { throw new ParseException("missing IP address after argument \"-si\"", i); } try { statusIPAddress = InetAddress.getByName(args[i]); } catch (UnknownHostException e) { throw new ParseException("\"" + args[i] + "\" is not a valid IP address.", i); } if (statusIPAddress == null) { throw new ParseException("\"" + statusIPAddress + "\" is not a valid IP address.", i); } } else if (args[i].equals("-si")) { i++; if (i == args.length) { throw new ParseException("missing IP address after argument \"-si\"", i); } try { statusIPAddress = InetAddress.getByName(args[i]); } catch (UnknownHostException e) { throw new ParseException("\"" + args[i] + "\" is not a valid IP address.", i); } if (statusIPAddress == null) { throw new ParseException("\"" + statusIPAddress + "\" is not a valid IP address.", i); } } else if (args[i].equals("-nr")) { rampingDisabled = true; } else if (args[i].equals("-noCommPort")) { comPortDisabled = true; } else if (args[i].equals("-ns")) { statusServerDisabled = true; } else if (args[i].equals("-h")) { usageHelpRequested = true; } else if (args[i].equals("-PhiPi")) { if (teensyNinjaModImplRequested) { throw new ParseException( "can only run one implementation at a time, either \"-PhiPi\" or \"-TeensyNinja\"", i); } phiPiModImplRequested = true; i++; if (i == args.length) { throw new ParseException( "missing serial port name after argument \"-PhiPi\"", i); } phiPiModSerialPort = args[i]; } else if (args[i].equals("-TeensyNinja")) { if (phiPiModImplRequested) { throw new ParseException( "can only run one implementation at a time, either \"-PhiPi\" or \"-TeensyNinja\"", i); } teensyNinjaModImplRequested = true; i++; if (i == args.length) { throw new ParseException( "missing Parallel port name after argument \"-TeensyNinja\"", i); } teensyNinjaModSerialPort = args[i]; } else { throw new ParseException("Unknown command line argument : \"" + args[i] + "\"", i); } } if (commandIPAddress != null && statusIPAddress == null && !statusServerDisabled) { statusIPAddress = commandIPAddress; } if (statusIPAddress != null && statusIPAddress.equals(commandIPAddress) && commandPort == statusPort) { throw new IllegalArgumentException( "You must specify different values for command and status ports" + " if you intend to use same IP address for status as well as command."); } try { commandIPAddress = InetAddress.getByName("0.0.0.0"); } catch (UnknownHostException e) { // Should never happen!! e.printStackTrace(); } try { statusIPAddress = InetAddress.getByName("0.0.0.0"); } catch (UnknownHostException e) { // Should never happen!! e.printStackTrace(); } } /** * Method to return requested socket port for command socket * * @return requested command socket port */ int getCommandPort() { return commandPort; } /** * Method to return requested socket port for status socket * * @return requested status socket port */ int getStatusPort() { return statusPort; } /** * Method to return requested IP address for command socket * * @return requested IP address for command socket */ InetAddress getCommandIPAddress() { return commandIPAddress; } /** * Method to return requested IP address for status socket * * @return requested IP address for status socket */ InetAddress getStatusIPAddress() { return statusIPAddress; } /** * A method to check if status server is requested * * @return true if status server is not requested, false otherwise */ boolean isStatusServerDisabled() { return statusServerDisabled; } /** * A method to check if ramping is enabled * * @return true if ramping is enabled, false otherwise */ boolean isRampingDisabled() { return rampingDisabled; } /** * A method to check if the Ninja connected to the server is assumed to be * having PhiPi's modifications and firmware * * @return true if PhiPi mod is requested, false otherwise */ boolean isPhiPiModImplRequested() { return phiPiModImplRequested; } /** * A method to get the serial port on which PhiPi modded Ninja is connected * * @return configured serial port at the command line */ String getPhiPiModSerialPort() { return phiPiModSerialPort; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { return getServerInformaton(); } /** * A method to query server startup parameters * * @return String containing server startup parameters */ String getServerInformaton() { StringBuffer sb = new StringBuffer(); sb.append("Command server socket address : "); sb.append(commandIPAddress); sb.append(':'); sb.append(commandPort); sb.append("\n"); sb.append(" Status server socket address : "); sb.append(statusIPAddress); sb.append(':'); sb.append(statusPort); sb.append("\n"); sb.append(" Is status server disabled ? "); sb.append(statusServerDisabled); sb.append("\n"); sb.append(" Is ramping disabled ? "); sb.append(rampingDisabled); sb.append("\n"); return sb.toString(); } /** * A method to check if user requested usage information * * @return true if usage help is requested, false otherwise */ boolean isUsageHelpRequested() { return usageHelpRequested; } /** * A method to check if the Ninja connected to the server is assumed to be * having Manish's modifications * * @return true if PhiPi mod is requested, false otherwise */ boolean isTeensyNinjaModImplRequested() { return teensyNinjaModImplRequested; } /** * A method to get the serial port on which tinsyninja modded Ninja is connected * * @return configured serial port at the command line */ String getTeensyNinjaModSerialPort() { return teensyNinjaModSerialPort; } boolean isComPortDisabled() { return comPortDisabled; } /** * A method that prints usage information in the console. */ static void printUsage() { System.out.println(""); System.out.println(""); System.out.println("NinjaTelnetServer usage:"); System.out .println(" NinjaTelnetServer [-p ] [-i ] [-sp ] [-si ] [-nr] [-ns] [-PhiPi |-TeensyNinja ]"); System.out.println(""); System.out.println("where:"); System.out .println(" -p followed by a valid port number is the tcp port on which to listen to for commands"); System.out.println(" default: 3487"); System.out.println(""); System.out .println(" -i followed by a valid IP address to which the server binds for listening to commands"); System.out .println(" default: 0.0.0.0 i.e. binds to all ip addresses that are assigned to the machine"); System.out.println(""); System.out .println(" -sp followed by a valid port number is the tcp port on which to listen to for status requests"); System.out.println(" default: 3488"); System.out.println(""); System.out .println(" -si followed by a valid IP address to which the server binds for listening to commands"); System.out.println(" default: same as command server IPaddress"); System.out.println(""); System.out .println(" -nr stands for \"no ramping\"; if specified, disables velocity/dceleration"); System.out.println(""); System.out .println(" -ns stands for \"no status\"; if specified, no status server will be started"); System.out.println(""); System.out .println(" -PhiPi stands for \"Ninja with PhiPi mods via serial interface\"; if specified, will try to use serial port impl"); System.out.println(""); System.out .println(" -TeensyNinja stands for \"Ninja with teensyninja mods via serial interface\"; if specified, will try to use serial port impl"); System.out.println(""); System.out .println(" -noCommPort doesn't initiate any comm port; a very useful feature for development on a laptop without serial ports"); } }