added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / staging / epl / EplSdoUdpu.c
blobbe52233b3ee83690dd66e8bbd6916e6219103557
1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
6 Project: openPOWERLINK
8 Description: source file for SDO/UDP-Protocolabstractionlayer module
10 License:
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
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.
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.
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.
41 Severability Clause:
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.
50 -------------------------------------------------------------------------
52 $RCSfile: EplSdoUdpu.c,v $
54 $Author: D.Krueger $
56 $Revision: 1.8 $ $Date: 2008/10/17 15:32:32 $
58 $State: Exp $
60 Build Environment:
61 GCC V3.4
63 -------------------------------------------------------------------------
65 Revision History:
67 2006/06/26 k.t.: start of the implementation
69 ****************************************************************************/
71 #include "user/EplSdoUdpu.h"
73 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
75 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
76 #include "SocketLinuxKernel.h"
77 #include <linux/completion.h>
78 #include <linux/sched.h>
79 #endif
81 /***************************************************************************/
82 /* */
83 /* */
84 /* G L O B A L D E F I N I T I O N S */
85 /* */
86 /* */
87 /***************************************************************************/
89 //---------------------------------------------------------------------------
90 // const defines
91 //---------------------------------------------------------------------------
93 #ifndef EPL_SDO_MAX_CONNECTION_UDP
94 #define EPL_SDO_MAX_CONNECTION_UDP 5
95 #endif
97 //---------------------------------------------------------------------------
98 // local types
99 //---------------------------------------------------------------------------
101 typedef struct {
102 unsigned long m_ulIpAddr; // in network byte order
103 unsigned int m_uiPort; // in network byte order
105 } tEplSdoUdpCon;
107 // instance table
108 typedef struct {
109 tEplSdoUdpCon m_aSdoAbsUdpConnection[EPL_SDO_MAX_CONNECTION_UDP];
110 tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
111 SOCKET m_UdpSocket;
113 #if (TARGET_SYSTEM == _WIN32_)
114 HANDLE m_ThreadHandle;
115 LPCRITICAL_SECTION m_pCriticalSection;
116 CRITICAL_SECTION m_CriticalSection;
118 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
119 struct completion m_CompletionUdpThread;
120 int m_ThreadHandle;
121 int m_iTerminateThread;
122 #endif
124 } tEplSdoUdpInstance;
126 //---------------------------------------------------------------------------
127 // modul globale vars
128 //---------------------------------------------------------------------------
130 static tEplSdoUdpInstance SdoUdpInstance_g;
132 //---------------------------------------------------------------------------
133 // local function prototypes
134 //---------------------------------------------------------------------------
136 #if (TARGET_SYSTEM == _WIN32_)
137 static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter);
139 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
140 static int EplSdoUdpThread(void *pArg_p);
141 #endif
143 /***************************************************************************/
144 /* */
145 /* */
146 /* C L A S S <EPL-SDO-UDP-Layer> */
147 /* */
148 /* */
149 /***************************************************************************/
151 // Description: Protocolabstraction layer for UDP
154 /***************************************************************************/
156 //=========================================================================//
157 // //
158 // P U B L I C F U N C T I O N S //
159 // //
160 //=========================================================================//
162 //---------------------------------------------------------------------------
164 // Function: EplSdoUdpuInit
166 // Description: init first instance of the module
170 // Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
171 // callback-function
174 // Returns: tEplKernel = Errorcode
177 // State:
179 //---------------------------------------------------------------------------
180 tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
182 tEplKernel Ret;
184 Ret = EplSdoUdpuAddInstance(fpReceiveCb_p);
186 return Ret;
189 //---------------------------------------------------------------------------
191 // Function: EplSdoUdpuAddInstance
193 // Description: init additional instance of the module
194 // înit socket and start Listen-Thread
198 // Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
199 // callback-function
202 // Returns: tEplKernel = Errorcode
205 // State:
207 //---------------------------------------------------------------------------
208 tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
210 tEplKernel Ret;
212 #if (TARGET_SYSTEM == _WIN32_)
213 int iError;
214 WSADATA Wsa;
216 #endif
218 // set instance variables to 0
219 EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
221 Ret = kEplSuccessful;
223 // save pointer to callback-function
224 if (fpReceiveCb_p != NULL) {
225 SdoUdpInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
226 } else {
227 Ret = kEplSdoUdpMissCb;
228 goto Exit;
231 #if (TARGET_SYSTEM == _WIN32_)
232 // start winsock2 for win32
233 // windows specific start of socket
234 iError = WSAStartup(MAKEWORD(2, 0), &Wsa);
235 if (iError != 0) {
236 Ret = kEplSdoUdpNoSocket;
237 goto Exit;
239 // create critical section for acccess of instnace variables
240 SdoUdpInstance_g.m_pCriticalSection =
241 &SdoUdpInstance_g.m_CriticalSection;
242 InitializeCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
244 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
245 init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
246 SdoUdpInstance_g.m_iTerminateThread = 0;
247 #endif
249 SdoUdpInstance_g.m_ThreadHandle = 0;
250 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
252 Ret = EplSdoUdpuConfig(INADDR_ANY, 0);
254 Exit:
255 return Ret;
258 //---------------------------------------------------------------------------
260 // Function: EplSdoUdpuDelInstance
262 // Description: del instance of the module
263 // del socket and del Listen-Thread
267 // Parameters:
270 // Returns: tEplKernel = Errorcode
273 // State:
275 //---------------------------------------------------------------------------
276 tEplKernel PUBLIC EplSdoUdpuDelInstance()
278 tEplKernel Ret;
280 #if (TARGET_SYSTEM == _WIN32_)
281 BOOL fTermError;
282 #endif
284 Ret = kEplSuccessful;
286 if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
287 // close thread
288 #if (TARGET_SYSTEM == _WIN32_)
289 fTermError =
290 TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
291 if (fTermError == FALSE) {
292 Ret = kEplSdoUdpThreadError;
293 goto Exit;
295 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
296 SdoUdpInstance_g.m_iTerminateThread = 1;
297 /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
298 send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
299 wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
300 #endif
302 SdoUdpInstance_g.m_ThreadHandle = 0;
305 if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
306 // close socket
307 closesocket(SdoUdpInstance_g.m_UdpSocket);
308 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
310 #if (TARGET_SYSTEM == _WIN32_)
311 // delete critical section
312 DeleteCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
313 #endif
315 #if (TARGET_SYSTEM == _WIN32_)
316 // for win 32
317 WSACleanup();
318 #endif
320 #if (TARGET_SYSTEM == _WIN32_)
321 Exit:
322 #endif
323 return Ret;
326 //---------------------------------------------------------------------------
328 // Function: EplSdoUdpuConfig
330 // Description: reconfigurate socket with new IP-Address
331 // -> needed for NMT ResetConfiguration
333 // Parameters: ulIpAddr_p = IpAddress in platform byte order
334 // uiPort_p = port number in platform byte order
337 // Returns: tEplKernel = Errorcode
340 // State:
342 //---------------------------------------------------------------------------
343 tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
344 unsigned int uiPort_p)
346 tEplKernel Ret;
347 struct sockaddr_in Addr;
348 int iError;
350 #if (TARGET_SYSTEM == _WIN32_)
351 BOOL fTermError;
352 unsigned long ulThreadId;
353 #endif
355 Ret = kEplSuccessful;
357 if (uiPort_p == 0) { // set UDP port to default port number
358 uiPort_p = EPL_C_SDO_EPL_PORT;
359 } else if (uiPort_p > 65535) {
360 Ret = kEplSdoUdpSocketError;
361 goto Exit;
364 if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
366 // close old thread
367 #if (TARGET_SYSTEM == _WIN32_)
368 fTermError =
369 TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
370 if (fTermError == FALSE) {
371 Ret = kEplSdoUdpThreadError;
372 goto Exit;
374 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
375 SdoUdpInstance_g.m_iTerminateThread = 1;
376 /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
377 send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
378 wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
379 SdoUdpInstance_g.m_iTerminateThread = 0;
380 #endif
382 SdoUdpInstance_g.m_ThreadHandle = 0;
385 if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
386 // close socket
387 iError = closesocket(SdoUdpInstance_g.m_UdpSocket);
388 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
389 if (iError != 0) {
390 Ret = kEplSdoUdpSocketError;
391 goto Exit;
394 // create Socket
395 SdoUdpInstance_g.m_UdpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
396 if (SdoUdpInstance_g.m_UdpSocket == INVALID_SOCKET) {
397 Ret = kEplSdoUdpNoSocket;
398 EPL_DBGLVL_SDO_TRACE0("EplSdoUdpuConfig: socket() failed\n");
399 goto Exit;
401 // bind socket
402 Addr.sin_family = AF_INET;
403 Addr.sin_port = htons((unsigned short)uiPort_p);
404 Addr.sin_addr.s_addr = htonl(ulIpAddr_p);
405 iError =
406 bind(SdoUdpInstance_g.m_UdpSocket, (struct sockaddr *)&Addr,
407 sizeof(Addr));
408 if (iError < 0) {
409 //iError = WSAGetLastError();
410 EPL_DBGLVL_SDO_TRACE1
411 ("EplSdoUdpuConfig: bind() finished with %i\n", iError);
412 Ret = kEplSdoUdpNoSocket;
413 goto Exit;
415 // create Listen-Thread
416 #if (TARGET_SYSTEM == _WIN32_)
417 // for win32
419 // create thread
420 SdoUdpInstance_g.m_ThreadHandle = CreateThread(NULL,
422 EplSdoUdpThread,
423 &SdoUdpInstance_g,
424 0, &ulThreadId);
425 if (SdoUdpInstance_g.m_ThreadHandle == NULL) {
426 Ret = kEplSdoUdpThreadError;
427 goto Exit;
429 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
431 SdoUdpInstance_g.m_ThreadHandle =
432 kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g, CLONE_KERNEL);
433 if (SdoUdpInstance_g.m_ThreadHandle == 0) {
434 Ret = kEplSdoUdpThreadError;
435 goto Exit;
437 #endif
439 Exit:
440 return Ret;
444 //---------------------------------------------------------------------------
446 // Function: EplSdoUdpuInitCon
448 // Description: init a new connect
452 // Parameters: pSdoConHandle_p = pointer for the new connection handle
453 // uiTargetNodeId_p = NodeId of the target node
456 // Returns: tEplKernel = Errorcode
459 // State:
461 //---------------------------------------------------------------------------
462 tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
463 unsigned int uiTargetNodeId_p)
465 tEplKernel Ret;
466 unsigned int uiCount;
467 unsigned int uiFreeCon;
468 tEplSdoUdpCon *pSdoUdpCon;
470 Ret = kEplSuccessful;
472 // get free entry in control structure
473 uiCount = 0;
474 uiFreeCon = EPL_SDO_MAX_CONNECTION_UDP;
475 pSdoUdpCon = &SdoUdpInstance_g.m_aSdoAbsUdpConnection[0];
476 while (uiCount < EPL_SDO_MAX_CONNECTION_UDP) {
477 if ((pSdoUdpCon->m_ulIpAddr & htonl(0xFF)) == htonl(uiTargetNodeId_p)) { // existing connection to target node found
478 // set handle
479 *pSdoConHandle_p = (uiCount | EPL_SDO_UDP_HANDLE);
481 goto Exit;
482 } else if ((pSdoUdpCon->m_ulIpAddr == 0)
483 && (pSdoUdpCon->m_uiPort == 0)) {
484 uiFreeCon = uiCount;
486 uiCount++;
487 pSdoUdpCon++;
490 if (uiFreeCon == EPL_SDO_MAX_CONNECTION_UDP) {
491 // error no free handle
492 Ret = kEplSdoUdpNoFreeHandle;
493 } else {
494 pSdoUdpCon =
495 &SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiFreeCon];
496 // save infos for connection
497 pSdoUdpCon->m_uiPort = htons(EPL_C_SDO_EPL_PORT);
498 pSdoUdpCon->m_ulIpAddr = htonl(0xC0A86400 | uiTargetNodeId_p); // 192.168.100.uiTargetNodeId_p
500 // set handle
501 *pSdoConHandle_p = (uiFreeCon | EPL_SDO_UDP_HANDLE);
505 Exit:
506 return Ret;
510 //---------------------------------------------------------------------------
512 // Function: EplSdoUdpuSendData
514 // Description: send data using exisiting connection
518 // Parameters: SdoConHandle_p = connection handle
519 // pSrcData_p = pointer to data
520 // dwDataSize_p = number of databyte
521 // -> without asend-header!!!
523 // Returns: tEplKernel = Errorcode
526 // State:
528 //---------------------------------------------------------------------------
529 tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
530 tEplFrame * pSrcData_p, DWORD dwDataSize_p)
532 tEplKernel Ret;
533 int iError;
534 unsigned int uiArray;
535 struct sockaddr_in Addr;
537 Ret = kEplSuccessful;
539 uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
540 if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
541 Ret = kEplSdoUdpInvalidHdl;
542 goto Exit;
544 //set message type
545 AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, 0x06); // SDO
546 // target node id (for Udp = 0)
547 AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, 0x00);
548 // set source-nodeid (for Udp = 0)
549 AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
551 // calc size
552 dwDataSize_p += EPL_ASND_HEADER_SIZE;
554 // call sendto
555 Addr.sin_family = AF_INET;
556 #if (TARGET_SYSTEM == _WIN32_)
557 // enter critical section for process function
558 EnterCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
559 #endif
561 Addr.sin_port =
562 (unsigned short)SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].
563 m_uiPort;
564 Addr.sin_addr.s_addr =
565 SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr;
567 #if (TARGET_SYSTEM == _WIN32_)
568 // leave critical section for process function
569 LeaveCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
570 #endif
572 iError = sendto(SdoUdpInstance_g.m_UdpSocket, // sockethandle
573 (const char *)&pSrcData_p->m_le_bMessageType, // data to send
574 dwDataSize_p, // number of bytes to send
575 0, // flags
576 (struct sockaddr *)&Addr, // target
577 sizeof(struct sockaddr_in)); // sizeof targetadress
578 if (iError < 0) {
579 EPL_DBGLVL_SDO_TRACE1
580 ("EplSdoUdpuSendData: sendto() finished with %i\n", iError);
581 Ret = kEplSdoUdpSendError;
582 goto Exit;
585 Exit:
586 return Ret;
590 //---------------------------------------------------------------------------
592 // Function: EplSdoUdpuDelCon
594 // Description: delete connection from intern structure
598 // Parameters: SdoConHandle_p = connection handle
600 // Returns: tEplKernel = Errorcode
603 // State:
605 //---------------------------------------------------------------------------
606 tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
608 tEplKernel Ret;
609 unsigned int uiArray;
611 uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
613 if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
614 Ret = kEplSdoUdpInvalidHdl;
615 goto Exit;
616 } else {
617 Ret = kEplSuccessful;
620 // delete connection
621 SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr = 0;
622 SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_uiPort = 0;
624 Exit:
625 return Ret;
628 //=========================================================================//
629 // //
630 // P R I V A T E F U N C T I O N S //
631 // //
632 //=========================================================================//
634 //---------------------------------------------------------------------------
636 // Function: EplSdoUdpThread
638 // Description: thread check socket for new data
642 // Parameters: lpParameter = pointer to parameter type tEplSdoUdpThreadPara
645 // Returns: DWORD = errorcode
648 // State:
650 //---------------------------------------------------------------------------
651 #if (TARGET_SYSTEM == _WIN32_)
652 static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter)
653 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
654 static int EplSdoUdpThread(void *pArg_p)
655 #endif
658 tEplSdoUdpInstance *pInstance;
659 struct sockaddr_in RemoteAddr;
660 int iError;
661 int iCount;
662 int iFreeEntry;
663 BYTE abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
664 unsigned int uiSize;
665 tEplSdoConHdl SdoConHdl;
667 #if (TARGET_SYSTEM == _WIN32_)
668 pInstance = (tEplSdoUdpInstance *) lpParameter;
670 for (;;)
671 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
672 pInstance = (tEplSdoUdpInstance *) pArg_p;
673 daemonize("EplSdoUdpThread");
674 allow_signal(SIGTERM);
676 for (; pInstance->m_iTerminateThread == 0;)
677 #endif
680 // wait for data
681 uiSize = sizeof(struct sockaddr);
682 iError = recvfrom(pInstance->m_UdpSocket, // Socket
683 (char *)&abBuffer[0], // buffer for data
684 sizeof(abBuffer), // size of the buffer
685 0, // flags
686 (struct sockaddr *)&RemoteAddr,
687 (int *)&uiSize);
688 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
689 if (iError == -ERESTARTSYS) {
690 break;
692 #endif
693 if (iError > 0) {
694 // get handle for higher layer
695 iCount = 0;
696 iFreeEntry = 0xFFFF;
697 #if (TARGET_SYSTEM == _WIN32_)
698 // enter critical section for process function
699 EnterCriticalSection(SdoUdpInstance_g.
700 m_pCriticalSection);
701 #endif
702 while (iCount < EPL_SDO_MAX_CONNECTION_UDP) {
703 // check if this connection is already known
704 if ((pInstance->m_aSdoAbsUdpConnection[iCount].
705 m_ulIpAddr == RemoteAddr.sin_addr.s_addr)
706 && (pInstance->
707 m_aSdoAbsUdpConnection[iCount].
708 m_uiPort == RemoteAddr.sin_port)) {
709 break;
712 if ((pInstance->m_aSdoAbsUdpConnection[iCount].
713 m_ulIpAddr == 0)
714 && (pInstance->
715 m_aSdoAbsUdpConnection[iCount].
716 m_uiPort == 0)
717 && (iFreeEntry == 0xFFFF))
719 iFreeEntry = iCount;
722 iCount++;
725 if (iCount == EPL_SDO_MAX_CONNECTION_UDP) {
726 // connection unknown
727 // see if there is a free handle
728 if (iFreeEntry != 0xFFFF) {
729 // save adress infos
730 pInstance->
731 m_aSdoAbsUdpConnection[iFreeEntry].
732 m_ulIpAddr =
733 RemoteAddr.sin_addr.s_addr;
734 pInstance->
735 m_aSdoAbsUdpConnection[iFreeEntry].
736 m_uiPort = RemoteAddr.sin_port;
737 #if (TARGET_SYSTEM == _WIN32_)
738 // leave critical section for process function
739 LeaveCriticalSection(SdoUdpInstance_g.
740 m_pCriticalSection);
741 #endif
742 // call callback
743 SdoConHdl = iFreeEntry;
744 SdoConHdl |= EPL_SDO_UDP_HANDLE;
745 // offset 4 -> start of SDO Sequence header
746 pInstance->m_fpSdoAsySeqCb(SdoConHdl,
747 (tEplAsySdoSeq
748 *) &
749 abBuffer[4],
750 (iError -
751 4));
752 } else {
753 EPL_DBGLVL_SDO_TRACE0
754 ("Error in EplSdoUdpThread() no free handle\n");
755 #if (TARGET_SYSTEM == _WIN32_)
756 // leave critical section for process function
757 LeaveCriticalSection(SdoUdpInstance_g.
758 m_pCriticalSection);
759 #endif
762 } else {
763 // known connection
764 // call callback with correct handle
765 SdoConHdl = iCount;
766 SdoConHdl |= EPL_SDO_UDP_HANDLE;
767 #if (TARGET_SYSTEM == _WIN32_)
768 // leave critical section for process function
769 LeaveCriticalSection(SdoUdpInstance_g.
770 m_pCriticalSection);
771 #endif
772 // offset 4 -> start of SDO Sequence header
773 pInstance->m_fpSdoAsySeqCb(SdoConHdl,
774 (tEplAsySdoSeq *) &
775 abBuffer[4],
776 (iError - 4));
778 } // end of if(iError!=SOCKET_ERROR)
779 } // end of for(;;)
781 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
782 complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
783 #endif
785 return 0;
788 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
790 // EOF