//*****************************************************************************
// (C) Automotive Lighting Reutlingen GmbH
// Tuebinger Strasse 123, 72762 Reutlingen, Germany
//
// Automotive Lighting Reutlingen GmbH owns all the rights to this work.
// This work shall not be copied, reproduced, used, modified, transferred
// or its information shall not be disclosed without the prior written
// authorization of Automotive Lighting Reutlingen GmbH.
//*****************************************************************************
//-----------------------------------------------------------------------------
/// \file ApplCmd_Rdm.c
///
/// \brief
///
/// \descr
///
/// Additional information can be found in the design description (Link:
/// MDDD)
///
/// \author Heusel Johannes ALDE-RT/EEG-PM2 (F89037A)
/// mailTo:johannes.heusel(at)al-lighting.com
//-----------------------------------------------------------------------------
//=============================================================================
// Includes
//=============================================================================
#include "ApplCmd_Rdm.h"
//=============================================================================
// Public types
//=============================================================================
typedef void* (*tpfnGetVirtData)(uint32* pulSize);
#define MAC_APPLCMD_RDM_ENUM
//lint -e451 Header file repeatedly included but does not have a standard include guard
#include
//lint +e451 Header file repeatedly included but does not have a standard include guard
#undef MAC_APPLCMD_RDM_ENUM
#define APPLCMD_RDM_MAC_DECL_FCT
//lint -e451 Header file repeatedly included but does not have a standard include guard
#include
//lint +e451 Header file repeatedly included but does not have a standard include guard
#undef APPLCMD_RDM_MAC_DECL_FCT
#define MAC_APPLCMD_RDM_LIST_CALLBACK
//lint -e451 Header file repeatedly included but does not have a standard include guard
#include
//lint +e451 Header file repeatedly included but does not have a standard include guard
#undef MAC_APPLCMD_RDM_LIST_CALLBACK
//============================================================================
// Preprocessor definitions
//=============================================================================
#ifndef APPLCMD_RDM_MESSAGE_OFFSET
#define APPLCMD_RDM_MESSAGE_OFFSET (0U)
#endif
#ifdef SUPPORT_RDM_SERVICES
#ifndef PRJ_TYP_Sb015
static uint8 DiagR_CalcSrcAddressForVirtID(uint8** ppSrc,
const tpfnGetVirtData* pfnGetVirtData,
uint32 ulAdr,
uint32 ulNumOfBytes,
uint8 ucMaxTableEntries);
#endif
//=============================================================================
// Public functions definition
//=============================================================================
//-----------------------------------------------------------------------------
/// \brief DiagR_ReadMemByAddress
///
/// \descr
///
/// \param -
///
/// \return void
//-----------------------------------------------------------------------------
// PRQA S 3408 1 // It is actually being declared using macros
uint8 ApplCmd_Rdm_ReadMemByAddr( MsgContextType *const pMsgContext )
{
uint8 ResponseCode = 0u;
const uint8 *pucReqData = pMsgContext->reqData;
const uint16 unReqDataLen = pMsgContext->reqDataLen;
uint8 *pucResData = pMsgContext->resData;
// Evt. hier auch noch mit CallBack Technik arbeiten, fur den Fall das die Ausfuhrung langer dauert.
// Read Memory by Address mit Lange null wird ebenfalls positive Acknowledged.
uint8 ucNumberOfBytesForAdr = pucReqData[0u + APPLCMD_RDM_MESSAGE_OFFSET] & 0x0fu;
const uint8 ucNumberOfBytesForLen = (pucReqData[0U + APPLCMD_RDM_MESSAGE_OFFSET] >> 4U);
const uint8 *const pucLenInfo = &pucReqData[1U + APPLCMD_RDM_MESSAGE_OFFSET] + ucNumberOfBytesForAdr;
uint32 ulNumOfBytes, ulAdr;
uint8* pReadAddress = (uint8*) 0u;
ulAdr = (ucNumberOfBytesForAdr == 1U) ? ((uint32)pucReqData[1U]<< 0U) :
(ucNumberOfBytesForAdr == 2U) ? ((uint32)pucReqData[1U + APPLCMD_RDM_MESSAGE_OFFSET]<< 8U) | ((uint32)pucReqData[2U + APPLCMD_RDM_MESSAGE_OFFSET]<< 0U) :
(ucNumberOfBytesForAdr == 3U) ? ((uint32)pucReqData[1U + APPLCMD_RDM_MESSAGE_OFFSET]<<16U) | ((uint32)pucReqData[2U + APPLCMD_RDM_MESSAGE_OFFSET]<< 8U) | ((uint32)pucReqData[3U + APPLCMD_RDM_MESSAGE_OFFSET]<< 0U) :
(ucNumberOfBytesForAdr == 4U) ? ((uint32)pucReqData[1U + APPLCMD_RDM_MESSAGE_OFFSET]<<24U) | ((uint32)pucReqData[2U + APPLCMD_RDM_MESSAGE_OFFSET]<<16U) | ((uint32)pucReqData[3U + APPLCMD_RDM_MESSAGE_OFFSET]<< 8U) | ((uint32)pucReqData[4U + APPLCMD_RDM_MESSAGE_OFFSET]<< 0U) :
(uint32)0xffffffffu;
ulNumOfBytes = (ucNumberOfBytesForLen == 1U) ? ((uint32)pucLenInfo[0U] << 0U) :
(ucNumberOfBytesForLen == 2U) ? ((uint32)pucLenInfo[0U] << 8U ) | ((uint32)pucLenInfo[1U] << 0U) :
(ucNumberOfBytesForLen == 3U) ? ((uint32)pucLenInfo[0U] << 16U) | ((uint32)pucLenInfo[1U] << 8U) | ((uint32)pucLenInfo[2U] << 0U) :
(ucNumberOfBytesForLen == 4U) ? ((uint32)pucLenInfo[0U] << 24U) | ((uint32)pucLenInfo[1U] << 16U) | ((uint32)pucLenInfo[2U] << 8U) | ((uint32)pucLenInfo[3U] << 0U) :
(uint32)0xffffffffu;
if ( (ulAdr == (uint32)0xffffffffu) || (ulNumOfBytes == (uint32)0xffffffffu) )
{
ResponseCode = 0x31u; //DCM_E_REQUESTOUTOFRANGE;
}
else if (unReqDataLen != (uint16)(1U + (uint16)ucNumberOfBytesForAdr + (uint16)ucNumberOfBytesForLen))
{
ResponseCode = 0x13u; //DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
}
else
{
// do nothing
}
if (ResponseCode == 0u /*DCM_E_OK*/)
{
const boolean boAddressIsInRam = (boolean) ((( RDM_RAM_BEGIN <= ulAdr ) && ( ulAdr < RDM_RAM_END )) ? TRUE : FALSE);
const boolean boAddressIsInReg = (boolean) ((( RDM_REG_BEGIN <= ulAdr ) && ( ulAdr < RDM_REG_END )) ? TRUE : FALSE);
#if(RDM_ROM_BEGIN > 0U)
const boolean boAddressIsInRom = (boolean) ((( RDM_ROM_BEGIN <= ulAdr ) && ( ulAdr < RDM_ROM_END )) ? TRUE : FALSE);
#else
const boolean boAddressIsInRom = (boolean) ((ulAdr < RDM_ROM_END ) ? TRUE : FALSE);
#endif
if ( (boAddressIsInRam == TRUE) // RAM area
|| (boAddressIsInRom == TRUE) // ROM area
|| (boAddressIsInReg == TRUE)) // Register area
{
// PRQA S 306 1 // correct cast - working with actual address
pReadAddress = (uint8*)(ulAdr);
}
else
{
#ifndef PRJ_TYP_Sb015
/* User Data? */
if ( ( RDM_VIRT_ID_BEGIN <= ulAdr ) && ( ulAdr < (RDM_VIRT_ID_END) ))
{
ResponseCode = DiagR_CalcSrcAddressForVirtID(&pReadAddress, apfnGetVirtDataUserStructs, ulAdr, ulNumOfBytes, (uint8)eMaxCmdRdmList);
}
else
{
ResponseCode = 0x22u; //DCM_E_CONDITIONSNOTCORRECT;
}
#endif
}
/* Address is OK? */
if (pReadAddress != (uint8*) 0)
{
pMsgContext->resDataLen = (uint16)ulNumOfBytes;
while (ulNumOfBytes-- != 0U)
{
*pucResData = *pReadAddress;
pucResData++; pReadAddress++;
}
}
}
return ResponseCode;
}
//-----------------------------------------------------------------------------
/// \brief DiagR_WriteMemByAddress
///
/// \descr
///
/// \param -
///
/// \return void
//-----------------------------------------------------------------------------
// PRQA S 3408 1 // It is actually being declared using macros
uint8 ApplCmd_Rdm_WriteMemByAddr( MsgContextType* const pMsgContext )
{
uint8 ResponseCode = 0;
const uint8 *pucReqData = pMsgContext->reqData;
const uint16 unReqDataLen = pMsgContext->reqDataLen;
// Evt. hier auch noch mit CallBack Technik arbeiten, fur den Fall das die Ausfuhrung langer dauert.
// Write Memory by Address mit Lange 0 wird ebenfalls aktzeptiert, aber 0 Bytes geschrieben.
{
const uint8 ucNumberOfBytesForLen = pucReqData[0U + APPLCMD_RDM_MESSAGE_OFFSET] >> 4U;
const uint8 ucNumberOfBytesForAdr = pucReqData[0U + APPLCMD_RDM_MESSAGE_OFFSET] & 0x0fU;
const uint8 *const pucLenInfo = &pucReqData[1U + APPLCMD_RDM_MESSAGE_OFFSET] + ucNumberOfBytesForAdr;
uint32 ulNumOfBytes, ulAdr;
ulAdr = (ucNumberOfBytesForAdr == 1U) ? ((uint32)pucReqData[1U + APPLCMD_RDM_MESSAGE_OFFSET]<< 0U) :
(ucNumberOfBytesForAdr == 2U) ? ((uint32)pucReqData[1U + APPLCMD_RDM_MESSAGE_OFFSET]<< 8U) | ((uint32)pucReqData[2U + APPLCMD_RDM_MESSAGE_OFFSET]<< 0U) :
(ucNumberOfBytesForAdr == 3U) ? ((uint32)pucReqData[1U + APPLCMD_RDM_MESSAGE_OFFSET]<<16U) | ((uint32)pucReqData[2U + APPLCMD_RDM_MESSAGE_OFFSET]<< 8U) | ((uint32)pucReqData[3U + APPLCMD_RDM_MESSAGE_OFFSET]<< 0U) :
(ucNumberOfBytesForAdr == 4U) ? ((uint32)pucReqData[1U + APPLCMD_RDM_MESSAGE_OFFSET]<<24U) | ((uint32)pucReqData[2U + APPLCMD_RDM_MESSAGE_OFFSET]<<16U) | ((uint32)pucReqData[3U + APPLCMD_RDM_MESSAGE_OFFSET]<< 8U) | ((uint32)pucReqData[4U + APPLCMD_RDM_MESSAGE_OFFSET]<< 0U) :
(uint32)0xffffffffU;
ulNumOfBytes = (ucNumberOfBytesForLen == 1U) ? ((uint32)pucLenInfo[0U] << 0U) :
(ucNumberOfBytesForLen == 2U) ? ((uint32)pucLenInfo[0U] << 8U ) | ((uint32)pucLenInfo[1U] << 0U) :
(ucNumberOfBytesForLen == 3U) ? ((uint32)pucLenInfo[0U] << 16U) | ((uint32)pucLenInfo[1U] << 8U) | ((uint32)pucLenInfo[2U] << 0U) :
(ucNumberOfBytesForLen == 4U) ? ((uint32)pucLenInfo[0U] << 24U) | ((uint32)pucLenInfo[1U] << 16U) | ((uint32)pucLenInfo[2U] << 8U) | ((uint32)pucLenInfo[3U] << 0U) :
(uint32)0xffffffffU;
if ( (ulAdr == (uint32)0xffffffffU) || (ulNumOfBytes == (uint32)0xffffffffU) )
{
ResponseCode = 0x31u /*DCM_E_REQUESTOUTOFRANGE*/;
}
else if (unReqDataLen != (uint16)(1U + (uint16)ucNumberOfBytesForAdr + (uint16)ucNumberOfBytesForLen + (uint16)ulNumOfBytes))
{
ResponseCode = 0x13u /*DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT*/;
}
else
{
// do nothing
}
if (ResponseCode == 0U)
{
const uint8 *pSrc = &pucReqData[1] + ucNumberOfBytesForLen + ucNumberOfBytesForAdr;
uint8 *pDest = NULL_PTR;
if( ( RDM_RAM_BEGIN <= ulAdr ) && ( ulAdr < RDM_RAM_END ) ) // RAM area
{
// PRQA S 306 1 // correct cast - working with actual address
pDest = (uint8*)(ulAdr);
}
else
{
#ifndef PRJ_TYP_Sb015
if ( ( RDM_VIRT_ID_BEGIN <= ulAdr ) && ( ulAdr < RDM_VIRT_ID_END ))
{
ResponseCode = DiagR_CalcSrcAddressForVirtID(&pDest, apfnGetVirtDataUserStructs, ulAdr, ulNumOfBytes, (uint8)eMaxCmdRdmList);
}
else
{
ResponseCode = 0x22u; //DCM_E_CONDITIONSNOTCORRECT;
}
#endif
}
if (pDest != NULL_PTR)
{
// Only Serv-Id as positive reply no further data required.
pMsgContext->resDataLen = (uint16)0;
while (ulNumOfBytes-- != 0U)
{
*pDest = *pSrc;
pDest++; pSrc++;
}
}
}
}
return ResponseCode;
}
//-----------------------------------------------------------------------------
/// \brief DiagR_CalcSrcAddressForVirtID
///
/// \descr
///
/// \param -
///
/// \return void
//-----------------------------------------------------------------------------
//=============================================================================
// Private functions definition
//=============================================================================
#ifndef PRJ_TYP_Sb015
static uint8 DiagR_CalcSrcAddressForVirtID(uint8** ppSrc,
const tpfnGetVirtData* pfnGetVirtData,
uint32 ulAdr,
uint32 ulNumOfBytes,
uint8 ucMaxTableEntries)
{
uint8 ResponseCode = 0x22;
uint8 ucVirtID = (uint8)((ulAdr >> RDM_BITPOS_VIRT_ID) & RDM_VIRT_ID_MASK);
uint16 ulAddressOffset = (uint16)(ulAdr & RDM_ADDROFFSET_MASK);
/* ID is in range? */
if(ucVirtID < ucMaxTableEntries)
{
uint32 ulSize = 0;
uint8* pucStartAddress = (uint8*)0;
/* Check if entry exists in table. Reserved entries have NULL as value. */
if (pfnGetVirtData[ucVirtID] != NULL_PTR)
{
/* Get the start address. */
pucStartAddress = (uint8*)(pfnGetVirtData[ucVirtID])(&ulSize);
}
/* Verify address and length. */
if ( (pucStartAddress != (uint8*)0) &&
( (ulAddressOffset + ulNumOfBytes) <= ulSize) )
{
*ppSrc = (uint8*)&pucStartAddress[ulAddressOffset];
ResponseCode = 0;
}
}
return ResponseCode;
}
#endif
#endif
//-----------------------------------------------------------------------------
/// \brief ApplCmd_Rdm_StartSession
///
/// \descr
///
/// \param -
///
/// \return void
//-----------------------------------------------------------------------------
// PRQA S 3408 1 // It is actually being declared using macros
//=============================================================================
// Public functions definition
//=============================================================================
// PRQA S 3408 1 // It is actually being declared using macros
uint8 ApplCmd_Rdm_StartSession( MsgContextType *const pMsgContext )
{
uint8 cnt = 0U;
pMsgContext->resData[cnt++] = pMsgContext->reqData[0];
pMsgContext->resData[cnt++] = 0xFFu; // P2SERVER_MAX MSB
pMsgContext->resData[cnt++] = 0xFFu; // P2SERVER_MAX LSB
pMsgContext->resData[cnt++] = 0xFFu; // P2STRSERVER_MAX/10 MSB
pMsgContext->resData[cnt++] = 0xFFu; // P2STRSERVER_MAX/10 LSB
pMsgContext->resDataLen = cnt;
return 0U;
}
//-----------------------------------------------------------------------------
/// \brief ApplCmd_Rdm_SecurityAccess
///
/// \descr
///
/// \param -
///
/// \return void
//-----------------------------------------------------------------------------
// PRQA S 3408 1 // It is actually being declared using macros
uint8 ApplCmd_Rdm_SecurityAccess( MsgContextType *const pMsgContext )
{
uint8 cnt = 0U;
pMsgContext->resData[cnt++] = pMsgContext->reqData[0U + APPLCMD_RDM_MESSAGE_OFFSET];
pMsgContext->resData[cnt++] = pMsgContext->reqData[1U + APPLCMD_RDM_MESSAGE_OFFSET];
pMsgContext->resData[cnt++] = pMsgContext->reqData[2U + APPLCMD_RDM_MESSAGE_OFFSET];
pMsgContext->resData[cnt++] = 0U; // Result code 0: No Erro
pMsgContext->resDataLen = cnt;
return 0U;
}