/* * Player Java Client 3 - PlayerClient.java * Copyright (C) 2002-2006 Radu Bogdan Rusu, Maxim Batalin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ * */ package javaclient3; import java.net.Socket; import java.net.SocketException; import java.io.DataInputStream; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.util.Date; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import javaclient3.structures.PlayerConstants; import javaclient3.structures.PlayerDevAddr; import javaclient3.structures.PlayerMsgHdr; import javaclient3.structures.player.PlayerDeviceDevlist; import javaclient3.structures.player.PlayerDeviceDriverInfo; import javaclient3.xdr.*; /** * The PlayerClient is the main Javaclient class. It contains methods for interacting with the * player device. The player device represents the server itself, and is used in configuring * the behavior of the server. There is only one such device (with index 0) and it is always * open. * @author Radu Bogdan Rusu, Maxim Batalin, Esben Ostergaard * @version * <ul> * <li>v3.0 - Player 3.0 supported * </ul> */ public class PlayerClient extends Thread implements PlayerConstants { public static final boolean isDebugging = (System.getProperty ("PlayerClient.debug") != null) ? true : false; // Logging support private Logger logger = Logger.getLogger (PlayerClient.class.getName ()); // private static final boolean stopOnEOFException = // (System.getProperty ("PlayerClient.stopOnEOFException") != null) ? false : true; // List of all available devices private PlayerDeviceDevlist pddlist; private boolean readyPDDList = false; // Driver information for a particular device private PlayerDeviceDriverInfo pddi; private boolean readyPDDI = false; // Used for creating PlayerDevice type objects on requestDeviceAccess () private PlayerDevice newpd; private boolean readyRequestDevice = false; // Used for lookupName () and lookupCode () private PlayerClientUtils pcu = new PlayerClientUtils (); protected Socket socket; protected BufferedOutputStream buffer; /** * The input stream for the socket connected to the player server. */ protected DataInputStream is; /** * The output stream for the socket connected to the player server. * It's buffered, so remember to flush()! */ protected DataOutputStream os; protected Vector<PlayerDevice> deviceList = new Vector<PlayerDevice>(); private boolean receivedAuthentication = false; private boolean readyPortNumber = false; XdrBufferEncodingStream xdrbuffEnc; private int portNumber; private long millis; private int nanos; // Timeout for packets // private long timeout = 100; private boolean isThreaded; private boolean isRunning; // current data mode private int datamode = PLAYER_DATAMODE_PUSH; /** * The PlayerClient constructor. Once called, it will create a socket with the Player server * running on host <b>servername</b> on port <b>portNumber</b>. * @param serverName url of the host running Player * @param portNumber the port number of the Player server */ public PlayerClient (String serverName, int portNumber) { try { // init isThreaded = false; isRunning = false; // initialize network connection socket = new Socket (serverName, portNumber); // open the proper streams (I/O) is = new DataInputStream (socket.getInputStream ()); buffer = new BufferedOutputStream (socket.getOutputStream (), 128); os = new DataOutputStream (new DataOutputStream (buffer)); String ident = ""; StringBuffer playerInfo = new StringBuffer (); // write the player version number (manual says it's 32 chars) for (int i = 0; i < PLAYER_IDENT_STRLEN; i++) ident += (char)is.readByte (); playerInfo.append ("\n" + ident.replace('\0', ' ').trim() + "\n"); // Read and print (on screen) all available devices requestDeviceList (); readAll (); if (isReadyPDDList()) { PlayerDeviceDevlist list = getPDDList (); playerInfo.append ("selected devices [" + serverName + ":" + portNumber + "]:" + "\n"); for (int i = 0; i < list.getDeviceCount (); i++) { // Decode the host // XdrBufferEncodingStream xdr = new XdrBufferEncodingStream (4); // xdr.beginEncoding (null, 0); // xdr.xdrEncodeInt (list.getDevList ()[i].getHost ()); // xdr.endEncoding (); // String host = xdr.getXdrData ()[3] + "." + xdr.getXdrData ()[2] + // "." + xdr.getXdrData ()[1] + "." + xdr.getXdrData ()[0]; // xdr.close (); // Print everything on screen playerInfo.append (" " + //host + ":" + + list.getDevList ()[i].getRobot () + ":" + pcu.lookupName (list.getDevList ()[i].getInterf ()) + ":" + list.getDevList ()[i].getIndex ()); PlayerDevAddr pda = list.getDevList ()[i]; // Request additional device information requestDriverInfo (pda); readAll (); if (isReadyPDDI ()) // Log the driver's name if possible playerInfo.append (" (" + getPDDI ().getDriverName() + ")\n"); else playerInfo.append ("\n"); } } // Send the Player information to the logger logger.log (Level.INFO, playerInfo.toString ()); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Error in PlayerClient init: " + e.toString (), e); } } /** * The PlayerClient "destructor". Once called, it will close all the open * streams/sockets with the Player server. */ public void close () { try { /* for (int i = 0; i < deviceList.size (); i++) { PlayerDevice pd = (PlayerDevice)deviceList.get (i); requestDeviceAccess (pd.getDeviceAddress ().getInterf (), pd.getDeviceAddress ().getIndex (), PLAYER_CLOSE_MODE); readAll (); } */ // close all sockets this.setNotThreaded (); os.close (); buffer.close (); is.close (); socket.close (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Error in PlayerClient stop: " + e.toString (), e); } } /** * Change the mode Javaclient runs to non-threaded. * NOTE: waits for thread to stop */ public void setNotThreaded() { if (!isThreaded) return; isThreaded = false; while (isRunning == true) // wait to exit run thread try { Thread.sleep (10); } catch (Exception e) { } } /** * Start a threaded copy of Javaclient. * @param millis number of miliseconds to sleep between calls * @param nanos number of nanoseconds to sleep between calls */ public void runThreaded (long millis, int nanos) { if (isThreaded) { logger.log (Level.WARNING, "[PlayerClient]: A second call for runThreaded, ignoring!"); return; } this.millis = millis; this.nanos = nanos; isThreaded = true; this.start (); } /** * Start the Javaclient thread. Ran automatically from runThreaded (). */ public void run () { isRunning = true; try { while (isThreaded) { if (this.datamode == PLAYER_DATAMODE_PULL) { this.requestData (); while (read () != PLAYER_MSGTYPE_SYNCH && isThreaded); } else // while (is.available () != 0) // while (read () != PLAYER_MSGTYPE_SYNCH && isThreaded); read (); if (millis < 0) Thread.yield (); else if (nanos <= 0) Thread.sleep (millis); else Thread.sleep (millis, nanos); } } catch (InterruptedException e) { throw new PlayerException (e); } // } catch (IOException e) { throw new PlayerException (e); } isRunning = false; // sync with setNotThreaded } /** * Return the Javaclient2 logger. * @return the Javaclient2 logger as a Logger object */ public Logger getLogger () { return this.logger; } /** * Sends a Player message header filled with the given values. * @param type type of message (DATA, CMD, REQ, RESP_ACK, SYNCH, RESP_NACK) * @param subtype subtype of message * @param size size of the payload to follow */ private void sendHeader (int type, int subtype, int size) { try { PlayerDevAddr devAddr = new PlayerDevAddr (); devAddr.setHost (0); devAddr.setRobot (0); devAddr.setInterf (PLAYER_PLAYER_CODE); devAddr.setIndex (0); Date d = new Date (); double timestamp = d.getTime () / 1000; XdrBufferEncodingStream xdr = new XdrBufferEncodingStream (PlayerMsgHdr.PLAYERXDR_MSGHDR_SIZE); xdr.beginEncoding (null, 0); /* see player.h / player_msghdr for additional explanations */ /* The "host" on which the device resides */ xdr.xdrEncodeInt (devAddr.getHost ()); /* The "robot" or device collection in which the device resides */ xdr.xdrEncodeInt (devAddr.getRobot ()); /* The interface provided by the device; must be one of PLAYER_*_CODE */ xdr.xdrEncodeShort (devAddr.getInterf ()); /* Which device of that interface */ xdr.xdrEncodeShort (devAddr.getIndex ()); /* Message type; must be one of PLAYER_MSGTYPE_* */ xdr.xdrEncodeByte ((byte)type); /* Message subtype; interface specific */ xdr.xdrEncodeByte ((byte)subtype); /* Time associated with message contents (seconds since epoch) */ xdr.xdrEncodeDouble (timestamp); /* For keeping track of associated messages. */ xdr.xdrEncodeInt (0); /* Size in bytes of the payload to follow */ xdr.xdrEncodeInt (size); xdr.endEncoding (); os.write (xdr.getXdrData (), 0, PlayerMsgHdr.PLAYERXDR_MSGHDR_SIZE); xdr.close (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Error sending header: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-encoding header: " + e.toString (), e); } } /** * Reads the Player message header from the network. */ private PlayerMsgHdr readHeader () { // Create two new empty structures to hold the header PlayerMsgHdr header = new PlayerMsgHdr (); PlayerDevAddr devaddr = new PlayerDevAddr (); try { byte[] buffer = new byte[PlayerMsgHdr.PLAYERXDR_MSGHDR_SIZE]; // Read the header from the network is.readFully (buffer, 0, PlayerMsgHdr.PLAYERXDR_MSGHDR_SIZE); // Begin decoding the XDR buffer XdrBufferDecodingStream xdr = new XdrBufferDecodingStream (buffer); xdr.beginDecoding (); // Decode the player_devaddr devaddr.setHost (xdr.xdrDecodeInt ()); devaddr.setRobot (xdr.xdrDecodeInt ()); devaddr.setInterf (xdr.xdrDecodeShort ()); devaddr.setIndex (xdr.xdrDecodeShort ()); header.setAddr (devaddr); // Decode the rest of the player_msghdr header.setType (xdr.xdrDecodeByte ()); header.setSubtype (xdr.xdrDecodeByte ()); header.setTimestamp (xdr.xdrDecodeDouble ()); header.setSeq (xdr.xdrDecodeInt ()); header.setSize (xdr.xdrDecodeInt ()); xdr.endDecoding (); xdr.close (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Error reading header: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-decoding header: " + e.toString (), e); } return header; } /** * Request/reply: Get the list of available devices. * <br><br> * It's useful for applications such as viewer programs and test suites * that tailor behave differently depending on which devices are * available. To request the list, send a null PLAYER_PLAYER_REQ_DEVLIST. */ public void requestDeviceList () { try { XdrBufferEncodingStream xdr = new XdrBufferEncodingStream (8); xdr.beginEncoding (null, 0); xdr.xdrEncodeInt (0); // devices_count xdr.xdrEncodeInt (0); // array count xdr.endEncoding (); int size = xdr.getXdrLength (); sendHeader ((int)PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_DEVLIST, size); os.write (xdr.getXdrData (), 0, size); os.flush (); xdr.close (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Couldn't request device list: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-encoding request DEVLIST: " + e.toString (), e); } } /** * Request/reply: Get the driver name for a particular device. * <br><br> * To get a name, send a PLAYER_PLAYER_REQ_DRIVERINFO request that * specifies the address of the desired device in the addr field. Set * driver_name_count to 0 and leave driver_name empty. The response will * contain the driver name. * @param device the device */ public void requestDriverInfo (PlayerDevAddr device) { try { // Encode the data into XDR format XdrBufferEncodingStream xdr = new XdrBufferEncodingStream (PlayerDevAddr.PLAYERXDR_DEVADDR_SIZE + 8); xdr.beginEncoding (null, 0); xdr.xdrEncodeInt (device.getHost ()); xdr.xdrEncodeInt (device.getRobot ()); xdr.xdrEncodeShort (device.getInterf ()); xdr.xdrEncodeShort (device.getIndex ()); xdr.xdrEncodeInt (0); // driver_name_count xdr.xdrEncodeInt (0); // array count xdr.endEncoding (); int size = xdr.getXdrLength (); sendHeader ((int)PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_DRIVERINFO, size); os.write (xdr.getXdrData (), 0, size); os.flush (); xdr.close (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Couldn't request device info: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-encoding request DRIVERINFO: " + e.toString (), e); } } /** * Request/reply: (un)subscribe to a device * <br><br> * This is the most important request! Before interacting with a device, * the client must request appropriate access. Valid access modes are: <br> * <ul> * <li>PLAYER_OPEN_MODE : subscribe to the device. You will receive * any data published by the device and you may send it commands * and/or requests. * </li> * <li>PLAYER_CLOSE_MODE : unsubscribe from the device. * </li> * <li>PLAYER_ERROR_MODE : the requested access was not granted (only * appears in responses) * </li> * </ul> * <br><br> * To request access, send a PLAYER_PLAYER_REQ_DEV request that specifies * the desired device address in the addr field and the desired access mode * in access. Set driver_name_count to 0 and leave driver_name empty. * <br> * The response will indicate the granted access in the access field and * the name of the underlying driver in the driver_name field. Note that * the granted access may not be the same as the requested access (e.g. if * initialization of the driver failed). * * @param code the interface code * @param index the index for the device * @param access the requested access * @return an object of PlayerDevice type */ private PlayerDevice requestDeviceAccess(int code, int index, int access) { Boolean deviceInList = false; PlayerDeviceDevlist list = getPDDList(); if (isDebugging) logger.log(Level.FINEST, "[PlayerClient][Debug]: Subscribing to " + pcu.lookupName((short) code) + ":" + index); // Check to make sure the device we would like to connect to exists for (int i = 0; i < list.getDeviceCount(); i++) { if ((list.getDevList()[i].getInterf() == code) && (list.getDevList()[i].getIndex() == index)) { deviceInList = true; break; } } if (!deviceInList) { throw new PlayerException("[PlayerClient] Requested device " + pcu.lookupName((short) code) + ":" + index + " is not in the device list."); } try { PlayerDevAddr devAddr = new PlayerDevAddr(); devAddr.setHost(0); devAddr.setRobot(0); devAddr.setInterf(code); devAddr.setIndex(index); // Encode the data into XDR format XdrBufferEncodingStream xdr = new XdrBufferEncodingStream( PlayerDevAddr.PLAYERXDR_DEVADDR_SIZE + 12); xdr.beginEncoding(null, 0); xdr.xdrEncodeInt(devAddr.getHost()); xdr.xdrEncodeInt(devAddr.getRobot()); xdr.xdrEncodeShort(devAddr.getInterf()); xdr.xdrEncodeShort(devAddr.getIndex()); xdr.xdrEncodeByte((byte) access); // requested access xdr.xdrEncodeInt(0); // driver_name_count xdr.xdrEncodeInt(0); // array count xdr.endEncoding(); int size = xdr.getXdrLength(); sendHeader((int) PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_DEV, size); os.write(xdr.getXdrData(), 0, size); os.flush(); xdr.close(); if (isThreaded) { logger.log(Level.FINEST, "requestDeviceAccess () called while" + " main thread is running!"); } else { int result; while ((result = read(code, index)) != PLAYER_MSGTYPE_RESP_ACK) { if (result == PLAYER_MSGTYPE_RESP_NACK) throw new PlayerException( "[PlayerClient] Negative acknowledgement received " + "for " + pcu.lookupName((short) code) + ":" + index); } } return getRequestedDevice(code, index); } catch (IOException e) { throw new PlayerException( "[PlayerClient]: Couldn't request device access: " + e.toString(), e); } catch (OncRpcException e) { throw new PlayerException( "[PlayerClient]: Error XDR-encoding request DEV: " + e.toString(), e); } } /** * Configuration request: Get data. * <br><br> * When the server is in a PLAYER_DATAMODE_PULL data delivery mode, * the client can request a single round of data by sending a * PLAYER_PLAYER_REQ_DATA request. */ public void requestData () { try { sendHeader ((int)PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_DATA, 0); os.flush (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Couldn't request data: " + e.toString (), e); } } /** * Configuration request: Change data delivery mode. * <br><br> * The Player server supports 2 data modes, PUSH and PULL. * To switch to a different mode send a request with the format given * below. The server's reply will be a zero-length acknowledgement. * @param mode the requested mode */ public void requestDataDeliveryMode (int mode) { this.datamode = mode; try { // Encode the data into XDR format XdrBufferEncodingStream xdr = new XdrBufferEncodingStream (4); xdr.beginEncoding (null, 0); xdr.xdrEncodeInt (mode); // the requested mode xdr.endEncoding (); int size = xdr.getXdrLength (); sendHeader ((int)PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_DATAMODE, size); os.write (xdr.getXdrData (), 0, size); os.flush (); xdr.close (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Couldn't request change of datamode: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-encoding request DATAMODE: " + e.toString (), e); } } /** * [NEEDS TESTING, OBSOLETE? - NOT IMPLEMENTED IN PLAYER2] * <br><br> * Configuration request: Authentication. * <br><br> * If server authentication has been enabled (by providing '-key <key>' * on the command-line; see Command line options); then each client must * authenticate itself before otherwise interacting with the server. To * authenticate, send a request with this format. * <br><br> * If the key matches the server's key then the client is authenticated, * the server will reply with a zero-length acknowledgement, and the * client can continue with other operations. If the key does not match, * or if the client attempts any other server interactions before * authenticating, then the connection will be closed immediately. It is * only necessary to authenticate each client once. * <br><br> * Note that this support for authentication is NOT a security mechanism. * The keys are always in plain text, both in memory and when transmitted * over the network; further, since the key is given on the command-line, * there is a very good chance that you can find it in plain text in the * process table (in Linux try 'ps -ax | grep player'). Thus you should not * use an important password as your key, nor should you rely on Player * authentication to prevent bad guys from driving your robots (use a * firewall instead). Rather, authentication was introduced into Player to * prevent accidentally connecting one's client program to someone else's * robot. This kind of accident occurs primarily when Stage is running in a * multi-user environment. In this case it is very likely that there is a * Player server listening on port 6665, and clients will generally connect * to that port by default, unless a specific option is given. * <br><br> * This mechanism was never really used, and may be removed. * @param key the authentication key */ public void requestAuthentication (byte[] key) { try { if (key.length > PLAYER_KEYLEN) throw new PlayerException ("[PlayerClient]: Supplied " + "authentication key is " + key.length + " but should be <= " + PLAYER_KEYLEN + " bytes"); // Encode the data into XDR format XdrBufferEncodingStream xdr = new XdrBufferEncodingStream (8); xdr.beginEncoding (null, 0); xdr.xdrEncodeInt (key.length); // length of key xdr.xdrEncodeByte ((byte)key.length); // length of key xdr.endEncoding (); int size = xdr.getXdrLength (); sendHeader ((int)PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_AUTH, size); os.write (xdr.getXdrData (), 0, size); xdr.close (); int leftOvers = 0; // Take care of the residual zero bytes if ((key.length % 4) != 0) leftOvers = 4 - (key.length % 4); byte[] buf = new byte[leftOvers]; os.write (key); os.write (buf, 0, leftOvers); os.flush (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Couldn't request authentication: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-encoding request AUTH: " + e.toString (), e); } } /** * [NEEDS TESTING, returns NACK - NOT FINISHED IN PLAYER2] * (warning : player interface discarding message of unsupported subtype 8) * <br><br> * Use nameservice to get the corresponding port for a robot name * (only with Stage). * @param name the robot name */ public void requestNameService (char[] name) { try { if (name.length > PLAYER_MAX_DRIVER_STRING_LEN) throw new PlayerException ("[PlayerClient]: Supplied " + "robot name " + name.length + " but should be <= " + PLAYER_MAX_DRIVER_STRING_LEN + " bytes"); // Encode the data into XDR format XdrBufferEncodingStream xdr = new XdrBufferEncodingStream (8); xdr.beginEncoding (null, 0); xdr.xdrEncodeInt (name.length); // length of name xdr.xdrEncodeByte ((byte)name.length); // length of name xdr.endEncoding (); int size = xdr.getXdrLength (); sendHeader ((int)PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_NAMESERVICE, size); os.write (xdr.getXdrData (), 0, size); xdr.close (); int leftOvers = 0; // Take care of the residual zero bytes if ((name.length % 4) != 0) leftOvers = 4 - (name.length % 4); byte[] buf = new byte[leftOvers]; os.write (new String (name).getBytes ()); os.write (buf, 0, leftOvers); os.flush (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Couldn't request name service: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-encoding request NAMESERVICE: " + e.toString (), e); } } /** * [NOT IMPLEMENTED IN PLAYER2 YET?] */ public void requestIdent () { try { sendHeader ((int)PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_IDENT, 0); os.flush (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Couldn't request ident: " + e.toString (), e); } } /** * Configuration request: Add client queue replace rule. * <br><br> * Allows the client to add a replace rule to their server queue. Replace * rules define which messages will be replaced when new data arrives. * If you are not updating frequently from the server then the use of * replace rules for data packets will stop any queue overflow messages. * <br><br> * Each field in the request corresponds to the equivalent field in the * message header (use -1 for a "don't care" value). * * @param interf interface to set replace rule for (-1 for wildcard) * @param index index to set replace rule for (-1 for wildcard) * @param type message type to set replace rule for (-1 for wildcard), * i.e. PLAYER_MSGTYPE_DATA * @param subtype message subtype to set replace rule for (-1 for wildcard) * @param replace should we replace these messages */ public void requestAddReplaceRule (int interf, int index, int type, int subtype, int replace) { try { // Encode the data into XDR format XdrBufferEncodingStream xdr = new XdrBufferEncodingStream (20); xdr.beginEncoding (null, 0); xdr.xdrEncodeInt (interf); xdr.xdrEncodeInt (index); xdr.xdrEncodeInt (type); xdr.xdrEncodeInt (subtype); xdr.xdrEncodeInt (replace); xdr.endEncoding (); int size = xdr.getXdrLength (); sendHeader ((int)PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_ADD_REPLACE_RULE, size); os.write (xdr.getXdrData (), 0, size); os.flush (); xdr.close (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Couldn't request ADD_REPLACE_RULE: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-encoding request ADD_REPLACE_RULE: " + e.toString (), e); } } /** * Returns an object of type PlayerDevice containing the requested device. * @param interf requested interface * @param index requested index * @return a PlayerDevice object containing the requested device */ private PlayerDevice getRequestedDevice (int interf, int index) { while (!readyRequestDevice); PlayerDevAddr pda = newpd.getDeviceAddress (); if ((pda.getInterf () == interf) && (pda.getIndex () == index)) return newpd; else return null; } /** * Read the Player server replies. * <br><br> * @return the message type code */ private short read () { return read (0, 0); } /** * Read the Player server replies. * <br><br> * @param interf the interface type * @param index the index number * @return the message type code */ private short read (int interf, int index) { PlayerMsgHdr header; byte[] buffer; XdrBufferDecodingStream xdr; try { // Read the Player header header = readHeader (); if (isDebugging) logger.log (Level.FINEST, "[PlayerClient][Debug] Type = " + pcu.lookupNameType (header.getType()) + "/" + header.getType() + " , with payload size = " + header.getSize() + " for " + header.getAddr ().getInterf () + ":" + header.getAddr ().getIndex ()); // verify the message type code - see "Message Formats" from the // Player manual switch (header.getType ()) { // Data message case PLAYER_MSGTYPE_DATA: { if (header.getAddr ().getInterf () == 0) break; if (header.getAddr ().getInterf () != PLAYER_PLAYER_CODE) readDataDevice (header); if (isDebugging) logger.log (Level.FINEST, "[PlayerClient][Debug]: Data for " + pcu.lookupName (header.getAddr ().getInterf ()) + ":" + header.getAddr ().getIndex ()); break; } // Command message - should never receive it case PLAYER_MSGTYPE_CMD: { if (isDebugging) logger.log (Level.FINEST, "[PlayerClient][Debug]: " + "Error! Client should never receive a CMD !"); break; } // Request message - should never receive it case PLAYER_MSGTYPE_REQ: { if (isDebugging) logger.log (Level.FINEST, "[PlayerClient][Debug]: " + "Error! Client should never receive a REQ !"); break; } // Acknowledgement response message case PLAYER_MSGTYPE_RESP_ACK: { if (header.getAddr().getInterf() != PLAYER_PLAYER_CODE) handleRequestsDevice (header); else // Handle acknowledgement response messages switch (header.getSubtype ()) { case 0: break; // get the list of available devices case PLAYER_PLAYER_REQ_DEVLIST: { pddlist = new PlayerDeviceDevlist (); // Temporary buffer for reading devices_count buffer = new byte[8]; // Read devices_count and array count (4+4) is.readFully (buffer, 0, 8); // Begin decoding the XDR buffer xdr = new XdrBufferDecodingStream (buffer); xdr.beginDecoding (); // The number of devices pddlist.setDeviceCount (xdr.xdrDecodeInt ()); xdr.endDecoding (); xdr.close (); PlayerDevAddr[] devAddrList = new PlayerDevAddr[pddlist.getDeviceCount ()]; // Read the list of available devices for (int i = 0; i < pddlist.getDeviceCount (); i++) { buffer = new byte[PlayerDevAddr.PLAYERXDR_DEVADDR_SIZE]; //while (is.available() == 0); is.readFully (buffer, 0, PlayerDevAddr.PLAYERXDR_DEVADDR_SIZE); devAddrList[i] = decodeDevAddr (buffer); } pddlist.setDevList (devAddrList); readyPDDList = true; break; } // get the driver name for a particular device. case PLAYER_PLAYER_REQ_DRIVERINFO: { pddi = new PlayerDeviceDriverInfo (); // Read the device identifier buffer = new byte[PlayerDevAddr.PLAYERXDR_DEVADDR_SIZE]; is.readFully (buffer, 0, PlayerDevAddr.PLAYERXDR_DEVADDR_SIZE); PlayerDevAddr devAddr = decodeDevAddr (buffer); pddi.setAddr (devAddr); // Temporary buffer for reading driver_name_count buffer = new byte[8]; // Read devices_count and array count (4+4) is.readFully (buffer, 0, 8); // Begin decoding the XDR buffer xdr = new XdrBufferDecodingStream (buffer); xdr.beginDecoding (); // Length of the driver name pddi.setDriverNameCount (xdr.xdrDecodeInt ()); xdr.endDecoding (); xdr.close (); // Read the driver name buffer = new byte[pddi.getDriverNameCount ()]; is.readFully (buffer, 0, (pddi.getDriverNameCount ())); pddi.setDriverName (new String (buffer)); // Take care of the residual zero bytes if ((pddi.getDriverNameCount () % 4) != 0) is.readFully (buffer, 0, 4 - (pddi.getDriverNameCount () % 4)); readyPDDI = true; break; } // (un)subscribe to device case PLAYER_PLAYER_REQ_DEV: { // Read the device identifier buffer = new byte[PlayerDevAddr.PLAYERXDR_DEVADDR_SIZE]; is.readFully (buffer, 0, PlayerDevAddr.PLAYERXDR_DEVADDR_SIZE); PlayerDevAddr devAddr = decodeDevAddr (buffer); // Read the granted access and driver name count buffer = new byte[12]; // Read access, driver_name_count, array_count is.readFully (buffer, 0, 12); // Begin decoding the XDR buffer xdr = new XdrBufferDecodingStream (buffer); xdr.beginDecoding (); // The number of devices byte access = xdr.xdrDecodeByte (); int driverNameCount = xdr.xdrDecodeInt (); xdr.endDecoding (); xdr.close (); // Read the driver name buffer = new byte[driverNameCount]; is.readFully (buffer, 0, driverNameCount); if (access == PLAYER_ERROR_MODE) throw new PlayerException ("[PlayerClient]: " + "Error subscribing to : " + pcu.lookupName (devAddr.getInterf ()) + ":" + devAddr.getIndex ()); if (isDebugging) logger.log (Level.FINEST, "[PlayerClient][Debug]: " + "Got response: " + pcu.lookupName (devAddr.getInterf ()) + ":" + devAddr.getIndex () + "(" + new String (buffer) + ")" + " size of payload: " + header.getSize ()); // Create an instance of the actual object interface PlayerDevice requestedpd = requestSatisfy (devAddr, access, new String (buffer)); newpd = requestedpd; // Take care of the residual zero bytes if ((driverNameCount % 4) != 0) is.readFully (buffer, 0, 4 - (driverNameCount % 4)); readyRequestDevice = true; break; } // request data case PLAYER_PLAYER_REQ_DATA: { break; } // change data delivery mode case PLAYER_PLAYER_REQ_DATAMODE: { break; } // authentication // [OBSOLETE?] case PLAYER_PLAYER_REQ_AUTH: { receivedAuthentication = true; break; } case PLAYER_PLAYER_REQ_NAMESERVICE: { // portNumber = is.readShort (); readyPortNumber = true; break; } // [NOTIMPLEMENTED?] case PLAYER_PLAYER_REQ_IDENT: { break; } case PLAYER_PLAYER_REQ_ADD_REPLACE_RULE: { if (isDebugging) logger.log (Level.FINEST, "[PlayerClient][Debug]: " + "PLAYER_PLAYER_REQ_ADD_REPLACE_RULE " + "was succesful!"); break; } default: { logger.log (Level.WARNING, "[PlayerClient]: " + "Unknown message subtype received in read ()"); } } break; } // Synchronization message case PLAYER_MSGTYPE_SYNCH: { if (isDebugging) logger.log (Level.FINEST, "[PlayerClient][Debug]: " + "Synchronization received"); break; } // Negative acknowledgement response message case PLAYER_MSGTYPE_RESP_NACK: { if (isDebugging) logger.log (Level.FINEST, "[PlayerClient][Debug]: " + "Negative acknowledgement received"); // deviceList[(int)device][(int)index].handleNARMessage (); break; } default: { if ((isDebugging) && (header.getType () != 0)) logger.log (Level.FINEST, "[PlayerClient][Debug]: " + "Unknown message type " + header.getType () + " received in read()"); break; } } } catch (EOFException e) { // if (stopOnEOFException) // System.exit (1); throw new PlayerException ("[PlayerClient]: java.io.EOFException : Is the Player server still running?"); } catch (SocketException e) { // if (stopOnEOFException) // System.exit (1); throw new PlayerException ("[PlayerClient]: java.Socket.EOFException : Is the Player server still running?"); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Read error: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-decoding data : " + e.toString (), e); } return header.getType (); } /** * XDR-Decode the PlayerDevAddr structure. * @param buffer an array of bytes containing raw read data * @return an object of type PlayerDevAddr containing the decoded structure */ private PlayerDevAddr decodeDevAddr (byte[] buffer) { PlayerDevAddr devAddr = new PlayerDevAddr (); try { XdrBufferDecodingStream xdr = new XdrBufferDecodingStream (buffer); xdr.beginDecoding (); devAddr.setHost (xdr.xdrDecodeInt ()); devAddr.setRobot (xdr.xdrDecodeInt ()); devAddr.setInterf (xdr.xdrDecodeShort ()); devAddr.setIndex (xdr.xdrDecodeShort ()); xdr.endDecoding (); xdr.close (); } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Error reading PlayerDevAddr data: " + e.toString (), e); } catch (OncRpcException e) { throw new PlayerException ("[PlayerClient]: Error XDR-decoding PlayerDevAddr data: " + e.toString (), e); } return devAddr; } /** * Read the Player server replies in non-threaded mode. */ public int readAll () { if (isThreaded) return 0; if (this.datamode == PLAYER_DATAMODE_PULL) { requestData (); while (read () != PLAYER_MSGTYPE_SYNCH); return PLAYER_MSGTYPE_SYNCH; } int type = 0; // try { /* long start = System.currentTimeMillis (); while (is.available () == 0) { if (System.currentTimeMillis () > (start + timeout)) break; } while (is.available () != 0) {*/ type = read (); // if (type == PLAYER_MSGTYPE_SYNCH) break; // } /* } catch (IOException e) { throw new PlayerException ("[PlayerClient]: Error reading data: " + e.toString (), e); }*/ return type; } /** * Calls the device's readData () method. * @param header Player header */ private void readDataDevice (PlayerMsgHdr header) { PlayerDevAddr devAddr = header.getAddr (); for (int i = 0; i < deviceList.size (); i++) { PlayerDevAddr currAddr = ((PlayerDevice)deviceList.get (i)).getDeviceAddress (); if ( currAddr.getHost () == devAddr.getHost () && currAddr.getIndex () == devAddr.getIndex () && currAddr.getInterf () == devAddr.getInterf () && currAddr.getRobot () == devAddr.getRobot () ) { ((PlayerDevice)deviceList.get (i)).readData (header); break; } } } /** * Calls the device's handleResponse () method in case of a REQ/REP. * @param header Player header */ private void handleRequestsDevice (PlayerMsgHdr header) { PlayerDevAddr devAddr = header.getAddr (); for (int i = 0; i < deviceList.size (); i++) { PlayerDevAddr currAddr = ((PlayerDevice)deviceList.get (i)).getDeviceAddress (); if ( currAddr.getHost () == devAddr.getHost () && currAddr.getIndex () == devAddr.getIndex () && currAddr.getInterf () == devAddr.getInterf () && currAddr.getRobot () == devAddr.getRobot () ) { ((PlayerDevice)deviceList.get (i)).handleResponse (header); break; } } } /** * Handle several Player replies. If PLAYER_MSGTYPE_RESP_ACK after a requestDeviceAccess (), * creates a newpd object of a PlayerDevice type. * @return the message type that Player replied with. */ private PlayerDevice requestSatisfy (PlayerDevAddr devAddr, byte access, String driverName) { // If unsubscribe, just return if (access == PLAYER_CLOSE_MODE) return null; PlayerDevice newpd = null; switch (devAddr.getInterf ()) { case PLAYER_NULL_CODE: { // /dev/null analogue break; } case PLAYER_PLAYER_CODE: { // the server itself break; } case PLAYER_POWER_CODE: { // power subsystem newpd = new PowerInterface (this); break; } case PLAYER_GRIPPER_CODE: { // gripper newpd = new GripperInterface (this); break; } case PLAYER_POSITION2D_CODE: { // device that moves newpd = new Position2DInterface (this); break; } case PLAYER_SONAR_CODE: { // fixed range-finder newpd = new SonarInterface (this); break; } case PLAYER_LASER_CODE: { // scanning range-finder newpd = new LaserInterface (this); break; } case PLAYER_BLOBFINDER_CODE: { // visual blobfinder newpd = new BlobfinderInterface (this); break; } case PLAYER_PTZ_CODE: { // pan-tilt-zoom unit newpd = new PtzInterface (this); break; } case PLAYER_FIDUCIAL_CODE: { // fiducial detector newpd = new FiducialInterface (this); break; } case PLAYER_SPEECH_CODE: { // speech I/O newpd = new SpeechInterface (this); break; } case PLAYER_GPS_CODE: { // GPS unit newpd = new GPSInterface (this); break; } case PLAYER_BUMPER_CODE: { // bumper array newpd = new BumperInterface (this); break; } case PLAYER_DIO_CODE: { // digital I/O newpd = new DIOInterface (this); break; } case PLAYER_AIO_CODE: { // analog I/O newpd = new AIOInterface (this); break; } case PLAYER_IR_CODE: { // IR array newpd = new IRInterface (this); break; } case PLAYER_WIFI_CODE: { // wifi card status newpd = new WiFiInterface (this); break; } case PLAYER_WAVEFORM_CODE: { // fetch raw waveforms newpd = new WaveformInterface (this); break; } case PLAYER_LOCALIZE_CODE: { // localization newpd = new LocalizeInterface (this); break; } case PLAYER_MCOM_CODE: { // multicoms newpd = new MComInterface (this); break; } case PLAYER_SOUND_CODE: { // sound file playback newpd = new SoundInterface (this); break; } case PLAYER_AUDIODSP_CODE: { // audio DSP I/O newpd = new AudioDSPInterface (this); break; } case PLAYER_AUDIOMIXER_CODE: { // audio I/O newpd = new AudioMixerInterface (this); break; } case PLAYER_POSITION3D_CODE: { // 3-D position newpd = new Position3DInterface (this); break; } case PLAYER_SIMULATION_CODE: { // simulators newpd = new SimulationInterface (this); break; } case PLAYER_SERVICE_ADV_CODE: { // LAN advertisement // Player support obsolete? break; } case PLAYER_BLINKENLIGHT_CODE: { // blinking lights newpd = new BlinkenlightInterface (this); break; } case PLAYER_CAMERA_CODE: { // camera device (gazebo) newpd = new CameraInterface (this); break; } case PLAYER_MAP_CODE: { // get a map newpd = new MapInterface (this); break; } case PLAYER_PLANNER_CODE: { // 2D motion planner newpd = new PlannerInterface (this); break; } case PLAYER_LOG_CODE: { // log R/W control newpd = new LogInterface (this); break; } case PLAYER_JOYSTICK_CODE: { // joystick newpd = new JoystickInterface (this); break; } case PLAYER_SPEECH_RECOGNITION_CODE: { // speech recognition I/O newpd = new SpeechRecognitionInterface (this); break; } case PLAYER_OPAQUE_CODE: { // plugin interface break; } case PLAYER_POSITION1D_CODE: { // 1-D position newpd = new Position1DInterface (this); break; } case PLAYER_ACTARRAY_CODE: { // actuator array interface newpd = new ActarrayInterface (this); break; } case PLAYER_LIMB_CODE: { // limb interface newpd = new LimbInterface (this); break; } case PLAYER_GRAPHICS2D_CODE: { // graphics2d interface newpd = new Graphics2DInterface (this); break; } case PLAYER_GRAPHICS3D_CODE: { // graphics3d interface newpd = new Graphics3DInterface (this); break; } case PLAYER_RFID_CODE: { // rfid interface newpd = new RFIDInterface (this); break; } case PLAYER_WSN_CODE: { // WSN interface newpd = new WSNInterface (this); break; } case PLAYER_HEALTH_CODE: { // health interface newpd = new HealthInterface (this); break; } case PLAYER_IMU_CODE: { // IMU interface newpd = new IMUInterface (this); break; } case PLAYER_POINTCLOUD3D_CODE: { // PointCloud3D interface newpd = new PointCloud3DInterface (this); break; } case PLAYER_RANGER_CODE: { // Ranger interface newpd = new RangerInterface (this); break; } default: { logger.log (Level.WARNING, "[PlayerClient]: " + "Unsupported device error! - " + devAddr.getInterf ()); newpd = null; break; } } if (newpd != null) { newpd.setDeviceAddress (devAddr); newpd.setDeviceAccess (access); newpd.setDeviceDriverName (driverName); // add the device to the list deviceList.add (newpd); } return newpd; } /* /** * Get the current read timeout in milliseconds. * @return the current read timeout in milliseconds / public long getReadTimeout () { return this.timeout; } /** * Set the read timeout in milliseconds. * @param newTimeout new timeout in milliseconds / public void setReadTimeout (long newTimeout) { this.timeout = newTimeout; }*/ /** * Check to see if the Player server replied with a * PLAYER_PLAYER_REQ_DEVLIST successfully. * @return true if the PLAYER_PLAYER_REQ_DEVLIST occured, false otherwise * @see #getPDDList() */ public boolean isReadyPDDList () { if (readyPDDList) { readyPDDList = false; return true; } return false; } /** * Check to see if the Player server replied with a * PLAYER_PLAYER_DRIVERINFO_REQ successfully. * @return true if the PLAYER_PLAYER_DRIVERINFO_REQ occured, false * otherwise * @see #getPDDI() */ public boolean isReadyPDDI () { if (readyPDDI) { readyPDDI = false; return true; } return false; } /** * Get the list of available devices after a * PLAYER_PLAYER_REQ_DEVLIST request. * @return an object of PlayerDeviceDevlist type * @see #isReadyPDDList() */ public PlayerDeviceDevlist getPDDList () { return pddlist; } /** * Get the driver name for a particular device after a * PLAYER_PLAYER_DRIVERINFO_REQ request. * @return an object of PlayerDeviceDriverInfo type * @see #isReadyPDDI() */ public PlayerDeviceDriverInfo getPDDI () { return pddi; } /** * Get the port number for the specified robot after a * PLAYER_PLAYER_NAMESERVICE_REQ request. * @return the port number the specified robot runs on * @see #requestNameService(char[]) * @see #isReadyPortNumber() */ public int getPortNumber () { return portNumber; } /** * Check to see if the client has authenticated successfully. * @return true if client has authenticated, false otherwise */ public boolean isAuthenticated () { if (receivedAuthentication) { receivedAuthentication = false; return true; } return false; } /** * Check to see if the port number has been identified. * @return true if the port is ready to be read, false otherwise * @see #getPortNumber() */ public boolean isReadyPortNumber () { if (readyPortNumber) { readyPortNumber = false; return true; } return false; } /** * Check to see if the Player server replied with a * PLAYER_PLAYER_REQ_DEV successfully. * @return true if the PLAYER_PLAYER_REQ_DEV occured, false * otherwise */ public boolean isReadyRequestDevice () { if (readyRequestDevice) { readyRequestDevice = false; return true; } return false; } /** * Request a Power device. * @param index the device index * @param access access mode * @return a Power device if successful, null otherwise */ public PowerInterface requestInterfacePower (int index, int access) { return (PowerInterface) requestInterface (PLAYER_POWER_CODE, index, access); } /** * Request a Gripper device. * @param index the device index * @param access access mode * @return a Gripper device if successful, null otherwise */ public GripperInterface requestInterfaceGripper (int index, int access) { return (GripperInterface) requestInterface (PLAYER_GRIPPER_CODE, index, access); } /** * Request a Position2D device. * @param index the device index * @param access access mode * @return a Position2D device if successful, null otherwise */ public Position2DInterface requestInterfacePosition2D (int index, int access) { return (Position2DInterface) requestInterface (PLAYER_POSITION2D_CODE, index, access); } /** * Request a Sonar device. * @param index the device index * @param access access mode * @return a Sonar device if successful, null otherwise */ public SonarInterface requestInterfaceSonar (int index, int access) { return (SonarInterface) requestInterface (PLAYER_SONAR_CODE, index, access); } /** * Request a Laser device. * @param index the device index * @param access access mode * @return a Laser device if successful, null otherwise */ public LaserInterface requestInterfaceLaser (int index, int access) { return (LaserInterface) requestInterface (PLAYER_LASER_CODE, index, access); } /** * Request a Blobfinder device. * @param index the device index * @param access access mode * @return a Blobfinder device if successful, null otherwise */ public BlobfinderInterface requestInterfaceBlobfinder (int index, int access) { return (BlobfinderInterface) requestInterface (PLAYER_BLOBFINDER_CODE, index, access); } /** * Request a Ptz device. * @param index the device index * @param access access mode * @return a Ptz device if successful, null otherwise */ public PtzInterface requestInterfacePtz (int index, int access) { return (PtzInterface) requestInterface (PLAYER_PTZ_CODE, index, access); } /** * Request a Fiducial device. * @param index the device index * @param access access mode * @return a Fiducial device if successful, null otherwise */ public FiducialInterface requestInterfaceFiducial (int index, int access) { return (FiducialInterface) requestInterface (PLAYER_FIDUCIAL_CODE, index, access); } /** * Request a Speech device. * @param index the device index * @param access access mode * @return a Speech device if successful, null otherwise */ public SpeechInterface requestInterfaceSpeech (int index, int access) { return (SpeechInterface) requestInterface (PLAYER_SPEECH_CODE, index, access); } /** * Request a GPS device. * @param index the device index * @param access access mode * @return a GPS device if successful, null otherwise */ public GPSInterface requestInterfaceGPS (int index, int access) { return (GPSInterface)requestInterface (PLAYER_GPS_CODE, index, access); } /** * Request a Bumper device. * @param index the device index * @param access access mode * @return a Bumper device if successful, null otherwise */ public BumperInterface requestInterfaceBumper (int index, int access) { return (BumperInterface) requestInterface (PLAYER_BUMPER_CODE, index, access); } /** * Request a DIO device. * @param index the device index * @param access access mode * @return a DIO device if successful, null otherwise */ public DIOInterface requestInterfaceDIO (int index, int access) { return (DIOInterface)requestInterface (PLAYER_DIO_CODE, index, access); } /** * Request an AIO device. * @param index the device index * @param access access mode * @return an AIO device if successful, null otherwise */ public AIOInterface requestInterfaceAIO (int index, int access) { return (AIOInterface)requestInterface (PLAYER_AIO_CODE, index, access); } /** * Request an IR device. * @param index the device index * @param access access mode * @return an IR device if successful, null otherwise */ public IRInterface requestInterfaceIR (int index, int access) { return (IRInterface)requestInterface (PLAYER_IR_CODE, index, access); } /** * Request a WiFi device. * @param index the device index * @param access access mode * @return a WiFi device if successful, null otherwise */ public WiFiInterface requestInterfaceWiFi (int index, int access) { return (WiFiInterface)requestInterface (PLAYER_WIFI_CODE, index, access); } /** * Request a Waveform device. * @param index the device index * @param access access mode * @return a Waveform device if successful, null otherwise */ public WaveformInterface requestInterfaceWaveform (int index, int access) { return (WaveformInterface) requestInterface (PLAYER_WAVEFORM_CODE, index, access); } /** * Request a Localize device. * @param index the device index * @param access access mode * @return a Localize device if successful, null otherwise */ public LocalizeInterface requestInterfaceLocalize (int index, int access) { return (LocalizeInterface) requestInterface (PLAYER_LOCALIZE_CODE, index, access); } /** * Request a MComm device. * @param index the device index * @param access access mode * @return a MComm device if successful, null otherwise */ public MComInterface requestInterfaceMCom (int index, int access) { return (MComInterface) requestInterface (PLAYER_MCOM_CODE, index, access); } /** * Request a Sound device. * @param index the device index * @param access access mode * @return a Sound device if successful, null otherwise */ public SoundInterface requestInterfaceSound (int index, int access) { return (SoundInterface) requestInterface (PLAYER_SOUND_CODE, index, access); } /** * Request an AudioDSP device. * @param index the device index * @param access access mode * @return an AudioDSP device if successful, null otherwise */ public AudioDSPInterface requestInterfaceAudioDSP (int index, int access) { return (AudioDSPInterface) requestInterface (PLAYER_AUDIODSP_CODE, index, access); } /** * Request an AudioMixer device. * @param index the device index * @param access access mode * @return an AudioMixer device if successful, null otherwise */ public AudioMixerInterface requestInterfaceAudioMixer (int index, int access) { return (AudioMixerInterface) requestInterface (PLAYER_AUDIOMIXER_CODE, index, access); } /** * Request a Position3D device. * @param index the device index * @param access access mode * @return a Position3D device if successful, null otherwise */ public Position3DInterface requestInterfacePosition3D (int index, int access) { return (Position3DInterface) requestInterface (PLAYER_POSITION3D_CODE, index, access); } /** * Request a Simulation device. * @param index the device index * @param access access mode * @return a Simulation device if successful, null otherwise */ public SimulationInterface requestInterfaceSimulation (int index, int access) { return (SimulationInterface) requestInterface (PLAYER_SIMULATION_CODE, index, access); } /** * Request a Blinkenlight device. * @param index the device index * @param access access mode * @return a Blinkenlight device if successful, null otherwise */ public BlinkenlightInterface requestInterfaceBlinkenlight (int index, int access) { return (BlinkenlightInterface) requestInterface (PLAYER_BLINKENLIGHT_CODE, index, access); } /** * Request a Camera device. * @param index the device index * @param access access mode * @return a Camera device if successful, null otherwise */ public CameraInterface requestInterfaceCamera (int index, int access) { return (CameraInterface) requestInterface (PLAYER_CAMERA_CODE, index, access); } /** * Request a Map device. * @param index the device index * @param access access mode * @return a Map device if successful, null otherwise */ public MapInterface requestInterfaceMap (int index, int access) { return (MapInterface)requestInterface (PLAYER_MAP_CODE, index, access); } /** * Request a Planner device. * @param index the device index * @param access access mode * @return a Planner device if successful, null otherwise */ public PlannerInterface requestInterfacePlanner (int index, int access) { return (PlannerInterface) requestInterface (PLAYER_PLANNER_CODE, index, access); } /** * Request a Log device. * @param index the device index * @param access access mode * @return a Log device if successful, null otherwise */ public LogInterface requestInterfaceLog (int index, int access) { return (LogInterface)requestInterface (PLAYER_LOG_CODE, index, access); } /** * Request a Joystick device. * @param index the device index * @param access access mode * @return a Joystick device if successful, null otherwise */ public JoystickInterface requestInterfaceJoystick (int index, int access) { return (JoystickInterface)requestInterface (PLAYER_JOYSTICK_CODE, index, access); } /** * Request a Speech Recognition device. * @param index the device index * @param access access mode * @return a Speech Recognition device if successful, null otherwise */ public SpeechRecognitionInterface requestInterfaceSpeechRecognition (int index, int access) { return (SpeechRecognitionInterface) requestInterface (PLAYER_SPEECH_RECOGNITION_CODE, index, access); } /** * Request an Opaque device. * @param index the device index * @param access access mode * @return an Opaque device if successful, null otherwise */ public OpaqueInterface requestInterfaceOpaque (int index, int access) { return (OpaqueInterface) requestInterface (PLAYER_OPAQUE_CODE, index, access); } /** * Request a Position1D device. * @param index the device index * @param access access mode * @return a Position1D device if successful, null otherwise */ public Position1DInterface requestInterfacePosition1D (int index, int access) { return (Position1DInterface) requestInterface (PLAYER_POSITION1D_CODE, index, access); } /** * Request an Actarray device. * @param index the device index * @param access access mode * @return an Actarray device if successful, null otherwise */ public ActarrayInterface requestInterfaceActarray (int index, int access) { return (ActarrayInterface) requestInterface (PLAYER_ACTARRAY_CODE, index, access); } /** * Request a Limb device. * @param index the device index * @param access access mode * @return a Limb device if successful, null otherwise */ public LimbInterface requestInterfaceLimb (int index, int access) { return (LimbInterface)requestInterface (PLAYER_LIMB_CODE, index, access); } /** * Request a Graphics2D device. * @param index the device index * @param access access mode * @return a Graphics2D device if successful, null otherwise */ public Graphics2DInterface requestInterfaceGraphics2D (int index, int access) { return (Graphics2DInterface) requestInterface (PLAYER_GRAPHICS2D_CODE, index, access); } /** * Request a Graphics3D device. * @param index the device index * @param access access mode * @return a Graphics3D device if successful, null otherwise */ public Graphics3DInterface requestInterfaceGraphics3D (int index, int access) { return (Graphics3DInterface) requestInterface (PLAYER_GRAPHICS3D_CODE, index, access); } /** * Request a RFID device. * @param index the device index * @param access access mode * @return a RFID device if successful, null otherwise */ public RFIDInterface requestInterfaceRFID (int index, int access) { return (RFIDInterface)requestInterface (PLAYER_RFID_CODE, index, access); } /** * Request a WSN device. * @param index the device index * @param access access mode * @return a WSN device if successful, null otherwise */ public WSNInterface requestInterfaceWSN (int index, int access) { return (WSNInterface)requestInterface (PLAYER_WSN_CODE, index, access); } /** * Request a Health device. * @param index the device index * @param access access mode * @return a Health device if successful, null otherwise */ public HealthInterface requestInterfaceHealth (int index, int access) { return (HealthInterface)requestInterface (PLAYER_HEALTH_CODE, index, access); } /** * Request a IMU device. * @param index the device index * @param access access mode * @return a IMU device if successful, null otherwise */ public IMUInterface requestInterfaceIMU (int index, int access) { return (IMUInterface)requestInterface (PLAYER_IMU_CODE, index, access); } /** * Request a PointCloud3D device. * @param index the device index * @param access access mode * @return a PointCloud3D device if successful, null otherwise */ public PointCloud3DInterface requestInterfacePointCloud3D (int index, int access) { return (PointCloud3DInterface)requestInterface (PLAYER_POINTCLOUD3D_CODE, index, access); } /** * Request a Ranger device. * @param index the device index * @param access access mode * @return a Ranger device if successful, null otherwise */ public RangerInterface requestInterfaceRanger (int index, int access) { return (RangerInterface) requestInterface (PLAYER_RANGER_CODE, index, access); } /** * Request a generic device. Don't forget to cast the result to the * appropriate interface type. * @param type the interface type * @param index the device index * @param access access mode * @return a generic device if successful, null otherwise */ public PlayerDevice requestInterface (int type, int index, int access) { // if (isThreaded) // isThreaded = false; // Thread myc = Thread.currentThread (); // myc.suspend(); return requestDeviceAccess (type, index, access); // isThreaded = true; /* if (isReadyRequestDevice ()) return newpd; else return null;*/ //return xnewpd; } }