Staging: comedi: Remove comedi_cmd typedef
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / epl / EplSdoComu.c
CommitLineData
9d7164cf
DK
1/****************************************************************************
2
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
5
6 Project: openPOWERLINK
7
8 Description: source file for SDO Command Layer module
9
10 License:
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
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.
22
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.
27
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.
40
41 Severability Clause:
42
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.
49
50 -------------------------------------------------------------------------
51
52 $RCSfile: EplSdoComu.c,v $
53
54 $Author: D.Krueger $
55
56 $Revision: 1.14 $ $Date: 2008/10/17 15:32:32 $
57
58 $State: Exp $
59
60 Build Environment:
61 GCC V3.4
62
63 -------------------------------------------------------------------------
64
65 Revision History:
66
67 2006/06/26 k.t.: start of the implementation
68
69****************************************************************************/
70
71#include "user/EplSdoComu.h"
72
73#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) == 0) &&\
74 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) == 0) )
75
833dfbe7 76#error 'ERROR: At least SDO Server or SDO Client should be activate!'
9d7164cf
DK
77
78#endif
79
80#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
833dfbe7 81#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
9d7164cf 82
833dfbe7 83#error 'ERROR: SDO Server needs OBDu module!'
9d7164cf 84
833dfbe7 85#endif
9d7164cf
DK
86
87#endif
88
89/***************************************************************************/
90/* */
91/* */
92/* G L O B A L D E F I N I T I O N S */
93/* */
94/* */
95/***************************************************************************/
96
97//---------------------------------------------------------------------------
98// const defines
99//---------------------------------------------------------------------------
100
101#ifndef EPL_MAX_SDO_COM_CON
102#define EPL_MAX_SDO_COM_CON 5
103#endif
104
9d7164cf
DK
105//---------------------------------------------------------------------------
106// local types
107//---------------------------------------------------------------------------
108
109// intern events
833dfbe7
GKH
110typedef enum {
111 kEplSdoComConEventSendFirst = 0x00, // first frame to send
112 kEplSdoComConEventRec = 0x01, // frame received
113 kEplSdoComConEventConEstablished = 0x02, // connection established
114 kEplSdoComConEventConClosed = 0x03, // connection closed
115 kEplSdoComConEventAckReceived = 0x04, // acknowledge received by lower layer
116 // -> continue sending
117 kEplSdoComConEventFrameSended = 0x05, // lower has send a frame
118 kEplSdoComConEventInitError = 0x06, // error duringinitialisiation
119 // of the connection
120 kEplSdoComConEventTimeout = 0x07 // timeout in lower layer
9d7164cf 121#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7 122 ,
9d7164cf 123
833dfbe7
GKH
124 kEplSdoComConEventInitCon = 0x08, // init connection (only client)
125 kEplSdoComConEventAbort = 0x09 // abort sdo transfer (only client)
9d7164cf 126#endif
833dfbe7 127} tEplSdoComConEvent;
9d7164cf 128
833dfbe7
GKH
129typedef enum {
130 kEplSdoComSendTypeReq = 0x00, // send a request
131 kEplSdoComSendTypeAckRes = 0x01, // send a resonse without data
132 kEplSdoComSendTypeRes = 0x02, // send response with data
133 kEplSdoComSendTypeAbort = 0x03 // send abort
134} tEplSdoComSendType;
9d7164cf
DK
135
136// state of the state maschine
833dfbe7
GKH
137typedef enum {
138 // General State
139 kEplSdoComStateIdle = 0x00, // idle state
9d7164cf
DK
140
141#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
833dfbe7
GKH
142 // Server States
143 kEplSdoComStateServerSegmTrans = 0x01, // send following frames
9d7164cf
DK
144#endif
145
9d7164cf 146#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7
GKH
147 // Client States
148 kEplSdoComStateClientWaitInit = 0x10, // wait for init connection
149 // on lower layer
150 kEplSdoComStateClientConnected = 0x11, // connection established
151 kEplSdoComStateClientSegmTrans = 0x12 // send following frames
9d7164cf 152#endif
9d7164cf
DK
153} tEplSdoComState;
154
9d7164cf 155// control structure for transaction
833dfbe7
GKH
156typedef struct {
157 tEplSdoSeqConHdl m_SdoSeqConHdl; // if != 0 -> entry used
158 tEplSdoComState m_SdoComState;
159 BYTE m_bTransactionId;
160 unsigned int m_uiNodeId; // NodeId of the target
161 // -> needed to reinit connection
162 // after timeout
163 tEplSdoTransType m_SdoTransType; // Auto, Expedited, Segmented
164 tEplSdoServiceType m_SdoServiceType; // WriteByIndex, ReadByIndex
165 tEplSdoType m_SdoProtType; // protocol layer: Auto, Udp, Asnd, Pdo
166 BYTE *m_pData; // pointer to data
167 unsigned int m_uiTransSize; // number of bytes
168 // to transfer
169 unsigned int m_uiTransferredByte; // number of bytes
170 // already transferred
171 tEplSdoFinishedCb m_pfnTransferFinished; // callback function of the
172 // application
173 // -> called in the end of
174 // the SDO transfer
175 void *m_pUserArg; // user definable argument pointer
176
177 DWORD m_dwLastAbortCode; // save the last abort code
9d7164cf 178#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7
GKH
179 // only for client
180 unsigned int m_uiTargetIndex; // index to access
181 unsigned int m_uiTargetSubIndex; // subiondex to access
9d7164cf 182
833dfbe7
GKH
183 // for future use
184 unsigned int m_uiTimeout; // timeout for this connection
9d7164cf
DK
185
186#endif
187
188} tEplSdoComCon;
189
190// instance table
833dfbe7
GKH
191typedef struct {
192 tEplSdoComCon m_SdoComCon[EPL_MAX_SDO_COM_CON];
9d7164cf
DK
193
194#if defined(WIN32) || defined(_WIN32)
833dfbe7
GKH
195 LPCRITICAL_SECTION m_pCriticalSection;
196 CRITICAL_SECTION m_CriticalSection;
9d7164cf
DK
197#endif
198
833dfbe7 199} tEplSdoComInstance;
9d7164cf
DK
200
201//---------------------------------------------------------------------------
202// modul globale vars
203//---------------------------------------------------------------------------
204static tEplSdoComInstance SdoComInstance_g;
205//---------------------------------------------------------------------------
206// local function prototypes
207//---------------------------------------------------------------------------
833dfbe7
GKH
208tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
209 tEplAsySdoCom * pAsySdoCom_p,
210 unsigned int uiDataSize_p);
9d7164cf 211
833dfbe7
GKH
212tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
213 tEplAsySdoConState AsySdoConState_p);
9d7164cf 214
833dfbe7
GKH
215static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
216 tEplSdoComConEvent SdoComConEvent_p,
217 tEplAsySdoCom * pAsySdoCom_p);
9d7164cf 218
833dfbe7
GKH
219static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
220 tEplSdoComConEvent SdoComConEvent_p,
221 tEplAsySdoCom * pAsySdoCom_p);
9d7164cf 222
833dfbe7
GKH
223static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p,
224 tEplSdoComCon * pSdoComCon_p,
225 tEplSdoComConState
226 SdoComConState_p);
9d7164cf
DK
227
228#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
833dfbe7
GKH
229static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
230 tEplAsySdoCom * pAsySdoCom_p);
9d7164cf 231
833dfbe7
GKH
232static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
233 unsigned int uiIndex_p,
234 unsigned int uiSubIndex_p,
235 tEplSdoComSendType SendType_p);
9d7164cf 236
833dfbe7
GKH
237static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
238 tEplAsySdoCom * pAsySdoCom_p);
9d7164cf
DK
239#endif
240
9d7164cf
DK
241#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
242
833dfbe7 243static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p);
9d7164cf 244
833dfbe7
GKH
245static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
246 tEplAsySdoCom * pAsySdoCom_p);
9d7164cf 247
833dfbe7
GKH
248static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
249 DWORD dwAbortCode_p);
9d7164cf
DK
250#endif
251
9d7164cf
DK
252/***************************************************************************/
253/* */
254/* */
255/* C L A S S <SDO Command Layer> */
256/* */
257/* */
258/***************************************************************************/
259//
260// Description: SDO Command layer Modul
261//
262//
263/***************************************************************************/
264
265//=========================================================================//
266// //
267// P U B L I C F U N C T I O N S //
268// //
269//=========================================================================//
270
271//---------------------------------------------------------------------------
272//
273// Function: EplSdoComInit
274//
275// Description: Init first instance of the module
276//
277//
278//
279// Parameters:
280//
281//
282// Returns: tEplKernel = errorcode
283//
284//
285// State:
286//
287//---------------------------------------------------------------------------
288tEplKernel PUBLIC EplSdoComInit(void)
289{
833dfbe7 290 tEplKernel Ret;
9d7164cf 291
833dfbe7 292 Ret = EplSdoComAddInstance();
9d7164cf 293
833dfbe7 294 return Ret;
9d7164cf
DK
295
296}
297
298//---------------------------------------------------------------------------
299//
300// Function: EplSdoComAddInstance
301//
302// Description: Init additional instance of the module
303//
304//
305//
306// Parameters:
307//
308//
309// Returns: tEplKernel = errorcode
310//
311//
312// State:
313//
314//---------------------------------------------------------------------------
315tEplKernel PUBLIC EplSdoComAddInstance(void)
316{
833dfbe7 317 tEplKernel Ret;
9d7164cf 318
833dfbe7 319 Ret = kEplSuccessful;
9d7164cf 320
833dfbe7
GKH
321 // init controll structure
322 EPL_MEMSET(&SdoComInstance_g, 0x00, sizeof(SdoComInstance_g));
9d7164cf 323
833dfbe7
GKH
324 // init instance of lower layer
325 Ret = EplSdoAsySeqAddInstance(EplSdoComReceiveCb, EplSdoComConCb);
326 if (Ret != kEplSuccessful) {
327 goto Exit;
328 }
9d7164cf 329#if defined(WIN32) || defined(_WIN32)
833dfbe7
GKH
330 // create critical section for process function
331 SdoComInstance_g.m_pCriticalSection =
332 &SdoComInstance_g.m_CriticalSection;
333 InitializeCriticalSection(SdoComInstance_g.m_pCriticalSection);
9d7164cf
DK
334#endif
335
833dfbe7
GKH
336 Exit:
337 return Ret;
9d7164cf
DK
338}
339
340//---------------------------------------------------------------------------
341//
342// Function: EplSdoComDelInstance
343//
344// Description: delete instance of the module
345//
346//
347//
348// Parameters:
349//
350//
351// Returns: tEplKernel = errorcode
352//
353//
354// State:
355//
356//---------------------------------------------------------------------------
357tEplKernel PUBLIC EplSdoComDelInstance(void)
358{
833dfbe7 359 tEplKernel Ret;
9d7164cf 360
833dfbe7 361 Ret = kEplSuccessful;
9d7164cf
DK
362
363#if defined(WIN32) || defined(_WIN32)
833dfbe7
GKH
364 // delete critical section for process function
365 DeleteCriticalSection(SdoComInstance_g.m_pCriticalSection);
9d7164cf
DK
366#endif
367
833dfbe7
GKH
368 Ret = EplSdoAsySeqDelInstance();
369 if (Ret != kEplSuccessful) {
370 goto Exit;
371 }
9d7164cf 372
833dfbe7
GKH
373 Exit:
374 return Ret;
9d7164cf
DK
375}
376
377//---------------------------------------------------------------------------
378//
379// Function: EplSdoComDefineCon
380//
381// Description: function defines a SDO connection to another node
382// -> init lower layer and returns a handle for the connection.
383// Two client connections to the same node via the same protocol
384// are not allowed. If this function detects such a situation
385// it will return kEplSdoComHandleExists and the handle of
386// the existing connection in pSdoComConHdl_p.
387// Using of existing server connections is possible.
388//
389// Parameters: pSdoComConHdl_p = pointer to the buffer of the handle
390// uiTargetNodeId_p = NodeId of the targetnode
391// ProtType_p = type of protocol to use for connection
392//
393//
394// Returns: tEplKernel = errorcode
395//
396//
397// State:
398//
399//---------------------------------------------------------------------------
400#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7
GKH
401tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
402 unsigned int uiTargetNodeId_p,
403 tEplSdoType ProtType_p)
9d7164cf 404{
833dfbe7
GKH
405 tEplKernel Ret;
406 unsigned int uiCount;
407 unsigned int uiFreeHdl;
408 tEplSdoComCon *pSdoComCon;
409
410 // check Parameter
411 ASSERT(pSdoComConHdl_p != NULL);
412
413 // check NodeId
414 if ((uiTargetNodeId_p == EPL_C_ADR_INVALID)
415 || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST)) {
416 Ret = kEplInvalidNodeId;
417
418 }
419 // search free control structure
420 pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
421 uiCount = 0;
422 uiFreeHdl = EPL_MAX_SDO_COM_CON;
423 while (uiCount < EPL_MAX_SDO_COM_CON) {
424 if (pSdoComCon->m_SdoSeqConHdl == 0) { // free entry
425 uiFreeHdl = uiCount;
426 } else if ((pSdoComCon->m_uiNodeId == uiTargetNodeId_p)
427 && (pSdoComCon->m_SdoProtType == ProtType_p)) { // existing client connection with same node ID and same protocol type
428 *pSdoComConHdl_p = uiCount;
429 Ret = kEplSdoComHandleExists;
430 goto Exit;
431 }
432 uiCount++;
433 pSdoComCon++;
434 }
435
436 if (uiFreeHdl == EPL_MAX_SDO_COM_CON) {
437 Ret = kEplSdoComNoFreeHandle;
438 goto Exit;
439 }
440
441 pSdoComCon = &SdoComInstance_g.m_SdoComCon[uiFreeHdl];
442 // save handle for application
443 *pSdoComConHdl_p = uiFreeHdl;
444 // save parameters
445 pSdoComCon->m_SdoProtType = ProtType_p;
446 pSdoComCon->m_uiNodeId = uiTargetNodeId_p;
447
448 // set Transaction Id
449 pSdoComCon->m_bTransactionId = 0;
450
451 // check protocol
452 switch (ProtType_p) {
453 // udp
454 case kEplSdoTypeUdp:
455 {
456 // call connection int function of lower layer
457 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
458 pSdoComCon->m_uiNodeId,
459 kEplSdoTypeUdp);
460 if (Ret != kEplSuccessful) {
461 goto Exit;
462 }
463 break;
464 }
465
466 // Asend
467 case kEplSdoTypeAsnd:
468 {
469 // call connection int function of lower layer
470 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
471 pSdoComCon->m_uiNodeId,
472 kEplSdoTypeAsnd);
473 if (Ret != kEplSuccessful) {
474 goto Exit;
475 }
476 break;
477 }
478
479 // Pdo -> not supported
480 case kEplSdoTypePdo:
481 default:
482 {
483 Ret = kEplSdoComUnsupportedProt;
484 goto Exit;
485 }
486 } // end of switch(m_ProtType_p)
487
488 // call process function
489 Ret = EplSdoComProcessIntern(uiFreeHdl,
490 kEplSdoComConEventInitCon, NULL);
491
492 Exit:
493 return Ret;
9d7164cf
DK
494}
495#endif
496//---------------------------------------------------------------------------
497//
498// Function: EplSdoComInitTransferByIndex
499//
500// Description: function init SDO Transfer for a defined connection
501//
502//
503//
504// Parameters: SdoComTransParam_p = Structure with parameters for connection
505//
506//
507// Returns: tEplKernel = errorcode
508//
509//
510// State:
511//
512//---------------------------------------------------------------------------
513#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7
GKH
514tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
515 pSdoComTransParam_p)
9d7164cf 516{
833dfbe7
GKH
517 tEplKernel Ret;
518 tEplSdoComCon *pSdoComCon;
519
520 // check parameter
521 if ((pSdoComTransParam_p->m_uiSubindex >= 0xFF)
522 || (pSdoComTransParam_p->m_uiIndex == 0)
523 || (pSdoComTransParam_p->m_uiIndex > 0xFFFF)
524 || (pSdoComTransParam_p->m_pData == NULL)
525 || (pSdoComTransParam_p->m_uiDataSize == 0)) {
526 Ret = kEplSdoComInvalidParam;
527 goto Exit;
528 }
529
530 if (pSdoComTransParam_p->m_SdoComConHdl >= EPL_MAX_SDO_COM_CON) {
531 Ret = kEplSdoComInvalidHandle;
532 goto Exit;
533 }
534 // get pointer to control structure of connection
535 pSdoComCon =
536 &SdoComInstance_g.m_SdoComCon[pSdoComTransParam_p->m_SdoComConHdl];
537
538 // check if handle ok
539 if (pSdoComCon->m_SdoSeqConHdl == 0) {
540 Ret = kEplSdoComInvalidHandle;
541 goto Exit;
542 }
543 // check if command layer is idle
544 if ((pSdoComCon->m_uiTransferredByte + pSdoComCon->m_uiTransSize) > 0) { // handle is not idle
545 Ret = kEplSdoComHandleBusy;
546 goto Exit;
547 }
548 // save parameter
549 // callback function for end of transfer
550 pSdoComCon->m_pfnTransferFinished =
551 pSdoComTransParam_p->m_pfnSdoFinishedCb;
552 pSdoComCon->m_pUserArg = pSdoComTransParam_p->m_pUserArg;
553
554 // set type of SDO command
555 if (pSdoComTransParam_p->m_SdoAccessType == kEplSdoAccessTypeRead) {
556 pSdoComCon->m_SdoServiceType = kEplSdoServiceReadByIndex;
557 } else {
558 pSdoComCon->m_SdoServiceType = kEplSdoServiceWriteByIndex;
559
560 }
561 // save pointer to data
562 pSdoComCon->m_pData = pSdoComTransParam_p->m_pData;
563 // maximal bytes to transfer
564 pSdoComCon->m_uiTransSize = pSdoComTransParam_p->m_uiDataSize;
565 // bytes already transfered
566 pSdoComCon->m_uiTransferredByte = 0;
567
568 // reset parts of control structure
569 pSdoComCon->m_dwLastAbortCode = 0;
570 pSdoComCon->m_SdoTransType = kEplSdoTransAuto;
571 // save timeout
572 //pSdoComCon->m_uiTimeout = SdoComTransParam_p.m_uiTimeout;
573
574 // save index and subindex
575 pSdoComCon->m_uiTargetIndex = pSdoComTransParam_p->m_uiIndex;
576 pSdoComCon->m_uiTargetSubIndex = pSdoComTransParam_p->m_uiSubindex;
577
578 // call process function
579 Ret = EplSdoComProcessIntern(pSdoComTransParam_p->m_SdoComConHdl, kEplSdoComConEventSendFirst, // event to start transfer
580 NULL);
581
582 Exit:
583 return Ret;
9d7164cf
DK
584
585}
586#endif
587
588//---------------------------------------------------------------------------
589//
590// Function: EplSdoComUndefineCon
591//
592// Description: function undefine a SDO connection
593//
594//
595//
596// Parameters: SdoComConHdl_p = handle for the connection
597//
598//
599// Returns: tEplKernel = errorcode
600//
601//
602// State:
603//
604//---------------------------------------------------------------------------
605#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7 606tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
9d7164cf 607{
833dfbe7
GKH
608 tEplKernel Ret;
609 tEplSdoComCon *pSdoComCon;
610
611 Ret = kEplSuccessful;
612
613 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
614 Ret = kEplSdoComInvalidHandle;
615 goto Exit;
616 }
617 // get pointer to control structure
618 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
619
620 // $$$ d.k. abort a running transfer before closing the sequence layer
621
622 if (((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) !=
623 EPL_SDO_SEQ_INVALID_HDL)
624 && (pSdoComCon->m_SdoSeqConHdl != 0)) {
625 // close connection in lower layer
626 switch (pSdoComCon->m_SdoProtType) {
627 case kEplSdoTypeAsnd:
628 case kEplSdoTypeUdp:
629 {
630 Ret =
631 EplSdoAsySeqDelCon(pSdoComCon->
632 m_SdoSeqConHdl);
633 break;
634 }
635
636 case kEplSdoTypePdo:
637 case kEplSdoTypeAuto:
638 default:
639 {
640 Ret = kEplSdoComUnsupportedProt;
641 goto Exit;
642 }
643
644 } // end of switch(pSdoComCon->m_SdoProtType)
645 }
646
647 // clean controll structure
648 EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
649 Exit:
650 return Ret;
9d7164cf
DK
651}
652#endif
653//---------------------------------------------------------------------------
654//
655// Function: EplSdoComGetState
656//
657// Description: function returns the state fo the connection
658//
659//
660//
661// Parameters: SdoComConHdl_p = handle for the connection
662// pSdoComFinished_p = pointer to structur for sdo state
663//
664//
665// Returns: tEplKernel = errorcode
666//
667//
668// State:
669//
670//---------------------------------------------------------------------------
671#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7
GKH
672tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
673 tEplSdoComFinished * pSdoComFinished_p)
9d7164cf 674{
833dfbe7
GKH
675 tEplKernel Ret;
676 tEplSdoComCon *pSdoComCon;
677
678 Ret = kEplSuccessful;
679
680 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
681 Ret = kEplSdoComInvalidHandle;
682 goto Exit;
683 }
684 // get pointer to control structure
685 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
686
687 // check if handle ok
688 if (pSdoComCon->m_SdoSeqConHdl == 0) {
689 Ret = kEplSdoComInvalidHandle;
690 goto Exit;
691 }
692
693 pSdoComFinished_p->m_pUserArg = pSdoComCon->m_pUserArg;
694 pSdoComFinished_p->m_uiNodeId = pSdoComCon->m_uiNodeId;
695 pSdoComFinished_p->m_uiTargetIndex = pSdoComCon->m_uiTargetIndex;
696 pSdoComFinished_p->m_uiTargetSubIndex = pSdoComCon->m_uiTargetSubIndex;
697 pSdoComFinished_p->m_uiTransferredByte =
698 pSdoComCon->m_uiTransferredByte;
699 pSdoComFinished_p->m_dwAbortCode = pSdoComCon->m_dwLastAbortCode;
700 pSdoComFinished_p->m_SdoComConHdl = SdoComConHdl_p;
701 if (pSdoComCon->m_SdoServiceType == kEplSdoServiceWriteByIndex) {
702 pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeWrite;
703 } else {
704 pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeRead;
705 }
706
707 if (pSdoComCon->m_dwLastAbortCode != 0) { // sdo abort
708 pSdoComFinished_p->m_SdoComConState =
709 kEplSdoComTransferRxAborted;
710
711 // delete abort code
712 pSdoComCon->m_dwLastAbortCode = 0;
713
714 } else if ((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == EPL_SDO_SEQ_INVALID_HDL) { // check state
715 pSdoComFinished_p->m_SdoComConState =
716 kEplSdoComTransferLowerLayerAbort;
717 } else if (pSdoComCon->m_SdoComState == kEplSdoComStateClientWaitInit) {
718 // finished
719 pSdoComFinished_p->m_SdoComConState =
720 kEplSdoComTransferNotActive;
721 } else if (pSdoComCon->m_uiTransSize == 0) { // finished
722 pSdoComFinished_p->m_SdoComConState =
723 kEplSdoComTransferFinished;
724 }
725
726 Exit:
727 return Ret;
9d7164cf
DK
728
729}
730#endif
731//---------------------------------------------------------------------------
732//
733// Function: EplSdoComSdoAbort
734//
735// Description: function abort a sdo transfer
736//
737//
738//
739// Parameters: SdoComConHdl_p = handle for the connection
740// dwAbortCode_p = abort code
741//
742//
743// Returns: tEplKernel = errorcode
744//
745//
746// State:
747//
748//---------------------------------------------------------------------------
749#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
750tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
833dfbe7 751 DWORD dwAbortCode_p)
9d7164cf 752{
833dfbe7
GKH
753 tEplKernel Ret;
754 tEplSdoComCon *pSdoComCon;
755
756 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
757 Ret = kEplSdoComInvalidHandle;
758 goto Exit;
759 }
760 // get pointer to control structure of connection
761 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
762
763 // check if handle ok
764 if (pSdoComCon->m_SdoSeqConHdl == 0) {
765 Ret = kEplSdoComInvalidHandle;
766 goto Exit;
767 }
768 // save pointer to abort code
769 pSdoComCon->m_pData = (BYTE *) & dwAbortCode_p;
770
771 Ret = EplSdoComProcessIntern(SdoComConHdl_p,
772 kEplSdoComConEventAbort,
773 (tEplAsySdoCom *) NULL);
774
775 Exit:
776 return Ret;
9d7164cf
DK
777}
778#endif
779
780//=========================================================================//
781// //
782// P R I V A T E F U N C T I O N S //
783// //
784//=========================================================================//
785
786//---------------------------------------------------------------------------
787//
788// Function: EplSdoComReceiveCb
789//
790// Description: callback function for SDO Sequence Layer
791// -> indicates new data
792//
793//
794//
795// Parameters: SdoSeqConHdl_p = Handle for connection
796// pAsySdoCom_p = pointer to data
797// uiDataSize_p = size of data ($$$ not used yet, but it should)
798//
799//
800// Returns:
801//
802//
803// State:
804//
805//---------------------------------------------------------------------------
833dfbe7
GKH
806tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
807 tEplAsySdoCom * pAsySdoCom_p,
808 unsigned int uiDataSize_p)
9d7164cf 809{
833dfbe7 810 tEplKernel Ret;
9d7164cf 811
833dfbe7
GKH
812 // search connection internally
813 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
814 kEplSdoComConEventRec, pAsySdoCom_p);
9d7164cf 815
833dfbe7
GKH
816 EPL_DBGLVL_SDO_TRACE3
817 ("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n",
818 SdoSeqConHdl_p, (WORD) pAsySdoCom_p->m_le_abCommandData[0],
819 uiDataSize_p);
9d7164cf 820
833dfbe7 821 return Ret;
9d7164cf
DK
822}
823
824//---------------------------------------------------------------------------
825//
826// Function: EplSdoComConCb
827//
828// Description: callback function called by SDO Sequence Layer to inform
829// command layer about state change of connection
830//
831//
832//
833// Parameters: SdoSeqConHdl_p = Handle of the connection
834// AsySdoConState_p = Event of the connection
835//
836//
837// Returns: tEplKernel = Errorcode
838//
839//
840// State:
841//
842//---------------------------------------------------------------------------
833dfbe7
GKH
843tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
844 tEplAsySdoConState AsySdoConState_p)
9d7164cf 845{
833dfbe7
GKH
846 tEplKernel Ret;
847 tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst;
848
849 Ret = kEplSuccessful;
850
851 // check state
852 switch (AsySdoConState_p) {
853 case kAsySdoConStateConnected:
854 {
855 EPL_DBGLVL_SDO_TRACE0("Connection established\n");
856 SdoComConEvent = kEplSdoComConEventConEstablished;
857 // start transmission if needed
858 break;
859 }
860
861 case kAsySdoConStateInitError:
862 {
863 EPL_DBGLVL_SDO_TRACE0("Error during initialisation\n");
864 SdoComConEvent = kEplSdoComConEventInitError;
865 // inform app about error and close sequence layer handle
866 break;
867 }
868
869 case kAsySdoConStateConClosed:
870 {
871 EPL_DBGLVL_SDO_TRACE0("Connection closed\n");
872 SdoComConEvent = kEplSdoComConEventConClosed;
873 // close sequence layer handle
874 break;
875 }
876
877 case kAsySdoConStateAckReceived:
878 {
879 EPL_DBGLVL_SDO_TRACE0("Acknowlage received\n");
880 SdoComConEvent = kEplSdoComConEventAckReceived;
881 // continue transmission
882 break;
883 }
884
885 case kAsySdoConStateFrameSended:
886 {
887 EPL_DBGLVL_SDO_TRACE0("One Frame sent\n");
888 SdoComConEvent = kEplSdoComConEventFrameSended;
889 // to continue transmission
890 break;
891
892 }
893
894 case kAsySdoConStateTimeout:
895 {
896 EPL_DBGLVL_SDO_TRACE0("Timeout\n");
897 SdoComConEvent = kEplSdoComConEventTimeout;
898 // close sequence layer handle
899 break;
900
901 }
902 } // end of switch(AsySdoConState_p)
903
904 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
905 SdoComConEvent, (tEplAsySdoCom *) NULL);
906
907 return Ret;
9d7164cf
DK
908}
909
910//---------------------------------------------------------------------------
911//
912// Function: EplSdoComSearchConIntern
913//
914// Description: search a Sdo Sequence Layer connection handle in the
915// control structure of the Command Layer
916//
917// Parameters: SdoSeqConHdl_p = Handle to search
918// SdoComConEvent_p = event to process
919// pAsySdoCom_p = pointer to received frame
920//
921// Returns: tEplKernel
922//
923//
924// State:
925//
926//---------------------------------------------------------------------------
833dfbe7
GKH
927static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
928 tEplSdoComConEvent SdoComConEvent_p,
929 tEplAsySdoCom * pAsySdoCom_p)
9d7164cf 930{
833dfbe7
GKH
931 tEplKernel Ret;
932 tEplSdoComCon *pSdoComCon;
933 tEplSdoComConHdl HdlCount;
934 tEplSdoComConHdl HdlFree;
935
936 Ret = kEplSdoComNotResponsible;
937
938 // get pointer to first element of the array
939 pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
940 HdlCount = 0;
941 HdlFree = 0xFFFF;
942 while (HdlCount < EPL_MAX_SDO_COM_CON) {
943 if (pSdoComCon->m_SdoSeqConHdl == SdoSeqConHdl_p) { // matching command layer handle found
944 Ret = EplSdoComProcessIntern(HdlCount,
945 SdoComConEvent_p,
946 pAsySdoCom_p);
947 } else if ((pSdoComCon->m_SdoSeqConHdl == 0)
948 && (HdlFree == 0xFFFF)) {
949 HdlFree = HdlCount;
950 }
951
952 pSdoComCon++;
953 HdlCount++;
954 }
955
956 if (Ret == kEplSdoComNotResponsible) { // no responsible command layer handle found
957 if (HdlFree == 0xFFFF) { // no free handle
958 // delete connection immediately
959 // 2008/04/14 m.u./d.k. This connection actually does not exist.
960 // pSdoComCon is invalid.
961 // Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
962 Ret = kEplSdoComNoFreeHandle;
963 } else { // create new handle
964 HdlCount = HdlFree;
965 pSdoComCon = &SdoComInstance_g.m_SdoComCon[HdlCount];
966 pSdoComCon->m_SdoSeqConHdl = SdoSeqConHdl_p;
967 Ret = EplSdoComProcessIntern(HdlCount,
968 SdoComConEvent_p,
969 pAsySdoCom_p);
970 }
971 }
972
973 return Ret;
9d7164cf
DK
974
975}
976
977//---------------------------------------------------------------------------
978//
979// Function: EplSdoComProcessIntern
980//
981// Description: search a Sdo Sequence Layer connection handle in the
982// control structer of the Command Layer
983//
984//
985//
986// Parameters: SdoComCon_p = index of control structure of connection
987// SdoComConEvent_p = event to process
988// pAsySdoCom_p = pointer to received frame
989//
990// Returns: tEplKernel = errorcode
991//
992//
993// State:
994//
995//---------------------------------------------------------------------------
833dfbe7
GKH
996static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
997 tEplSdoComConEvent SdoComConEvent_p,
998 tEplAsySdoCom * pAsySdoCom_p)
9d7164cf 999{
833dfbe7
GKH
1000 tEplKernel Ret;
1001 tEplSdoComCon *pSdoComCon;
1002 BYTE bFlag;
9d7164cf
DK
1003
1004#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
833dfbe7
GKH
1005 DWORD dwAbortCode;
1006 unsigned int uiSize;
9d7164cf
DK
1007#endif
1008
1009#if defined(WIN32) || defined(_WIN32)
833dfbe7
GKH
1010 // enter critical section for process function
1011 EnterCriticalSection(SdoComInstance_g.m_pCriticalSection);
1012 EPL_DBGLVL_SDO_TRACE0
1013 ("\n\tEnterCiticalSection EplSdoComProcessIntern\n\n");
9d7164cf
DK
1014#endif
1015
833dfbe7 1016 Ret = kEplSuccessful;
9d7164cf 1017
833dfbe7
GKH
1018 // get pointer to control structure
1019 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
9d7164cf 1020
833dfbe7
GKH
1021 // process state maschine
1022 switch (pSdoComCon->m_SdoComState) {
1023 // idle state
1024 case kEplSdoComStateIdle:
1025 {
1026 // check events
1027 switch (SdoComConEvent_p) {
9d7164cf 1028#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7
GKH
1029 // init con for client
1030 case kEplSdoComConEventInitCon:
1031 {
1032
1033 // call of the init function already
1034 // processed in EplSdoComDefineCon()
1035 // only change state to kEplSdoComStateClientWaitInit
1036 pSdoComCon->m_SdoComState =
1037 kEplSdoComStateClientWaitInit;
1038 break;
1039 }
9d7164cf
DK
1040#endif
1041
833dfbe7
GKH
1042 // int con for server
1043 case kEplSdoComConEventRec:
1044 {
9d7164cf 1045#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
833dfbe7
GKH
1046 // check if init of an transfer and no SDO abort
1047 if ((pAsySdoCom_p->m_le_bFlags & 0x80) == 0) { // SDO request
1048 if ((pAsySdoCom_p->m_le_bFlags & 0x40) == 0) { // no SDO abort
1049 // save tansaction id
1050 pSdoComCon->
1051 m_bTransactionId =
1052 AmiGetByteFromLe
1053 (&pAsySdoCom_p->
1054 m_le_bTransactionId);
1055 // check command
1056 switch (pAsySdoCom_p->
1057 m_le_bCommandId)
1058 {
1059 case kEplSdoServiceNIL:
1060 { // simply acknowlegde NIL command on sequence layer
1061
1062 Ret =
1063 EplSdoAsySeqSendData
1064 (pSdoComCon->
1065 m_SdoSeqConHdl,
1066 0,
1067 (tEplFrame
1068 *)
1069 NULL);
1070
1071 break;
1072 }
1073
1074 case kEplSdoServiceReadByIndex:
1075 { // read by index
1076
1077 // search entry an start transfer
1078 EplSdoComServerInitReadByIndex
1079 (pSdoComCon,
1080 pAsySdoCom_p);
1081 // check next state
1082 if (pSdoComCon->m_uiTransSize == 0) { // ready -> stay idle
1083 pSdoComCon->
1084 m_SdoComState
1085 =
1086 kEplSdoComStateIdle;
1087 // reset abort code
1088 pSdoComCon->
1089 m_dwLastAbortCode
1090 =
1091 0;
1092 } else { // segmented transfer
1093 pSdoComCon->
1094 m_SdoComState
1095 =
1096 kEplSdoComStateServerSegmTrans;
1097 }
1098
1099 break;
1100 }
1101
1102 case kEplSdoServiceWriteByIndex:
1103 {
1104
1105 // search entry an start write
1106 EplSdoComServerInitWriteByIndex
1107 (pSdoComCon,
1108 pAsySdoCom_p);
1109 // check next state
1110 if (pSdoComCon->m_uiTransSize == 0) { // already -> stay idle
1111 pSdoComCon->
1112 m_SdoComState
1113 =
1114 kEplSdoComStateIdle;
1115 // reset abort code
1116 pSdoComCon->
1117 m_dwLastAbortCode
1118 =
1119 0;
1120 } else { // segmented transfer
1121 pSdoComCon->
1122 m_SdoComState
1123 =
1124 kEplSdoComStateServerSegmTrans;
1125 }
1126
1127 break;
1128 }
1129
1130 default:
1131 {
1132 // unsupported command
1133 // -> abort senden
1134 dwAbortCode
1135 =
1136 EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER;
1137 // send abort
1138 pSdoComCon->
1139 m_pData
1140 =
1141 (BYTE
1142 *)
1143 &
1144 dwAbortCode;
1145 Ret =
1146 EplSdoComServerSendFrameIntern
1147 (pSdoComCon,
1148 0,
1149 0,
1150 kEplSdoComSendTypeAbort);
1151
1152 }
1153
1154 } // end of switch(pAsySdoCom_p->m_le_bCommandId)
1155 }
1156 } else { // this command layer handle is not responsible
1157 // (wrong direction or wrong transaction ID)
1158 Ret = kEplSdoComNotResponsible;
1159 goto Exit;
1160 }
9d7164cf
DK
1161#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1162
833dfbe7
GKH
1163 break;
1164 }
1165
1166 // connection closed
1167 case kEplSdoComConEventInitError:
1168 case kEplSdoComConEventTimeout:
1169 case kEplSdoComConEventConClosed:
1170 {
1171 Ret =
1172 EplSdoAsySeqDelCon(pSdoComCon->
1173 m_SdoSeqConHdl);
1174 // clean control structure
1175 EPL_MEMSET(pSdoComCon, 0x00,
1176 sizeof(tEplSdoComCon));
1177 break;
1178 }
1179
1180 default:
1181 // d.k. do nothing
1182 break;
1183 } // end of switch(SdoComConEvent_p)
1184 break;
1185 }
9d7164cf
DK
1186
1187#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
833dfbe7
GKH
1188 //-------------------------------------------------------------------------
1189 // SDO Server part
1190 // segmented transfer
1191 case kEplSdoComStateServerSegmTrans:
1192 {
1193 // check events
1194 switch (SdoComConEvent_p) {
1195 // send next frame
1196 case kEplSdoComConEventAckReceived:
1197 case kEplSdoComConEventFrameSended:
1198 {
1199 // check if it is a read
1200 if (pSdoComCon->m_SdoServiceType ==
1201 kEplSdoServiceReadByIndex) {
1202 // send next frame
1203 EplSdoComServerSendFrameIntern
1204 (pSdoComCon, 0, 0,
1205 kEplSdoComSendTypeRes);
1206 // if all send -> back to idle
1207 if (pSdoComCon->m_uiTransSize == 0) { // back to idle
1208 pSdoComCon->
1209 m_SdoComState =
1210 kEplSdoComStateIdle;
1211 // reset abort code
1212 pSdoComCon->
1213 m_dwLastAbortCode =
1214 0;
1215 }
1216
1217 }
1218 break;
1219 }
1220
1221 // process next frame
1222 case kEplSdoComConEventRec:
1223 {
1224 // check if the frame is a SDO response and has the right transaction ID
1225 bFlag =
1226 AmiGetByteFromLe(&pAsySdoCom_p->
1227 m_le_bFlags);
1228 if (((bFlag & 0x80) != 0)
1229 &&
1230 (AmiGetByteFromLe
1231 (&pAsySdoCom_p->
1232 m_le_bTransactionId) ==
1233 pSdoComCon->m_bTransactionId)) {
1234 // check if it is a abort
1235 if ((bFlag & 0x40) != 0) { // SDO abort
1236 // clear control structure
1237 pSdoComCon->
1238 m_uiTransSize = 0;
1239 pSdoComCon->
1240 m_uiTransferredByte
1241 = 0;
1242 // change state
1243 pSdoComCon->
1244 m_SdoComState =
1245 kEplSdoComStateIdle;
1246 // reset abort code
1247 pSdoComCon->
1248 m_dwLastAbortCode =
1249 0;
1250 // d.k.: do not execute anything further on this command
1251 break;
1252 }
1253 // check if it is a write
1254 if (pSdoComCon->
1255 m_SdoServiceType ==
1256 kEplSdoServiceWriteByIndex)
1257 {
1258 // write data to OD
1259 uiSize =
1260 AmiGetWordFromLe
1261 (&pAsySdoCom_p->
1262 m_le_wSegmentSize);
1263 if (pSdoComCon->
1264 m_dwLastAbortCode ==
1265 0) {
1266 EPL_MEMCPY
1267 (pSdoComCon->
1268 m_pData,
1269 &pAsySdoCom_p->
1270 m_le_abCommandData
1271 [0],
1272 uiSize);
1273 }
1274 // update counter
1275 pSdoComCon->
1276 m_uiTransferredByte
1277 += uiSize;
1278 pSdoComCon->
1279 m_uiTransSize -=
1280 uiSize;
1281
1282 // update pointer
1283 if (pSdoComCon->
1284 m_dwLastAbortCode ==
1285 0) {
1286 ( /*(BYTE*) */
1287 pSdoComCon->
1288 m_pData) +=
1289 uiSize;
1290 }
1291 // check end of transfer
1292 if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x30) { // transfer ready
1293 pSdoComCon->
1294 m_uiTransSize
1295 = 0;
1296
1297 if (pSdoComCon->
1298 m_dwLastAbortCode
1299 == 0) {
1300 // send response
1301 // send next frame
1302 EplSdoComServerSendFrameIntern
1303 (pSdoComCon,
1304 0,
1305 0,
1306 kEplSdoComSendTypeRes);
1307 // if all send -> back to idle
1308 if (pSdoComCon->m_uiTransSize == 0) { // back to idle
1309 pSdoComCon->
1310 m_SdoComState
1311 =
1312 kEplSdoComStateIdle;
1313 // reset abort code
1314 pSdoComCon->
1315 m_dwLastAbortCode
1316 =
1317 0;
1318 }
1319 } else { // send dabort code
1320 // send abort
1321 pSdoComCon->
1322 m_pData
1323 =
1324 (BYTE
1325 *)
1326 &
1327 pSdoComCon->
1328 m_dwLastAbortCode;
1329 Ret =
1330 EplSdoComServerSendFrameIntern
1331 (pSdoComCon,
1332 0,
1333 0,
1334 kEplSdoComSendTypeAbort);
1335
1336 // reset abort code
1337 pSdoComCon->
1338 m_dwLastAbortCode
1339 = 0;
1340
1341 }
1342 } else {
1343 // send acknowledge without any Command layer data
1344 Ret =
1345 EplSdoAsySeqSendData
1346 (pSdoComCon->
1347 m_SdoSeqConHdl,
1348 0,
1349 (tEplFrame
1350 *) NULL);
1351 }
1352 }
1353 } else { // this command layer handle is not responsible
1354 // (wrong direction or wrong transaction ID)
1355 Ret = kEplSdoComNotResponsible;
1356 goto Exit;
1357 }
1358 break;
1359 }
1360
1361 // connection closed
1362 case kEplSdoComConEventInitError:
1363 case kEplSdoComConEventTimeout:
1364 case kEplSdoComConEventConClosed:
1365 {
1366 Ret =
1367 EplSdoAsySeqDelCon(pSdoComCon->
1368 m_SdoSeqConHdl);
1369 // clean control structure
1370 EPL_MEMSET(pSdoComCon, 0x00,
1371 sizeof(tEplSdoComCon));
1372 break;
1373 }
1374
1375 default:
1376 // d.k. do nothing
1377 break;
1378 } // end of switch(SdoComConEvent_p)
1379
1380 break;
1381 }
9d7164cf
DK
1382#endif // endif of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1383
9d7164cf 1384#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7
GKH
1385 //-------------------------------------------------------------------------
1386 // SDO Client part
1387 // wait for finish of establishing connection
1388 case kEplSdoComStateClientWaitInit:
1389 {
1390
1391 // if connection handle is invalid reinit connection
1392 // d.k.: this will be done only on new events (i.e. InitTransfer)
1393 if ((pSdoComCon->
1394 m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) ==
1395 EPL_SDO_SEQ_INVALID_HDL) {
1396 // check kind of connection to reinit
1397 // check protocol
1398 switch (pSdoComCon->m_SdoProtType) {
1399 // udp
1400 case kEplSdoTypeUdp:
1401 {
1402 // call connection int function of lower layer
1403 Ret =
1404 EplSdoAsySeqInitCon
1405 (&pSdoComCon->
1406 m_SdoSeqConHdl,
1407 pSdoComCon->m_uiNodeId,
1408 kEplSdoTypeUdp);
1409 if (Ret != kEplSuccessful) {
1410 goto Exit;
1411 }
1412 break;
1413 }
1414
1415 // Asend -> not supported
1416 case kEplSdoTypeAsnd:
1417 {
1418 // call connection int function of lower layer
1419 Ret =
1420 EplSdoAsySeqInitCon
1421 (&pSdoComCon->
1422 m_SdoSeqConHdl,
1423 pSdoComCon->m_uiNodeId,
1424 kEplSdoTypeAsnd);
1425 if (Ret != kEplSuccessful) {
1426 goto Exit;
1427 }
1428 break;
1429 }
1430
1431 // Pdo -> not supported
1432 case kEplSdoTypePdo:
1433 default:
1434 {
1435 Ret = kEplSdoComUnsupportedProt;
1436 goto Exit;
1437 }
1438 } // end of switch(m_ProtType_p)
1439 // d.k.: reset transaction ID, because new sequence layer connection was initialized
1440 // $$$ d.k. is this really necessary?
1441 //pSdoComCon->m_bTransactionId = 0;
1442 }
1443 // check events
1444 switch (SdoComConEvent_p) {
1445 // connection established
1446 case kEplSdoComConEventConEstablished:
1447 {
1448 //send first frame if needed
1449 if ((pSdoComCon->m_uiTransSize > 0)
1450 && (pSdoComCon->m_uiTargetIndex != 0)) { // start SDO transfer
1451 Ret =
1452 EplSdoComClientSend
1453 (pSdoComCon);
1454 if (Ret != kEplSuccessful) {
1455 goto Exit;
1456 }
1457 // check if segemted transfer
1458 if (pSdoComCon->
1459 m_SdoTransType ==
1460 kEplSdoTransSegmented) {
1461 pSdoComCon->
1462 m_SdoComState =
1463 kEplSdoComStateClientSegmTrans;
1464 goto Exit;
1465 }
1466 }
1467 // goto state kEplSdoComStateClientConnected
1468 pSdoComCon->m_SdoComState =
1469 kEplSdoComStateClientConnected;
1470 goto Exit;
1471 }
1472
1473 case kEplSdoComConEventSendFirst:
1474 {
1475 // infos for transfer already saved by function EplSdoComInitTransferByIndex
1476 break;
1477 }
1478
1479 case kEplSdoComConEventConClosed:
1480 case kEplSdoComConEventInitError:
1481 case kEplSdoComConEventTimeout:
1482 {
1483 // close sequence layer handle
1484 Ret =
1485 EplSdoAsySeqDelCon(pSdoComCon->
1486 m_SdoSeqConHdl);
1487 pSdoComCon->m_SdoSeqConHdl |=
1488 EPL_SDO_SEQ_INVALID_HDL;
1489 // call callback function
1490 if (SdoComConEvent_p ==
1491 kEplSdoComConEventTimeout) {
1492 pSdoComCon->m_dwLastAbortCode =
1493 EPL_SDOAC_TIME_OUT;
1494 } else {
1495 pSdoComCon->m_dwLastAbortCode =
1496 0;
1497 }
1498 Ret =
1499 EplSdoComTransferFinished
1500 (SdoComCon_p, pSdoComCon,
1501 kEplSdoComTransferLowerLayerAbort);
1502 // d.k.: do not clean control structure
1503 break;
1504 }
1505
1506 default:
1507 // d.k. do nothing
1508 break;
1509
1510 } // end of switch(SdoComConEvent_p)
1511 break;
1512 }
1513
1514 // connected
1515 case kEplSdoComStateClientConnected:
1516 {
1517 // check events
1518 switch (SdoComConEvent_p) {
1519 // send a frame
1520 case kEplSdoComConEventSendFirst:
1521 case kEplSdoComConEventAckReceived:
1522 case kEplSdoComConEventFrameSended:
1523 {
1524 Ret = EplSdoComClientSend(pSdoComCon);
1525 if (Ret != kEplSuccessful) {
1526 goto Exit;
1527 }
1528 // check if read transfer finished
1529 if ((pSdoComCon->m_uiTransSize == 0)
1530 && (pSdoComCon->
1531 m_uiTransferredByte != 0)
1532 && (pSdoComCon->m_SdoServiceType ==
1533 kEplSdoServiceReadByIndex)) {
1534 // inc transaction id
1535 pSdoComCon->m_bTransactionId++;
1536 // call callback of application
1537 pSdoComCon->m_dwLastAbortCode =
1538 0;
1539 Ret =
1540 EplSdoComTransferFinished
1541 (SdoComCon_p, pSdoComCon,
1542 kEplSdoComTransferFinished);
1543
1544 goto Exit;
1545 }
1546 // check if segemted transfer
1547 if (pSdoComCon->m_SdoTransType ==
1548 kEplSdoTransSegmented) {
1549 pSdoComCon->m_SdoComState =
1550 kEplSdoComStateClientSegmTrans;
1551 goto Exit;
1552 }
1553 break;
1554 }
1555
1556 // frame received
1557 case kEplSdoComConEventRec:
1558 {
1559 // check if the frame is a SDO response and has the right transaction ID
1560 bFlag =
1561 AmiGetByteFromLe(&pAsySdoCom_p->
1562 m_le_bFlags);
1563 if (((bFlag & 0x80) != 0)
1564 &&
1565 (AmiGetByteFromLe
1566 (&pAsySdoCom_p->
1567 m_le_bTransactionId) ==
1568 pSdoComCon->m_bTransactionId)) {
1569 // check if abort or not
1570 if ((bFlag & 0x40) != 0) {
1571 // send acknowledge without any Command layer data
1572 Ret =
1573 EplSdoAsySeqSendData
1574 (pSdoComCon->
1575 m_SdoSeqConHdl, 0,
1576 (tEplFrame *)
1577 NULL);
1578 // inc transaction id
1579 pSdoComCon->
1580 m_bTransactionId++;
1581 // save abort code
1582 pSdoComCon->
1583 m_dwLastAbortCode =
1584 AmiGetDwordFromLe
1585 (&pAsySdoCom_p->
1586 m_le_abCommandData
1587 [0]);
1588 // call callback of application
1589 Ret =
1590 EplSdoComTransferFinished
1591 (SdoComCon_p,
1592 pSdoComCon,
1593 kEplSdoComTransferRxAborted);
1594
1595 goto Exit;
1596 } else { // normal frame received
1597 // check frame
1598 Ret =
1599 EplSdoComClientProcessFrame
1600 (SdoComCon_p,
1601 pAsySdoCom_p);
1602
1603 // check if transfer ready
1604 if (pSdoComCon->
1605 m_uiTransSize ==
1606 0) {
1607 // send acknowledge without any Command layer data
1608 Ret =
1609 EplSdoAsySeqSendData
1610 (pSdoComCon->
1611 m_SdoSeqConHdl,
1612 0,
1613 (tEplFrame
1614 *) NULL);
1615 // inc transaction id
1616 pSdoComCon->
1617 m_bTransactionId++;
1618 // call callback of application
1619 pSdoComCon->
1620 m_dwLastAbortCode
1621 = 0;
1622 Ret =
1623 EplSdoComTransferFinished
1624 (SdoComCon_p,
1625 pSdoComCon,
1626 kEplSdoComTransferFinished);
1627
1628 goto Exit;
1629 }
1630
1631 }
1632 } else { // this command layer handle is not responsible
1633 // (wrong direction or wrong transaction ID)
1634 Ret = kEplSdoComNotResponsible;
1635 goto Exit;
1636 }
1637 break;
1638 }
1639
1640 // connection closed event go back to kEplSdoComStateClientWaitInit
1641 case kEplSdoComConEventConClosed:
1642 { // connection closed by communication partner
1643 // close sequence layer handle
1644 Ret =
1645 EplSdoAsySeqDelCon(pSdoComCon->
1646 m_SdoSeqConHdl);
1647 // set handle to invalid and enter kEplSdoComStateClientWaitInit
1648 pSdoComCon->m_SdoSeqConHdl |=
1649 EPL_SDO_SEQ_INVALID_HDL;
1650 // change state
1651 pSdoComCon->m_SdoComState =
1652 kEplSdoComStateClientWaitInit;
1653
1654 // call callback of application
1655 pSdoComCon->m_dwLastAbortCode = 0;
1656 Ret =
1657 EplSdoComTransferFinished
1658 (SdoComCon_p, pSdoComCon,
1659 kEplSdoComTransferLowerLayerAbort);
1660
1661 goto Exit;
1662
1663 break;
1664 }
1665
1666 // abort to send from higher layer
1667 case kEplSdoComConEventAbort:
1668 {
1669 EplSdoComClientSendAbort(pSdoComCon,
1670 *((DWORD *)
1671 pSdoComCon->
1672 m_pData));
1673
1674 // inc transaction id
1675 pSdoComCon->m_bTransactionId++;
1676 // call callback of application
1677 pSdoComCon->m_dwLastAbortCode =
1678 *((DWORD *) pSdoComCon->m_pData);
1679 Ret =
1680 EplSdoComTransferFinished
1681 (SdoComCon_p, pSdoComCon,
1682 kEplSdoComTransferTxAborted);
1683
1684 break;
1685 }
1686
1687 case kEplSdoComConEventInitError:
1688 case kEplSdoComConEventTimeout:
1689 {
1690 // close sequence layer handle
1691 Ret =
1692 EplSdoAsySeqDelCon(pSdoComCon->
1693 m_SdoSeqConHdl);
1694 pSdoComCon->m_SdoSeqConHdl |=
1695 EPL_SDO_SEQ_INVALID_HDL;
1696 // change state
1697 pSdoComCon->m_SdoComState =
1698 kEplSdoComStateClientWaitInit;
1699 // call callback of application
1700 pSdoComCon->m_dwLastAbortCode =
1701 EPL_SDOAC_TIME_OUT;
1702 Ret =
1703 EplSdoComTransferFinished
1704 (SdoComCon_p, pSdoComCon,
1705 kEplSdoComTransferLowerLayerAbort);
1706
1707 }
1708
1709 default:
1710 // d.k. do nothing
1711 break;
1712
1713 } // end of switch(SdoComConEvent_p)
1714
1715 break;
1716 }
1717
1718 // process segmented transfer
1719 case kEplSdoComStateClientSegmTrans:
1720 {
1721 // check events
1722 switch (SdoComConEvent_p) {
1723 // sned a frame
1724 case kEplSdoComConEventSendFirst:
1725 case kEplSdoComConEventAckReceived:
1726 case kEplSdoComConEventFrameSended:
1727 {
1728 Ret = EplSdoComClientSend(pSdoComCon);
1729 if (Ret != kEplSuccessful) {
1730 goto Exit;
1731 }
1732 // check if read transfer finished
1733 if ((pSdoComCon->m_uiTransSize == 0)
1734 && (pSdoComCon->m_SdoServiceType ==
1735 kEplSdoServiceReadByIndex)) {
1736 // inc transaction id
1737 pSdoComCon->m_bTransactionId++;
1738 // change state
1739 pSdoComCon->m_SdoComState =
1740 kEplSdoComStateClientConnected;
1741 // call callback of application
1742 pSdoComCon->m_dwLastAbortCode =
1743 0;
1744 Ret =
1745 EplSdoComTransferFinished
1746 (SdoComCon_p, pSdoComCon,
1747 kEplSdoComTransferFinished);
1748
1749 goto Exit;
1750 }
1751
1752 break;
1753 }
1754
1755 // frame received
1756 case kEplSdoComConEventRec:
1757 {
1758 // check if the frame is a response
1759 bFlag =
1760 AmiGetByteFromLe(&pAsySdoCom_p->
1761 m_le_bFlags);
1762 if (((bFlag & 0x80) != 0)
1763 &&
1764 (AmiGetByteFromLe
1765 (&pAsySdoCom_p->
1766 m_le_bTransactionId) ==
1767 pSdoComCon->m_bTransactionId)) {
1768 // check if abort or not
1769 if ((bFlag & 0x40) != 0) {
1770 // send acknowledge without any Command layer data
1771 Ret =
1772 EplSdoAsySeqSendData
1773 (pSdoComCon->
1774 m_SdoSeqConHdl, 0,
1775 (tEplFrame *)
1776 NULL);
1777 // inc transaction id
1778 pSdoComCon->
1779 m_bTransactionId++;
1780 // change state
1781 pSdoComCon->
1782 m_SdoComState =
1783 kEplSdoComStateClientConnected;
1784 // save abort code
1785 pSdoComCon->
1786 m_dwLastAbortCode =
1787 AmiGetDwordFromLe
1788 (&pAsySdoCom_p->
1789 m_le_abCommandData
1790 [0]);
1791 // call callback of application
1792 Ret =
1793 EplSdoComTransferFinished
1794 (SdoComCon_p,
1795 pSdoComCon,
1796 kEplSdoComTransferRxAborted);
1797
1798 goto Exit;
1799 } else { // normal frame received
1800 // check frame
1801 Ret =
1802 EplSdoComClientProcessFrame
1803 (SdoComCon_p,
1804 pAsySdoCom_p);
1805
1806 // check if transfer ready
1807 if (pSdoComCon->
1808 m_uiTransSize ==
1809 0) {
1810 // send acknowledge without any Command layer data
1811 Ret =
1812 EplSdoAsySeqSendData
1813 (pSdoComCon->
1814 m_SdoSeqConHdl,
1815 0,
1816 (tEplFrame
1817 *) NULL);
1818 // inc transaction id
1819 pSdoComCon->
1820 m_bTransactionId++;
1821 // change state
1822 pSdoComCon->
1823 m_SdoComState
1824 =
1825 kEplSdoComStateClientConnected;
1826 // call callback of application
1827 pSdoComCon->
1828 m_dwLastAbortCode
1829 = 0;
1830 Ret =
1831 EplSdoComTransferFinished
1832 (SdoComCon_p,
1833 pSdoComCon,
1834 kEplSdoComTransferFinished);
1835
1836 }
1837
1838 }
1839 }
1840 break;
1841 }
1842
1843 // connection closed event go back to kEplSdoComStateClientWaitInit
1844 case kEplSdoComConEventConClosed:
1845 { // connection closed by communication partner
1846 // close sequence layer handle
1847 Ret =
1848 EplSdoAsySeqDelCon(pSdoComCon->
1849 m_SdoSeqConHdl);
1850 // set handle to invalid and enter kEplSdoComStateClientWaitInit
1851 pSdoComCon->m_SdoSeqConHdl |=
1852 EPL_SDO_SEQ_INVALID_HDL;
1853 // change state
1854 pSdoComCon->m_SdoComState =
1855 kEplSdoComStateClientWaitInit;
1856 // inc transaction id
1857 pSdoComCon->m_bTransactionId++;
1858 // call callback of application
1859 pSdoComCon->m_dwLastAbortCode = 0;
1860 Ret =
1861 EplSdoComTransferFinished
1862 (SdoComCon_p, pSdoComCon,
1863 kEplSdoComTransferFinished);
1864
1865 break;
1866 }
1867
1868 // abort to send from higher layer
1869 case kEplSdoComConEventAbort:
1870 {
1871 EplSdoComClientSendAbort(pSdoComCon,
1872 *((DWORD *)
1873 pSdoComCon->
1874 m_pData));
1875
1876 // inc transaction id
1877 pSdoComCon->m_bTransactionId++;
1878 // change state
1879 pSdoComCon->m_SdoComState =
1880 kEplSdoComStateClientConnected;
1881 // call callback of application
1882 pSdoComCon->m_dwLastAbortCode =
1883 *((DWORD *) pSdoComCon->m_pData);
1884 Ret =
1885 EplSdoComTransferFinished
1886 (SdoComCon_p, pSdoComCon,
1887 kEplSdoComTransferTxAborted);
1888
1889 break;
1890 }
1891
1892 case kEplSdoComConEventInitError:
1893 case kEplSdoComConEventTimeout:
1894 {
1895 // close sequence layer handle
1896 Ret =
1897 EplSdoAsySeqDelCon(pSdoComCon->
1898 m_SdoSeqConHdl);
1899 pSdoComCon->m_SdoSeqConHdl |=
1900 EPL_SDO_SEQ_INVALID_HDL;
1901 // change state
1902 pSdoComCon->m_SdoComState =
1903 kEplSdoComStateClientWaitInit;
1904 // call callback of application
1905 pSdoComCon->m_dwLastAbortCode =
1906 EPL_SDOAC_TIME_OUT;
1907 Ret =
1908 EplSdoComTransferFinished
1909 (SdoComCon_p, pSdoComCon,
1910 kEplSdoComTransferLowerLayerAbort);
1911
1912 }
1913
1914 default:
1915 // d.k. do nothing
1916 break;
1917
1918 } // end of switch(SdoComConEvent_p)
1919
1920 break;
1921 }
9d7164cf
DK
1922#endif // endo of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1923
833dfbe7 1924 } // end of switch(pSdoComCon->m_SdoComState)
9d7164cf
DK
1925
1926#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7 1927 Exit:
9d7164cf
DK
1928#endif
1929
1930#if defined(WIN32) || defined(_WIN32)
833dfbe7
GKH
1931 // leave critical section for process function
1932 EPL_DBGLVL_SDO_TRACE0
1933 ("\n\tLeaveCriticalSection EplSdoComProcessIntern\n\n");
1934 LeaveCriticalSection(SdoComInstance_g.m_pCriticalSection);
9d7164cf
DK
1935
1936#endif
1937
833dfbe7 1938 return Ret;
9d7164cf
DK
1939
1940}
1941
9d7164cf
DK
1942//---------------------------------------------------------------------------
1943//
1944// Function: EplSdoComServerInitReadByIndex
1945//
1946// Description: function start the processing of an read by index command
1947//
1948//
1949//
1950// Parameters: pSdoComCon_p = pointer to control structure of connection
1951// pAsySdoCom_p = pointer to received frame
1952//
1953// Returns: tEplKernel = errorcode
1954//
1955//
1956// State:
1957//
1958//---------------------------------------------------------------------------
1959#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
833dfbe7
GKH
1960static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
1961 tEplAsySdoCom * pAsySdoCom_p)
9d7164cf 1962{
833dfbe7
GKH
1963 tEplKernel Ret;
1964 unsigned int uiIndex;
1965 unsigned int uiSubindex;
1966 tEplObdSize EntrySize;
1967 tEplObdAccess AccessType;
1968 DWORD dwAbortCode;
9d7164cf 1969
833dfbe7 1970 dwAbortCode = 0;
9d7164cf 1971
833dfbe7
GKH
1972 // a init of a read could not be a segmented transfer
1973 // -> no variable part of header
9d7164cf 1974
833dfbe7
GKH
1975 // get index and subindex
1976 uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
1977 uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
9d7164cf 1978
833dfbe7
GKH
1979 // check accesstype of entry
1980 // existens of entry
9d7164cf 1981//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
833dfbe7 1982 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
9d7164cf
DK
1983/*#else
1984 Ret = kEplObdSubindexNotExist;
1985 AccessType = 0;
1986#endif*/
833dfbe7
GKH
1987 if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist
1988 dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
1989 // send abort
1990 pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
1991 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
1992 uiIndex,
1993 uiSubindex,
1994 kEplSdoComSendTypeAbort);
1995 goto Exit;
1996 } else if (Ret != kEplSuccessful) { // entry doesn't exist
1997 dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
1998 // send abort
1999 pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
2000 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2001 uiIndex,
2002 uiSubindex,
2003 kEplSdoComSendTypeAbort);
2004 goto Exit;
2005 }
2006 // compare accesstype must be read or const
2007 if (((AccessType & kEplObdAccRead) == 0)
2008 && ((AccessType & kEplObdAccConst) == 0)) {
2009
2010 if ((AccessType & kEplObdAccWrite) != 0) {
2011 // entry read a write only object
2012 dwAbortCode = EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ;
2013 } else {
2014 dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
2015 }
2016 // send abort
2017 pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
2018 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2019 uiIndex,
2020 uiSubindex,
2021 kEplSdoComSendTypeAbort);
2022 goto Exit;
2023 }
2024 // save service
2025 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceReadByIndex;
2026
2027 // get size of object to see iof segmented or expedited transfer
9d7164cf 2028//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
833dfbe7 2029 EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
9d7164cf
DK
2030/*#else
2031 EntrySize = 0;
2032#endif*/
833dfbe7
GKH
2033 if (EntrySize > EPL_SDO_MAX_PAYLOAD) { // segmented transfer
2034 pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
2035 // get pointer to object-entry data
9d7164cf 2036//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
833dfbe7
GKH
2037 pSdoComCon_p->m_pData =
2038 EplObduGetObjectDataPtr(uiIndex, uiSubindex);
9d7164cf 2039//#endif
833dfbe7
GKH
2040 } else { // expedited transfer
2041 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
2042 }
2043
2044 pSdoComCon_p->m_uiTransSize = EntrySize;
2045 pSdoComCon_p->m_uiTransferredByte = 0;
2046
2047 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2048 uiIndex,
2049 uiSubindex, kEplSdoComSendTypeRes);
2050 if (Ret != kEplSuccessful) {
2051 // error -> abort
2052 dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
2053 // send abort
2054 pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
2055 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2056 uiIndex,
2057 uiSubindex,
2058 kEplSdoComSendTypeAbort);
2059 goto Exit;
2060 }
2061
2062 Exit:
2063 return Ret;
9d7164cf
DK
2064}
2065#endif
2066
2067//---------------------------------------------------------------------------
2068//
2069// Function: EplSdoComServerSendFrameIntern();
2070//
2071// Description: function creats and send a frame for server
2072//
2073//
2074//
2075// Parameters: pSdoComCon_p = pointer to control structure of connection
2076// uiIndex_p = index to send if expedited transfer else 0
2077// uiSubIndex_p = subindex to send if expedited transfer else 0
2078// SendType_p = to of frame to send
2079//
2080// Returns: tEplKernel = errorcode
2081//
2082//
2083// State:
2084//
2085//---------------------------------------------------------------------------
2086#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
833dfbe7
GKH
2087static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
2088 unsigned int uiIndex_p,
2089 unsigned int uiSubIndex_p,
2090 tEplSdoComSendType SendType_p)
9d7164cf 2091{
833dfbe7
GKH
2092 tEplKernel Ret;
2093 BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
2094 tEplFrame *pFrame;
2095 tEplAsySdoCom *pCommandFrame;
2096 unsigned int uiSizeOfFrame;
2097 BYTE bFlag;
2098
2099 Ret = kEplSuccessful;
2100
2101 pFrame = (tEplFrame *) & abFrame[0];
2102
2103 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
2104
2105 // build generic part of frame
2106 // get pointer to command layerpart of frame
2107 pCommandFrame =
2108 &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
2109 m_le_abSdoSeqPayload;
2110 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
2111 pSdoComCon_p->m_SdoServiceType);
2112 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
2113 pSdoComCon_p->m_bTransactionId);
2114
2115 // set size to header size
2116 uiSizeOfFrame = 8;
2117
2118 // check SendType
2119 switch (SendType_p) {
2120 // requestframe to send
2121 case kEplSdoComSendTypeReq:
2122 {
2123 // nothing to do for server
2124 //-> error
2125 Ret = kEplSdoComInvalidSendType;
2126 break;
2127 }
2128
2129 // response without data to send
2130 case kEplSdoComSendTypeAckRes:
2131 {
2132 // set response flag
2133 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, 0x80);
2134
2135 // send frame
2136 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2137 uiSizeOfFrame, pFrame);
2138
2139 break;
2140 }
2141
2142 // responsframe to send
2143 case kEplSdoComSendTypeRes:
2144 {
2145 // set response flag
2146 bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags);
2147 bFlag |= 0x80;
2148 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2149
2150 // check type of resonse
2151 if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) { // Expedited transfer
2152 // copy data in frame
9d7164cf 2153//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
833dfbe7
GKH
2154 Ret = EplObduReadEntryToLe(uiIndex_p,
2155 uiSubIndex_p,
2156 &pCommandFrame->
2157 m_le_abCommandData
2158 [0],
2159 (tEplObdSize *) &
2160 pSdoComCon_p->
2161 m_uiTransSize);
2162 if (Ret != kEplSuccessful) {
2163 goto Exit;
2164 }
9d7164cf
DK
2165//#endif
2166
833dfbe7
GKH
2167 // set size of frame
2168 AmiSetWordToLe(&pCommandFrame->
2169 m_le_wSegmentSize,
2170 (WORD) pSdoComCon_p->
2171 m_uiTransSize);
2172
2173 // correct byte-counter
2174 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2175 pSdoComCon_p->m_uiTransferredByte +=
2176 pSdoComCon_p->m_uiTransSize;
2177 pSdoComCon_p->m_uiTransSize = 0;
2178
2179 // send frame
2180 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2181 Ret =
2182 EplSdoAsySeqSendData(pSdoComCon_p->
2183 m_SdoSeqConHdl,
2184 uiSizeOfFrame, pFrame);
2185 } else if (pSdoComCon_p->m_SdoTransType == kEplSdoTransSegmented) { // segmented transfer
2186 // distinguish between init, segment and complete
2187 if (pSdoComCon_p->m_uiTransferredByte == 0) { // init
2188 // set init flag
2189 bFlag =
2190 AmiGetByteFromLe(&pCommandFrame->
2191 m_le_bFlags);
2192 bFlag |= 0x10;
2193 AmiSetByteToLe(&pCommandFrame->
2194 m_le_bFlags, bFlag);
2195 // init variable header
2196 AmiSetDwordToLe(&pCommandFrame->
2197 m_le_abCommandData[0],
2198 pSdoComCon_p->
2199 m_uiTransSize);
2200 // copy data in frame
2201 EPL_MEMCPY(&pCommandFrame->
2202 m_le_abCommandData[4],
2203 pSdoComCon_p->m_pData,
2204 (EPL_SDO_MAX_PAYLOAD - 4));
2205
2206 // correct byte-counter
2207 pSdoComCon_p->m_uiTransSize -=
2208 (EPL_SDO_MAX_PAYLOAD - 4);
2209 pSdoComCon_p->m_uiTransferredByte +=
2210 (EPL_SDO_MAX_PAYLOAD - 4);
2211 // move data pointer
2212 pSdoComCon_p->m_pData +=
2213 (EPL_SDO_MAX_PAYLOAD - 4);
2214
2215 // set segment size
2216 AmiSetWordToLe(&pCommandFrame->
2217 m_le_wSegmentSize,
2218 (EPL_SDO_MAX_PAYLOAD -
2219 4));
2220
2221 // send frame
2222 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2223 Ret =
2224 EplSdoAsySeqSendData(pSdoComCon_p->
2225 m_SdoSeqConHdl,
2226 uiSizeOfFrame,
2227 pFrame);
2228
2229 } else
2230 if ((pSdoComCon_p->m_uiTransferredByte > 0)
2231 && (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD)) { // segment
2232 // set segment flag
2233 bFlag =
2234 AmiGetByteFromLe(&pCommandFrame->
2235 m_le_bFlags);
2236 bFlag |= 0x20;
2237 AmiSetByteToLe(&pCommandFrame->
2238 m_le_bFlags, bFlag);
2239
2240 // copy data in frame
2241 EPL_MEMCPY(&pCommandFrame->
2242 m_le_abCommandData[0],
2243 pSdoComCon_p->m_pData,
2244 EPL_SDO_MAX_PAYLOAD);
2245
2246 // correct byte-counter
2247 pSdoComCon_p->m_uiTransSize -=
2248 EPL_SDO_MAX_PAYLOAD;
2249 pSdoComCon_p->m_uiTransferredByte +=
2250 EPL_SDO_MAX_PAYLOAD;
2251 // move data pointer
2252 pSdoComCon_p->m_pData +=
2253 EPL_SDO_MAX_PAYLOAD;
2254
2255 // set segment size
2256 AmiSetWordToLe(&pCommandFrame->
2257 m_le_wSegmentSize,
2258 EPL_SDO_MAX_PAYLOAD);
2259
2260 // send frame
2261 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2262 Ret =
2263 EplSdoAsySeqSendData(pSdoComCon_p->
2264 m_SdoSeqConHdl,
2265 uiSizeOfFrame,
2266 pFrame);
2267 } else {
2268 if ((pSdoComCon_p->m_uiTransSize == 0)
2269 && (pSdoComCon_p->
2270 m_SdoServiceType !=
2271 kEplSdoServiceWriteByIndex)) {
2272 goto Exit;
2273 }
2274 // complete
2275 // set segment complete flag
2276 bFlag =
2277 AmiGetByteFromLe(&pCommandFrame->
2278 m_le_bFlags);
2279 bFlag |= 0x30;
2280 AmiSetByteToLe(&pCommandFrame->
2281 m_le_bFlags, bFlag);
2282
2283 // copy data in frame
2284 EPL_MEMCPY(&pCommandFrame->
2285 m_le_abCommandData[0],
2286 pSdoComCon_p->m_pData,
2287 pSdoComCon_p->m_uiTransSize);
2288
2289 // correct byte-counter
2290 pSdoComCon_p->m_uiTransferredByte +=
2291 pSdoComCon_p->m_uiTransSize;
2292
2293 // move data pointer
2294 pSdoComCon_p->m_pData +=
2295 pSdoComCon_p->m_uiTransSize;
2296
2297 // set segment size
2298 AmiSetWordToLe(&pCommandFrame->
2299 m_le_wSegmentSize,
2300 (WORD) pSdoComCon_p->
2301 m_uiTransSize);
2302
2303 // send frame
2304 uiSizeOfFrame +=
2305 pSdoComCon_p->m_uiTransSize;
2306 pSdoComCon_p->m_uiTransSize = 0;
2307 Ret =
2308 EplSdoAsySeqSendData(pSdoComCon_p->
2309 m_SdoSeqConHdl,
2310 uiSizeOfFrame,
2311 pFrame);
2312 }
2313
2314 }
2315 break;
2316 }
2317 // abort to send
2318 case kEplSdoComSendTypeAbort:
2319 {
2320 // set response and abort flag
2321 bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags);
2322 bFlag |= 0xC0;
2323 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2324
2325 // copy abortcode to frame
2326 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0],
2327 *((DWORD *) pSdoComCon_p->m_pData));
2328
2329 // set size of segment
2330 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,
2331 sizeof(DWORD));
2332
2333 // update counter
2334 pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
2335 pSdoComCon_p->m_uiTransSize = 0;
2336
2337 // calc framesize
2338 uiSizeOfFrame += sizeof(DWORD);
2339 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2340 uiSizeOfFrame, pFrame);
2341 break;
2342 }
2343 } // end of switch(SendType_p)
2344
2345 Exit:
2346 return Ret;
9d7164cf
DK
2347}
2348#endif
2349//---------------------------------------------------------------------------
2350//
2351// Function: EplSdoComServerInitWriteByIndex
2352//
2353// Description: function start the processing of an write by index command
2354//
2355//
2356//
2357// Parameters: pSdoComCon_p = pointer to control structure of connection
2358// pAsySdoCom_p = pointer to received frame
2359//
2360// Returns: tEplKernel = errorcode
2361//
2362//
2363// State:
2364//
2365//---------------------------------------------------------------------------
2366#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
833dfbe7
GKH
2367static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
2368 tEplAsySdoCom * pAsySdoCom_p)
9d7164cf 2369{
833dfbe7
GKH
2370 tEplKernel Ret = kEplSuccessful;
2371 unsigned int uiIndex;
2372 unsigned int uiSubindex;
2373 unsigned int uiBytesToTransfer;
2374 tEplObdSize EntrySize;
2375 tEplObdAccess AccessType;
2376 DWORD dwAbortCode;
2377 BYTE *pbSrcData;
2378
2379 dwAbortCode = 0;
2380
2381 // a init of a write
2382 // -> variable part of header possible
2383
2384 // check if expedited or segmented transfer
2385 if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x10) { // initiate segmented transfer
2386 pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
2387 // get index and subindex
2388 uiIndex =
2389 AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[4]);
2390 uiSubindex =
2391 AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[6]);
2392 // get source-pointer for copy
2393 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[8];
2394 // save size
2395 pSdoComCon_p->m_uiTransSize =
2396 AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
2397
2398 } else if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x00) { // expedited transfer
2399 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
2400 // get index and subindex
2401 uiIndex =
2402 AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
2403 uiSubindex =
2404 AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
2405 // get source-pointer for copy
2406 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[4];
2407 // save size
2408 pSdoComCon_p->m_uiTransSize =
2409 AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2410 // subtract header
2411 pSdoComCon_p->m_uiTransSize -= 4;
2412
2413 } else {
2414 // just ignore any other transfer type
2415 goto Exit;
2416 }
2417
2418 // check accesstype of entry
2419 // existens of entry
9d7164cf 2420//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
833dfbe7 2421 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
9d7164cf
DK
2422/*#else
2423 Ret = kEplObdSubindexNotExist;
2424 AccessType = 0;
2425#endif*/
833dfbe7
GKH
2426 if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist
2427 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
2428 // send abort
2429 // d.k. This is wrong: k.t. not needed send abort on end of write
2430 /*pSdoComCon_p->m_pData = (BYTE*)pSdoComCon_p->m_dwLastAbortCode;
2431 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2432 uiIndex,
2433 uiSubindex,
2434 kEplSdoComSendTypeAbort); */
2435 goto Abort;
2436 } else if (Ret != kEplSuccessful) { // entry doesn't exist
2437 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
2438 // send abort
2439 // d.k. This is wrong: k.t. not needed send abort on end of write
2440 /*
2441 pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
2442 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2443 uiIndex,
2444 uiSubindex,
2445 kEplSdoComSendTypeAbort); */
2446 goto Abort;
2447 }
2448 // compare accesstype must be read
2449 if ((AccessType & kEplObdAccWrite) == 0) {
2450
2451 if ((AccessType & kEplObdAccRead) != 0) {
2452 // entry write a read only object
2453 pSdoComCon_p->m_dwLastAbortCode =
2454 EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ;
2455 } else {
2456 pSdoComCon_p->m_dwLastAbortCode =
2457 EPL_SDOAC_UNSUPPORTED_ACCESS;
2458 }
2459 // send abort
2460 // d.k. This is wrong: k.t. not needed send abort on end of write
2461 /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
2462 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2463 uiIndex,
2464 uiSubindex,
2465 kEplSdoComSendTypeAbort); */
2466 goto Abort;
2467 }
2468 // save service
2469 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceWriteByIndex;
2470
2471 pSdoComCon_p->m_uiTransferredByte = 0;
2472
2473 // write data to OD
2474 if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) { // expedited transfer
2475 // size checking is done by EplObduWriteEntryFromLe()
9d7164cf
DK
2476
2477//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
833dfbe7
GKH
2478 Ret = EplObduWriteEntryFromLe(uiIndex,
2479 uiSubindex,
2480 pbSrcData,
2481 pSdoComCon_p->m_uiTransSize);
2482 switch (Ret) {
2483 case kEplSuccessful:
2484 {
2485 break;
2486 }
2487
2488 case kEplObdAccessViolation:
2489 {
2490 pSdoComCon_p->m_dwLastAbortCode =
2491 EPL_SDOAC_UNSUPPORTED_ACCESS;
2492 // send abort
2493 goto Abort;
2494 }
2495
2496 case kEplObdValueLengthError:
2497 {
2498 pSdoComCon_p->m_dwLastAbortCode =
2499 EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH;
2500 // send abort
2501 goto Abort;
2502 }
2503
2504 case kEplObdValueTooHigh:
2505 {
2506 pSdoComCon_p->m_dwLastAbortCode =
2507 EPL_SDOAC_VALUE_RANGE_TOO_HIGH;
2508 // send abort
2509 goto Abort;
2510 }
2511
2512 case kEplObdValueTooLow:
2513 {
2514 pSdoComCon_p->m_dwLastAbortCode =
2515 EPL_SDOAC_VALUE_RANGE_TOO_LOW;
2516 // send abort
2517 goto Abort;
2518 }
2519
2520 default:
2521 {
2522 pSdoComCon_p->m_dwLastAbortCode =
2523 EPL_SDOAC_GENERAL_ERROR;
2524 // send abort
2525 goto Abort;
2526 }
2527 }
9d7164cf 2528//#endif
833dfbe7
GKH
2529 // send command acknowledge
2530 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2531 0,
2532 0,
2533 kEplSdoComSendTypeAckRes);
2534
2535 pSdoComCon_p->m_uiTransSize = 0;
2536 goto Exit;
2537 } else {
2538 // get size of the object to check if it fits
2539 // because we directly write to the destination memory
2540 // d.k. no one calls the user OD callback function
2541
2542 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2543 EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
2544 /*#else
2545 EntrySize = 0;
2546 #endif */
2547 if (EntrySize < pSdoComCon_p->m_uiTransSize) { // parameter too big
2548 pSdoComCon_p->m_dwLastAbortCode =
2549 EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
2550 // send abort
2551 // d.k. This is wrong: k.t. not needed send abort on end of write
2552 /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
2553 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2554 uiIndex,
2555 uiSubindex,
2556 kEplSdoComSendTypeAbort); */
2557 goto Abort;
2558 }
2559
2560 uiBytesToTransfer =
2561 AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2562 // eleminate header (Command header (8) + variable part (4) + Command header (4))
2563 uiBytesToTransfer -= 16;
2564 // get pointer to object entry
9d7164cf 2565//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
833dfbe7
GKH
2566 pSdoComCon_p->m_pData = EplObduGetObjectDataPtr(uiIndex,
2567 uiSubindex);
9d7164cf 2568//#endif
833dfbe7
GKH
2569 if (pSdoComCon_p->m_pData == NULL) {
2570 pSdoComCon_p->m_dwLastAbortCode =
2571 EPL_SDOAC_GENERAL_ERROR;
2572 // send abort
2573 // d.k. This is wrong: k.t. not needed send abort on end of write
9d7164cf
DK
2574/* pSdoComCon_p->m_pData = (BYTE*)&pSdoComCon_p->m_dwLastAbortCode;
2575 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2576 uiIndex,
2577 uiSubindex,
2578 kEplSdoComSendTypeAbort);*/
833dfbe7
GKH
2579 goto Abort;
2580 }
2581 // copy data
2582 EPL_MEMCPY(pSdoComCon_p->m_pData, pbSrcData, uiBytesToTransfer);
2583
2584 // update internal counter
2585 pSdoComCon_p->m_uiTransferredByte = uiBytesToTransfer;
2586 pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer;
2587
2588 // update target pointer
2589 ( /*(BYTE*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
2590
2591 // send acknowledge without any Command layer data
2592 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2593 0, (tEplFrame *) NULL);
2594 goto Exit;
2595 }
2596
2597 Abort:
2598 if (pSdoComCon_p->m_dwLastAbortCode != 0) {
2599 // send abort
2600 pSdoComCon_p->m_pData =
2601 (BYTE *) & pSdoComCon_p->m_dwLastAbortCode;
2602 Ret =
2603 EplSdoComServerSendFrameIntern(pSdoComCon_p, uiIndex,
2604 uiSubindex,
2605 kEplSdoComSendTypeAbort);
2606
2607 // reset abort code
2608 pSdoComCon_p->m_dwLastAbortCode = 0;
2609 pSdoComCon_p->m_uiTransSize = 0;
2610 goto Exit;
2611 }
2612
2613 Exit:
2614 return Ret;
9d7164cf
DK
2615}
2616#endif
2617
2618//---------------------------------------------------------------------------
2619//
2620// Function: EplSdoComClientSend
2621//
2622// Description: function starts an sdo transfer an send all further frames
2623//
2624//
2625//
2626// Parameters: pSdoComCon_p = pointer to control structure of connection
2627//
2628// Returns: tEplKernel = errorcode
2629//
2630//
2631// State:
2632//
2633//---------------------------------------------------------------------------
2634#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7 2635static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
9d7164cf 2636{
833dfbe7
GKH
2637 tEplKernel Ret;
2638 BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
2639 tEplFrame *pFrame;
2640 tEplAsySdoCom *pCommandFrame;
2641 unsigned int uiSizeOfFrame;
2642 BYTE bFlags;
2643 BYTE *pbPayload;
2644
2645 Ret = kEplSuccessful;
2646
2647 pFrame = (tEplFrame *) & abFrame[0];
2648
2649 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
2650
2651 // build generic part of frame
2652 // get pointer to command layerpart of frame
2653 pCommandFrame =
2654 &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
2655 m_le_abSdoSeqPayload;
2656 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
2657 pSdoComCon_p->m_SdoServiceType);
2658 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
2659 pSdoComCon_p->m_bTransactionId);
2660
2661 // set size constant part of header
2662 uiSizeOfFrame = 8;
2663
2664 // check if first frame to send -> command header needed
2665 if (pSdoComCon_p->m_uiTransSize > 0) {
2666 if (pSdoComCon_p->m_uiTransferredByte == 0) { // start SDO transfer
2667 // check if segmented or expedited transfer
2668 // only for write commands
2669 switch (pSdoComCon_p->m_SdoServiceType) {
2670 case kEplSdoServiceReadByIndex:
2671 { // first frame of read access always expedited
2672 pSdoComCon_p->m_SdoTransType =
2673 kEplSdoTransExpedited;
2674 pbPayload =
2675 &pCommandFrame->
2676 m_le_abCommandData[0];
2677 // fill rest of header
2678 AmiSetWordToLe(&pCommandFrame->
2679 m_le_wSegmentSize, 4);
2680
2681 // create command header
2682 AmiSetWordToLe(pbPayload,
2683 (WORD) pSdoComCon_p->
2684 m_uiTargetIndex);
2685 pbPayload += 2;
2686 AmiSetByteToLe(pbPayload,
2687 (BYTE) pSdoComCon_p->
2688 m_uiTargetSubIndex);
2689 // calc size
2690 uiSizeOfFrame += 4;
2691
2692 // set pSdoComCon_p->m_uiTransferredByte to one
2693 pSdoComCon_p->m_uiTransferredByte = 1;
2694 break;
2695 }
2696
2697 case kEplSdoServiceWriteByIndex:
2698 {
2699 if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) { // segmented transfer
2700 // -> variable part of header needed
2701 // save that transfer is segmented
2702 pSdoComCon_p->m_SdoTransType =
2703 kEplSdoTransSegmented;
2704 // fill variable part of header
2705 AmiSetDwordToLe(&pCommandFrame->
2706 m_le_abCommandData
2707 [0],
2708 pSdoComCon_p->
2709 m_uiTransSize);
2710 // set pointer to real payload
2711 pbPayload =
2712 &pCommandFrame->
2713 m_le_abCommandData[4];
2714 // fill rest of header
2715 AmiSetWordToLe(&pCommandFrame->
2716 m_le_wSegmentSize,
2717 EPL_SDO_MAX_PAYLOAD);
2718 bFlags = 0x10;
2719 AmiSetByteToLe(&pCommandFrame->
2720 m_le_bFlags,
2721 bFlags);
2722 // create command header
2723 AmiSetWordToLe(pbPayload,
2724 (WORD)
2725 pSdoComCon_p->
2726 m_uiTargetIndex);
2727 pbPayload += 2;
2728 AmiSetByteToLe(pbPayload,
2729 (BYTE)
2730 pSdoComCon_p->
2731 m_uiTargetSubIndex);
2732 // on byte for reserved
2733 pbPayload += 2;
2734 // calc size
2735 uiSizeOfFrame +=
2736 EPL_SDO_MAX_PAYLOAD;
2737
2738 // copy payload
2739 EPL_MEMCPY(pbPayload,
2740 pSdoComCon_p->
2741 m_pData,
2742 (EPL_SDO_MAX_PAYLOAD
2743 - 8));
2744 pSdoComCon_p->m_pData +=
2745 (EPL_SDO_MAX_PAYLOAD - 8);
2746 // correct intern counter
2747 pSdoComCon_p->m_uiTransSize -=
2748 (EPL_SDO_MAX_PAYLOAD - 8);
2749 pSdoComCon_p->
2750 m_uiTransferredByte =
2751 (EPL_SDO_MAX_PAYLOAD - 8);
2752
2753 } else { // expedited trandsfer
2754 // save that transfer is expedited
2755 pSdoComCon_p->m_SdoTransType =
2756 kEplSdoTransExpedited;
2757 pbPayload =
2758 &pCommandFrame->
2759 m_le_abCommandData[0];
2760
2761 // create command header
2762 AmiSetWordToLe(pbPayload,
2763 (WORD)
2764 pSdoComCon_p->
2765 m_uiTargetIndex);
2766 pbPayload += 2;
2767 AmiSetByteToLe(pbPayload,
2768 (BYTE)
2769 pSdoComCon_p->
2770 m_uiTargetSubIndex);
2771 // + 2 -> one byte for subindex and one byte reserved
2772 pbPayload += 2;
2773 // copy data
2774 EPL_MEMCPY(pbPayload,
2775 pSdoComCon_p->
2776 m_pData,
2777 pSdoComCon_p->
2778 m_uiTransSize);
2779 // calc size
2780 uiSizeOfFrame +=
2781 (4 +
2782 pSdoComCon_p->
2783 m_uiTransSize);
2784 // fill rest of header
2785 AmiSetWordToLe(&pCommandFrame->
2786 m_le_wSegmentSize,
2787 (WORD) (4 +
2788 pSdoComCon_p->
2789 m_uiTransSize));
2790
2791 pSdoComCon_p->
2792 m_uiTransferredByte =
2793 pSdoComCon_p->m_uiTransSize;
2794 pSdoComCon_p->m_uiTransSize = 0;
2795 }
2796 break;
2797 }
2798
2799 case kEplSdoServiceNIL:
2800 default:
2801 // invalid service requested
2802 Ret = kEplSdoComInvalidServiceType;
2803 goto Exit;
2804 } // end of switch(pSdoComCon_p->m_SdoServiceType)
2805 } else // (pSdoComCon_p->m_uiTransferredByte > 0)
2806 { // continue SDO transfer
2807 switch (pSdoComCon_p->m_SdoServiceType) {
2808 // for expedited read is nothing to do
2809 // -> server sends data
2810
2811 case kEplSdoServiceWriteByIndex:
2812 { // send next frame
2813 if (pSdoComCon_p->m_SdoTransType ==
2814 kEplSdoTransSegmented) {
2815 if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) { // next segment
2816 pbPayload =
2817 &pCommandFrame->
2818 m_le_abCommandData
2819 [0];
2820 // fill rest of header
2821 AmiSetWordToLe
2822 (&pCommandFrame->
2823 m_le_wSegmentSize,
2824 EPL_SDO_MAX_PAYLOAD);
2825 bFlags = 0x20;
2826 AmiSetByteToLe
2827 (&pCommandFrame->
2828 m_le_bFlags,
2829 bFlags);
2830 // copy data
2831 EPL_MEMCPY(pbPayload,
2832 pSdoComCon_p->
2833 m_pData,
2834 EPL_SDO_MAX_PAYLOAD);
2835 pSdoComCon_p->m_pData +=
2836 EPL_SDO_MAX_PAYLOAD;
2837 // correct intern counter
2838 pSdoComCon_p->
2839 m_uiTransSize -=
2840 EPL_SDO_MAX_PAYLOAD;
2841 pSdoComCon_p->
2842 m_uiTransferredByte
2843 =
2844 EPL_SDO_MAX_PAYLOAD;
2845 // calc size
2846 uiSizeOfFrame +=
2847 EPL_SDO_MAX_PAYLOAD;
2848
2849 } else { // end of transfer
2850 pbPayload =
2851 &pCommandFrame->
2852 m_le_abCommandData
2853 [0];
2854 // fill rest of header
2855 AmiSetWordToLe
2856 (&pCommandFrame->
2857 m_le_wSegmentSize,
2858 (WORD)
2859 pSdoComCon_p->
2860 m_uiTransSize);
2861 bFlags = 0x30;
2862 AmiSetByteToLe
2863 (&pCommandFrame->
2864 m_le_bFlags,
2865 bFlags);
2866 // copy data
2867 EPL_MEMCPY(pbPayload,
2868 pSdoComCon_p->
2869 m_pData,
2870 pSdoComCon_p->
2871 m_uiTransSize);
2872 pSdoComCon_p->m_pData +=
2873 pSdoComCon_p->
2874 m_uiTransSize;
2875 // calc size
2876 uiSizeOfFrame +=
2877 pSdoComCon_p->
2878 m_uiTransSize;
2879 // correct intern counter
2880 pSdoComCon_p->
2881 m_uiTransSize = 0;
2882 pSdoComCon_p->
2883 m_uiTransferredByte
2884 =
2885 pSdoComCon_p->
2886 m_uiTransSize;
2887
2888 }
2889 } else {
2890 goto Exit;
2891 }
2892 break;
2893 }
2894 default:
2895 {
2896 goto Exit;
2897 }
2898 } // end of switch(pSdoComCon_p->m_SdoServiceType)
2899 }
2900 } else {
2901 goto Exit;
2902 }
2903
2904 // call send function of lower layer
2905 switch (pSdoComCon_p->m_SdoProtType) {
2906 case kEplSdoTypeAsnd:
2907 case kEplSdoTypeUdp:
2908 {
2909 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2910 uiSizeOfFrame, pFrame);
2911 break;
2912 }
2913
2914 default:
2915 {
2916 Ret = kEplSdoComUnsupportedProt;
2917 }
2918 } // end of switch(pSdoComCon_p->m_SdoProtType)
2919
2920 Exit:
2921 return Ret;
9d7164cf
DK
2922
2923}
2924#endif
2925//---------------------------------------------------------------------------
2926//
2927// Function: EplSdoComClientProcessFrame
2928//
2929// Description: function process a received frame
2930//
2931//
2932//
2933// Parameters: SdoComCon_p = connection handle
2934// pAsySdoCom_p = pointer to frame to process
2935//
2936// Returns: tEplKernel = errorcode
2937//
2938//
2939// State:
2940//
2941//---------------------------------------------------------------------------
2942#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7
GKH
2943static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
2944 tEplAsySdoCom * pAsySdoCom_p)
9d7164cf 2945{
833dfbe7
GKH
2946 tEplKernel Ret;
2947 BYTE bBuffer;
2948 unsigned int uiBuffer;
2949 unsigned int uiDataSize;
2950 unsigned long ulBuffer;
2951 tEplSdoComCon *pSdoComCon;
2952
2953 Ret = kEplSuccessful;
2954
2955 // get pointer to control structure
2956 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
2957
2958 // check if transaction Id fit
2959 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId);
2960 if (pSdoComCon->m_bTransactionId != bBuffer) {
2961 // incorrect transaction id
2962
2963 // if running transfer
2964 if ((pSdoComCon->m_uiTransferredByte != 0)
2965 && (pSdoComCon->m_uiTransSize != 0)) {
2966 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
2967 // -> send abort
2968 EplSdoComClientSendAbort(pSdoComCon,
2969 pSdoComCon->m_dwLastAbortCode);
2970 // call callback of application
2971 Ret =
2972 EplSdoComTransferFinished(SdoComCon_p, pSdoComCon,
2973 kEplSdoComTransferTxAborted);
2974 }
2975
2976 } else { // check if correct command
2977 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bCommandId);
2978 if (pSdoComCon->m_SdoServiceType != bBuffer) {
2979 // incorrect command
2980 // if running transfer
2981 if ((pSdoComCon->m_uiTransferredByte != 0)
2982 && (pSdoComCon->m_uiTransSize != 0)) {
2983 pSdoComCon->m_dwLastAbortCode =
2984 EPL_SDOAC_GENERAL_ERROR;
2985 // -> send abort
2986 EplSdoComClientSendAbort(pSdoComCon,
2987 pSdoComCon->
2988 m_dwLastAbortCode);
2989 // call callback of application
2990 Ret =
2991 EplSdoComTransferFinished(SdoComCon_p,
2992 pSdoComCon,
2993 kEplSdoComTransferTxAborted);
2994 }
2995
2996 } else { // switch on command
2997 switch (pSdoComCon->m_SdoServiceType) {
2998 case kEplSdoServiceWriteByIndex:
2999 { // check if confirmation from server
3000 // nothing more to do
3001 break;
3002 }
3003
3004 case kEplSdoServiceReadByIndex:
3005 { // check if it is an segmented or an expedited transfer
3006 bBuffer =
3007 AmiGetByteFromLe(&pAsySdoCom_p->
3008 m_le_bFlags);
3009 // mask uninteressting bits
3010 bBuffer &= 0x30;
3011 switch (bBuffer) {
3012 // expedited transfer
3013 case 0x00:
3014 {
3015 // check size of buffer
3016 uiBuffer =
3017 AmiGetWordFromLe
3018 (&pAsySdoCom_p->
3019 m_le_wSegmentSize);
3020 if (uiBuffer > pSdoComCon->m_uiTransSize) { // buffer provided by the application is to small
3021 // copy only a part
3022 uiDataSize =
3023 pSdoComCon->
3024 m_uiTransSize;
3025 } else { // buffer fits
3026 uiDataSize =
3027 uiBuffer;
3028 }
3029
3030 // copy data
3031 EPL_MEMCPY(pSdoComCon->
3032 m_pData,
3033 &pAsySdoCom_p->
3034 m_le_abCommandData
3035 [0],
3036 uiDataSize);
3037
3038 // correct counter
3039 pSdoComCon->
3040 m_uiTransSize = 0;
3041 pSdoComCon->
3042 m_uiTransferredByte
3043 = uiDataSize;
3044 break;
3045 }
3046
3047 // start of a segmented transfer
3048 case 0x10:
3049 { // get total size of transfer
3050 ulBuffer =
3051 AmiGetDwordFromLe
3052 (&pAsySdoCom_p->
3053 m_le_abCommandData
3054 [0]);
3055 if (ulBuffer <= pSdoComCon->m_uiTransSize) { // buffer fit
3056 pSdoComCon->
3057 m_uiTransSize
3058 =
3059 (unsigned
3060 int)
3061 ulBuffer;
3062 } else { // buffer to small
3063 // send abort
3064 pSdoComCon->
3065 m_dwLastAbortCode
3066 =
3067 EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
3068 // -> send abort
3069 EplSdoComClientSendAbort
3070 (pSdoComCon,
3071 pSdoComCon->
3072 m_dwLastAbortCode);
3073 // call callback of application
3074 Ret =
3075 EplSdoComTransferFinished
3076 (SdoComCon_p,
3077 pSdoComCon,
3078 kEplSdoComTransferRxAborted);
3079 goto Exit;
3080 }
3081
3082 // get segment size
3083 // check size of buffer
3084 uiBuffer =
3085 AmiGetWordFromLe
3086 (&pAsySdoCom_p->
3087 m_le_wSegmentSize);
3088 // subtract size of vaiable header from datasize
3089 uiBuffer -= 4;
3090 // copy data
3091 EPL_MEMCPY(pSdoComCon->
3092 m_pData,
3093 &pAsySdoCom_p->
3094 m_le_abCommandData
3095 [4],
3096 uiBuffer);
3097
3098 // correct counter an pointer
3099 pSdoComCon->m_pData +=
3100 uiBuffer;
3101 pSdoComCon->
3102 m_uiTransferredByte
3103 += uiBuffer;
3104 pSdoComCon->
3105 m_uiTransSize -=
3106 uiBuffer;
3107
3108 break;
3109 }
3110
3111 // segment
3112 case 0x20:
3113 {
3114 // get segment size
3115 // check size of buffer
3116 uiBuffer =
3117 AmiGetWordFromLe
3118 (&pAsySdoCom_p->
3119 m_le_wSegmentSize);
3120 // check if data to copy fit to buffer
3121 if (uiBuffer >= pSdoComCon->m_uiTransSize) { // to much data
3122 uiBuffer =
3123 (pSdoComCon->
3124 m_uiTransSize
3125 - 1);
3126 }
3127 // copy data
3128 EPL_MEMCPY(pSdoComCon->
3129 m_pData,
3130 &pAsySdoCom_p->
3131 m_le_abCommandData
3132 [0],
3133 uiBuffer);
3134
3135 // correct counter an pointer
3136 pSdoComCon->m_pData +=
3137 uiBuffer;
3138 pSdoComCon->
3139 m_uiTransferredByte
3140 += uiBuffer;
3141 pSdoComCon->
3142 m_uiTransSize -=
3143 uiBuffer;
3144 break;
3145 }
3146
3147 // last segment
3148 case 0x30:
3149 {
3150 // get segment size
3151 // check size of buffer
3152 uiBuffer =
3153 AmiGetWordFromLe
3154 (&pAsySdoCom_p->
3155 m_le_wSegmentSize);
3156 // check if data to copy fit to buffer
3157 if (uiBuffer > pSdoComCon->m_uiTransSize) { // to much data
3158 uiBuffer =
3159 (pSdoComCon->
3160 m_uiTransSize
3161 - 1);
3162 }
3163 // copy data
3164 EPL_MEMCPY(pSdoComCon->
3165 m_pData,
3166 &pAsySdoCom_p->
3167 m_le_abCommandData
3168 [0],
3169 uiBuffer);
3170
3171 // correct counter an pointer
3172 pSdoComCon->m_pData +=
3173 uiBuffer;
3174 pSdoComCon->
3175 m_uiTransferredByte
3176 += uiBuffer;
3177 pSdoComCon->
3178 m_uiTransSize = 0;
3179
3180 break;
3181 }
3182 } // end of switch(bBuffer & 0x30)
3183
3184 break;
3185 }
3186
3187 case kEplSdoServiceNIL:
3188 default:
3189 // invalid service requested
3190 // $$$ d.k. What should we do?
3191 break;
3192 } // end of switch(pSdoComCon->m_SdoServiceType)
3193 }
3194 }
3195
3196 Exit:
3197 return Ret;
9d7164cf
DK
3198}
3199#endif
3200
3201//---------------------------------------------------------------------------
3202//
3203// Function: EplSdoComClientSendAbort
3204//
3205// Description: function send a abort message
3206//
3207//
3208//
3209// Parameters: pSdoComCon_p = pointer to control structure of connection
3210// dwAbortCode_p = Sdo abort code
3211//
3212// Returns: tEplKernel = errorcode
3213//
3214//
3215// State:
3216//
3217//---------------------------------------------------------------------------
3218#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
833dfbe7
GKH
3219static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
3220 DWORD dwAbortCode_p)
9d7164cf 3221{
833dfbe7
GKH
3222 tEplKernel Ret;
3223 BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
3224 tEplFrame *pFrame;
3225 tEplAsySdoCom *pCommandFrame;
3226 unsigned int uiSizeOfFrame;
3227
3228 Ret = kEplSuccessful;
3229
3230 pFrame = (tEplFrame *) & abFrame[0];
3231
3232 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
3233
3234 // build generic part of frame
3235 // get pointer to command layerpart of frame
3236 pCommandFrame =
3237 &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
3238 m_le_abSdoSeqPayload;
3239 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
3240 pSdoComCon_p->m_SdoServiceType);
3241 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
3242 pSdoComCon_p->m_bTransactionId);
3243
3244 uiSizeOfFrame = 8;
3245
3246 // set response and abort flag
3247 pCommandFrame->m_le_bFlags |= 0x40;
3248
3249 // copy abortcode to frame
3250 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p);
3251
3252 // set size of segment
3253 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(DWORD));
3254
3255 // update counter
3256 pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
3257 pSdoComCon_p->m_uiTransSize = 0;
3258
3259 // calc framesize
3260 uiSizeOfFrame += sizeof(DWORD);
3261
3262 // save abort code
3263 pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p;
3264
3265 // call send function of lower layer
3266 switch (pSdoComCon_p->m_SdoProtType) {
3267 case kEplSdoTypeAsnd:
3268 case kEplSdoTypeUdp:
3269 {
3270 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
3271 uiSizeOfFrame, pFrame);
3272 break;
3273 }
3274
3275 default:
3276 {
3277 Ret = kEplSdoComUnsupportedProt;
3278 }
3279 } // end of switch(pSdoComCon_p->m_SdoProtType)
3280
3281 return Ret;
9d7164cf
DK
3282}
3283#endif
3284
3285//---------------------------------------------------------------------------
3286//
3287// Function: EplSdoComTransferFinished
3288//
3289// Description: calls callback function of application if available
3290// and clears entry in control structure
3291//
3292// Parameters: pSdoComCon_p = pointer to control structure of connection
3293// SdoComConState_p = state of SDO transfer
3294//
3295// Returns: tEplKernel = errorcode
3296//
3297//
3298// State:
3299//
3300//---------------------------------------------------------------------------
833dfbe7
GKH
3301static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p,
3302 tEplSdoComCon * pSdoComCon_p,
3303 tEplSdoComConState SdoComConState_p)
9d7164cf 3304{
833dfbe7
GKH
3305 tEplKernel Ret;
3306
3307 Ret = kEplSuccessful;
3308
3309 if (pSdoComCon_p->m_pfnTransferFinished != NULL) {
3310 tEplSdoFinishedCb pfnTransferFinished;
3311 tEplSdoComFinished SdoComFinished;
3312
3313 SdoComFinished.m_pUserArg = pSdoComCon_p->m_pUserArg;
3314 SdoComFinished.m_uiNodeId = pSdoComCon_p->m_uiNodeId;
3315 SdoComFinished.m_uiTargetIndex = pSdoComCon_p->m_uiTargetIndex;
3316 SdoComFinished.m_uiTargetSubIndex =
3317 pSdoComCon_p->m_uiTargetSubIndex;
3318 SdoComFinished.m_uiTransferredByte =
3319 pSdoComCon_p->m_uiTransferredByte;
3320 SdoComFinished.m_dwAbortCode = pSdoComCon_p->m_dwLastAbortCode;
3321 SdoComFinished.m_SdoComConHdl = SdoComCon_p;
3322 SdoComFinished.m_SdoComConState = SdoComConState_p;
3323 if (pSdoComCon_p->m_SdoServiceType ==
3324 kEplSdoServiceWriteByIndex) {
3325 SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeWrite;
3326 } else {
3327 SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeRead;
3328 }
3329
3330 // reset transfer state so this handle is not busy anymore
3331 pSdoComCon_p->m_uiTransferredByte = 0;
3332 pSdoComCon_p->m_uiTransSize = 0;
3333
3334 pfnTransferFinished = pSdoComCon_p->m_pfnTransferFinished;
3335 // delete function pointer to inform application only once for each transfer
3336 pSdoComCon_p->m_pfnTransferFinished = NULL;
3337
3338 // call application's callback function
3339 pfnTransferFinished(&SdoComFinished);
3340
3341 }
3342
3343 return Ret;
9d7164cf
DK
3344}
3345
3346// EOF