diff options
Diffstat (limited to 'drivers/staging/epl/EplObd.c')
-rw-r--r-- | drivers/staging/epl/EplObd.c | 3505 |
1 files changed, 3505 insertions, 0 deletions
diff --git a/drivers/staging/epl/EplObd.c b/drivers/staging/epl/EplObd.c new file mode 100644 index 00000000000..0f4db892a62 --- /dev/null +++ b/drivers/staging/epl/EplObd.c @@ -0,0 +1,3505 @@ +/**************************************************************************** + + (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 + www.systec-electronic.com + + Project: openPOWERLINK + + Description: source file for api function of EplOBD-Module + + License: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SYSTEC electronic GmbH nor the names of its + contributors may be used to endorse or promote products derived + from this software without prior written permission. For written + permission, please contact info@systec-electronic.com. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Severability Clause: + + If a provision of this License is or becomes illegal, invalid or + unenforceable in any jurisdiction, that shall not affect: + 1. the validity or enforceability in that jurisdiction of any other + provision of this License; or + 2. the validity or enforceability in other jurisdictions of that or + any other provision of this License. + + ------------------------------------------------------------------------- + + $RCSfile: EplObd.c,v $ + + $Author: D.Krueger $ + + $Revision: 1.12 $ $Date: 2008/10/17 15:32:32 $ + + $State: Exp $ + + Build Environment: + Microsoft VC7 + + ------------------------------------------------------------------------- + + Revision History: + + 2006/06/02 k.t.: start of the implementation, version 1.00 + ->based on CANopen OBD-Modul + +****************************************************************************/ + +#include "EplInc.h" +#include "kernel/EplObdk.h" // function prototyps of the EplOBD-Modul + +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) + +/***************************************************************************/ +/* */ +/* */ +/* G L O B A L D E F I N I T I O N S */ +/* */ +/* */ +/***************************************************************************/ + +//--------------------------------------------------------------------------- +// const defines +//--------------------------------------------------------------------------- + +// float definitions and macros +#define _SHIFTED_EXPONENT_MASK_SP 0xff +#define _BIAS_SP 126 +#define T_SP 23 +#define EXPONENT_DENORM_SP (-_BIAS_SP) +#define BASE_TO_THE_T_SP ((float) 8388608.0) +#define GET_EXPONENT_SP(x) ((((x) >> T_SP) & _SHIFTED_EXPONENT_MASK_SP) - _BIAS_SP) + + +//--------------------------------------------------------------------------- +// local types +//--------------------------------------------------------------------------- + +// struct for instance table +INSTANCE_TYPE_BEGIN + + EPL_MCO_DECL_INSTANCE_MEMBER () + + STATIC tEplObdInitParam INST_FAR m_ObdInitParam; + STATIC tEplObdStoreLoadObjCallback INST_NEAR m_fpStoreLoadObjCallback; + +INSTANCE_TYPE_END + +// decomposition of float +typedef union +{ + tEplObdReal32 m_flRealPart; + int m_nIntegerPart; + +} tEplObdRealParts; + + +//--------------------------------------------------------------------------- +// modul globale vars +//--------------------------------------------------------------------------- + +// This macro replace the unspecific pointer to an instance through +// the modul specific type for the local instance table. This macro +// must defined in each modul. +//#define tEplPtrInstance tEplInstanceInfo MEM* + +EPL_MCO_DECL_INSTANCE_VAR () + +BYTE MEM abEplObdTrashObject_g[8]; + + +//--------------------------------------------------------------------------- +// local function prototypes +//--------------------------------------------------------------------------- + +EPL_MCO_DEFINE_INSTANCE_FCT () + +static tEplKernel EplObdCallObjectCallback (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdCallback fpCallback_p, + tEplObdCbParam MEM* pCbParam_p); + +static tEplObdSize EplObdGetDataSizeIntern (tEplObdSubEntryPtr pSubIndexEntry_p); + +static tEplObdSize EplObdGetStrLen (void* pObjData_p, + tEplObdSize ObjLen_p, + tEplObdType ObjType_p); + +#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) +static tEplKernel EplObdCheckObjectRange ( + tEplObdSubEntryPtr pSubindexEntry_p, + void * pData_p); +#endif + +static tEplKernel EplObdGetVarEntry ( + tEplObdSubEntryPtr pSubindexEntry_p, + tEplObdVarEntry MEM** ppVarEntry_p); + +static tEplKernel EplObdGetEntry (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubindex_p, + tEplObdEntryPtr* ppObdEntry_p, + tEplObdSubEntryPtr* ppObdSubEntry_p); + +static tEplObdSize EplObdGetObjectSize (tEplObdSubEntryPtr pSubIndexEntry_p); + +static tEplKernel EplObdGetIndexIntern ( + tEplObdInitParam MEM* pInitParam_p, + unsigned int uiIndex_p, + tEplObdEntryPtr* ppObdEntry_p); + +static tEplKernel EplObdGetSubindexIntern ( + tEplObdEntryPtr pObdEntry_p, + unsigned int uiSubIndex_p, + tEplObdSubEntryPtr* ppObdSubEntry_p); + +static tEplKernel EplObdAccessOdPartIntern (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdPart CurrentOdPart_p, + tEplObdEntryPtr pObdEnty_p, + tEplObdDir Direction_p); + +static void * EplObdGetObjectDefaultPtr (tEplObdSubEntryPtr pSubIndexEntry_p); +static void MEM* EplObdGetObjectCurrentPtr (tEplObdSubEntryPtr pSubIndexEntry_p); + +#if (EPL_OBD_USE_STORE_RESTORE != FALSE) + + static tEplKernel EplObdCallStoreCallback (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdCbStoreParam MEM* pCbStoreParam_p); + +#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) + +static void EplObdCopyObjectData ( + void MEM* pDstData_p, + void * pSrcData_p, + tEplObdSize ObjSize_p, + tEplObdType ObjType_p); + +void * EplObdGetObjectDataPtrIntern (tEplObdSubEntryPtr pSubindexEntry_p); + +static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p, + BOOL* pfEntryNumerical_p); + +static tEplKernel PUBLIC EplObdWriteEntryPre (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p, + void * pSrcData_p, + void** ppDstData_p, + tEplObdSize Size_p, + tEplObdEntryPtr* ppObdEntry_p, + tEplObdSubEntryPtr* ppSubEntry_p, + tEplObdCbParam MEM* pCbParam_p, + tEplObdSize* pObdSize_p); + +static tEplKernel PUBLIC EplObdWriteEntryPost (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdEntryPtr pObdEntry_p, + tEplObdSubEntryPtr pSubEntry_p, + tEplObdCbParam MEM* pCbParam_p, + void * pSrcData_p, + void * pDstData_p, + tEplObdSize ObdSize_p); + + + +//=========================================================================// +// // +// P U B L I C F U N C T I O N S // +// // +//=========================================================================// + +//--------------------------------------------------------------------------- +// +// Function: EplObdInit() +// +// Description: initializes the first instance +// +// Parameters: pInitParam_p = init parameter +// +// Return: tEplKernel = errorcode +// +// State: +// +//--------------------------------------------------------------------------- + +EPLDLLEXPORT tEplKernel PUBLIC EplObdInit (EPL_MCO_DECL_PTR_INSTANCE_PTR_ + tEplObdInitParam MEM* pInitParam_p) +{ + +tEplKernel Ret; +EPL_MCO_DELETE_INSTANCE_TABLE (); + + if (pInitParam_p == NULL) + { + Ret = kEplSuccessful; + goto Exit; + } + + Ret = EplObdAddInstance (EPL_MCO_PTR_INSTANCE_PTR_ + pInitParam_p); + +Exit: + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdAddInstance() +// +// Description: adds a new instance +// +// Parameters: pInitParam_p +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance (EPL_MCO_DECL_PTR_INSTANCE_PTR_ + tEplObdInitParam MEM* pInitParam_p) +{ + +EPL_MCO_DECL_INSTANCE_PTR_LOCAL +tEplKernel Ret; + + // check if pointer to instance pointer valid + // get free instance and set the globale instance pointer + // set also the instance addr to parameterlist + EPL_MCO_CHECK_PTR_INSTANCE_PTR (); + EPL_MCO_GET_FREE_INSTANCE_PTR (); + EPL_MCO_SET_PTR_INSTANCE_PTR (); + + // save init parameters + EPL_MEMCPY (&EPL_MCO_GLB_VAR (m_ObdInitParam), pInitParam_p, sizeof (tEplObdInitParam)); + + // clear callback function for command LOAD and STORE + EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) = NULL; + + // sign instance as used + EPL_MCO_WRITE_INSTANCE_STATE (kStateUsed); + + // initialize object dictionary + // so all all VarEntries will be initialized to trash object and default values will be set to current data + Ret = EplObdAccessOdPart (EPL_MCO_INSTANCE_PTR_ + kEplObdPartAll, kEplObdDirInit); + + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdDeleteInstance() +// +// Description: delete instance +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- +#if (EPL_USE_DELETEINST_FUNC != FALSE) +EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance (EPL_MCO_DECL_INSTANCE_PTR) +{ + // check for all API function if instance is valid + EPL_MCO_CHECK_INSTANCE_STATE (); + + // sign instance as unused + EPL_MCO_WRITE_INSTANCE_STATE (kStateUnused); + + return kEplSuccessful; + +} +#endif // (EPL_USE_DELETEINST_FUNC != FALSE) + + +//--------------------------------------------------------------------------- +// +// Function: EplObdWriteEntry() +// +// Description: Function writes data to an OBD entry. Strings +// are stored with added '\0' character. +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ +// uiIndex_p = Index of the OD entry +// uiSubIndex_p = Subindex of the OD Entry +// pSrcData_p = Pointer to the data to write +// Size_p = Size of the data in Byte +// +// Return: tEplKernel = Errorcode +// +// +// State: +// +//--------------------------------------------------------------------------- + +EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p, + void * pSrcData_p, + tEplObdSize Size_p) +{ + +tEplKernel Ret; +tEplObdEntryPtr pObdEntry; +tEplObdSubEntryPtr pSubEntry; +tEplObdCbParam MEM CbParam; +void MEM* pDstData; +tEplObdSize ObdSize; + + + Ret = EplObdWriteEntryPre (EPL_MCO_INSTANCE_PTR_ + uiIndex_p, + uiSubIndex_p, + pSrcData_p, + &pDstData, + Size_p, + &pObdEntry, + &pSubEntry, + &CbParam, + &ObdSize); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + Ret = EplObdWriteEntryPost (EPL_MCO_INSTANCE_PTR_ + pObdEntry, + pSubEntry, + &CbParam, + pSrcData_p, + pDstData, + ObdSize); + if (Ret != kEplSuccessful) + { + goto Exit; + } + +Exit: + + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdReadEntry() +// +// Description: The function reads an object entry. The application +// can always read the data even if attrib kEplObdAccRead +// is not set. The attrib is only checked up for SDO transfer. +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ +// uiIndex_p = Index oof the OD entry to read +// uiSubIndex_p = Subindex to read +// pDstData_p = pointer to the buffer for data +// Offset_p = offset in data for read access +// pSize_p = IN: Size of the buffer +// OUT: number of readed Bytes +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p, + void * pDstData_p, + tEplObdSize * pSize_p) +{ + +tEplKernel Ret; +tEplObdEntryPtr pObdEntry; +tEplObdSubEntryPtr pSubEntry; +tEplObdCbParam MEM CbParam; +void * pSrcData; +tEplObdSize ObdSize; + + // check for all API function if instance is valid + EPL_MCO_CHECK_INSTANCE_STATE (); + + ASSERT (pDstData_p != NULL); + ASSERT (pSize_p != NULL); + + // get address of index and subindex entry + Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_ + uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // get pointer to object data + pSrcData = EplObdGetObjectDataPtrIntern (pSubEntry); + + // check source pointer + if (pSrcData == NULL) + { + Ret = kEplObdReadViolation; + goto Exit; + } + + //------------------------------------------------------------------------ + // address of source data to structure of callback parameters + // so callback function can change this data before reading + CbParam.m_uiIndex = uiIndex_p; + CbParam.m_uiSubIndex= uiSubIndex_p; + CbParam.m_pArg = pSrcData; + CbParam.m_ObdEvent = kEplObdEvPreRead; + Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_ + pObdEntry->m_fpCallback, &CbParam); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // get size of data and check if application has reserved enough memory + ObdSize = EplObdGetDataSizeIntern (pSubEntry); + // check if offset given and calc correct number of bytes to read + if (*pSize_p < ObdSize) + { + Ret = kEplObdValueLengthError; + goto Exit; + } + + // read value from object + EPL_MEMCPY (pDstData_p, pSrcData, ObdSize); + *pSize_p = ObdSize; + + // write address of destination data to structure of callback parameters + // so callback function can change this data after reading + CbParam.m_pArg = pDstData_p; + CbParam.m_ObdEvent = kEplObdEvPostRead; + Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_ + pObdEntry->m_fpCallback, &CbParam); + +Exit: + + return Ret; + +} + +//--------------------------------------------------------------------------- +// +// Function: EplObdAccessOdPart() +// +// Description: restores default values of one part of OD +// +// Parameters: ObdPart_p +// Direction_p +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdPart ObdPart_p, + tEplObdDir Direction_p) +{ + +tEplKernel Ret = kEplSuccessful; +BOOL fPartFount; +tEplObdEntryPtr pObdEntry; + + // check for all API function if instance is valid + EPL_MCO_CHECK_INSTANCE_STATE (); + + // part always has to be unequal to NULL + pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pPart); + ASSERTMSG (pObdEntry != NULL, "EplObdAccessOdPart(): no OD part is defined!\n"); + + // if ObdPart_p is not valid fPartFound keeps FALSE and function returns kEplObdIllegalPart + fPartFount = FALSE; + + // access to part + if ((ObdPart_p & kEplObdPartGen) != 0) + { + fPartFount = TRUE; + + Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_ + kEplObdPartGen, pObdEntry, Direction_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } + } + + // access to manufacturer part + pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pManufacturerPart); + + if ( ((ObdPart_p & kEplObdPartMan) != 0) && + (pObdEntry != NULL) ) + { + fPartFount = TRUE; + + Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_ + kEplObdPartMan, pObdEntry, Direction_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } + } + + // access to device part + pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pDevicePart); + + if ( ((ObdPart_p & kEplObdPartDev) != 0) && + (pObdEntry != NULL) ) + { + fPartFount = TRUE; + + Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_ + kEplObdPartDev, pObdEntry, Direction_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } + } + + #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) + { + // access to user part + pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pUserPart); + + if ( ((ObdPart_p & kEplObdPartUsr) != 0) && + (pObdEntry != NULL) ) + { + fPartFount = TRUE; + + Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_ + kEplObdPartUsr, pObdEntry, Direction_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } + } + } + #endif + + // no access to an OD part was done? illegal OD part was specified! + if (fPartFount == FALSE) + { + Ret = kEplObdIllegalPart; + } + +Exit: + + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdDefineVar() +// +// Description: defines a variable in OD +// +// Parameters: pEplVarParam_p +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar (EPL_MCO_DECL_INSTANCE_PTR_ + tEplVarParam MEM* pVarParam_p) +{ + +tEplKernel Ret; +tEplObdVarEntry MEM* pVarEntry; +tEplVarParamValid VarValid; +tEplObdSubEntryPtr pSubindexEntry; + + // check for all API function if instance is valid + EPL_MCO_CHECK_INSTANCE_STATE (); + + ASSERT (pVarParam_p != NULL); // is not allowed to be NULL + + // get address of subindex entry + Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_ + pVarParam_p->m_uiIndex, + pVarParam_p->m_uiSubindex, + NULL, &pSubindexEntry); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // get var entry + Ret = EplObdGetVarEntry (pSubindexEntry, &pVarEntry); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + VarValid = pVarParam_p->m_ValidFlag; + + // copy only this values, which valid flag is set + if ((VarValid & kVarValidSize) != 0) + { + if (pSubindexEntry->m_Type != kEplObdTypDomain) + { + tEplObdSize DataSize; + + // check passed size parameter + DataSize = EplObdGetObjectSize(pSubindexEntry); + if (DataSize != pVarParam_p->m_Size) + { // size of variable does not match + Ret = kEplObdValueLengthError; + goto Exit; + } + } + else + { // size can be set only for objects of type DOMAIN + pVarEntry->m_Size = pVarParam_p->m_Size; + } + } + + if ((VarValid & kVarValidData) != 0) + { + pVarEntry->m_pData = pVarParam_p->m_pData; + } +/* + #if (EPL_PDO_USE_STATIC_MAPPING == FALSE) + { + if ((VarValid & kVarValidCallback) != 0) + { + pVarEntry->m_fpCallback = pVarParam_p->m_fpCallback; + } + + if ((VarValid & kVarValidArg) != 0) + { + pVarEntry->m_pArg = pVarParam_p->m_pArg; + } + } + #endif +*/ + // Ret is already set to kEplSuccessful from ObdGetVarIntern() + +Exit: + + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetObjectDataPtr() +// +// Description: It returnes the current data pointer. But if object is an +// constant object it returnes the default pointer. +// +// Parameters: uiIndex_p = Index of the entry +// uiSubindex_p = Subindex of the entry +// +// Return: void * = pointer to object data +// +// State: +// +//--------------------------------------------------------------------------- + +EPLDLLEXPORT void * PUBLIC EplObdGetObjectDataPtr (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p) + { +tEplKernel Ret; +void * pData; +tEplObdEntryPtr pObdEntry; +tEplObdSubEntryPtr pObdSubEntry; + + + // get pointer to index structure + Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam), + uiIndex_p, + &pObdEntry); + if(Ret != kEplSuccessful) + { + pData = NULL; + goto Exit; + } + + // get pointer to subindex structure + Ret = EplObdGetSubindexIntern (pObdEntry, + uiSubIndex_p, + &pObdSubEntry); + if(Ret != kEplSuccessful) + { + pData = NULL; + goto Exit; + } + // get Datapointer + pData = EplObdGetObjectDataPtrIntern(pObdSubEntry); + +Exit: + return pData; + +} + + +#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) + +//--------------------------------------------------------------------------- +// +// Function: EplObdRegisterUserOd() +// +// Description: function registers the user OD +// +// Parameters: pUserOd_p =pointer to user ODd +// +// Return: tEplKernel = errorcode +// +// State: +// +//--------------------------------------------------------------------------- +EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdEntryPtr pUserOd_p) +{ + + EPL_MCO_CHECK_INSTANCE_STATE (); + + EPL_MCO_GLB_VAR (m_ObdInitParam.m_pUserPart) = pUserOd_p; + + return kEplSuccessful; + +} + +#endif + + +//--------------------------------------------------------------------------- +// +// Function: EplObdInitVarEntry() +// +// Description: function to initialize VarEntry dependened on object type +// +// Parameters: pVarEntry_p = pointer to var entry structure +// Type_p = object type +// ObdSize_p = size of object data +// +// Returns: none +// +// State: +// +//--------------------------------------------------------------------------- + +EPLDLLEXPORT void PUBLIC EplObdInitVarEntry (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdVarEntry MEM* pVarEntry_p, + tEplObdType Type_p, tEplObdSize ObdSize_p) +{ +/* + #if (EPL_PDO_USE_STATIC_MAPPING == FALSE) + { + // reset pointer to VAR callback and argument + pVarEntry_p->m_fpCallback = NULL; + pVarEntry_p->m_pArg = NULL; + } + #endif +*/ + +// 10-dec-2004 r.d.: this function will not be used for strings + if ((Type_p == kEplObdTypDomain)) +// (bType_p == kEplObdTypVString) /* || +// (bType_p == kEplObdTypOString) || +// (bType_p == kEplObdTypUString) */ ) + { + // variables which are defined as DOMAIN or VSTRING should not point to + // trash object, because this trash object contains only 8 bytes. DOMAINS or + // STRINGS can be longer. + pVarEntry_p->m_pData = NULL; + pVarEntry_p->m_Size = 0; + } + else + { + // set address to variable data to trash object + // This prevents an access violation if user forgets to call EplObdDefineVar() + // for this variable but mappes it in a PDO. + pVarEntry_p->m_pData = &abEplObdTrashObject_g[0]; + pVarEntry_p->m_Size = ObdSize_p; + } + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetDataSize() +// +// Description: function to initialize VarEntry dependened on object type +// +// gets the data size of an object +// for string objects it returnes the string length +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer +// uiIndex_p = Index +// uiSubIndex_p= Subindex +// +// Return: tEplObdSize +// +// State: +// +//--------------------------------------------------------------------------- +EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p) +{ +tEplKernel Ret; +tEplObdSize ObdSize; +tEplObdEntryPtr pObdEntry; +tEplObdSubEntryPtr pObdSubEntry; + + + // get pointer to index structure + Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam), + uiIndex_p, + &pObdEntry); + if(Ret != kEplSuccessful) + { + ObdSize = 0; + goto Exit; + } + + // get pointer to subindex structure + Ret = EplObdGetSubindexIntern (pObdEntry, + uiSubIndex_p, + &pObdSubEntry); + if(Ret != kEplSuccessful) + { + ObdSize = 0; + goto Exit; + } + + // get size + ObdSize = EplObdGetDataSizeIntern (pObdSubEntry); +Exit: + return ObdSize; +} +//--------------------------------------------------------------------------- +// +// Function: EplObdGetNodeId() +// +// Description: function returns nodeid from entry 0x1F93 +// +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR = Instancepointer +// +// Return: unsigned int = Node Id +// +// State: +// +//--------------------------------------------------------------------------- +EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR) +{ +tEplKernel Ret; +tEplObdSize ObdSize; +BYTE bNodeId; + + bNodeId = 0; + ObdSize = sizeof(bNodeId); + Ret = EplObdReadEntry(EPL_MCO_PTR_INSTANCE_PTR_ + EPL_OBD_NODE_ID_INDEX, + EPL_OBD_NODE_ID_SUBINDEX, + &bNodeId, + &ObdSize); + if(Ret != kEplSuccessful) + { + bNodeId = EPL_C_ADR_INVALID; + goto Exit; + } + +Exit: + return (unsigned int) bNodeId; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdSetNodeId() +// +// Description: function sets nodeid in entry 0x1F93 +// +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer +// uiNodeId_p = Node Id to set +// NodeIdType_p= Type on which way the Node Id was set +// +// Return: tEplKernel = Errorcode +// +// State: +// +//--------------------------------------------------------------------------- +EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ + unsigned int uiNodeId_p, + tEplObdNodeIdType NodeIdType_p) +{ +tEplKernel Ret; +tEplObdSize ObdSize; +BYTE fHwBool; +BYTE bNodeId; + + // check Node Id + if(uiNodeId_p == EPL_C_ADR_INVALID) + { + Ret = kEplInvalidNodeId; + goto Exit; + } + bNodeId = (BYTE)uiNodeId_p; + ObdSize = sizeof(BYTE); + // write NodeId to OD entry + Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_ + EPL_OBD_NODE_ID_INDEX, + EPL_OBD_NODE_ID_SUBINDEX, + &bNodeId, + ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // set HWBOOL-Flag in Subindex EPL_OBD_NODE_ID_HWBOOL_SUBINDEX + switch (NodeIdType_p) + { + // type unknown + case kEplObdNodeIdUnknown: + { + fHwBool = OBD_FALSE; + break; + } + + case kEplObdNodeIdSoftware: + { + fHwBool = OBD_FALSE; + break; + } + + case kEplObdNodeIdHardware: + { + fHwBool = OBD_TRUE; + break; + } + + default: + { + fHwBool = OBD_FALSE; + } + + } // end of switch (NodeIdType_p) + + // write flag + ObdSize = sizeof(fHwBool); + Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR + EPL_OBD_NODE_ID_INDEX, + EPL_OBD_NODE_ID_HWBOOL_SUBINDEX, + &fHwBool, + ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + +Exit: + return Ret; +} + +//--------------------------------------------------------------------------- +// +// Function: EplObdIsNumerical() +// +// Description: function checks if a entry is numerical or not +// +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer +// uiIndex_p = Index +// uiSubIndex_p = Subindex +// pfEntryNumerical_p = pointer to BOOL for returnvalue +// -> TRUE if entry a numerical value +// -> FALSE if entry not a numerical value +// +// Return: tEplKernel = Errorcode +// +// State: +// +//--------------------------------------------------------------------------- +EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p, + BOOL* pfEntryNumerical_p) +{ +tEplKernel Ret; +tEplObdEntryPtr pObdEntry; +tEplObdSubEntryPtr pObdSubEntry; + + + // get pointer to index structure + Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam), + uiIndex_p, + &pObdEntry); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // get pointer to subindex structure + Ret = EplObdGetSubindexIntern (pObdEntry, + uiSubIndex_p, + &pObdSubEntry); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + Ret = EplObdIsNumericalIntern(pObdSubEntry, pfEntryNumerical_p); + + +Exit: + return Ret; + +} + +//--------------------------------------------------------------------------- +// +// Function: EplObdReadEntryToLe() +// +// Description: The function reads an object entry from the byteoder +// of the system to the little endian byteorder for numerical values. +// For other types a normal read will be processed. This is usefull for +// the PDO and SDO module. The application +// can always read the data even if attrib kEplObdAccRead +// is not set. The attrib is only checked up for SDO transfer. +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ +// uiIndex_p = Index of the OD entry to read +// uiSubIndex_p = Subindex to read +// pDstData_p = pointer to the buffer for data +// Offset_p = offset in data for read access +// pSize_p = IN: Size of the buffer +// OUT: number of readed Bytes +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- +EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p, + void * pDstData_p, + tEplObdSize * pSize_p) +{ +tEplKernel Ret; +tEplObdEntryPtr pObdEntry; +tEplObdSubEntryPtr pSubEntry; +tEplObdCbParam MEM CbParam; +void * pSrcData; +tEplObdSize ObdSize; + + // check for all API function if instance is valid + EPL_MCO_CHECK_INSTANCE_STATE (); + + ASSERT (pDstData_p != NULL); + ASSERT (pSize_p != NULL); + + // get address of index and subindex entry + Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_ + uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // get pointer to object data + pSrcData = EplObdGetObjectDataPtrIntern (pSubEntry); + + // check source pointer + if (pSrcData == NULL) + { + Ret = kEplObdReadViolation; + goto Exit; + } + + //------------------------------------------------------------------------ + // address of source data to structure of callback parameters + // so callback function can change this data before reading + CbParam.m_uiIndex = uiIndex_p; + CbParam.m_uiSubIndex= uiSubIndex_p; + CbParam.m_pArg = pSrcData; + CbParam.m_ObdEvent = kEplObdEvPreRead; + Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_ + pObdEntry->m_fpCallback, &CbParam); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // get size of data and check if application has reserved enough memory + ObdSize = EplObdGetDataSizeIntern (pSubEntry); + // check if offset given and calc correct number of bytes to read + if (*pSize_p < ObdSize) + { + Ret = kEplObdValueLengthError; + goto Exit; + } + + // check if numerical type + switch(pSubEntry->m_Type) + { + //----------------------------------------------- + // types without ami + case kEplObdTypVString: + case kEplObdTypOString: + case kEplObdTypDomain: + default: + { + // read value from object + EPL_MEMCPY (pDstData_p, pSrcData, ObdSize); + break; + } + + //----------------------------------------------- + // numerical type which needs ami-write + // 8 bit or smaller values + case kEplObdTypBool: + case kEplObdTypInt8: + case kEplObdTypUInt8: + { + AmiSetByteToLe(pDstData_p, *((BYTE*)pSrcData)); + break; + } + + // 16 bit values + case kEplObdTypInt16: + case kEplObdTypUInt16: + { + AmiSetWordToLe(pDstData_p, *((WORD*)pSrcData)); + break; + } + + // 24 bit values + case kEplObdTypInt24: + case kEplObdTypUInt24: + { + AmiSetDword24ToLe(pDstData_p, *((DWORD*)pSrcData)); + break; + } + + // 32 bit values + case kEplObdTypInt32: + case kEplObdTypUInt32: + case kEplObdTypReal32: + { + AmiSetDwordToLe(pDstData_p, *((DWORD*)pSrcData)); + break; + } + + // 40 bit values + case kEplObdTypInt40: + case kEplObdTypUInt40: + { + AmiSetQword40ToLe(pDstData_p, *((QWORD*)pSrcData)); + break; + } + + // 48 bit values + case kEplObdTypInt48: + case kEplObdTypUInt48: + { + AmiSetQword48ToLe(pDstData_p, *((QWORD*)pSrcData)); + break; + } + + // 56 bit values + case kEplObdTypInt56: + case kEplObdTypUInt56: + { + AmiSetQword56ToLe(pDstData_p, *((QWORD*)pSrcData)); + break; + } + + // 64 bit values + case kEplObdTypInt64: + case kEplObdTypUInt64: + case kEplObdTypReal64: + { + AmiSetQword64ToLe(pDstData_p, *((QWORD*)pSrcData)); + break; + } + + // time of day + case kEplObdTypTimeOfDay: + case kEplObdTypTimeDiff: + { + AmiSetTimeOfDay(pDstData_p, ((tTimeOfDay*)pSrcData)); + break; + } + + }// end of switch(pSubEntry->m_Type) + + *pSize_p = ObdSize; + + + // write address of destination data to structure of callback parameters + // so callback function can change this data after reading + CbParam.m_pArg = pDstData_p; + CbParam.m_ObdEvent = kEplObdEvPostRead; + Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_ + pObdEntry->m_fpCallback, &CbParam); + +Exit: + + return Ret; + +} + +//--------------------------------------------------------------------------- +// +// Function: EplObdWriteEntryFromLe() +// +// Description: Function writes data to an OBD entry from a source with +// little endian byteorder to the od with system specuific +// byteorder. Not numerical values will only by copied. Strings +// are stored with added '\0' character. +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ +// uiIndex_p = Index of the OD entry +// uiSubIndex_p = Subindex of the OD Entry +// pSrcData_p = Pointer to the data to write +// Size_p = Size of the data in Byte +// +// Return: tEplKernel = Errorcode +// +// +// State: +// +//--------------------------------------------------------------------------- +EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p, + void * pSrcData_p, + tEplObdSize Size_p) +{ +tEplKernel Ret; +tEplObdEntryPtr pObdEntry; +tEplObdSubEntryPtr pSubEntry; +tEplObdCbParam MEM CbParam; +void MEM* pDstData; +tEplObdSize ObdSize; +QWORD qwBuffer; +void* pBuffer = &qwBuffer; + + + Ret = EplObdWriteEntryPre (EPL_MCO_INSTANCE_PTR_ + uiIndex_p, + uiSubIndex_p, + pSrcData_p, + &pDstData, + Size_p, + &pObdEntry, + &pSubEntry, + &CbParam, + &ObdSize); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + + // check if numerical type + switch(pSubEntry->m_Type) + { + //----------------------------------------------- + // types without ami + default: + { // do nothing, i.e. use the given source pointer + pBuffer = pSrcData_p; + break; + } + + //----------------------------------------------- + // numerical type which needs ami-write + // 8 bit or smaller values + case kEplObdTypBool: + case kEplObdTypInt8: + case kEplObdTypUInt8: + { + *((BYTE*)pBuffer) = AmiGetByteFromLe(pSrcData_p); + break; + } + + // 16 bit values + case kEplObdTypInt16: + case kEplObdTypUInt16: + { + *((WORD*)pBuffer) = AmiGetWordFromLe(pSrcData_p); + break; + } + + // 24 bit values + case kEplObdTypInt24: + case kEplObdTypUInt24: + { + *((DWORD*)pBuffer) = AmiGetDword24FromLe(pSrcData_p); + break; + } + + // 32 bit values + case kEplObdTypInt32: + case kEplObdTypUInt32: + case kEplObdTypReal32: + { + *((DWORD*)pBuffer) = AmiGetDwordFromLe(pSrcData_p); + break; + } + + // 40 bit values + case kEplObdTypInt40: + case kEplObdTypUInt40: + { + *((QWORD*)pBuffer) = AmiGetQword40FromLe(pSrcData_p); + break; + } + + // 48 bit values + case kEplObdTypInt48: + case kEplObdTypUInt48: + { + *((QWORD*)pBuffer) = AmiGetQword48FromLe(pSrcData_p); + break; + } + + // 56 bit values + case kEplObdTypInt56: + case kEplObdTypUInt56: + { + *((QWORD*)pBuffer) = AmiGetQword56FromLe(pSrcData_p); + break; + } + + // 64 bit values + case kEplObdTypInt64: + case kEplObdTypUInt64: + case kEplObdTypReal64: + { + *((QWORD*)pBuffer) = AmiGetQword64FromLe(pSrcData_p); + break; + } + + // time of day + case kEplObdTypTimeOfDay: + case kEplObdTypTimeDiff: + { + AmiGetTimeOfDay(pBuffer, ((tTimeOfDay*)pSrcData_p)); + break; + } + + }// end of switch(pSubEntry->m_Type) + + + Ret = EplObdWriteEntryPost (EPL_MCO_INSTANCE_PTR_ + pObdEntry, + pSubEntry, + &CbParam, + pBuffer, + pDstData, + ObdSize); + if (Ret != kEplSuccessful) + { + goto Exit; + } + +Exit: + + return Ret; + +} + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetAccessType() +// +// Description: Function returns accesstype of the entry +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ +// uiIndex_p = Index of the OD entry +// uiSubIndex_p = Subindex of the OD Entry +// pAccessTyp_p = pointer to buffer to store accesstype +// +// Return: tEplKernel = errorcode +// +// +// State: +// +//--------------------------------------------------------------------------- +EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p, + tEplObdAccess* pAccessTyp_p) + +{ +tEplKernel Ret; +tEplObdEntryPtr pObdEntry; +tEplObdSubEntryPtr pObdSubEntry; + + + // get pointer to index structure + Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam), + uiIndex_p, + &pObdEntry); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // get pointer to subindex structure + Ret = EplObdGetSubindexIntern (pObdEntry, + uiSubIndex_p, + &pObdSubEntry); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // get accessType + *pAccessTyp_p = pObdSubEntry->m_Access; + + +Exit: + return Ret; +} + +//--------------------------------------------------------------------------- +// +// Function: EplObdSearchVarEntry() +// +// Description: gets variable from OD +// +// Parameters: uiIndex_p = index of the var entry to search +// uiSubindex_p = subindex of var entry to search +// ppVarEntry_p = pointer to the pointer to the varentry +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +tEplKernel PUBLIC EplObdSearchVarEntry (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubindex_p, + tEplObdVarEntry MEM** ppVarEntry_p) +{ + +tEplKernel Ret; +tEplObdSubEntryPtr pSubindexEntry; + + // check for all API function if instance is valid + EPL_MCO_CHECK_INSTANCE_STATE (); + + // get address of subindex entry + Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_ + uiIndex_p, uiSubindex_p, NULL, &pSubindexEntry); + if (Ret == kEplSuccessful) + { + // get var entry + Ret = EplObdGetVarEntry (pSubindexEntry, ppVarEntry_p); + } + + return Ret; + +} +//=========================================================================// +// // +// P R I V A T E D E F I N I T I O N S // +// // +//=========================================================================// + +EPL_MCO_DECL_INSTANCE_FCT () +//--------------------------------------------------------------------------- +// +// Function: EplObdCallObjectCallback() +// +// Description: calls callback function of an object or of a variable +// +// Parameters: fpCallback_p +// pCbParam_p +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel EplObdCallObjectCallback (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdCallback fpCallback_p, + tEplObdCbParam MEM* pCbParam_p) +{ + +tEplKernel Ret; +tEplObdCallback MEM fpCallback; + + // check for all API function if instance is valid + EPL_MCO_CHECK_INSTANCE_STATE (); + + ASSERT (pCbParam_p != NULL); + + Ret = kEplSuccessful; + + // check address of callback function before calling it + if (fpCallback_p != NULL) + { + // KEIL C51 V6.01 has a bug. + // Therefore the parameter fpCallback_p has to be copied in local variable fpCallback. + fpCallback = fpCallback_p; + + // call callback function for this object + Ret = fpCallback (EPL_MCO_INSTANCE_PARAM_IDX_() + pCbParam_p); + } + + return Ret; +} + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetDataSizeIntern() +// +// Description: gets the data size of an object +// for string objects it returnes the string length +// +// Parameters: pSubIndexEntry_p +// +// Return: tEplObdSize +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplObdSize EplObdGetDataSizeIntern (tEplObdSubEntryPtr pSubIndexEntry_p) +{ + +tEplObdSize DataSize; +void MEM* pData; + + // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING + // then the current pointer is always NULL. The function + // returns the length of default string. + DataSize = EplObdGetObjectSize (pSubIndexEntry_p); + + if (pSubIndexEntry_p->m_Type == kEplObdTypVString) + { + // The pointer to current value can be received from EplObdGetObjectCurrentPtr() + pData = ((void MEM*) EplObdGetObjectCurrentPtr (pSubIndexEntry_p)); + if (pData != NULL) + { + DataSize = EplObdGetStrLen ((void *) pData, DataSize, pSubIndexEntry_p->m_Type); + } + + } + + return DataSize; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetStrLen() +// +// Description: The function calculates the length of string. The '\0' +// character is included!! +// +// Parameters: pObjData_p = pointer to string +// ObjLen_p = max. length of objectr entry +// bObjType_p = object type (VSTRING, ...) +// +// Returns: string length + 1 +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplObdSize EplObdGetStrLen (void * pObjData_p, + tEplObdSize ObjLen_p, + tEplObdType ObjType_p) +{ + +tEplObdSize StrLen = 0; +BYTE * pbString; + + if (pObjData_p == NULL) + { + goto Exit; + } + + //---------------------------------------- + // Visible String: data format byte + if (ObjType_p == kEplObdTypVString) + { + pbString = pObjData_p; + + for (StrLen = 0; StrLen < ObjLen_p; StrLen++) + { + if (*pbString == '\0') + { + StrLen++; + break; + } + + pbString++; + } + } + + //---------------------------------------- + // other string types ... + +Exit: + return (StrLen); + +} + + + +#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) + +//--------------------------------------------------------------------------- +// +// Function: EplObdCheckObjectRange() +// +// Description: function to check value range of object data +// +// NOTICE: The pointer of data (pData_p) must point out to an even address, +// if ObjType is unequal to kEplObdTypInt8 or kEplObdTypUInt8! But it is +// always realiced because pointer m_pDefault points always to an +// array of the SPECIFIED type. +// +// Parameters: pSubindexEntry_p +// pData_p +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel EplObdCheckObjectRange ( + tEplObdSubEntryPtr pSubindexEntry_p, + void * pData_p) +{ + +tEplKernel Ret; +void * pRangeData; + + ASSERTMSG (pSubindexEntry_p != NULL, + "EplObdCheckObjectRange(): no address to subindex struct!\n"); + + Ret = kEplSuccessful; + + // check if data range has to be checked + if ((pSubindexEntry_p->m_Access & kEplObdAccRange) == 0) + { + goto Exit; + } + + // get address of default data + pRangeData = pSubindexEntry_p->m_pDefault; + + // jump to called object type + switch ((tEplObdType) pSubindexEntry_p->m_Type) + { + // ----------------------------------------------------------------- + // ObdType kEplObdTypBool will not be checked because there are only + // two possible values 0 or 1. + + // ----------------------------------------------------------------- + // ObdTypes which has to be check up because numerical values + case kEplObdTypInt8: + + // switch to lower limit + pRangeData = ((tEplObdInteger8 *) pRangeData) + 1; + + // check if value is to low + if (*((tEplObdInteger8 *) pData_p) < *((tEplObdInteger8 *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((tEplObdInteger8 *) pRangeData) + 1; + + // check if value is to high + if (*((tEplObdInteger8 *) pData_p) > *((tEplObdInteger8 *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + case kEplObdTypUInt8: + + // switch to lower limit + pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1; + + // check if value is to low + if (*((tEplObdUnsigned8 *) pData_p) < *((tEplObdUnsigned8 *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((tEplObdUnsigned8*) pRangeData) + 1; + + // check if value is to high + if (*((tEplObdUnsigned8 *) pData_p) > *((tEplObdUnsigned8 *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + case kEplObdTypInt16: + + // switch to lower limit + pRangeData = ((tEplObdInteger16 *) pRangeData) + 1; + + // check if value is to low + if (*((tEplObdInteger16 *) pData_p) < *((tEplObdInteger16 *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((tEplObdInteger16 *) pRangeData) + 1; + + // check if value is to high + if (*((tEplObdInteger16 *) pData_p) > *((tEplObdInteger16 *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + case kEplObdTypUInt16: + + // switch to lower limit + pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1; + + // check if value is to low + if (*((tEplObdUnsigned16 *) pData_p) < *((tEplObdUnsigned16 *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1; + + // check if value is to high + if (*((tEplObdUnsigned16 *) pData_p) > *((tEplObdUnsigned16 *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + case kEplObdTypInt32: + + // switch to lower limit + pRangeData = ((tEplObdInteger32 *) pRangeData) + 1; + + // check if value is to low + if (*((tEplObdInteger32 *) pData_p) < *((tEplObdInteger32 *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((tEplObdInteger32 *) pRangeData) + 1; + + // check if value is to high + if (*((tEplObdInteger32 *) pData_p) > *((tEplObdInteger32 *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + case kEplObdTypUInt32: + + // switch to lower limit + pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1; + + // check if value is to low + if (*((tEplObdUnsigned32 *) pData_p) < *((tEplObdUnsigned32 *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1; + + // check if value is to high + if (*((tEplObdUnsigned32 *) pData_p) > *((tEplObdUnsigned32 *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + case kEplObdTypReal32: + + // switch to lower limit + pRangeData = ((tEplObdReal32 *) pRangeData) + 1; + + // check if value is to low + if (*((tEplObdReal32 *) pData_p) < *((tEplObdReal32 *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((tEplObdReal32 *) pRangeData) + 1; + + // check if value is to high + if (*((tEplObdReal32 *) pData_p) > *((tEplObdReal32 *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + // ----------------------------------------------------------------- + case kEplObdTypInt40: + case kEplObdTypInt48: + case kEplObdTypInt56: + case kEplObdTypInt64: + + // switch to lower limit + pRangeData = ((signed QWORD *) pRangeData) + 1; + + // check if value is to low + if (*((signed QWORD *) pData_p) < *((signed QWORD *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((signed QWORD *) pRangeData) + 1; + + // check if value is to high + if (*((signed QWORD *) pData_p) > *((signed QWORD *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + // ----------------------------------------------------------------- + case kEplObdTypUInt40: + case kEplObdTypUInt48: + case kEplObdTypUInt56: + case kEplObdTypUInt64: + + // switch to lower limit + pRangeData = ((unsigned QWORD *) pRangeData) + 1; + + // check if value is to low + if (*((unsigned QWORD *) pData_p) < *((unsigned QWORD *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((unsigned QWORD *) pRangeData) + 1; + + // check if value is to high + if (*((unsigned QWORD *) pData_p) > *((unsigned QWORD *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + // ----------------------------------------------------------------- + case kEplObdTypReal64: + + // switch to lower limit + pRangeData = ((tEplObdReal64 *) pRangeData) + 1; + + // check if value is to low + if (*((tEplObdReal64 *) pData_p) < *((tEplObdReal64 *) pRangeData)) + { + Ret = kEplObdValueTooLow; + break; + } + + // switch to higher limit + pRangeData = ((tEplObdReal64 *) pRangeData) + 1; + + // check if value is to high + if (*((tEplObdReal64 *) pData_p) > *((tEplObdReal64 *) pRangeData)) + { + Ret = kEplObdValueTooHigh; + } + + break; + + // ----------------------------------------------------------------- + case kEplObdTypTimeOfDay: + case kEplObdTypTimeDiff: + break; + + // ----------------------------------------------------------------- + // ObdTypes kEplObdTypXString and kEplObdTypDomain can not be checkt because + // they have no numerical value. + default: + + Ret = kEplObdUnknownObjectType; + break; + } + +Exit: + + return Ret; + +} +#endif // (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) + +//--------------------------------------------------------------------------- +// +// Function: EplObdWriteEntryPre() +// +// Description: Function prepares write of data to an OBD entry. Strings +// are stored with added '\0' character. +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ +// uiIndex_p = Index of the OD entry +// uiSubIndex_p = Subindex of the OD Entry +// pSrcData_p = Pointer to the data to write +// Size_p = Size of the data in Byte +// +// Return: tEplKernel = Errorcode +// +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel PUBLIC EplObdWriteEntryPre (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubIndex_p, + void * pSrcData_p, + void** ppDstData_p, + tEplObdSize Size_p, + tEplObdEntryPtr* ppObdEntry_p, + tEplObdSubEntryPtr* ppSubEntry_p, + tEplObdCbParam MEM* pCbParam_p, + tEplObdSize* pObdSize_p) +{ + +tEplKernel Ret; +tEplObdEntryPtr pObdEntry; +tEplObdSubEntryPtr pSubEntry; +tEplObdAccess Access; +void MEM* pDstData; +tEplObdSize ObdSize; +BOOL fEntryNumerical; + +#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE) + tEplObdVStringDomain MEM MemVStringDomain; + void MEM* pCurrData; +#endif + + // check for all API function if instance is valid + EPL_MCO_CHECK_INSTANCE_STATE (); + + ASSERT (pSrcData_p != NULL); // should never be NULL + + //------------------------------------------------------------------------ + // get address of index and subindex entry + Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_ + uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // get pointer to object data + pDstData = (void MEM*) EplObdGetObjectDataPtrIntern (pSubEntry); + + Access = (tEplObdAccess) pSubEntry->m_Access; + + // check access for write + // access violation if adress to current value is NULL + if ( ((Access & kEplObdAccConst) != 0) || + (pDstData == NULL) ) + { + Ret = kEplObdAccessViolation; + goto Exit; + } + + //------------------------------------------------------------------------ + // get size of object + // -as ObdSize = ObdGetObjectSize (pSubEntry); + + //------------------------------------------------------------------------ + // To use the same callback function for ObdWriteEntry as well as for + // an SDO download call at first (kEplObdEvPre...) the callback function + // with the argument pointer to object size. + pCbParam_p->m_uiIndex = uiIndex_p; + pCbParam_p->m_uiSubIndex = uiSubIndex_p; + + // Because object size and object pointer are + // adapted by user callback function, re-read + // this values. + ObdSize = EplObdGetObjectSize (pSubEntry); + pDstData = (void MEM*) EplObdGetObjectDataPtrIntern (pSubEntry); + + // 09-dec-2004 r.d.: + // Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain + // for String or Domain which lets called module directly change + // the data pointer or size. This prevents a recursive call to + // the callback function if it calls EplObdGetEntry(). + #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE) + if ( (pSubEntry->m_Type == kEplObdTypVString) || + (pSubEntry->m_Type == kEplObdTypDomain) || + (pSubEntry->m_Type == kEplObdTypOString)) + { + if (pSubEntry->m_Type == kEplObdTypVString) + { + // reserve one byte for 0-termination + // -as ObdSize -= 1; + Size_p += 1; + } + + // fill out new arg-struct + MemVStringDomain.m_DownloadSize = Size_p; + MemVStringDomain.m_ObjSize = ObdSize; + MemVStringDomain.m_pData = pDstData; + + pCbParam_p->m_ObdEvent = kEplObdEvWrStringDomain; + pCbParam_p->m_pArg = &MemVStringDomain; + // call user callback + Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_ + pObdEntry->m_fpCallback, pCbParam_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // write back new settings + pCurrData = pSubEntry->m_pCurrent; + if ((pSubEntry->m_Type == kEplObdTypVString) + ||(pSubEntry->m_Type == kEplObdTypOString)) + { + ((tEplObdVString MEM*) pCurrData)->m_Size = MemVStringDomain.m_ObjSize; + ((tEplObdVString MEM*) pCurrData)->m_pString = MemVStringDomain.m_pData; + } + else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain) + { + ((tEplObdVarEntry MEM*) pCurrData)->m_Size = MemVStringDomain.m_ObjSize; + ((tEplObdVarEntry MEM*) pCurrData)->m_pData = (void MEM*) MemVStringDomain.m_pData; + } + + // Because object size and object pointer are + // adapted by user callback function, re-read + // this values. + ObdSize = MemVStringDomain.m_ObjSize; + pDstData = (void MEM*) MemVStringDomain.m_pData; + } + #endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE) + + // 07-dec-2004 r.d.: size from application is needed because callback function can change the object size + // -as 16.11.04 CbParam.m_pArg = &ObdSize; + // 09-dec-2004 r.d.: CbParam.m_pArg = &Size_p; + pCbParam_p->m_pArg = &ObdSize; + pCbParam_p->m_ObdEvent = kEplObdEvInitWrite; + Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_ + pObdEntry->m_fpCallback, pCbParam_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + if (Size_p > ObdSize) + { + Ret = kEplObdValueLengthError; + goto Exit; + } + + if (pSubEntry->m_Type == kEplObdTypVString) + { + if (((char MEM*) pSrcData_p)[Size_p - 1] == '\0') + { // last byte of source string contains null character + + // reserve one byte in destination for 0-termination + Size_p -= 1; + } + else if (Size_p >= ObdSize) + { // source string is not 0-terminated + // and destination buffer is too short + Ret = kEplObdValueLengthError; + goto Exit; + } + } + + Ret = EplObdIsNumericalIntern(pSubEntry, &fEntryNumerical); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + if ((fEntryNumerical != FALSE) + && (Size_p != ObdSize)) + { + // type is numerical, therefor size has to fit, but it does not. + Ret = kEplObdValueLengthError; + goto Exit; + } + + // use given size, because non-numerical objects can be written with shorter values + ObdSize = Size_p; + + // set output parameters + *pObdSize_p = ObdSize; + *ppObdEntry_p = pObdEntry; + *ppSubEntry_p = pSubEntry; + *ppDstData_p = pDstData; + + // all checks are done + // the caller may now convert the numerial source value to platform byte order in a temporary buffer + +Exit: + + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdWriteEntryPost() +// +// Description: Function finishes write of data to an OBD entry. Strings +// are stored with added '\0' character. +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ +// uiIndex_p = Index of the OD entry +// uiSubIndex_p = Subindex of the OD Entry +// pSrcData_p = Pointer to the data to write +// Size_p = Size of the data in Byte +// +// Return: tEplKernel = Errorcode +// +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel PUBLIC EplObdWriteEntryPost (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdEntryPtr pObdEntry_p, + tEplObdSubEntryPtr pSubEntry_p, + tEplObdCbParam MEM* pCbParam_p, + void * pSrcData_p, + void * pDstData_p, + tEplObdSize ObdSize_p) +{ + +tEplKernel Ret; + + + // caller converted the source value to platform byte order + // now the range of the value may be checked + + #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) + { + // check data range + Ret = EplObdCheckObjectRange (pSubEntry_p, pSrcData_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } + } + #endif + + // now call user callback function to check value + // write address of source data to structure of callback parameters + // so callback function can check this data + pCbParam_p->m_pArg = pSrcData_p; + pCbParam_p->m_ObdEvent = kEplObdEvPreWrite; + Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_ + pObdEntry_p->m_fpCallback, pCbParam_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // copy object data to OBD + EPL_MEMCPY (pDstData_p, pSrcData_p, ObdSize_p); + + // terminate string with 0 + if (pSubEntry_p->m_Type == kEplObdTypVString) + { + ((char MEM*) pDstData_p)[ObdSize_p] = '\0'; + } + + // write address of destination to structure of callback parameters + // so callback function can change data subsequently + pCbParam_p->m_pArg = pDstData_p; + pCbParam_p->m_ObdEvent = kEplObdEvPostWrite; + Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_ + pObdEntry_p->m_fpCallback, pCbParam_p); + +Exit: + + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetObjectSize() +// +// Description: function to get size of object +// The function determines if an object type an fixed data type (BYTE, WORD, ...) +// or non fixed object (string, domain). This information is used to decide +// if download data are stored temporary or not. For objects with fixed data length +// and types a value range checking can process. +// For strings the function returns the whole object size not the +// length of string. +// +// Parameters: pSubIndexEntry_p +// +// Return: tEplObdSize +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplObdSize EplObdGetObjectSize (tEplObdSubEntryPtr pSubIndexEntry_p) +{ + +tEplObdSize DataSize = 0; +void * pData; + + switch (pSubIndexEntry_p->m_Type) + { + // ----------------------------------------------------------------- + case kEplObdTypBool: + + DataSize = 1; + break; + + // ----------------------------------------------------------------- + // ObdTypes which has to be check because numerical values + case kEplObdTypInt8: + DataSize = sizeof (tEplObdInteger8); + break; + + // ----------------------------------------------------------------- + case kEplObdTypUInt8: + DataSize = sizeof (tEplObdUnsigned8); + break; + + // ----------------------------------------------------------------- + case kEplObdTypInt16: + DataSize = sizeof (tEplObdInteger16); + break; + + // ----------------------------------------------------------------- + case kEplObdTypUInt16: + DataSize = sizeof (tEplObdUnsigned16); + break; + + // ----------------------------------------------------------------- + case kEplObdTypInt32: + DataSize = sizeof (tEplObdInteger32); + break; + + // ----------------------------------------------------------------- + case kEplObdTypUInt32: + DataSize = sizeof (tEplObdUnsigned32); + break; + + // ----------------------------------------------------------------- + case kEplObdTypReal32: + DataSize = sizeof (tEplObdReal32); + break; + + // ----------------------------------------------------------------- + // ObdTypes which has to be not checked because not NUM values + case kEplObdTypDomain: + + pData = (void *) pSubIndexEntry_p->m_pCurrent; + if ((void MEM*) pData != (void MEM*) NULL) + { + DataSize = ((tEplObdVarEntry MEM*) pData)->m_Size; + } + break; + + // ----------------------------------------------------------------- + case kEplObdTypVString: + //case kEplObdTypUString: + + // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING + // then the current pointer is always NULL. The function + // returns the length of default string. + pData = (void *) pSubIndexEntry_p->m_pCurrent; + if ((void MEM*) pData != (void MEM*) NULL) + { + // The max. size of strings defined by STRING-Macro is stored in + // tEplObdVString of current value. + // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members) + DataSize = ((tEplObdVString MEM*) pData)->m_Size; + } + else + { + // The current position is not decleared. The string + // is located in ROM, therefor use default pointer. + pData = (void *) pSubIndexEntry_p->m_pDefault; + if ((CONST void ROM*) pData != (CONST void ROM*) NULL) + { + // The max. size of strings defined by STRING-Macro is stored in + // tEplObdVString of default value. + DataSize = ((CONST tEplObdVString ROM*) pData)->m_Size; + } + } + + break; + + // ----------------------------------------------------------------- + case kEplObdTypOString: + + pData = (void *) pSubIndexEntry_p->m_pCurrent; + if ((void MEM*) pData != (void MEM*) NULL) + { + // The max. size of strings defined by STRING-Macro is stored in + // tEplObdVString of current value. + // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members) + DataSize = ((tEplObdOString MEM*) pData)->m_Size; + } + else + { + // The current position is not decleared. The string + // is located in ROM, therefor use default pointer. + pData = (void *) pSubIndexEntry_p->m_pDefault; + if ((CONST void ROM*) pData != (CONST void ROM*) NULL) + { + // The max. size of strings defined by STRING-Macro is stored in + // tEplObdVString of default value. + DataSize = ((CONST tEplObdOString ROM*) pData)->m_Size; + } + } + break; + + // ----------------------------------------------------------------- + case kEplObdTypInt24: + case kEplObdTypUInt24: + + DataSize = 3; + break; + + + // ----------------------------------------------------------------- + case kEplObdTypInt40: + case kEplObdTypUInt40: + + DataSize = 5; + break; + + // ----------------------------------------------------------------- + case kEplObdTypInt48: + case kEplObdTypUInt48: + + DataSize = 6; + break; + + // ----------------------------------------------------------------- + case kEplObdTypInt56: + case kEplObdTypUInt56: + + DataSize = 7; + break; + + // ----------------------------------------------------------------- + case kEplObdTypInt64: + case kEplObdTypUInt64: + case kEplObdTypReal64: + + DataSize = 8; + break; + + // ----------------------------------------------------------------- + case kEplObdTypTimeOfDay: + case kEplObdTypTimeDiff: + + DataSize = 6; + break; + + // ----------------------------------------------------------------- + default: + break; + } + + return DataSize; +} + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetObjectDefaultPtr() +// +// Description: function to get the default pointer (type specific) +// +// Parameters: pSubIndexEntry_p = pointer to subindex structure +// +// Returns: (void *) = pointer to default value +// +// State: +// +//--------------------------------------------------------------------------- + +static void * EplObdGetObjectDefaultPtr (tEplObdSubEntryPtr pSubIndexEntry_p) +{ + +void * pDefault; +tEplObdType Type; + + ASSERTMSG (pSubIndexEntry_p != NULL, "EplObdGetObjectDefaultPtr(): pointer to SubEntry not valid!\n"); + + // get address to default data from default pointer + pDefault = pSubIndexEntry_p->m_pDefault; + if (pDefault != NULL) + { + // there are some special types, whose default pointer always is NULL or has to get from other structure + // get type from subindex structure + Type = pSubIndexEntry_p->m_Type; + + // check if object type is a string value + if ((Type == kEplObdTypVString) /* || + (Type == kEplObdTypUString) */ ) + { + + // EPL_OBD_SUBINDEX_RAM_VSTRING + // tEplObdSize m_Size; --> size of default string + // char * m_pDefString; --> pointer to default string + // char * m_pString; --> pointer to string in RAM + // + pDefault = (void *) ((tEplObdVString *) pDefault)->m_pString; + } + else if(Type == kEplObdTypOString) + { + pDefault = (void *) ((tEplObdOString *) pDefault)->m_pString; + } + } + + return pDefault; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetVarEntry() +// +// Description: gets a variable entry of an object +// +// Parameters: pSubindexEntry_p +// ppVarEntry_p +// +// Return: tCopKernel +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel EplObdGetVarEntry ( + tEplObdSubEntryPtr pSubindexEntry_p, + tEplObdVarEntry MEM** ppVarEntry_p) +{ + +tEplKernel Ret = kEplObdVarEntryNotExist; + + ASSERT (ppVarEntry_p != NULL); // is not allowed to be NULL + ASSERT (pSubindexEntry_p != NULL); + + // check VAR-Flag - only this object points to variables + if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0) + { + // check if object is an array + if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0) + { + *ppVarEntry_p = &((tEplObdVarEntry MEM*) pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1]; + } + else + { + *ppVarEntry_p = (tEplObdVarEntry MEM*) pSubindexEntry_p->m_pCurrent; + } + + Ret = kEplSuccessful; + } + + return Ret; + +} + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetEntry() +// +// Description: gets a index entry from OD +// +// Parameters: uiIndex_p = Index number +// uiSubindex_p = Subindex number +// ppObdEntry_p = pointer to the pointer to the entry +// ppObdSubEntry_p = pointer to the pointer to the subentry +// +// Return: tEplKernel + +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel EplObdGetEntry (EPL_MCO_DECL_INSTANCE_PTR_ + unsigned int uiIndex_p, + unsigned int uiSubindex_p, + tEplObdEntryPtr* ppObdEntry_p, + tEplObdSubEntryPtr* ppObdSubEntry_p) +{ + +tEplObdEntryPtr pObdEntry; +tEplObdCbParam MEM CbParam; +tEplKernel Ret; + + // check for all API function if instance is valid + EPL_MCO_CHECK_INSTANCE_STATE (); + + //------------------------------------------------------------------------ + // get address of entry of index + Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam), uiIndex_p, &pObdEntry); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + //------------------------------------------------------------------------ + // get address of entry of subindex + Ret = EplObdGetSubindexIntern (pObdEntry, uiSubindex_p, ppObdSubEntry_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + //------------------------------------------------------------------------ + // call callback function to inform user/stack that an object will be searched + // if the called module returnes an error then we abort the searching with kEplObdIndexNotExist + CbParam.m_uiIndex = uiIndex_p; + CbParam.m_uiSubIndex = uiSubindex_p; + CbParam.m_pArg = NULL; + CbParam.m_ObdEvent = kEplObdEvCheckExist; + Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_ + pObdEntry->m_fpCallback, &CbParam); + if (Ret != kEplSuccessful) + { + Ret = kEplObdIndexNotExist; + goto Exit; + } + + //------------------------------------------------------------------------ + // it is allowed to set ppObdEntry_p to NULL + // if so, no address will be written to calling function + if (ppObdEntry_p != NULL) + { + *ppObdEntry_p = pObdEntry; + } + +Exit: + + return Ret; + +} +//--------------------------------------------------------------------------- +// +// Function: EplObdGetObjectCurrentPtr() +// +// Description: function to get Current pointer (type specific) +// +// Parameters: pSubIndexEntry_p +// +// Return: void MEM* +// +// State: +// +//--------------------------------------------------------------------------- + +static void MEM* EplObdGetObjectCurrentPtr (tEplObdSubEntryPtr pSubIndexEntry_p) +{ + +void MEM* pData; +unsigned int uiArrayIndex; +tEplObdSize Size; + + pData = pSubIndexEntry_p->m_pCurrent; + + // check if constant object + if (pData != NULL) + { + // check if object is an array + if ((pSubIndexEntry_p->m_Access & kEplObdAccArray) != 0) + { + // calculate correct data pointer + uiArrayIndex = pSubIndexEntry_p->m_uiSubIndex - 1; + if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) + { + Size = sizeof (tEplObdVarEntry); + } + else + { + Size = EplObdGetObjectSize (pSubIndexEntry_p); + } + pData = ((BYTE MEM*) pData) + (Size * uiArrayIndex); + } + + // check if VarEntry + if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) + { + // The data pointer is stored in VarEntry->pData + pData = ((tEplObdVarEntry MEM*) pData)->m_pData; + } + + // the default pointer is stored for strings in tEplObdVString + else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString) /* || + (pSubIndexEntry_p->m_Type == kEplObdTypUString) */ ) + { + pData = (void MEM*) ((tEplObdVString MEM*) pData)->m_pString; + } + else if (pSubIndexEntry_p->m_Type == kEplObdTypOString) + { + pData = (void MEM*) ((tEplObdOString MEM*) pData)->m_pString; + } + } + + return pData; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetIndexIntern() +// +// Description: gets a index entry from OD +// +// Parameters: pInitParam_p +// uiIndex_p +// ppObdEntry_p +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel EplObdGetIndexIntern ( + tEplObdInitParam MEM* pInitParam_p, + unsigned int uiIndex_p, + tEplObdEntryPtr* ppObdEntry_p) +{ + +tEplObdEntryPtr pObdEntry; +tEplKernel Ret; +unsigned int uiIndex; + +#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) + +unsigned int nLoop; + + // if user OD is used then objekts also has to be searched in user OD + // there is less code need if we do this in a loop + nLoop = 2; + +#endif + + ASSERTMSG (ppObdEntry_p != NULL, "EplObdGetIndexIntern(): pointer to index entry is NULL!\n"); + + Ret = kEplObdIndexNotExist; + + // get start address of OD part + // start address depends on object index because + // object dictionary is divided in 3 parts + if ((uiIndex_p >= 0x1000) && (uiIndex_p < 0x2000)) + { + pObdEntry = pInitParam_p->m_pPart; + } + else if ((uiIndex_p >= 0x2000) && (uiIndex_p < 0x6000)) + { + pObdEntry = pInitParam_p->m_pManufacturerPart; + } + + // index range 0xA000 to 0xFFFF is reserved for DSP-405 + // DS-301 defines that range 0x6000 to 0x9FFF (!!!) is stored if "store" was written to 0x1010/3. + // Therefore default configuration is OBD_INCLUDE_A000_TO_DEVICE_PART = FALSE. + // But a CANopen Application which does not implement dynamic OD or user-OD but wants to use static objets 0xA000... + // should set OBD_INCLUDE_A000_TO_DEVICE_PART to TRUE. + +#if (EPL_OBD_INCLUDE_A000_TO_DEVICE_PART == FALSE) + else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0x9FFF)) +#else + else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0xFFFF)) +#endif + { + pObdEntry = pInitParam_p->m_pDevicePart; + } + + +#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) + + // if index does not match in static OD then index only has to be searched in user OD + else + { + // begin from first entry of user OD part + pObdEntry = pInitParam_p->m_pUserPart; + + // no user OD is available + if (pObdEntry == NULL) + { + goto Exit; + } + + // loop must only run once + nLoop = 1; + } + + do + { + +#else + + // no user OD is available + // so other object can be found in OD + else + { + Ret = kEplObdIllegalPart; + goto Exit; + } + +#endif + + // note: + // The end of Index table is marked with m_uiIndex = 0xFFFF. + // If this function will be called with wIndex_p = 0xFFFF, entry + // should not be found. Therefor it is important to use + // while{} instead of do{}while !!! + + // get first index of index table + uiIndex = pObdEntry->m_uiIndex; + + // search Index in OD part + while (uiIndex != EPL_OBD_TABLE_INDEX_END) + { + // go to the end of this function if index is found + if (uiIndex_p == uiIndex) + { + // write address of OD entry to calling function + *ppObdEntry_p = pObdEntry; + Ret = kEplSuccessful; + goto Exit; + } + + // objects are sorted in OD + // if the current index in OD is greater than the index which is to search then break loop + // in this case user OD has to be search too + if (uiIndex_p < uiIndex) + { + break; + } + + // next entry in index table + pObdEntry++; + + // get next index of index table + uiIndex = pObdEntry->m_uiIndex; + } + +#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) + + // begin from first entry of user OD part + pObdEntry = pInitParam_p->m_pUserPart; + + // no user OD is available + if (pObdEntry == NULL) + { + goto Exit; + } + + // switch next loop for user OD + nLoop--; + + } while (nLoop > 0); + +#endif + + // in this line Index was not found + +Exit: + + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdGetSubindexIntern() +// +// Description: gets a subindex entry from a index entry +// +// Parameters: pObdEntry_p +// bSubIndex_p +// ppObdSubEntry_p +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel EplObdGetSubindexIntern ( + tEplObdEntryPtr pObdEntry_p, + unsigned int uiSubIndex_p, + tEplObdSubEntryPtr* ppObdSubEntry_p) +{ + +tEplObdSubEntryPtr pSubEntry; +unsigned int nSubIndexCount; +tEplKernel Ret; + + ASSERTMSG (pObdEntry_p != NULL, "EplObdGetSubindexIntern(): pointer to index is NULL!\n"); + ASSERTMSG (ppObdSubEntry_p != NULL, "EplObdGetSubindexIntern(): pointer to subindex is NULL!\n"); + + Ret = kEplObdSubindexNotExist; + + // get start address of subindex table and count of subindices + pSubEntry = pObdEntry_p->m_pSubIndex; + nSubIndexCount = pObdEntry_p->m_uiCount; + ASSERTMSG ((pSubEntry != NULL) && (nSubIndexCount > 0), + "ObdGetSubindexIntern(): invalid subindex table within index table!\n"); // should never be NULL + + // search subindex in subindex table + while (nSubIndexCount > 0) + { + // check if array is found + if ((pSubEntry->m_Access & kEplObdAccArray) != 0) + { + // check if subindex is in range + if (uiSubIndex_p < pObdEntry_p->m_uiCount) + { + // update subindex number (subindex entry of an array is always in RAM !!!) + pSubEntry->m_uiSubIndex = uiSubIndex_p; + *ppObdSubEntry_p = pSubEntry; + Ret = kEplSuccessful; + goto Exit; + } + } + + // go to the end of this function if subindex is found + else if (uiSubIndex_p == pSubEntry->m_uiSubIndex) + { + *ppObdSubEntry_p = pSubEntry; + Ret = kEplSuccessful; + goto Exit; + } + + // objects are sorted in OD + // if the current subindex in OD is greater than the subindex which is to search then break loop + // in this case user OD has to be search too + if (uiSubIndex_p < pSubEntry->m_uiSubIndex) + { + break; + } + + pSubEntry++; + nSubIndexCount--; + } + + // in this line SubIndex was not fount + +Exit: + + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdSetStoreLoadObjCallback() +// +// Description: function set address to callbackfunction for command Store and Load +// +// Parameters: fpCallback_p +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- +#if (EPL_OBD_USE_STORE_RESTORE != FALSE) +EPLDLLEXPORT tEplKernel PUBLIC EplObdSetStoreLoadObjCallback (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdStoreLoadObjCallback fpCallback_p) +{ + + EPL_MCO_CHECK_INSTANCE_STATE (); + + // set new address of callback function + EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) = fpCallback_p; + + return kEplSuccessful; + +} +#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) + + +//--------------------------------------------------------------------------- +// +// Function: EplObdAccessOdPartIntern() +// +// Description: runs through OD and executes a job +// +// Parameters: CurrentOdPart_p +// pObdEnty_p +// Direction_p = what is to do (load values from flash or EEPROM, store, ...) +// +// Return: tEplKernel +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel EplObdAccessOdPartIntern (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdPart CurrentOdPart_p, + tEplObdEntryPtr pObdEnty_p, + tEplObdDir Direction_p) +{ + +tEplObdSubEntryPtr pSubIndex; +unsigned int nSubIndexCount; +tEplObdAccess Access; +void MEM* pDstData; +void * pDefault; +tEplObdSize ObjSize; +tEplKernel Ret; +tEplObdCbStoreParam MEM CbStore; +tEplObdVarEntry MEM* pVarEntry; + + ASSERT (pObdEnty_p != NULL); + + Ret = kEplSuccessful; + + // prepare structure for STORE RESTORE callback function + CbStore.m_bCurrentOdPart = (BYTE) CurrentOdPart_p; + CbStore.m_pData = NULL; + CbStore.m_ObjSize = 0; + + // command of first action depends on direction to access + #if (EPL_OBD_USE_STORE_RESTORE != FALSE) + if (Direction_p == kEplObdDirLoad) + { + CbStore.m_bCommand = (BYTE) kEplObdCommOpenRead; + + // call callback function for previous command + Ret = EplObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_ + &CbStore); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // set command for index and subindex loop + CbStore.m_bCommand = (BYTE) kEplObdCommReadObj; + } + else if (Direction_p == kEplObdDirStore) + { + CbStore.m_bCommand = (BYTE) kEplObdCommOpenWrite; + + // call callback function for previous command + Ret = EplObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_ + &CbStore); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // set command for index and subindex loop + CbStore.m_bCommand = (BYTE) kEplObdCommWriteObj; + } + #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) + + // we should not restore the OD values here + // the next NMT command "Reset Node" or "Reset Communication" resets the OD data + if (Direction_p != kEplObdDirRestore) + { + // walk through OD part till end is found + while (pObdEnty_p->m_uiIndex != EPL_OBD_TABLE_INDEX_END) + { + // get address to subindex table and count of subindices + pSubIndex = pObdEnty_p->m_pSubIndex; + nSubIndexCount = pObdEnty_p->m_uiCount; + ASSERT ((pSubIndex != NULL) && (nSubIndexCount > 0)); // should never be NULL + + // walk through subindex table till all subinices were restored + while (nSubIndexCount != 0) + { + Access = (tEplObdAccess) pSubIndex->m_Access; + + // get pointer to current and default data + pDefault = EplObdGetObjectDefaultPtr (pSubIndex); + pDstData = EplObdGetObjectCurrentPtr (pSubIndex); + + // NOTE (for kEplObdTypVString): + // The function returnes the max. number of bytes for a + // current string. + // r.d.: For stings the default-size will be read in other lines following (kEplObdDirInit). + ObjSize = EplObdGetObjectSize (pSubIndex); + + // switch direction of OD access + switch (Direction_p) + { + // -------------------------------------------------------------------------- + // VarEntry structures has to be initialized + case kEplObdDirInit: + + // If VAR-Flag is set, m_pCurrent means not address of data + // but address of tEplObdVarEntry. Address of data has to be get from + // this structure. + if ((Access & kEplObdAccVar) != 0) + { + EplObdGetVarEntry (pSubIndex, &pVarEntry); + EplObdInitVarEntry (pVarEntry, pSubIndex->m_Type, ObjSize); +/* + if ((Access & kEplObdAccArray) == 0) + { + EplObdInitVarEntry (pSubIndex->m_pCurrent, pSubIndex->m_Type, ObjSize); + } + else + { + EplObdInitVarEntry ((tEplObdVarEntry MEM*) (((BYTE MEM*) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)), + pSubIndex->m_Type, ObjSize); + } +*/ + // at this time no application variable is defined !!! + // therefore data can not be copied. + break; + } + else if (pSubIndex->m_Type == kEplObdTypVString) + { + // If pointer m_pCurrent is not equal to NULL then the + // string was defined with EPL_OBD_SUBINDEX_RAM_VSTRING. The current + // pointer points to struct tEplObdVString located in MEM. + // The element size includes the max. number of + // bytes. The element m_pString includes the pointer + // to string in MEM. The memory location of default string + // must be copied to memory location of current string. + + pDstData = pSubIndex->m_pCurrent; + if (pDstData != NULL) + { + // 08-dec-2004: code optimization !!! + // entries ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString + // and ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read + // twice. thats not necessary! + + // For copying data we have to set the destination pointer to the real RAM string. This + // pointer to RAM string is located in default string info structure. (translated r.d.) + pDstData = (void MEM*) ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString; + ObjSize = ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size; + + + ((tEplObdVString MEM*) pSubIndex->m_pCurrent)->m_pString = pDstData; + ((tEplObdVString MEM*) pSubIndex->m_pCurrent)->m_Size = ObjSize; + } + + } + else if(pSubIndex->m_Type == kEplObdTypOString) + { + pDstData = pSubIndex->m_pCurrent; + if (pDstData != NULL) + { + // 08-dec-2004: code optimization !!! + // entries ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString + // and ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read + // twice. thats not necessary! + + // For copying data we have to set the destination pointer to the real RAM string. This + // pointer to RAM string is located in default string info structure. (translated r.d.) + pDstData = (void MEM*) ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString; + ObjSize = ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size; + + + ((tEplObdOString MEM*) pSubIndex->m_pCurrent)->m_pString = pDstData; + ((tEplObdOString MEM*) pSubIndex->m_pCurrent)->m_Size = ObjSize; + } + + } + + + // no break !! because copy of data has to done too. + + // -------------------------------------------------------------------------- + // all objects has to be restored with default values + case kEplObdDirRestore: + + // 09-dec-2004 r.d.: optimization! the same code for kEplObdDirRestore and kEplObdDirLoad + // is replaced to function ObdCopyObjectData() with a new parameter. + + + // restore object data for init phase + EplObdCopyObjectData (pDstData, pDefault, ObjSize, pSubIndex->m_Type); + break; + + // -------------------------------------------------------------------------- + // objects with attribute kEplObdAccStore has to be load from EEPROM or from a file + case kEplObdDirLoad: + + // restore object data for init phase + EplObdCopyObjectData (pDstData, pDefault, ObjSize, pSubIndex->m_Type); + + // no break !! because callback function has to be called too. + + // -------------------------------------------------------------------------- + // objects with attribute kEplObdAccStore has to be stored in EEPROM or in a file + case kEplObdDirStore: + + // when attribute kEplObdAccStore is set, then call callback function + #if (EPL_OBD_USE_STORE_RESTORE != FALSE) + if ((Access & kEplObdAccStore) != 0) + { + // fill out data pointer and size of data + CbStore.m_pData = pDstData; + CbStore.m_ObjSize = ObjSize; + + // call callback function for read or write object + Ret = ObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_ + &CbStore); + if (Ret != kEplSuccessful) + { + goto Exit; + } + } + #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) + break; + + + // -------------------------------------------------------------------------- + // if OD Builder key has to be checked no access to subindex and data should be made + case kEplObdDirOBKCheck: + + // no break !! because we want to break the second loop too. + + + // -------------------------------------------------------------------------- + // unknown Direction + default: + + // so we can break the second loop earler + nSubIndexCount = 1; + break; + } + + nSubIndexCount--; + + // next subindex entry + if ((Access & kEplObdAccArray) == 0) + { + pSubIndex++; + if ((nSubIndexCount > 0) + && ((pSubIndex->m_Access & kEplObdAccArray) != 0)) + { + // next subindex points to an array + // reset subindex number + pSubIndex->m_uiSubIndex = 1; + } + } + else + { + if (nSubIndexCount > 0) + { + // next subindex points to an array + // increment subindex number + pSubIndex->m_uiSubIndex++; + } + } + } + + // next index entry + pObdEnty_p++; + } + } + + // ----------------------------------------------------------------------------------------- + // command of last action depends on direction to access + if (Direction_p == kEplObdDirOBKCheck) + { + + goto Exit; + } + #if (EPL_OBD_USE_STORE_RESTORE != FALSE) + else + { + if (Direction_p == kEplObdDirLoad) + { + CbStore.m_bCommand = (BYTE) kEplObdCommCloseRead; + } + else if (Direction_p == kEplObdDirStore) + { + CbStore.m_bCommand = (BYTE) kEplObdCommCloseWrite; + } + else if (Direction_p == kEplObdDirRestore) + { + CbStore.m_bCommand = (BYTE) kEplObdCommClear; + } + else + { + goto Exit; + } + + // call callback function for last command + Ret = EplObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_ + &CbStore); + } + #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) + +// goto Exit; + +Exit: + + return Ret; + +} + + +// ---------------------------------------------------------------------------- +// Function: EplObdCopyObjectData() +// +// Description: checks pointers to object data and copy them from source to destination +// +// Parameters: pDstData_p = destination pointer +// pSrcData_p = source pointer +// ObjSize_p = size of object +// ObjType_p = +// +// Returns: tEplKernel = error code +// ---------------------------------------------------------------------------- + +static void EplObdCopyObjectData ( + void MEM* pDstData_p, + void * pSrcData_p, + tEplObdSize ObjSize_p, + tEplObdType ObjType_p) +{ + + +tEplObdSize StrSize = 0; + + + // it is allowed to set default and current address to NULL (nothing to copy) + if (pDstData_p != NULL) + { + + if (ObjType_p == kEplObdTypVString) + { + // The function calculates the really number of characters of string. The + // object entry size can be bigger as string size of default string. + // The '\0'-termination is included. A string with no characters has a + // size of 1. + StrSize = EplObdGetStrLen ((void *) pSrcData_p, ObjSize_p, kEplObdTypVString); + + // If the string length is greater than or equal to the entry size in OD then only copy + // entry size - 1 and always set the '\0'-termination. + if (StrSize >= ObjSize_p) + { + StrSize = ObjSize_p - 1; + } + } + + if (pSrcData_p != NULL) + { + // copy data + EPL_MEMCPY (pDstData_p, pSrcData_p, ObjSize_p); + + if (ObjType_p == kEplObdTypVString) + { + ((char MEM*) pDstData_p)[StrSize] = '\0'; + } + } + } + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplObdIsNumericalIntern() +// +// Description: function checks if a entry is numerical or not +// +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer +// uiIndex_p = Index +// uiSubIndex_p = Subindex +// pfEntryNumerical_p = pointer to BOOL for returnvalue +// -> TRUE if entry a numerical value +// -> FALSE if entry not a numerical value +// +// Return: tEplKernel = Errorcode +// +// State: +// +//--------------------------------------------------------------------------- +static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p, + BOOL* pfEntryNumerical_p) +{ +tEplKernel Ret = kEplSuccessful; + + + // get Type + if((pObdSubEntry_p->m_Type == kEplObdTypVString) + || (pObdSubEntry_p->m_Type == kEplObdTypOString) + || (pObdSubEntry_p->m_Type == kEplObdTypDomain)) + { // not numerical types + *pfEntryNumerical_p = FALSE; + } + else + { // numerical types + *pfEntryNumerical_p = TRUE; + } + + return Ret; + +} + + +// ------------------------------------------------------------------------- +// function to classify object type (fixed/non fixed) +// ------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// Function: EplObdCallStoreCallback() +// +// Description: checks address to callback function and calles it when unequal +// to NULL +// +// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = (instance pointer) +// pCbStoreParam_p = address to callback parameters +// +// Returns: tEplKernel = error code +// ---------------------------------------------------------------------------- +#if (EPL_OBD_USE_STORE_RESTORE != FALSE) +static tEplKernel EplObdCallStoreCallback (EPL_MCO_DECL_INSTANCE_PTR_ + tEplObdCbStoreParam MEM* pCbStoreParam_p) +{ + +tEplKernel Ret = kEplSuccessful; + + ASSERT (pCbStoreParam_p != NULL); + + // check if function pointer is NULL - if so, no callback should be called + if (EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) != NULL) + { + Ret = EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) (EPL_MCO_INSTANCE_PARAM_IDX_() + pCbStoreParam_p); + } + + return Ret; + +} +#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) +//--------------------------------------------------------------------------- +// +// Function: EplObdGetObjectDataPtrIntern() +// +// Description: Function gets the data pointer of an object. +// It returnes the current data pointer. But if object is an +// constant object it returnes the default pointer. +// +// Parameters: pSubindexEntry_p = pointer to subindex entry +// +// Return: void * = pointer to object data +// +// State: +// +//--------------------------------------------------------------------------- + +void * EplObdGetObjectDataPtrIntern (tEplObdSubEntryPtr pSubindexEntry_p) +{ + +void * pData; +tEplObdAccess Access; + + ASSERTMSG (pSubindexEntry_p != NULL, "EplObdGetObjectDataPtrIntern(): pointer to SubEntry not valid!\n"); + + // there are are some objects whose data pointer has to get from other structure + // get access type for this object + Access = pSubindexEntry_p->m_Access; + + // If object has access type = const, + // for data only exists default values. + if ((Access & kEplObdAccConst) != 0) + { + // The pointer to defualt value can be received from ObdGetObjectDefaultPtr() + pData = ((void *) EplObdGetObjectDefaultPtr (pSubindexEntry_p)); + } + else + { + // The pointer to current value can be received from ObdGetObjectCurrentPtr() + pData = ((void *) EplObdGetObjectCurrentPtr (pSubindexEntry_p)); + } + + return pData; + +} +#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) +// EOF + |