Example #1
0
BufReq_ReturnType Com_CopyRxData(PduIdType PduId, const PduInfoType* PduInfoPtr, PduLengthType* RxBufferSizePtr) {
	/* !req COM782 */ /* If pdu group stopped -> return BUFREQ_E_NOT_OK */
	imask_t state;
	BufReq_ReturnType r = BUFREQ_OK;
	uint8 remainingBytes;
	boolean sizeOk;
	boolean dirOk;
	boolean lockOk;
	if(COM_INIT != initStatus) {
		DET_REPORTERROR(COM_COPYRXDATA_ID, COM_E_UNINIT);
		return BUFREQ_NOT_OK;
	}
	Irq_Save(state);
	/* @req COM658 */ /* Interrupts disabled */
	remainingBytes = GET_IPdu(PduId)->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
	sizeOk = remainingBytes >= PduInfoPtr->SduLength;
    dirOk = GET_IPdu(PduId)->ComIPduDirection == RECEIVE;
	lockOk = isPduBufferLocked(PduId);
	if (dirOk && lockOk && sizeOk) {
		memcpy((void *)((uint8 *)GET_ArcIPdu(PduId)->ComIPduDataPtr+Com_BufferPduState[PduId].currentPosition), PduInfoPtr->SduDataPtr, PduInfoPtr->SduLength);
		Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;
		*RxBufferSizePtr = GET_IPdu(PduId)->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
	} else {
		r = BUFREQ_NOT_OK;
	}
	Irq_Restore(state);
	return r;
}
Example #2
0
uint8 Com_SendSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {
	VALIDATE_SIGNAL(SignalId, 0x0a, E_NOT_OK);
	// Store pointer to signal for easier coding.
	const ComSignal_type * Signal = GET_Signal(SignalId);
	const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);
	Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Signal->ComIPduHandleId);

	if (isPduBufferLocked(getPduId(IPdu))) {
		return COM_BUSY;
	}
	//DEBUG(DEBUG_LOW, "Com_SendSignal: id %d, nBytes %d, BitPosition %d, intVal %d\n", SignalId, nBytes, signal->ComBitPosition, (uint32)*(uint8 *)SignalDataPtr);

	imask_t irq_state;

	Irq_Save(irq_state);
	Com_WriteSignalDataToPdu(Signal->ComHandleId, SignalDataPtr);

	// If the signal has an update bit. Set it!
	if (Signal->ComSignalArcUseUpdateBit) {
		SETBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
	}

	/*
	 * If signal has triggered transmit property, trigger a transmission!
	 */
	if (Signal->ComTransferProperty == TRIGGERED) {
		Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;
	}
	Irq_Restore(irq_state);

	return E_OK;
}
Example #3
0
/**
 *
 * @param PduId
 * @param PduInfoPtr
 * @param RetryInfoPtr not supported
 * @param TxDataCntPtr
 * @return
 */
BufReq_ReturnType Com_CopyTxData(PduIdType PduId, PduInfoType* PduInfoPtr, RetryInfoType* RetryInfoPtr, PduLengthType* TxDataCntPtr) {
	/* TODO: Validate PduId, etc? */
	/* !req COM663*/
	/* !req COM783*/ /* Do not copy any data and return BUFREQ_E_NOT_OK if pdu group stopped */
	imask_t state;
	BufReq_ReturnType r = BUFREQ_OK;

	if(COM_INIT != initStatus) {
		DET_REPORTERROR(COM_COPYTXDATA_ID, COM_E_UNINIT);
		return BUFREQ_NOT_OK;
	}

	const ComIPdu_type *IPdu = GET_IPdu(PduId);
	boolean dirOk = ComConfig->ComIPdu[PduId].ComIPduDirection == SEND;
	boolean sizeOk;
	(void)RetryInfoPtr; // get rid of compiler warning

	Irq_Save(state);
	sizeOk = IPdu->ComIPduSize >= Com_BufferPduState[PduId].currentPosition + PduInfoPtr->SduLength;
	Com_BufferPduState[PduId].locked = true;
	if (dirOk && sizeOk) {
		void* source = (void *)GET_ArcIPdu(PduId)->ComIPduDataPtr;
		memcpy(PduInfoPtr->SduDataPtr,(uint8 *)source + Com_BufferPduState[PduId].currentPosition, PduInfoPtr->SduLength);
		Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;
		*TxDataCntPtr = IPdu->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
	} else {
		r = BUFREQ_NOT_OK;
	}
	Irq_Restore(state);
	return r;
}
Example #4
0
void Com_TpRxIndication(PduIdType PduId, NotifResultType Result) {
	PDU_ID_CHECK_NO_RETURN(PduId, 0x14);

	const ComIPdu_type *IPdu = GET_IPdu(PduId);
	Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(PduId);
	imask_t state;

	Irq_Save(state);

	// If Ipdu is stopped
	if (!Arc_IPdu->Com_Arc_IpduStarted) {
		UnlockTpBuffer(getPduId(IPdu));
		Irq_Restore(state);
		return;
	}
	if (Result == NTFRSLT_OK) {
		if (IPdu->ComIPduSignalProcessing == IMMEDIATE) {
			// irqs needs to be disabled until signal notifications have been called
			// Otherwise a new Tp session can start and fill up pdus
			UnlockTpBuffer(getPduId(IPdu));
		}
		// In deferred mode, buffers are unlocked in mainfunction
		Com_RxProcessSignals(IPdu,Arc_IPdu);
	} else {
		UnlockTpBuffer(getPduId(IPdu));
	}
	Irq_Restore(state);

}
Example #5
0
Std_ReturnType Com_SendSignalGroup(Com_SignalGroupIdType SignalGroupId) {
//#warning Com_SendSignalGroup should be performed atomically. Should we disable interrupts here?
	const ComSignal_type * Signal = GET_Signal(SignalGroupId);
	Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Signal->ComIPduHandleId);
	const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);

	if (isPduBufferLocked(getPduId(IPdu))) {
		return COM_BUSY;
	}

	// Copy shadow buffer to Ipdu data space
	imask_t irq_state;

	Irq_Save(irq_state);

	Com_CopySignalGroupDataFromShadowBufferToPdu(SignalGroupId);

	// If the signal has an update bit. Set it!
	if (Signal->ComSignalArcUseUpdateBit) {
		SETBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
	}

	// If signal has triggered transmit property, trigger a transmission!
	if (Signal->ComTransferProperty == TRIGGERED) {
		Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;
	}
	Irq_Restore(irq_state);

	return E_OK;
}
Example #6
0
uint8 Com_ReceiveDynSignal(Com_SignalIdType SignalId, void* SignalDataPtr, uint16* Length) {
	const ComSignal_type * Signal = GET_Signal(SignalId);
	Com_Arc_IPdu_type    *Arc_IPdu   = GET_ArcIPdu(Signal->ComIPduHandleId);
	const ComIPdu_type   *IPdu       = GET_IPdu(Signal->ComIPduHandleId);
    imask_t state;
   	uint8 startFromPduByte;
	uint8 r = E_OK;
	const void* pduDataPtr;
	Com_SignalType signalType = Signal->ComSignalType;
	if (signalType != UINT8_DYN) {
		return COM_SERVICE_NOT_AVAILABLE;
	}

    Irq_Save(state);

	if (*Length > Arc_IPdu->Com_Arc_DynSignalLength) {
		*Length = Arc_IPdu->Com_Arc_DynSignalLength;
	}
	startFromPduByte = (Signal->ComBitPosition) / 8;
	pduDataPtr = 0;
	if (IPdu->ComIPduSignalProcessing == DEFERRED && IPdu->ComIPduDirection == RECEIVE) {
		pduDataPtr = IPdu->ComIPduDeferredDataPtr;
	} else {
		if (isPduBufferLocked(getPduId(IPdu))) {
			r = COM_BUSY;
		}
		pduDataPtr = IPdu->ComIPduDataPtr;
	}
	memcpy((void*)SignalDataPtr, (void*)((uint8*)pduDataPtr + startFromPduByte), *Length);

    Irq_Restore(state);

	return r;
}
Example #7
0
//lint -esym(904, Com_RxIndication) //PC-Lint Exception of rule 14.7
void Com_RxIndication(PduIdType ComRxPduId, const PduInfoType* PduInfoPtr) {
	PDU_ID_CHECK_NO_RETURN(ComRxPduId, 0x14);

	const ComIPdu_type *IPdu = GET_IPdu(ComRxPduId);
	Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);
	imask_t state;
	Irq_Save(state);

	// If Ipdu is stopped
	if (!Arc_IPdu->Com_Arc_IpduStarted) {
		Irq_Restore(state);
		return;
	}

	// Check callout status
	if (IPdu->ComIPduCallout != NULL) {
		if (!IPdu->ComIPduCallout(ComRxPduId, PduInfoPtr->SduDataPtr)) {
			// TODO Report error to DET.
			// Det_ReportError();
			Irq_Restore(state);
			return;
		}
	}

	// Copy IPDU data
	memcpy(IPdu->ComIPduDataPtr, PduInfoPtr->SduDataPtr, IPdu->ComIPduSize);

	Com_RxProcessSignals(IPdu,Arc_IPdu);

	Irq_Restore(state);

	return;
}
BufReq_ReturnType Com_StartOfReception(PduIdType ComRxPduId, PduLengthType TpSduLength, PduLengthType* RxBufferSizePtr) {
	PduLengthType ComIPduSize;
	imask_t state;
	BufReq_ReturnType r = BUFREQ_OK;
	Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);

	Irq_Save(state);
	if (Arc_IPdu->Com_Arc_IpduStarted) {
		if (GET_IPdu(ComRxPduId)->ComIPduDirection == RECEIVE) {
			if (!Com_BufferPduState[ComRxPduId].locked) {
				ComIPduSize = GET_IPdu(ComRxPduId)->ComIPduSize;
				if (ComIPduSize >= TpSduLength) {
					Com_BufferPduState[ComRxPduId].locked = TRUE;
					*RxBufferSizePtr = ComIPduSize;
					Com_SetDynSignalLength(ComRxPduId,TpSduLength);
				} else {
					r = BUFREQ_OVFL;
				}
			} else {
				r = BUFREQ_BUSY;
			}
		}
	} else {
		r = BUFREQ_NOT_OK;
	}
	Irq_Restore(state);
	return r;
}
Example #9
0
Std_ReturnType Com_Internal_TriggerIPduSend(PduIdType ComTxPduId) {
	PDU_ID_CHECK(ComTxPduId, 0x17, E_NOT_OK);

#if PDUR_COM_SUPPORT == STD_OFF
	return E_NOT_OK;
#else
	const ComIPdu_type *IPdu = GET_IPdu(ComTxPduId);
	Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComTxPduId);
    imask_t state;
    Irq_Save(state);

    if( isPduBufferLocked(ComTxPduId) ) {
    	return E_NOT_OK;
    }

	// Is the IPdu ready for transmission?
	if (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer == 0 && Arc_IPdu->Com_Arc_IpduStarted) {

        //lint --e(725)	Suppress PC-Lint warning "Expected positive indentation...". What means?
		// Check callout status
		if (IPdu->ComIPduCallout != NULL) {
			if (!IPdu->ComIPduCallout(ComTxPduId, IPdu->ComIPduDataPtr)) {
				// TODO Report error to DET.
				// Det_ReportError();
			    Irq_Restore(state);
				return E_NOT_OK;
			}
		}
		PduInfoType PduInfoPackage;
		PduInfoPackage.SduDataPtr = (uint8 *)IPdu->ComIPduDataPtr;
		if (IPdu->ComIPduDynSignalRef != 0) {
			uint8 sizeWithoutDynSignal = IPdu->ComIPduSize - (IPdu->ComIPduDynSignalRef->ComBitSize/8);
			PduInfoPackage.SduLength = sizeWithoutDynSignal + Arc_IPdu->Com_Arc_DynSignalLength;
		} else {
			PduInfoPackage.SduLength = IPdu->ComIPduSize;
		}

		// Send IPdu!
		if (PduR_ComTransmit(IPdu->ArcIPduOutgoingId, &PduInfoPackage) == E_OK) {
			// Clear all update bits for the contained signals
			for (uint8 i = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[i] != NULL); i++) {
				if (IPdu->ComIPduSignalRef[i]->ComSignalArcUseUpdateBit) {
					CLEARBIT(IPdu->ComIPduDataPtr, IPdu->ComIPduSignalRef[i]->ComUpdateBitPosition);
				}
			}
		} else {
			UnlockTpBuffer(getPduId(IPdu));
			return E_NOT_OK;
		}

		// Reset miminum delay timer.
		Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer = IPdu->ComTxIPdu.ComTxIPduMinimumDelayFactor;
	} else {
		return E_NOT_OK;
	}
    Irq_Restore(state);
    return E_OK;
#endif
}
static void Com_SetDynSignalLength(PduIdType ComRxPduId,PduLengthType TpSduLength) {
	const ComIPdu_type *IPdu = GET_IPdu(ComRxPduId);
	if (IPdu->ComIPduDynSignalRef == 0) {
		return;
	}
	{ //to make hcs12 compiler happier
    	const ComSignal_type * const dynSignal = IPdu->ComIPduDynSignalRef;
    	Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);
    	Arc_IPdu->Com_Arc_DynSignalLength = TpSduLength - (dynSignal->ComBitPosition/8);
	}
	return;
}
Example #11
0
static void Com_SetDynSignalLength(PduIdType ComRxPduId,PduLengthType TpSduLength) {
	const ComIPdu_type *IPdu = GET_IPdu(ComRxPduId);
	if (IPdu->ComIPduDynSignalRef == 0) {
		return;
	}
	const ComSignal_type * const dynSignal = IPdu->ComIPduDynSignalRef;
	Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);
	/* @req COM758 */
	if( TpSduLength > (dynSignal->ComBitPosition/8) ) {
	Arc_IPdu->Com_Arc_DynSignalLength = TpSduLength - (dynSignal->ComBitPosition/8);
	} else {
		Arc_IPdu->Com_Arc_DynSignalLength = 0;
	}
	return;
}
Example #12
0
BufReq_ReturnType Com_StartOfReception(PduIdType ComRxPduId, PduLengthType TpSduLength, PduLengthType* RxBufferSizePtr) {
	/* TODO: Validate ComRxPduId? */
	PduLengthType ComIPduSize;
	imask_t state;
	BufReq_ReturnType r = BUFREQ_OK;

	if(COM_INIT != initStatus) {
		DET_REPORTERROR(COM_STARTOFRECEPTION_ID, COM_E_UNINIT);
		return BUFREQ_NOT_OK;
	}

	Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);

	Irq_Save(state);
	if (Arc_IPdu->Com_Arc_IpduStarted) {
		if (GET_IPdu(ComRxPduId)->ComIPduDirection == RECEIVE) {
			/* !req COM657 */
			if (!Com_BufferPduState[ComRxPduId].locked) {
				ComIPduSize = GET_IPdu(ComRxPduId)->ComIPduSize;
				if (ComIPduSize >= TpSduLength) {
					Com_BufferPduState[ComRxPduId].locked = true;
					*RxBufferSizePtr = ComIPduSize;
					/* @req COM656 */
					Com_SetDynSignalLength(ComRxPduId,TpSduLength);
				} else {
					/* @req COM654 */
					/* @req COM655 */
					r = BUFREQ_OVFL;
				}
			} else {
				r = BUFREQ_BUSY;
			}
		}
	} else {
		/* @req COM721 */
		r = BUFREQ_NOT_OK;
	}
	Irq_Restore(state);
	return r;
}
Example #13
0
uint8 Com_SendDynSignal(Com_SignalIdType SignalId, const void* SignalDataPtr, uint16 Length) {
	const ComSignal_type * Signal = GET_Signal(SignalId);
	Com_Arc_IPdu_type    *Arc_IPdu   = GET_ArcIPdu(Signal->ComIPduHandleId);
	const ComIPdu_type   *IPdu       = GET_IPdu(Signal->ComIPduHandleId);
    imask_t state;

	Com_SignalType signalType = Signal->ComSignalType;
	uint8 signalLength;
	Com_BitPositionType bitPosition;
	uint8 startFromPduByte;
	if (signalType != UINT8_DYN) {
		return COM_SERVICE_NOT_AVAILABLE;
	}
	if (isPduBufferLocked(getPduId(IPdu))) {
		return COM_BUSY;
	}

	signalLength = Signal->ComBitSize / 8;
	bitPosition = Signal->ComBitPosition;
	if (signalLength < Length) {
		return E_NOT_OK;
	}
	startFromPduByte = bitPosition / 8;

	Irq_Save(state);
	memcpy((void *)((uint8 *)IPdu->ComIPduDataPtr + startFromPduByte), SignalDataPtr, Length);
	Arc_IPdu->Com_Arc_DynSignalLength = Length;
	// If the signal has an update bit. Set it!
	if (Signal->ComSignalArcUseUpdateBit) {
		SETBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
	}
	 // If signal has triggered transmit property, trigger a transmission!
	if (Signal->ComTransferProperty == TRIGGERED) {
		Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;
	}
    Irq_Restore(state);

    return E_OK;
}
Example #14
0
void Com_Init(const Com_ConfigType *config ) {
	DEBUG(DEBUG_LOW, "--Initialization of COM--\n");
	/* !req COM328 */ /* Shall not enable inter-ECU communication */
	/* !req COM483 */

	/* @req COM128 */
	/* @req COM217 */
	/* @req COM444 */
	/* @req COM772 */ // If timeout set to 0

	uint8 failure = 0;
	/* @req COM433 */
	if( NULL == config ) {
		DET_REPORTERROR(COM_INIT_ID, COM_E_PARAM_POINTER);
		return;
	}
	ComConfig = config;

	uint32 firstTimeout;
	boolean dataChanged = FALSE;
	//lint --e(928)	PC-Lint exception Misra 11.4, Must be like this. /tojo
	uint8 endiannessByte = *(const uint8 *)&endianness_test;
	if      ( endiannessByte == 0xef ) { Com_SystemEndianness = COM_LITTLE_ENDIAN; }
	else if ( endiannessByte == 0xde ) { Com_SystemEndianness = COM_BIG_ENDIAN; }
	else {
		// No other endianness supported
		//lint --e(506)	PC-Lint exception Misra 13.7, 14.1, Allow boolean to always be false.
		assert(0);
	}

	// Initialize each IPdu
	//ComIPdu_type *IPdu;
	//Com_Arc_IPdu_type *Arc_IPdu;
	const ComSignal_type *Signal;
	const ComGroupSignal_type *GroupSignal;
	uint16 bufferIndex = 0;
	for (uint16 i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
	    boolean pduHasGroupSignal = FALSE;
		const ComIPdu_type *IPdu = GET_IPdu(i);
		Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(i);
		Arc_IPdu->Com_Arc_DynSignalLength = 0;

		if (i >= ComConfig->ComNofIPdus) {
			DET_REPORTERROR(COM_INIT_ID ,COM_E_TOO_MANY_IPDU);
			failure = 1;
			break;
		}
		/* Set the data ptr for this Pdu */
		Arc_IPdu->ComIPduDataPtr = (void *)&Com_Arc_Buffer[bufferIndex];
		bufferIndex += IPdu->ComIPduSize;
		// If this is a TX and cyclic IPdu, configure the first deadline.
		if ( (IPdu->ComIPduDirection == SEND) &&
				( (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == PERIODIC) || (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == MIXED) )) {
			//IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeTimeOffsetFactor;
			Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeTimeOffsetFactor;
		}


		// Reset firstTimeout.
		firstTimeout = 0xffffffffu;

		// Initialize the memory with the default value.
		/* @req COM015 */
		if (IPdu->ComIPduDirection == SEND) {
			memset((void *)Arc_IPdu->ComIPduDataPtr, IPdu->ComTxIPdu.ComTxIPduUnusedAreasDefault, IPdu->ComIPduSize);
		}

		// For each signal in this PDU.
		//Arc_IPdu->NComIPduSignalRef = 0;
		for (uint16 j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL) ; j++) {
			Signal = IPdu->ComIPduSignalRef[j];
			Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);

			// Configure signal deadline monitoring if used.
			/* @req COM333 */ // If timeout set to 0
			if (Signal->ComTimeoutFactor > 0) {

				if (Signal->ComSignalArcUseUpdateBit) {
					// This signal uses an update bit, and hence has its own deadline monitoring.
					/* @req COM292 */
					Arc_Signal->Com_Arc_DeadlineCounter = Signal->ComFirstTimeoutFactor; // Configure the deadline counter

				} else {
					// This signal does not use an update bit, and should therefore use per I-PDU deadline monitoring.
					if (firstTimeout > Signal->ComFirstTimeoutFactor) {
						firstTimeout = Signal->ComFirstTimeoutFactor;
					}
				}
			}

			// Clear update bits
			/* @req COM117 */
			if (Signal->ComSignalArcUseUpdateBit) {
				CLEARBIT(Arc_IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
			}

			// If this signal is a signal group
			if (Signal->Com_Arc_IsSignalGroup) {
			    pduHasGroupSignal = TRUE;
			    Arc_Signal->Com_Arc_ShadowBuffer = (void *)&Com_Arc_Buffer[bufferIndex];
				// For each group signal of this signal group.
				for(uint8 h = 0; Signal->ComGroupSignal[h] != NULL; h++) {
					GroupSignal = Signal->ComGroupSignal[h];
					Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(GroupSignal->ComHandleId);
					// Set pointer to shadow buffer
					Arc_GroupSignal->Com_Arc_ShadowBuffer = (void *)Arc_Signal->Com_Arc_ShadowBuffer;

					// Initialize shadowbuffer.
					/* @req COM484 */
					Com_Internal_UpdateShadowSignal(GroupSignal->ComHandleId, GroupSignal->ComSignalInitValue);
				}
				// Initialize group signal data from shadowbuffer.
				/* @req COM098 */
				Com_CopySignalGroupDataFromShadowBufferToPdu(Signal->ComHandleId, false, &dataChanged);
			} else {
				// Initialize signal data.
				/* @req COM098 */
				Com_WriteSignalDataToPdu(Signal->ComHandleId, Signal->ComSignalInitValue, &dataChanged);
			}
		}
		if( pduHasGroupSignal ) {
		    /* This pdu has includes group signals. Means that a shodow buffer was set up.
		     * Increment index. */
		    bufferIndex += IPdu->ComIPduSize;
		}
		if (IPdu->ComIPduDirection == RECEIVE && IPdu->ComIPduSignalProcessing == DEFERRED) {
		    /* Set pointer to the deferred buffer */
		    Arc_IPdu->ComIPduDeferredDataPtr = (void *)&Com_Arc_Buffer[bufferIndex];
	        bufferIndex += IPdu->ComIPduSize;
			// Copy the initialized pdu to deferred buffer
			memcpy(Arc_IPdu->ComIPduDeferredDataPtr,Arc_IPdu->ComIPduDataPtr,IPdu->ComIPduSize);
		}
		// Configure per I-PDU based deadline monitoring.
		for (uint16 j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL); j++) {
			Signal = IPdu->ComIPduSignalRef[j];
			Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);

			/* @req COM333 */ // If timeout set to 0
			if ( (Signal->ComTimeoutFactor > 0) && (!Signal->ComSignalArcUseUpdateBit) ) {
				/* @req COM290 */
				Arc_Signal->Com_Arc_DeadlineCounter = firstTimeout;
			}
		}
	}
	for (uint16 i = 0; i < ComConfig->ComNofIPdus; i++) {
		Com_BufferPduState[i].currentPosition = 0;
		Com_BufferPduState[i].locked = false;
	}

	// An error occurred.
	if (failure) {
		DEBUG(DEBUG_LOW, "--Initialization of COM failed--\n");
		//DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_INVALID_FILTER_CONFIGURATION);
	} else {
		initStatus = COM_INIT;
		DEBUG(DEBUG_LOW, "--Initialization of COM completed--\n");
	}
}
void Com_Init(const Com_ConfigType *config ) {
	uint8 failure = 0;
	uint32 firstTimeout;
	uint8 endiannessByte;
	uint16 i;
	uint16 j;
    //ComIPdu_type *IPdu;
	//Com_Arc_IPdu_type *Arc_IPdu;
	const ComSignal_type *Signal;
	const ComGroupSignal_type *GroupSignal;
	
	DEBUG_PRINT0(DEBUG_LOW, "--Initialization of COM--\n");

	ComConfig = config;

	//lint --e(928)	PC-Lint exception Misra 11.4, Must be like this. /tojo
	endiannessByte = *(const uint8 *)&endianness_test;
	if      ( endiannessByte == 0xef ) { Com_SystemEndianness = COM_LITTLE_ENDIAN; }
	else if ( endiannessByte == 0xde ) { Com_SystemEndianness = COM_BIG_ENDIAN; }
	else {
		// No other endianness supported
		//lint --e(506)	PC-Lint exception Misra 13.7, 14.1, Allow boolean to always be false.
		AR_ASSERT(0);
	}

	// Initialize each IPdu
#if 0
	//F*****g bad code as always need a dummy ComIPdu config with Com_Arc_EOL equal to TRUE.
	for (i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
#else /*So I changed it to ...*/
    for(i = 0;i < COM_N_IPDUS;i++){
#endif
		const ComIPdu_type *IPdu = GET_IPdu(i);
		Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(i);
		Arc_IPdu->Com_Arc_DynSignalLength = 0;

		if (i >= COM_N_IPDUS) {
			DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_TOO_MANY_IPDU);
			failure = 1;
			break;
		}

		// If this is a TX and cyclic IPdu, configure the first deadline.
		if ( (IPdu->ComIPduDirection == SEND) &&
             ( (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == PERIODIC) || (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == MIXED) )) {
			//IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeTimeOffsetFactor;
			Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeTimeOffsetFactor;
		}


		// Reset firstTimeout.
		firstTimeout = 0xffffffffu;

		// Initialize the memory with the default value.
		if (IPdu->ComIPduDirection == SEND) {
			memset((void *)IPdu->ComIPduDataPtr, IPdu->ComTxIPdu.ComTxIPduUnusedAreasDefault, IPdu->ComIPduSize);
		}

		// For each signal in this PDU.
		//Arc_IPdu->NComIPduSignalRef = 0;
		for (j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL) ; j++) {
			Com_Arc_Signal_type * Arc_Signal;
			Signal = IPdu->ComIPduSignalRef[j];
			Arc_Signal = GET_ArcSignal(Signal->ComHandleId);

			// Configure signal deadline monitoring if used.
			if (Signal->ComTimeoutFactor > 0) {

				if (Signal->ComSignalArcUseUpdateBit) {
					// This signal uses an update bit, and hence has its own deadline monitoring.
					Arc_Signal->Com_Arc_DeadlineCounter = Signal->ComFirstTimeoutFactor; // Configure the deadline counter

				} else {
					// This signal does not use an update bit, and should therefore use per I-PDU deadline monitoring.
					if (firstTimeout > Signal->ComFirstTimeoutFactor) {
						firstTimeout = Signal->ComFirstTimeoutFactor;
					}
				}
			}

			// Clear update bits
			if (Signal->ComSignalArcUseUpdateBit) {
				CLEARBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
			}

			// If this signal is a signal group
			if (Signal->Com_Arc_IsSignalGroup) {
			    uint8 h;
				// For each group signal of this signal group.
				for(h = 0; Signal->ComGroupSignal[h] != NULL; h++) {
					Com_Arc_GroupSignal_type *Arc_GroupSignal;
					GroupSignal = Signal->ComGroupSignal[h];
					Arc_GroupSignal = GET_ArcGroupSignal(GroupSignal->ComHandleId);
					// Set pointer to shadow buffer
					Arc_GroupSignal->Com_Arc_ShadowBuffer = (void *)Signal->Com_Arc_ShadowBuffer;
					// Initialize group signal data.
					Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, GroupSignal->ComHandleId, GroupSignal->ComSignalInitValue);
				}
			} else {
				// Initialize signal data.
				Com_WriteSignalDataToPdu(Signal->ComHandleId, Signal->ComSignalInitValue);
			}
		}
		if (IPdu->ComIPduDirection == RECEIVE && IPdu->ComIPduSignalProcessing == DEFERRED) {
			// Copy the initialized pdu to deferred buffer
			memcpy(IPdu->ComIPduDeferredDataPtr,IPdu->ComIPduDataPtr,IPdu->ComIPduSize);
		}
		// Configure per I-PDU based deadline monitoring.
		for (j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL); j++) {
			Com_Arc_Signal_type * Arc_Signal;
			Signal = IPdu->ComIPduSignalRef[j];
			Arc_Signal = GET_ArcSignal(Signal->ComHandleId);

			if ( (Signal->ComTimeoutFactor > 0) && (!Signal->ComSignalArcUseUpdateBit) ) {
				Arc_Signal->Com_Arc_DeadlineCounter = firstTimeout;
			}
		}
	}
	for (i = 0; i < COM_N_IPDUS; i++) {
		Com_BufferPduState[i].currentPosition = 0;
		Com_BufferPduState[i].locked = FALSE;
	}

	// An error occurred.
	if (failure) {
		DEBUG_PRINT0(DEBUG_LOW, "--Initialization of COM failed--\n");
		//DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_INVALID_FILTER_CONFIGURATION);
	} else {
		DEBUG_PRINT0(DEBUG_LOW, "--Initialization of COM completed--\n");
	}
}


void Com_DeInit( void ) {

}

void Com_IpduGroupStart(Com_PduGroupIdType IpduGroupId,boolean Initialize) {
    uint16 i;
	(void)Initialize; // Nothing to be done. This is just to avoid Lint warning.
#if 0
	for (i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
#else /*So I changed it to ...*/
    for(i = 0;i < COM_N_IPDUS;i++){
#endif
		if (ComConfig->ComIPdu[i].ComIPduGroupRef == IpduGroupId) {
			Com_Arc_Config.ComIPdu[i].Com_Arc_IpduStarted = 1;
		}
	}
}

void Com_IpduGroupStop(Com_PduGroupIdType IpduGroupId) {
    uint16 i;
#if 0
	for (i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
#else /*So I changed it to ...*/
    for(i = 0;i < COM_N_IPDUS;i++){
#endif
		if (ComConfig->ComIPdu[i].ComIPduGroupRef == IpduGroupId) {
			Com_Arc_Config.ComIPdu[i].Com_Arc_IpduStarted = 0;
		}
	}
}

/**
 *
 * @param PduId
 * @param PduInfoPtr
 * @param RetryInfoPtr not supported
 * @param TxDataCntPtr
 * @return
 */
BufReq_ReturnType Com_CopyTxData(PduIdType PduId, PduInfoType* PduInfoPtr, RetryInfoType* RetryInfoPtr, PduLengthType* TxDataCntPtr) {
	imask_t state;
	BufReq_ReturnType r = BUFREQ_OK;
	const ComIPdu_type *IPdu = GET_IPdu(PduId);
	boolean dirOk = ComConfig->ComIPdu[PduId].ComIPduDirection == SEND;
	boolean sizeOk;
	(void)RetryInfoPtr; // get rid of compiler warning

	Irq_Save(state);
	sizeOk = IPdu->ComIPduSize >= Com_BufferPduState[PduId].currentPosition + PduInfoPtr->SduLength;
	Com_BufferPduState[PduId].locked = TRUE;
	if (dirOk && sizeOk) {
		void* source = (void *)(IPdu->ComIPduDataPtr);
		memcpy((void *)PduInfoPtr->SduDataPtr,(void *)((uint8*)source + Com_BufferPduState[PduId].currentPosition), PduInfoPtr->SduLength);
		Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;
		*TxDataCntPtr = IPdu->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
	} else {
		r = BUFREQ_NOT_OK;
	}
	Irq_Restore(state);
	return r;
}