package metrobotics; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Scanner; /** * @author Pablo Munoz - Metrobotics * This class is in charge of communicating with the Central Server. * It interacts with GuiState, which is the Thread that inits, acks, checks for messages, * and requests positions. */ public class ServerComm { static Socket socInitMsg = null; static Socket socImages = null; PrintWriter outInit = null; // CHANGE THIS. I NEED ANOTHER TYPE OF OUTPUT BufferedReader inInit = null; OutputStream outSt = null; InputStream inSt = null; String toServer, fromServer; DataOutputStream daout = null; DataInputStream dataIn = null; private MainFrame mf; Calendar cal; ArrayList<Robot> robots; Robot bot; ServerComm(MainFrame mf, ArrayList<Robot> robots){ this.robots = robots; this.mf = mf; try { System.out.println("Sending Request"); socInitMsg = new Socket(Gui.centralServerIP, Gui.centralServerInitMsgPort); //socInitMsg.setTcpNoDelay(true); //socInitMsg.setTrafficClass(0x10); if(socInitMsg.isConnected()){ System.out.println("Aknowledgement Received"); } outSt = socInitMsg.getOutputStream(); inSt = socInitMsg.getInputStream(); daout = new DataOutputStream(outSt); dataIn = new DataInputStream(inSt); //socImages = new Socket(Robot.centralServerIP, Robot.centralServerImagePort); } catch (UnknownHostException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } public void init(){ // Sending INIT toServer = "INIT" + " " + GUIConstants.SID_GUI + " " + Gui.guiName + " " + 0 + " " + 0; if(Gui.debug){ System.out.println(toServer); } writeStream(toServer); } public boolean ack(){ // Reading ACK String regex = "[\\d]"; String ackString = readStream(); Scanner parse = new Scanner(ackString); parse.next(); String guiToParse = parse.next(); if(guiToParse.isEmpty()){ // TODO || !guiToParse.matches(regex)){ return false; } Gui.setGUIId(Long.parseLong(guiToParse)); System.out.println(Gui.getGUIId()); mf.guiId.setText("GUI ID: " + Gui.getGUIId()); if(Gui.debug){ System.out.println("ACK received and processed"); } return true; } //pablo is stupid public void check4Msg() { cal = Calendar.getInstance(); try { if(dataIn.available()>0){ String message = readStream(); mf.messageFromServer.setText(" From Server " + cal.get(Calendar.HOUR) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND) + " " + message); Scanner msgScan = new Scanner(message); String messageToken = msgScan.next(); if((messageToken.compareTo("IDENT")) == 0){ if(Gui.debug){ System.out.println("Check4Msg: IDENT received and calling identProc()"); } identProc(msgScan); } else if((messageToken.compareTo("POSE")) ==0){ aksPoseProc(msgScan); } else if((messageToken.compareTo("PLAYER")) == 0){ askPlayerProc(msgScan); } else { System.out.println("Message Unknown"); } if(Gui.debug){ System.out.println(message); } } } catch (IOException e) { e.printStackTrace(); } } public void askPose(long UniqueId) { // Sending ASKPOSE toServer = "ASKPOSE " + UniqueId; writeStream(toServer); if(Gui.debug){ System.out.println("Requesting ASKPOSE"); } } public void aksPoseProc(Scanner msgScan){ if(Gui.debug){ System.out.println("askPoseProc() Processing ASKPOSE"); System.out.println("askPoseProc() Robot num = " + robots.size()); } long []robotsId = new long[robots.size()]; int []robotsKey = new int[robots.size()]; boolean [] checkDrop = new boolean[robots.size()]; boolean callIdent = false; int r = 0; for(Robot x : robots){ robotsId[r] = x.getUniqueId(); robotsKey[r] = x.getRobotKey(); r++; } // ASKPOSE nBots UniqueID x y theta conf. int size = Integer.parseInt(msgScan.next()); for(int i=0; i<size; i++){ long unique_id = Long.parseLong(msgScan.next()); if(Gui.debug){ System.out.println("Unique ID: " + unique_id); } double x = Double.parseDouble(msgScan.next()); double y = Double.parseDouble(msgScan.next()); double t = Double.parseDouble(msgScan.next()); double conf = Double.parseDouble(msgScan.next()); int robotInListIndex = -1; int k = 0; // Check if the robot is already the list for(long id : robotsId){ if(id == unique_id){ robotInListIndex = k; break; } k++; } if(robotInListIndex == -1){ callIdent = true; } else if(robotInListIndex<robots.size()){ checkDrop[robotInListIndex] = true; //bot = new Robot.Builder(false).build(); // Change this to: robots.get(robotsKey[robotInListIndex]).setGridX(x); robots.get(robotsKey[robotInListIndex]).setGridY(y); robots.get(robotsKey[robotInListIndex]).setGridTheta(t); robots.get(robotsKey[robotInListIndex]).setGridConfidence(conf); // etc... and test // bot = robots.get(robotsKey[robotInListIndex]); // bot.setGridX(x); // bot.setGridY(y); // bot.setGridTheta(t); // bot.setGridConfidence(conf); if(Gui.debug){ System.out.println("Updated position for Robot " + robots.get(robotsKey[robotInListIndex]).getUniqueId()); } mf.grid.repaint(); } } // Check for decrease in number of robots int i=0; boolean repaint = false; for(boolean b : checkDrop){ if(b==false){ robots.remove(i); Robot.Builder.setRobotCounter(robots.size()); int j=0; for(Robot x : robots){ x.setRobotKey(j); j++; } repaint = true; } i++; } if(repaint){ if(Gui.debug){ System.out.println("Creating new RobotSel and Grid to reflect changes in robot list"); } mf.newRobotSelAndGrid(); } if(callIdent){ this.writeStream("IDENT"); if(Gui.debug){ System.out.println("Sending IDENT to update robots list"); } } } public void askPlayerProc(Scanner msgScan){ if(Gui.debug){ System.out.println("askPlayerProc() Processing ASKPLAYER"); System.out.println("askPlayerProc() Robot num = " + robots.size()); } // TODO: This code is incomplete long []robotsId = new long[robots.size()]; int []robotsKey = new int[robots.size()]; // boolean [] checkDrop = new boolean[robots.size()]; // boolean callIdent = false; int r = 0; for(Robot x : robots){ robotsId[r] = x.getUniqueId(); robotsKey[r] = x.getRobotKey(); r++; } // ASKPLAYER nBots UniqueID and add PlayerClient if it hasn't been added yet. int size = Integer.parseInt(msgScan.next()); for(int i=0; i<size; i++){ long unique_id = Long.parseLong(msgScan.next()); if(Gui.debug){ System.out.println("Unique ID: " + unique_id); } String playerIP = msgScan.next(); int port = Integer.parseInt(msgScan.next()); //int robotInListIndex = -1; int k = 0; // Check if the robot is already the list for(long id : robotsId){ if(id == unique_id){ if(!robots.get(robotsKey[k]).getHasCamera()){ // TODO: Create PlayerClient and request CameraProxy robots.get(robotsKey[k]).setPlayerClientAndCamera(playerIP, port); } // robotInListIndex = k; // break; } k++; } //if(robotInListIndex == -1){ //callIdent = true; //} } } public void identProc(Scanner msgScan){ long [] robotsId = new long[robots.size()]; boolean robotExists = false; int r = 0; for(Robot x : robots){ robotsId[r] = x.getUniqueId(); r++; } Arrays.sort(robotsId); int size = Integer.parseInt(msgScan.next()); if(Gui.debug){ System.out.println("Number of robots: " + size); } for(int i=0; i<size; i++){ // Unique_id long unique_id = Long.parseLong(msgScan.next()); if(Gui.debug){ System.out.println("Unique ID: " + unique_id); } if(Arrays.binarySearch(robotsId, unique_id)>=0){ robotExists = true; } // String clientUniqueName String name = msgScan.next(); // STring clientType String type = msgScan.next(); // int num_provides int num_prov = Integer.parseInt(msgScan.next()); for(int j=0; j<num_prov; j++){ // n strings // TODO: Handle proxies. msgScan.next(); } if(!robotExists){ bot = new Robot.Builder(false).build(); bot.setUniqueId(unique_id); bot.setName(name); bot.setRobotIcon(type); robots.add(bot); } robotExists = false; } mf.newRobotSelAndGrid(); } public String readStream() { StringBuffer sb = new StringBuffer(); int size; try { size = dataIn.read(); // First byte is size for(int i=0; i<size; i++){ int incoming = dataIn.read(); sb.append((char)incoming); } fromServer = sb.toString(); if(Gui.debug){ System.out.println("readStream() Read from server: " + fromServer); } } catch (IOException e) { e.printStackTrace(); } return fromServer; } public void writeStream(String message){ message = message + '\0'; try { daout.writeByte(message.length()); daout.write(message.getBytes(), 0, message.length()); daout.flush(); } catch (IOException e) { e.printStackTrace(); } } // OLD METHODS TO CLEAN // Please disregard this methods. I used them with my testing server. // I will delete them soon. Pablo public long init(DataOutputStream outData, DataInputStream inData, String name) { // Sending INIT toServer = "INIT" + " " + GUIConstants.SID_GUI + " " + name + " " + 0 + " " + 0 + '\0'; try { outData.writeByte(toServer.length()); outData.write(toServer.getBytes(), 0, toServer.length()); outData.flush(); // Reading ACK StringBuffer sb = new StringBuffer(); int size = inData.read(); // First byte is size. System.out.println(size); for(int i=0; i<size; i++){ int incoming = inData.read(); sb.append((char)incoming); } fromServer = sb.toString(); System.out.println(fromServer); // byte [] buf = new byte[4]; // int charsRead = inData.read(buf, 0, 4); // System.out.println(charsRead); // fromServer = new String(buf); // System.out.println(fromServer); // Get guiID; // This Works but I am trying to implement one that reads until the buffer is empty. See below. // byte [] guiId = new byte[11]; // charsRead = inSt.read(guiId, 0, 11); // System.out.println(charsRead); // fromServer = new String(guiId); // for(int i=0; i<fromServer.length(); i++){ // if(!Character.isDigit(fromServer.charAt(i))) // fromServer.replace(fromServer.charAt(i), (char) 32); // } // fromServer = fromServer.trim(); // long gui_id = Long.parseLong(fromServer); // System.out.println(fromServer); // Robot.setGuiId((int)gui_id); //sb = new StringBuffer(); //int incomingChar = inData.read(); // dataIn.read(); //do{ //incomingChar = inData.read(); //dataIn.read(); //sb.append((char)incomingChar); //System.out.print(incomingChar); //}while(inData.available() > 0); //System.out.println(); //fromServer = sb.toString(); //for(int i=0; i<fromServer.length(); i++){ //if(!Character.isDigit(fromServer.charAt(i))) //fromServer.replace(fromServer.charAt(i), (char)32); //} //fromServer = fromServer.trim(); //gui_id = Long.parseLong(fromServer); //System.out.println(fromServer); Scanner parse = new Scanner(fromServer); parse.next(); //gui_id = Long.parseLong(parse.next()); //System.out.println(gui_id); } catch (IOException e) { e.printStackTrace(); } //return gui_id; return 0; } public ArrayList<Robot> identRequest(){ ArrayList<Robot> robotList = new ArrayList<Robot>(); // Request IDENT for the first time (Request the Global State) toServer = " IDENT" + '\0'; try { daout.write(toServer.getBytes(), 0, toServer.length()); daout.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return robotList; } // This should be used with ControlServerMain public ArrayList<Robot> initSimulation() { // TODO: This should be deleted when my fake server can run simulations. ControlServerMain... ArrayList<Robot> robotList = new ArrayList<Robot>();; // Sending INIT toServer = " INIT" + " " + GUIConstants.SID_GUI + " ELGUI " + 0 + " " + 0 + "\0"; try { daout.write(toServer.getBytes(), 0, toServer.length()); daout.flush(); System.out.println("Init sent: " + toServer); // Reading ACK byte [] buf = new byte[4]; int charsRead = inSt.read(buf, 0, 4); System.out.println(charsRead); fromServer = new String(buf); System.out.println(fromServer); // Get guiID; // This Works but I am trying to implement one that reads until the buffer is empty. See below. // byte [] guiId = new byte[11]; // charsRead = inSt.read(guiId, 0, 11); // System.out.println(charsRead); // fromServer = new String(guiId); // for(int i=0; i<fromServer.length(); i++){ // if(!Character.isDigit(fromServer.charAt(i))) // fromServer.replace(fromServer.charAt(i), (char) 32); // } // fromServer = fromServer.trim(); // long gui_id = Long.parseLong(fromServer); // System.out.println(fromServer); // Robot.setGuiId((int)gui_id); StringBuffer sb = new StringBuffer(); int incomingChar = dataIn.read(); do{ sb.append((char)incomingChar); incomingChar = dataIn.read(); }while(incomingChar != '\0'); fromServer = sb.toString(); for(int i=0; i<fromServer.length(); i++){ if(!Character.isDigit(fromServer.charAt(i))) fromServer.replace(fromServer.charAt(i), (char) 32); } fromServer = fromServer.trim(); long gui_id = Long.parseLong(fromServer); System.out.println(fromServer); //Gui.setGuiId(gui_id); // Request IDENT (Request the Global State) toServer = " IDENT"; daout.write(toServer.getBytes(), 0, toServer.length()); daout.flush(); // Loop for reading Initial Configuration // This is the structure that the Central Server is going to send for the config. //char init = (char)inSt.read(); //init = swapByteOrderInt(init); //System.out.println((int)init); int FIELD_SIZE = 64; char command_id; // Using charInUse //int session_id; // Using intInUse int robotUnique_id; // name should be derived from here int owner_id; // Using intInUse int species_id; // type_id; // Using intInUse // State: int x; // Using intInUse int y = 0; // Using intInUse int theta; // Using intInUse int speed_x; int speed_y; int speed_theta; // int num_of_provides; // Using intInUse int provides; // String [] provides; //char [] name = new char[FIELD_SIZE]; //String name; // so the formula so far for number of bytes is: 7 x 4 (bytes) + // num_of_provides x 128 + 128bytes. Robot botToAdd = new Robot.Builder(false).build(); // For testing with my server //if(true) //return robotList; //c_id = new byte[1]; // charsRead2 = inSt.read(c_id, 0, 1); //System.out.println(charsRead2); // fromServer = new String(c_id); command_id = (char)inSt.read(); //(char)(c_id[0] & 0xFF); do{ // if command_id = 3 the config is done. ACK is 2 System.out.println("Command ID" + (int)command_id); // command_id if(command_id!=10) botToAdd = new Robot.Builder(false).build(); // unique_id robotUnique_id = dataIn.readInt(); //robotUnique_id = swapByteOrderInt(robotUnique_id); botToAdd.setUniqueId(robotUnique_id); System.out.println("UniqueId" + robotUnique_id); //if(command_id!=10) //botToAdd.setSessionId(session_id); //System.out.println("Session ID " + session_id);// session_id); // owner_id owner_id = dataIn.readInt(); //owner_id = swapByteOrderInt(owner_id); System.out.println("Owner Id " + owner_id); botToAdd.setOwnerId(owner_id); // type_id; species_id = dataIn.readInt(); //species_id = swapByteOrderInt(species_id); if(command_id!=10) // botToAdd.setRobotIcon(species_id); System.out.println("Type " + species_id); // x; x = dataIn.readInt(); //x = swapByteOrderInt(x); System.out.println(x); if(command_id!=10) botToAdd.setGridX(x); // y; y = dataIn.readInt(); //y = swapByteOrderInt(y); if(command_id!=10) botToAdd.setGridY(y); System.out.println(" y " + y); // theta; theta = dataIn.readInt(); //theta = swapByteOrderInt(theta); if(command_id!=10) botToAdd.setGridTheta(theta); System.out.println("theta " + theta); /* Commented to test with my server speed_x = dataIn.readInt(); speed_x = swapByteOrderInt(speed_x); System.out.println(speed_x); //speed_x = swapByteOrderDouble(speed_x); System.out.println("speed_x " + speed_x); speed_y = dataIn.readInt(); speed_y = swapByteOrderInt(speed_y); System.out.println(speed_y); // speed_x = swapByteOrder(speed); System.out.println("speed_y" + speed_y); speed_theta = dataIn.readInt(); speed_theta = swapByteOrderInt(speed_theta); System.out.println(speed_theta); // speed_x = swapByteOrder(speed); System.out.println("speed_theta " + speed_theta); provides = dataIn.readInt(); provides = swapByteOrderInt(provides); System.out.println("Provides " + provides); // Fix Name //byte [] nameByte = new byte[FIELD_SIZE]; //int charsReadName = inSt.read(nameByte, 0, FIELD_SIZE); //name = new String(nameByte); //if(command_id!=10) //botToAdd.setName(name); //System.out.println("Name " + name + " " + charsReadName); //int charNull; //while((charNull = inSt.read())== '\0'){ //} if(command_id!=10) robotList.add(botToAdd); //command_id = (char)charNull; //(char)inSt.read(); * * */ //END OF COMMENT TO TEST WITH MY SERVER if(command_id!=10) robotList.add(botToAdd); command_id = (char)inSt.read(); }while(command_id != 10); // END OF CONFIGURATION LOOP // Read death Monkey and ignore //toServer = "QUIT\0"; //outSt.write(toServer.getBytes(), 0, 5); //outSt.flush(); } catch (IOException e1) { e1.printStackTrace(); } //outInit.write(toServer); //DataOutputStream daout = new DataOutputStream(outSt); // Testing Joel Server //try { //fromServer = inInit.readLine(); //System.out.println(fromServer); // Closing connection with Joel's server //System.out.println("Sending QUIT"); //toServer = "QUIT"; //outInit.print(toServer); //} catch (IOException e) { //e.printStackTrace(); //} // End of testing // try { // while((fromServer = inInit.readLine()) != null){ // System.out.println(fromServer); // toServer = "PING"; // outInit.println(toServer); // } // } catch (IOException e) { // e.printStackTrace(); // } // // try { // while((fromServer = inInit.readLine()) != null){ // if(fromServer.compareTo("start") == 0){ // System.out.println("Building new list of Robots"); // } // if(fromServer.compareTo("Robot") == 0){ // botToAdd = new Robot.Builder(false).build(); // fromServer = inInit.readLine(); // botToAdd.setRobotIcon(Integer.parseInt(fromServer)); // fromServer = inInit.readLine(); // botToAdd.setName(fromServer); // fromServer = inInit.readLine(); // botToAdd.setGridX(Double.parseDouble(fromServer)); // fromServer = inInit.readLine(); // botToAdd.setGridY(Double.parseDouble(fromServer)); // fromServer = inInit.readLine(); // botToAdd.setGridTheta(Double.parseDouble(fromServer)); // robotList.add(botToAdd); // } // if(fromServer.compareTo("end") == 0){ // break; // } // } // } catch (IOException e) { // e.printStackTrace(); // } System.out.println("Finished Initialization"); return robotList; } public ArrayList<Robot> requestGlobalState(){ // IDENT ArrayList<Robot> robotsnewState = new ArrayList<Robot>(); try { // Request IDENT (Request the Global State) toServer = " IDENT"; daout.write(toServer.getBytes(), 0, toServer.length()); daout.flush(); Robot newBots = new Robot.Builder(false).build(); char command_id = (char)inSt.read(); //(char)(c_id[0] & 0xFF); do{ // if command_id = 3 the config is done. ACK is 2 System.out.println("Command ID" + (int)command_id); // command_id if(command_id!=10) newBots = new Robot.Builder(false).build(); // unique_id int robotUnique_id = dataIn.readInt(); //robotUnique_id = swapByteOrderInt(robotUnique_id); newBots.setUniqueId(robotUnique_id); System.out.println("UniqueId" + robotUnique_id); // owner_id int owner_id = dataIn.readInt(); //owner_id = swapByteOrderInt(owner_id); System.out.println("Owner Id " + owner_id); newBots.setOwnerId(owner_id); // type_id; int species_id = dataIn.readInt(); //species_id = swapByteOrderInt(species_id); if(command_id!=10) //newBots.setRobotIcon(species_id); System.out.println("Type " + species_id); // x; int x = dataIn.readInt(); //x = swapByteOrderInt(x); System.out.println(x); if(command_id!=10) newBots.setGridX(x); // y; int y = dataIn.readInt(); //y = swapByteOrderInt(y); if(command_id!=10) newBots.setGridY(y); System.out.println(" y " + y); // theta; int theta = dataIn.readInt(); //theta = swapByteOrderInt(theta); if(command_id!=10) newBots.setGridTheta(theta); System.out.println("theta " + theta); /* Commented to test with my server speed_x = dataIn.readInt(); speed_x = swapByteOrderInt(speed_x); System.out.println(speed_x); //speed_x = swapByteOrderDouble(speed_x); System.out.println("speed_x " + speed_x); speed_y = dataIn.readInt(); speed_y = swapByteOrderInt(speed_y); System.out.println(speed_y); // speed_x = swapByteOrder(speed); System.out.println("speed_y" + speed_y); speed_theta = dataIn.readInt(); speed_theta = swapByteOrderInt(speed_theta); System.out.println(speed_theta); // speed_x = swapByteOrder(speed); System.out.println("speed_theta " + speed_theta); provides = dataIn.readInt(); provides = swapByteOrderInt(provides); System.out.println("Provides " + provides); // Fix Name //byte [] nameByte = new byte[FIELD_SIZE]; //int charsReadName = inSt.read(nameByte, 0, FIELD_SIZE); //name = new String(nameByte); //if(command_id!=10) //botToAdd.setName(name); //System.out.println("Name " + name + " " + charsReadName); //int charNull; //while((charNull = inSt.read())== '\0'){ //} if(command_id!=10) robotList.add(botToAdd); //command_id = (char)charNull; //(char)inSt.read(); * * */ //END OF COMMENT TO TEST WITH MY SERVER if(command_id!=10) robotsnewState.add(newBots); command_id = (char)inSt.read(); }while(command_id != 10); } catch (IOException e1) { e1.printStackTrace(); } System.out.println("Finished New State"); return robotsnewState; } public boolean sendReqGrab() { return true; } public boolean sendReqUnGrab() { return false; } }