/* Actual MDI protocol implementation *****************************************/ void CMDI::DecAFPacket(CVector<_BINARY>& vecbiAFPkt) { int i; /* CRC check ------------------------------------------------------------ */ CCRC CRCObject; // FIXME: is this length always the correct length? In the actual packet // there is also a value for the length included!!!???!??? const int iLenAFPkt = vecbiAFPkt.Size(); /* We do the CRC check at the beginning no matter if it is used or not since we have to reset bit access for that */ /* Reset bit extraction access */ vecbiAFPkt.ResetBitAccess(); /* Check the CRC of this packet */ CRCObject.Reset(16); /* "- 2": 16 bits for CRC at the end */ for (i = 0; i < iLenAFPkt / SIZEOF__BYTE - 2; i++) CRCObject.AddByte((_BYTE) vecbiAFPkt.Separate(SIZEOF__BYTE)); const _BOOLEAN bCRCOk = CRCObject.CheckCRC(vecbiAFPkt.Separate(16)); /* Actual packet decoding ----------------------------------------------- */ vecbiAFPkt.ResetBitAccess(); /* SYNC: two-byte ASCII representation of "AF" (2 bytes) */ string strSyncASCII = ""; for (i = 0; i < 2; i++) strSyncASCII += (_BYTE) vecbiAFPkt.Separate(SIZEOF__BYTE); /* Check if string is correct */ if (strSyncASCII.compare("AF") != 0) return; // TODO: error handling!!!!!!!!!!!!!!!!!!!!!! /* LEN: length of the payload, in bytes (4 bytes long -> 32 bits) */ const int iPayLLen = (int) vecbiAFPkt.Separate(32); /* SEQ: sequence number. Each AF Packet shall increment the sequence number by one for each packet sent, regardless of content. There shall be no requirement that the first packet received shall have a specific value. The counter shall wrap from FFFF_[16] to 0000_[16], thus the value shall count, FFFE_[16], FFFF_[16], 0000_[16], 0001_[16], etc. (2 bytes long -> 16 bits) */ // TODO: use sequence number somehow!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! const int iCurSeqNum = (int) vecbiAFPkt.Separate(16); /* iSeqNumber++; if (iSeqNumber > 0xFFFF) iSeqNumber = 0; */ /* AR: AF protocol Revision - a field combining the CF, MAJ and MIN fields */ /* CF: CRC Flag, 0 if the CRC field is not used (CRC value shall be 0000_[16]) or 1 if the CRC field contains a valid CRC (1 bit long) */ if ((_BOOLEAN) vecbiAFPkt.Separate(1)) { /* Use CRC check which was already done */ if (!bCRCOk) return; // TODO: error handling!!!!!!!!!!!!!!!!!!!!!! } /* MAJ: major revision of the AF protocol in use (3 bits long) */ const int iMajRevAFProt = (int) vecbiAFPkt.Separate(3); /* MIN: minor revision of the AF protocol in use (4 bits long) */ const int iMinRevAFProt = (int) vecbiAFPkt.Separate(4); // TODO: check if protocol versions match our version!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /* Protocol Type (PT): single byte encoding the protocol of the data carried in the payload. For TAG Packets, the value shall be the ASCII representation of "T" */ if ((_BYTE) vecbiAFPkt.Separate(SIZEOF__BYTE) != 'T') return; // TODO: error handling!!!!!!!!!!!!!!!!!!!!!! /* Payload -------------------------------------------------------------- */ CMDIInPkt MIDInPkt; /* Decode all tags */ int iCurConsBytes = 0; /* Each tag must have at least a header with 8 bytes -> "- 8" */ while (iCurConsBytes < iPayLLen - 8) iCurConsBytes += DecodeTag(MIDInPkt, vecbiAFPkt); /* Add new MDI data to buffer */ MDIInBuffer.Put(MIDInPkt); }
/******************************************************************************\ * Decoder * \******************************************************************************/ void CDataDecoder::ProcessDataInternal(CParameter& ReceiverParam) { int i, j; int iPacketID; int iNewContInd; int iNewPacketDataSize; int iOldPacketDataSize; int iNumSkipBytes; _BINARY biFirstFlag; _BINARY biLastFlag; _BINARY biPadPackInd; CCRC CRCObject; /* Check if something went wrong in the initialization routine */ if (DoNotProcessData == TRUE) return; /* CRC check for all packets -------------------------------------------- */ /* Reset bit extraction access */ (*pvecInputData).ResetBitAccess(); for (j = 0; j < iNumDataPackets; j++) { /* Check the CRC of this packet */ CRCObject.Reset(16); /* "- 2": 16 bits for CRC at the end */ for (i = 0; i < iTotalPacketSize - 2; i++) CRCObject.AddByte((_BYTE) (*pvecInputData).Separate(SIZEOF__BYTE)); /* Store result in vector and show CRC in multimedia window */ if (CRCObject.CheckCRC((*pvecInputData).Separate(16)) == TRUE) { veciCRCOk[j] = 1; /* CRC ok */ PostWinMessage(MS_MSC_CRC, 0); /* Green light */ } else { veciCRCOk[j] = 0; /* CRC wrong */ PostWinMessage(MS_MSC_CRC, 2); /* Red light */ } } /* Extract packet data -------------------------------------------------- */ /* Reset bit extraction access */ (*pvecInputData).ResetBitAccess(); for (j = 0; j < iNumDataPackets; j++) { /* Check if CRC was ok */ if (veciCRCOk[j] == 1) { /* Read header data --------------------------------------------- */ /* First flag */ biFirstFlag = (_BINARY) (*pvecInputData).Separate(1); /* Last flag */ biLastFlag = (_BINARY) (*pvecInputData).Separate(1); /* Packet ID */ iPacketID = (int) (*pvecInputData).Separate(2); /* Padded packet indicator (PPI) */ biPadPackInd = (_BINARY) (*pvecInputData).Separate(1); /* Continuity index (CI) */ iNewContInd = (int) (*pvecInputData).Separate(3); /* Act on parameters given in header */ /* Continuity index: this 3-bit field shall increment by one modulo-8 for each packet with this packet Id */ if ((iContInd[iPacketID] + 1) % 8 != iNewContInd) DataUnit[iPacketID].bOK = FALSE; /* Store continuity index */ iContInd[iPacketID] = iNewContInd; /* Reset flag for data unit ok when receiving the first packet of a new data unit */ if (biFirstFlag == TRUE) { DataUnit[iPacketID].Reset(); DataUnit[iPacketID].bOK = TRUE; } /* If all packets are received correctely, data unit is ready */ if (biLastFlag == TRUE) if (DataUnit[iPacketID].bOK == TRUE) DataUnit[iPacketID].bReady = TRUE; /* Data field --------------------------------------------------- */ /* Get size of new data block */ if (biPadPackInd == TRUE) { /* Padding is present: the first byte gives the number of useful data bytes in the data field. */ iNewPacketDataSize = (int) (*pvecInputData).Separate(SIZEOF__BYTE) * SIZEOF__BYTE; if (iNewPacketDataSize > iMaxPacketDataSize) { /* Error, reset flags */ DataUnit[iPacketID].bOK = FALSE; DataUnit[iPacketID].bReady = FALSE; /* Set values to read complete packet size */ iNewPacketDataSize = iNewPacketDataSize; iNumSkipBytes = 2; /* Only CRC has to be skipped */ } else { /* Number of unused bytes ("- 2" because we also have the one byte which stored the size, the other byte is the header) */ iNumSkipBytes = iTotalPacketSize - 2 - iNewPacketDataSize / SIZEOF__BYTE; } /* Packets with no useful data are permitted if no packet data is available to fill the logical frame. The PPI shall be set to 1 and the first byte of the data field shall be set to 0 to indicate no useful data. The first and last flags shall be set to 1. The continuity index shall be incremented for these empty packets */ if ((biFirstFlag == TRUE) && (biLastFlag == TRUE) && (iNewPacketDataSize == 0)) { /* Packet with no useful data, reset flag */ DataUnit[iPacketID].bReady = FALSE; } } else { iNewPacketDataSize = iMaxPacketDataSize; /* All bytes are useful bytes, only CRC has to be skipped */ iNumSkipBytes = 2; } /* Add new data to data unit vector (bit-wise copying) */ iOldPacketDataSize = DataUnit[iPacketID].vecbiData.Size(); DataUnit[iPacketID].vecbiData.Enlarge(iNewPacketDataSize); /* Read useful bits */ for (i = 0; i < iNewPacketDataSize; i++) DataUnit[iPacketID].vecbiData[iOldPacketDataSize + i] = (_BINARY) (*pvecInputData).Separate(1); /* Read bytes which are not used */ for (i = 0; i < iNumSkipBytes; i++) (*pvecInputData).Separate(SIZEOF__BYTE); /* Use data unit ------------------------------------------------ */ if (DataUnit[iPacketID].bReady == TRUE) { /* Decode all IDs regardless whether activated or not (iPacketID == or != iServPacketID) */ /* Only DAB multimedia is supported */ switch (eAppType) { case AT_MOTSLISHOW: /* MOTSlideshow */ /* Packet unit decoding */ MOTSlideShow[iPacketID]. AddDataUnit(DataUnit[iPacketID].vecbiData); break; case AT_JOURNALINE: break; } /* Packet was used, reset it now for new filling with new data (this will also reset the flag "DataUnit[iPacketID].bReady") */ DataUnit[iPacketID].Reset(); } } else { /* Skip incorrect packet */ for (i = 0; i < iTotalPacketSize; i++) (*pvecInputData).Separate(SIZEOF__BYTE); } } }