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