static tEplKernel EplCfmuFinishConfig(tEplCfmuNodeInfo* pNodeInfo_p, tEplNmtCommand NmtCommand_p) { tEplKernel Ret = kEplSuccessful; if (pNodeInfo_p->m_SdoComConHdl != ~0U) { Ret = EplSdoComUndefineCon(pNodeInfo_p->m_SdoComConHdl); pNodeInfo_p->m_SdoComConHdl = ~0U; if (Ret != kEplSuccessful) { EPL_DBGLVL_CFM_TRACE0("SDO Free Error!\n"); goto Exit; } } pNodeInfo_p->m_CfmState = kEplCfmuStateIdle; if (EplCfmuInstance_g.m_pfnCbEventCnResult != NULL) { Ret = EplCfmuInstance_g.m_pfnCbEventCnResult(pNodeInfo_p->m_EventCnProgress.m_uiNodeId, NmtCommand_p); } 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); } } else if (Ret == kEplSdoSeqConnectionBusy) { // close connection Ret = EplSdoComUndefineCon(pNodeInfo_p->m_SdoComConHdl); pNodeInfo_p->m_SdoComConHdl = ~0U; if (Ret != kEplSuccessful) { EPL_DBGLVL_CFM_TRACE0("SDO Free Error!\n"); goto Exit; } // reinit command layer connection Ret = EplSdoComDefineCon(&pNodeInfo_p->m_SdoComConHdl, pNodeInfo_p->m_EventCnProgress.m_uiNodeId, kEplSdoTypeAsnd); if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) { goto Exit; } // retry transfer TransParamByIndex.m_SdoComConHdl = pNodeInfo_p->m_SdoComConHdl; Ret = EplSdoComInitTransferByIndex(&TransParamByIndex); } Exit: return Ret; }
tEplKernel EplCfmuProcessNodeEvent(unsigned int uiNodeId_p, tEplNmtNodeEvent NodeEvent_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)) { goto Exit; } pNodeInfo = EplCfmuAllocNodeInfo(uiNodeId_p); if (pNodeInfo == NULL) { Ret = kEplInvalidNodeId; goto Exit; } if (pNodeInfo->m_CfmState != kEplCfmuStateIdle) { // send abort pNodeInfo->m_CfmState = kEplCfmuStateInternalAbort; 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_TRACE0("SDO Free Error!\n"); 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_TRACE2("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_TRACE2("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_TRACE1("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_TRACE1("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_TRACE1("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_TRACE3("CN%x - Cfg Mismatch | MN Expects: %lx-%lx ", uiNodeId_p, dwExpConfDate, dwExpConfTime); EPL_DBGLVL_CFM_TRACE2("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 occured EPL_DBGLVL_CFM_TRACE1("CfmCbEvent(Node): EplCfmuSdoWriteObject() returned 0x%02X\n", Ret); } } Exit: return Ret; }