case NakAckHeader.NAK_ACK_MSG: case NakAckHeader.NAK_MSG: if(hdr.type == NakAckHeader.NAK_ACK_MSG) { Message      ack_msg=new Message(msg.getSrc(), null, null); NakAckHeader h=new NakAckHeader(NakAckHeader.NAK_ACK_RSP, hdr.seqno, null); ack_msg.putHeader(getName(), h); passDown(new Event(Event.MSG, ack_msg)); }
switch(hdr.type) {
    public void up(Event evt) {	NakAckHeader  hdr=null;	Message       msg, msg_copy;	int           rc;	switch(evt.getType()) {	case Event.SUSPECT:	    if(Trace.trace)		Trace.info("NAKACK.up()", "received SUSPECT event (suspected member=" + evt.getArg() + ")");	    naker.suspect((Address) evt.getArg());	    out_of_bander.suspect((Address) evt.getArg());	    break;	    	case Event.STABLE:  // generated by STABLE layer. Delete stable messages passed in arg	    naker.stable((long[])evt.getArg());	    return; // don't pass up further (Bela Aug 7 2001)	case Event.SET_LOCAL_ADDRESS:	    local_addr=(Address)evt.getArg();	    break;	case Event.GET_MSGS_RECEIVED:  // returns the highest seqnos delivered to the appl. (used by STABLE)	    long[] highest=naker.getHighestSeqnosDelivered();	    passDown(new Event(Event.GET_MSGS_RECEIVED_OK, highest));	    return; // don't pass up further (bela Aug 7 2001)	case Event.MSG:	     synchronized (this) {		  msg=(Message)evt.getArg();		  // check to see if this is a wrapped msg. If yes, send an ACK		  hdr=(NakAckHeader)msg.removeHeader(WRAPPED_MSG_KEY); // see whether it is a wrapped message		  if(hdr != null && hdr.type == NakAckHeader.WRAPPED_MSG) { // send back an ACK to hdr.sender		      Message      ack_msg=new Message(hdr.sender, null, null);		      NakAckHeader h=new NakAckHeader(NakAckHeader.NAK_ACK_RSP, hdr.seqno, null);		      		      if(hdr.sender == null)			  Trace.warn("NAKACK.up()", "WRAPPED: header's 'sender' field is null; " +				     "cannot send ACK !");		      ack_msg.putHeader(getName(), h);		      passDown(new Event(Event.MSG, ack_msg));		  }		  hdr=(NakAckHeader)msg.removeHeader(getName());		  if(hdr == null)		      break;  // pass up		  switch(hdr.type) {		  case NakAckHeader.NAK_ACK_MSG:		  case NakAckHeader.NAK_MSG:		      if(hdr.type == NakAckHeader.NAK_ACK_MSG) {  // first thing: send ACK back to sender			  Message      ack_msg=new Message(msg.getSrc(), null, null);			  NakAckHeader h=new NakAckHeader(NakAckHeader.NAK_ACK_RSP, hdr.seqno, null);			  ack_msg.putHeader(getName(), h);			  passDown(new Event(Event.MSG, ack_msg));		      }		      // while still a client, we just pass up all messages, without checking for message		      // view IDs or seqnos: other layers further up will discard messages not destined		      // for us (e.g. based on view IDs).		      // Also: store msg in queue, when view change is received, replay messages with the same		      // vid as the new view		      if(!is_server) {			  msg_copy=msg.copy();                // msg without header			  msg_copy.putHeader(getName(), hdr); // put header back on as we removed it above			  queued_msgs.add(msg_copy);          // need a copy since passUp() will modify msg			  passUp(new Event(Event.MSG, msg));			  return;		      }		      // check for VIDs: is the message's VID the same as ours ?		      if(vid != null && hdr.vid != null) { // only check if our vid and message's vid available			  Address my_addr=vid.getCoordAddress(), other_addr=hdr.vid.getCoordAddress();			  if(my_addr == null || other_addr == null) {			      Trace.warn("NAKACK.up()", "my vid or message's vid does not contain " +					 "a coordinator; discarding message !");			      return;			  }			  if(!my_addr.equals(other_addr)) {			      Trace.warn("NAKACK.up()", "creator of own vid (" + my_addr + ")is different from " +					 "creator of message's vid (" + other_addr + "); discarding message !");			      return;			  }			  rc=hdr.vid.compareTo(vid);			  if(rc > 0) {           // message is sent in next view -> store !			      if(Trace.trace)				  Trace.info("NAKACK.up()", "message's vid (" + hdr.vid + "#" + hdr.seqno + 					     ") is bigger than current vid: (" + vid+ ") message is queued !");			      msg.putHeader(getName(), hdr);  // put header back on as we removed it above			      queued_msgs.add(msg);			      return;			  }			  if(rc < 0) {      // message sent in prev. view -> discard !			      if(Trace.trace)				  Trace.warn("NAKACK.up()", "message's vid (" + hdr.vid +") is smaller than " + 					     "current vid ("+ vid+"): message <"+ msg.getSrc() + ":#" +					     hdr.seqno + "> is discarded ! Hdr is " + hdr);			      return;			  }			  // If we made it down here, the vids are the same --> OK		      }		      msg.putHeader(getName(), hdr);   // stored in received_msgs, re-sent later that's why hdr is added !		      naker.receive(hdr.seqno, msg, null);		      return;        // naker passes message up for us !		  case NakAckHeader.RETRANSMIT_MSG:		      naker.retransmit(msg.getSrc(), hdr.seqno, hdr.last_seqno);		      return;		  case NakAckHeader.NAK_ACK_RSP:		      naker.receiveAck(hdr.seqno, msg.getSrc());		      return;        // discard, no need to pass up		  case NakAckHeader.OUT_OF_BAND_MSG:		      out_of_bander.receive(hdr.seqno, msg, hdr.stable_msgs);		      return;        // naker passes message up for us !		  case NakAckHeader.OUT_OF_BAND_RSP:		      out_of_bander.receiveAck(hdr.seqno, msg.getSrc());		      return;		  default:		      Trace.error("NAKACK.up()", "NakAck header type " + hdr.type + " not known !");		      break;		  }	     } //end synchronized	}	passUp(evt);    }