/** @file * $Source: /afs/ba.infn.it/user/pamela/src/CVS/chewbacca/PamOffLineSW/techmodel/McmdReader.cpp,v $ * $Id: McmdReader.cpp,v 1.2 2008-10-01 09:53:42 mocchiut Exp $ * $Author: mocchiut $ * * Implementation of the McmdReader class. */ extern "C" { #include "CRC.h" } #include "ReaderAlgorithms.h" using namespace pamela::techmodel; /** * Constructor. */ McmdReader::McmdReader(void) : TechmodelAlgorithm(PacketType::Mcmd, "Mcmd") { Mcmd = new McmdEvent(); } /** * Get a string with the version info of the algorithm. */ std::string McmdReader::GetVersionInfo(void) const { return "$Header: /afs/ba.infn.it/user/pamela/src/CVS/chewbacca/PamOffLineSW/techmodel/McmdReader.cpp,v 1.2 2008-10-01 09:53:42 mocchiut Exp $\n"; } /** * Initialize the algorithm with a special run. This will initialize the * event reader routines for all packet types. */ void McmdReader::Init(PamelaRun *run) { // logger->debug(_T("Initialize")); // SetInputStream(run); run->WriteSubPacket(this, &Mcmd, Mcmd->Class()); } /** * Unpack the Mcmd event * Each subpacket is prafaceded by 4 OBT bytes. * The elementar structure is a kind of * --------CPU - OBT--------------------------------- * OBT - 4 Bytes * --------Start Sub-Packet--------------------------------- * SeqID - 2 Bytes * T - 1 bit | spare - 7 bits | Mcmd-ID - 1 byte * Spare - 4 bits | Mcmd Lenght 12 bits * Time Tag - 4 Bytes * DATA - McmdLength * 2 Bytes * don't care - 1 Byte * END-ID - 1 Byte is the sum of subPacket Bytes module 256 * --------End Sub-Packet--------------------------------- * --------CPU CRC-16 on OBT + subPacket--------------------------------- * subCRC - 2 Bytes * this structure is repeated one or more times. * The last 2 Bytes are CRC16 computed by CPU on all previous (OBT + subpacket data + subCRC) repetitions * @Event Number * @length is the size in bytes of the event (or packet) */ void McmdReader::PKT_RunEvent(char* mysubData, long int length) throw (WrongCRCException_PKTUsed) { stringstream oss; string msg; int i = 0; const int obt_len = 4; const int subHeader_len = 10; const int subTrailer_len = 2; const int subPckCRC_len = 2; long int dataLength = 0; char OBT[obt_len] = { 0 }; char subHeader[subHeader_len] = { 0 }; char subTrailer[subTrailer_len] = { 0 }; char subPckCRC[subPckCRC_len] = { 0 }; char* subData = NULL; UINT16 subCRC = 0; //CRC of the subpacket (updated as subPckt is read) UINT16 readCRC = 0; //CRC read from the subpacket UINT16 partialCRC = 0; //partial CRC updated as mcmd packet is read (to compare with CRC read in the total Mcmd header) McmdRecord *rec; Mcmd->Records->Clear(); TClonesArray &recs = *(Mcmd->Records); int start = 0; // while(start < (length)) { // printf(" %i => %X \n",start,(UINT8)mysubData[start]); // start++; // }; // start=0; while (start < (length - 2 - obt_len - subTrailer_len - subTrailer_len - subPckCRC_len)) // while(start < (length-2)) { // printf(" 1data %X \n",(UINT8)mysubData[start]); //Read the OBT preceeding the subpacket then calculate a partial CRC for it //and update the partialCRC for (int m = start; m < start + obt_len; m++) { OBT[m - start] = mysubData[m]; } start += obt_len; // printf(" 2data %X \n",(UINT8)mysubData[start]); // printf(" 2data %X \n",(UINT8)mysubData[start]+1); subCRC = CM_Compute_CRC16(0, (BYTE*) &OBT, obt_len); partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) &OBT, obt_len); //Read the header for the subPacket and read mcmdLength //12 is the total lenght of subHeader + subTrailer for (int m = start; m < start + subHeader_len; m++) { subHeader[m - start] = mysubData[m]; } start += subHeader_len; // printf(" 3data %X \n",(UINT8)mysubData[start]); // printf(" 3data %X \n",(UINT8)mysubData[start+1]); subCRC = CM_Compute_CRC16(subCRC, (BYTE*) &subHeader, subHeader_len); partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) &subHeader, subHeader_len); dataLength = (((0x0fff) & ((UINT16)subHeader[4])) << 8 | ((UINT16)subHeader[5]) * 2) - subHeader_len - subTrailer_len; // printf(" datalenght = %i subh 4 %X subd 5 %X \n",dataLength,(UINT8)subHeader[4],(UINT8)subHeader[5]); //the line below is exactly how it was in the original version if (dataLength < 0) break; //it should throw an exception ***TBD*** //I add also this check if (dataLength + start > (length - 2 - subTrailer_len - subPckCRC_len)) { oss.str(""); oss << "MCMD: Error in the MCMD Packet lenght, it is not " << length; msg = oss.str(); PamOffLineSW::mainLogUtil->logWarning(msg); break; //it should throw an exception ***TBD*** } //read subpacket data according to data length then calculate partial CRC for data //and update the partialCRC subData = new char[dataLength]; for (int m = start; m < start + dataLength; m++) { subData[m - start] = mysubData[m]; } start += dataLength; // printf(" 4data %X \n",(UINT8)mysubData[start]); // printf(" 4data %X \n",(UINT8)mysubData[start+1]); for (int jj = 0; jj < dataLength; jj++) { subCRC = CM_Compute_CRC16(subCRC, (BYTE*) (subData + jj), 1); partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) (subData + jj), 1); } //Read the CRC inside of MCMD //To check sum of all sub packet data, module 256 ****TBD**** for (int m = start; m < start + subTrailer_len; m++) { subTrailer[m - start] = mysubData[m]; } start += subTrailer_len; // printf(" 5data %X \n",(UINT8)mysubData[start]); // printf(" 5data %X \n",(UINT8)mysubData[start+1]); subCRC = CM_Compute_CRC16(subCRC, (BYTE*) &subTrailer, 2); partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) &subTrailer, 2); //Read the CRC of subPacket for (int m = start; m < start + subPckCRC_len; m++) { subPckCRC[m - start] = mysubData[m]; } start += subPckCRC_len; partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) &subPckCRC, 2); readCRC = (((BYTE)subPckCRC[0]) << 8) + ((BYTE)subPckCRC[1]); //finally check if the RecordCRC is correct //and finally update the partialCRC //TO DO - if one CRC is wrong also the total one will be corrupted // printf(" subCRC %X readCRC %X \n",subCRC,readCRC); if (subCRC == readCRC) { rec = new (recs[i++]) McmdRecord(); //aggiungo un nuovo McmdRecord all'evento rec->MCMD_RECORD_OBT = (((UINT32)OBT[0] << 24) & 0xFF000000) + (((UINT32)OBT[1] << 16) & 0x00FF0000) + (((UINT32)OBT[2] << 8) & 0x0000FF00) + (((UINT32)OBT[3]) & 0x000000FF); rec->SeqID = (((BYTE)subHeader[0] << 8) & 0xFF00) + (((BYTE)subHeader[1]) & 0x00FF); rec->Tbit = ((BYTE)((subHeader[2] & 0x80)) >> 7); rec->ID1 = (BYTE)subHeader[3]; rec->McmdLength = (0x0fff) & (((UINT16)(subHeader[4] << 8)) + ((UINT16)subHeader[5])); rec->TimeTag = (((UINT32)subHeader[6] << 24) & 0xFF000000) + (((UINT32)subHeader[7] << 16) & 0x00FF0000) + (((UINT32)subHeader[8] << 8) & 0x0000FF00) + (((UINT32)subHeader[9]) & 0x000000FF); rec->endID = (BYTE)subTrailer[1]; rec->McmdData = new TArrayC(dataLength, subData); // delete [] subData; } else { oss.str(""); oss << "Wrong CRC on Subpacket internal to MCMD Packet "; msg = oss.str(); PamOffLineSW::mainLogUtil->logAll(msg); } delete[] subData; } if (start != length - 2) { oss.str(""); oss << "MCMD: Error in the MCMD Packet lenght (start!=length-2), it is not " << length; msg = oss.str(); PamOffLineSW::mainLogUtil->logWarning(msg); } //in the end compare the calculated partial CRC with the MCMD packet CRC readCRC = (((UINT16)(mysubData[length - 2] << 8)) & 0xFF00) + (((UINT16)mysubData[length - 1]) & 0x00FF); //readCRC = (((UINT16)(mysubData[length - 1]<<8))&0xFF00) + (((UINT16)mysubData[length])&0x00FF); // // printf(" CICCIOEND readCRC %X partialCRC %X \n",(UINT16)readCRC,(UINT16)partialCRC); // if(partialCRC != readCRC) throw WrongCRCException(" Wrong Global CRC for MCMD Packet "); if (partialCRC != readCRC) { oss.str(""); oss << "Wrong CRC for MCMD Packet: " << " CRC COMPUTED= " << partialCRC << " CRC READ= " << readCRC; msg = oss.str(); PamOffLineSW::mainLogUtil->logWarning(msg); throw WrongCRCException_PKTUsed(" Wrong CRC for MCMD Packet. "); }; }