⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genericatmswitch.java

📁 一个小型网络仿真器的实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        }
      }
    }
  }

  private void sw_proc_slot_time() {
    java.util.Iterator i=voports.values().iterator();
    while(i.hasNext()) {
      sw_demux_spq((Port)i.next());
    }
    i=voports.values().iterator();
    while(i.hasNext()) {
      Port voport=(Port)i.next();
      if((!voport.sigQueue.isEmpty() || !voport.abr.ptr.isEmpty()
          || !voport.vbr.ptr.isEmpty()) &&
          !voport.link_busy) {
        voport.link_busy=true;
        sw_schedule_output(voport);
      }
    }
  }

  private void sw_averaging_interval() {
    //update cell loss percent
    sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
  }

  private void sw_demux_spq(Port voport) {
    Cell cell;
    int i,temp,qs,pick,no_drop,lst[]=null;
    boolean done,match;
    ForwardEntry fe;

    qs = voport.spq.size();
    no_drop=(qs > sw_speedup.getValue() ? qs-sw_speedup.getValue():0);
    if(no_drop!=0) {
      sw_cpucong.setValue(true);
      sw_cpucong.update(theSim.now());

      lst=new int[qs];
      for(i=0;i<qs;i++) lst[i]=i;
      for(i=0;i<no_drop;i++) {
        pick=randgen.nextInt(qs-i)+i;
        //swap entry i with the picked entry
        temp=lst[i];
        lst[i]=lst[pick];
        lst[pick]=temp;
      }

      //the above code shuffles the number randomly (fairly too),
      //(only the first no_drop entries actually "shuffled" out)
      //and the first no_drop entries will be the index of the cell
      //in spq to be dropped
    }
    pick=0;
    match=false;
    while(!voport.spq.isEmpty()) {
      cell=(Cell)voport.spq.remove(0);

      for(i=0;i<no_drop;i++) {
        if(pick==lst[i]) {
          match=true;
          break;
        }
      }

      if(match) {
        num_dropped++;
        sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
        cell=null;
        match=false;
      }
      else {
        fe=(ForwardEntry)cell.forwardEntry;

        //it's time to switch ...
        cell.vpi=fe.tokey.vpi;
        cell.vci=fe.tokey.vci;

        if(fe.contype==UNIInfo.CON_ABR || fe.contype==UNIInfo.CON_UBR) {
          if((voport.abr.ptr.size() < sw_oqsize.getValue())
            || (sw_oqsize.getValue() == -1)) {
            voport.abr.ptr.add(cell);
            voport.abr.iq.setValue(voport.abr.ptr.size(),theSim.now(),sw_log_factor.getValue());
          }
          else {
            num_dropped++;
            sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
            voport.abr.dq.setValue(voport.abr.dq.getValue()+1,theSim.now(),sw_log_factor.getValue());
            cell=null;
          }
        }
        else {
          if((voport.vbr.ptr.size() < sw_oqsize.getValue())
            || (sw_oqsize.getValue()==-1)) {
            voport.vbr.ptr.add(cell);
            voport.vbr.iq.setValue(voport.vbr.ptr.size(),theSim.now(),sw_log_factor.getValue());
          }
          else {
            num_dropped++;
            sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
            voport.vbr.dq.setValue(voport.vbr.dq.getValue()+1,theSim.now(),sw_log_factor.getValue());
            cell=null;
          }
        }
      }
      pick++;
    }
  }

  private void sw_schedule_output(Port voport) {
    Cell icell=null;

    if(!voport.sigQueue.isEmpty()) {
      icell=(Cell)voport.sigQueue.remove(0);
    }
    else if(!voport.vbr.ptr.isEmpty()) {
      icell=(Cell)voport.vbr.ptr.remove(0);
      voport.vbr.iq.setValue(voport.vbr.iq.getValue() - 1,theSim.now(),sw_log_factor.getValue());
    }
    else if(!voport.abr.ptr.isEmpty()) {
      icell=(Cell)voport.abr.ptr.remove(0);
      voport.abr.iq.setValue(voport.abr.iq.getValue() - 1,theSim.now(),sw_log_factor.getValue());
    }

    theSim.enqueue(new SimEvent(SimProvider.EV_RECEIVE,this,
                                voport.to_link,theSim.now(),icell));
  }

  private void sw_receive(SimEvent e) {
    long ticks;

    ticks=SimClock.USec2Tick(sw_delay.getValue());
    theSim.enqueue(new SimEvent(MY_RECEIVE,e.getSource(),this,
                        theSim.now()+ticks,e.getParams()));

    //update cell count
    total_cell++;
    sw_cells_received.setValue(sw_cells_received.getValue()+1,theSim.now(),sw_log_factor.getValue());
  }

  private void sw_my_receive(SimEvent e) {
    Cell cell=(Cell)e.getParams();

    ForwardEntry fe;
    SimComponent src=(SimComponent)e.getSource();
    Port voport=null;

    fe=(ForwardEntry)sw_forward_table.lookup(cell.vpi,cell.vci,src);
    if(fe==null) { //no forwarding info
      //check for signaling cells
      if(cell.vpi==0 && cell.vci==5) {
        doUNI(cell,(Port)voports.get(src));
      }
      else {
      //else, drop the cell
        num_dropped++;
        sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
      }
      return;
    }

    cell.forwardEntry=fe;
    voport=(Port)voports.get(fe.tokey.link);
    voport.spq.add(cell);
  }

  private void doUNI(Cell cell,Port voport) {
    CallRecord rec;
    SimComponent dest;
    int vpi,vci,cref;

    if(voport.aal.receiveCell(cell)==1) {
      UNIInfo uni=(UNIInfo)cell.payload;

      switch(uni.msgtype) {
        case UNIInfo.UNI_SETUP:

        //first, add a new record
          CallRecord newrec=new CallRecord();
          newrec.fe=new ForwardEntry();

          if(uni.newvpi!=-1 && uni.newvci!=-1) {
            newrec.fe.fromkey=new ForwardKey(uni.newvpi,uni.newvci,voport.to_link);
          }
          else { //tedious, must generate new vpi,vci
            do {
              vpi=randgen.nextInt(255)+1;
              vci=randgen.nextInt(65535)+1;
              newrec.fe.fromkey=new ForwardKey(vpi,vci,voport.to_link);
            } while(sw_forward_table.fromkeyExist(newrec.fe.fromkey));
          }

          newrec.fromkey=new CallRecordKey(uni.callref,voport.to_link);
          newrec.fe.contype=uni.contype;
          newrec.fe.svc=true;

          dest=sw_route_table.queryOutLink(uni.calledNSAP);
          if(dest==null || dest==voport.to_link) { //this is bad...
            //System.out.println("Routing problem at switch: "+getName());
            //System.out.println("  Call request from: "+voport.to_link.getName());
            //System.out.print("  Either destination not found or ");
            //System.out.println(" destination same as source.");

            //it's time to send a release_complete...
            UNIInfo newuni=new UNIInfo();
            newuni.callref=uni.callref+65535; //see NOTE below
            newuni.msgtype=UNIInfo.UNI_RELEASE_COMPLETE;
            voport.sigQueue.addAll(voport.aal.sendData(newuni,20,0,5));
            return;
          }

          do { //tedious again, must generate new vpi,vci
            vpi=randgen.nextInt(255)+1;
            vci=randgen.nextInt(65535)+1;
            newrec.fe.tokey=new ForwardKey(vpi,vci,dest);
          } while(sw_forward_table.tokeyExist(newrec.fe.tokey));

          //now generate new callref to dest
          do {
            cref=randgen.nextInt(65535)+1;
            newrec.tokey=new CallRecordKey(cref,dest);
/* NOTE:
    Call reference actually has a flag, 0 when sent from source,
    1 when sent toward source. Here, I use 1-65535 when sent from source,
    and 65536-131070 when sent toward source. This is to avoid
    simultaneus assignment of same call reference from two source
    (refer UNI3.1 spec of ATMForum).
    (Of course, in the records and r_records maps, the original value
    1-65535 is always used)
*/
          } while(r_records.get(newrec.tokey)!=null);

          sw_forward_table.addNewEntry(newrec.fe);
          records.put(newrec.fromkey,newrec);
          r_records.put(newrec.tokey,newrec);

        //next, send back CALL_PROCEEDING
          UNIInfo newuni=new UNIInfo();
          newuni.callref=uni.callref+65535; //remember, toward source should
                                            //add 65535
          newuni.msgtype=UNIInfo.UNI_CALL_PROCEEDING;
          newuni.newvpi=newrec.fe.fromkey.vpi;
          newuni.newvci=newrec.fe.fromkey.vci;
          voport.sigQueue.addAll(voport.aal.sendData(newuni,20,0,5));

        //then, pass along the SETUP message, change necessary info
          uni.callref=newrec.tokey.callref;
          uni.newvpi=newrec.fe.tokey.vpi;
          uni.newvci=newrec.fe.tokey.vci;
          voport=(Port)voports.get(dest); //switch port to destination port
          voport.sigQueue.addAll(voport.aal.sendData(uni,120,0,5));
          break;

        case UNIInfo.UNI_CONNECT:
          //need to pass along this message to source

          rec=(CallRecord)r_records.get(new CallRecordKey(uni.callref-65535,voport.to_link));
          if(rec==null) return; //no record?!!
          uni.callref=rec.fromkey.callref+65535;
          voport=(Port)voports.get(rec.fromkey.link);
          voport.sigQueue.addAll(voport.aal.sendData(uni,20,0,5));
          break;

        case UNIInfo.UNI_RELEASE:
          //must delete record, and pass along
          //release can be from either direction
          if(uni.callref>65535) { //reverse direction, from destination
            rec=(CallRecord)r_records.get(new CallRecordKey(uni.callref-65535,voport.to_link));
            if(rec==null) return; //no record?!!
            uni.callref=rec.fromkey.callref+65535;
            voport=(Port)voports.get(rec.fromkey.link);
          }
          else {
            rec=(CallRecord)records.get(new CallRecordKey(uni.callref,voport.to_link));
            if(rec==null) return; //no record?!!
            uni.callref=rec.tokey.callref;
            voport=(Port)voports.get(rec.tokey.link);
          }
          voport.sigQueue.addAll(voport.aal.sendData(uni,20,0,5));

          //delete the record
          sw_forward_table.removeEntry(rec.fe);
          records.remove(rec.fromkey);
          r_records.remove(rec.tokey);
          break;

        case UNIInfo.UNI_RELEASE_COMPLETE:
          //only used for rejecting call setup request
          //so assume from the destination side
          //must delete record and pass along
          rec=(CallRecord)r_records.get(new CallRecordKey(uni.callref-65535,voport.to_link));
          if(rec==null) return; //no record?!!
          uni.callref=rec.fromkey.callref+65535;
          voport=(Port)voports.get(rec.fromkey.link);
          voport.sigQueue.addAll(voport.aal.sendData(uni,20,0,5));

          //delete the record
          sw_forward_table.removeEntry(rec.fe);
          records.remove(rec.fromkey);
          r_records.remove(rec.tokey);
          break;
      }
    }
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -