Staging: epl: remove _WIN_32_ and _NO_OS_ defines
[safe/jmp/linux-2.6] / drivers / staging / epl / EplSdoUdpu.c
1 /****************************************************************************
2
3   (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4       www.systec-electronic.com
5
6   Project:      openPOWERLINK
7
8   Description:  source file for SDO/UDP-Protocolabstractionlayer 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: EplSdoUdpu.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.8 $  $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/EplSdoUdpu.h"
72
73 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
74
75 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
76 #include "SocketLinuxKernel.h"
77 #include <linux/completion.h>
78 #include <linux/sched.h>
79 #endif
80
81 /***************************************************************************/
82 /*                                                                         */
83 /*                                                                         */
84 /*          G L O B A L   D E F I N I T I O N S                            */
85 /*                                                                         */
86 /*                                                                         */
87 /***************************************************************************/
88
89 //---------------------------------------------------------------------------
90 // const defines
91 //---------------------------------------------------------------------------
92
93 #ifndef EPL_SDO_MAX_CONNECTION_UDP
94 #define EPL_SDO_MAX_CONNECTION_UDP  5
95 #endif
96
97 //---------------------------------------------------------------------------
98 // local types
99 //---------------------------------------------------------------------------
100
101 typedef struct {
102         unsigned long m_ulIpAddr;       // in network byte order
103         unsigned int m_uiPort;  // in network byte order
104
105 } tEplSdoUdpCon;
106
107 // instance table
108 typedef struct {
109         tEplSdoUdpCon m_aSdoAbsUdpConnection[EPL_SDO_MAX_CONNECTION_UDP];
110         tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
111         SOCKET m_UdpSocket;
112
113 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
114         struct completion m_CompletionUdpThread;
115         int m_ThreadHandle;
116         int m_iTerminateThread;
117 #endif
118
119 } tEplSdoUdpInstance;
120
121 //---------------------------------------------------------------------------
122 // modul globale vars
123 //---------------------------------------------------------------------------
124
125 static tEplSdoUdpInstance SdoUdpInstance_g;
126
127 //---------------------------------------------------------------------------
128 // local function prototypes
129 //---------------------------------------------------------------------------
130
131 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
132 static int EplSdoUdpThread(void *pArg_p);
133 #endif
134
135 /***************************************************************************/
136 /*                                                                         */
137 /*                                                                         */
138 /*          C L A S S  <EPL-SDO-UDP-Layer>                                 */
139 /*                                                                         */
140 /*                                                                         */
141 /***************************************************************************/
142 //
143 // Description: Protocolabstraction layer for UDP
144 //
145 //
146 /***************************************************************************/
147
148 //=========================================================================//
149 //                                                                         //
150 //          P U B L I C   F U N C T I O N S                                //
151 //                                                                         //
152 //=========================================================================//
153
154 //---------------------------------------------------------------------------
155 //
156 // Function:    EplSdoUdpuInit
157 //
158 // Description: init first instance of the module
159 //
160 //
161 //
162 // Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
163 //                                  callback-function
164 //
165 //
166 // Returns:     tEplKernel  = Errorcode
167 //
168 //
169 // State:
170 //
171 //---------------------------------------------------------------------------
172 tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
173 {
174         tEplKernel Ret;
175
176         Ret = EplSdoUdpuAddInstance(fpReceiveCb_p);
177
178         return Ret;
179 }
180
181 //---------------------------------------------------------------------------
182 //
183 // Function:    EplSdoUdpuAddInstance
184 //
185 // Description: init additional instance of the module
186 //              înit socket and start Listen-Thread
187 //
188 //
189 //
190 // Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
191 //                                  callback-function
192 //
193 //
194 // Returns:     tEplKernel  = Errorcode
195 //
196 //
197 // State:
198 //
199 //---------------------------------------------------------------------------
200 tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
201 {
202         tEplKernel Ret;
203
204         // set instance variables to 0
205         EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
206
207         Ret = kEplSuccessful;
208
209         // save pointer to callback-function
210         if (fpReceiveCb_p != NULL) {
211                 SdoUdpInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
212         } else {
213                 Ret = kEplSdoUdpMissCb;
214                 goto Exit;
215         }
216
217 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
218         init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
219         SdoUdpInstance_g.m_iTerminateThread = 0;
220 #endif
221
222         SdoUdpInstance_g.m_ThreadHandle = 0;
223         SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
224
225         Ret = EplSdoUdpuConfig(INADDR_ANY, 0);
226
227       Exit:
228         return Ret;
229 }
230
231 //---------------------------------------------------------------------------
232 //
233 // Function:    EplSdoUdpuDelInstance
234 //
235 // Description: del instance of the module
236 //              del socket and del Listen-Thread
237 //
238 //
239 //
240 // Parameters:
241 //
242 //
243 // Returns:     tEplKernel  = Errorcode
244 //
245 //
246 // State:
247 //
248 //---------------------------------------------------------------------------
249 tEplKernel EplSdoUdpuDelInstance(void)
250 {
251         tEplKernel Ret;
252
253         Ret = kEplSuccessful;
254
255         if (SdoUdpInstance_g.m_ThreadHandle != 0) {     // listen thread was started
256                 // close thread
257 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
258                 SdoUdpInstance_g.m_iTerminateThread = 1;
259                 /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
260                 send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
261                 wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
262 #endif
263
264                 SdoUdpInstance_g.m_ThreadHandle = 0;
265         }
266
267         if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
268                 // close socket
269                 closesocket(SdoUdpInstance_g.m_UdpSocket);
270                 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
271         }
272         return Ret;
273 }
274
275 //---------------------------------------------------------------------------
276 //
277 // Function:    EplSdoUdpuConfig
278 //
279 // Description: reconfigurate socket with new IP-Address
280 //              -> needed for NMT ResetConfiguration
281 //
282 // Parameters:  ulIpAddr_p      = IpAddress in platform byte order
283 //              uiPort_p        = port number in platform byte order
284 //
285 //
286 // Returns:     tEplKernel  = Errorcode
287 //
288 //
289 // State:
290 //
291 //---------------------------------------------------------------------------
292 tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p)
293 {
294         tEplKernel Ret;
295         struct sockaddr_in Addr;
296         int iError;
297
298         Ret = kEplSuccessful;
299
300         if (uiPort_p == 0) {    // set UDP port to default port number
301                 uiPort_p = EPL_C_SDO_EPL_PORT;
302         } else if (uiPort_p > 65535) {
303                 Ret = kEplSdoUdpSocketError;
304                 goto Exit;
305         }
306
307         if (SdoUdpInstance_g.m_ThreadHandle != 0) {     // listen thread was started
308
309                 // close old thread
310 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
311                 SdoUdpInstance_g.m_iTerminateThread = 1;
312                 /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
313                 send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
314                 wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
315                 SdoUdpInstance_g.m_iTerminateThread = 0;
316 #endif
317
318                 SdoUdpInstance_g.m_ThreadHandle = 0;
319         }
320
321         if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
322                 // close socket
323                 iError = closesocket(SdoUdpInstance_g.m_UdpSocket);
324                 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
325                 if (iError != 0) {
326                         Ret = kEplSdoUdpSocketError;
327                         goto Exit;
328                 }
329         }
330         // create Socket
331         SdoUdpInstance_g.m_UdpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
332         if (SdoUdpInstance_g.m_UdpSocket == INVALID_SOCKET) {
333                 Ret = kEplSdoUdpNoSocket;
334                 EPL_DBGLVL_SDO_TRACE0("EplSdoUdpuConfig: socket() failed\n");
335                 goto Exit;
336         }
337         // bind socket
338         Addr.sin_family = AF_INET;
339         Addr.sin_port = htons((unsigned short)uiPort_p);
340         Addr.sin_addr.s_addr = htonl(ulIpAddr_p);
341         iError =
342             bind(SdoUdpInstance_g.m_UdpSocket, (struct sockaddr *)&Addr,
343                  sizeof(Addr));
344         if (iError < 0) {
345                 //iError = WSAGetLastError();
346                 EPL_DBGLVL_SDO_TRACE1
347                     ("EplSdoUdpuConfig: bind() finished with %i\n", iError);
348                 Ret = kEplSdoUdpNoSocket;
349                 goto Exit;
350         }
351         // create Listen-Thread
352 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
353
354         SdoUdpInstance_g.m_ThreadHandle =
355             kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g, CLONE_KERNEL);
356         if (SdoUdpInstance_g.m_ThreadHandle == 0) {
357                 Ret = kEplSdoUdpThreadError;
358                 goto Exit;
359         }
360 #endif
361
362       Exit:
363         return Ret;
364
365 }
366
367 //---------------------------------------------------------------------------
368 //
369 // Function:    EplSdoUdpuInitCon
370 //
371 // Description: init a new connect
372 //
373 //
374 //
375 // Parameters:  pSdoConHandle_p = pointer for the new connection handle
376 //              uiTargetNodeId_p = NodeId of the target node
377 //
378 //
379 // Returns:     tEplKernel  = Errorcode
380 //
381 //
382 // State:
383 //
384 //---------------------------------------------------------------------------
385 tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
386                              unsigned int uiTargetNodeId_p)
387 {
388         tEplKernel Ret;
389         unsigned int uiCount;
390         unsigned int uiFreeCon;
391         tEplSdoUdpCon *pSdoUdpCon;
392
393         Ret = kEplSuccessful;
394
395         // get free entry in control structure
396         uiCount = 0;
397         uiFreeCon = EPL_SDO_MAX_CONNECTION_UDP;
398         pSdoUdpCon = &SdoUdpInstance_g.m_aSdoAbsUdpConnection[0];
399         while (uiCount < EPL_SDO_MAX_CONNECTION_UDP) {
400                 if ((pSdoUdpCon->m_ulIpAddr & htonl(0xFF)) == htonl(uiTargetNodeId_p)) {        // existing connection to target node found
401                         // set handle
402                         *pSdoConHandle_p = (uiCount | EPL_SDO_UDP_HANDLE);
403
404                         goto Exit;
405                 } else if ((pSdoUdpCon->m_ulIpAddr == 0)
406                            && (pSdoUdpCon->m_uiPort == 0)) {
407                         uiFreeCon = uiCount;
408                 }
409                 uiCount++;
410                 pSdoUdpCon++;
411         }
412
413         if (uiFreeCon == EPL_SDO_MAX_CONNECTION_UDP) {
414                 // error no free handle
415                 Ret = kEplSdoUdpNoFreeHandle;
416         } else {
417                 pSdoUdpCon =
418                     &SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiFreeCon];
419                 // save infos for connection
420                 pSdoUdpCon->m_uiPort = htons(EPL_C_SDO_EPL_PORT);
421                 pSdoUdpCon->m_ulIpAddr = htonl(0xC0A86400 | uiTargetNodeId_p);  // 192.168.100.uiTargetNodeId_p
422
423                 // set handle
424                 *pSdoConHandle_p = (uiFreeCon | EPL_SDO_UDP_HANDLE);
425
426         }
427
428       Exit:
429         return Ret;
430
431 }
432
433 //---------------------------------------------------------------------------
434 //
435 // Function:    EplSdoUdpuSendData
436 //
437 // Description: send data using exisiting connection
438 //
439 //
440 //
441 // Parameters:  SdoConHandle_p  = connection handle
442 //              pSrcData_p      = pointer to data
443 //              dwDataSize_p    = number of databyte
444 //                                  -> without asend-header!!!
445 //
446 // Returns:     tEplKernel  = Errorcode
447 //
448 //
449 // State:
450 //
451 //---------------------------------------------------------------------------
452 tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
453                               tEplFrame *pSrcData_p, DWORD dwDataSize_p)
454 {
455         tEplKernel Ret;
456         int iError;
457         unsigned int uiArray;
458         struct sockaddr_in Addr;
459
460         Ret = kEplSuccessful;
461
462         uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
463         if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
464                 Ret = kEplSdoUdpInvalidHdl;
465                 goto Exit;
466         }
467         //set message type
468         AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, 0x06);   // SDO
469         // target node id (for Udp = 0)
470         AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, 0x00);
471         // set source-nodeid (for Udp = 0)
472         AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
473
474         // calc size
475         dwDataSize_p += EPL_ASND_HEADER_SIZE;
476
477         // call sendto
478         Addr.sin_family = AF_INET;
479         Addr.sin_port =
480             (unsigned short)SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].
481             m_uiPort;
482         Addr.sin_addr.s_addr =
483             SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr;
484
485         iError = sendto(SdoUdpInstance_g.m_UdpSocket,   // sockethandle
486                         (const char *)&pSrcData_p->m_le_bMessageType,   // data to send
487                         dwDataSize_p,   // number of bytes to send
488                         0,      // flags
489                         (struct sockaddr *)&Addr,       // target
490                         sizeof(struct sockaddr_in));    // sizeof targetadress
491         if (iError < 0) {
492                 EPL_DBGLVL_SDO_TRACE1
493                     ("EplSdoUdpuSendData: sendto() finished with %i\n", iError);
494                 Ret = kEplSdoUdpSendError;
495                 goto Exit;
496         }
497
498       Exit:
499         return Ret;
500
501 }
502
503 //---------------------------------------------------------------------------
504 //
505 // Function:    EplSdoUdpuDelCon
506 //
507 // Description: delete connection from intern structure
508 //
509 //
510 //
511 // Parameters:  SdoConHandle_p  = connection handle
512 //
513 // Returns:     tEplKernel  = Errorcode
514 //
515 //
516 // State:
517 //
518 //---------------------------------------------------------------------------
519 tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
520 {
521         tEplKernel Ret;
522         unsigned int uiArray;
523
524         uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
525
526         if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
527                 Ret = kEplSdoUdpInvalidHdl;
528                 goto Exit;
529         } else {
530                 Ret = kEplSuccessful;
531         }
532
533         // delete connection
534         SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr = 0;
535         SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_uiPort = 0;
536
537       Exit:
538         return Ret;
539 }
540
541 //=========================================================================//
542 //                                                                         //
543 //          P R I V A T E   F U N C T I O N S                              //
544 //                                                                         //
545 //=========================================================================//
546
547 //---------------------------------------------------------------------------
548 //
549 // Function:        EplSdoUdpThread
550 //
551 // Description:     thread check socket for new data
552 //
553 //
554 //
555 // Parameters:      lpParameter = pointer to parameter type tEplSdoUdpThreadPara
556 //
557 //
558 // Returns:         DWORD   =   errorcode
559 //
560 //
561 // State:
562 //
563 //---------------------------------------------------------------------------
564 static int EplSdoUdpThread(void *pArg_p)
565 {
566
567         tEplSdoUdpInstance *pInstance;
568         struct sockaddr_in RemoteAddr;
569         int iError;
570         int iCount;
571         int iFreeEntry;
572         BYTE abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
573         unsigned int uiSize;
574         tEplSdoConHdl SdoConHdl;
575
576 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
577         pInstance = (tEplSdoUdpInstance *) pArg_p;
578         daemonize("EplSdoUdpThread");
579         allow_signal(SIGTERM);
580
581         for (; pInstance->m_iTerminateThread == 0;)
582 #endif
583
584         {
585                 // wait for data
586                 uiSize = sizeof(struct sockaddr);
587                 iError = recvfrom(pInstance->m_UdpSocket,       // Socket
588                                   (char *)&abBuffer[0], // buffer for data
589                                   sizeof(abBuffer),     // size of the buffer
590                                   0,    // flags
591                                   (struct sockaddr *)&RemoteAddr,
592                                   (int *)&uiSize);
593 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
594                 if (iError == -ERESTARTSYS) {
595                         break;
596                 }
597 #endif
598                 if (iError > 0) {
599                         // get handle for higher layer
600                         iCount = 0;
601                         iFreeEntry = 0xFFFF;
602                         while (iCount < EPL_SDO_MAX_CONNECTION_UDP) {
603                                 // check if this connection is already known
604                                 if ((pInstance->m_aSdoAbsUdpConnection[iCount].
605                                      m_ulIpAddr == RemoteAddr.sin_addr.s_addr)
606                                     && (pInstance->
607                                         m_aSdoAbsUdpConnection[iCount].
608                                         m_uiPort == RemoteAddr.sin_port)) {
609                                         break;
610                                 }
611
612                                 if ((pInstance->m_aSdoAbsUdpConnection[iCount].
613                                      m_ulIpAddr == 0)
614                                     && (pInstance->
615                                         m_aSdoAbsUdpConnection[iCount].
616                                         m_uiPort == 0)
617                                     && (iFreeEntry == 0xFFFF))
618                                 {
619                                         iFreeEntry = iCount;
620                                 }
621
622                                 iCount++;
623                         }
624
625                         if (iCount == EPL_SDO_MAX_CONNECTION_UDP) {
626                                 // connection unknown
627                                 // see if there is a free handle
628                                 if (iFreeEntry != 0xFFFF) {
629                                         // save adress infos
630                                         pInstance->
631                                             m_aSdoAbsUdpConnection[iFreeEntry].
632                                             m_ulIpAddr =
633                                             RemoteAddr.sin_addr.s_addr;
634                                         pInstance->
635                                             m_aSdoAbsUdpConnection[iFreeEntry].
636                                             m_uiPort = RemoteAddr.sin_port;
637                                         // call callback
638                                         SdoConHdl = iFreeEntry;
639                                         SdoConHdl |= EPL_SDO_UDP_HANDLE;
640                                         // offset 4 -> start of SDO Sequence header
641                                         pInstance->m_fpSdoAsySeqCb(SdoConHdl,
642                                                                    (tEplAsySdoSeq
643                                                                     *) &
644                                                                    abBuffer[4],
645                                                                    (iError -
646                                                                     4));
647                                 } else {
648                                         EPL_DBGLVL_SDO_TRACE0
649                                             ("Error in EplSdoUdpThread() no free handle\n");
650                                 }
651
652                         } else {
653                                 // known connection
654                                 // call callback with correct handle
655                                 SdoConHdl = iCount;
656                                 SdoConHdl |= EPL_SDO_UDP_HANDLE;
657                                 // offset 4 -> start of SDO Sequence header
658                                 pInstance->m_fpSdoAsySeqCb(SdoConHdl,
659                                                            (tEplAsySdoSeq *) &
660                                                            abBuffer[4],
661                                                            (iError - 4));
662                         }
663                 }               // end of  if(iError!=SOCKET_ERROR)
664         }                       // end of for(;;)
665
666 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
667         complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
668 #endif
669
670         return 0;
671 }
672
673 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
674
675 // EOF