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