Merge git://git.infradead.org/iommu-2.6
[sfrench/cifs-2.6.git] / drivers / staging / epl / EplSdoAsySequ.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 asychronous SDO Sequence 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: EplSdoAsySequ.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.10 $  $Date: 2008/11/13 17:13:09 $
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/EplSdoAsySequ.h"
72
73 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) == 0) &&\
74      (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) == 0)   )
75
76 #error 'ERROR: At least UDP or Asnd module needed!'
77
78 #endif
79 /***************************************************************************/
80 /*                                                                         */
81 /*                                                                         */
82 /*          G L O B A L   D E F I N I T I O N S                            */
83 /*                                                                         */
84 /*                                                                         */
85 /***************************************************************************/
86
87 //---------------------------------------------------------------------------
88 // const defines
89 //---------------------------------------------------------------------------
90
91 #define EPL_SDO_HISTORY_SIZE        5
92
93 #ifndef EPL_MAX_SDO_SEQ_CON
94 #define EPL_MAX_SDO_SEQ_CON         10
95 #endif
96
97 #define EPL_SEQ_DEFAULT_TIMEOUT     5000        // in [ms] => 5 sec
98
99 #define EPL_SEQ_RETRY_COUNT         5   // => max. Timeout 30 sec
100
101 #define EPL_SEQ_NUM_THRESHOLD       100 // threshold which distinguishes between old and new sequence numbers
102
103 // define frame with size of Asnd-Header-, SDO Sequenze Header size, SDO Command header
104 // and Ethernet-Header size
105 #define EPL_SEQ_FRAME_SIZE          24
106 // size of the header of the asynchronus SDO Sequence layer
107 #define EPL_SEQ_HEADER_SIZE         4
108
109 // buffersize for one frame in history
110 #define EPL_SEQ_HISTROY_FRAME_SIZE  EPL_MAX_SDO_FRAME_SIZE
111
112 // mask to get scon and rcon
113 #define EPL_ASY_SDO_CON_MASK        0x03
114
115 //---------------------------------------------------------------------------
116 // local types
117 //---------------------------------------------------------------------------
118
119 // events for processfunction
120 typedef enum {
121         kAsySdoSeqEventNoEvent = 0x00,  // no Event
122         kAsySdoSeqEventInitCon = 0x01,  // init connection
123         kAsySdoSeqEventFrameRec = 0x02, // frame received
124         kAsySdoSeqEventFrameSend = 0x03,        // frame to send
125         kAsySdoSeqEventTimeout = 0x04,  // Timeout for connection
126         kAsySdoSeqEventCloseCon = 0x05  // higher layer close connection
127 } tEplAsySdoSeqEvent;
128
129 // structure for History-Buffer
130 typedef struct {
131         u8 m_bFreeEntries;
132         u8 m_bWrite;            // index of the next free buffer entry
133         u8 m_bAck;              // index of the next message which should become acknowledged
134         u8 m_bRead;             // index between m_bAck and m_bWrite to the next message for retransmission
135         u8 m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE]
136             [EPL_SEQ_HISTROY_FRAME_SIZE];
137         unsigned int m_auiFrameSize[EPL_SDO_HISTORY_SIZE];
138
139 } tEplAsySdoConHistory;
140
141 // state of the statemaschine
142 typedef enum {
143         kEplAsySdoStateIdle = 0x00,
144         kEplAsySdoStateInit1 = 0x01,
145         kEplAsySdoStateInit2 = 0x02,
146         kEplAsySdoStateInit3 = 0x03,
147         kEplAsySdoStateConnected = 0x04,
148         kEplAsySdoStateWaitAck = 0x05
149 } tEplAsySdoState;
150
151 // connection control structure
152 typedef struct {
153         tEplSdoConHdl m_ConHandle;
154         tEplAsySdoState m_SdoState;
155         u8 m_bRecSeqNum;        // name from view of the communication partner
156         u8 m_bSendSeqNum;       // name from view of the communication partner
157         tEplAsySdoConHistory m_SdoConHistory;
158         tEplTimerHdl m_EplTimerHdl;
159         unsigned int m_uiRetryCount;    // retry counter
160         unsigned int m_uiUseCount;      // one sequence layer connection may be used by
161         // multiple command layer connections
162
163 } tEplAsySdoSeqCon;
164
165 // instance structure
166 typedef struct {
167         tEplAsySdoSeqCon m_AsySdoConnection[EPL_MAX_SDO_SEQ_CON];
168         tEplSdoComReceiveCb m_fpSdoComReceiveCb;
169         tEplSdoComConCb m_fpSdoComConCb;
170
171 #if defined(WIN32) || defined(_WIN32)
172         LPCRITICAL_SECTION m_pCriticalSection;
173         CRITICAL_SECTION m_CriticalSection;
174
175         LPCRITICAL_SECTION m_pCriticalSectionReceive;
176         CRITICAL_SECTION m_CriticalSectionReceive;
177 #endif
178
179 } tEplAsySdoSequInstance;
180
181 //---------------------------------------------------------------------------
182 // modul globale vars
183 //---------------------------------------------------------------------------
184
185 static tEplAsySdoSequInstance AsySdoSequInstance_g;
186
187 //---------------------------------------------------------------------------
188 // local function prototypes
189 //---------------------------------------------------------------------------
190
191 static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p,
192                                       unsigned int uiDataSize_p,
193                                       tEplFrame * pData_p,
194                                       tEplAsySdoSeq * pRecFrame_p,
195                                       tEplAsySdoSeqEvent Event_p);
196
197 static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
198                                          unsigned int uiDataSize_p,
199                                          tEplFrame * pData_p,
200                                          BOOL fFrameInHistory);
201
202 static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
203                                              unsigned int uiDataSize_p,
204                                              tEplFrame * pEplFrame_p);
205
206 tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
207                               tEplAsySdoSeq *pSdoSeqData_p,
208                               unsigned int uiDataSize_p);
209
210 static tEplKernel EplSdoAsyInitHistory(void);
211
212 static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
213                                              tEplFrame * pFrame_p,
214                                              unsigned int uiSize_p);
215
216 static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
217                                              u8 bRecSeqNumber_p);
218
219 static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
220                                            tEplFrame ** ppFrame_p,
221                                            unsigned int *puiSize_p,
222                                            BOOL fInitRead);
223
224 static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon *
225                                                        pAsySdoSeqCon_p);
226
227 static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
228                                        unsigned long ulTimeout);
229
230 /***************************************************************************/
231 /*                                                                         */
232 /*                                                                         */
233 /*          C L A S S  <EPL asychronus SDO Sequence layer>                 */
234 /*                                                                         */
235 /*                                                                         */
236 /***************************************************************************/
237 //
238 // Description: this module contains the asynchronus SDO Sequence Layer for
239 //              the EPL SDO service
240 //
241 //
242 /***************************************************************************/
243
244 //=========================================================================//
245 //                                                                         //
246 //          P U B L I C   F U N C T I O N S                                //
247 //                                                                         //
248 //=========================================================================//
249
250 //---------------------------------------------------------------------------
251 //
252 // Function:    EplSdoAsySeqInit
253 //
254 // Description: init first instance
255 //
256 //
257 //
258 // Parameters:  fpSdoComCb_p    = callback function to inform Command layer
259 //                                about new frames
260 //              fpSdoComConCb_p = callback function to inform command layer
261 //                                about connection state
262 //
263 //
264 // Returns:     tEplKernel = errorcode
265 //
266 //
267 // State:
268 //
269 //---------------------------------------------------------------------------
270 tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
271                             tEplSdoComConCb fpSdoComConCb_p)
272 {
273         tEplKernel Ret;
274
275         Ret = EplSdoAsySeqAddInstance(fpSdoComCb_p, fpSdoComConCb_p);
276
277         return Ret;
278
279 }
280
281 //---------------------------------------------------------------------------
282 //
283 // Function:    EplSdoAsySeqAddInstance
284 //
285 // Description: init following instances
286 //
287 //
288 //
289 // Parameters:  fpSdoComCb_p    = callback function to inform Command layer
290 //                                about new frames
291 //              fpSdoComConCb_p = callback function to inform command layer
292 //                                about connection state
293 //
294 // Returns:     tEplKernel = errorcode
295 //
296 //
297 // State:
298 //
299 //---------------------------------------------------------------------------
300 tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
301                                    tEplSdoComConCb fpSdoComConCb_p)
302 {
303         tEplKernel Ret;
304
305         Ret = kEplSuccessful;
306
307         // check functionpointer
308         if (fpSdoComCb_p == NULL) {
309                 Ret = kEplSdoSeqMissCb;
310                 goto Exit;
311         } else {
312                 AsySdoSequInstance_g.m_fpSdoComReceiveCb = fpSdoComCb_p;
313         }
314
315         // check functionpointer
316         if (fpSdoComConCb_p == NULL) {
317                 Ret = kEplSdoSeqMissCb;
318                 goto Exit;
319         } else {
320                 AsySdoSequInstance_g.m_fpSdoComConCb = fpSdoComConCb_p;
321         }
322
323         // set controllstructure to 0
324         EPL_MEMSET(&AsySdoSequInstance_g.m_AsySdoConnection[0], 0x00,
325                    sizeof(AsySdoSequInstance_g.m_AsySdoConnection));
326
327         // init History
328         Ret = EplSdoAsyInitHistory();
329         if (Ret != kEplSuccessful) {
330                 goto Exit;
331         }
332 #if defined(WIN32) || defined(_WIN32)
333         // create critical section for process function
334         AsySdoSequInstance_g.m_pCriticalSection =
335             &AsySdoSequInstance_g.m_CriticalSection;
336         InitializeCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
337
338         // init critical section for receive cb function
339         AsySdoSequInstance_g.m_pCriticalSectionReceive =
340             &AsySdoSequInstance_g.m_CriticalSectionReceive;
341         InitializeCriticalSection(AsySdoSequInstance_g.
342                                   m_pCriticalSectionReceive);
343 #endif
344
345 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
346         // init lower layer
347         Ret = EplSdoUdpuAddInstance(EplSdoAsyReceiveCb);
348         if (Ret != kEplSuccessful) {
349                 goto Exit;
350         }
351 #endif
352
353 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
354         // init lower layer
355         Ret = EplSdoAsnduAddInstance(EplSdoAsyReceiveCb);
356         if (Ret != kEplSuccessful) {
357                 goto Exit;
358         }
359 #endif
360
361       Exit:
362         return Ret;
363
364 }
365
366 //---------------------------------------------------------------------------
367 //
368 // Function:    EplSdoAsySeqDelInstance
369 //
370 // Description: delete instances
371 //
372 //
373 //
374 // Parameters:
375 //
376 //
377 // Returns:     tEplKernel = errorcode
378 //
379 //
380 // State:
381 //
382 //---------------------------------------------------------------------------
383 tEplKernel EplSdoAsySeqDelInstance(void)
384 {
385         tEplKernel Ret;
386         unsigned int uiCount;
387         tEplAsySdoSeqCon *pAsySdoSeqCon;
388
389         Ret = kEplSuccessful;
390
391         // delete timer of open connections
392         uiCount = 0;
393         pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0];
394         while (uiCount < EPL_MAX_SDO_SEQ_CON) {
395                 if (pAsySdoSeqCon->m_ConHandle != 0) {
396                         EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
397                 }
398                 uiCount++;
399                 pAsySdoSeqCon++;
400         }
401
402 #if defined(WIN32) || defined(_WIN32)
403         // delete critical section for process function
404         DeleteCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
405 #endif
406
407         // set instance-table to 0
408         EPL_MEMSET(&AsySdoSequInstance_g, 0x00, sizeof(AsySdoSequInstance_g));
409
410 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
411         // delete lower layer
412         Ret = EplSdoUdpuDelInstance();
413 #endif
414
415 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
416         // delete lower layer
417         Ret = EplSdoAsnduDelInstance();
418 #endif
419
420         return Ret;
421 }
422
423 //---------------------------------------------------------------------------
424 //
425 // Function:    EplSdoAsySeqInitCon
426 //
427 // Description: start initialization of a sequence layer connection.
428 //              It tries to reuse an existing connection to the same node.
429 //
430 //
431 // Parameters:  pSdoSeqConHdl_p = pointer to the variable for the connection handle
432 //              uiNodeId_p      = Node Id of the target
433 //              SdoType          = Type of the SDO connection
434 //
435 //
436 // Returns:     tEplKernel = errorcode
437 //
438 //
439 // State:
440 //
441 //---------------------------------------------------------------------------
442 tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p,
443                                unsigned int uiNodeId_p,
444                                tEplSdoType SdoType)
445 {
446         tEplKernel Ret;
447         unsigned int uiCount;
448         unsigned int uiFreeCon;
449         tEplSdoConHdl ConHandle;
450         tEplAsySdoSeqCon *pAsySdoSeqCon;
451         Ret = kEplSuccessful;
452
453         // check SdoType
454         // call init function of the protcol abstraction layer
455         // which tries to find an existing connection to the same node
456         switch (SdoType) {
457                 // SDO over UDP
458         case kEplSdoTypeUdp:
459                 {
460 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
461                         Ret = EplSdoUdpuInitCon(&ConHandle, uiNodeId_p);
462                         if (Ret != kEplSuccessful) {
463                                 goto Exit;
464                         }
465 #else
466                         Ret = kEplSdoSeqUnsupportedProt;
467 #endif
468                         break;
469                 }
470
471                 // SDO over Asnd
472         case kEplSdoTypeAsnd:
473                 {
474 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
475                         Ret = EplSdoAsnduInitCon(&ConHandle, uiNodeId_p);
476                         if (Ret != kEplSuccessful) {
477                                 goto Exit;
478                         }
479 #else
480                         Ret = kEplSdoSeqUnsupportedProt;
481 #endif
482                         break;
483                 }
484
485                 // unsupported protocols
486                 // -> auto should be replaced by command layer
487         case kEplSdoTypeAuto:
488         case kEplSdoTypePdo:
489         default:
490                 {
491                         Ret = kEplSdoSeqUnsupportedProt;
492                         goto Exit;
493                 }
494
495         }                       // end of switch(SdoType)
496
497         // find existing connection to the same node or find empty entry for connection
498         uiCount = 0;
499         uiFreeCon = EPL_MAX_SDO_SEQ_CON;
500         pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0];
501
502         while (uiCount < EPL_MAX_SDO_SEQ_CON) {
503                 if (pAsySdoSeqCon->m_ConHandle == ConHandle) {  // existing connection found
504                         break;
505                 }
506                 if (pAsySdoSeqCon->m_ConHandle == 0) {
507                         uiFreeCon = uiCount;
508                 }
509                 uiCount++;
510                 pAsySdoSeqCon++;
511         }
512
513         if (uiCount == EPL_MAX_SDO_SEQ_CON) {
514                 if (uiFreeCon == EPL_MAX_SDO_SEQ_CON) { // no free entry found
515                         switch (SdoType) {
516                                 // SDO over UDP
517                         case kEplSdoTypeUdp:
518                                 {
519 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
520                                         Ret = EplSdoUdpuDelCon(ConHandle);
521                                         if (Ret != kEplSuccessful) {
522                                                 goto Exit;
523                                         }
524 #endif
525                                         break;
526                                 }
527
528                                 // SDO over Asnd
529                         case kEplSdoTypeAsnd:
530                                 {
531 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
532                                         Ret = EplSdoAsnduDelCon(ConHandle);
533                                         if (Ret != kEplSuccessful) {
534                                                 goto Exit;
535                                         }
536 #endif
537                                         break;
538                                 }
539
540                                 // unsupported protocols
541                                 // -> auto should be replaced by command layer
542                         case kEplSdoTypeAuto:
543                         case kEplSdoTypePdo:
544                         default:
545                                 {
546                                         Ret = kEplSdoSeqUnsupportedProt;
547                                         goto Exit;
548                                 }
549
550                         }       // end of switch(SdoType)
551
552                         Ret = kEplSdoSeqNoFreeHandle;
553                         goto Exit;
554                 } else {        // free entry found
555                         pAsySdoSeqCon =
556                             &AsySdoSequInstance_g.m_AsySdoConnection[uiFreeCon];
557                         pAsySdoSeqCon->m_ConHandle = ConHandle;
558                         uiCount = uiFreeCon;
559                 }
560         }
561         // set handle
562         *pSdoSeqConHdl_p = (uiCount | EPL_SDO_ASY_HANDLE);
563
564         // increment use counter
565         pAsySdoSeqCon->m_uiUseCount++;
566
567         // call intern process function
568         Ret = EplSdoAsySeqProcess(uiCount,
569                                   0, NULL, NULL, kAsySdoSeqEventInitCon);
570
571       Exit:
572         return Ret;
573 }
574
575 //---------------------------------------------------------------------------
576 //
577 // Function:    EplSdoAsySeqSendData
578 //
579 // Description: send sata unsing a established connection
580 //
581 //
582 //
583 // Parameters:  pSdoSeqConHdl_p = connection handle
584 //              uiDataSize_p    = Size of Frame to send
585 //                                  -> wihtout SDO sequence layer header, Asnd header
586 //                                     and ethernetnet
587 //                                  ==> SDO Sequence layer payload
588 //              SdoType          = Type of the SDO connection
589 //
590 //
591 // Returns:     tEplKernel = errorcode
592 //
593 //
594 // State:
595 //
596 //---------------------------------------------------------------------------
597 tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
598                                 unsigned int uiDataSize_p,
599                                 tEplFrame *pabData_p)
600 {
601         tEplKernel Ret;
602         unsigned int uiHandle;
603
604         uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK);
605
606         // check if connection ready
607         if (AsySdoSequInstance_g.m_AsySdoConnection[uiHandle].m_SdoState ==
608             kEplAsySdoStateIdle) {
609                 // no connection with this handle
610                 Ret = kEplSdoSeqInvalidHdl;
611                 goto Exit;
612         } else if (AsySdoSequInstance_g.m_AsySdoConnection[uiHandle].
613                    m_SdoState != kEplAsySdoStateConnected) {
614                 Ret = kEplSdoSeqConnectionBusy;
615                 goto Exit;
616         }
617
618         Ret = EplSdoAsySeqProcess(uiHandle,
619                                   uiDataSize_p,
620                                   pabData_p, NULL, kAsySdoSeqEventFrameSend);
621       Exit:
622         return Ret;
623 }
624
625 //---------------------------------------------------------------------------
626 //
627 // Function:    EplSdoAsySeqProcessEvent
628 //
629 // Description: function processes extern events
630 //              -> later needed for timeout controll with timer-module
631 //
632 //
633 //
634 // Parameters:  pEvent_p = pointer to event
635 //
636 //
637 // Returns:     tEplKernel = errorcode
638 //
639 //
640 // State:
641 //
642 //---------------------------------------------------------------------------
643 tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p)
644 {
645         tEplKernel Ret;
646         tEplTimerEventArg *pTimerEventArg;
647         tEplAsySdoSeqCon *pAsySdoSeqCon;
648         tEplTimerHdl EplTimerHdl;
649         unsigned int uiCount;
650
651         Ret = kEplSuccessful;
652         // check parameter
653         if (pEvent_p == NULL) {
654                 Ret = kEplSdoSeqInvalidEvent;
655                 goto Exit;
656         }
657
658         if (pEvent_p->m_EventType != kEplEventTypeTimer) {
659                 Ret = kEplSdoSeqInvalidEvent;
660                 goto Exit;
661         }
662         // get timerhdl
663         pTimerEventArg = (tEplTimerEventArg *) pEvent_p->m_pArg;
664         EplTimerHdl = pTimerEventArg->m_TimerHdl;
665
666         // get pointer to intern control structure of connection
667         if (pTimerEventArg->m_ulArg == 0) {
668                 goto Exit;
669         }
670         pAsySdoSeqCon = (tEplAsySdoSeqCon *) pTimerEventArg->m_ulArg;
671
672         // check if time is current
673         if (EplTimerHdl != pAsySdoSeqCon->m_EplTimerHdl) {
674                 // delete timer
675                 EplTimeruDeleteTimer(&EplTimerHdl);
676                 goto Exit;
677         }
678         // delete timer
679         EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
680
681         // get indexnumber of control structure
682         uiCount = 0;
683         while ((&AsySdoSequInstance_g.m_AsySdoConnection[uiCount]) !=
684                pAsySdoSeqCon) {
685                 uiCount++;
686                 if (uiCount > EPL_MAX_SDO_SEQ_CON) {
687                         goto Exit;
688                 }
689         }
690
691         // process event and call processfunction if needed
692         Ret = EplSdoAsySeqProcess(uiCount,
693                                   0, NULL, NULL, kAsySdoSeqEventTimeout);
694
695       Exit:
696         return Ret;
697
698 }
699
700 //---------------------------------------------------------------------------
701 //
702 // Function:    EplSdoAsySeqDelCon
703 //
704 // Description: del and close one connection
705 //
706 //
707 //
708 // Parameters:  SdoSeqConHdl_p = handle of connection
709 //
710 //
711 // Returns:     tEplKernel = errorcode
712 //
713 //
714 // State:
715 //
716 //---------------------------------------------------------------------------
717 tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p)
718 {
719         tEplKernel Ret = kEplSuccessful;
720         unsigned int uiHandle;
721         tEplAsySdoSeqCon *pAsySdoSeqCon;
722
723         uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK);
724
725         // check if handle invalid
726         if (uiHandle >= EPL_MAX_SDO_SEQ_CON) {
727                 Ret = kEplSdoSeqInvalidHdl;
728                 goto Exit;
729         }
730         // get pointer to connection
731         pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle];
732
733         // decrement use counter
734         pAsySdoSeqCon->m_uiUseCount--;
735
736         if (pAsySdoSeqCon->m_uiUseCount == 0) {
737                 // process close in processfunction
738                 Ret = EplSdoAsySeqProcess(uiHandle,
739                                           0,
740                                           NULL, NULL, kAsySdoSeqEventCloseCon);
741
742                 //check protocol
743                 if ((pAsySdoSeqCon->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) ==
744                     EPL_SDO_UDP_HANDLE) {
745 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
746                         // call close function of lower layer
747                         EplSdoUdpuDelCon(pAsySdoSeqCon->m_ConHandle);
748 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
749                 } else {
750 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
751                         // call close function of lower layer
752                         EplSdoAsnduDelCon(pAsySdoSeqCon->m_ConHandle);
753 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
754                 }
755
756                 // delete timer
757                 EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
758
759                 // clean controllstructure
760                 EPL_MEMSET(pAsySdoSeqCon, 0x00, sizeof(tEplAsySdoSeqCon));
761                 pAsySdoSeqCon->m_SdoConHistory.m_bFreeEntries =
762                     EPL_SDO_HISTORY_SIZE;
763         }
764
765       Exit:
766         return Ret;
767
768 }
769
770 //=========================================================================//
771 //                                                                         //
772 //          P R I V A T E   F U N C T I O N S                              //
773 //                                                                         //
774 //=========================================================================//
775
776 //---------------------------------------------------------------------------
777 //
778 // Function:    EplEplSdoAsySeqProcess
779 //
780 // Description: intern function to process the asynchronus SDO Sequence Layer
781 //              state maschine
782 //
783 //
784 //
785 // Parameters:  uiHandle_p      = index of the control structure of the connection
786 //              uiDataSize_p    = size of data frame to process (can be 0)
787 //                                  -> without size of sequence header and Asnd header!!!
788 //
789 //              pData_p         = pointer to frame to send (can be NULL)
790 //              pRecFrame_p     = pointer to received frame (can be NULL)
791 //              Event_p         = Event to process
792 //
793 //
794 //
795 // Returns:     tEplKernel = errorcode
796 //
797 //
798 // State:
799 //
800 //---------------------------------------------------------------------------
801 static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p,
802                                       unsigned int uiDataSize_p,
803                                       tEplFrame * pData_p,
804                                       tEplAsySdoSeq * pRecFrame_p,
805                                       tEplAsySdoSeqEvent Event_p)
806 {
807         tEplKernel Ret;
808         unsigned int uiFrameSize;
809         tEplFrame *pEplFrame;
810         tEplAsySdoSeqCon *pAsySdoSeqCon;
811         tEplSdoSeqConHdl SdoSeqConHdl;
812         unsigned int uiFreeEntries;
813
814 #if defined(WIN32) || defined(_WIN32)
815         // enter  critical section for process function
816         EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
817 #endif
818
819         Ret = kEplSuccessful;
820
821         // get handle for hinger layer
822         SdoSeqConHdl = uiHandle_p | EPL_SDO_ASY_HANDLE;
823
824         // check if handle invalid
825         if ((SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) ==
826             EPL_SDO_SEQ_INVALID_HDL) {
827                 Ret = kEplSdoSeqInvalidHdl;
828                 goto Exit;
829         }
830         // get pointer to connection
831         pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle_p];
832
833         // check size
834         if ((pData_p == NULL) && (pRecFrame_p == NULL) && (uiDataSize_p != 0)) {
835                 Ret = kEplSdoSeqInvalidFrame;
836                 goto Exit;
837         }
838         // check state
839         switch (pAsySdoSeqCon->m_SdoState) {
840                 // idle state
841         case kEplAsySdoStateIdle:
842                 {
843                         // check event
844                         switch (Event_p) {
845                                 // new connection
846                                 // -> send init frame and change to
847                                 // kEplAsySdoStateInit1
848                         case kAsySdoSeqEventInitCon:
849                                 {
850                                         // set sending scon to 1
851                                         pAsySdoSeqCon->m_bRecSeqNum = 0x01;
852                                         // set set send rcon to 0
853                                         pAsySdoSeqCon->m_bSendSeqNum = 0x00;
854                                         Ret =
855                                             EplSdoAsySeqSendIntern
856                                             (pAsySdoSeqCon, 0, NULL, FALSE);
857                                         if (Ret != kEplSuccessful) {
858                                                 goto Exit;
859                                         }
860                                         // change state
861                                         pAsySdoSeqCon->m_SdoState =
862                                             kEplAsySdoStateInit1;
863
864                                         // set timer
865                                         Ret =
866                                             EplSdoAsySeqSetTimer(pAsySdoSeqCon,
867                                                                  EPL_SEQ_DEFAULT_TIMEOUT);
868
869                                         break;
870                                 }
871
872                                 // init con from extern
873                                 // check rcon and scon
874                                 // -> send answer
875                         case kAsySdoSeqEventFrameRec:
876                                 {
877 /*
878                     PRINTF3("%s scon=%u rcon=%u\n",
879                             __func__,
880                             pRecFrame_p->m_le_bSendSeqNumCon,
881                             pRecFrame_p->m_le_bRecSeqNumCon);
882 */
883                                         // check if scon == 1 and rcon == 0
884                                         if (((pRecFrame_p->
885                                               m_le_bRecSeqNumCon &
886                                               EPL_ASY_SDO_CON_MASK) == 0x00)
887                                             &&
888                                             ((pRecFrame_p->
889                                               m_le_bSendSeqNumCon &
890                                               EPL_ASY_SDO_CON_MASK) == 0x01)) {
891                                                 // save sequence numbers
892                                                 pAsySdoSeqCon->m_bRecSeqNum =
893                                                     AmiGetByteFromLe
894                                                     (&pRecFrame_p->
895                                                      m_le_bRecSeqNumCon);
896                                                 pAsySdoSeqCon->m_bSendSeqNum =
897                                                     AmiGetByteFromLe
898                                                     (&pRecFrame_p->
899                                                      m_le_bSendSeqNumCon);
900                                                 // create answer and send answer
901                                                 // set rcon to 1 (in send direction own scon)
902                                                 pAsySdoSeqCon->m_bRecSeqNum++;
903                                                 Ret =
904                                                     EplSdoAsySeqSendIntern
905                                                     (pAsySdoSeqCon, 0, NULL,
906                                                      FALSE);
907                                                 if (Ret != kEplSuccessful) {
908                                                         goto Exit;
909                                                 }
910                                                 // change state to kEplAsySdoStateInit2
911                                                 pAsySdoSeqCon->m_SdoState =
912                                                     kEplAsySdoStateInit2;
913
914                                                 // set timer
915                                                 Ret =
916                                                     EplSdoAsySeqSetTimer
917                                                     (pAsySdoSeqCon,
918                                                      EPL_SEQ_DEFAULT_TIMEOUT);
919                                         } else {        // error -> close
920                                                 // delete timer
921                                                 EplTimeruDeleteTimer
922                                                     (&pAsySdoSeqCon->
923                                                      m_EplTimerHdl);
924                                                 if (((pRecFrame_p->
925                                                       m_le_bRecSeqNumCon &
926                                                       EPL_ASY_SDO_CON_MASK) !=
927                                                      0x00)
928                                                     || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) {   // d.k. only answer with close message if the message sent was not a close message
929                                                         // save sequence numbers
930                                                         pAsySdoSeqCon->
931                                                             m_bRecSeqNum =
932                                                             AmiGetByteFromLe
933                                                             (&pRecFrame_p->
934                                                              m_le_bRecSeqNumCon);
935                                                         pAsySdoSeqCon->
936                                                             m_bSendSeqNum =
937                                                             AmiGetByteFromLe
938                                                             (&pRecFrame_p->
939                                                              m_le_bSendSeqNumCon);
940                                                         // set rcon and scon to 0
941                                                         pAsySdoSeqCon->
942                                                             m_bSendSeqNum &=
943                                                             EPL_SEQ_NUM_MASK;
944                                                         pAsySdoSeqCon->
945                                                             m_bRecSeqNum &=
946                                                             EPL_SEQ_NUM_MASK;
947                                                         // send frame
948                                                         EplSdoAsySeqSendIntern
949                                                             (pAsySdoSeqCon, 0,
950                                                              NULL, FALSE);
951                                                 }
952                                                 // call Command Layer Cb
953                                                 AsySdoSequInstance_g.
954                                                     m_fpSdoComConCb
955                                                     (SdoSeqConHdl,
956                                                      kAsySdoConStateInitError);
957                                         }
958                                         break;
959                                 }
960
961                         default:
962                                 // d.k. do nothing
963                                 break;
964
965                         }       // end of switch(Event_p)
966                         break;
967                 }
968
969                 // init connection step 1
970                 // wait for frame with scon = 1
971                 // and rcon = 1
972         case kEplAsySdoStateInit1:
973                 {
974 //            PRINTF0("EplSdoAsySequ: StateInit1\n");
975
976                         // check event
977                         switch (Event_p) {
978                                 // frame received
979                         case kAsySdoSeqEventFrameRec:
980                                 {
981                                         // check scon == 1 and rcon == 1
982                                         if (((pRecFrame_p->
983                                               m_le_bRecSeqNumCon &
984                                               EPL_ASY_SDO_CON_MASK) == 0x01)
985                                             && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01)) {   // create answer own scon = 2
986                                                 // save sequence numbers
987                                                 pAsySdoSeqCon->m_bRecSeqNum =
988                                                     AmiGetByteFromLe
989                                                     (&pRecFrame_p->
990                                                      m_le_bRecSeqNumCon);
991                                                 pAsySdoSeqCon->m_bSendSeqNum =
992                                                     AmiGetByteFromLe
993                                                     (&pRecFrame_p->
994                                                      m_le_bSendSeqNumCon);
995
996                                                 pAsySdoSeqCon->m_bRecSeqNum++;
997                                                 Ret =
998                                                     EplSdoAsySeqSendIntern
999                                                     (pAsySdoSeqCon, 0, NULL,
1000                                                      FALSE);
1001                                                 if (Ret != kEplSuccessful) {
1002                                                         goto Exit;
1003                                                 }
1004                                                 // change state to kEplAsySdoStateInit3
1005                                                 pAsySdoSeqCon->m_SdoState =
1006                                                     kEplAsySdoStateInit3;
1007
1008                                                 // set timer
1009                                                 Ret =
1010                                                     EplSdoAsySeqSetTimer
1011                                                     (pAsySdoSeqCon,
1012                                                      EPL_SEQ_DEFAULT_TIMEOUT);
1013
1014                                         }
1015                                         // check if scon == 1 and rcon == 0, i.e. other side wants me to be server
1016                                         else if (((pRecFrame_p->
1017                                                    m_le_bRecSeqNumCon &
1018                                                    EPL_ASY_SDO_CON_MASK) ==
1019                                                   0x00)
1020                                                  &&
1021                                                  ((pRecFrame_p->
1022                                                    m_le_bSendSeqNumCon &
1023                                                    EPL_ASY_SDO_CON_MASK) ==
1024                                                   0x01)) {
1025                                                 // save sequence numbers
1026                                                 pAsySdoSeqCon->m_bRecSeqNum =
1027                                                     AmiGetByteFromLe
1028                                                     (&pRecFrame_p->
1029                                                      m_le_bRecSeqNumCon);
1030                                                 pAsySdoSeqCon->m_bSendSeqNum =
1031                                                     AmiGetByteFromLe
1032                                                     (&pRecFrame_p->
1033                                                      m_le_bSendSeqNumCon);
1034                                                 // create answer and send answer
1035                                                 // set rcon to 1 (in send direction own scon)
1036                                                 pAsySdoSeqCon->m_bRecSeqNum++;
1037                                                 Ret =
1038                                                     EplSdoAsySeqSendIntern
1039                                                     (pAsySdoSeqCon, 0, NULL,
1040                                                      FALSE);
1041                                                 if (Ret != kEplSuccessful) {
1042                                                         goto Exit;
1043                                                 }
1044                                                 // change state to kEplAsySdoStateInit2
1045                                                 pAsySdoSeqCon->m_SdoState =
1046                                                     kEplAsySdoStateInit2;
1047
1048                                                 // set timer
1049                                                 Ret =
1050                                                     EplSdoAsySeqSetTimer
1051                                                     (pAsySdoSeqCon,
1052                                                      EPL_SEQ_DEFAULT_TIMEOUT);
1053                                         } else {        // error -> Close
1054                                                 pAsySdoSeqCon->m_SdoState =
1055                                                     kEplAsySdoStateIdle;
1056                                                 // delete timer
1057                                                 EplTimeruDeleteTimer
1058                                                     (&pAsySdoSeqCon->
1059                                                      m_EplTimerHdl);
1060                                                 if (((pRecFrame_p->
1061                                                       m_le_bRecSeqNumCon &
1062                                                       EPL_ASY_SDO_CON_MASK) !=
1063                                                      0x00)
1064                                                     || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) {   // d.k. only answer with close message if the message sent was not a close message
1065                                                         // save sequence numbers
1066                                                         pAsySdoSeqCon->
1067                                                             m_bRecSeqNum =
1068                                                             AmiGetByteFromLe
1069                                                             (&pRecFrame_p->
1070                                                              m_le_bRecSeqNumCon);
1071                                                         pAsySdoSeqCon->
1072                                                             m_bSendSeqNum =
1073                                                             AmiGetByteFromLe
1074                                                             (&pRecFrame_p->
1075                                                              m_le_bSendSeqNumCon);
1076
1077                                                         // set rcon and scon to 0
1078                                                         pAsySdoSeqCon->
1079                                                             m_bSendSeqNum &=
1080                                                             EPL_SEQ_NUM_MASK;
1081                                                         pAsySdoSeqCon->
1082                                                             m_bRecSeqNum &=
1083                                                             EPL_SEQ_NUM_MASK;
1084                                                         // send frame
1085                                                         EplSdoAsySeqSendIntern
1086                                                             (pAsySdoSeqCon, 0,
1087                                                              NULL, FALSE);
1088                                                 }
1089                                                 // call Command Layer Cb
1090                                                 AsySdoSequInstance_g.
1091                                                     m_fpSdoComConCb
1092                                                     (SdoSeqConHdl,
1093                                                      kAsySdoConStateInitError);
1094                                         }
1095                                         break;
1096                                 }
1097
1098                                 // timeout
1099                         case kAsySdoSeqEventTimeout:
1100                                 {       // error -> Close
1101                                         pAsySdoSeqCon->m_SdoState =
1102                                             kEplAsySdoStateIdle;
1103
1104                                         // set rcon and scon to 0
1105                                         pAsySdoSeqCon->m_bSendSeqNum &=
1106                                             EPL_SEQ_NUM_MASK;
1107                                         pAsySdoSeqCon->m_bRecSeqNum &=
1108                                             EPL_SEQ_NUM_MASK;
1109                                         // send frame
1110                                         EplSdoAsySeqSendIntern(pAsySdoSeqCon,
1111                                                                0, NULL, FALSE);
1112                                         // call Command Layer Cb
1113                                         AsySdoSequInstance_g.
1114                                             m_fpSdoComConCb(SdoSeqConHdl,
1115                                                             kAsySdoConStateInitError);
1116                                         break;
1117                                 }
1118
1119                         default:
1120                                 // d.k. do nothing
1121                                 break;
1122
1123                         }       // end of switch(Event_p)
1124                         break;
1125                 }
1126
1127                 // init connection step 2
1128         case kEplAsySdoStateInit2:
1129                 {
1130 //            PRINTF0("EplSdoAsySequ: StateInit2\n");
1131
1132                         // check event
1133                         switch (Event_p) {
1134                                 // frame received
1135                         case kAsySdoSeqEventFrameRec:
1136                                 {
1137                                         // check scon == 2 and rcon == 1
1138                                         if (((pRecFrame_p->
1139                                               m_le_bRecSeqNumCon &
1140                                               EPL_ASY_SDO_CON_MASK) == 0x01)
1141                                             && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02)) {   // create answer own rcon = 2
1142                                                 // save sequence numbers
1143                                                 pAsySdoSeqCon->m_bRecSeqNum =
1144                                                     AmiGetByteFromLe
1145                                                     (&pRecFrame_p->
1146                                                      m_le_bRecSeqNumCon);
1147                                                 pAsySdoSeqCon->m_bSendSeqNum =
1148                                                     AmiGetByteFromLe
1149                                                     (&pRecFrame_p->
1150                                                      m_le_bSendSeqNumCon);
1151
1152                                                 pAsySdoSeqCon->m_bRecSeqNum++;
1153                                                 Ret =
1154                                                     EplSdoAsySeqSendIntern
1155                                                     (pAsySdoSeqCon, 0, NULL,
1156                                                      FALSE);
1157                                                 if (Ret != kEplSuccessful) {
1158                                                         goto Exit;
1159                                                 }
1160                                                 // change state to kEplAsySdoStateConnected
1161                                                 pAsySdoSeqCon->m_SdoState =
1162                                                     kEplAsySdoStateConnected;
1163
1164                                                 // set timer
1165                                                 Ret =
1166                                                     EplSdoAsySeqSetTimer
1167                                                     (pAsySdoSeqCon,
1168                                                      EPL_SEQ_DEFAULT_TIMEOUT);
1169
1170                                                 // call Command Layer Cb
1171                                                 AsySdoSequInstance_g.
1172                                                     m_fpSdoComConCb
1173                                                     (SdoSeqConHdl,
1174                                                      kAsySdoConStateConnected);
1175
1176                                         }
1177                                         // check scon == 1 and rcon == 1, i.e. other side wants me to initiate the connection
1178                                         else if (((pRecFrame_p->
1179                                                    m_le_bRecSeqNumCon &
1180                                                    EPL_ASY_SDO_CON_MASK) ==
1181                                                   0x01)
1182                                                  &&
1183                                                  ((pRecFrame_p->
1184                                                    m_le_bSendSeqNumCon &
1185                                                    EPL_ASY_SDO_CON_MASK) ==
1186                                                   0x01)) {
1187                                                 // save sequence numbers
1188                                                 pAsySdoSeqCon->m_bRecSeqNum =
1189                                                     AmiGetByteFromLe
1190                                                     (&pRecFrame_p->
1191                                                      m_le_bRecSeqNumCon);
1192                                                 pAsySdoSeqCon->m_bSendSeqNum =
1193                                                     AmiGetByteFromLe
1194                                                     (&pRecFrame_p->
1195                                                      m_le_bSendSeqNumCon);
1196                                                 // create answer and send answer
1197                                                 // set rcon to 1 (in send direction own scon)
1198                                                 pAsySdoSeqCon->m_bRecSeqNum++;
1199                                                 Ret =
1200                                                     EplSdoAsySeqSendIntern
1201                                                     (pAsySdoSeqCon, 0, NULL,
1202                                                      FALSE);
1203                                                 if (Ret != kEplSuccessful) {
1204                                                         goto Exit;
1205                                                 }
1206                                                 // set timer
1207                                                 Ret =
1208                                                     EplSdoAsySeqSetTimer
1209                                                     (pAsySdoSeqCon,
1210                                                      EPL_SEQ_DEFAULT_TIMEOUT);
1211                                                 // change state to kEplAsySdoStateInit3
1212                                                 pAsySdoSeqCon->m_SdoState =
1213                                                     kEplAsySdoStateInit3;
1214
1215                                         } else {        // error -> Close
1216                                                 pAsySdoSeqCon->m_SdoState =
1217                                                     kEplAsySdoStateIdle;
1218                                                 // delete timer
1219                                                 EplTimeruDeleteTimer
1220                                                     (&pAsySdoSeqCon->
1221                                                      m_EplTimerHdl);
1222                                                 if (((pRecFrame_p->
1223                                                       m_le_bRecSeqNumCon &
1224                                                       EPL_ASY_SDO_CON_MASK) !=
1225                                                      0x00)
1226                                                     || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) {   // d.k. only answer with close message if the message sent was not a close message
1227                                                         // save sequence numbers
1228                                                         pAsySdoSeqCon->
1229                                                             m_bRecSeqNum =
1230                                                             AmiGetByteFromLe
1231                                                             (&pRecFrame_p->
1232                                                              m_le_bRecSeqNumCon);
1233                                                         pAsySdoSeqCon->
1234                                                             m_bSendSeqNum =
1235                                                             AmiGetByteFromLe
1236                                                             (&pRecFrame_p->
1237                                                              m_le_bSendSeqNumCon);
1238                                                         // set rcon and scon to 0
1239                                                         pAsySdoSeqCon->
1240                                                             m_bSendSeqNum &=
1241                                                             EPL_SEQ_NUM_MASK;
1242                                                         pAsySdoSeqCon->
1243                                                             m_bRecSeqNum &=
1244                                                             EPL_SEQ_NUM_MASK;
1245                                                         // send frame
1246                                                         EplSdoAsySeqSendIntern
1247                                                             (pAsySdoSeqCon, 0,
1248                                                              NULL, FALSE);
1249                                                 }
1250                                                 // call Command Layer Cb
1251                                                 AsySdoSequInstance_g.
1252                                                     m_fpSdoComConCb
1253                                                     (SdoSeqConHdl,
1254                                                      kAsySdoConStateInitError);
1255                                         }
1256                                         break;
1257                                 }
1258
1259                                 // timeout
1260                         case kAsySdoSeqEventTimeout:
1261                                 {       // error -> Close
1262                                         pAsySdoSeqCon->m_SdoState =
1263                                             kEplAsySdoStateIdle;
1264                                         // set rcon and scon to 0
1265                                         pAsySdoSeqCon->m_bSendSeqNum &=
1266                                             EPL_SEQ_NUM_MASK;
1267                                         pAsySdoSeqCon->m_bRecSeqNum &=
1268                                             EPL_SEQ_NUM_MASK;
1269                                         // send frame
1270                                         EplSdoAsySeqSendIntern(pAsySdoSeqCon,
1271                                                                0, NULL, FALSE);
1272
1273                                         // call Command Layer Cb
1274                                         AsySdoSequInstance_g.
1275                                             m_fpSdoComConCb(SdoSeqConHdl,
1276                                                             kAsySdoConStateInitError);
1277                                         break;
1278                                 }
1279
1280                         default:
1281                                 // d.k. do nothing
1282                                 break;
1283
1284                         }       // end of switch(Event_p)
1285                         break;
1286                 }
1287
1288                 // init connection step 3
1289         case kEplAsySdoStateInit3:
1290                 {
1291                         // check event
1292                         switch (Event_p) {
1293                                 // frame received
1294                         case kAsySdoSeqEventFrameRec:
1295                                 {
1296                                         // check scon == 2 and rcon == 2
1297                                         if (((pRecFrame_p->
1298                                               m_le_bRecSeqNumCon &
1299                                               EPL_ASY_SDO_CON_MASK) == 0x02)
1300                                             &&
1301                                             ((pRecFrame_p->
1302                                               m_le_bSendSeqNumCon &
1303                                               EPL_ASY_SDO_CON_MASK) == 0x02)) {
1304                                                 // save sequence numbers
1305                                                 pAsySdoSeqCon->m_bRecSeqNum =
1306                                                     AmiGetByteFromLe
1307                                                     (&pRecFrame_p->
1308                                                      m_le_bRecSeqNumCon);
1309                                                 pAsySdoSeqCon->m_bSendSeqNum =
1310                                                     AmiGetByteFromLe
1311                                                     (&pRecFrame_p->
1312                                                      m_le_bSendSeqNumCon);
1313                                                 // change state to kEplAsySdoStateConnected
1314                                                 pAsySdoSeqCon->m_SdoState =
1315                                                     kEplAsySdoStateConnected;
1316
1317                                                 // set timer
1318                                                 Ret =
1319                                                     EplSdoAsySeqSetTimer
1320                                                     (pAsySdoSeqCon,
1321                                                      EPL_SEQ_DEFAULT_TIMEOUT);
1322                                                 // call Command Layer Cb
1323                                                 AsySdoSequInstance_g.
1324                                                     m_fpSdoComConCb
1325                                                     (SdoSeqConHdl,
1326                                                      kAsySdoConStateConnected);
1327
1328                                         }
1329                                         // check scon == 2 and rcon == 1
1330                                         else if (((pRecFrame_p->
1331                                                    m_le_bRecSeqNumCon &
1332                                                    EPL_ASY_SDO_CON_MASK) ==
1333                                                   0x01)
1334                                                  && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02)) {      // create answer own rcon = 2
1335                                                 // save sequence numbers
1336                                                 pAsySdoSeqCon->m_bRecSeqNum =
1337                                                     AmiGetByteFromLe
1338                                                     (&pRecFrame_p->
1339                                                      m_le_bRecSeqNumCon);
1340                                                 pAsySdoSeqCon->m_bSendSeqNum =
1341                                                     AmiGetByteFromLe
1342                                                     (&pRecFrame_p->
1343                                                      m_le_bSendSeqNumCon);
1344
1345                                                 pAsySdoSeqCon->m_bRecSeqNum++;
1346                                                 Ret =
1347                                                     EplSdoAsySeqSendIntern
1348                                                     (pAsySdoSeqCon, 0, NULL,
1349                                                      FALSE);
1350                                                 if (Ret != kEplSuccessful) {
1351                                                         goto Exit;
1352                                                 }
1353                                                 // change state to kEplAsySdoStateConnected
1354                                                 pAsySdoSeqCon->m_SdoState =
1355                                                     kEplAsySdoStateConnected;
1356
1357                                                 // set timer
1358                                                 Ret =
1359                                                     EplSdoAsySeqSetTimer
1360                                                     (pAsySdoSeqCon,
1361                                                      EPL_SEQ_DEFAULT_TIMEOUT);
1362
1363                                                 // call Command Layer Cb
1364                                                 AsySdoSequInstance_g.
1365                                                     m_fpSdoComConCb
1366                                                     (SdoSeqConHdl,
1367                                                      kAsySdoConStateConnected);
1368
1369                                         } else {        // error -> Close
1370                                                 pAsySdoSeqCon->m_SdoState =
1371                                                     kEplAsySdoStateIdle;
1372                                                 // delete timer
1373                                                 EplTimeruDeleteTimer
1374                                                     (&pAsySdoSeqCon->
1375                                                      m_EplTimerHdl);
1376                                                 if (((pRecFrame_p->
1377                                                       m_le_bRecSeqNumCon &
1378                                                       EPL_ASY_SDO_CON_MASK) !=
1379                                                      0x00)
1380                                                     || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) {   // d.k. only answer with close message if the message sent was not a close message
1381                                                         // save sequence numbers
1382                                                         pAsySdoSeqCon->
1383                                                             m_bRecSeqNum =
1384                                                             AmiGetByteFromLe
1385                                                             (&pRecFrame_p->
1386                                                              m_le_bRecSeqNumCon);
1387                                                         pAsySdoSeqCon->
1388                                                             m_bSendSeqNum =
1389                                                             AmiGetByteFromLe
1390                                                             (&pRecFrame_p->
1391                                                              m_le_bSendSeqNumCon);
1392                                                         // set rcon and scon to 0
1393                                                         pAsySdoSeqCon->
1394                                                             m_bSendSeqNum &=
1395                                                             EPL_SEQ_NUM_MASK;
1396                                                         pAsySdoSeqCon->
1397                                                             m_bRecSeqNum &=
1398                                                             EPL_SEQ_NUM_MASK;
1399                                                         // send frame
1400                                                         EplSdoAsySeqSendIntern
1401                                                             (pAsySdoSeqCon, 0,
1402                                                              NULL, FALSE);
1403                                                 }
1404                                                 // call Command Layer Cb
1405                                                 AsySdoSequInstance_g.
1406                                                     m_fpSdoComConCb
1407                                                     (SdoSeqConHdl,
1408                                                      kAsySdoConStateInitError);
1409                                         }
1410                                         break;
1411                                 }
1412
1413                                 // timeout
1414                         case kAsySdoSeqEventTimeout:
1415                                 {       // error -> Close
1416                                         pAsySdoSeqCon->m_SdoState =
1417                                             kEplAsySdoStateIdle;
1418                                         // set rcon and scon to 0
1419                                         pAsySdoSeqCon->m_bSendSeqNum &=
1420                                             EPL_SEQ_NUM_MASK;
1421                                         pAsySdoSeqCon->m_bRecSeqNum &=
1422                                             EPL_SEQ_NUM_MASK;
1423                                         // send frame
1424                                         EplSdoAsySeqSendIntern(pAsySdoSeqCon,
1425                                                                0, NULL, FALSE);
1426
1427                                         // call Command Layer Cb
1428                                         AsySdoSequInstance_g.
1429                                             m_fpSdoComConCb(SdoSeqConHdl,
1430                                                             kAsySdoConStateInitError);
1431                                         break;
1432                                 }
1433
1434                         default:
1435                                 // d.k. do nothing
1436                                 break;
1437
1438                         }       // end of switch(Event_p)
1439                         break;
1440                 }
1441
1442                 // connection established
1443         case kEplAsySdoStateConnected:
1444                 {
1445                         // check event
1446                         switch (Event_p) {
1447
1448                                 // frame to send
1449                         case kAsySdoSeqEventFrameSend:
1450                                 {
1451                                         // set timer
1452                                         Ret =
1453                                             EplSdoAsySeqSetTimer(pAsySdoSeqCon,
1454                                                                  EPL_SEQ_DEFAULT_TIMEOUT);
1455                                         // check if data frame or ack
1456                                         if (pData_p == NULL) {  // send ack
1457                                                 // inc scon
1458                                                 //pAsySdoSeqCon->m_bRecSeqNum += 4;
1459                                                 Ret =
1460                                                     EplSdoAsySeqSendIntern
1461                                                     (pAsySdoSeqCon, 0, NULL,
1462                                                      FALSE);
1463                                                 if (Ret != kEplSuccessful) {
1464                                                         goto Exit;
1465                                                 }
1466                                         } else {        // send dataframe
1467                                                 // increment send sequence number
1468                                                 pAsySdoSeqCon->m_bRecSeqNum +=
1469                                                     4;
1470                                                 Ret =
1471                                                     EplSdoAsySeqSendIntern
1472                                                     (pAsySdoSeqCon,
1473                                                      uiDataSize_p, pData_p,
1474                                                      TRUE);
1475                                                 if (Ret == kEplSdoSeqRequestAckNeeded) {        // request ack
1476                                                         // change state to wait ack
1477                                                         pAsySdoSeqCon->
1478                                                             m_SdoState =
1479                                                             kEplAsySdoStateWaitAck;
1480                                                         // set Ret to kEplSuccessful, because no error
1481                                                         // for higher layer
1482                                                         Ret = kEplSuccessful;
1483
1484                                                 } else if (Ret !=
1485                                                            kEplSuccessful) {
1486                                                         goto Exit;
1487                                                 } else {
1488                                                         // call Command Layer Cb
1489                                                         AsySdoSequInstance_g.
1490                                                             m_fpSdoComConCb
1491                                                             (SdoSeqConHdl,
1492                                                              kAsySdoConStateFrameSended);
1493                                                 }
1494                                         }
1495                                         break;
1496                                 }       // end of case kAsySdoSeqEventFrameSend
1497
1498                                 // frame received
1499                         case kAsySdoSeqEventFrameRec:
1500                                 {
1501                                         u8 bSendSeqNumCon =
1502                                             AmiGetByteFromLe(&pRecFrame_p->
1503                                                              m_le_bSendSeqNumCon);
1504
1505                                         // set timer
1506                                         Ret =
1507                                             EplSdoAsySeqSetTimer(pAsySdoSeqCon,
1508                                                                  EPL_SEQ_DEFAULT_TIMEOUT);
1509                                         // check scon
1510                                         switch (bSendSeqNumCon &
1511                                                 EPL_ASY_SDO_CON_MASK) {
1512                                                 // close from other node
1513                                         case 0:
1514                                         case 1:
1515                                                 {
1516                                                         // return to idle
1517                                                         pAsySdoSeqCon->
1518                                                             m_SdoState =
1519                                                             kEplAsySdoStateIdle;
1520                                                         // delete timer
1521                                                         EplTimeruDeleteTimer
1522                                                             (&pAsySdoSeqCon->
1523                                                              m_EplTimerHdl);
1524                                                         // call Command Layer Cb
1525                                                         AsySdoSequInstance_g.
1526                                                             m_fpSdoComConCb
1527                                                             (SdoSeqConHdl,
1528                                                              kAsySdoConStateConClosed);
1529
1530                                                         break;
1531                                                 }
1532
1533                                                 // Request Ack or Error Ack
1534                                                 // possible contain data
1535                                         case 3:
1536                                                 // normal frame
1537                                         case 2:
1538                                                 {
1539                                                         if ((AmiGetByteFromLe
1540                                                              (&pRecFrame_p->
1541                                                               m_le_bRecSeqNumCon)
1542                                                              &
1543                                                              EPL_ASY_SDO_CON_MASK)
1544                                                             == 3) {
1545 //                                PRINTF0("EplSdoAsySequ: error response received\n");
1546
1547                                                                 // error response (retransmission request)
1548                                                                 // resend frames from history
1549
1550                                                                 // read frame from history
1551                                                                 Ret =
1552                                                                     EplSdoAsyReadFromHistory
1553                                                                     (pAsySdoSeqCon,
1554                                                                      &pEplFrame,
1555                                                                      &uiFrameSize,
1556                                                                      TRUE);
1557                                                                 if (Ret !=
1558                                                                     kEplSuccessful)
1559                                                                 {
1560                                                                         goto Exit;
1561                                                                 }
1562
1563                                                                 while ((pEplFrame != NULL)
1564                                                                        &&
1565                                                                        (uiFrameSize
1566                                                                         != 0)) {
1567                                                                         // send frame
1568                                                                         Ret =
1569                                                                             EplSdoAsySeqSendLowerLayer
1570                                                                             (pAsySdoSeqCon,
1571                                                                              uiFrameSize,
1572                                                                              pEplFrame);
1573                                                                         if (Ret
1574                                                                             !=
1575                                                                             kEplSuccessful)
1576                                                                         {
1577                                                                                 goto Exit;
1578                                                                         }
1579                                                                         // read next frame from history
1580                                                                         Ret =
1581                                                                             EplSdoAsyReadFromHistory
1582                                                                             (pAsySdoSeqCon,
1583                                                                              &pEplFrame,
1584                                                                              &uiFrameSize,
1585                                                                              FALSE);
1586                                                                         if (Ret
1587                                                                             !=
1588                                                                             kEplSuccessful)
1589                                                                         {
1590                                                                                 goto Exit;
1591                                                                         }
1592                                                                 }       // end of while((pabFrame != NULL)
1593                                                         }       // end of if (error response)
1594
1595                                                         if (((pAsySdoSeqCon->m_bSendSeqNum + 4) & EPL_SEQ_NUM_MASK) == (bSendSeqNumCon & EPL_SEQ_NUM_MASK)) {   // next frame of sequence received
1596                                                                 // save send sequence number (without ack request)
1597                                                                 pAsySdoSeqCon->
1598                                                                     m_bSendSeqNum
1599                                                                     =
1600                                                                     bSendSeqNumCon
1601                                                                     & ~0x01;
1602
1603                                                                 // check if ack or data-frame
1604                                                                 //ignore ack -> already processed
1605                                                                 if (uiDataSize_p
1606                                                                     >
1607                                                                     EPL_SEQ_HEADER_SIZE)
1608                                                                 {
1609                                                                         AsySdoSequInstance_g.
1610                                                                             m_fpSdoComReceiveCb
1611                                                                             (SdoSeqConHdl,
1612                                                                              ((tEplAsySdoCom *) & pRecFrame_p->m_le_abSdoSeqPayload), (uiDataSize_p - EPL_SEQ_HEADER_SIZE));
1613                                                                         // call Command Layer Cb
1614                                                                         AsySdoSequInstance_g.
1615                                                                             m_fpSdoComConCb
1616                                                                             (SdoSeqConHdl,
1617                                                                              kAsySdoConStateFrameSended);
1618
1619                                                                 } else {
1620                                                                         // call Command Layer Cb
1621                                                                         AsySdoSequInstance_g.
1622                                                                             m_fpSdoComConCb
1623                                                                             (SdoSeqConHdl,
1624                                                                              kAsySdoConStateAckReceived);
1625                                                                 }
1626                                                         } else if (((bSendSeqNumCon - pAsySdoSeqCon->m_bSendSeqNum - 4) & EPL_SEQ_NUM_MASK) < EPL_SEQ_NUM_THRESHOLD) {  // frame of sequence was lost,
1627                                                                 // because difference of received and old value
1628                                                                 // is less then halve of the values range.
1629
1630                                                                 // send error frame with own rcon = 3
1631                                                                 pAsySdoSeqCon->
1632                                                                     m_bSendSeqNum
1633                                                                     |= 0x03;
1634                                                                 Ret =
1635                                                                     EplSdoAsySeqSendIntern
1636                                                                     (pAsySdoSeqCon,
1637                                                                      0, NULL,
1638                                                                      FALSE);
1639                                                                 // restore send sequence number
1640                                                                 pAsySdoSeqCon->
1641                                                                     m_bSendSeqNum
1642                                                                     =
1643                                                                     (pAsySdoSeqCon->
1644                                                                      m_bSendSeqNum
1645                                                                      &
1646                                                                      EPL_SEQ_NUM_MASK)
1647                                                                     | 0x02;
1648                                                                 if (Ret !=
1649                                                                     kEplSuccessful)
1650                                                                 {
1651                                                                         goto Exit;
1652                                                                 }
1653                                                                 // break here, because a requested acknowledge
1654                                                                 // was sent implicitly above
1655                                                                 break;
1656                                                         }
1657                                                         // else, ignore repeated frame
1658
1659                                                         if ((bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 3) {     // ack request received
1660
1661                                                                 // create ack with own scon = 2
1662                                                                 Ret =
1663                                                                     EplSdoAsySeqSendIntern
1664                                                                     (pAsySdoSeqCon,
1665                                                                      0, NULL,
1666                                                                      FALSE);
1667                                                                 if (Ret !=
1668                                                                     kEplSuccessful)
1669                                                                 {
1670                                                                         goto Exit;
1671                                                                 }
1672                                                         }
1673
1674                                                         break;
1675                                                 }
1676
1677                                         }       // switch(pAsySdoSeqCon->m_bSendSeqNum & EPL_ASY_SDO_CON_MASK)
1678                                         break;
1679                                 }       // end of case kAsySdoSeqEventFrameRec:
1680
1681                                 //close event from higher layer
1682                         case kAsySdoSeqEventCloseCon:
1683                                 {
1684                                         pAsySdoSeqCon->m_SdoState =
1685                                             kEplAsySdoStateIdle;
1686                                         // set rcon and scon to 0
1687                                         pAsySdoSeqCon->m_bSendSeqNum &=
1688                                             EPL_SEQ_NUM_MASK;
1689                                         pAsySdoSeqCon->m_bRecSeqNum &=
1690                                             EPL_SEQ_NUM_MASK;
1691                                         // send frame
1692                                         EplSdoAsySeqSendIntern(pAsySdoSeqCon,
1693                                                                0, NULL, FALSE);
1694
1695                                         // delete timer
1696                                         EplTimeruDeleteTimer(&pAsySdoSeqCon->
1697                                                              m_EplTimerHdl);
1698                                         // call Command Layer Cb is not necessary, because the event came from there
1699 //                    AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
1700 //                                                            kAsySdoConStateInitError);
1701                                         break;
1702                                 }
1703
1704                                 // timeout
1705                         case kAsySdoSeqEventTimeout:
1706                                 {
1707
1708                                         uiFreeEntries =
1709                                             EplSdoAsyGetFreeEntriesFromHistory
1710                                             (pAsySdoSeqCon);
1711                                         if ((uiFreeEntries <
1712                                              EPL_SDO_HISTORY_SIZE)
1713                                             && (pAsySdoSeqCon->m_uiRetryCount < EPL_SEQ_RETRY_COUNT)) { // unacknowlegded frames in history
1714                                                 // and retry counter not exceeded
1715
1716                                                 // resend data with acknowledge request
1717
1718                                                 // increment retry counter
1719                                                 pAsySdoSeqCon->m_uiRetryCount++;
1720
1721                                                 // set timer
1722                                                 Ret =
1723                                                     EplSdoAsySeqSetTimer
1724                                                     (pAsySdoSeqCon,
1725                                                      EPL_SEQ_DEFAULT_TIMEOUT);
1726
1727                                                 // read first frame from history
1728                                                 Ret =
1729                                                     EplSdoAsyReadFromHistory
1730                                                     (pAsySdoSeqCon, &pEplFrame,
1731                                                      &uiFrameSize, TRUE);
1732                                                 if (Ret != kEplSuccessful) {
1733                                                         goto Exit;
1734                                                 }
1735
1736                                                 if ((pEplFrame != NULL)
1737                                                     && (uiFrameSize != 0)) {
1738
1739                                                         // set ack request in scon
1740                                                         AmiSetByteToLe
1741                                                             (&pEplFrame->m_Data.
1742                                                              m_Asnd.m_Payload.
1743                                                              m_SdoSequenceFrame.
1744                                                              m_le_bSendSeqNumCon,
1745                                                              AmiGetByteFromLe
1746                                                              (&pEplFrame->
1747                                                               m_Data.m_Asnd.
1748                                                               m_Payload.
1749                                                               m_SdoSequenceFrame.
1750                                                               m_le_bSendSeqNumCon)
1751                                                              | 0x03);
1752
1753                                                         // send frame
1754                                                         Ret =
1755                                                             EplSdoAsySeqSendLowerLayer
1756                                                             (pAsySdoSeqCon,
1757                                                              uiFrameSize,
1758                                                              pEplFrame);
1759                                                         if (Ret !=
1760                                                             kEplSuccessful) {
1761                                                                 goto Exit;
1762                                                         }
1763
1764                                                 }
1765                                         } else {
1766                                                 // timeout, because of no traffic -> Close
1767                                                 pAsySdoSeqCon->m_SdoState =
1768                                                     kEplAsySdoStateIdle;
1769                                                 // set rcon and scon to 0
1770                                                 pAsySdoSeqCon->m_bSendSeqNum &=
1771                                                     EPL_SEQ_NUM_MASK;
1772                                                 pAsySdoSeqCon->m_bRecSeqNum &=
1773                                                     EPL_SEQ_NUM_MASK;
1774                                                 // send frame
1775                                                 EplSdoAsySeqSendIntern
1776                                                     (pAsySdoSeqCon, 0, NULL,
1777                                                      FALSE);
1778
1779                                                 // call Command Layer Cb
1780                                                 AsySdoSequInstance_g.
1781                                                     m_fpSdoComConCb
1782                                                     (SdoSeqConHdl,
1783                                                      kAsySdoConStateTimeout);
1784                                         }
1785
1786                                         break;
1787                                 }
1788
1789                         default:
1790                                 // d.k. do nothing
1791                                 break;
1792
1793                         }       // end of switch(Event_p)
1794                         break;
1795                 }
1796
1797                 // wait for Acknowledge (history buffer full)
1798         case kEplAsySdoStateWaitAck:
1799                 {
1800                         PRINTF0("EplSdoAsySequ: StateWaitAck\n");
1801
1802                         // set timer
1803                         Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
1804                                                    EPL_SEQ_DEFAULT_TIMEOUT);
1805
1806                         //TODO: retry of acknowledge
1807                         if (Event_p == kAsySdoSeqEventFrameRec) {
1808                                 // check rcon
1809                                 switch (pRecFrame_p->
1810                                         m_le_bRecSeqNumCon &
1811                                         EPL_ASY_SDO_CON_MASK) {
1812                                         // close-frome other node
1813                                 case 0:
1814                                         {
1815                                                 // return to idle
1816                                                 pAsySdoSeqCon->m_SdoState =
1817                                                     kEplAsySdoStateIdle;
1818                                                 // delete timer
1819                                                 EplTimeruDeleteTimer
1820                                                     (&pAsySdoSeqCon->
1821                                                      m_EplTimerHdl);
1822                                                 // call Command Layer Cb
1823                                                 AsySdoSequInstance_g.
1824                                                     m_fpSdoComConCb
1825                                                     (SdoSeqConHdl,
1826                                                      kAsySdoConStateConClosed);
1827
1828                                                 break;
1829                                         }
1830
1831                                         // normal frame
1832                                 case 2:
1833                                         {
1834                                                 // should be ack
1835                                                 // -> change to state kEplAsySdoStateConnected
1836                                                 pAsySdoSeqCon->m_SdoState =
1837                                                     kEplAsySdoStateConnected;
1838                                                 // call Command Layer Cb
1839                                                 AsySdoSequInstance_g.
1840                                                     m_fpSdoComConCb
1841                                                     (SdoSeqConHdl,
1842                                                      kAsySdoConStateAckReceived);
1843                                                 // send data to higher layer if needed
1844                                                 if (uiDataSize_p >
1845                                                     EPL_SEQ_HEADER_SIZE) {
1846                                                         AsySdoSequInstance_g.
1847                                                             m_fpSdoComReceiveCb
1848                                                             (SdoSeqConHdl,
1849                                                              ((tEplAsySdoCom *)
1850                                                               & pRecFrame_p->
1851                                                               m_le_abSdoSeqPayload),
1852                                                              (uiDataSize_p -
1853                                                               EPL_SEQ_HEADER_SIZE));
1854                                                 }
1855                                                 break;
1856                                         }
1857
1858                                         // Request Ack or Error Ack
1859                                 case 3:
1860                                         {
1861                                                 // -> change to state kEplAsySdoStateConnected
1862                                                 pAsySdoSeqCon->m_SdoState =
1863                                                     kEplAsySdoStateConnected;
1864
1865                                                 if (pRecFrame_p->m_le_bRecSeqNumCon == pAsySdoSeqCon->m_bRecSeqNum) {   // ack request
1866                                                         // -> send ack
1867                                                         // save sequence numbers
1868                                                         pAsySdoSeqCon->
1869                                                             m_bRecSeqNum =
1870                                                             AmiGetByteFromLe
1871                                                             (&pRecFrame_p->
1872                                                              m_le_bRecSeqNumCon);
1873                                                         pAsySdoSeqCon->
1874                                                             m_bSendSeqNum =
1875                                                             AmiGetByteFromLe
1876                                                             (&pRecFrame_p->
1877                                                              m_le_bSendSeqNumCon);
1878
1879                                                         // create answer own rcon = 2
1880                                                         pAsySdoSeqCon->
1881                                                             m_bRecSeqNum--;
1882
1883                                                         // check if ack or data-frame
1884                                                         if (uiDataSize_p >
1885                                                             EPL_SEQ_HEADER_SIZE)
1886                                                         {
1887                                                                 AsySdoSequInstance_g.
1888                                                                     m_fpSdoComReceiveCb
1889                                                                     (SdoSeqConHdl,
1890                                                                      ((tEplAsySdoCom *) & pRecFrame_p->m_le_abSdoSeqPayload), (uiDataSize_p - EPL_SEQ_HEADER_SIZE));
1891                                                                 // call Command Layer Cb
1892                                                                 AsySdoSequInstance_g.
1893                                                                     m_fpSdoComConCb
1894                                                                     (SdoSeqConHdl,
1895                                                                      kAsySdoConStateFrameSended);
1896
1897                                                         } else {
1898                                                                 Ret =
1899                                                                     EplSdoAsySeqSendIntern
1900                                                                     (pAsySdoSeqCon,
1901                                                                      0, NULL,
1902                                                                      FALSE);
1903                                                                 if (Ret !=
1904                                                                     kEplSuccessful)
1905                                                                 {
1906                                                                         goto Exit;
1907                                                                 }
1908                                                         }
1909
1910                                                 } else {
1911                                                         // error ack
1912                                                         // resend frames from history
1913
1914                                                         // read frame from history
1915                                                         Ret =
1916                                                             EplSdoAsyReadFromHistory
1917                                                             (pAsySdoSeqCon,
1918                                                              &pEplFrame,
1919                                                              &uiFrameSize,
1920                                                              TRUE);
1921                                                         while ((pEplFrame !=
1922                                                                 NULL)
1923                                                                && (uiFrameSize
1924                                                                    != 0)) {
1925                                                                 // send frame
1926                                                                 Ret =
1927                                                                     EplSdoAsySeqSendLowerLayer
1928                                                                     (pAsySdoSeqCon,
1929                                                                      uiFrameSize,
1930                                                                      pEplFrame);
1931                                                                 if (Ret !=
1932                                                                     kEplSuccessful)
1933                                                                 {
1934                                                                         goto Exit;
1935                                                                 }
1936                                                                 // read next frame
1937
1938                                                                 // read frame from history
1939                                                                 Ret =
1940                                                                     EplSdoAsyReadFromHistory
1941                                                                     (pAsySdoSeqCon,
1942                                                                      &pEplFrame,
1943                                                                      &uiFrameSize,
1944                                                                      FALSE);
1945                                                         }       // end of while((pabFrame != NULL)
1946                                                 }
1947                                                 break;
1948                                         }
1949                                 }       // end of switch(pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK)
1950
1951                         } else if (Event_p == kAsySdoSeqEventTimeout) { // error -> Close
1952                                 pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
1953                                 // set rcon and scon to 0
1954                                 pAsySdoSeqCon->m_bSendSeqNum &=
1955                                     EPL_SEQ_NUM_MASK;
1956                                 pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
1957                                 // send frame
1958                                 EplSdoAsySeqSendIntern(pAsySdoSeqCon,
1959                                                        0, NULL, FALSE);
1960
1961                                 // call Command Layer Cb
1962                                 AsySdoSequInstance_g.
1963                                     m_fpSdoComConCb(SdoSeqConHdl,
1964                                                     kAsySdoConStateTimeout);
1965                         }
1966
1967                         break;
1968                 }
1969
1970                 // unknown state
1971         default:
1972                 {
1973                         EPL_DBGLVL_SDO_TRACE0
1974                             ("Error: Unknown State in EplSdoAsySeqProcess\n");
1975
1976                 }
1977         }                       // end of switch(pAsySdoSeqCon->m_SdoState)
1978
1979       Exit:
1980
1981 #if defined(WIN32) || defined(_WIN32)
1982         // leave critical section for process function
1983         LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
1984 #endif
1985         return Ret;
1986
1987 }
1988
1989 //---------------------------------------------------------------------------
1990 //
1991 // Function:    EplSdoAsySeqSendIntern
1992 //
1993 // Description: intern function to create and send a frame
1994 //              -> if uiDataSize_p == 0 create a frame with infos from
1995 //                 pAsySdoSeqCon_p
1996 //
1997 //
1998 //
1999 // Parameters:  pAsySdoSeqCon_p = pointer to control structure of the connection
2000 //              uiDataSize_p    = size of data frame to process (can be 0)
2001 //                                  -> without size of sequence header and Asnd header!!!
2002 //              pData_p         = pointer to frame to process (can be NULL)
2003 //              fFrameInHistory = if TRUE frame is saved to history else not
2004 //
2005 //
2006 //
2007 // Returns:     tEplKernel = errorcode
2008 //
2009 //
2010 // State:
2011 //
2012 //---------------------------------------------------------------------------
2013 static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
2014                                          unsigned int uiDataSize_p,
2015                                          tEplFrame * pData_p,
2016                                          BOOL fFrameInHistory_p)
2017 {
2018         tEplKernel Ret;
2019         u8 abFrame[EPL_SEQ_FRAME_SIZE];
2020         tEplFrame *pEplFrame;
2021         unsigned int uiFreeEntries;
2022
2023         if (pData_p == NULL) {  // set pointer to own frame
2024                 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
2025                 pEplFrame = (tEplFrame *) & abFrame[0];
2026         } else {                // set pointer to frame from calling function
2027                 pEplFrame = pData_p;
2028         }
2029
2030         if (fFrameInHistory_p != FALSE) {
2031                 // check if only one free entry in history buffer
2032                 uiFreeEntries =
2033                     EplSdoAsyGetFreeEntriesFromHistory(pAsySdoSeqCon_p);
2034                 if (uiFreeEntries == 1) {       // request an acknowledge in dataframe
2035                         // own scon = 3
2036                         pAsySdoSeqCon_p->m_bRecSeqNum |= 0x03;
2037                 }
2038         }
2039         // fillin header informations
2040         // set service id sdo
2041         AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_le_bServiceId, 0x05);
2042         AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
2043                        m_le_abReserved, 0x00);
2044         // set receive sequence number and rcon
2045         AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
2046                        m_le_bRecSeqNumCon, pAsySdoSeqCon_p->m_bSendSeqNum);
2047         // set send sequence number and scon
2048         AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
2049                        m_le_bSendSeqNumCon, pAsySdoSeqCon_p->m_bRecSeqNum);
2050
2051         // add size
2052         uiDataSize_p += EPL_SEQ_HEADER_SIZE;
2053
2054         // forward frame to appropriate lower layer
2055         Ret = EplSdoAsySeqSendLowerLayer(pAsySdoSeqCon_p, uiDataSize_p, pEplFrame);     // pointer to frame
2056
2057         // check if all allright
2058         if ((Ret == kEplSuccessful)
2059             && (fFrameInHistory_p != FALSE)) {
2060                 // set own scon to 2 if needed
2061                 if ((pAsySdoSeqCon_p->m_bRecSeqNum & 0x03) == 0x03) {
2062                         pAsySdoSeqCon_p->m_bRecSeqNum--;
2063                 }
2064                 // save frame to history
2065                 Ret = EplSdoAsyAddFrameToHistory(pAsySdoSeqCon_p,
2066                                                  pEplFrame, uiDataSize_p);
2067                 if (Ret == kEplSdoSeqNoFreeHistory) {   // request Ack needed
2068                         Ret = kEplSdoSeqRequestAckNeeded;
2069                 }
2070
2071         }
2072
2073         return Ret;
2074 }
2075
2076 //---------------------------------------------------------------------------
2077 //
2078 // Function:    EplSdoAsySeqSendLowerLayer
2079 //
2080 // Description: intern function to send a previously created frame to lower layer
2081 //
2082 // Parameters:  pAsySdoSeqCon_p = pointer to control structure of the connection
2083 //              uiDataSize_p    = size of data frame to process (can be 0)
2084 //                                  -> without size of Asnd header!!!
2085 //              pData_p         = pointer to frame to process (can be NULL)
2086 //
2087 // Returns:     tEplKernel = errorcode
2088 //
2089 //
2090 // State:
2091 //
2092 //---------------------------------------------------------------------------
2093 static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
2094                                              unsigned int uiDataSize_p,
2095                                              tEplFrame * pEplFrame_p)
2096 {
2097         tEplKernel Ret;
2098
2099         // call send-function
2100         // check handle for UDP or Asnd
2101         if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_UDP_HANDLE) {   // send over UDP
2102 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
2103                 Ret = EplSdoUdpuSendData(pAsySdoSeqCon_p->m_ConHandle, pEplFrame_p,     // pointer to frame
2104                                          uiDataSize_p);
2105 #else
2106                 Ret = kEplSdoSeqUnsupportedProt;
2107 #endif
2108
2109         } else if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_ASND_HANDLE) {   // ASND
2110 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
2111                 Ret = EplSdoAsnduSendData(pAsySdoSeqCon_p->m_ConHandle, pEplFrame_p,    // pointer to frame
2112                                           uiDataSize_p);
2113 #else
2114                 Ret = kEplSdoSeqUnsupportedProt;
2115 #endif
2116         } else {                // error
2117                 Ret = kEplSdoSeqInvalidHdl;
2118         }
2119
2120         return Ret;
2121 }
2122
2123 //---------------------------------------------------------------------------
2124 //
2125 // Function:        EplSdoAsyReceiveCb
2126 //
2127 // Description:     callback-function for received frames from lower layer
2128 //
2129 //
2130 //
2131 // Parameters:      ConHdl_p        = handle of the connection
2132 //                  pSdoSeqData_p   = pointer to frame
2133 //                  uiDataSize_p    = size of frame
2134 //
2135 //
2136 // Returns:         tEplKernel = errorcode
2137 //
2138 //
2139 // State:
2140 //
2141 //---------------------------------------------------------------------------
2142 tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
2143                               tEplAsySdoSeq *pSdoSeqData_p,
2144                               unsigned int uiDataSize_p)
2145 {
2146         tEplKernel Ret;
2147         unsigned int uiCount = 0;
2148         unsigned int uiFreeEntry = EPL_MAX_SDO_SEQ_CON;
2149         tEplAsySdoSeqCon *pAsySdoSeqCon;
2150
2151 #if defined(WIN32) || defined(_WIN32)
2152         // enter  critical section
2153         EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive);
2154 #endif
2155
2156         EPL_DBGLVL_SDO_TRACE2("Handle: 0x%x , First Databyte 0x%x\n", ConHdl_p,
2157                               ((u8 *) pSdoSeqData_p)[0]);
2158
2159         // search controll structure for this connection
2160         pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiCount];
2161         while (uiCount < EPL_MAX_SDO_SEQ_CON) {
2162                 if (pAsySdoSeqCon->m_ConHandle == ConHdl_p) {
2163                         break;
2164                 } else if ((pAsySdoSeqCon->m_ConHandle == 0)
2165                            && (uiFreeEntry == EPL_MAX_SDO_SEQ_CON)) {
2166                         // free entry
2167                         uiFreeEntry = uiCount;
2168                 }
2169                 uiCount++;
2170                 pAsySdoSeqCon++;
2171         }
2172
2173         if (uiCount == EPL_MAX_SDO_SEQ_CON) {   // new connection
2174                 if (uiFreeEntry == EPL_MAX_SDO_SEQ_CON) {
2175                         Ret = kEplSdoSeqNoFreeHandle;
2176                         goto Exit;
2177                 } else {
2178                         pAsySdoSeqCon =
2179                             &AsySdoSequInstance_g.
2180                             m_AsySdoConnection[uiFreeEntry];
2181                         // save handle from lower layer
2182                         pAsySdoSeqCon->m_ConHandle = ConHdl_p;
2183                         // increment use counter
2184                         pAsySdoSeqCon->m_uiUseCount++;
2185                         uiCount = uiFreeEntry;
2186                 }
2187         }
2188         // call history ack function
2189         Ret = EplSdoAsyAckFrameToHistory(pAsySdoSeqCon,
2190                                          (AmiGetByteFromLe
2191                                           (&pSdoSeqData_p->
2192                                            m_le_bRecSeqNumCon) &
2193                                           EPL_SEQ_NUM_MASK));
2194         if (Ret != kEplSuccessful) {
2195                 goto Exit;
2196         }
2197 #if defined(WIN32) || defined(_WIN32)
2198         // leave critical section
2199         LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive);
2200 #endif
2201
2202         // call process function with pointer of frame and event kAsySdoSeqEventFrameRec
2203         Ret = EplSdoAsySeqProcess(uiCount,
2204                                   uiDataSize_p,
2205                                   NULL, pSdoSeqData_p, kAsySdoSeqEventFrameRec);
2206
2207       Exit:
2208         return Ret;
2209 }
2210
2211 //---------------------------------------------------------------------------
2212 //
2213 // Function:        EplSdoAsyInitHistory
2214 //
2215 // Description:     inti function for history buffer
2216 //
2217 //
2218 //
2219 // Parameters:
2220 //
2221 //
2222 // Returns:         tEplKernel = errorcode
2223 //
2224 //
2225 // State:
2226 //
2227 //---------------------------------------------------------------------------
2228 static tEplKernel EplSdoAsyInitHistory(void)
2229 {
2230         tEplKernel Ret;
2231         unsigned int uiCount;
2232
2233         Ret = kEplSuccessful;
2234         // init m_bFreeEntries in history-buffer
2235         for (uiCount = 0; uiCount < EPL_MAX_SDO_SEQ_CON; uiCount++) {
2236                 AsySdoSequInstance_g.m_AsySdoConnection[uiCount].
2237                     m_SdoConHistory.m_bFreeEntries = EPL_SDO_HISTORY_SIZE;
2238         }
2239
2240         return Ret;
2241 }
2242
2243 //---------------------------------------------------------------------------
2244 //
2245 // Function:        EplSdoAsyAddFrameToHistory
2246 //
2247 // Description:     function to add a frame to the history buffer
2248 //
2249 //
2250 //
2251 // Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
2252 //                  pFrame_p        = pointer to frame
2253 //                  uiSize_p        = size of the frame
2254 //                                     -> without size of the ethernet header
2255 //                                        and the asnd header
2256 //
2257 // Returns:         tEplKernel = errorcode
2258 //
2259 //
2260 // State:
2261 //
2262 //---------------------------------------------------------------------------
2263 static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
2264                                              tEplFrame * pFrame_p,
2265                                              unsigned int uiSize_p)
2266 {
2267         tEplKernel Ret;
2268         tEplAsySdoConHistory *pHistory;
2269
2270         Ret = kEplSuccessful;
2271
2272         // add frame to history buffer
2273
2274         // check size
2275         // $$$ d.k. EPL_SEQ_HISTORY_FRAME_SIZE includes the header size, but uiSize_p does not!!!
2276         if (uiSize_p > EPL_SEQ_HISTROY_FRAME_SIZE) {
2277                 Ret = kEplSdoSeqFrameSizeError;
2278                 goto Exit;
2279         }
2280         // save pointer to history
2281         pHistory = &pAsySdoSeqCon_p->m_SdoConHistory;
2282
2283         // check if a free entry is available
2284         if (pHistory->m_bFreeEntries > 0) {     // write message in free entry
2285                 EPL_MEMCPY(&
2286                            ((tEplFrame *) pHistory->
2287                             m_aabHistoryFrame[pHistory->m_bWrite])->
2288                            m_le_bMessageType, &pFrame_p->m_le_bMessageType,
2289                            uiSize_p + EPL_ASND_HEADER_SIZE);
2290                 // store size
2291                 pHistory->m_auiFrameSize[pHistory->m_bWrite] = uiSize_p;
2292
2293                 // decremend number of free bufferentries
2294                 pHistory->m_bFreeEntries--;
2295
2296                 // increment writeindex
2297                 pHistory->m_bWrite++;
2298
2299                 // check if write-index run over array-boarder
2300                 if (pHistory->m_bWrite == EPL_SDO_HISTORY_SIZE) {
2301                         pHistory->m_bWrite = 0;
2302                 }
2303
2304         } else {                // no free entry
2305                 Ret = kEplSdoSeqNoFreeHistory;
2306         }
2307
2308       Exit:
2309         return Ret;
2310 }
2311
2312 //---------------------------------------------------------------------------
2313 //
2314 // Function:        EplSdoAsyAckFrameToHistory
2315 //
2316 // Description:     function to delete acknowledged frames fron history buffer
2317 //
2318 //
2319 //
2320 // Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
2321 //                  bRecSeqNumber_p = receive sequence number of the received frame
2322 //
2323 //
2324 // Returns:         tEplKernel = errorcode
2325 //
2326 //
2327 // State:
2328 //
2329 //---------------------------------------------------------------------------
2330 static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
2331                                              u8 bRecSeqNumber_p)
2332 {
2333         tEplKernel Ret;
2334         tEplAsySdoConHistory *pHistory;
2335         u8 bAckIndex;
2336         u8 bCurrentSeqNum;
2337
2338         Ret = kEplSuccessful;
2339
2340         // get pointer to history buffer
2341         pHistory = &pAsySdoSeqCon_p->m_SdoConHistory;
2342
2343         // release all acknowledged frames from history buffer
2344
2345         // check if there are entries in history
2346         if (pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE) {
2347                 bAckIndex = pHistory->m_bAck;
2348                 do {
2349                         bCurrentSeqNum =
2350                             (((tEplFrame *) pHistory->
2351                               m_aabHistoryFrame[bAckIndex])->m_Data.m_Asnd.
2352                              m_Payload.m_SdoSequenceFrame.
2353                              m_le_bSendSeqNumCon & EPL_SEQ_NUM_MASK);
2354                         if (((bRecSeqNumber_p -
2355                               bCurrentSeqNum) & EPL_SEQ_NUM_MASK)
2356                             < EPL_SEQ_NUM_THRESHOLD) {
2357                                 pHistory->m_auiFrameSize[bAckIndex] = 0;
2358                                 bAckIndex++;
2359                                 pHistory->m_bFreeEntries++;
2360                                 if (bAckIndex == EPL_SDO_HISTORY_SIZE) {        // read index run over array-boarder
2361                                         bAckIndex = 0;
2362                                 }
2363                         } else {        // nothing to do anymore,
2364                                 // because any further frame in history has larger sequence
2365                                 // number than the acknowledge
2366                                 goto Exit;
2367                         }
2368                 }
2369                 while ((((bRecSeqNumber_p - 1 -
2370                           bCurrentSeqNum) & EPL_SEQ_NUM_MASK)
2371                         < EPL_SEQ_NUM_THRESHOLD)
2372                        && (pHistory->m_bWrite != bAckIndex));
2373
2374                 // store local read-index to global var
2375                 pHistory->m_bAck = bAckIndex;
2376         }
2377
2378       Exit:
2379         return Ret;
2380 }
2381
2382 //---------------------------------------------------------------------------
2383 //
2384 // Function:        EplSdoAsyReadFromHistory
2385 //
2386 // Description:     function to one frame from history
2387 //
2388 //
2389 //
2390 // Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
2391 //                  ppFrame_p       = pointer to pointer to the buffer of the stored frame
2392 //                  puiSize_p       = OUT: size of the frame
2393 //                  fInitRead       = bool which indicate a start of retransmission
2394 //                                      -> return last not acknowledged message if TRUE
2395 //
2396 //
2397 // Returns:         tEplKernel = errorcode
2398 //
2399 //
2400 // State:
2401 //
2402 //---------------------------------------------------------------------------
2403 static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
2404                                            tEplFrame ** ppFrame_p,
2405                                            unsigned int *puiSize_p,
2406                                            BOOL fInitRead_p)
2407 {
2408         tEplKernel Ret;
2409         tEplAsySdoConHistory *pHistory;
2410
2411         Ret = kEplSuccessful;
2412
2413         // read one message from History
2414
2415         // get pointer to history buffer
2416         pHistory = &pAsySdoSeqCon_p->m_SdoConHistory;
2417
2418         // check if init
2419         if (fInitRead_p != FALSE) {     // initialize read index to the index which shall be acknowledged next
2420                 pHistory->m_bRead = pHistory->m_bAck;
2421         }
2422         // check if entries are available for reading
2423         if ((pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE)
2424             && (pHistory->m_bWrite != pHistory->m_bRead)) {
2425 //        PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (u16)pHistory->m_bRead, (u16)pHistory->m_bWrite, (u16)pHistory->m_bAck);
2426 //        PRINTF2(", free entries = %u, next frame size = %u\n", (u16)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]);
2427
2428                 // return pointer to stored frame
2429                 *ppFrame_p =
2430                     (tEplFrame *) pHistory->m_aabHistoryFrame[pHistory->
2431                                                               m_bRead];
2432
2433                 // save size
2434                 *puiSize_p = pHistory->m_auiFrameSize[pHistory->m_bRead];
2435
2436                 pHistory->m_bRead++;
2437                 if (pHistory->m_bRead == EPL_SDO_HISTORY_SIZE) {
2438                         pHistory->m_bRead = 0;
2439                 }
2440
2441         } else {
2442 //        PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (u16)pHistory->m_bRead, (u16)pHistory->m_bAck, (u16)pHistory->m_bFreeEntries);
2443
2444                 // no more frames to send
2445                 // return null pointer
2446                 *ppFrame_p = NULL;
2447
2448                 *puiSize_p = 0;
2449         }
2450
2451         return Ret;
2452
2453 }
2454
2455 //---------------------------------------------------------------------------
2456 //
2457 // Function:        EplSdoAsyGetFreeEntriesFromHistory
2458 //
2459 // Description:     function returns the number of free histroy entries
2460 //
2461 //
2462 //
2463 // Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
2464 //
2465 //
2466 // Returns:         unsigned int    = number of free entries
2467 //
2468 //
2469 // State:
2470 //
2471 //---------------------------------------------------------------------------
2472 static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon *
2473                                                        pAsySdoSeqCon_p)
2474 {
2475         unsigned int uiFreeEntries;
2476
2477         uiFreeEntries =
2478             (unsigned int)pAsySdoSeqCon_p->m_SdoConHistory.m_bFreeEntries;
2479
2480         return uiFreeEntries;
2481 }
2482
2483 //---------------------------------------------------------------------------
2484 //
2485 // Function:        EplSdoAsySeqSetTimer
2486 //
2487 // Description:     function sets or modify timer in timermosule
2488 //
2489 //
2490 //
2491 // Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
2492 //                  ulTimeout       = timeout in ms
2493 //
2494 //
2495 // Returns:         unsigned int    = number of free entries
2496 //
2497 //
2498 // State:
2499 //
2500 //---------------------------------------------------------------------------
2501 static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
2502                                        unsigned long ulTimeout)
2503 {
2504         tEplKernel Ret;
2505         tEplTimerArg TimerArg;
2506
2507         TimerArg.m_EventSink = kEplEventSinkSdoAsySeq;
2508         TimerArg.m_ulArg = (unsigned long)pAsySdoSeqCon_p;
2509
2510         if (pAsySdoSeqCon_p->m_EplTimerHdl == 0) {      // create new timer
2511                 Ret = EplTimeruSetTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl,
2512                                           ulTimeout, TimerArg);
2513         } else {                // modify exisiting timer
2514                 Ret = EplTimeruModifyTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl,
2515                                              ulTimeout, TimerArg);
2516
2517         }
2518
2519         return Ret;
2520 }
2521
2522 // EOF