public void run() { byte[] last = null; while (!Thread.currentThread().isInterrupted()) { byte[] data = recv(); if (!Util.equals( data, last)) { // prevent re-processing the same received packet again and again... in real // life the transmission doesn't "hang around" but this simulation does not // have a mechanism for "clearing the air" yet. last = data; // detect frame type FrameType frameType = FrameType.nullOrValueOf(Util.first(data, FrameType.LENGTH)); if (frameType == null) { log("Received invalid frame data: " + Hex.encodeHexString(data)); } else if (frameType.equals(FrameType.BEACON)) { // if( frame instanceof BeaconFrame ) { BeaconFrame beaconFrame = new BeaconFrame(data); // (BeaconFrame)frame; NodeInfo nodeInfo = nodes.get(beaconFrame.sourceNodeAddress); if (nodeInfo == null) { nodeInfo = new NodeInfo(); nodeInfo.address = beaconFrame.sourceNodeAddress; nodes.put(beaconFrame.sourceNodeAddress, nodeInfo); } nodeInfo.lastBeaconAt = System.currentTimeMillis(); nodes.put(beaconFrame.sourceNodeAddress, nodeInfo); beaconReply(beaconFrame); for (Connection c : ports.values()) { if (c.authentication() == null) { portAdviceReply(beaconFrame, c.portAdvice()); } else { portAdviceReply(beaconFrame, c.endorsedPortAdvice()); } } } else if (frameType.equals( FrameType.PORT_ADVICE)) { // else if( frame instanceof PortAdviceFrame ) { PortAdviceFrame portAdviceFrame = new PortAdviceFrame(data); // (PortAdviceFrame)frame; // once we have a port advice, we do not let anyone redefine it. node must be reset in // order to accept new definitions. if (!ports.containsKey(portAdviceFrame.portAddress())) { // only add the port advice if we support its protocols if (encodings.contains(portAdviceFrame.encoding)) { ports.put(portAdviceFrame.portAddress(), new Connection(link, portAdviceFrame)); } } } else if (frameType.equals(FrameType.ENDORSED_PORT_ADVICE)) { EndorsedPortAdviceFrame endorsedPortAdviceFrame = new EndorsedPortAdviceFrame(data); /* // if it's authenticated port advice, then we overwrite existing advice for that port; for example this can be used to change secrets Connection c = ports.get(endorsedPortAdviceFrame.portAddress()); if( c != null ) { c.recv(data); // XXX TODO hmm, so how do we find out from the connection if the frame was authentic - because we need to know before we do ports.put(...) } */ // for now we use the same rule as non-authenticated port advice, which is only to // create a new port if we don't already have it if (!ports.containsKey(endorsedPortAdviceFrame.portAddress())) { // only add the port advice if we support its protocols if (encodings.contains(endorsedPortAdviceFrame.encoding) && authentications.contains(endorsedPortAdviceFrame.authentication)) { ports.put( endorsedPortAdviceFrame.portAddress(), new Connection(link, endorsedPortAdviceFrame)); } } } else if (frameType.equals(FrameType.DATA)) { Connection c = ports.get(DataFrame.extractPortAddress(data)); if (c != null) { c.recv( data); // pass the frame to appropriate connection - it will handle handshakes, // data, etc. } } else if (frameType.equals(FrameType.ENDORSED_DATA)) { Connection c = ports.get(EndorsedDataFrame.extractPortAddress(data)); if (c != null) { c.recv( data); // pass the frame to appropriate connection - it will handle handshakes, // data, etc. } } } Util.sleep(1, TimeUnit.MILLISECONDS); } }