tEplKernel PUBLIC EplCfmuCbObdAccess(tEplObdCbParam MEM* pParam_p) { tEplKernel Ret = kEplSuccessful; tEplObdVStringDomain* pMemVStringDomain; tEplCfmuNodeInfo* pNodeInfo = NULL; BYTE* pbBuffer; pParam_p->m_dwAbortCode = 0; if ((pParam_p->m_uiIndex != 0x1F22) || (pParam_p->m_ObdEvent != kEplObdEvWrStringDomain)) { goto Exit; } // abort any running SDO transfer pNodeInfo = EPL_CFMU_GET_NODEINFO(pParam_p->m_uiSubIndex); if ((pNodeInfo != NULL) && (pNodeInfo->m_SdoComConHdl != ~0)) { Ret = EplSdoComSdoAbort(pNodeInfo->m_SdoComConHdl, EPL_SDOAC_DATA_NOT_TRANSF_DUE_DEVICE_STATE); } pMemVStringDomain = pParam_p->m_pArg; if ((pMemVStringDomain->m_ObjSize != pMemVStringDomain->m_DownloadSize) || (pMemVStringDomain->m_pData == NULL)) { pNodeInfo = EplCfmuAllocNodeInfo(pParam_p->m_uiSubIndex); if (pNodeInfo == NULL) { pParam_p->m_dwAbortCode = EPL_SDOAC_OUT_OF_MEMORY; Ret = kEplNoResource; goto Exit; } pbBuffer = pNodeInfo->m_pbObdBufferConciseDcf; if (pbBuffer != NULL) { EPL_FREE(pbBuffer); pNodeInfo->m_pbObdBufferConciseDcf = NULL; } pbBuffer = EPL_MALLOC(pMemVStringDomain->m_DownloadSize); if (pbBuffer == NULL) { pParam_p->m_dwAbortCode = EPL_SDOAC_OUT_OF_MEMORY; Ret = kEplNoResource; goto Exit; } pNodeInfo->m_pbObdBufferConciseDcf = pbBuffer; pMemVStringDomain->m_pData = pbBuffer; pMemVStringDomain->m_ObjSize = pMemVStringDomain->m_DownloadSize; } Exit: return Ret; }
static tEplKernel EplCfmuSdoWriteObject( tEplCfmuNodeInfo* pNodeInfo_p, void* pSrcData_le_p, unsigned int uiSize_p) { tEplKernel Ret = kEplSuccessful; tEplSdoComTransParamByIndex TransParamByIndex; if ((pSrcData_le_p == NULL) || (uiSize_p == 0)) { Ret = kEplApiInvalidParam; goto Exit; } if (pNodeInfo_p->m_SdoComConHdl == ~0) { // init command layer connection Ret = EplSdoComDefineCon(&pNodeInfo_p->m_SdoComConHdl, pNodeInfo_p->m_EventCnProgress.m_uiNodeId, kEplSdoTypeAsnd); if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) { goto Exit; } } TransParamByIndex.m_pData = pSrcData_le_p; TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeWrite; TransParamByIndex.m_SdoComConHdl = pNodeInfo_p->m_SdoComConHdl; TransParamByIndex.m_uiDataSize = uiSize_p; TransParamByIndex.m_uiIndex = pNodeInfo_p->m_EventCnProgress.m_uiObjectIndex; TransParamByIndex.m_uiSubindex = pNodeInfo_p->m_EventCnProgress.m_uiObjectSubIndex; TransParamByIndex.m_pfnSdoFinishedCb = EplCfmuCbSdoCon; TransParamByIndex.m_pUserArg = pNodeInfo_p; Ret = EplSdoComInitTransferByIndex(&TransParamByIndex); if (Ret == kEplSdoComHandleBusy) { Ret = EplSdoComSdoAbort(pNodeInfo_p->m_SdoComConHdl, EPL_SDOAC_DATA_NOT_TRANSF_DUE_LOCAL_CONTROL); if (Ret == kEplSuccessful) { Ret = EplSdoComInitTransferByIndex(&TransParamByIndex); } } Exit: return Ret; }
tEplKernel EplCfmuDelInstance(void) { tEplKernel Ret = kEplSuccessful; unsigned int uiNodeId; tEplVarParam VarParam; BYTE* pbBuffer; tEplCfmuNodeInfo* pNodeInfo; // free domain for object 0x1F22 CFM_ConciseDcfList_ADOM VarParam.m_pData = NULL; VarParam.m_Size = 0; VarParam.m_uiIndex = 0x1F22; for (uiNodeId = 1; uiNodeId <= EPL_NMT_MAX_NODE_ID; uiNodeId++) { pNodeInfo = EPL_CFMU_GET_NODEINFO(uiNodeId); if (pNodeInfo != NULL) { if (pNodeInfo->m_SdoComConHdl != ~0) { Ret = EplSdoComSdoAbort(pNodeInfo->m_SdoComConHdl, EPL_SDOAC_DATA_NOT_TRANSF_DUE_DEVICE_STATE); } pbBuffer = pNodeInfo->m_pbObdBufferConciseDcf; if (pbBuffer != NULL) { VarParam.m_uiSubindex = uiNodeId; VarParam.m_ValidFlag = kVarValidAll; Ret = EplObdDefineVar(&VarParam); // ignore return code, because buffer has to be freed anyway EPL_FREE(pbBuffer); pNodeInfo->m_pbObdBufferConciseDcf = NULL; } EPL_FREE(pNodeInfo); EPL_CFMU_GET_NODEINFO(uiNodeId) = NULL; } } Ret = kEplSuccessful; //Exit: return Ret; }
tEplKernel EplCfmuProcessNodeEvent(unsigned int uiNodeId_p, tEplNmtNodeEvent NodeEvent_p, tEplNmtState NmtState_p) { tEplKernel Ret = kEplSuccessful; static DWORD dw_le_Signature; tEplCfmuNodeInfo* pNodeInfo = NULL; tEplObdSize ObdSize; DWORD dwExpConfTime = 0; DWORD dwExpConfDate = 0; tEplIdentResponse* pIdentResponse = NULL; BOOL fDoUpdate = FALSE; if ((NodeEvent_p != kEplNmtNodeEventCheckConf) && (NodeEvent_p != kEplNmtNodeEventUpdateConf) && (NodeEvent_p != kEplNmtNodeEventFound) && ((NodeEvent_p != kEplNmtNodeEventNmtState) || (NmtState_p != kEplNmtCsNotActive))) { goto Exit; } pNodeInfo = EplCfmuAllocNodeInfo(uiNodeId_p); if (pNodeInfo == NULL) { Ret = kEplInvalidNodeId; goto Exit; } if (pNodeInfo->m_CfmState != kEplCfmuStateIdle) { // Set node CFM state pNodeInfo->m_CfmState = kEplCfmuStateInternalAbort; // Send abort if SDO command is not undefined if (pNodeInfo->m_SdoComConHdl != ~0U) { Ret = EplSdoComSdoAbort(pNodeInfo->m_SdoComConHdl, EPL_SDOAC_DATA_NOT_TRANSF_DUE_LOCAL_CONTROL); if (Ret != kEplSuccessful) { goto Exit; } // close connection Ret = EplSdoComUndefineCon(pNodeInfo->m_SdoComConHdl); pNodeInfo->m_SdoComConHdl = ~0U; if (Ret != kEplSuccessful) { EPL_DBGLVL_CFM_TRACE("SDO Free Error!\n"); goto Exit; } } } if ((NodeEvent_p == kEplNmtNodeEventFound) || ((NodeEvent_p == kEplNmtNodeEventNmtState) && (NmtState_p == kEplNmtCsNotActive))) { // just close SDO connection in case of IdentResponse or loss of connection goto Exit; } pNodeInfo->m_uiCurDataSize = 0; // fetch pointer to ConciseDCF from object 0x1F22 // (this allows the application to link its own memory to this object) pNodeInfo->m_pbDataConciseDcf = EplObduGetObjectDataPtr(0x1F22, uiNodeId_p); if (pNodeInfo->m_pbDataConciseDcf == NULL) { Ret = kEplCfmNoConfigData; goto Exit; } ObdSize = EplObduGetDataSize(0x1F22, uiNodeId_p); pNodeInfo->m_dwBytesRemaining = (DWORD) ObdSize; pNodeInfo->m_EventCnProgress.m_dwTotalNumberOfBytes = pNodeInfo->m_dwBytesRemaining; #if (EPL_CFM_CONFIGURE_CYCLE_LENGTH != FALSE) pNodeInfo->m_EventCnProgress.m_dwTotalNumberOfBytes += sizeof (DWORD); #endif pNodeInfo->m_EventCnProgress.m_dwBytesDownloaded = 0; if (ObdSize < sizeof (DWORD)) { pNodeInfo->m_EventCnProgress.m_EplError = kEplCfmInvalidDcf; Ret = EplCfmuCallCbProgress(pNodeInfo); if (Ret != kEplSuccessful) { goto Exit; } Ret = pNodeInfo->m_EventCnProgress.m_EplError; goto Exit; } pNodeInfo->m_dwEntriesRemaining = AmiGetDwordFromLe(pNodeInfo->m_pbDataConciseDcf); pNodeInfo->m_pbDataConciseDcf += sizeof (DWORD); pNodeInfo->m_dwBytesRemaining -= sizeof (DWORD); pNodeInfo->m_EventCnProgress.m_dwBytesDownloaded += sizeof (DWORD); if (pNodeInfo->m_dwEntriesRemaining == 0) { pNodeInfo->m_EventCnProgress.m_EplError = kEplCfmNoConfigData; Ret = EplCfmuCallCbProgress(pNodeInfo); if (Ret != kEplSuccessful) { goto Exit; } } else { ObdSize = sizeof (dwExpConfDate); Ret = EplObduReadEntry(0x1F26, uiNodeId_p, &dwExpConfDate, &ObdSize); if (Ret != kEplSuccessful) { EPL_DBGLVL_CFM_TRACE("CN%x Error Reading 0x1F26 returns 0x%X\n", uiNodeId_p, Ret); } ObdSize = sizeof (dwExpConfTime); Ret = EplObduReadEntry(0x1F27, uiNodeId_p, &dwExpConfTime, &ObdSize); if (Ret != kEplSuccessful) { EPL_DBGLVL_CFM_TRACE("CN%x Error Reading 0x1F27 returns 0x%X\n", uiNodeId_p, Ret); } if ((dwExpConfDate != 0) || (dwExpConfTime != 0)) { // store configuration in CN at the end of the download, // because expected configuration date or time is set pNodeInfo->m_fDoStore = TRUE; pNodeInfo->m_EventCnProgress.m_dwTotalNumberOfBytes += sizeof (DWORD); } else { // expected configuration date and time is not set fDoUpdate = TRUE; } EplIdentuGetIdentResponse(uiNodeId_p, &pIdentResponse); if (pIdentResponse == NULL) { EPL_DBGLVL_CFM_TRACE("CN%x Ident Response is NULL\n", uiNodeId_p); Ret = kEplInvalidNodeId; goto Exit; } } #if (EPL_CFM_CONFIGURE_CYCLE_LENGTH != FALSE) ObdSize = sizeof (EplCfmuInstance_g.m_le_dwCycleLength); Ret = EplObduReadEntryToLe(0x1006, 0x00, &EplCfmuInstance_g.m_le_dwCycleLength, &ObdSize); if (Ret != kEplSuccessful) { // local OD access failed EPL_DBGLVL_CFM_TRACE("Local OBD read failed %d\n", Ret); goto Exit; } #endif if ((pNodeInfo->m_dwEntriesRemaining == 0) || ((NodeEvent_p != kEplNmtNodeEventUpdateConf) && (fDoUpdate == FALSE) && ((AmiGetDwordFromLe(&pIdentResponse->m_le_dwVerifyConfigurationDate) == dwExpConfDate) && (AmiGetDwordFromLe(&pIdentResponse->m_le_dwVerifyConfigurationTime) == dwExpConfTime)))) { pNodeInfo->m_CfmState = kEplCfmuStateIdle; // current version is already available on the CN, no need to write new values, we can continue EPL_DBGLVL_CFM_TRACE("CN%x - Cfg Upto Date\n", uiNodeId_p); Ret = EplCfmuDownloadCycleLength(pNodeInfo); if (Ret == kEplReject) { pNodeInfo->m_CfmState = kEplCfmuStateUpToDate; } } else if (NodeEvent_p == kEplNmtNodeEventUpdateConf) { pNodeInfo->m_CfmState = kEplCfmuStateDownload; Ret = EplCfmuDownloadObject(pNodeInfo); if (Ret == kEplSuccessful) { // SDO transfer started Ret = kEplReject; } } else { pNodeInfo->m_CfmState = kEplCfmuStateWaitRestore; pNodeInfo->m_EventCnProgress.m_dwTotalNumberOfBytes += sizeof (dw_le_Signature); AmiSetDwordToLe(&dw_le_Signature, 0x64616F6C); //Restore Default Parameters EPL_DBGLVL_CFM_TRACE("CN%x - Cfg Mismatch | MN Expects: %lx-%lx ", uiNodeId_p, dwExpConfDate, dwExpConfTime); EPL_DBGLVL_CFM_TRACE("CN Has: %lx-%lx. Restoring Default...\n", AmiGetDwordFromLe(&pIdentResponse->m_le_dwVerifyConfigurationDate), AmiGetDwordFromLe(&pIdentResponse->m_le_dwVerifyConfigurationTime)); pNodeInfo->m_EventCnProgress.m_uiObjectIndex = 0x1011; pNodeInfo->m_EventCnProgress.m_uiObjectSubIndex = 0x01; Ret = EplCfmuSdoWriteObject(pNodeInfo, &dw_le_Signature, sizeof (dw_le_Signature)); if (Ret == kEplSuccessful) { // SDO transfer started Ret = kEplReject; } else { // error occurred EPL_DBGLVL_CFM_TRACE("CfmCbEvent(Node): EplCfmuSdoWriteObject() returned 0x%02X\n", Ret); } } Exit: return Ret; }