| 1 | 
/** @file | 
| 2 | 
 * $Source: /afs/ba.infn.it/user/pamela/src/CVS/chewbacca/PamOffLineSW/techmodel/McmdReader.cpp,v $ | 
| 3 | 
 * $Id: McmdReader.cpp,v 1.4 2009/09/30 12:21:38 mocchiut Exp $ | 
| 4 | 
 * $Author: mocchiut $ | 
| 5 | 
 * | 
| 6 | 
 * Implementation of the McmdReader class. | 
| 7 | 
 */ | 
| 8 | 
 | 
| 9 | 
extern "C" { | 
| 10 | 
#include "CRC.h" | 
| 11 | 
} | 
| 12 | 
#include "ReaderAlgorithms.h" | 
| 13 | 
using namespace pamela::techmodel; | 
| 14 | 
 | 
| 15 | 
/** | 
| 16 | 
 * Constructor. | 
| 17 | 
 */ | 
| 18 | 
McmdReader::McmdReader(void) : | 
| 19 | 
  TechmodelAlgorithm(PacketType::Mcmd, "Mcmd") { | 
| 20 | 
  Mcmd = new McmdEvent(); | 
| 21 | 
} | 
| 22 | 
 | 
| 23 | 
/** | 
| 24 | 
 * Get a string with the version info of the algorithm. | 
| 25 | 
 */ | 
| 26 | 
std::string McmdReader::GetVersionInfo(void) const { | 
| 27 | 
  return "$Header: /afs/ba.infn.it/user/pamela/src/CVS/chewbacca/PamOffLineSW/techmodel/McmdReader.cpp,v 1.4 2009/09/30 12:21:38 mocchiut Exp $\n"; | 
| 28 | 
} | 
| 29 | 
 | 
| 30 | 
/** | 
| 31 | 
 * Initialize the algorithm with a special run. This will initialize the | 
| 32 | 
 * event reader routines for all packet types. | 
| 33 | 
 */ | 
| 34 | 
void McmdReader::Init(PamelaRun *run) { | 
| 35 | 
  // logger->debug(_T("Initialize")); | 
| 36 | 
  // SetInputStream(run); | 
| 37 | 
  run->WriteSubPacket(this, &Mcmd, Mcmd->Class()); | 
| 38 | 
} | 
| 39 | 
 | 
| 40 | 
/** | 
| 41 | 
 * Unpack the Mcmd event | 
| 42 | 
 *  Each subpacket is prafaceded by 4 OBT bytes. | 
| 43 | 
 *  The elementar structure is a kind of | 
| 44 | 
 * --------CPU - OBT--------------------------------- | 
| 45 | 
 *  OBT     - 4 Bytes | 
| 46 | 
 * --------Start Sub-Packet--------------------------------- | 
| 47 | 
 *  SeqID  - 2 Bytes | 
| 48 | 
 *  T          - 1 bit       | spare  - 7 bits | Mcmd-ID - 1 byte | 
| 49 | 
 *  Spare  - 4 bits     | Mcmd Lenght 12 bits | 
| 50 | 
 *  Time Tag      - 4 Bytes | 
| 51 | 
 *  DATA            - McmdLength * 2 Bytes | 
| 52 | 
 *  don't care    - 1 Byte | 
| 53 | 
 *  END-ID         - 1 Byte is the sum of subPacket Bytes module 256 | 
| 54 | 
 * --------End Sub-Packet--------------------------------- | 
| 55 | 
 * --------CPU CRC-16 on OBT + subPacket--------------------------------- | 
| 56 | 
 * subCRC        - 2 Bytes | 
| 57 | 
 * this structure is repeated one or more times. | 
| 58 | 
 * The last 2 Bytes are CRC16 computed by CPU on all previous (OBT + subpacket data + subCRC) repetitions | 
| 59 | 
 | 
| 60 | 
 * @Event Number | 
| 61 | 
 * @length is the size in bytes of the event (or packet) | 
| 62 | 
 */ | 
| 63 | 
void McmdReader::PKT_RunEvent(char* mysubData, long int length) throw (WrongCRCException_PKTUsed) { | 
| 64 | 
  stringstream oss; | 
| 65 | 
  string msg; | 
| 66 | 
 | 
| 67 | 
  int i = 0; | 
| 68 | 
  const int obt_len = 4; | 
| 69 | 
  const int subHeader_len = 10; | 
| 70 | 
  const int subTrailer_len = 2; | 
| 71 | 
  const int subPckCRC_len = 2; | 
| 72 | 
  long int dataLength = 0; | 
| 73 | 
 | 
| 74 | 
  char OBT[obt_len] = { 0 }; | 
| 75 | 
  char subHeader[subHeader_len] = { 0 }; | 
| 76 | 
  char subTrailer[subTrailer_len] = { 0 }; | 
| 77 | 
  char subPckCRC[subPckCRC_len] = { 0 }; | 
| 78 | 
  char* subData = NULL; | 
| 79 | 
 | 
| 80 | 
  UINT16 subCRC = 0; //CRC of the subpacket (updated as subPckt is read) | 
| 81 | 
  UINT16 readCRC = 0; //CRC read from the subpacket | 
| 82 | 
  UINT16 partialCRC = 0; //partial CRC updated as mcmd packet is read (to compare with CRC read in the total Mcmd header) | 
| 83 | 
  McmdRecord *rec; | 
| 84 | 
 | 
| 85 | 
  Mcmd->Records->Clear(); | 
| 86 | 
  TClonesArray &recs = *(Mcmd->Records); | 
| 87 | 
 | 
| 88 | 
  int start = 0; | 
| 89 | 
  //    while(start < (length)) { | 
| 90 | 
  //      printf(" %i => %X \n",start,(UINT8)mysubData[start]); | 
| 91 | 
  //      start++; | 
| 92 | 
  //    }; | 
| 93 | 
  //    start=0; | 
| 94 | 
 | 
| 95 | 
  while (start < (length - 2 - obt_len - subTrailer_len - subTrailer_len - subPckCRC_len)) | 
| 96 | 
  //    while(start < (length-2)) | 
| 97 | 
  { | 
| 98 | 
    //    printf(" 1data %X \n",(UINT8)mysubData[start]); | 
| 99 | 
    //Read the OBT preceeding the subpacket then calculate a partial CRC for it | 
| 100 | 
    //and update the partialCRC | 
| 101 | 
    for (int m = start; m < start + obt_len; m++) { | 
| 102 | 
      OBT[m - start] = mysubData[m]; | 
| 103 | 
    } | 
| 104 | 
    start += obt_len; | 
| 105 | 
 | 
| 106 | 
    //    printf(" 2data %X \n",(UINT8)mysubData[start]); | 
| 107 | 
    //    printf(" 2data %X \n",(UINT8)mysubData[start]+1); | 
| 108 | 
    subCRC = CM_Compute_CRC16(0, (BYTE*) &OBT, obt_len); | 
| 109 | 
    partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) &OBT, obt_len); | 
| 110 | 
    //Read the header for the subPacket and read mcmdLength | 
| 111 | 
    //12 is the total lenght of subHeader + subTrailer | 
| 112 | 
    for (int m = start; m < start + subHeader_len; m++) { | 
| 113 | 
      subHeader[m - start] = mysubData[m]; | 
| 114 | 
    } | 
| 115 | 
    start += subHeader_len; | 
| 116 | 
 | 
| 117 | 
    //    printf(" 3data %X \n",(UINT8)mysubData[start]); | 
| 118 | 
    //    printf(" 3data %X \n",(UINT8)mysubData[start+1]); | 
| 119 | 
    subCRC = CM_Compute_CRC16(subCRC, (BYTE*) &subHeader, subHeader_len); | 
| 120 | 
    partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) &subHeader, subHeader_len); | 
| 121 | 
    dataLength = (((0x0fff) & ((UINT16)subHeader[4])) << 8 | ((UINT16)subHeader[5]) * 2) - subHeader_len | 
| 122 | 
        - subTrailer_len; | 
| 123 | 
    //      printf(" datalenght = %i  subh 4 %X subd 5 %X \n",dataLength,(UINT8)subHeader[4],(UINT8)subHeader[5]); | 
| 124 | 
    //the line below is exactly how it was in the original version | 
| 125 | 
    if (dataLength < 0) | 
| 126 | 
      break; //it should throw an exception ***TBD*** | 
| 127 | 
    //I add also this check | 
| 128 | 
    if (dataLength + start > (length - 2 - subTrailer_len - subPckCRC_len)) { | 
| 129 | 
      oss.str(""); | 
| 130 | 
      oss << "MCMD: Error in the MCMD Packet lenght, it is not " << length; | 
| 131 | 
      msg = oss.str(); | 
| 132 | 
      PamOffLineSW::mainLogUtil->logWarning(msg); | 
| 133 | 
      break; //it should throw an exception ***TBD*** | 
| 134 | 
    } | 
| 135 | 
 | 
| 136 | 
    //read subpacket data according to data length then calculate partial CRC for data | 
| 137 | 
    //and update the partialCRC | 
| 138 | 
 | 
| 139 | 
    subData = new char[dataLength]; | 
| 140 | 
    for (int m = start; m < start + dataLength; m++) { | 
| 141 | 
      subData[m - start] = mysubData[m]; | 
| 142 | 
    } | 
| 143 | 
    start += dataLength; | 
| 144 | 
 | 
| 145 | 
    //    printf(" 4data %X \n",(UINT8)mysubData[start]); | 
| 146 | 
    //    printf(" 4data %X \n",(UINT8)mysubData[start+1]); | 
| 147 | 
    for (int jj = 0; jj < dataLength; jj++) { | 
| 148 | 
      subCRC = CM_Compute_CRC16(subCRC, (BYTE*) (subData + jj), 1); | 
| 149 | 
      partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) (subData + jj), 1); | 
| 150 | 
    } | 
| 151 | 
 | 
| 152 | 
    //Read the CRC inside of MCMD | 
| 153 | 
    //To check sum of all sub packet data, module 256 ****TBD**** | 
| 154 | 
    for (int m = start; m < start + subTrailer_len; m++) { | 
| 155 | 
      subTrailer[m - start] = mysubData[m]; | 
| 156 | 
    } | 
| 157 | 
    start += subTrailer_len; | 
| 158 | 
    //     printf(" 5data %X \n",(UINT8)mysubData[start]); | 
| 159 | 
    //     printf(" 5data %X \n",(UINT8)mysubData[start+1]); | 
| 160 | 
 | 
| 161 | 
    subCRC = CM_Compute_CRC16(subCRC, (BYTE*) &subTrailer, 2); | 
| 162 | 
    partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) &subTrailer, 2); | 
| 163 | 
    //Read the CRC of subPacket | 
| 164 | 
    for (int m = start; m < start + subPckCRC_len; m++) { | 
| 165 | 
      subPckCRC[m - start] = mysubData[m]; | 
| 166 | 
    } | 
| 167 | 
    start += subPckCRC_len; | 
| 168 | 
 | 
| 169 | 
    partialCRC = CM_Compute_CRC16(partialCRC, (BYTE*) &subPckCRC, 2); | 
| 170 | 
    readCRC = (((BYTE)subPckCRC[0]) << 8) + ((BYTE)subPckCRC[1]); | 
| 171 | 
 | 
| 172 | 
    //finally check if the RecordCRC is correct | 
| 173 | 
    //and finally update the partialCRC | 
| 174 | 
    //TO DO - if one CRC is wrong also the total one will be corrupted | 
| 175 | 
    //     printf(" subCRC %X readCRC %X \n",subCRC,readCRC); | 
| 176 | 
    //    if (subCRC == readCRC) { // BUG?! Emiliano 2009 10 01 | 
| 177 | 
      rec = new (recs[i++]) McmdRecord(); //aggiungo un nuovo McmdRecord all'evento | 
| 178 | 
      rec->MCMD_RECORD_OBT = (((UINT32)OBT[0] << 24) & 0xFF000000) + (((UINT32)OBT[1] << 16) & 0x00FF0000) | 
| 179 | 
          + (((UINT32)OBT[2] << 8) & 0x0000FF00) + (((UINT32)OBT[3]) & 0x000000FF); | 
| 180 | 
      rec->SeqID = (((BYTE)subHeader[0] << 8) & 0xFF00) + (((BYTE)subHeader[1]) & 0x00FF); | 
| 181 | 
      rec->Tbit = ((BYTE)((subHeader[2] & 0x80)) >> 7); | 
| 182 | 
      rec->ID1 = (BYTE)subHeader[3]; | 
| 183 | 
      rec->McmdLength = (0x0fff) & (((UINT16)(subHeader[4] << 8)) + ((UINT16)subHeader[5])); | 
| 184 | 
      rec->TimeTag = (((UINT32)subHeader[6] << 24) & 0xFF000000) + (((UINT32)subHeader[7] << 16) & 0x00FF0000) + (((UINT32)subHeader[8] | 
| 185 | 
          << 8) & 0x0000FF00) + (((UINT32)subHeader[9]) & 0x000000FF); | 
| 186 | 
      rec->endID = (BYTE)subTrailer[1]; | 
| 187 | 
 | 
| 188 | 
      rec->McmdData = new TArrayC(dataLength, subData); | 
| 189 | 
      //     delete [] subData; | 
| 190 | 
    if (subCRC == readCRC) { | 
| 191 | 
      rec->Mcmd_Block_crc_ok = 1; | 
| 192 | 
    } | 
| 193 | 
    else { | 
| 194 | 
      rec->Mcmd_Block_crc_ok = 0; | 
| 195 | 
      oss.str(""); | 
| 196 | 
      oss << "Wrong CRC on Subpacket internal to MCMD Packet "; | 
| 197 | 
      msg = oss.str(); | 
| 198 | 
      PamOffLineSW::mainLogUtil->logAll(msg); | 
| 199 | 
    } | 
| 200 | 
 | 
| 201 | 
    delete[] subData; | 
| 202 | 
  } | 
| 203 | 
 | 
| 204 | 
  if (start != length - 2) { | 
| 205 | 
    oss.str(""); | 
| 206 | 
    oss << "MCMD: Error in the MCMD Packet lenght (start!=length-2), it is not " << length; | 
| 207 | 
    msg = oss.str(); | 
| 208 | 
    PamOffLineSW::mainLogUtil->logWarning(msg); | 
| 209 | 
  } | 
| 210 | 
 | 
| 211 | 
  //in the end compare the calculated partial CRC with the MCMD packet CRC | 
| 212 | 
  readCRC = (((UINT16)(mysubData[length - 2] << 8)) & 0xFF00) + (((UINT16)mysubData[length - 1]) & 0x00FF); | 
| 213 | 
  //readCRC = (((UINT16)(mysubData[length - 1]<<8))&0xFF00) + (((UINT16)mysubData[length])&0x00FF); | 
| 214 | 
  // | 
| 215 | 
  //    printf(" CICCIOEND readCRC %X partialCRC %X \n",(UINT16)readCRC,(UINT16)partialCRC); | 
| 216 | 
  //    if(partialCRC != readCRC) throw WrongCRCException(" Wrong Global CRC for MCMD Packet "); | 
| 217 | 
  if (partialCRC != readCRC) { | 
| 218 | 
    Mcmd->Mcmd_crc_ok = 0; | 
| 219 | 
    oss.str(""); | 
| 220 | 
    oss << "Wrong CRC for MCMD Packet: " << " CRC COMPUTED= " << partialCRC << " CRC READ=  " << readCRC; | 
| 221 | 
    msg = oss.str(); | 
| 222 | 
    PamOffLineSW::mainLogUtil->logWarning(msg); | 
| 223 | 
    throw WrongCRCException_PKTUsed(" Wrong CRC for MCMD Packet. "); | 
| 224 | 
  } else { | 
| 225 | 
    Mcmd->Mcmd_crc_ok = 1; | 
| 226 | 
  } | 
| 227 | 
} | 
| 228 | 
 |