1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for SDO Command Layer module
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
50 -------------------------------------------------------------------------
52 $RCSfile: EplSdoComu.c,v $
56 $Revision: 1.14 $ $Date: 2008/10/17 15:32:32 $
63 -------------------------------------------------------------------------
67 2006/06/26 k.t.: start of the implementation
69 ****************************************************************************/
71 #include "user/EplSdoComu.h"
73 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) == 0) &&\
74 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) == 0) )
76 #error 'ERROR: At least SDO Server or SDO Client should be activate!'
80 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
81 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
83 #error 'ERROR: SDO Server needs OBDu module!'
89 /***************************************************************************/
92 /* G L O B A L D E F I N I T I O N S */
95 /***************************************************************************/
97 //---------------------------------------------------------------------------
99 //---------------------------------------------------------------------------
101 #ifndef EPL_MAX_SDO_COM_CON
102 #define EPL_MAX_SDO_COM_CON 5
106 //---------------------------------------------------------------------------
108 //---------------------------------------------------------------------------
113 kEplSdoComConEventSendFirst = 0x00, // first frame to send
114 kEplSdoComConEventRec = 0x01, // frame received
115 kEplSdoComConEventConEstablished= 0x02, // connection established
116 kEplSdoComConEventConClosed = 0x03, // connection closed
117 kEplSdoComConEventAckReceived = 0x04, // acknowledge received by lower layer
118 // -> continue sending
119 kEplSdoComConEventFrameSended = 0x05, // lower has send a frame
120 kEplSdoComConEventInitError = 0x06, // error duringinitialisiation
122 kEplSdoComConEventTimeout = 0x07 // timeout in lower layer
123 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
127 kEplSdoComConEventInitCon = 0x08, // init connection (only client)
128 kEplSdoComConEventAbort = 0x09 // abort sdo transfer (only client)
136 kEplSdoComSendTypeReq = 0x00, // send a request
137 kEplSdoComSendTypeAckRes = 0x01, // send a resonse without data
138 kEplSdoComSendTypeRes = 0x02, // send response with data
139 kEplSdoComSendTypeAbort = 0x03 // send abort
143 // state of the state maschine
147 kEplSdoComStateIdle = 0x00, // idle state
149 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
151 kEplSdoComStateServerSegmTrans = 0x01, // send following frames
155 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
157 kEplSdoComStateClientWaitInit = 0x10, // wait for init connection
159 kEplSdoComStateClientConnected = 0x11, // connection established
160 kEplSdoComStateClientSegmTrans = 0x12 // send following frames
168 // control structure for transaction
171 tEplSdoSeqConHdl m_SdoSeqConHdl; // if != 0 -> entry used
172 tEplSdoComState m_SdoComState;
173 BYTE m_bTransactionId;
174 unsigned int m_uiNodeId; // NodeId of the target
175 // -> needed to reinit connection
177 tEplSdoTransType m_SdoTransType; // Auto, Expedited, Segmented
178 tEplSdoServiceType m_SdoServiceType; // WriteByIndex, ReadByIndex
179 tEplSdoType m_SdoProtType; // protocol layer: Auto, Udp, Asnd, Pdo
180 BYTE* m_pData; // pointer to data
181 unsigned int m_uiTransSize; // number of bytes
183 unsigned int m_uiTransferredByte;// number of bytes
184 // already transferred
185 tEplSdoFinishedCb m_pfnTransferFinished;// callback function of the
187 // -> called in the end of
189 void* m_pUserArg; // user definable argument pointer
191 DWORD m_dwLastAbortCode; // save the last abort code
192 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
194 unsigned int m_uiTargetIndex; // index to access
195 unsigned int m_uiTargetSubIndex; // subiondex to access
198 unsigned int m_uiTimeout; // timeout for this connection
207 tEplSdoComCon m_SdoComCon[EPL_MAX_SDO_COM_CON];
209 #if defined(WIN32) || defined(_WIN32)
210 LPCRITICAL_SECTION m_pCriticalSection;
211 CRITICAL_SECTION m_CriticalSection;
216 //---------------------------------------------------------------------------
217 // modul globale vars
218 //---------------------------------------------------------------------------
219 static tEplSdoComInstance SdoComInstance_g;
220 //---------------------------------------------------------------------------
221 // local function prototypes
222 //---------------------------------------------------------------------------
223 tEplKernel PUBLIC EplSdoComReceiveCb (tEplSdoSeqConHdl SdoSeqConHdl_p,
224 tEplAsySdoCom* pAsySdoCom_p,
225 unsigned int uiDataSize_p);
228 tEplKernel PUBLIC EplSdoComConCb (tEplSdoSeqConHdl SdoSeqConHdl_p,
229 tEplAsySdoConState AsySdoConState_p);
231 static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
232 tEplSdoComConEvent SdoComConEvent_p,
233 tEplAsySdoCom* pAsySdoCom_p);
235 static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
236 tEplSdoComConEvent SdoComConEvent_p,
237 tEplAsySdoCom* pAsySdoCom_p);
239 static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p,
240 tEplSdoComCon* pSdoComCon_p,
241 tEplSdoComConState SdoComConState_p);
243 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
244 static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon* pSdoComCon_p,
245 tEplAsySdoCom* pAsySdoCom_p);
247 static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon* pSdoComCon_p,
248 unsigned int uiIndex_p,
249 unsigned int uiSubIndex_p,
250 tEplSdoComSendType SendType_p);
252 static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon* pSdoComCon_p,
253 tEplAsySdoCom* pAsySdoCom_p);
257 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
259 static tEplKernel EplSdoComClientSend(tEplSdoComCon* pSdoComCon_p);
261 static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
262 tEplAsySdoCom* pAsySdoCom_p);
264 static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon* pSdoComCon_p,
265 DWORD dwAbortCode_p);
270 /***************************************************************************/
273 /* C L A S S <SDO Command Layer> */
276 /***************************************************************************/
278 // Description: SDO Command layer Modul
281 /***************************************************************************/
283 //=========================================================================//
285 // P U B L I C F U N C T I O N S //
287 //=========================================================================//
289 //---------------------------------------------------------------------------
291 // Function: EplSdoComInit
293 // Description: Init first instance of the module
300 // Returns: tEplKernel = errorcode
305 //---------------------------------------------------------------------------
306 tEplKernel PUBLIC EplSdoComInit(void)
311 Ret = EplSdoComAddInstance();
317 //---------------------------------------------------------------------------
319 // Function: EplSdoComAddInstance
321 // Description: Init additional instance of the module
328 // Returns: tEplKernel = errorcode
333 //---------------------------------------------------------------------------
334 tEplKernel PUBLIC EplSdoComAddInstance(void)
338 Ret = kEplSuccessful;
340 // init controll structure
341 EPL_MEMSET(&SdoComInstance_g, 0x00, sizeof(SdoComInstance_g));
343 // init instance of lower layer
344 Ret = EplSdoAsySeqAddInstance(EplSdoComReceiveCb, EplSdoComConCb);
345 if(Ret != kEplSuccessful)
350 #if defined(WIN32) || defined(_WIN32)
351 // create critical section for process function
352 SdoComInstance_g.m_pCriticalSection = &SdoComInstance_g.m_CriticalSection;
353 InitializeCriticalSection(SdoComInstance_g.m_pCriticalSection);
360 //---------------------------------------------------------------------------
362 // Function: EplSdoComDelInstance
364 // Description: delete instance of the module
371 // Returns: tEplKernel = errorcode
376 //---------------------------------------------------------------------------
377 tEplKernel PUBLIC EplSdoComDelInstance(void)
381 Ret = kEplSuccessful;
384 #if defined(WIN32) || defined(_WIN32)
385 // delete critical section for process function
386 DeleteCriticalSection(SdoComInstance_g.m_pCriticalSection);
389 Ret = EplSdoAsySeqDelInstance();
390 if(Ret != kEplSuccessful)
400 //---------------------------------------------------------------------------
402 // Function: EplSdoComDefineCon
404 // Description: function defines a SDO connection to another node
405 // -> init lower layer and returns a handle for the connection.
406 // Two client connections to the same node via the same protocol
407 // are not allowed. If this function detects such a situation
408 // it will return kEplSdoComHandleExists and the handle of
409 // the existing connection in pSdoComConHdl_p.
410 // Using of existing server connections is possible.
412 // Parameters: pSdoComConHdl_p = pointer to the buffer of the handle
413 // uiTargetNodeId_p = NodeId of the targetnode
414 // ProtType_p = type of protocol to use for connection
417 // Returns: tEplKernel = errorcode
422 //---------------------------------------------------------------------------
423 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
424 tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl* pSdoComConHdl_p,
425 unsigned int uiTargetNodeId_p,
426 tEplSdoType ProtType_p)
429 unsigned int uiCount;
430 unsigned int uiFreeHdl;
431 tEplSdoComCon* pSdoComCon;
434 ASSERT(pSdoComConHdl_p != NULL);
437 if((uiTargetNodeId_p == EPL_C_ADR_INVALID)
438 ||(uiTargetNodeId_p >= EPL_C_ADR_BROADCAST))
440 Ret = kEplInvalidNodeId;
444 // search free control structure
445 pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
447 uiFreeHdl = EPL_MAX_SDO_COM_CON;
448 while (uiCount < EPL_MAX_SDO_COM_CON)
450 if (pSdoComCon->m_SdoSeqConHdl == 0)
454 else if ((pSdoComCon->m_uiNodeId == uiTargetNodeId_p)
455 && (pSdoComCon->m_SdoProtType == ProtType_p))
456 { // existing client connection with same node ID and same protocol type
457 *pSdoComConHdl_p = uiCount;
458 Ret = kEplSdoComHandleExists;
465 if (uiFreeHdl == EPL_MAX_SDO_COM_CON)
467 Ret = kEplSdoComNoFreeHandle;
471 pSdoComCon = &SdoComInstance_g.m_SdoComCon[uiFreeHdl];
472 // save handle for application
473 *pSdoComConHdl_p = uiFreeHdl;
475 pSdoComCon->m_SdoProtType = ProtType_p;
476 pSdoComCon->m_uiNodeId = uiTargetNodeId_p;
478 // set Transaction Id
479 pSdoComCon->m_bTransactionId = 0;
487 // call connection int function of lower layer
488 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
489 pSdoComCon->m_uiNodeId,
491 if(Ret != kEplSuccessful)
499 case kEplSdoTypeAsnd:
501 // call connection int function of lower layer
502 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
503 pSdoComCon->m_uiNodeId,
505 if(Ret != kEplSuccessful)
512 // Pdo -> not supported
516 Ret = kEplSdoComUnsupportedProt;
519 }// end of switch(m_ProtType_p)
521 // call process function
522 Ret = EplSdoComProcessIntern(uiFreeHdl,
523 kEplSdoComConEventInitCon,
530 //---------------------------------------------------------------------------
532 // Function: EplSdoComInitTransferByIndex
534 // Description: function init SDO Transfer for a defined connection
538 // Parameters: SdoComTransParam_p = Structure with parameters for connection
541 // Returns: tEplKernel = errorcode
546 //---------------------------------------------------------------------------
547 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
548 tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex* pSdoComTransParam_p)
551 tEplSdoComCon* pSdoComCon;
554 if ((pSdoComTransParam_p->m_uiSubindex >= 0xFF)
555 || (pSdoComTransParam_p->m_uiIndex == 0)
556 || (pSdoComTransParam_p->m_uiIndex > 0xFFFF)
557 || (pSdoComTransParam_p->m_pData == NULL)
558 || (pSdoComTransParam_p->m_uiDataSize == 0))
560 Ret = kEplSdoComInvalidParam;
564 if(pSdoComTransParam_p->m_SdoComConHdl >= EPL_MAX_SDO_COM_CON)
566 Ret = kEplSdoComInvalidHandle;
570 // get pointer to control structure of connection
571 pSdoComCon = &SdoComInstance_g.m_SdoComCon[pSdoComTransParam_p->m_SdoComConHdl];
573 // check if handle ok
574 if(pSdoComCon->m_SdoSeqConHdl == 0)
576 Ret = kEplSdoComInvalidHandle;
580 // check if command layer is idle
581 if ((pSdoComCon->m_uiTransferredByte + pSdoComCon->m_uiTransSize) > 0)
582 { // handle is not idle
583 Ret = kEplSdoComHandleBusy;
588 // callback function for end of transfer
589 pSdoComCon->m_pfnTransferFinished = pSdoComTransParam_p->m_pfnSdoFinishedCb;
590 pSdoComCon->m_pUserArg = pSdoComTransParam_p->m_pUserArg;
592 // set type of SDO command
593 if (pSdoComTransParam_p->m_SdoAccessType == kEplSdoAccessTypeRead)
595 pSdoComCon->m_SdoServiceType = kEplSdoServiceReadByIndex;
599 pSdoComCon->m_SdoServiceType = kEplSdoServiceWriteByIndex;
602 // save pointer to data
603 pSdoComCon->m_pData = pSdoComTransParam_p->m_pData;
604 // maximal bytes to transfer
605 pSdoComCon->m_uiTransSize = pSdoComTransParam_p->m_uiDataSize;
606 // bytes already transfered
607 pSdoComCon->m_uiTransferredByte = 0;
609 // reset parts of control structure
610 pSdoComCon->m_dwLastAbortCode = 0;
611 pSdoComCon->m_SdoTransType = kEplSdoTransAuto;
613 //pSdoComCon->m_uiTimeout = SdoComTransParam_p.m_uiTimeout;
615 // save index and subindex
616 pSdoComCon->m_uiTargetIndex = pSdoComTransParam_p->m_uiIndex;
617 pSdoComCon->m_uiTargetSubIndex = pSdoComTransParam_p->m_uiSubindex;
619 // call process function
620 Ret = EplSdoComProcessIntern(pSdoComTransParam_p->m_SdoComConHdl,
621 kEplSdoComConEventSendFirst, // event to start transfer
630 //---------------------------------------------------------------------------
632 // Function: EplSdoComUndefineCon
634 // Description: function undefine a SDO connection
638 // Parameters: SdoComConHdl_p = handle for the connection
641 // Returns: tEplKernel = errorcode
646 //---------------------------------------------------------------------------
647 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
648 tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
651 tEplSdoComCon* pSdoComCon;
653 Ret = kEplSuccessful;
655 if(SdoComConHdl_p >= EPL_MAX_SDO_COM_CON)
657 Ret = kEplSdoComInvalidHandle;
661 // get pointer to control structure
662 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
664 // $$$ d.k. abort a running transfer before closing the sequence layer
666 if(((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) != EPL_SDO_SEQ_INVALID_HDL)
667 && (pSdoComCon->m_SdoSeqConHdl != 0))
669 // close connection in lower layer
670 switch(pSdoComCon->m_SdoProtType)
672 case kEplSdoTypeAsnd:
675 Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
680 case kEplSdoTypeAuto:
683 Ret = kEplSdoComUnsupportedProt;
687 }// end of switch(pSdoComCon->m_SdoProtType)
691 // clean controll structure
692 EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
697 //---------------------------------------------------------------------------
699 // Function: EplSdoComGetState
701 // Description: function returns the state fo the connection
705 // Parameters: SdoComConHdl_p = handle for the connection
706 // pSdoComFinished_p = pointer to structur for sdo state
709 // Returns: tEplKernel = errorcode
714 //---------------------------------------------------------------------------
715 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
716 tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
717 tEplSdoComFinished* pSdoComFinished_p)
720 tEplSdoComCon* pSdoComCon;
722 Ret = kEplSuccessful;
724 if(SdoComConHdl_p >= EPL_MAX_SDO_COM_CON)
726 Ret = kEplSdoComInvalidHandle;
730 // get pointer to control structure
731 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
733 // check if handle ok
734 if(pSdoComCon->m_SdoSeqConHdl == 0)
736 Ret = kEplSdoComInvalidHandle;
740 pSdoComFinished_p->m_pUserArg = pSdoComCon->m_pUserArg;
741 pSdoComFinished_p->m_uiNodeId = pSdoComCon->m_uiNodeId;
742 pSdoComFinished_p->m_uiTargetIndex = pSdoComCon->m_uiTargetIndex;
743 pSdoComFinished_p->m_uiTargetSubIndex = pSdoComCon->m_uiTargetSubIndex;
744 pSdoComFinished_p->m_uiTransferredByte = pSdoComCon->m_uiTransferredByte;
745 pSdoComFinished_p->m_dwAbortCode = pSdoComCon->m_dwLastAbortCode;
746 pSdoComFinished_p->m_SdoComConHdl = SdoComConHdl_p;
747 if (pSdoComCon->m_SdoServiceType == kEplSdoServiceWriteByIndex)
749 pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeWrite;
753 pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeRead;
756 if(pSdoComCon->m_dwLastAbortCode != 0)
758 pSdoComFinished_p->m_SdoComConState = kEplSdoComTransferRxAborted;
761 pSdoComCon->m_dwLastAbortCode = 0;
764 else if((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK)== EPL_SDO_SEQ_INVALID_HDL)
766 pSdoComFinished_p->m_SdoComConState = kEplSdoComTransferLowerLayerAbort;
768 else if(pSdoComCon->m_SdoComState == kEplSdoComStateClientWaitInit)
771 pSdoComFinished_p->m_SdoComConState = kEplSdoComTransferNotActive;
773 else if(pSdoComCon->m_uiTransSize == 0)
775 pSdoComFinished_p->m_SdoComConState = kEplSdoComTransferFinished;
783 //---------------------------------------------------------------------------
785 // Function: EplSdoComSdoAbort
787 // Description: function abort a sdo transfer
791 // Parameters: SdoComConHdl_p = handle for the connection
792 // dwAbortCode_p = abort code
795 // Returns: tEplKernel = errorcode
800 //---------------------------------------------------------------------------
801 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
802 tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
806 tEplSdoComCon* pSdoComCon;
809 if(SdoComConHdl_p >= EPL_MAX_SDO_COM_CON)
811 Ret = kEplSdoComInvalidHandle;
815 // get pointer to control structure of connection
816 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
818 // check if handle ok
819 if(pSdoComCon->m_SdoSeqConHdl == 0)
821 Ret = kEplSdoComInvalidHandle;
825 // save pointer to abort code
826 pSdoComCon->m_pData = (BYTE*)&dwAbortCode_p;
828 Ret = EplSdoComProcessIntern(SdoComConHdl_p,
829 kEplSdoComConEventAbort,
830 (tEplAsySdoCom*)NULL);
837 //=========================================================================//
839 // P R I V A T E F U N C T I O N S //
841 //=========================================================================//
843 //---------------------------------------------------------------------------
845 // Function: EplSdoComReceiveCb
847 // Description: callback function for SDO Sequence Layer
848 // -> indicates new data
852 // Parameters: SdoSeqConHdl_p = Handle for connection
853 // pAsySdoCom_p = pointer to data
854 // uiDataSize_p = size of data ($$$ not used yet, but it should)
862 //---------------------------------------------------------------------------
863 tEplKernel PUBLIC EplSdoComReceiveCb (tEplSdoSeqConHdl SdoSeqConHdl_p,
864 tEplAsySdoCom* pAsySdoCom_p,
865 unsigned int uiDataSize_p)
870 // search connection internally
871 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
872 kEplSdoComConEventRec,
875 EPL_DBGLVL_SDO_TRACE3("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n", SdoSeqConHdl_p, (WORD)pAsySdoCom_p->m_le_abCommandData[0], uiDataSize_p);
880 //---------------------------------------------------------------------------
882 // Function: EplSdoComConCb
884 // Description: callback function called by SDO Sequence Layer to inform
885 // command layer about state change of connection
889 // Parameters: SdoSeqConHdl_p = Handle of the connection
890 // AsySdoConState_p = Event of the connection
893 // Returns: tEplKernel = Errorcode
898 //---------------------------------------------------------------------------
899 tEplKernel PUBLIC EplSdoComConCb (tEplSdoSeqConHdl SdoSeqConHdl_p,
900 tEplAsySdoConState AsySdoConState_p)
903 tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst;
905 Ret = kEplSuccessful;
908 switch(AsySdoConState_p)
910 case kAsySdoConStateConnected:
912 EPL_DBGLVL_SDO_TRACE0("Connection established\n");
913 SdoComConEvent = kEplSdoComConEventConEstablished;
914 // start transmission if needed
918 case kAsySdoConStateInitError:
920 EPL_DBGLVL_SDO_TRACE0("Error during initialisation\n");
921 SdoComConEvent = kEplSdoComConEventInitError;
922 // inform app about error and close sequence layer handle
926 case kAsySdoConStateConClosed:
928 EPL_DBGLVL_SDO_TRACE0("Connection closed\n");
929 SdoComConEvent = kEplSdoComConEventConClosed;
930 // close sequence layer handle
934 case kAsySdoConStateAckReceived:
936 EPL_DBGLVL_SDO_TRACE0("Acknowlage received\n");
937 SdoComConEvent = kEplSdoComConEventAckReceived;
938 // continue transmission
942 case kAsySdoConStateFrameSended:
944 EPL_DBGLVL_SDO_TRACE0("One Frame sent\n");
945 SdoComConEvent = kEplSdoComConEventFrameSended;
946 // to continue transmission
951 case kAsySdoConStateTimeout:
953 EPL_DBGLVL_SDO_TRACE0("Timeout\n");
954 SdoComConEvent = kEplSdoComConEventTimeout;
955 // close sequence layer handle
959 }// end of switch(AsySdoConState_p)
961 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
963 (tEplAsySdoCom*)NULL);
968 //---------------------------------------------------------------------------
970 // Function: EplSdoComSearchConIntern
972 // Description: search a Sdo Sequence Layer connection handle in the
973 // control structure of the Command Layer
975 // Parameters: SdoSeqConHdl_p = Handle to search
976 // SdoComConEvent_p = event to process
977 // pAsySdoCom_p = pointer to received frame
979 // Returns: tEplKernel
984 //---------------------------------------------------------------------------
985 static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
986 tEplSdoComConEvent SdoComConEvent_p,
987 tEplAsySdoCom* pAsySdoCom_p)
990 tEplSdoComCon* pSdoComCon;
991 tEplSdoComConHdl HdlCount;
992 tEplSdoComConHdl HdlFree;
994 Ret = kEplSdoComNotResponsible;
996 // get pointer to first element of the array
997 pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
1000 while (HdlCount < EPL_MAX_SDO_COM_CON)
1002 if (pSdoComCon->m_SdoSeqConHdl == SdoSeqConHdl_p)
1003 { // matching command layer handle found
1004 Ret = EplSdoComProcessIntern(HdlCount,
1008 else if ((pSdoComCon->m_SdoSeqConHdl == 0)
1009 &&(HdlFree == 0xFFFF))
1018 if (Ret == kEplSdoComNotResponsible)
1019 { // no responsible command layer handle found
1020 if (HdlFree == 0xFFFF)
1022 // delete connection immediately
1023 // 2008/04/14 m.u./d.k. This connection actually does not exist.
1024 // pSdoComCon is invalid.
1025 // Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
1026 Ret = kEplSdoComNoFreeHandle;
1029 { // create new handle
1031 pSdoComCon = &SdoComInstance_g.m_SdoComCon[HdlCount];
1032 pSdoComCon->m_SdoSeqConHdl = SdoSeqConHdl_p;
1033 Ret = EplSdoComProcessIntern(HdlCount,
1043 //---------------------------------------------------------------------------
1045 // Function: EplSdoComProcessIntern
1047 // Description: search a Sdo Sequence Layer connection handle in the
1048 // control structer of the Command Layer
1052 // Parameters: SdoComCon_p = index of control structure of connection
1053 // SdoComConEvent_p = event to process
1054 // pAsySdoCom_p = pointer to received frame
1056 // Returns: tEplKernel = errorcode
1061 //---------------------------------------------------------------------------
1062 static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
1063 tEplSdoComConEvent SdoComConEvent_p,
1064 tEplAsySdoCom* pAsySdoCom_p)
1067 tEplSdoComCon* pSdoComCon;
1070 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1072 unsigned int uiSize;
1075 #if defined(WIN32) || defined(_WIN32)
1076 // enter critical section for process function
1077 EnterCriticalSection(SdoComInstance_g.m_pCriticalSection);
1078 EPL_DBGLVL_SDO_TRACE0("\n\tEnterCiticalSection EplSdoComProcessIntern\n\n");
1081 Ret = kEplSuccessful;
1083 // get pointer to control structure
1084 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
1086 // process state maschine
1087 switch(pSdoComCon->m_SdoComState)
1090 case kEplSdoComStateIdle:
1093 switch(SdoComConEvent_p)
1095 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1096 // init con for client
1097 case kEplSdoComConEventInitCon:
1100 // call of the init function already
1101 // processed in EplSdoComDefineCon()
1102 // only change state to kEplSdoComStateClientWaitInit
1103 pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
1109 // int con for server
1110 case kEplSdoComConEventRec:
1112 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1113 // check if init of an transfer and no SDO abort
1114 if ((pAsySdoCom_p->m_le_bFlags & 0x80) == 0)
1116 if ((pAsySdoCom_p->m_le_bFlags & 0x40) == 0)
1118 // save tansaction id
1119 pSdoComCon->m_bTransactionId = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId);
1121 switch(pAsySdoCom_p->m_le_bCommandId)
1123 case kEplSdoServiceNIL:
1124 { // simply acknowlegde NIL command on sequence layer
1126 Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
1133 case kEplSdoServiceReadByIndex:
1136 // search entry an start transfer
1137 EplSdoComServerInitReadByIndex(pSdoComCon,
1140 if(pSdoComCon->m_uiTransSize == 0)
1141 { // ready -> stay idle
1142 pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
1144 pSdoComCon->m_dwLastAbortCode = 0;
1147 { // segmented transfer
1148 pSdoComCon->m_SdoComState = kEplSdoComStateServerSegmTrans;
1154 case kEplSdoServiceWriteByIndex:
1157 // search entry an start write
1158 EplSdoComServerInitWriteByIndex(pSdoComCon,
1161 if(pSdoComCon->m_uiTransSize == 0)
1162 { // already -> stay idle
1163 pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
1165 pSdoComCon->m_dwLastAbortCode = 0;
1168 { // segmented transfer
1169 pSdoComCon->m_SdoComState = kEplSdoComStateServerSegmTrans;
1177 // unsupported command
1179 dwAbortCode = EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER;
1181 pSdoComCon->m_pData = (BYTE*)&dwAbortCode;
1182 Ret = EplSdoComServerSendFrameIntern(pSdoComCon,
1185 kEplSdoComSendTypeAbort);
1190 }// end of switch(pAsySdoCom_p->m_le_bCommandId)
1194 { // this command layer handle is not responsible
1195 // (wrong direction or wrong transaction ID)
1196 Ret = kEplSdoComNotResponsible;
1199 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1204 // connection closed
1205 case kEplSdoComConEventInitError:
1206 case kEplSdoComConEventTimeout:
1207 case kEplSdoComConEventConClosed:
1209 Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
1210 // clean control structure
1211 EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
1218 }// end of switch(SdoComConEvent_p)
1222 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1223 //-------------------------------------------------------------------------
1225 // segmented transfer
1226 case kEplSdoComStateServerSegmTrans:
1229 switch(SdoComConEvent_p)
1232 case kEplSdoComConEventAckReceived:
1233 case kEplSdoComConEventFrameSended:
1235 // check if it is a read
1236 if(pSdoComCon->m_SdoServiceType == kEplSdoServiceReadByIndex)
1239 EplSdoComServerSendFrameIntern(pSdoComCon,
1242 kEplSdoComSendTypeRes);
1243 // if all send -> back to idle
1244 if(pSdoComCon->m_uiTransSize == 0)
1246 pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
1248 pSdoComCon->m_dwLastAbortCode = 0;
1255 // process next frame
1256 case kEplSdoComConEventRec:
1258 // check if the frame is a SDO response and has the right transaction ID
1259 bFlag = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bFlags);
1260 if (((bFlag & 0x80) != 0) && (AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId) == pSdoComCon->m_bTransactionId))
1262 // check if it is a abort
1263 if((bFlag & 0x40) != 0)
1265 // clear control structure
1266 pSdoComCon->m_uiTransSize = 0;
1267 pSdoComCon->m_uiTransferredByte = 0;
1269 pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
1271 pSdoComCon->m_dwLastAbortCode = 0;
1272 // d.k.: do not execute anything further on this command
1276 // check if it is a write
1277 if(pSdoComCon->m_SdoServiceType == kEplSdoServiceWriteByIndex)
1280 uiSize = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
1281 if(pSdoComCon->m_dwLastAbortCode == 0)
1283 EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[0],uiSize);
1286 pSdoComCon->m_uiTransferredByte += uiSize;
1287 pSdoComCon->m_uiTransSize -= uiSize;
1290 if(pSdoComCon->m_dwLastAbortCode == 0)
1292 (/*(BYTE*)*/pSdoComCon->m_pData) += uiSize;
1295 // check end of transfer
1296 if((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x30)
1298 pSdoComCon->m_uiTransSize = 0;
1300 if(pSdoComCon->m_dwLastAbortCode == 0)
1304 EplSdoComServerSendFrameIntern(pSdoComCon,
1307 kEplSdoComSendTypeRes);
1308 // if all send -> back to idle
1309 if(pSdoComCon->m_uiTransSize == 0)
1311 pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
1313 pSdoComCon->m_dwLastAbortCode = 0;
1317 { // send dabort code
1319 pSdoComCon->m_pData = (BYTE*)&pSdoComCon->m_dwLastAbortCode;
1320 Ret = EplSdoComServerSendFrameIntern(pSdoComCon,
1323 kEplSdoComSendTypeAbort);
1326 pSdoComCon->m_dwLastAbortCode = 0;
1332 // send acknowledge without any Command layer data
1333 Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
1340 { // this command layer handle is not responsible
1341 // (wrong direction or wrong transaction ID)
1342 Ret = kEplSdoComNotResponsible;
1348 // connection closed
1349 case kEplSdoComConEventInitError:
1350 case kEplSdoComConEventTimeout:
1351 case kEplSdoComConEventConClosed:
1353 Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
1354 // clean control structure
1355 EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
1362 }// end of switch(SdoComConEvent_p)
1366 #endif // endif of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1369 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1370 //-------------------------------------------------------------------------
1372 // wait for finish of establishing connection
1373 case kEplSdoComStateClientWaitInit:
1376 // if connection handle is invalid reinit connection
1377 // d.k.: this will be done only on new events (i.e. InitTransfer)
1378 if((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == EPL_SDO_SEQ_INVALID_HDL)
1380 // check kind of connection to reinit
1382 switch(pSdoComCon->m_SdoProtType)
1385 case kEplSdoTypeUdp:
1387 // call connection int function of lower layer
1388 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
1389 pSdoComCon->m_uiNodeId,
1391 if(Ret != kEplSuccessful)
1398 // Asend -> not supported
1399 case kEplSdoTypeAsnd:
1401 // call connection int function of lower layer
1402 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
1403 pSdoComCon->m_uiNodeId,
1405 if(Ret != kEplSuccessful)
1412 // Pdo -> not supported
1413 case kEplSdoTypePdo:
1416 Ret = kEplSdoComUnsupportedProt;
1419 }// end of switch(m_ProtType_p)
1420 // d.k.: reset transaction ID, because new sequence layer connection was initialized
1421 // $$$ d.k. is this really necessary?
1422 //pSdoComCon->m_bTransactionId = 0;
1426 switch(SdoComConEvent_p)
1428 // connection established
1429 case kEplSdoComConEventConEstablished:
1431 //send first frame if needed
1432 if((pSdoComCon->m_uiTransSize > 0)
1433 &&(pSdoComCon->m_uiTargetIndex != 0))
1434 { // start SDO transfer
1435 Ret = EplSdoComClientSend(pSdoComCon);
1436 if(Ret != kEplSuccessful)
1441 // check if segemted transfer
1442 if(pSdoComCon->m_SdoTransType == kEplSdoTransSegmented)
1444 pSdoComCon->m_SdoComState = kEplSdoComStateClientSegmTrans;
1448 // goto state kEplSdoComStateClientConnected
1449 pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
1453 case kEplSdoComConEventSendFirst:
1455 // infos for transfer already saved by function EplSdoComInitTransferByIndex
1459 case kEplSdoComConEventConClosed:
1460 case kEplSdoComConEventInitError:
1461 case kEplSdoComConEventTimeout:
1463 // close sequence layer handle
1464 Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
1465 pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
1466 // call callback function
1467 if (SdoComConEvent_p == kEplSdoComConEventTimeout)
1469 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_TIME_OUT;
1473 pSdoComCon->m_dwLastAbortCode = 0;
1475 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferLowerLayerAbort);
1476 // d.k.: do not clean control structure
1484 } // end of switch(SdoComConEvent_p)
1489 case kEplSdoComStateClientConnected:
1492 switch(SdoComConEvent_p)
1495 case kEplSdoComConEventSendFirst:
1496 case kEplSdoComConEventAckReceived:
1497 case kEplSdoComConEventFrameSended:
1499 Ret = EplSdoComClientSend(pSdoComCon);
1500 if(Ret != kEplSuccessful)
1505 // check if read transfer finished
1506 if((pSdoComCon->m_uiTransSize == 0)
1507 && (pSdoComCon->m_uiTransferredByte != 0)
1508 && (pSdoComCon->m_SdoServiceType == kEplSdoServiceReadByIndex))
1510 // inc transaction id
1511 pSdoComCon->m_bTransactionId++;
1512 // call callback of application
1513 pSdoComCon->m_dwLastAbortCode = 0;
1514 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
1519 // check if segemted transfer
1520 if(pSdoComCon->m_SdoTransType == kEplSdoTransSegmented)
1522 pSdoComCon->m_SdoComState = kEplSdoComStateClientSegmTrans;
1529 case kEplSdoComConEventRec:
1531 // check if the frame is a SDO response and has the right transaction ID
1532 bFlag = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bFlags);
1533 if (((bFlag & 0x80) != 0) && (AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId) == pSdoComCon->m_bTransactionId))
1535 // check if abort or not
1536 if((bFlag & 0x40) != 0)
1538 // send acknowledge without any Command layer data
1539 Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
1542 // inc transaction id
1543 pSdoComCon->m_bTransactionId++;
1545 pSdoComCon->m_dwLastAbortCode = AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
1546 // call callback of application
1547 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferRxAborted);
1552 { // normal frame received
1554 Ret = EplSdoComClientProcessFrame(SdoComCon_p, pAsySdoCom_p);
1556 // check if transfer ready
1557 if(pSdoComCon->m_uiTransSize == 0)
1559 // send acknowledge without any Command layer data
1560 Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
1563 // inc transaction id
1564 pSdoComCon->m_bTransactionId++;
1565 // call callback of application
1566 pSdoComCon->m_dwLastAbortCode = 0;
1567 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
1575 { // this command layer handle is not responsible
1576 // (wrong direction or wrong transaction ID)
1577 Ret = kEplSdoComNotResponsible;
1583 // connection closed event go back to kEplSdoComStateClientWaitInit
1584 case kEplSdoComConEventConClosed:
1585 { // connection closed by communication partner
1586 // close sequence layer handle
1587 Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
1588 // set handle to invalid and enter kEplSdoComStateClientWaitInit
1589 pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
1591 pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
1593 // call callback of application
1594 pSdoComCon->m_dwLastAbortCode = 0;
1595 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferLowerLayerAbort);
1602 // abort to send from higher layer
1603 case kEplSdoComConEventAbort:
1605 EplSdoComClientSendAbort(pSdoComCon,*((DWORD*)pSdoComCon->m_pData));
1607 // inc transaction id
1608 pSdoComCon->m_bTransactionId++;
1609 // call callback of application
1610 pSdoComCon->m_dwLastAbortCode = *((DWORD*)pSdoComCon->m_pData);
1611 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferTxAborted);
1616 case kEplSdoComConEventInitError:
1617 case kEplSdoComConEventTimeout:
1619 // close sequence layer handle
1620 Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
1621 pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
1623 pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
1624 // call callback of application
1625 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_TIME_OUT;
1626 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferLowerLayerAbort);
1634 } // end of switch(SdoComConEvent_p)
1639 // process segmented transfer
1640 case kEplSdoComStateClientSegmTrans:
1643 switch(SdoComConEvent_p)
1646 case kEplSdoComConEventSendFirst:
1647 case kEplSdoComConEventAckReceived:
1648 case kEplSdoComConEventFrameSended:
1650 Ret = EplSdoComClientSend(pSdoComCon);
1651 if(Ret != kEplSuccessful)
1656 // check if read transfer finished
1657 if((pSdoComCon->m_uiTransSize == 0)
1658 && (pSdoComCon->m_SdoServiceType == kEplSdoServiceReadByIndex))
1660 // inc transaction id
1661 pSdoComCon->m_bTransactionId++;
1663 pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
1664 // call callback of application
1665 pSdoComCon->m_dwLastAbortCode = 0;
1666 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
1675 case kEplSdoComConEventRec:
1677 // check if the frame is a response
1678 bFlag = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bFlags);
1679 if (((bFlag & 0x80) != 0) && (AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId) == pSdoComCon->m_bTransactionId))
1681 // check if abort or not
1682 if((bFlag & 0x40) != 0)
1684 // send acknowledge without any Command layer data
1685 Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
1688 // inc transaction id
1689 pSdoComCon->m_bTransactionId++;
1691 pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
1693 pSdoComCon->m_dwLastAbortCode = AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
1694 // call callback of application
1695 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferRxAborted);
1700 { // normal frame received
1702 Ret = EplSdoComClientProcessFrame(SdoComCon_p, pAsySdoCom_p);
1704 // check if transfer ready
1705 if(pSdoComCon->m_uiTransSize == 0)
1707 // send acknowledge without any Command layer data
1708 Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
1711 // inc transaction id
1712 pSdoComCon->m_bTransactionId++;
1714 pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
1715 // call callback of application
1716 pSdoComCon->m_dwLastAbortCode = 0;
1717 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
1726 // connection closed event go back to kEplSdoComStateClientWaitInit
1727 case kEplSdoComConEventConClosed:
1728 { // connection closed by communication partner
1729 // close sequence layer handle
1730 Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
1731 // set handle to invalid and enter kEplSdoComStateClientWaitInit
1732 pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
1734 pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
1735 // inc transaction id
1736 pSdoComCon->m_bTransactionId++;
1737 // call callback of application
1738 pSdoComCon->m_dwLastAbortCode = 0;
1739 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
1744 // abort to send from higher layer
1745 case kEplSdoComConEventAbort:
1747 EplSdoComClientSendAbort(pSdoComCon,*((DWORD*)pSdoComCon->m_pData));
1749 // inc transaction id
1750 pSdoComCon->m_bTransactionId++;
1752 pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
1753 // call callback of application
1754 pSdoComCon->m_dwLastAbortCode = *((DWORD*)pSdoComCon->m_pData);
1755 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferTxAborted);
1760 case kEplSdoComConEventInitError:
1761 case kEplSdoComConEventTimeout:
1763 // close sequence layer handle
1764 Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
1765 pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
1767 pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
1768 // call callback of application
1769 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_TIME_OUT;
1770 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferLowerLayerAbort);
1778 } // end of switch(SdoComConEvent_p)
1782 #endif // endo of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1784 }// end of switch(pSdoComCon->m_SdoComState)
1788 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1792 #if defined(WIN32) || defined(_WIN32)
1793 // leave critical section for process function
1794 EPL_DBGLVL_SDO_TRACE0("\n\tLeaveCriticalSection EplSdoComProcessIntern\n\n");
1795 LeaveCriticalSection(SdoComInstance_g.m_pCriticalSection);
1804 //---------------------------------------------------------------------------
1806 // Function: EplSdoComServerInitReadByIndex
1808 // Description: function start the processing of an read by index command
1812 // Parameters: pSdoComCon_p = pointer to control structure of connection
1813 // pAsySdoCom_p = pointer to received frame
1815 // Returns: tEplKernel = errorcode
1820 //---------------------------------------------------------------------------
1821 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1822 static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon* pSdoComCon_p,
1823 tEplAsySdoCom* pAsySdoCom_p)
1826 unsigned int uiIndex;
1827 unsigned int uiSubindex;
1828 tEplObdSize EntrySize;
1829 tEplObdAccess AccessType;
1834 // a init of a read could not be a segmented transfer
1835 // -> no variable part of header
1837 // get index and subindex
1838 uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
1839 uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
1841 // check accesstype of entry
1842 // existens of entry
1843 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
1844 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
1846 Ret = kEplObdSubindexNotExist;
1849 if(Ret == kEplObdSubindexNotExist)
1850 { // subentry doesn't exist
1851 dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
1853 pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
1854 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
1857 kEplSdoComSendTypeAbort);
1860 else if(Ret != kEplSuccessful)
1861 { // entry doesn't exist
1862 dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
1864 pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
1865 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
1868 kEplSdoComSendTypeAbort);
1872 // compare accesstype must be read or const
1873 if(((AccessType & kEplObdAccRead) == 0)
1874 && ((AccessType & kEplObdAccConst) == 0))
1877 if((AccessType & kEplObdAccWrite) != 0)
1879 // entry read a write only object
1880 dwAbortCode = EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ;
1884 dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
1887 pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
1888 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
1891 kEplSdoComSendTypeAbort);
1896 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceReadByIndex;
1898 // get size of object to see iof segmented or expedited transfer
1899 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
1900 EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
1904 if(EntrySize > EPL_SDO_MAX_PAYLOAD)
1905 { // segmented transfer
1906 pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
1907 // get pointer to object-entry data
1908 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
1909 pSdoComCon_p->m_pData = EplObduGetObjectDataPtr(uiIndex, uiSubindex);
1913 { // expedited transfer
1914 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
1917 pSdoComCon_p->m_uiTransSize = EntrySize;
1918 pSdoComCon_p->m_uiTransferredByte = 0;
1920 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
1923 kEplSdoComSendTypeRes);
1924 if(Ret != kEplSuccessful)
1927 dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
1929 pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
1930 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
1933 kEplSdoComSendTypeAbort);
1942 //---------------------------------------------------------------------------
1944 // Function: EplSdoComServerSendFrameIntern();
1946 // Description: function creats and send a frame for server
1950 // Parameters: pSdoComCon_p = pointer to control structure of connection
1951 // uiIndex_p = index to send if expedited transfer else 0
1952 // uiSubIndex_p = subindex to send if expedited transfer else 0
1953 // SendType_p = to of frame to send
1955 // Returns: tEplKernel = errorcode
1960 //---------------------------------------------------------------------------
1961 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1962 static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon* pSdoComCon_p,
1963 unsigned int uiIndex_p,
1964 unsigned int uiSubIndex_p,
1965 tEplSdoComSendType SendType_p)
1968 BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
1970 tEplAsySdoCom* pCommandFrame;
1971 unsigned int uiSizeOfFrame;
1974 Ret = kEplSuccessful;
1976 pFrame = (tEplFrame*)&abFrame[0];
1978 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
1980 // build generic part of frame
1981 // get pointer to command layerpart of frame
1982 pCommandFrame = &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_abSdoSeqPayload;
1983 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId, pSdoComCon_p->m_SdoServiceType);
1984 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId, pSdoComCon_p->m_bTransactionId);
1986 // set size to header size
1992 // requestframe to send
1993 case kEplSdoComSendTypeReq:
1995 // nothing to do for server
1997 Ret = kEplSdoComInvalidSendType;
2001 // response without data to send
2002 case kEplSdoComSendTypeAckRes:
2004 // set response flag
2005 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, 0x80);
2008 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2015 // responsframe to send
2016 case kEplSdoComSendTypeRes:
2018 // set response flag
2019 bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
2021 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2023 // check type of resonse
2024 if(pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited)
2025 { // Expedited transfer
2026 // copy data in frame
2027 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2028 Ret = EplObduReadEntryToLe(uiIndex_p,
2030 &pCommandFrame->m_le_abCommandData[0],
2031 (tEplObdSize*)&pSdoComCon_p->m_uiTransSize);
2032 if(Ret != kEplSuccessful)
2038 // set size of frame
2039 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, (WORD) pSdoComCon_p->m_uiTransSize);
2041 // correct byte-counter
2042 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2043 pSdoComCon_p->m_uiTransferredByte += pSdoComCon_p->m_uiTransSize;
2044 pSdoComCon_p->m_uiTransSize = 0;
2048 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2049 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2053 else if(pSdoComCon_p->m_SdoTransType == kEplSdoTransSegmented)
2054 { // segmented transfer
2055 // distinguish between init, segment and complete
2056 if(pSdoComCon_p->m_uiTransferredByte == 0)
2059 bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
2061 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2062 // init variable header
2063 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0],pSdoComCon_p->m_uiTransSize);
2064 // copy data in frame
2065 EPL_MEMCPY(&pCommandFrame->m_le_abCommandData[4],pSdoComCon_p->m_pData, (EPL_SDO_MAX_PAYLOAD-4));
2067 // correct byte-counter
2068 pSdoComCon_p->m_uiTransSize -= (EPL_SDO_MAX_PAYLOAD-4);
2069 pSdoComCon_p->m_uiTransferredByte += (EPL_SDO_MAX_PAYLOAD-4);
2070 // move data pointer
2071 pSdoComCon_p->m_pData +=(EPL_SDO_MAX_PAYLOAD-4);
2074 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,(EPL_SDO_MAX_PAYLOAD-4));
2077 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2078 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2083 else if((pSdoComCon_p->m_uiTransferredByte > 0)
2084 &&(pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD))
2087 bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
2089 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2091 // copy data in frame
2092 EPL_MEMCPY(&pCommandFrame->m_le_abCommandData[0],pSdoComCon_p->m_pData, EPL_SDO_MAX_PAYLOAD);
2094 // correct byte-counter
2095 pSdoComCon_p->m_uiTransSize -= EPL_SDO_MAX_PAYLOAD;
2096 pSdoComCon_p->m_uiTransferredByte += EPL_SDO_MAX_PAYLOAD;
2097 // move data pointer
2098 pSdoComCon_p->m_pData +=EPL_SDO_MAX_PAYLOAD;
2101 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,EPL_SDO_MAX_PAYLOAD);
2104 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2105 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2111 if((pSdoComCon_p->m_uiTransSize == 0)
2112 && (pSdoComCon_p->m_SdoServiceType != kEplSdoServiceWriteByIndex))
2117 // set segment complete flag
2118 bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
2120 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2122 // copy data in frame
2123 EPL_MEMCPY(&pCommandFrame->m_le_abCommandData[0],pSdoComCon_p->m_pData, pSdoComCon_p->m_uiTransSize);
2125 // correct byte-counter
2126 pSdoComCon_p->m_uiTransferredByte += pSdoComCon_p->m_uiTransSize;
2129 // move data pointer
2130 pSdoComCon_p->m_pData +=pSdoComCon_p->m_uiTransSize;
2133 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, (WORD) pSdoComCon_p->m_uiTransSize);
2136 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2137 pSdoComCon_p->m_uiTransSize = 0;
2138 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2147 case kEplSdoComSendTypeAbort:
2149 // set response and abort flag
2150 bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
2152 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2154 // copy abortcode to frame
2155 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], *((DWORD*)pSdoComCon_p->m_pData));
2157 // set size of segment
2158 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(DWORD));
2161 pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
2162 pSdoComCon_p->m_uiTransSize = 0;
2165 uiSizeOfFrame += sizeof(DWORD);
2166 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2171 } // end of switch(SendType_p)
2177 //---------------------------------------------------------------------------
2179 // Function: EplSdoComServerInitWriteByIndex
2181 // Description: function start the processing of an write by index command
2185 // Parameters: pSdoComCon_p = pointer to control structure of connection
2186 // pAsySdoCom_p = pointer to received frame
2188 // Returns: tEplKernel = errorcode
2193 //---------------------------------------------------------------------------
2194 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
2195 static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon* pSdoComCon_p,
2196 tEplAsySdoCom* pAsySdoCom_p)
2198 tEplKernel Ret = kEplSuccessful;
2199 unsigned int uiIndex;
2200 unsigned int uiSubindex;
2201 unsigned int uiBytesToTransfer;
2202 tEplObdSize EntrySize;
2203 tEplObdAccess AccessType;
2209 // a init of a write
2210 // -> variable part of header possible
2212 // check if expedited or segmented transfer
2213 if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x10)
2214 { // initiate segmented transfer
2215 pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
2216 // get index and subindex
2217 uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[4]);
2218 uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[6]);
2219 // get source-pointer for copy
2220 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[8];
2222 pSdoComCon_p->m_uiTransSize = AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
2225 else if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x00)
2226 { // expedited transfer
2227 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
2228 // get index and subindex
2229 uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
2230 uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
2231 // get source-pointer for copy
2232 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[4];
2234 pSdoComCon_p->m_uiTransSize = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2236 pSdoComCon_p->m_uiTransSize -= 4;
2241 // just ignore any other transfer type
2245 // check accesstype of entry
2246 // existens of entry
2247 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2248 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
2250 Ret = kEplObdSubindexNotExist;
2253 if (Ret == kEplObdSubindexNotExist)
2254 { // subentry doesn't exist
2255 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
2257 // d.k. This is wrong: k.t. not needed send abort on end of write
2258 /*pSdoComCon_p->m_pData = (BYTE*)pSdoComCon_p->m_dwLastAbortCode;
2259 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2262 kEplSdoComSendTypeAbort);*/
2265 else if(Ret != kEplSuccessful)
2266 { // entry doesn't exist
2267 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
2269 // d.k. This is wrong: k.t. not needed send abort on end of write
2271 pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
2272 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2275 kEplSdoComSendTypeAbort);*/
2279 // compare accesstype must be read
2280 if((AccessType & kEplObdAccWrite) == 0)
2283 if((AccessType & kEplObdAccRead) != 0)
2285 // entry write a read only object
2286 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ;
2290 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
2293 // d.k. This is wrong: k.t. not needed send abort on end of write
2294 /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
2295 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2298 kEplSdoComSendTypeAbort);*/
2303 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceWriteByIndex;
2305 pSdoComCon_p->m_uiTransferredByte = 0;
2308 if(pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited)
2309 { // expedited transfer
2310 // size checking is done by EplObduWriteEntryFromLe()
2312 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2313 Ret = EplObduWriteEntryFromLe(uiIndex,
2316 pSdoComCon_p->m_uiTransSize);
2319 case kEplSuccessful:
2324 case kEplObdAccessViolation:
2326 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
2331 case kEplObdValueLengthError:
2333 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH;
2338 case kEplObdValueTooHigh:
2340 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_VALUE_RANGE_TOO_HIGH;
2345 case kEplObdValueTooLow:
2347 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_VALUE_RANGE_TOO_LOW;
2354 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
2360 // send command acknowledge
2361 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2364 kEplSdoComSendTypeAckRes);
2366 pSdoComCon_p->m_uiTransSize = 0;
2371 // get size of the object to check if it fits
2372 // because we directly write to the destination memory
2373 // d.k. no one calls the user OD callback function
2375 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2376 EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
2380 if(EntrySize < pSdoComCon_p->m_uiTransSize)
2381 { // parameter too big
2382 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
2384 // d.k. This is wrong: k.t. not needed send abort on end of write
2385 /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
2386 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2389 kEplSdoComSendTypeAbort);*/
2393 uiBytesToTransfer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2394 // eleminate header (Command header (8) + variable part (4) + Command header (4))
2395 uiBytesToTransfer -= 16;
2396 // get pointer to object entry
2397 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2398 pSdoComCon_p->m_pData = EplObduGetObjectDataPtr(uiIndex,
2401 if(pSdoComCon_p->m_pData == NULL)
2403 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
2405 // d.k. This is wrong: k.t. not needed send abort on end of write
2406 /* pSdoComCon_p->m_pData = (BYTE*)&pSdoComCon_p->m_dwLastAbortCode;
2407 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2410 kEplSdoComSendTypeAbort);*/
2415 EPL_MEMCPY(pSdoComCon_p->m_pData, pbSrcData, uiBytesToTransfer);
2417 // update internal counter
2418 pSdoComCon_p->m_uiTransferredByte = uiBytesToTransfer;
2419 pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer;
2421 // update target pointer
2422 (/*(BYTE*)*/pSdoComCon_p->m_pData) += uiBytesToTransfer;
2424 // send acknowledge without any Command layer data
2425 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2432 if(pSdoComCon_p->m_dwLastAbortCode != 0)
2435 pSdoComCon_p->m_pData = (BYTE*)&pSdoComCon_p->m_dwLastAbortCode;
2436 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2439 kEplSdoComSendTypeAbort);
2442 pSdoComCon_p->m_dwLastAbortCode = 0;
2443 pSdoComCon_p->m_uiTransSize = 0;
2452 //---------------------------------------------------------------------------
2454 // Function: EplSdoComClientSend
2456 // Description: function starts an sdo transfer an send all further frames
2460 // Parameters: pSdoComCon_p = pointer to control structure of connection
2462 // Returns: tEplKernel = errorcode
2467 //---------------------------------------------------------------------------
2468 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
2469 static tEplKernel EplSdoComClientSend(tEplSdoComCon* pSdoComCon_p)
2472 BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
2474 tEplAsySdoCom* pCommandFrame;
2475 unsigned int uiSizeOfFrame;
2479 Ret = kEplSuccessful;
2481 pFrame = (tEplFrame*)&abFrame[0];
2483 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
2485 // build generic part of frame
2486 // get pointer to command layerpart of frame
2487 pCommandFrame = &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_abSdoSeqPayload;
2488 AmiSetByteToLe( &pCommandFrame->m_le_bCommandId, pSdoComCon_p->m_SdoServiceType);
2489 AmiSetByteToLe( &pCommandFrame->m_le_bTransactionId, pSdoComCon_p->m_bTransactionId);
2491 // set size constant part of header
2494 // check if first frame to send -> command header needed
2495 if (pSdoComCon_p->m_uiTransSize > 0)
2497 if (pSdoComCon_p->m_uiTransferredByte == 0)
2498 { // start SDO transfer
2499 // check if segmented or expedited transfer
2500 // only for write commands
2501 switch(pSdoComCon_p->m_SdoServiceType)
2503 case kEplSdoServiceReadByIndex:
2504 { // first frame of read access always expedited
2505 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
2506 pbPayload = &pCommandFrame->m_le_abCommandData[0];
2507 // fill rest of header
2508 AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, 4);
2510 // create command header
2511 AmiSetWordToLe(pbPayload, (WORD)pSdoComCon_p->m_uiTargetIndex);
2513 AmiSetByteToLe(pbPayload, (BYTE)pSdoComCon_p->m_uiTargetSubIndex);
2517 // set pSdoComCon_p->m_uiTransferredByte to one
2518 pSdoComCon_p->m_uiTransferredByte = 1;
2522 case kEplSdoServiceWriteByIndex:
2524 if(pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD )
2525 { // segmented transfer
2526 // -> variable part of header needed
2527 // save that transfer is segmented
2528 pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
2529 // fill variable part of header
2530 AmiSetDwordToLe( &pCommandFrame->m_le_abCommandData[0], pSdoComCon_p->m_uiTransSize);
2531 // set pointer to real payload
2532 pbPayload = &pCommandFrame->m_le_abCommandData[4];
2533 // fill rest of header
2534 AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, EPL_SDO_MAX_PAYLOAD);
2536 AmiSetByteToLe( &pCommandFrame->m_le_bFlags, bFlags);
2537 // create command header
2538 AmiSetWordToLe(pbPayload, (WORD) pSdoComCon_p->m_uiTargetIndex);
2540 AmiSetByteToLe(pbPayload, (BYTE)pSdoComCon_p->m_uiTargetSubIndex);
2541 // on byte for reserved
2544 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2547 EPL_MEMCPY( pbPayload,pSdoComCon_p->m_pData, (EPL_SDO_MAX_PAYLOAD - 8));
2548 pSdoComCon_p->m_pData += (EPL_SDO_MAX_PAYLOAD - 8);
2549 // correct intern counter
2550 pSdoComCon_p->m_uiTransSize -= (EPL_SDO_MAX_PAYLOAD - 8);
2551 pSdoComCon_p->m_uiTransferredByte = (EPL_SDO_MAX_PAYLOAD - 8);
2555 { // expedited trandsfer
2556 // save that transfer is expedited
2557 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
2558 pbPayload = &pCommandFrame->m_le_abCommandData[0];
2560 // create command header
2561 AmiSetWordToLe(pbPayload, (WORD) pSdoComCon_p->m_uiTargetIndex);
2563 AmiSetByteToLe(pbPayload, (BYTE)pSdoComCon_p->m_uiTargetSubIndex);
2564 // + 2 -> one byte for subindex and one byte reserved
2567 EPL_MEMCPY( pbPayload,pSdoComCon_p->m_pData, pSdoComCon_p->m_uiTransSize);
2569 uiSizeOfFrame += (4 + pSdoComCon_p->m_uiTransSize);
2570 // fill rest of header
2571 AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, (WORD) (4 + pSdoComCon_p->m_uiTransSize));
2573 pSdoComCon_p->m_uiTransferredByte = pSdoComCon_p->m_uiTransSize;
2574 pSdoComCon_p->m_uiTransSize = 0;
2579 case kEplSdoServiceNIL:
2581 // invalid service requested
2582 Ret = kEplSdoComInvalidServiceType;
2584 } // end of switch(pSdoComCon_p->m_SdoServiceType)
2586 else // (pSdoComCon_p->m_uiTransferredByte > 0)
2587 { // continue SDO transfer
2588 switch(pSdoComCon_p->m_SdoServiceType)
2590 // for expedited read is nothing to do
2591 // -> server sends data
2593 case kEplSdoServiceWriteByIndex:
2594 { // send next frame
2595 if(pSdoComCon_p->m_SdoTransType == kEplSdoTransSegmented)
2597 if(pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD)
2599 pbPayload = &pCommandFrame->m_le_abCommandData[0];
2600 // fill rest of header
2601 AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, EPL_SDO_MAX_PAYLOAD);
2603 AmiSetByteToLe( &pCommandFrame->m_le_bFlags, bFlags);
2605 EPL_MEMCPY( pbPayload,pSdoComCon_p->m_pData, EPL_SDO_MAX_PAYLOAD);
2606 pSdoComCon_p->m_pData += EPL_SDO_MAX_PAYLOAD;
2607 // correct intern counter
2608 pSdoComCon_p->m_uiTransSize -= EPL_SDO_MAX_PAYLOAD;
2609 pSdoComCon_p->m_uiTransferredByte = EPL_SDO_MAX_PAYLOAD;
2611 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2616 { // end of transfer
2617 pbPayload = &pCommandFrame->m_le_abCommandData[0];
2618 // fill rest of header
2619 AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, (WORD) pSdoComCon_p->m_uiTransSize);
2621 AmiSetByteToLe( &pCommandFrame->m_le_bFlags, bFlags);
2623 EPL_MEMCPY( pbPayload,pSdoComCon_p->m_pData, pSdoComCon_p->m_uiTransSize);
2624 pSdoComCon_p->m_pData += pSdoComCon_p->m_uiTransSize;
2626 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2627 // correct intern counter
2628 pSdoComCon_p->m_uiTransSize = 0;
2629 pSdoComCon_p->m_uiTransferredByte = pSdoComCon_p->m_uiTransSize;
2643 } // end of switch(pSdoComCon_p->m_SdoServiceType)
2652 // call send function of lower layer
2653 switch(pSdoComCon_p->m_SdoProtType)
2655 case kEplSdoTypeAsnd:
2656 case kEplSdoTypeUdp:
2658 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2666 Ret = kEplSdoComUnsupportedProt;
2668 } // end of switch(pSdoComCon_p->m_SdoProtType)
2676 //---------------------------------------------------------------------------
2678 // Function: EplSdoComClientProcessFrame
2680 // Description: function process a received frame
2684 // Parameters: SdoComCon_p = connection handle
2685 // pAsySdoCom_p = pointer to frame to process
2687 // Returns: tEplKernel = errorcode
2692 //---------------------------------------------------------------------------
2693 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
2694 static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
2695 tEplAsySdoCom* pAsySdoCom_p)
2699 unsigned int uiBuffer;
2700 unsigned int uiDataSize;
2701 unsigned long ulBuffer;
2702 tEplSdoComCon* pSdoComCon;
2705 Ret = kEplSuccessful;
2707 // get pointer to control structure
2708 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
2710 // check if transaction Id fit
2711 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId);
2712 if(pSdoComCon->m_bTransactionId != bBuffer)
2714 // incorrect transaction id
2716 // if running transfer
2717 if((pSdoComCon->m_uiTransferredByte != 0)
2718 && (pSdoComCon->m_uiTransSize !=0))
2720 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
2722 EplSdoComClientSendAbort(pSdoComCon, pSdoComCon->m_dwLastAbortCode);
2723 // call callback of application
2724 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferTxAborted);
2729 { // check if correct command
2730 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bCommandId);
2731 if(pSdoComCon->m_SdoServiceType != bBuffer)
2733 // incorrect command
2734 // if running transfer
2735 if((pSdoComCon->m_uiTransferredByte != 0)
2736 && (pSdoComCon->m_uiTransSize !=0))
2738 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
2740 EplSdoComClientSendAbort(pSdoComCon, pSdoComCon->m_dwLastAbortCode);
2741 // call callback of application
2742 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferTxAborted);
2747 { // switch on command
2748 switch(pSdoComCon->m_SdoServiceType)
2750 case kEplSdoServiceWriteByIndex:
2751 { // check if confirmation from server
2752 // nothing more to do
2756 case kEplSdoServiceReadByIndex:
2757 { // check if it is an segmented or an expedited transfer
2758 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bFlags);
2759 // mask uninteressting bits
2763 // expedited transfer
2766 // check size of buffer
2767 uiBuffer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2768 if(uiBuffer > pSdoComCon->m_uiTransSize)
2769 { // buffer provided by the application is to small
2771 uiDataSize = pSdoComCon->m_uiTransSize;
2775 uiDataSize = uiBuffer;
2779 EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[0], uiDataSize);
2782 pSdoComCon->m_uiTransSize = 0;
2783 pSdoComCon->m_uiTransferredByte = uiDataSize;
2787 // start of a segmented transfer
2789 { // get total size of transfer
2790 ulBuffer = AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
2791 if(ulBuffer <= pSdoComCon->m_uiTransSize)
2793 pSdoComCon->m_uiTransSize = (unsigned int)ulBuffer;
2796 { // buffer to small
2798 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
2800 EplSdoComClientSendAbort(pSdoComCon, pSdoComCon->m_dwLastAbortCode);
2801 // call callback of application
2802 Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferRxAborted);
2807 // check size of buffer
2808 uiBuffer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2809 // subtract size of vaiable header from datasize
2812 EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[4], uiBuffer);
2814 // correct counter an pointer
2815 pSdoComCon->m_pData += uiBuffer;
2816 pSdoComCon->m_uiTransferredByte += uiBuffer;
2817 pSdoComCon->m_uiTransSize -= uiBuffer;
2826 // check size of buffer
2827 uiBuffer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2828 // check if data to copy fit to buffer
2829 if(uiBuffer >= pSdoComCon->m_uiTransSize)
2831 uiBuffer = (pSdoComCon->m_uiTransSize - 1);
2834 EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[0], uiBuffer);
2836 // correct counter an pointer
2837 pSdoComCon->m_pData += uiBuffer;
2838 pSdoComCon->m_uiTransferredByte += uiBuffer;
2839 pSdoComCon->m_uiTransSize -= uiBuffer;
2847 // check size of buffer
2848 uiBuffer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2849 // check if data to copy fit to buffer
2850 if(uiBuffer > pSdoComCon->m_uiTransSize)
2852 uiBuffer = (pSdoComCon->m_uiTransSize - 1);
2855 EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[0], uiBuffer);
2857 // correct counter an pointer
2858 pSdoComCon->m_pData += uiBuffer;
2859 pSdoComCon->m_uiTransferredByte += uiBuffer;
2860 pSdoComCon->m_uiTransSize = 0;
2864 }// end of switch(bBuffer & 0x30)
2869 case kEplSdoServiceNIL:
2871 // invalid service requested
2872 // $$$ d.k. What should we do?
2874 }// end of switch(pSdoComCon->m_SdoServiceType)
2883 //---------------------------------------------------------------------------
2885 // Function: EplSdoComClientSendAbort
2887 // Description: function send a abort message
2891 // Parameters: pSdoComCon_p = pointer to control structure of connection
2892 // dwAbortCode_p = Sdo abort code
2894 // Returns: tEplKernel = errorcode
2899 //---------------------------------------------------------------------------
2900 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
2901 static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon* pSdoComCon_p,
2902 DWORD dwAbortCode_p)
2905 BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
2907 tEplAsySdoCom* pCommandFrame;
2908 unsigned int uiSizeOfFrame;
2910 Ret = kEplSuccessful;
2912 pFrame = (tEplFrame*)&abFrame[0];
2914 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
2916 // build generic part of frame
2917 // get pointer to command layerpart of frame
2918 pCommandFrame = &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_abSdoSeqPayload;
2919 AmiSetByteToLe( &pCommandFrame->m_le_bCommandId, pSdoComCon_p->m_SdoServiceType);
2920 AmiSetByteToLe( &pCommandFrame->m_le_bTransactionId, pSdoComCon_p->m_bTransactionId);
2924 // set response and abort flag
2925 pCommandFrame->m_le_bFlags |= 0x40;
2927 // copy abortcode to frame
2928 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p);
2930 // set size of segment
2931 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(DWORD));
2934 pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
2935 pSdoComCon_p->m_uiTransSize = 0;
2938 uiSizeOfFrame += sizeof(DWORD);
2941 pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p;
2943 // call send function of lower layer
2944 switch(pSdoComCon_p->m_SdoProtType)
2946 case kEplSdoTypeAsnd:
2947 case kEplSdoTypeUdp:
2949 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2957 Ret = kEplSdoComUnsupportedProt;
2959 } // end of switch(pSdoComCon_p->m_SdoProtType)
2966 //---------------------------------------------------------------------------
2968 // Function: EplSdoComTransferFinished
2970 // Description: calls callback function of application if available
2971 // and clears entry in control structure
2973 // Parameters: pSdoComCon_p = pointer to control structure of connection
2974 // SdoComConState_p = state of SDO transfer
2976 // Returns: tEplKernel = errorcode
2981 //---------------------------------------------------------------------------
2982 static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p,
2983 tEplSdoComCon* pSdoComCon_p,
2984 tEplSdoComConState SdoComConState_p)
2988 Ret = kEplSuccessful;
2990 if(pSdoComCon_p->m_pfnTransferFinished != NULL)
2992 tEplSdoFinishedCb pfnTransferFinished;
2993 tEplSdoComFinished SdoComFinished;
2995 SdoComFinished.m_pUserArg = pSdoComCon_p->m_pUserArg;
2996 SdoComFinished.m_uiNodeId = pSdoComCon_p->m_uiNodeId;
2997 SdoComFinished.m_uiTargetIndex = pSdoComCon_p->m_uiTargetIndex;
2998 SdoComFinished.m_uiTargetSubIndex = pSdoComCon_p->m_uiTargetSubIndex;
2999 SdoComFinished.m_uiTransferredByte = pSdoComCon_p->m_uiTransferredByte;
3000 SdoComFinished.m_dwAbortCode = pSdoComCon_p->m_dwLastAbortCode;
3001 SdoComFinished.m_SdoComConHdl = SdoComCon_p;
3002 SdoComFinished.m_SdoComConState = SdoComConState_p;
3003 if (pSdoComCon_p->m_SdoServiceType == kEplSdoServiceWriteByIndex)
3005 SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeWrite;
3009 SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeRead;
3012 // reset transfer state so this handle is not busy anymore
3013 pSdoComCon_p->m_uiTransferredByte = 0;
3014 pSdoComCon_p->m_uiTransSize = 0;
3016 pfnTransferFinished = pSdoComCon_p->m_pfnTransferFinished;
3017 // delete function pointer to inform application only once for each transfer
3018 pSdoComCon_p->m_pfnTransferFinished = NULL;
3020 // call application's callback function
3021 pfnTransferFinished(&SdoComFinished);