• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

roclib/src_sp605/Iterator.cxx (r4864/r3416)

Go to the documentation of this file.
00001 #include "sp605/Iterator.h"
00002 
00003 #include "sp605/Board.h"
00004 
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 
00009 sp605::Iterator::Iterator(int fmt) :
00010    fBoard(0),
00011    fFormat(fmt),
00012    fBuffer(0),
00013    fBufferLen(0),
00014    fBufferPos(0),
00015    fInterm(0),
00016    fIntermSize(0),
00017    fIntermFill(0),
00018    fSP605Id(0xffffffff),
00019    fKind(kindNone),
00020    fMsg(),
00021    fLastSenderId(0xffffffff),
00022    fRocMsg(),
00023    fLastRocEpoch(0)
00024 {
00025    for (int n=0;n<MaxSpadicId;n++)
00026       for (int g=0;g<MaxGroupId;g++)
00027          fLastEpoch[n][g] = 0;
00028 }
00029 
00030 sp605::Iterator::~Iterator()
00031 {
00032   if (fInterm) { free(fInterm); fInterm = 0; }
00033 }
00034 
00035 bool sp605::Iterator::assign(void* buf, unsigned sz)
00036 {
00037    fBuffer = buf;
00038    fBufferLen = sz;
00039    fBufferPos = 0;
00040    fKind = kindNone;
00041 
00042    return fBufferLen >= 8;
00043 }
00044 
00045 bool sp605::Iterator::nextBuffer(sp605::Board* brd, double tmout)
00046 {
00047    if (brd==0) return false;
00048 
00049    void *buf = 0;
00050    unsigned len = 0;
00051 
00052    if (!brd->getNextBuffer(buf, len, tmout)) return false;
00053 
00054    fFormat = brd->getMsgFormat();
00055 
00056    return assign(buf, len);
00057 }
00058 
00059 
00060 void sp605::Iterator::allocateInterm()
00061 {
00062    if (fInterm) { free(fInterm); fInterm = 0; }
00063 
00064    fInterm = malloc(128);
00065    fIntermSize = 128;
00066    fIntermFill = 0;
00067 }
00068 
00069 
00070 bool sp605::Iterator::next(double tmout)
00071 {
00072    //  if we had previous message set, clear data from intermediate buffer
00073    if (fKind != kindNone) fIntermFill = 0;
00074 
00075    fKind = kindNone;
00076 
00077    while (true) {
00078 
00079       if ((fBuffer==0) || (fBufferPos>=fBufferLen))
00080          if (!nextBuffer(fBoard, tmout)) return false;
00081 
00082       void* curr = (char*) fBuffer + fBufferPos;
00083 
00084       if (fFormat == formatSpadic10Direct) {
00085          // process direct format here
00086 
00087          unsigned rest_len = fBufferLen - fBufferPos;
00088 
00089          if (fIntermFill>0) {
00090             // this is case of cuted message, one need to extend buffer slowly by 2 bytes
00091 
00092             if ((rest_len<2) || (fIntermFill>=fIntermSize)) {
00093                printf("Internal error!!!\n");
00094                fBufferPos = fBufferLen;
00095                return false;
00096             }
00097             // append two bytes more
00098             memcpy((char*) fInterm + fIntermFill, curr, 2);
00099             fBufferPos+=2;
00100             fIntermFill+=2;
00101 
00102             unsigned msg_sz = fMsg.assign(fInterm, fIntermFill);
00103 
00104             if (msg_sz==0) return false;
00105 
00106             if (msg_sz>fIntermFill) continue;
00107 
00108          } else {
00109 
00110             unsigned msg_sz = fMsg.assign(curr, rest_len);
00111             if (msg_sz==0) return false;
00112 
00113             if (msg_sz > rest_len) {
00114                // keep part of message in intermediate buffer, continue reading
00115                if (fInterm==0) allocateInterm();
00116 
00117                if (fIntermSize < rest_len) {
00118                   printf("Internal buffer too short !!!!");
00119                   fBufferPos = fBufferLen;
00120                   return false;
00121                }
00122 
00123                memcpy(fInterm, curr, rest_len);
00124 
00125                fIntermFill = rest_len;
00126 
00127                continue; // try to get rest part of data
00128             }
00129 
00130             fBufferPos += msg_sz;
00131          }
00132 
00133          fKind = kindSpadic;
00134 
00135          // always use spadic 0 number
00136          fMsg.setSpadicNumber(0);
00137 
00138          // extract last spadic epoch
00139          if (fMsg.isEpoch()) fLastEpoch[fMsg.getSpadicNumber()][fMsg.getGroup()] = fMsg.getEpoch();
00140 
00141          return true;
00142 
00143          // end of direct format processing
00144       }
00145 
00146       if (fFormat != formatSpadic10Optic) {
00147          printf("Only spadic1.0 formats are supported");
00148          fBufferPos = fBufferLen;
00149          return false;
00150       }
00151 
00152 
00153       // if we are here, we want to get some etra data
00154 
00155       if (fBufferLen - fBufferPos < 8) {
00156          printf("Wrong %u bytes number in the buffer, cannot be interpreted as optic stream \n", fBufferLen);
00157          fBufferPos = fBufferLen;
00158          return false;
00159       }
00160 
00161       // we shit pointer immediately
00162       fBufferPos+=8;
00163 
00164       // in first two bytes sender id is
00165       unsigned sender_id = *((uint16_t*) curr);
00166 
00167       if (fLastSenderId != 0xffffffff)
00168          if (sender_id!=fLastSenderId) {
00169             printf("We expect sender id 0x%x got 0x%x\n", fLastSenderId, sender_id);
00170             fBufferPos = fBufferLen;
00171             return false;
00172          }
00173 
00174       // first 5 bits are used for spadic id / SYNC producer coding
00175       unsigned kindid = sender_id & 0x1f;
00176 
00177       // next 10 bits are used for sp605 id coding
00178       unsigned sp605id = (sender_id >> 5) & 0x3ff;
00179 
00180       // check that sp605id remained
00181       if (fSP605Id == 0xffffffff) fSP605Id = sp605id;
00182       if (fSP605Id != sp605id) {
00183          printf("Mismatch of SP605 id - current %u and previous %x\n", sp605id, fSP605Id);
00184          fSP605Id = sp605id;
00185       }
00186 
00187       // special case - messages from the SYNC/AUX receiver of sp605 board, use roc::Message here
00188       if (kindid == 0x1f) {
00189          fRocMsg.assign(curr, roc::formatOptic2);
00190          fRocMsg.setRocNumber(fSP605Id);
00191          fKind = kindRoc;
00192          if (fRocMsg.isEpochMsg()) fLastRocEpoch = fRocMsg.getEpochNumber();
00193          return true;
00194       }
00195 
00196       // copy next portion of data into the intermediate buffer
00197       if (fInterm==0) allocateInterm();
00198 
00199       if (fIntermFill > fIntermSize - 6) {
00200          printf("Not enough space in intermediate buffer to accumulate message\n");
00201          fBufferPos = fBufferLen;
00202          return false;
00203       }
00204 
00205       // we need to change bytes order here - it comes with big-endian !!!
00206       uint8_t* tgt = (uint8_t*) fInterm + fIntermFill;
00207       uint8_t* src = (uint8_t*) curr + 2;
00208       // memcpy((uint8_t*) fInterm + fIntermFill, (uint8_t*) curr + 2, 6);
00209       tgt[0] = src[5]; tgt[1] = src[4]; tgt[2] = src[3];
00210       tgt[3] = src[2]; tgt[4] = src[1]; tgt[5] = src[0];
00211 
00212       // uint16_t* p = (uint16_t*) fInterm;
00213       // printf("%4x %4x %4x\n", p[0], p[1], p[2]);
00214 
00215       fIntermFill += 6;
00216 
00217       unsigned msg_sz = fMsg.assign(fInterm, fIntermFill);
00218 
00219       // printf("Message size = %u\n", msg_sz);
00220 
00221       if (msg_sz==0) {
00222          fprintf(stderr, "Wrong spadic1.0 message format\n");
00223          fBufferPos = fBufferLen;
00224          return false;
00225       }
00226 
00227       if (msg_sz > fIntermFill) {
00228          // this is indication that message size is bigger than available in the intermediate buffer
00229          // try to get next portion, verify that sender id are the same
00230          fLastSenderId = sender_id;
00231       } else {
00232          fLastSenderId = 0xffffffff; // indicate that data in intermediate buffer is ready
00233 
00234          // SPDIC message complete, analyze it if necessary
00235 
00236          fKind = kindSpadic;
00237 
00238          // only 4 Spadics are supported
00239          setSpadicId((kindid >> 1) & 0x3);
00240 
00241          fMsg.setSpadicNumber(getSpadicId());
00242 
00243          if (fMsg.isEpoch()) fLastEpoch[fMsg.getSpadicNumber()][fMsg.getGroup()] = fMsg.getEpoch();
00244 
00245          if (msg_sz == fIntermFill) return true;
00246 
00247          if ((msg_sz == fIntermFill-2) && (((uint8_t*) fInterm) [fIntermFill-1] == 0xf5)) {
00248             // printf("NOP at the end\n");
00249             return true;
00250          }
00251 
00252          fprintf(stderr, "Rest of the data in intermediate buffer is not NOP!!!");
00253 
00254          return true;
00255       }
00256 
00257    }
00258 
00259    return false;
00260 }
00261 
00262 uint64_t sp605::Iterator::getMsgFullTime() const
00263 {
00264   if (isRocMsg()) return fRocMsg.getMsgFullTime(fLastRocEpoch);
00265   if (isSpadicMsg()) return fMsg.getMsgFullTime(fLastEpoch[fMsg.getSpadicNumber()][fMsg.getGroup()]);
00266 
00267   return 0;
00268 }
00269 
00270 double sp605::Iterator::getMsgFullTimeD() const
00271 {
00272    if (isRocMsg()) return fRocMsg.getMsgFullTimeD(fLastRocEpoch);
00273    if (isSpadicMsg()) return fMsg.getMsgFullTimeD(fLastEpoch[fMsg.getSpadicNumber()][fMsg.getGroup()]);
00274    return 0.;
00275 }
00276 
00277 
00278 void sp605::Iterator::printMessage()
00279 {
00280    if (isRocMsg()) fRocMsg.printData();
00281    if (isSpadicMsg()) fMsg.printData();
00282 }
00283 

Generated on Tue Dec 10 2013 04:52:23 for ROCsoft by  doxygen 1.7.1