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