/*
This file is part of JOP, the Java Optimized Processor
see <http://www.jopdesign.com/>
Copyright (C) 2010, Thomas Hassler, Lukas Marx
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Thomas Hassler e0425918@student.tuwien.ac.at
* @author Lukas Marx lukas.marx@gmail.com
* @version 1.0
*/
package ttpa.protocol;
//import ttpa.user.UserRodl;
/**
* MSA
*/
public class Msa
{
/** firework, epoch counter, log_name, file name / op, rec_name, checksum */
private byte[] msaArray = new byte[TtpaConst.MSA_LENGTH];
/** file name */
private byte file;
/** operation */
private byte op;
/** if there was a checksum error in the msa round all msd data bytes are set to 0xFF */
private boolean checksumError = false;
/** log name that the master will send in MSA round */
private byte masterMsaLog = 0x01;
/** record name that the master will send in MSA round */
private byte masterMsaRec = 0x01;
/** file/op byte that the master will send in MSA round */
private byte masterMsaFileOp;
public Msa() {
msaArray[0] = TtpaConst.FIREWORK[5];
}
/**
* initializes the MSA Round
*
* @param ectrCnt epoch counter counts every roudn
* @param logName logical name of the node
* @param fileOp filename and operation
* @param recName record name
*/
public void init(byte ectrCnt, byte logName, byte fileOp, byte recName)
{
this.msaArray[0] = TtpaConst.FIREWORK[5];
this.msaArray[1] = ectrCnt; // epoch counter
this.msaArray[2] = logName; // logical name of the node
this.msaArray[3] = fileOp; // file name and operation (read, write, execute) (bit 7...2 = file, bit 0..1 = op)
this.msaArray[4] = recName; // record name
this.msaArray[5] = Node.calcCheck(msaArray, TtpaConst.MSA_LENGTH);
}
/**
* @return logical name that was sent in the MSA round
*/
public byte getMsaLogName()
{
return msaArray[2];
}
/**
* @return file name and operation that was sent in the MSA round
*/
public byte getMsaFileOp()
{
return msaArray[3];
}
/**
* @return record name that was sent in the MSA round
*/
public byte getMsaRecName()
{
return msaArray[4];
}
/**
* sends the MSA frame
*
* @return true if this was the last slot, false else
*/
public boolean msaSendFrame()
{
// first slot (send FW byte)
if (Start.node.getSlotCounter() == 0)
{
Transmit.sendFWByte(msaArray[0]);
}
// all other slots
else
{
Transmit.sendByte(msaArray[Start.node.getSlotCounter()]);
}
// this is the last slot
if (Start.node.getSlotCounter() == TtpaConst.MSA_LENGTH - 1)
{
return true;
}
return false;
}
/**
* @param myChecksumError the boolean value for the object
*/
public void setChecksumError(boolean myChecksumError)
{
checksumError = myChecksumError;
}
/**
* @return checksum_error
*/
public boolean isChecksumError()
{
return checksumError;
}
/**
* saves the received data in the msa_array
*
* @return true if there was a checksum error, false else
*/
public boolean msaRecvFrame()
{
msaArray[Start.node.getSlotCounter()] = Transmit.recvByte();
// this is the last slot
if (Start.node.getSlotCounter() == TtpaConst.MSA_LENGTH - 1)
{
// calculate checksum
if ( Node.calcCheck(msaArray, (byte) (TtpaConst.MSA_LENGTH )) != msaArray[TtpaConst.MSA_LENGTH - 1] )
{
setChecksumError(true);
System.out.println("Checksum Error");
}
return true;
}
return false;
}
/**
* @param file file name
*/
public void setFile(byte file)
{
this.file = file;
}
/**
* @return file name
*/
public byte getFile()
{
return file;
}
/**
* @return type of operation
*/
public byte getOp()
{
return op;
}
/**
* @param myOp type of operation
*/
public void setOp(byte myOp)
{
this.op = myOp;
}
/**
* calculates the file name and operation of the received MSA bytes
* (file name and operation are sent in one byte and must be separated)
*/
public void divideFileNameOp()
{
byte myFile, myOp;
byte myByte = getMsaFileOp(); // get value to split
myOp = (byte) (myByte & ((byte) 3)); // get operation (the two LSB)
myFile = myByte >>>= 2; // shift out the op bits
myFile &= (byte) 63; // get file name
setFile(myFile);
setOp(myOp);
}
/**
* calculate the combined file, op value to send for MSA round of a byte file and op
* the 6 most significant bits are file the 2 least significant bits are op
*
* @param myFile file name to address
* @param myOp operation to do
*/
public void calcFileNameOp(byte myFile, byte myOp)
{
masterMsaFileOp = myFile <<= 2; // shift 2 to left for operation to fit in
myOp &= (byte) 3; // make sure the 6 msb bits are 0
masterMsaFileOp |= myOp; // combine file and op
}
/**
* @param master_msa_log logical name that the master will send in MSA
*/
public void setMasterMsaLog(byte master_msa_log)
{
this.masterMsaLog = master_msa_log;
}
/**
* @return logical name that the master will send in MSA
*/
public byte getMasterMsaLog()
{
return masterMsaLog;
}
/**
* @param master_msa_rec record name that the master will send in MSA
*/
public void setMasterMsaRec(byte master_msa_rec)
{
this.masterMsaRec = master_msa_rec;
}
/**
* @return record name that the master will send in MSA
*/
public byte getMasterMsaRec()
{
return masterMsaRec;
}
/**
* @return combined file/op byte that the master will send in MSA
*/
public byte getMasterMsaFileOp()
{
return masterMsaFileOp;
}
}