| 1 | kusanagi | 1.1 | /** @file | 
| 2 | kusanagi | 1.2 | * $Author: kusanagi $ | 
| 3 |  |  | * $Date: 2004/07/06 12:20:23 $ | 
| 4 |  |  | * $Revision: 1.1.1.1 $ | 
| 5 | kusanagi | 1.1 | * | 
| 6 |  |  | * Implementation of the functions of a sample Algorithm class. | 
| 7 |  |  | * This file can be used as a templace to develop your own algorithm. | 
| 8 |  |  | */ | 
| 9 |  |  |  | 
| 10 |  |  | #include <log4cpp/Category.hh> | 
| 11 |  |  | #include <fstream> | 
| 12 |  |  | #include "TechmodelAlgorithm.h" | 
| 13 |  |  | #include "EventReader.h" | 
| 14 |  |  | #include "ReaderAlgorithms.h" | 
| 15 |  |  | #include "Exception.h" | 
| 16 |  |  | #include "stdio.h" | 
| 17 |  |  | extern "C" { | 
| 18 |  |  | #include "CRC.h" | 
| 19 |  |  | } | 
| 20 |  |  |  | 
| 21 |  |  | #define BYTE unsigned char | 
| 22 |  |  |  | 
| 23 |  |  | using namespace pamela; | 
| 24 |  |  | using namespace pamela::techmodel; | 
| 25 |  |  |  | 
| 26 |  |  | static log4cpp::Category& cat = log4cpp::Category::getInstance("pamela.techmodel.EventReader"); | 
| 27 |  |  | static unsigned int prevPckCounter = 0; | 
| 28 |  |  | static unsigned int prevPckOBT     = 0; | 
| 29 |  |  | /** | 
| 30 |  |  | * Constructor. | 
| 31 |  |  | */ | 
| 32 |  |  | EventReader::EventReader(void): | 
| 33 |  |  | TechmodelAlgorithm(0, "TechmodelEventReader") { | 
| 34 |  |  | cat <<  log4cpp::Priority::DEBUG | 
| 35 |  |  | <<  "Constructor " | 
| 36 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 37 |  |  | Header = new EventHeader(); | 
| 38 |  |  | /* | 
| 39 |  |  |  | 
| 40 |  |  |  | 
| 41 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Alarm, | 
| 42 |  |  | new AlarmReader())); | 
| 43 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Khb, | 
| 44 |  |  | new KhbReader())); | 
| 45 |  |  | */ | 
| 46 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Physics,    new PhysicsReader())); | 
| 47 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::ForcedPkt,  new ForcedPktReader())); | 
| 48 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::RunHeader,  new RunHeaderReader())); | 
| 49 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::RunTrailer, new RunTrailerReader())); | 
| 50 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Log,      new LogReader())); | 
| 51 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::VarDump,  new VarDumpReader())); | 
| 52 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::ArrDump,  new ArrDumpReader())); | 
| 53 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TabDump,  new TabDumpReader())); | 
| 54 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Tmtc,     new TmtcReader())); | 
| 55 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Mcmd,     new McmdReader())); | 
| 56 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibCal, new CalibCalReader())); | 
| 57 | kusanagi | 1.2 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibTrk1, new CalibTrk1Reader())); | 
| 58 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibTrk2, new CalibTrk2Reader())); | 
| 59 | kusanagi | 1.1 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibTrd, new CalibTrdReader())); | 
| 60 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibTof, new CalibTofReader())); | 
| 61 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibS4,  new CalibS4Reader())); | 
| 62 |  |  | /* | 
| 63 |  |  | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::HA_Header_E5, | 
| 64 |  |  | new E5Reader())); | 
| 65 |  |  | */ | 
| 66 |  |  | } | 
| 67 |  |  |  | 
| 68 |  |  | /** | 
| 69 |  |  | * Get a string with the version info of the algorithm. | 
| 70 |  |  | */ | 
| 71 |  |  | std::string EventReader::GetVersionInfo(void) const { | 
| 72 |  |  | return | 
| 73 | kusanagi | 1.2 | "$Header: /home/cvsmanager/yoda/techmodel/EventReader.cpp,v 1.1.1.1 2004/07/06 12:20:23 kusanagi Exp $\n"; | 
| 74 | kusanagi | 1.1 | } | 
| 75 |  |  |  | 
| 76 |  |  | /** | 
| 77 |  |  | * Initialize the algorithm with a special run. This will initialize the | 
| 78 |  |  | * event reader routines for all packet types. | 
| 79 |  |  | */ | 
| 80 |  |  | void EventReader::Init(PamelaRun *run) { | 
| 81 |  |  | SetInputStream(run); | 
| 82 |  |  |  | 
| 83 |  |  | //Create the structure of directories and create xxx.Header.root files | 
| 84 |  |  | run->WriteHeaders(this, &Header); | 
| 85 |  |  |  | 
| 86 |  |  | //Create the xxx.root in it's specific directory | 
| 87 |  |  | for (AlgorithmMap::iterator i = TechmodelAlgorithmMap.begin(); | 
| 88 |  |  | i != TechmodelAlgorithmMap.end(); i++) { | 
| 89 |  |  | cat  <<  log4cpp::Priority::DEBUG | 
| 90 |  |  | <<  " Initializing algo " << i->second->GetAlgorithmName() | 
| 91 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 92 |  |  | i->second->Init(run); | 
| 93 |  |  | } | 
| 94 |  |  | Run = dynamic_cast<TechmodelPamelaRun*>(run); | 
| 95 |  |  | } | 
| 96 |  |  |  | 
| 97 |  |  | static void SkipToNextHeader(ifstream *); | 
| 98 |  |  |  | 
| 99 |  |  | /** | 
| 100 |  |  | * Read the next event header, call the reader algorithms that | 
| 101 |  |  | * correspond to its packet type, and read the event trailer. | 
| 102 |  |  | */ | 
| 103 |  |  |  | 
| 104 |  |  | // 15 June 2004 ---note------------------ | 
| 105 |  |  | // A nice refacoring would require to not read again the packet data (which is | 
| 106 |  |  | // read in the UnpackPscuHeader() and put directly in the | 
| 107 |  |  | // EventAlgorithm->RunEvent(....) directly the data inside the packet.... will see later.... | 
| 108 |  |  | // 15 June 2004 ---note------------------ | 
| 109 |  |  | void EventReader::RunEvent(int EventNumber) { | 
| 110 |  |  |  | 
| 111 |  |  | cat <<  log4cpp::Priority::ERROR <<  "Start Unpacking........" | 
| 112 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 113 |  |  | //for now i'll suppose that the raw file starts immediately with the right bytes | 
| 114 |  |  | //to insert a GetPacketStart() | 
| 115 |  |  | while (!InputFile->eof()){ | 
| 116 |  |  | try { | 
| 117 |  |  | if (FindStart()) { | 
| 118 |  |  | if(UnpackPscuHeader()){ | 
| 119 |  |  | const PacketType* type = Header->GetPscuHeader()->GetPacketType(); | 
| 120 |  |  | AlgorithmMap::iterator i = TechmodelAlgorithmMap.find(type); | 
| 121 |  |  | if (i != TechmodelAlgorithmMap.end()) { | 
| 122 |  |  | TechmodelAlgorithm *EventAlgorithm = i->second; | 
| 123 |  |  | EventAlgorithm->RunEvent(EventNumber, Header->GetPscuHeader()->GetPacketLenght()); | 
| 124 |  |  | Run->FillTrees(type); | 
| 125 |  |  | Header->GetCounter()->Increment(type); | 
| 126 |  |  | } else { | 
| 127 |  |  | cat <<  log4cpp::Priority::ERROR | 
| 128 |  |  | <<  "No way to read events of type" << type->GetName() | 
| 129 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 130 |  |  | throw Exception("No way to read events of type " + type->GetName()); | 
| 131 |  |  | } | 
| 132 |  |  | } //else { | 
| 133 |  |  | //**TO BE DONE**   <<WRONG CRC l --- LOST PACKET>>// | 
| 134 |  |  | //Have to be defined a "WrongCRC" packet::Type? | 
| 135 |  |  | //} | 
| 136 |  |  | } | 
| 137 |  |  | } catch (...) { | 
| 138 |  |  | //This have to be more detailed. More exceptions type are needed. | 
| 139 |  |  | cat <<  log4cpp::Priority::ERROR <<  "Couldn't read the event. Skipping to the next header." | 
| 140 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 141 |  |  | } | 
| 142 |  |  | } | 
| 143 |  |  | Header->GetCounter()->PrintCounters(); | 
| 144 |  |  | } | 
| 145 |  |  |  | 
| 146 |  |  | static void SkipToNextHeader(ifstream* TechmodelFile) { | 
| 147 |  |  | //  yeah. | 
| 148 |  |  | } | 
| 149 |  |  |  | 
| 150 |  |  |  | 
| 151 |  |  |  | 
| 152 |  |  | /** | 
| 153 |  |  | * Unpack the PSCU header from a file into the structure. | 
| 154 |  |  | */ | 
| 155 |  |  | int EventReader::UnpackPscuHeader(void) throw (std::exception) { | 
| 156 |  |  | int response; | 
| 157 |  |  | char buff[16]; | 
| 158 |  |  | InputFile->read(buff, sizeof(buff)); | 
| 159 |  |  |  | 
| 160 |  |  | prevPckCounter = 0; | 
| 161 |  |  | prevPckOBT     = 0; | 
| 162 |  |  |  | 
| 163 |  |  | unsigned char PacketId1    = buff[3]; | 
| 164 |  |  | unsigned char PacketId2    = buff[4]; | 
| 165 |  |  | unsigned int  Counter      = (((UINT32)buff[5]<<16)&0x00FF0000) + (((UINT32)buff[6]<<8)&0x0000FF00) + (((UINT32)buff[7])&0x000000FF); | 
| 166 |  |  | unsigned int  OrbitalTime  = (((UINT32)buff[8]<<24)&0xFF000000) + (((UINT32)buff[9]<<16)&0x00FF0000) +  (((UINT32)buff[10]<<8)&0x0000FF00) + (((UINT32)buff[11])&0x000000FF); | 
| 167 |  |  | unsigned int  PacketLenght = (((UINT32)buff[12]<<16)&0x00FF0000) +  (((UINT32)buff[13]<<8)&0x0000FF00) + (((UINT32)buff[14])&0x000000FF); | 
| 168 |  |  | unsigned char CRC          = buff[15]; | 
| 169 |  |  |  | 
| 170 |  |  | if (Counter < prevPckCounter){ | 
| 171 |  |  | cat <<  log4cpp::Priority::ERROR | 
| 172 |  |  | <<  " Packet counter is less than before of " << (prevPckCounter - Counter) | 
| 173 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 174 |  |  | } | 
| 175 |  |  |  | 
| 176 |  |  | if (OrbitalTime < prevPckOBT){ | 
| 177 |  |  | cat <<  log4cpp::Priority::WARN | 
| 178 |  |  | <<  " Orbital Time is less than before of " << (prevPckOBT - OrbitalTime) | 
| 179 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 180 |  |  | } | 
| 181 |  |  |  | 
| 182 |  |  |  | 
| 183 |  |  | if ((BYTE)CM_Compute_CRC16(0, (BYTE*)&buff, 15) == (BYTE)buff[15]){ | 
| 184 |  |  | long int initPos = InputFile->tellg(); | 
| 185 |  |  | long int finalPos; | 
| 186 |  |  | Header->GetPscuHeader()->SetPacketId(PacketId1, PacketId2); | 
| 187 |  |  | Header->GetPscuHeader()->SetCounter(Counter); | 
| 188 |  |  | Header->GetPscuHeader()->SetOrbitalTime(OrbitalTime); | 
| 189 |  |  | //PacketLength is the length of the whole DATApacket starting from the first byte after the header | 
| 190 |  |  | //plus the CRC legth (which varies for each type of packet) | 
| 191 |  |  | Header->GetPscuHeader()->SetPacketLenght(PacketLenght); | 
| 192 |  |  | Header->GetPscuHeader()->SetCRC(CRC); | 
| 193 |  |  |  | 
| 194 |  |  | //commented out because of the above test code | 
| 195 |  |  | InputFile->seekg(Header->GetPscuHeader()->GetPacketLenght(), std::ios::cur); | 
| 196 |  |  | FindStart(); | 
| 197 |  |  | finalPos =  (long int)InputFile->tellg() - (1 + initPos + (long int)(Header->GetPscuHeader()->GetPacketLenght())); | 
| 198 |  |  | if(finalPos == 0){ | 
| 199 |  |  | cat <<  log4cpp::Priority::INFO <<  " Correct packet length \n" | 
| 200 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 201 |  |  | } | 
| 202 |  |  | if (finalPos > 0 && finalPos < 64) { | 
| 203 |  |  | cat <<  log4cpp::Priority::WARN | 
| 204 |  |  | <<  " Correct packet length: Padded of " << finalPos << " bytes \n" | 
| 205 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 206 |  |  | } | 
| 207 |  |  | if (finalPos > 64){ | 
| 208 |  |  | cat <<  log4cpp::Priority::ERROR <<  " Wrong packet length? (because of wrong padding?) \n" | 
| 209 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 210 |  |  | } | 
| 211 |  |  | InputFile->seekg(initPos, std::ios::beg); | 
| 212 |  |  | response =  true; | 
| 213 |  |  | } else { | 
| 214 |  |  | cat <<  log4cpp::Priority::ERROR <<  " WRONG CRC FOR HEADER " | 
| 215 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 216 |  |  | response =  false; | 
| 217 |  |  | } | 
| 218 |  |  |  | 
| 219 |  |  | char tmpId1[4]; | 
| 220 |  |  | char tmpId2[4]; | 
| 221 |  |  | char tmpLength[12]; | 
| 222 |  |  | char tmpStart[100]; | 
| 223 |  |  | char tmpCRC[4]; | 
| 224 |  |  | sprintf(tmpId1, "%02X", PacketId1); | 
| 225 |  |  | sprintf(tmpId2, "%02X", PacketId2); | 
| 226 |  |  | sprintf(tmpLength, "%06X", PacketLenght); | 
| 227 |  |  | sprintf(tmpStart, "%X", ((long int)(InputFile->tellg()) - 16)); | 
| 228 |  |  | sprintf(tmpCRC, "%02X", CRC); | 
| 229 |  |  | cat <<  log4cpp::Priority::INFO | 
| 230 |  |  | <<  "\n Packet Counter (decimal) : "  <<  Counter | 
| 231 |  |  | <<  "\n Id1 - Id2                : "  <<  tmpId1 <<  " - " <<  tmpId2 | 
| 232 |  |  | <<  "\n Orbital Time (decimal)   : "  <<  OrbitalTime | 
| 233 |  |  | <<  "\n Lenght                   : "  <<  tmpLength | 
| 234 |  |  | <<  "\n CRC                      : "  <<  tmpCRC | 
| 235 |  |  | <<  "\n Header Start Position    : "  <<  tmpStart | 
| 236 |  |  | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 237 |  |  | return response; | 
| 238 |  |  | } | 
| 239 |  |  |  | 
| 240 |  |  | /** | 
| 241 |  |  | * Unpack the trailer of a PSCU event into the structure. | 
| 242 |  |  | */ | 
| 243 |  |  | void EventReader::UnpackPscuTrailer(void) throw (std::exception) { | 
| 244 |  |  |  | 
| 245 |  |  | } | 
| 246 |  |  |  | 
| 247 |  |  | /** | 
| 248 |  |  | * Find the next starting poin for the PSCU event looking for a {0xFA, 0xFE, 0xDE} sequence | 
| 249 |  |  | */ | 
| 250 |  |  | int EventReader::FindStart(void) throw (std::exception) { | 
| 251 |  |  | //search an hexadecimal sequence in a file | 
| 252 |  |  | //subSign    ------> pointer to the sequence buffer | 
| 253 |  |  | //subSignDim ------> dimension of the buffer | 
| 254 |  |  | // at exit | 
| 255 |  |  | // return true if founds a match (else false) | 
| 256 |  |  | // subF point rigth after the match, if found. Else EOF. | 
| 257 |  |  | //Maurizio 15/11/2002----------------------- | 
| 258 |  |  | const unsigned char subSign[3]={0xFA, 0xFE, 0xDE}; | 
| 259 |  |  | int subSignDim = 3; | 
| 260 |  |  | //------------------------------------------ | 
| 261 |  |  | int subIndex = 0; | 
| 262 |  |  | char dataByte; | 
| 263 |  |  | /*InputFile->read(fileByte, 1); | 
| 264 |  |  | if ( *fileByte ==  *(subSign+subIndex)){ | 
| 265 |  |  | if (subIndex++ == (subSignDim-1)) { | 
| 266 |  |  | InputFile->seekg(-(subIndex), std::ios::cur); | 
| 267 |  |  | return 1; | 
| 268 |  |  | } | 
| 269 |  |  | }*/ | 
| 270 |  |  | while (!InputFile->eof()) { | 
| 271 |  |  | InputFile->get(dataByte); | 
| 272 |  |  | if (dataByte == (char)(*(subSign+subIndex))){ | 
| 273 |  |  | if (subIndex++ == (subSignDim-1)) { | 
| 274 |  |  | InputFile->seekg(-(subIndex), std::ios::cur); | 
| 275 |  |  | return 1; | 
| 276 |  |  | } | 
| 277 |  |  | } else { | 
| 278 |  |  | if (InputFile->eof()) { | 
| 279 |  |  | throw Exception("Extra bytes over the last packets"); | 
| 280 |  |  | } else { | 
| 281 |  |  | return 0; | 
| 282 |  |  | } | 
| 283 |  |  | //InputFile->seekg(-(subIndex+1), std::ios::cur); | 
| 284 |  |  | //subIndex = 0; | 
| 285 |  |  | } | 
| 286 |  |  | } | 
| 287 |  |  | return 0; | 
| 288 |  |  | } | 
| 289 |  |  |  | 
| 290 |  |  | ClassImp(EventReader) |