public synchronized void message(LocoNetMessage m){
  int opCode=m.getOpCode();
switch (opCode) {
case LnConstants.OPC_PEER_XFER:
    int src=m.getElement(2);
  int dst=m.getElement(3) + m.getElement(4) * 256;
int[] packet=m.getPeerXfrData();
if (src == lowPart(LocoBufferAddress)) {
String lbv=((packet[2] != 0) ? dotme(packet[2]) : "1.0");
setLBVersion(lbv);
}
if (dst == LocoBufferAddress && src == lowPart(unitAddress) && (packet[4] == unitSubAddress)) {
stopTimer();
replyReceived();
String fw=((packet[2] != 0) ? dotme(packet[2]) : "1.3.2");
setLIOVersion(fw);
if (packet[0] == LocoIO.LOCOIO_SV_READ || reading) {
if (lastOpCv >= 0 && lastOpCv <= 50) {
  int data=(packet[2] != 0) ? packet[5] : packet[7];
  int channel=(lastOpCv / 3) - 1;
  if (channel < 0) {
    log.warn("... channel is less than zero!!!");
    channel=0;
  }
  int type=lastOpCv - (channel * 3 + 3);
  log.debug("... updating port " + channel + " SV"+ type+ "("+ (type == 1 ? "value1" : type == 2 ? "value2" : type == 0 ? "mode" : "unknown")+ ") = 0x"+ Integer.toHexString(data));
  if (type == 2) {
    setV2(channel,data);
    setMode(channel,"<none>");
  }
 else   if (type == 1) {
    setV1(channel,data);
    setMode(channel,"<none>");
  }
 else   if (type == 0) {
    setSV(channel,data);
    LocoIOMode lim=validmodes.getLocoIOModeFor(getSV(channel),getV1(channel),getV2(channel));
    if (lim == null) {
      setMode(channel,"<none>");
      setAddr(channel,0);
      log.debug("Could not find mode!");
    }
 else {
      setMode(channel,lim.getFullMode());
      setAddr(channel,validmodes.valuesToAddress(lim.getOpcode(),getSV(channel),getV1(channel),getV2(channel)));
    }
    log.debug("... decoded address (" + "cv=" + Integer.toHexString(getSV(channel)) + " "+ "v1="+ Integer.toHexString(getV1(channel))+ " "+ "v2="+ Integer.toHexString(getV2(channel))+ ") "+ "is "+ getAddr(channel)+ "(0x"+ Integer.toHexString(getAddr(channel))+ ")");
  }
 else {
    log.warn("OPC_PEER_XFR: Type (" + type + ") is not {0,1,2} for channel "+ channel);
  }
}
 else {
}
}
issueNextOperation();
return;
}
 else {
return;
}
case LnConstants.OPC_INPUT_REP:
if (log.isDebugEnabled()) {
log.debug(LnConstants.OPC_NAME(opCode) + " received");
}
for (int i=0; i < _numRows; i++) {
if (capture[i]) {
if (log.isDebugEnabled()) {
log.debug("row set for capture: " + i);
}
int val1=m.getElement(1);
int val2=m.getElement(2);
setAddr(i,((val2 & 0x0F) << 5) * 256 + ((val1 & 0x7f) << 1) | (((val2 & LnConstants.OPC_SW_REQ_DIR) == LnConstants.OPC_SW_REQ_DIR) ? 0x01 : 0x00));
capture[i]=false;
}
}
return;
case LnConstants.OPC_SW_REQ:
if (log.isDebugEnabled()) {
log.debug(LnConstants.OPC_NAME(opCode) + " received");
}
for (int i=0; i < _numRows; i++) {
if (capture[i]) {
if (log.isDebugEnabled()) {
log.debug("row set for capture: " + i);
}
int val1=m.getElement(1);
int val2=m.getElement(2);
int addr=LocoIO.SENSOR_ADR(val1,val2);
setAddr(i,addr);
capture[i]=false;
}
}
return;
default :
}
}

public synchronized void message ( LocoNetMessage m ) { int opCode = m . getOpCode ( ) ; switch ( opCode ) { case LnConstants . OPC_PEER_XFER : int src = m . getElement ( 2 ) ; int dst = m . getElement ( 3 ) + m . getElement ( 4 ) * 256 ; int [ ] packet = m . getPeerXfrData ( ) ; if ( src == lowPart ( LocoBufferAddress ) ) { String lbv = ( ( packet [ 2 ] != 0 ) ? dotme ( packet [ 2 ] ) : "1.0" ) ; setLBVersion ( lbv ) ; } if ( dst == LocoBufferAddress && src == lowPart ( unitAddress ) && ( packet [ 4 ] == unitSubAddress ) ) { stopTimer ( ) ; replyReceived ( ) ; String fw = ( ( packet [ 2 ] != 0 ) ? dotme ( packet [ 2 ] ) : "1.3.2" ) ; setLIOVersion ( fw ) ; if ( packet [ 0 ] == LocoIO . LOCOIO_SV_READ || reading ) { if ( lastOpCv >= 0 && lastOpCv <= 50 ) { int data = ( packet [ 2 ] != 0 ) ? packet [ 5 ] : packet [ 7 ] ; int channel = ( lastOpCv / 3 ) - 1 ; if ( channel < 0 ) { log . warn ( "... channel is less than zero!!!" ) ; channel = 0 ; } int type = lastOpCv - ( channel * 3 + 3 ) ; log . debug ( "... updating port " + channel + " SV" + type + "(" + ( type == 1 ? "value1" : type == 2 ? "value2" : type == 0 ? "mode" : "unknown" ) + ") = 0x" + Integer . toHexString ( data ) ) ; if ( type == 2 ) { setV2 ( channel , data ) ; setMode ( channel , "<none>" ) ; } else if ( type == 1 ) { setV1 ( channel , data ) ; setMode ( channel , "<none>" ) ; } else if ( type == 0 ) { setSV ( channel , data ) ; LocoIOMode lim = validmodes . getLocoIOModeFor ( getSV ( channel ) , getV1 ( channel ) , getV2 ( channel ) ) ; if ( lim == null ) { setMode ( channel , "<none>" ) ; setAddr ( channel , 0 ) ; log . debug ( "Could not find mode!" ) ; } else { setMode ( channel , lim . getFullMode ( ) ) ; setAddr ( channel , validmodes . valuesToAddress ( lim . getOpcode ( ) , getSV ( channel ) , getV1 ( channel ) , getV2 ( channel ) ) ) ; } log . debug ( "... decoded address (" + "cv=" + Integer . toHexString ( getSV ( channel ) ) + " " + "v1=" + Integer . toHexString ( getV1 ( channel ) ) + " " + "v2=" + Integer . toHexString ( getV2 ( channel ) ) + ") " + "is " + getAddr ( channel ) + "(0x" + Integer . toHexString ( getAddr ( channel ) ) + ")" ) ; } else { log . warn ( "OPC_PEER_XFR: Type (" + type + ") is not {0,1,2} for channel " + channel ) ; } } else { } } issueNextOperation ( ) ; return ; } else { return ; } case LnConstants . OPC_INPUT_REP : if ( log . isDebugEnabled ( ) ) { log . debug ( LnConstants . OPC_NAME ( opCode ) + " received" ) ; } for ( int i = 0 ; i < _numRows ; i ++ ) { if ( capture [ i ] ) { if ( log . isDebugEnabled ( ) ) { log . debug ( "row set for capture: " + i ) ; } int val1 = m . getElement ( 1 ) ; int val2 = m . getElement ( 2 ) ; setAddr ( i , ( ( val2 & 0x0F ) << 5 ) * 256 + ( ( val1 & 0x7f ) << 1 ) | ( ( ( val2 & LnConstants . OPC_SW_REQ_DIR ) == LnConstants . OPC_SW_REQ_DIR ) ? 0x01 : 0x00 ) ) ; capture [ i ] = false ; } } return ; case LnConstants . OPC_SW_REQ : if ( log . isDebugEnabled ( ) ) { log . debug ( LnConstants . OPC_NAME ( opCode ) + " received" ) ; } for ( int i = 0 ; i < _numRows ; i ++ ) { if ( capture [ i ] ) { if ( log . isDebugEnabled ( ) ) { log . debug ( "row set for capture: " + i ) ; } int val1 = m . getElement ( 1 ) ; int val2 = m . getElement ( 2 ) ; int addr = LocoIO . SENSOR_ADR ( val1 , val2 ) ; setAddr ( i , addr ) ; capture [ i ] = false ; } } return ; default : } }
listen to the loconet . we ' re listening for incoming opc_peer_xfr messages , which might be part of a read or write sequence . we ' re also _sometimes_ listening for commands as part of a " capture " operation . < p > the incoming loconet opc_peer_xfr messages don ' t retain any information about the cv number or whether it was a read or write operation . we store the data regardless of whether it was read or write , but we need to remember the cv number in the lastopcv member . < p >
