static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC)
{
  CCRC crc;
  crc.Init();
  const UInt32 kBufferSize = (1 << 14);
  Byte buffer[kBufferSize];
  for (;;)
  {
    UInt32 realProcessedSize;
    RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize));
    if(realProcessedSize == 0)
    {
      resultCRC = crc.GetDigest();
      return S_OK;
    }
    crc.Update(buffer, realProcessedSize);
  }
}
HRESULT COutVolumeStream::Flush()
{
  if (_volumeStream)
  {
    _file.UnPackSize = _curPos;
    _file.FileCRC = _crc.GetDigest();
    RINOK(WriteVolumeHeader(_archive, _file, _options));
    _archive.Close();
    _volumeStream.Release();
    _file.StartPos += _file.UnPackSize;
  }
  return S_OK;
}
STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
  if(processedSize != NULL)
    *processedSize = 0;
  while(size > 0)
  {
    if (!_volumeStream)
    {
      RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize));
      RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
      _volIndex++;
      _curPos = 0;
      RINOK(_archive.Create(_volumeStream, true));
      RINOK(_archive.SkeepPrefixArchiveHeader());
      _crc.Init();
      continue;
    }
    UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length());
    UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos);

    _crc.Update(data, curSize);
    UInt32 realProcessed;
    RINOK(_volumeStream->Write(data, curSize, &realProcessed))
    data = (void *)((Byte *)data + realProcessed);
    size -= realProcessed;
    if(processedSize != NULL)
      *processedSize += realProcessed;
    _curPos += realProcessed;
    if (realProcessed != curSize && realProcessed == 0)
      return E_FAIL;
    if (_curPos == pureSize)
    {
      RINOK(Flush());
    }
  }
  return S_OK;
}
Exemple #4
0
/* 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);
}
Exemple #5
0
/* Actual MDI protocol implementation *****************************************/
CVector<_BINARY> CMDI::GenAFPacket(const _BOOLEAN bWithSDC)
{
    /*
    	The AF layer encapsulates a single TAG Packet. Mandatory TAG items:
    	*ptr, dlfc, fac_, sdc_, sdci, robm, str0-3
    */
    int					i;
    CVector<_BINARY>	vecbiAFPkt;

    /* Increment MDI packet counter and generate counter tag */
    GenTagLoFrCnt();

    /* Payload length in bytes */
// TODO: check if padding bits are needed to get byte alignment!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    const int iPayloadLenBytes = (vecbiTagProTy.Size() +
                                  vecbiTagLoFrCnt.Size() + vecbiTagFAC.Size() + vecbiTagSDC.Size() +
                                  vecbiTagSDCChanInf.Size() + vecbiTagRobMod.Size() +
                                  vecbiTagStr[0].Size() + vecbiTagStr[1].Size() + vecbiTagStr[2].Size() +
                                  vecbiTagStr[3].Size()) / SIZEOF__BYTE;

    /* 10 bytes AF header, 2 bytes CRC, payload */
    const int iAFPktLenBits =
        iPayloadLenBytes * SIZEOF__BYTE + 12 * SIZEOF__BYTE;

    /* Init vector length */
    vecbiAFPkt.Init(iAFPktLenBits);
    vecbiAFPkt.ResetBitAccess();

    /* SYNC: two-byte ASCII representation of "AF" */
    vecbiAFPkt.Enqueue((uint32_t) 'A', SIZEOF__BYTE);
    vecbiAFPkt.Enqueue((uint32_t) 'F', SIZEOF__BYTE);

    /* LEN: length of the payload, in bytes (4 bytes long -> 32 bits) */
    vecbiAFPkt.Enqueue((uint32_t) iPayloadLenBytes, 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) */
    vecbiAFPkt.Enqueue((uint32_t) iSeqNumber, 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 (bUseAFCRC == TRUE)
        vecbiAFPkt.Enqueue((uint32_t) 1, 1);
    else
        vecbiAFPkt.Enqueue((uint32_t) 0, 1);

    /* MAJ: major revision of the AF protocol in use (3 bits long) */
    vecbiAFPkt.Enqueue((uint32_t) AF_MAJOR_REVISION, 3);

    /* MIN: minor revision of the AF protocol in use (4 bits long) */
    vecbiAFPkt.Enqueue((uint32_t) AF_MINOR_REVISION, 4);

    /* 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" */
    vecbiAFPkt.Enqueue((uint32_t) 'T', SIZEOF__BYTE);


    /* Payload -------------------------------------------------------------- */

// TODO: copy data byte wise -> check if possible to do that...

    /* *ptr tag */
    vecbiTagProTy.ResetBitAccess();
    for (i = 0; i < vecbiTagProTy.Size(); i++)
        vecbiAFPkt.Enqueue(vecbiTagProTy.Separate(1), 1);

    /* dlfc tag */
    vecbiTagLoFrCnt.ResetBitAccess();
    for (i = 0; i < vecbiTagLoFrCnt.Size(); i++)
        vecbiAFPkt.Enqueue(vecbiTagLoFrCnt.Separate(1), 1);

    /* fac_ tag */
    vecbiTagFAC.ResetBitAccess();
    for (i = 0; i < vecbiTagFAC.Size(); i++)
        vecbiAFPkt.Enqueue(vecbiTagFAC.Separate(1), 1);

    /* SDC tag must be delayed in some cases */
    if (bWithSDC == TRUE)
    {
        /* sdc_ tag */
        vecbiTagSDC.ResetBitAccess();
        for (i = 0; i < vecbiTagSDC.Size(); i++)
            vecbiAFPkt.Enqueue(vecbiTagSDC.Separate(1), 1);
    }

    /* sdci tag */
    vecbiTagSDCChanInf.ResetBitAccess();
    for (i = 0; i < vecbiTagSDCChanInf.Size(); i++)
        vecbiAFPkt.Enqueue(vecbiTagSDCChanInf.Separate(1), 1);

    /* robm tag */
    vecbiTagRobMod.ResetBitAccess();
    for (i = 0; i < vecbiTagRobMod.Size(); i++)
        vecbiAFPkt.Enqueue(vecbiTagRobMod.Separate(1), 1);

    /* strx tag */
    for (int j = 0; j < MAX_NUM_STREAMS; j++)
    {
        vecbiTagStr[j].ResetBitAccess();
        for (i = 0; i < vecbiTagStr[j].Size(); i++)
            vecbiAFPkt.Enqueue(vecbiTagStr[j].Separate(1), 1);
    }


    /* CRC: CRC calculated as described in annex A if the CF field is 1,
       otherwise 0000_[16] */
    if (bUseAFCRC == TRUE)
    {
        CCRC CRCObject;

        /* CRC -------------------------------------------------------------- */
        /* Calculate the CRC and put at the end of the stream */
        CRCObject.Reset(16);

        vecbiAFPkt.ResetBitAccess();

        /* 2 bytes CRC -> "- 2" */
        for (int i = 0; i < iAFPktLenBits / SIZEOF__BYTE - 2; i++)
            CRCObject.AddByte((_BYTE) vecbiAFPkt.Separate(SIZEOF__BYTE));

        /* Now, pointer in "enqueue"-function is back at the same place,
           add CRC */
        vecbiAFPkt.Enqueue(CRCObject.GetCRC(), 16);
    }
    else
        vecbiAFPkt.Enqueue((uint32_t) 0, 16);

    return vecbiAFPkt;
}
void CTextMessage::SetText(const string& strMessage, const _BINARY biToggleBit)
{
	int		i, j;
	int		iNumBodyBytes;
	_BINARY	biFirstFlag;
	_BINARY	biLastFlag;
	CCRC	CRCObject;

	/* Get length of text message. 
	   TODO: take care of multiple byte characters (UTF-8 coding)! */
	int iLenBytesOfText = strMessage.length();

	/* Calculate required number of segments. The body shall contain 16 bytes
	   of character data */
	iNumSeg = (int) ceil((_REAL) iLenBytesOfText / BYTES_PER_SEG_TEXT_MESS);

	/* The text message may comprise up to 8 segments. Check the number of
	   segments, if number is larger, cut message */
	if (iNumSeg > 8)
	{
		iNumSeg = 8;
		iLenBytesOfText = iNumSeg * BYTES_PER_SEG_TEXT_MESS;
	}

	/* Allocate memory for segment pointer */
	vvbiSegment.Init(iNumSeg);


	/* Generate segments ---------------------------------------------------- */
	/* Reset position in string */
	int iPosInStr = 0;

	for (i = 0; i < iNumSeg; i++)
	{
		/* Calculate number of bytes for body */
		const int iRemainingBytes = iLenBytesOfText - iPosInStr;

		/* All segments should have the maximum number of bytes per segment
		   except the last one which takes the remaining bytes */
		if (iRemainingBytes > BYTES_PER_SEG_TEXT_MESS)
			iNumBodyBytes = BYTES_PER_SEG_TEXT_MESS;
		else
			iNumBodyBytes = iRemainingBytes;

		/* Init segment vector: "Beginning of segment" 4 * 8 bits,
		   Header 16 bits, body n * 8 bits, CRC 16 bits */
		vvbiSegment[i].Init(4 * 8 + 16 + iNumBodyBytes * 8 + 16);

		/* Reset enqueue function */
		vvbiSegment[i].ResetBitAccess();


		/* Generate "beginning of segment" identification by "all 0xFF" ----- */
		for (j = 0; j < NUM_BYTES_TEXT_MESS_IN_AUD_STR; j++)
			vvbiSegment[i].Enqueue((uint32_t) 0xFF, SIZEOF__BYTE);


		/* Header ----------------------------------------------------------- */
		/* Toggle bit */
		vvbiSegment[i].Enqueue((uint32_t) biToggleBit, 1);

		/* Determine position of segment */
		if (i == 0)
			biFirstFlag = 1;
		else
			biFirstFlag = 0;

		if (iLenBytesOfText - iPosInStr <= BYTES_PER_SEG_TEXT_MESS)
			biLastFlag = 1;
		else
			biLastFlag = 0;

		/* Enqueue first flag */
		vvbiSegment[i].Enqueue((uint32_t) biFirstFlag, 1);

		/* Enqueue last flag */
		vvbiSegment[i].Enqueue((uint32_t) biLastFlag, 1);

		/* Command flag. This is a data block -> command flag = 0 */
		vvbiSegment[i].Enqueue((uint32_t) 0, 1);

		/* Field 1: specify the number of bytes in the body minus 1 (It
		   shall normally take the value 15 except in the last segment) */
		vvbiSegment[i].Enqueue((uint32_t) iNumBodyBytes - 1, 4);

		/* Field 2. If First flag = "1", this field shall contain the
		   value "1111" */
		if (biFirstFlag == 1)
			vvbiSegment[i].Enqueue((uint32_t) 15 /* 1111 */, 4);
		else
		{
			/* Rfa. The bit shall be set to zero until it is defined */
			vvbiSegment[i].Enqueue((uint32_t) 0, 1);

			/* SegNum: specify the sequence number of the current segment 
			   minus 1. The value 0 is reserved for future use */
			vvbiSegment[i].Enqueue((uint32_t) i, 3);
		}

		/* Rfa. These bits shall be set to zero until they are defined */
		vvbiSegment[i].Enqueue((uint32_t) 0, 4);


		/* Body ------------------------------------------------------------- */
		/* Set body bytes */
		for (j = 0; j < iNumBodyBytes; j++)
		{
			vvbiSegment[i].Enqueue((uint32_t) strMessage.at(iPosInStr),
				SIZEOF__BYTE);

			iPosInStr++;
		}


		/* CRC -------------------------------------------------------------- */
		/* Reset bit access and skip segment beginning piece (all 0xFFs) */
		vvbiSegment[i].ResetBitAccess();
		vvbiSegment[i].Separate(SIZEOF__BYTE * NUM_BYTES_TEXT_MESS_IN_AUD_STR);

		/* Calculate the CRC and put it at the end of the segment */
		CRCObject.Reset(16);

		/* "byLengthBody" was defined in the header */
		for (j = 0; j < iNumBodyBytes + 2 /* Header */; j++)
			CRCObject.AddByte((_BYTE) vvbiSegment[i].Separate(SIZEOF__BYTE));

		/* Now, pointer in "enqueue"-function is back at the same place,
		   add CRC */
		vvbiSegment[i].Enqueue(CRCObject.GetCRC(), 16);


		/* Reset bit access for using segment in encoder function */
		vvbiSegment[i].ResetBitAccess();
	}
}
Exemple #7
0
/******************************************************************************\
* Encoder                                                                      *
\******************************************************************************/
void CDataEncoder::GeneratePacket(CVector<_BINARY>& vecbiPacket)
{
	int			i;
	_BOOLEAN	bLastFlag;

	/* Init size for whole packet, not only body */
	vecbiPacket.Init(iTotalPacketSize);
	vecbiPacket.ResetBitAccess();

	/* Calculate remaining data size to be transmitted */
	const int iRemainSize = vecbiCurDataUnit.Size() - iCurDataPointer;


	/* Header --------------------------------------------------------------- */
	/* First flag */
	if (iCurDataPointer == 0)
		vecbiPacket.Enqueue((uint32_t) 1, 1);
	else
		vecbiPacket.Enqueue((uint32_t) 0, 1);

	/* Last flag */
	if (iRemainSize > iPacketLen)
	{
		vecbiPacket.Enqueue((uint32_t) 0, 1);
		bLastFlag = FALSE;
	}
	else
	{
		vecbiPacket.Enqueue((uint32_t) 1, 1);
		bLastFlag = TRUE;
	}

	/* Packet Id */
	vecbiPacket.Enqueue((uint32_t) iPacketID, 2);

	/* Padded packet indicator (PPI) */
	if (iRemainSize < iPacketLen)
		vecbiPacket.Enqueue((uint32_t) 1, 1);
	else
		vecbiPacket.Enqueue((uint32_t) 0, 1);

	/* Continuity index (CI) */
	vecbiPacket.Enqueue((uint32_t) iContinInd, 3);

	/* Increment index modulo 8 (1 << 3) */
	iContinInd++;
	if (iContinInd == 8)
		iContinInd = 0;


	/* Body ----------------------------------------------------------------- */
	if (iRemainSize >= iPacketLen)
	{
		if (iRemainSize == iPacketLen)
		{
			/* Last packet */
			for (i = 0; i < iPacketLen; i++)
				vecbiPacket.Enqueue(vecbiCurDataUnit.Separate(1), 1);
		}
		else
		{
			for (i = 0; i < iPacketLen; i++)
			{
				vecbiPacket.Enqueue(vecbiCurDataUnit.Separate(1), 1);
				iCurDataPointer++;
			}
		}
	}
	else
	{
		/* Padded packet. If the PPI is 1 then the first byte shall indicate
		   the number of useful bytes that follow, and the data field is
		   completed with padding bytes of value 0x00 */
		vecbiPacket.Enqueue((uint32_t) (iRemainSize / SIZEOF__BYTE),
			SIZEOF__BYTE);

		/* Data */
		for (i = 0; i < iRemainSize; i++)
			vecbiPacket.Enqueue(vecbiCurDataUnit.Separate(1), 1);

		/* Padding */
		for (i = 0; i < iPacketLen - iRemainSize; i++)
			vecbiPacket.Enqueue(vecbiCurDataUnit.Separate(1), 1);
	}

	/* If this was the last packet, get data for next data unit */
	if (bLastFlag == TRUE)
	{
		/* Generate new data unit */
		MOTSlideShowEncoder.GetDataUnit(vecbiCurDataUnit);
		vecbiCurDataUnit.ResetBitAccess();

		/* Reset data pointer and continuity index */
		iCurDataPointer = 0;
	}


	/* CRC ------------------------------------------------------------------ */
	CCRC CRCObject;

	/* Reset bit access */
	vecbiPacket.ResetBitAccess();

	/* Calculate the CRC and put it at the end of the segment */
	CRCObject.Reset(16);

	/* "byLengthBody" was defined in the header */
	for (i = 0; i < (iTotalPacketSize / SIZEOF__BYTE - 2); i++)
		CRCObject.AddByte(vecbiPacket.Separate(SIZEOF__BYTE));

	/* Now, pointer in "enqueue"-function is back at the same place, add CRC */
	vecbiPacket.Enqueue(CRCObject.GetCRC(), 16);
}
Exemple #8
0
/******************************************************************************\
* 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);
		}
	}
}