/** * @copyright 2013 Computer Science Department, Recursive InterNetworking Architecture (RINA) laboratory, Boston University. * All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation * for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all * copies and that both the copyright notice and this permission notice appear in supporting documentation. * The RINA laboratory of the Computer Science Department at Boston University makes no * representations about the suitability of this software for any purpose. * **/ package rina.ipc.ae; import java.util.LinkedHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import rina.irm.impl.IRMImpl; import rina.irm.util.HandleEntry; import rina.message.DTP; import rina.object.internal.ForwardingTable; import rina.object.internal.Neighbor; import rina.object.internal.Neighbors; import rina.rib.impl.RIBImpl; import rina.util.MessageQueue; /** * Demultiplex flows on the handle * @author Yuefeng Wang. Computer Science Department, Boston University * */ public class DataTransferAEHandler extends Thread{ private Log log = LogFactory.getLog(this.getClass()); private int handleID = -1; private HandleEntry he = null; private String apName = null; private String apInstance = null; private String aeName = null; private String aeInstance = null; private RIBImpl rib = null; private IRMImpl irm = null; private boolean listen = true; private int rinaAddr = -1; private LinkedHashMap<Integer, MessageQueue> flowQueues = null; private ForwardingTable forwardingTable = null; private Neighbors neighbors = null; public DataTransferAEHandler(int handleID, HandleEntry he, RIBImpl rib, IRMImpl irm) { this.handleID = handleID; this.he = he; this.apName = this.he.getSrcApName(); this.apInstance = this.he.getSrcApInstance(); this.aeName = this.he.getSrcAeName(); this.aeInstance = this.he.getSrcAeInstance(); this.rib = rib; this.irm = irm; this.rinaAddr = (Integer)this.rib.getAttribute("rinaAddr"); this.flowQueues = (LinkedHashMap<Integer, MessageQueue>)this.rib.getAttribute("flowQueues"); this.neighbors = (Neighbors)this.rib.getAttribute("neighbors"); this.forwardingTable = (ForwardingTable)this.rib.getAttribute("forwardingTable"); this.start(); } public void run() { this.log.info("Data Transfer Handler started on handleID " + this.handleID + ". RINA Addr is " + this.rinaAddr); while(this.listen) { byte[] msg = this.irm.receive(this.handleID); DTP dtpMsg = new DTP(msg); this.processDTPMessage(dtpMsg); } } private void processDTPMessage(DTP dtpMsg) { dtpMsg.printDTPHeader(); if(dtpMsg.getDestAddr() == this.rinaAddr) { this.demultiplex(dtpMsg); }else { this.relay(dtpMsg); } } //int counter = 0; private void relay(DTP dtpMsg) { this.log.debug("Relay DTP msg"); // counter++; // // if(counter > 100) // { // if( Math.random() < 0.3 ) // { // System.err.println("packet drop zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz " + counter); // return; // } // } int dstAddr = dtpMsg.getDestAddr(); long nextHop = this.forwardingTable.getNextHop(dstAddr); // this.log.debug("next hop of " + dstAddr + " is " + nextHop); Neighbor neighbor = this.neighbors.getBeighbor(nextHop); if( neighbor == null) { this.log.error("Next hop does not exsit"); } try { int handleID = this.irm.allocateFlow(this.apName,this.apInstance, "Data Transfer", "1", neighbor.getApName(),neighbor.getApInstance(), "Data Transfer", "1"); this.irm.send(handleID, dtpMsg.toBytes()); this.log.info( " DTP Msg relayed, and sent over handleID " + handleID); } catch (Exception e) { this.log.info( "DTP Msg relayed, but sent error"); return; } } private void demultiplex(DTP dtpMsg) { this.log.debug("Demultiplex DTP msg"); // this.log.debug("msg is " + new String(dtpMsg.getPayload())); int dstCEPID = dtpMsg.getDestCEPid(); if(this.flowQueues.containsKey(dstCEPID)) { this.flowQueues.get(dstCEPID).addReceive(dtpMsg.getPayload()); }else { this.log.error("dstCEPID is not found, msg discarded"); } } }