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