diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 19:54:53 (GMT) |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 20:01:40 (GMT) |
commit | ae19ffbadc1b2100285a5b5b3d0a4e0a11390904 (patch) | |
tree | 3c2086ab67398a019089a47ca3f362a4bc6db74f /drivers/staging/epl/EplSdoAsySequ.c | |
parent | 34e84f39a27d059a3e6ec6e8b94aafa702e6f220 (diff) | |
parent | 9173a8ef24a6b1b8031507b35b8ffe5f85a87692 (diff) | |
download | linux-fsl-qoriq-ae19ffbadc1b2100285a5b5b3d0a4e0a11390904.tar.xz |
Merge branch 'master' into for-linus
Diffstat (limited to 'drivers/staging/epl/EplSdoAsySequ.c')
-rw-r--r-- | drivers/staging/epl/EplSdoAsySequ.c | 2522 |
1 files changed, 0 insertions, 2522 deletions
diff --git a/drivers/staging/epl/EplSdoAsySequ.c b/drivers/staging/epl/EplSdoAsySequ.c deleted file mode 100644 index 256d708..0000000 --- a/drivers/staging/epl/EplSdoAsySequ.c +++ /dev/null @@ -1,2522 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for asychronous SDO Sequence Layer 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: EplSdoAsySequ.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.10 $ $Date: 2008/11/13 17:13:09 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/26 k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplSdoAsySequ.h" - -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) == 0) &&\ - (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) == 0) ) - -#error 'ERROR: At least UDP or Asnd module needed!' - -#endif -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#define EPL_SDO_HISTORY_SIZE 5 - -#ifndef EPL_MAX_SDO_SEQ_CON -#define EPL_MAX_SDO_SEQ_CON 10 -#endif - -#define EPL_SEQ_DEFAULT_TIMEOUT 5000 // in [ms] => 5 sec - -#define EPL_SEQ_RETRY_COUNT 5 // => max. Timeout 30 sec - -#define EPL_SEQ_NUM_THRESHOLD 100 // threshold which distinguishes between old and new sequence numbers - -// define frame with size of Asnd-Header-, SDO Sequenze Header size, SDO Command header -// and Ethernet-Header size -#define EPL_SEQ_FRAME_SIZE 24 -// size of the header of the asynchronus SDO Sequence layer -#define EPL_SEQ_HEADER_SIZE 4 - -// buffersize for one frame in history -#define EPL_SEQ_HISTROY_FRAME_SIZE EPL_MAX_SDO_FRAME_SIZE - -// mask to get scon and rcon -#define EPL_ASY_SDO_CON_MASK 0x03 - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -// events for processfunction -typedef enum { - kAsySdoSeqEventNoEvent = 0x00, // no Event - kAsySdoSeqEventInitCon = 0x01, // init connection - kAsySdoSeqEventFrameRec = 0x02, // frame received - kAsySdoSeqEventFrameSend = 0x03, // frame to send - kAsySdoSeqEventTimeout = 0x04, // Timeout for connection - kAsySdoSeqEventCloseCon = 0x05 // higher layer close connection -} tEplAsySdoSeqEvent; - -// structure for History-Buffer -typedef struct { - u8 m_bFreeEntries; - u8 m_bWrite; // index of the next free buffer entry - u8 m_bAck; // index of the next message which should become acknowledged - u8 m_bRead; // index between m_bAck and m_bWrite to the next message for retransmission - u8 m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE] - [EPL_SEQ_HISTROY_FRAME_SIZE]; - unsigned int m_auiFrameSize[EPL_SDO_HISTORY_SIZE]; - -} tEplAsySdoConHistory; - -// state of the statemaschine -typedef enum { - kEplAsySdoStateIdle = 0x00, - kEplAsySdoStateInit1 = 0x01, - kEplAsySdoStateInit2 = 0x02, - kEplAsySdoStateInit3 = 0x03, - kEplAsySdoStateConnected = 0x04, - kEplAsySdoStateWaitAck = 0x05 -} tEplAsySdoState; - -// connection control structure -typedef struct { - tEplSdoConHdl m_ConHandle; - tEplAsySdoState m_SdoState; - u8 m_bRecSeqNum; // name from view of the communication partner - u8 m_bSendSeqNum; // name from view of the communication partner - tEplAsySdoConHistory m_SdoConHistory; - tEplTimerHdl m_EplTimerHdl; - unsigned int m_uiRetryCount; // retry counter - unsigned int m_uiUseCount; // one sequence layer connection may be used by - // multiple command layer connections - -} tEplAsySdoSeqCon; - -// instance structure -typedef struct { - tEplAsySdoSeqCon m_AsySdoConnection[EPL_MAX_SDO_SEQ_CON]; - tEplSdoComReceiveCb m_fpSdoComReceiveCb; - tEplSdoComConCb m_fpSdoComConCb; - -#if defined(WIN32) || defined(_WIN32) - LPCRITICAL_SECTION m_pCriticalSection; - CRITICAL_SECTION m_CriticalSection; - - LPCRITICAL_SECTION m_pCriticalSectionReceive; - CRITICAL_SECTION m_CriticalSectionReceive; -#endif - -} tEplAsySdoSequInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -static tEplAsySdoSequInstance AsySdoSequInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p, - unsigned int uiDataSize_p, - tEplFrame * pData_p, - tEplAsySdoSeq * pRecFrame_p, - tEplAsySdoSeqEvent Event_p); - -static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned int uiDataSize_p, - tEplFrame * pData_p, - BOOL fFrameInHistory); - -static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned int uiDataSize_p, - tEplFrame * pEplFrame_p); - -tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p, - tEplAsySdoSeq *pSdoSeqData_p, - unsigned int uiDataSize_p); - -static tEplKernel EplSdoAsyInitHistory(void); - -static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - tEplFrame * pFrame_p, - unsigned int uiSize_p); - -static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - u8 bRecSeqNumber_p); - -static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - tEplFrame ** ppFrame_p, - unsigned int *puiSize_p, - BOOL fInitRead); - -static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon * - pAsySdoSeqCon_p); - -static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned long ulTimeout); - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S <EPL asychronus SDO Sequence layer> */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: this module contains the asynchronus SDO Sequence Layer for -// the EPL SDO service -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqInit -// -// Description: init first instance -// -// -// -// Parameters: fpSdoComCb_p = callback function to inform Command layer -// about new frames -// fpSdoComConCb_p = callback function to inform command layer -// about connection state -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p, - tEplSdoComConCb fpSdoComConCb_p) -{ - tEplKernel Ret; - - Ret = EplSdoAsySeqAddInstance(fpSdoComCb_p, fpSdoComConCb_p); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqAddInstance -// -// Description: init following instances -// -// -// -// Parameters: fpSdoComCb_p = callback function to inform Command layer -// about new frames -// fpSdoComConCb_p = callback function to inform command layer -// about connection state -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p, - tEplSdoComConCb fpSdoComConCb_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // check functionpointer - if (fpSdoComCb_p == NULL) { - Ret = kEplSdoSeqMissCb; - goto Exit; - } else { - AsySdoSequInstance_g.m_fpSdoComReceiveCb = fpSdoComCb_p; - } - - // check functionpointer - if (fpSdoComConCb_p == NULL) { - Ret = kEplSdoSeqMissCb; - goto Exit; - } else { - AsySdoSequInstance_g.m_fpSdoComConCb = fpSdoComConCb_p; - } - - // set controllstructure to 0 - EPL_MEMSET(&AsySdoSequInstance_g.m_AsySdoConnection[0], 0x00, - sizeof(AsySdoSequInstance_g.m_AsySdoConnection)); - - // init History - Ret = EplSdoAsyInitHistory(); - if (Ret != kEplSuccessful) { - goto Exit; - } -#if defined(WIN32) || defined(_WIN32) - // create critical section for process function - AsySdoSequInstance_g.m_pCriticalSection = - &AsySdoSequInstance_g.m_CriticalSection; - InitializeCriticalSection(AsySdoSequInstance_g.m_pCriticalSection); - - // init critical section for receive cb function - AsySdoSequInstance_g.m_pCriticalSectionReceive = - &AsySdoSequInstance_g.m_CriticalSectionReceive; - InitializeCriticalSection(AsySdoSequInstance_g. - m_pCriticalSectionReceive); -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - // init lower layer - Ret = EplSdoUdpuAddInstance(EplSdoAsyReceiveCb); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - // init lower layer - Ret = EplSdoAsnduAddInstance(EplSdoAsyReceiveCb); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqDelInstance -// -// Description: delete instances -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqDelInstance(void) -{ - tEplKernel Ret; - unsigned int uiCount; - tEplAsySdoSeqCon *pAsySdoSeqCon; - - Ret = kEplSuccessful; - - // delete timer of open connections - uiCount = 0; - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0]; - while (uiCount < EPL_MAX_SDO_SEQ_CON) { - if (pAsySdoSeqCon->m_ConHandle != 0) { - EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl); - } - uiCount++; - pAsySdoSeqCon++; - } - -#if defined(WIN32) || defined(_WIN32) - // delete critical section for process function - DeleteCriticalSection(AsySdoSequInstance_g.m_pCriticalSection); -#endif - - // set instance-table to 0 - EPL_MEMSET(&AsySdoSequInstance_g, 0x00, sizeof(AsySdoSequInstance_g)); - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - // delete lower layer - Ret = EplSdoUdpuDelInstance(); -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - // delete lower layer - Ret = EplSdoAsnduDelInstance(); -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqInitCon -// -// Description: start initialization of a sequence layer connection. -// It tries to reuse an existing connection to the same node. -// -// -// Parameters: pSdoSeqConHdl_p = pointer to the variable for the connection handle -// uiNodeId_p = Node Id of the target -// SdoType = Type of the SDO connection -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p, - unsigned int uiNodeId_p, - tEplSdoType SdoType) -{ - tEplKernel Ret; - unsigned int uiCount; - unsigned int uiFreeCon; - tEplSdoConHdl ConHandle; - tEplAsySdoSeqCon *pAsySdoSeqCon; - Ret = kEplSuccessful; - - // check SdoType - // call init function of the protcol abstraction layer - // which tries to find an existing connection to the same node - switch (SdoType) { - // SDO over UDP - case kEplSdoTypeUdp: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - Ret = EplSdoUdpuInitCon(&ConHandle, uiNodeId_p); - if (Ret != kEplSuccessful) { - goto Exit; - } -#else - Ret = kEplSdoSeqUnsupportedProt; -#endif - break; - } - - // SDO over Asnd - case kEplSdoTypeAsnd: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - Ret = EplSdoAsnduInitCon(&ConHandle, uiNodeId_p); - if (Ret != kEplSuccessful) { - goto Exit; - } -#else - Ret = kEplSdoSeqUnsupportedProt; -#endif - break; - } - - // unsupported protocols - // -> auto should be replaced by command layer - case kEplSdoTypeAuto: - case kEplSdoTypePdo: - default: - { - Ret = kEplSdoSeqUnsupportedProt; - goto Exit; - } - - } // end of switch(SdoType) - - // find existing connection to the same node or find empty entry for connection - uiCount = 0; - uiFreeCon = EPL_MAX_SDO_SEQ_CON; - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0]; - - while (uiCount < EPL_MAX_SDO_SEQ_CON) { - if (pAsySdoSeqCon->m_ConHandle == ConHandle) { // existing connection found - break; - } - if (pAsySdoSeqCon->m_ConHandle == 0) { - uiFreeCon = uiCount; - } - uiCount++; - pAsySdoSeqCon++; - } - - if (uiCount == EPL_MAX_SDO_SEQ_CON) { - if (uiFreeCon == EPL_MAX_SDO_SEQ_CON) { // no free entry found - switch (SdoType) { - // SDO over UDP - case kEplSdoTypeUdp: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - Ret = EplSdoUdpuDelCon(ConHandle); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - break; - } - - // SDO over Asnd - case kEplSdoTypeAsnd: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - Ret = EplSdoAsnduDelCon(ConHandle); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - break; - } - - // unsupported protocols - // -> auto should be replaced by command layer - case kEplSdoTypeAuto: - case kEplSdoTypePdo: - default: - { - Ret = kEplSdoSeqUnsupportedProt; - goto Exit; - } - - } // end of switch(SdoType) - - Ret = kEplSdoSeqNoFreeHandle; - goto Exit; - } else { // free entry found - pAsySdoSeqCon = - &AsySdoSequInstance_g.m_AsySdoConnection[uiFreeCon]; - pAsySdoSeqCon->m_ConHandle = ConHandle; - uiCount = uiFreeCon; - } - } - // set handle - *pSdoSeqConHdl_p = (uiCount | EPL_SDO_ASY_HANDLE); - - // increment use counter - pAsySdoSeqCon->m_uiUseCount++; - - // call intern process function - Ret = EplSdoAsySeqProcess(uiCount, - 0, NULL, NULL, kAsySdoSeqEventInitCon); - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqSendData -// -// Description: send sata unsing a established connection -// -// -// -// Parameters: pSdoSeqConHdl_p = connection handle -// uiDataSize_p = Size of Frame to send -// -> wihtout SDO sequence layer header, Asnd header -// and ethernetnet -// ==> SDO Sequence layer payload -// SdoType = Type of the SDO connection -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p, - unsigned int uiDataSize_p, - tEplFrame *pabData_p) -{ - tEplKernel Ret; - unsigned int uiHandle; - - uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK); - - // check if connection ready - if (AsySdoSequInstance_g.m_AsySdoConnection[uiHandle].m_SdoState == - kEplAsySdoStateIdle) { - // no connection with this handle - Ret = kEplSdoSeqInvalidHdl; - goto Exit; - } else if (AsySdoSequInstance_g.m_AsySdoConnection[uiHandle]. - m_SdoState != kEplAsySdoStateConnected) { - Ret = kEplSdoSeqConnectionBusy; - goto Exit; - } - - Ret = EplSdoAsySeqProcess(uiHandle, - uiDataSize_p, - pabData_p, NULL, kAsySdoSeqEventFrameSend); - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqProcessEvent -// -// Description: function processes extern events -// -> later needed for timeout controll with timer-module -// -// -// -// Parameters: pEvent_p = pointer to event -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p) -{ - tEplKernel Ret; - tEplTimerEventArg *pTimerEventArg; - tEplAsySdoSeqCon *pAsySdoSeqCon; - tEplTimerHdl EplTimerHdl; - unsigned int uiCount; - - Ret = kEplSuccessful; - // check parameter - if (pEvent_p == NULL) { - Ret = kEplSdoSeqInvalidEvent; - goto Exit; - } - - if (pEvent_p->m_EventType != kEplEventTypeTimer) { - Ret = kEplSdoSeqInvalidEvent; - goto Exit; - } - // get timerhdl - pTimerEventArg = (tEplTimerEventArg *) pEvent_p->m_pArg; - EplTimerHdl = pTimerEventArg->m_TimerHdl; - - // get pointer to intern control structure of connection - if (pTimerEventArg->m_ulArg == 0) { - goto Exit; - } - pAsySdoSeqCon = (tEplAsySdoSeqCon *) pTimerEventArg->m_ulArg; - - // check if time is current - if (EplTimerHdl != pAsySdoSeqCon->m_EplTimerHdl) { - // delete timer - EplTimeruDeleteTimer(&EplTimerHdl); - goto Exit; - } - // delete timer - EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl); - - // get indexnumber of control structure - uiCount = 0; - while ((&AsySdoSequInstance_g.m_AsySdoConnection[uiCount]) != - pAsySdoSeqCon) { - uiCount++; - if (uiCount > EPL_MAX_SDO_SEQ_CON) { - goto Exit; - } - } - - // process event and call processfunction if needed - Ret = EplSdoAsySeqProcess(uiCount, - 0, NULL, NULL, kAsySdoSeqEventTimeout); - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqDelCon -// -// Description: del and close one connection -// -// -// -// Parameters: SdoSeqConHdl_p = handle of connection -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiHandle; - tEplAsySdoSeqCon *pAsySdoSeqCon; - - uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK); - - // check if handle invalid - if (uiHandle >= EPL_MAX_SDO_SEQ_CON) { - Ret = kEplSdoSeqInvalidHdl; - goto Exit; - } - // get pointer to connection - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle]; - - // decrement use counter - pAsySdoSeqCon->m_uiUseCount--; - - if (pAsySdoSeqCon->m_uiUseCount == 0) { - // process close in processfunction - Ret = EplSdoAsySeqProcess(uiHandle, - 0, - NULL, NULL, kAsySdoSeqEventCloseCon); - - //check protocol - if ((pAsySdoSeqCon->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == - EPL_SDO_UDP_HANDLE) { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - // call close function of lower layer - EplSdoUdpuDelCon(pAsySdoSeqCon->m_ConHandle); -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - } else { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - // call close function of lower layer - EplSdoAsnduDelCon(pAsySdoSeqCon->m_ConHandle); -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - } - - // delete timer - EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl); - - // clean controllstructure - EPL_MEMSET(pAsySdoSeqCon, 0x00, sizeof(tEplAsySdoSeqCon)); - pAsySdoSeqCon->m_SdoConHistory.m_bFreeEntries = - EPL_SDO_HISTORY_SIZE; - } - - Exit: - return Ret; - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplEplSdoAsySeqProcess -// -// Description: intern function to process the asynchronus SDO Sequence Layer -// state maschine -// -// -// -// Parameters: uiHandle_p = index of the control structure of the connection -// uiDataSize_p = size of data frame to process (can be 0) -// -> without size of sequence header and Asnd header!!! -// -// pData_p = pointer to frame to send (can be NULL) -// pRecFrame_p = pointer to received frame (can be NULL) -// Event_p = Event to process -// -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p, - unsigned int uiDataSize_p, - tEplFrame * pData_p, - tEplAsySdoSeq * pRecFrame_p, - tEplAsySdoSeqEvent Event_p) -{ - tEplKernel Ret; - unsigned int uiFrameSize; - tEplFrame *pEplFrame; - tEplAsySdoSeqCon *pAsySdoSeqCon; - tEplSdoSeqConHdl SdoSeqConHdl; - unsigned int uiFreeEntries; - -#if defined(WIN32) || defined(_WIN32) - // enter critical section for process function - EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSection); -#endif - - Ret = kEplSuccessful; - - // get handle for hinger layer - SdoSeqConHdl = uiHandle_p | EPL_SDO_ASY_HANDLE; - - // check if handle invalid - if ((SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == - EPL_SDO_SEQ_INVALID_HDL) { - Ret = kEplSdoSeqInvalidHdl; - goto Exit; - } - // get pointer to connection - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle_p]; - - // check size - if ((pData_p == NULL) && (pRecFrame_p == NULL) && (uiDataSize_p != 0)) { - Ret = kEplSdoSeqInvalidFrame; - goto Exit; - } - // check state - switch (pAsySdoSeqCon->m_SdoState) { - // idle state - case kEplAsySdoStateIdle: - { - // check event - switch (Event_p) { - // new connection - // -> send init frame and change to - // kEplAsySdoStateInit1 - case kAsySdoSeqEventInitCon: - { - // set sending scon to 1 - pAsySdoSeqCon->m_bRecSeqNum = 0x01; - // set set send rcon to 0 - pAsySdoSeqCon->m_bSendSeqNum = 0x00; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit1; - - // set timer - Ret = - EplSdoAsySeqSetTimer(pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - break; - } - - // init con from extern - // check rcon and scon - // -> send answer - case kAsySdoSeqEventFrameRec: - { -/* - PRINTF3("%s scon=%u rcon=%u\n", - __func__, - pRecFrame_p->m_le_bSendSeqNumCon, - pRecFrame_p->m_le_bRecSeqNumCon); -*/ - // check if scon == 1 and rcon == 0 - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x00) - && - ((pRecFrame_p-> - m_le_bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x01)) { - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // create answer and send answer - // set rcon to 1 (in send direction own scon) - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateInit2 - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit2; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - } else { // error -> close - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) != - 0x00) - || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) { // d.k. only answer with close message if the message sent was not a close message - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // set rcon and scon to 0 - pAsySdoSeqCon-> - m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon-> - m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, - NULL, FALSE); - } - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateInitError); - } - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // init connection step 1 - // wait for frame with scon = 1 - // and rcon = 1 - case kEplAsySdoStateInit1: - { -// PRINTF0("EplSdoAsySequ: StateInit1\n"); - - // check event - switch (Event_p) { - // frame received - case kAsySdoSeqEventFrameRec: - { - // check scon == 1 and rcon == 1 - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x01) - && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01)) { // create answer own scon = 2 - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateInit3 - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit3; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - } - // check if scon == 1 and rcon == 0, i.e. other side wants me to be server - else if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x00) - && - ((pRecFrame_p-> - m_le_bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x01)) { - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // create answer and send answer - // set rcon to 1 (in send direction own scon) - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateInit2 - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit2; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - } else { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) != - 0x00) - || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) { // d.k. only answer with close message if the message sent was not a close message - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - // set rcon and scon to 0 - pAsySdoSeqCon-> - m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon-> - m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, - NULL, FALSE); - } - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateInitError); - } - break; - } - - // timeout - case kAsySdoSeqEventTimeout: - { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb(SdoSeqConHdl, - kAsySdoConStateInitError); - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // init connection step 2 - case kEplAsySdoStateInit2: - { -// PRINTF0("EplSdoAsySequ: StateInit2\n"); - - // check event - switch (Event_p) { - // frame received - case kAsySdoSeqEventFrameRec: - { - // check scon == 2 and rcon == 1 - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x01) - && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02)) { // create answer own rcon = 2 - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConnected); - - } - // check scon == 1 and rcon == 1, i.e. other side wants me to initiate the connection - else if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x01) - && - ((pRecFrame_p-> - m_le_bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x01)) { - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // create answer and send answer - // set rcon to 1 (in send direction own scon) - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - // change state to kEplAsySdoStateInit3 - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit3; - - } else { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) != - 0x00) - || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) { // d.k. only answer with close message if the message sent was not a close message - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // set rcon and scon to 0 - pAsySdoSeqCon-> - m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon-> - m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, - NULL, FALSE); - } - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateInitError); - } - break; - } - - // timeout - case kAsySdoSeqEventTimeout: - { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb(SdoSeqConHdl, - kAsySdoConStateInitError); - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // init connection step 3 - case kEplAsySdoStateInit3: - { - // check event - switch (Event_p) { - // frame received - case kAsySdoSeqEventFrameRec: - { - // check scon == 2 and rcon == 2 - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x02) - && - ((pRecFrame_p-> - m_le_bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x02)) { - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // change state to kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConnected); - - } - // check scon == 2 and rcon == 1 - else if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x01) - && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02)) { // create answer own rcon = 2 - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConnected); - - } else { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) != - 0x00) - || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) { // d.k. only answer with close message if the message sent was not a close message - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // set rcon and scon to 0 - pAsySdoSeqCon-> - m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon-> - m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, - NULL, FALSE); - } - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateInitError); - } - break; - } - - // timeout - case kAsySdoSeqEventTimeout: - { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb(SdoSeqConHdl, - kAsySdoConStateInitError); - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // connection established - case kEplAsySdoStateConnected: - { - // check event - switch (Event_p) { - - // frame to send - case kAsySdoSeqEventFrameSend: - { - // set timer - Ret = - EplSdoAsySeqSetTimer(pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - // check if data frame or ack - if (pData_p == NULL) { // send ack - // inc scon - //pAsySdoSeqCon->m_bRecSeqNum += 4; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - } else { // send dataframe - // increment send sequence number - pAsySdoSeqCon->m_bRecSeqNum += - 4; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, - uiDataSize_p, pData_p, - TRUE); - if (Ret == kEplSdoSeqRequestAckNeeded) { // request ack - // change state to wait ack - pAsySdoSeqCon-> - m_SdoState = - kEplAsySdoStateWaitAck; - // set Ret to kEplSuccessful, because no error - // for higher layer - Ret = kEplSuccessful; - - } else if (Ret != - kEplSuccessful) { - goto Exit; - } else { - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateFrameSended); - } - } - break; - } // end of case kAsySdoSeqEventFrameSend - - // frame received - case kAsySdoSeqEventFrameRec: - { - u8 bSendSeqNumCon = - AmiGetByteFromLe(&pRecFrame_p-> - m_le_bSendSeqNumCon); - - // set timer - Ret = - EplSdoAsySeqSetTimer(pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - // check scon - switch (bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) { - // close from other node - case 0: - case 1: - { - // return to idle - pAsySdoSeqCon-> - m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConClosed); - - break; - } - - // Request Ack or Error Ack - // possible contain data - case 3: - // normal frame - case 2: - { - if ((AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon) - & - EPL_ASY_SDO_CON_MASK) - == 3) { -// PRINTF0("EplSdoAsySequ: error response received\n"); - - // error response (retransmission request) - // resend frames from history - - // read frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, - &pEplFrame, - &uiFrameSize, - TRUE); - if (Ret != - kEplSuccessful) - { - goto Exit; - } - - while ((pEplFrame != NULL) - && - (uiFrameSize - != 0)) { - // send frame - Ret = - EplSdoAsySeqSendLowerLayer - (pAsySdoSeqCon, - uiFrameSize, - pEplFrame); - if (Ret - != - kEplSuccessful) - { - goto Exit; - } - // read next frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, - &pEplFrame, - &uiFrameSize, - FALSE); - if (Ret - != - kEplSuccessful) - { - goto Exit; - } - } // end of while((pabFrame != NULL) - } // end of if (error response) - - if (((pAsySdoSeqCon->m_bSendSeqNum + 4) & EPL_SEQ_NUM_MASK) == (bSendSeqNumCon & EPL_SEQ_NUM_MASK)) { // next frame of sequence received - // save send sequence number (without ack request) - pAsySdoSeqCon-> - m_bSendSeqNum - = - bSendSeqNumCon - & ~0x01; - - // check if ack or data-frame - //ignore ack -> already processed - if (uiDataSize_p - > - EPL_SEQ_HEADER_SIZE) - { - AsySdoSequInstance_g. - m_fpSdoComReceiveCb - (SdoSeqConHdl, - ((tEplAsySdoCom *) & pRecFrame_p->m_le_abSdoSeqPayload), (uiDataSize_p - EPL_SEQ_HEADER_SIZE)); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateFrameSended); - - } else { - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateAckReceived); - } - } else if (((bSendSeqNumCon - pAsySdoSeqCon->m_bSendSeqNum - 4) & EPL_SEQ_NUM_MASK) < EPL_SEQ_NUM_THRESHOLD) { // frame of sequence was lost, - // because difference of received and old value - // is less then halve of the values range. - - // send error frame with own rcon = 3 - pAsySdoSeqCon-> - m_bSendSeqNum - |= 0x03; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, - 0, NULL, - FALSE); - // restore send sequence number - pAsySdoSeqCon-> - m_bSendSeqNum - = - (pAsySdoSeqCon-> - m_bSendSeqNum - & - EPL_SEQ_NUM_MASK) - | 0x02; - if (Ret != - kEplSuccessful) - { - goto Exit; - } - // break here, because a requested acknowledge - // was sent implicitly above - break; - } - // else, ignore repeated frame - - if ((bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 3) { // ack request received - - // create ack with own scon = 2 - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, - 0, NULL, - FALSE); - if (Ret != - kEplSuccessful) - { - goto Exit; - } - } - - break; - } - - } // switch(pAsySdoSeqCon->m_bSendSeqNum & EPL_ASY_SDO_CON_MASK) - break; - } // end of case kAsySdoSeqEventFrameRec: - - //close event from higher layer - case kAsySdoSeqEventCloseCon: - { - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - - // delete timer - EplTimeruDeleteTimer(&pAsySdoSeqCon-> - m_EplTimerHdl); - // call Command Layer Cb is not necessary, because the event came from there -// AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl, -// kAsySdoConStateInitError); - break; - } - - // timeout - case kAsySdoSeqEventTimeout: - { - - uiFreeEntries = - EplSdoAsyGetFreeEntriesFromHistory - (pAsySdoSeqCon); - if ((uiFreeEntries < - EPL_SDO_HISTORY_SIZE) - && (pAsySdoSeqCon->m_uiRetryCount < EPL_SEQ_RETRY_COUNT)) { // unacknowlegded frames in history - // and retry counter not exceeded - - // resend data with acknowledge request - - // increment retry counter - pAsySdoSeqCon->m_uiRetryCount++; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - // read first frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, &pEplFrame, - &uiFrameSize, TRUE); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if ((pEplFrame != NULL) - && (uiFrameSize != 0)) { - - // set ack request in scon - AmiSetByteToLe - (&pEplFrame->m_Data. - m_Asnd.m_Payload. - m_SdoSequenceFrame. - m_le_bSendSeqNumCon, - AmiGetByteFromLe - (&pEplFrame-> - m_Data.m_Asnd. - m_Payload. - m_SdoSequenceFrame. - m_le_bSendSeqNumCon) - | 0x03); - - // send frame - Ret = - EplSdoAsySeqSendLowerLayer - (pAsySdoSeqCon, - uiFrameSize, - pEplFrame); - if (Ret != - kEplSuccessful) { - goto Exit; - } - - } - } else { - // timeout, because of no traffic -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateTimeout); - } - - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // wait for Acknowledge (history buffer full) - case kEplAsySdoStateWaitAck: - { - PRINTF0("EplSdoAsySequ: StateWaitAck\n"); - - // set timer - Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - //TODO: retry of acknowledge - if (Event_p == kAsySdoSeqEventFrameRec) { - // check rcon - switch (pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) { - // close-frome other node - case 0: - { - // return to idle - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConClosed); - - break; - } - - // normal frame - case 2: - { - // should be ack - // -> change to state kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateAckReceived); - // send data to higher layer if needed - if (uiDataSize_p > - EPL_SEQ_HEADER_SIZE) { - AsySdoSequInstance_g. - m_fpSdoComReceiveCb - (SdoSeqConHdl, - ((tEplAsySdoCom *) - & pRecFrame_p-> - m_le_abSdoSeqPayload), - (uiDataSize_p - - EPL_SEQ_HEADER_SIZE)); - } - break; - } - - // Request Ack or Error Ack - case 3: - { - // -> change to state kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - - if (pRecFrame_p->m_le_bRecSeqNumCon == pAsySdoSeqCon->m_bRecSeqNum) { // ack request - // -> send ack - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - // create answer own rcon = 2 - pAsySdoSeqCon-> - m_bRecSeqNum--; - - // check if ack or data-frame - if (uiDataSize_p > - EPL_SEQ_HEADER_SIZE) - { - AsySdoSequInstance_g. - m_fpSdoComReceiveCb - (SdoSeqConHdl, - ((tEplAsySdoCom *) & pRecFrame_p->m_le_abSdoSeqPayload), (uiDataSize_p - EPL_SEQ_HEADER_SIZE)); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateFrameSended); - - } else { - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, - 0, NULL, - FALSE); - if (Ret != - kEplSuccessful) - { - goto Exit; - } - } - - } else { - // error ack - // resend frames from history - - // read frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, - &pEplFrame, - &uiFrameSize, - TRUE); - while ((pEplFrame != - NULL) - && (uiFrameSize - != 0)) { - // send frame - Ret = - EplSdoAsySeqSendLowerLayer - (pAsySdoSeqCon, - uiFrameSize, - pEplFrame); - if (Ret != - kEplSuccessful) - { - goto Exit; - } - // read next frame - - // read frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, - &pEplFrame, - &uiFrameSize, - FALSE); - } // end of while((pabFrame != NULL) - } - break; - } - } // end of switch(pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) - - } else if (Event_p == kAsySdoSeqEventTimeout) { // error -> Close - pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb(SdoSeqConHdl, - kAsySdoConStateTimeout); - } - - break; - } - - // unknown state - default: - { - EPL_DBGLVL_SDO_TRACE0 - ("Error: Unknown State in EplSdoAsySeqProcess\n"); - - } - } // end of switch(pAsySdoSeqCon->m_SdoState) - - Exit: - -#if defined(WIN32) || defined(_WIN32) - // leave critical section for process function - LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSection); -#endif - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqSendIntern -// -// Description: intern function to create and send a frame -// -> if uiDataSize_p == 0 create a frame with infos from -// pAsySdoSeqCon_p -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of the connection -// uiDataSize_p = size of data frame to process (can be 0) -// -> without size of sequence header and Asnd header!!! -// pData_p = pointer to frame to process (can be NULL) -// fFrameInHistory = if TRUE frame is saved to history else not -// -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned int uiDataSize_p, - tEplFrame * pData_p, - BOOL fFrameInHistory_p) -{ - tEplKernel Ret; - u8 abFrame[EPL_SEQ_FRAME_SIZE]; - tEplFrame *pEplFrame; - unsigned int uiFreeEntries; - - if (pData_p == NULL) { // set pointer to own frame - EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame)); - pEplFrame = (tEplFrame *) & abFrame[0]; - } else { // set pointer to frame from calling function - pEplFrame = pData_p; - } - - if (fFrameInHistory_p != FALSE) { - // check if only one free entry in history buffer - uiFreeEntries = - EplSdoAsyGetFreeEntriesFromHistory(pAsySdoSeqCon_p); - if (uiFreeEntries == 1) { // request an acknowledge in dataframe - // own scon = 3 - pAsySdoSeqCon_p->m_bRecSeqNum |= 0x03; - } - } - // fillin header informations - // set service id sdo - AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_le_bServiceId, 0x05); - AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame. - m_le_abReserved, 0x00); - // set receive sequence number and rcon - AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame. - m_le_bRecSeqNumCon, pAsySdoSeqCon_p->m_bSendSeqNum); - // set send sequence number and scon - AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame. - m_le_bSendSeqNumCon, pAsySdoSeqCon_p->m_bRecSeqNum); - - // add size - uiDataSize_p += EPL_SEQ_HEADER_SIZE; - - // forward frame to appropriate lower layer - Ret = EplSdoAsySeqSendLowerLayer(pAsySdoSeqCon_p, uiDataSize_p, pEplFrame); // pointer to frame - - // check if all allright - if ((Ret == kEplSuccessful) - && (fFrameInHistory_p != FALSE)) { - // set own scon to 2 if needed - if ((pAsySdoSeqCon_p->m_bRecSeqNum & 0x03) == 0x03) { - pAsySdoSeqCon_p->m_bRecSeqNum--; - } - // save frame to history - Ret = EplSdoAsyAddFrameToHistory(pAsySdoSeqCon_p, - pEplFrame, uiDataSize_p); - if (Ret == kEplSdoSeqNoFreeHistory) { // request Ack needed - Ret = kEplSdoSeqRequestAckNeeded; - } - - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqSendLowerLayer -// -// Description: intern function to send a previously created frame to lower layer -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of the connection -// uiDataSize_p = size of data frame to process (can be 0) -// -> without size of Asnd header!!! -// pData_p = pointer to frame to process (can be NULL) -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned int uiDataSize_p, - tEplFrame * pEplFrame_p) -{ - tEplKernel Ret; - - // call send-function - // check handle for UDP or Asnd - if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_UDP_HANDLE) { // send over UDP -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - Ret = EplSdoUdpuSendData(pAsySdoSeqCon_p->m_ConHandle, pEplFrame_p, // pointer to frame - uiDataSize_p); -#else - Ret = kEplSdoSeqUnsupportedProt; -#endif - - } else if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_ASND_HANDLE) { // ASND -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - Ret = EplSdoAsnduSendData(pAsySdoSeqCon_p->m_ConHandle, pEplFrame_p, // pointer to frame - uiDataSize_p); -#else - Ret = kEplSdoSeqUnsupportedProt; -#endif - } else { // error - Ret = kEplSdoSeqInvalidHdl; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyReceiveCb -// -// Description: callback-function for received frames from lower layer -// -// -// -// Parameters: ConHdl_p = handle of the connection -// pSdoSeqData_p = pointer to frame -// uiDataSize_p = size of frame -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p, - tEplAsySdoSeq *pSdoSeqData_p, - unsigned int uiDataSize_p) -{ - tEplKernel Ret; - unsigned int uiCount = 0; - unsigned int uiFreeEntry = EPL_MAX_SDO_SEQ_CON; - tEplAsySdoSeqCon *pAsySdoSeqCon; - -#if defined(WIN32) || defined(_WIN32) - // enter critical section - EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive); -#endif - - EPL_DBGLVL_SDO_TRACE2("Handle: 0x%x , First Databyte 0x%x\n", ConHdl_p, - ((u8 *) pSdoSeqData_p)[0]); - - // search controll structure for this connection - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiCount]; - while (uiCount < EPL_MAX_SDO_SEQ_CON) { - if (pAsySdoSeqCon->m_ConHandle == ConHdl_p) { - break; - } else if ((pAsySdoSeqCon->m_ConHandle == 0) - && (uiFreeEntry == EPL_MAX_SDO_SEQ_CON)) { - // free entry - uiFreeEntry = uiCount; - } - uiCount++; - pAsySdoSeqCon++; - } - - if (uiCount == EPL_MAX_SDO_SEQ_CON) { // new connection - if (uiFreeEntry == EPL_MAX_SDO_SEQ_CON) { - Ret = kEplSdoSeqNoFreeHandle; - goto Exit; - } else { - pAsySdoSeqCon = - &AsySdoSequInstance_g. - m_AsySdoConnection[uiFreeEntry]; - // save handle from lower layer - pAsySdoSeqCon->m_ConHandle = ConHdl_p; - // increment use counter - pAsySdoSeqCon->m_uiUseCount++; - uiCount = uiFreeEntry; - } - } - // call history ack function - Ret = EplSdoAsyAckFrameToHistory(pAsySdoSeqCon, - (AmiGetByteFromLe - (&pSdoSeqData_p-> - m_le_bRecSeqNumCon) & - EPL_SEQ_NUM_MASK)); - if (Ret != kEplSuccessful) { - goto Exit; - } -#if defined(WIN32) || defined(_WIN32) - // leave critical section - LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive); -#endif - - // call process function with pointer of frame and event kAsySdoSeqEventFrameRec - Ret = EplSdoAsySeqProcess(uiCount, - uiDataSize_p, - NULL, pSdoSeqData_p, kAsySdoSeqEventFrameRec); - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyInitHistory -// -// Description: inti function for history buffer -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsyInitHistory(void) -{ - tEplKernel Ret; - unsigned int uiCount; - - Ret = kEplSuccessful; - // init m_bFreeEntries in history-buffer - for (uiCount = 0; uiCount < EPL_MAX_SDO_SEQ_CON; uiCount++) { - AsySdoSequInstance_g.m_AsySdoConnection[uiCount]. - m_SdoConHistory.m_bFreeEntries = EPL_SDO_HISTORY_SIZE; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyAddFrameToHistory -// -// Description: function to add a frame to the history buffer -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// pFrame_p = pointer to frame -// uiSize_p = size of the frame -// -> without size of the ethernet header -// and the asnd header -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - tEplFrame * pFrame_p, - unsigned int uiSize_p) -{ - tEplKernel Ret; - tEplAsySdoConHistory *pHistory; - - Ret = kEplSuccessful; - - // add frame to history buffer - - // check size - // $$$ d.k. EPL_SEQ_HISTORY_FRAME_SIZE includes the header size, but uiSize_p does not!!! - if (uiSize_p > EPL_SEQ_HISTROY_FRAME_SIZE) { - Ret = kEplSdoSeqFrameSizeError; - goto Exit; - } - // save pointer to history - pHistory = &pAsySdoSeqCon_p->m_SdoConHistory; - - // check if a free entry is available - if (pHistory->m_bFreeEntries > 0) { // write message in free entry - EPL_MEMCPY(& - ((tEplFrame *) pHistory-> - m_aabHistoryFrame[pHistory->m_bWrite])-> - m_le_bMessageType, &pFrame_p->m_le_bMessageType, - uiSize_p + EPL_ASND_HEADER_SIZE); - // store size - pHistory->m_auiFrameSize[pHistory->m_bWrite] = uiSize_p; - - // decremend number of free bufferentries - pHistory->m_bFreeEntries--; - - // increment writeindex - pHistory->m_bWrite++; - - // check if write-index run over array-boarder - if (pHistory->m_bWrite == EPL_SDO_HISTORY_SIZE) { - pHistory->m_bWrite = 0; - } - - } else { // no free entry - Ret = kEplSdoSeqNoFreeHistory; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyAckFrameToHistory -// -// Description: function to delete acknowledged frames fron history buffer -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// bRecSeqNumber_p = receive sequence number of the received frame -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - u8 bRecSeqNumber_p) -{ - tEplKernel Ret; - tEplAsySdoConHistory *pHistory; - u8 bAckIndex; - u8 bCurrentSeqNum; - - Ret = kEplSuccessful; - - // get pointer to history buffer - pHistory = &pAsySdoSeqCon_p->m_SdoConHistory; - - // release all acknowledged frames from history buffer - - // check if there are entries in history - if (pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE) { - bAckIndex = pHistory->m_bAck; - do { - bCurrentSeqNum = - (((tEplFrame *) pHistory-> - m_aabHistoryFrame[bAckIndex])->m_Data.m_Asnd. - m_Payload.m_SdoSequenceFrame. - m_le_bSendSeqNumCon & EPL_SEQ_NUM_MASK); - if (((bRecSeqNumber_p - - bCurrentSeqNum) & EPL_SEQ_NUM_MASK) - < EPL_SEQ_NUM_THRESHOLD) { - pHistory->m_auiFrameSize[bAckIndex] = 0; - bAckIndex++; - pHistory->m_bFreeEntries++; - if (bAckIndex == EPL_SDO_HISTORY_SIZE) { // read index run over array-boarder - bAckIndex = 0; - } - } else { // nothing to do anymore, - // because any further frame in history has larger sequence - // number than the acknowledge - goto Exit; - } - } - while ((((bRecSeqNumber_p - 1 - - bCurrentSeqNum) & EPL_SEQ_NUM_MASK) - < EPL_SEQ_NUM_THRESHOLD) - && (pHistory->m_bWrite != bAckIndex)); - - // store local read-index to global var - pHistory->m_bAck = bAckIndex; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyReadFromHistory -// -// Description: function to one frame from history -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// ppFrame_p = pointer to pointer to the buffer of the stored frame -// puiSize_p = OUT: size of the frame -// fInitRead = bool which indicate a start of retransmission -// -> return last not acknowledged message if TRUE -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - tEplFrame ** ppFrame_p, - unsigned int *puiSize_p, - BOOL fInitRead_p) -{ - tEplKernel Ret; - tEplAsySdoConHistory *pHistory; - - Ret = kEplSuccessful; - - // read one message from History - - // get pointer to history buffer - pHistory = &pAsySdoSeqCon_p->m_SdoConHistory; - - // check if init - if (fInitRead_p != FALSE) { // initialize read index to the index which shall be acknowledged next - pHistory->m_bRead = pHistory->m_bAck; - } - // check if entries are available for reading - if ((pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE) - && (pHistory->m_bWrite != pHistory->m_bRead)) { -// PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (u16)pHistory->m_bRead, (u16)pHistory->m_bWrite, (u16)pHistory->m_bAck); -// PRINTF2(", free entries = %u, next frame size = %u\n", (u16)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]); - - // return pointer to stored frame - *ppFrame_p = - (tEplFrame *) pHistory->m_aabHistoryFrame[pHistory-> - m_bRead]; - - // save size - *puiSize_p = pHistory->m_auiFrameSize[pHistory->m_bRead]; - - pHistory->m_bRead++; - if (pHistory->m_bRead == EPL_SDO_HISTORY_SIZE) { - pHistory->m_bRead = 0; - } - - } else { -// PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (u16)pHistory->m_bRead, (u16)pHistory->m_bAck, (u16)pHistory->m_bFreeEntries); - - // no more frames to send - // return null pointer - *ppFrame_p = NULL; - - *puiSize_p = 0; - } - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyGetFreeEntriesFromHistory -// -// Description: function returns the number of free histroy entries -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// -// -// Returns: unsigned int = number of free entries -// -// -// State: -// -//--------------------------------------------------------------------------- -static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon * - pAsySdoSeqCon_p) -{ - unsigned int uiFreeEntries; - - uiFreeEntries = - (unsigned int)pAsySdoSeqCon_p->m_SdoConHistory.m_bFreeEntries; - - return uiFreeEntries; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqSetTimer -// -// Description: function sets or modify timer in timermosule -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// ulTimeout = timeout in ms -// -// -// Returns: unsigned int = number of free entries -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned long ulTimeout) -{ - tEplKernel Ret; - tEplTimerArg TimerArg; - - TimerArg.m_EventSink = kEplEventSinkSdoAsySeq; - TimerArg.m_ulArg = (unsigned long)pAsySdoSeqCon_p; - - if (pAsySdoSeqCon_p->m_EplTimerHdl == 0) { // create new timer - Ret = EplTimeruSetTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl, - ulTimeout, TimerArg); - } else { // modify exisiting timer - Ret = EplTimeruModifyTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl, - ulTimeout, TimerArg); - - } - - return Ret; -} - -// EOF |