Staging: epl: run Lindent on *.c files
[deliverable/linux.git] / 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 == _WIN32_)
114 HANDLE m_ThreadHandle;
115 LPCRITICAL_SECTION m_pCriticalSection;
116 CRITICAL_SECTION m_CriticalSection;
117
118 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
119 struct completion m_CompletionUdpThread;
120 int m_ThreadHandle;
121 int m_iTerminateThread;
122 #endif
123
124 } tEplSdoUdpInstance;
125
126 //---------------------------------------------------------------------------
127 // modul globale vars
128 //---------------------------------------------------------------------------
129
130 static tEplSdoUdpInstance SdoUdpInstance_g;
131
132 //---------------------------------------------------------------------------
133 // local function prototypes
134 //---------------------------------------------------------------------------
135
136 #if (TARGET_SYSTEM == _WIN32_)
137 static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter);
138
139 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
140 static int EplSdoUdpThread(void *pArg_p);
141 #endif
142
143 /***************************************************************************/
144 /* */
145 /* */
146 /* C L A S S <EPL-SDO-UDP-Layer> */
147 /* */
148 /* */
149 /***************************************************************************/
150 //
151 // Description: Protocolabstraction layer for UDP
152 //
153 //
154 /***************************************************************************/
155
156 //=========================================================================//
157 // //
158 // P U B L I C F U N C T I O N S //
159 // //
160 //=========================================================================//
161
162 //---------------------------------------------------------------------------
163 //
164 // Function: EplSdoUdpuInit
165 //
166 // Description: init first instance of the module
167 //
168 //
169 //
170 // Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
171 // callback-function
172 //
173 //
174 // Returns: tEplKernel = Errorcode
175 //
176 //
177 // State:
178 //
179 //---------------------------------------------------------------------------
180 tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
181 {
182 tEplKernel Ret;
183
184 Ret = EplSdoUdpuAddInstance(fpReceiveCb_p);
185
186 return Ret;
187 }
188
189 //---------------------------------------------------------------------------
190 //
191 // Function: EplSdoUdpuAddInstance
192 //
193 // Description: init additional instance of the module
194 // înit socket and start Listen-Thread
195 //
196 //
197 //
198 // Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
199 // callback-function
200 //
201 //
202 // Returns: tEplKernel = Errorcode
203 //
204 //
205 // State:
206 //
207 //---------------------------------------------------------------------------
208 tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
209 {
210 tEplKernel Ret;
211
212 #if (TARGET_SYSTEM == _WIN32_)
213 int iError;
214 WSADATA Wsa;
215
216 #endif
217
218 // set instance variables to 0
219 EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
220
221 Ret = kEplSuccessful;
222
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;
229 }
230
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;
238 }
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);
243
244 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
245 init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
246 SdoUdpInstance_g.m_iTerminateThread = 0;
247 #endif
248
249 SdoUdpInstance_g.m_ThreadHandle = 0;
250 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
251
252 Ret = EplSdoUdpuConfig(INADDR_ANY, 0);
253
254 Exit:
255 return Ret;
256 }
257
258 //---------------------------------------------------------------------------
259 //
260 // Function: EplSdoUdpuDelInstance
261 //
262 // Description: del instance of the module
263 // del socket and del Listen-Thread
264 //
265 //
266 //
267 // Parameters:
268 //
269 //
270 // Returns: tEplKernel = Errorcode
271 //
272 //
273 // State:
274 //
275 //---------------------------------------------------------------------------
276 tEplKernel PUBLIC EplSdoUdpuDelInstance()
277 {
278 tEplKernel Ret;
279
280 #if (TARGET_SYSTEM == _WIN32_)
281 BOOL fTermError;
282 #endif
283
284 Ret = kEplSuccessful;
285
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;
294 }
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
301
302 SdoUdpInstance_g.m_ThreadHandle = 0;
303 }
304
305 if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
306 // close socket
307 closesocket(SdoUdpInstance_g.m_UdpSocket);
308 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
309 }
310 #if (TARGET_SYSTEM == _WIN32_)
311 // delete critical section
312 DeleteCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
313 #endif
314
315 #if (TARGET_SYSTEM == _WIN32_)
316 // for win 32
317 WSACleanup();
318 #endif
319
320 #if (TARGET_SYSTEM == _WIN32_)
321 Exit:
322 #endif
323 return Ret;
324 }
325
326 //---------------------------------------------------------------------------
327 //
328 // Function: EplSdoUdpuConfig
329 //
330 // Description: reconfigurate socket with new IP-Address
331 // -> needed for NMT ResetConfiguration
332 //
333 // Parameters: ulIpAddr_p = IpAddress in platform byte order
334 // uiPort_p = port number in platform byte order
335 //
336 //
337 // Returns: tEplKernel = Errorcode
338 //
339 //
340 // State:
341 //
342 //---------------------------------------------------------------------------
343 tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
344 unsigned int uiPort_p)
345 {
346 tEplKernel Ret;
347 struct sockaddr_in Addr;
348 int iError;
349
350 #if (TARGET_SYSTEM == _WIN32_)
351 BOOL fTermError;
352 unsigned long ulThreadId;
353 #endif
354
355 Ret = kEplSuccessful;
356
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;
362 }
363
364 if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
365
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;
373 }
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
381
382 SdoUdpInstance_g.m_ThreadHandle = 0;
383 }
384
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;
392 }
393 }
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;
400 }
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;
414 }
415 // create Listen-Thread
416 #if (TARGET_SYSTEM == _WIN32_)
417 // for win32
418
419 // create thread
420 SdoUdpInstance_g.m_ThreadHandle = CreateThread(NULL,
421 0,
422 EplSdoUdpThread,
423 &SdoUdpInstance_g,
424 0, &ulThreadId);
425 if (SdoUdpInstance_g.m_ThreadHandle == NULL) {
426 Ret = kEplSdoUdpThreadError;
427 goto Exit;
428 }
429 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
430
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;
436 }
437 #endif
438
439 Exit:
440 return Ret;
441
442 }
443
444 //---------------------------------------------------------------------------
445 //
446 // Function: EplSdoUdpuInitCon
447 //
448 // Description: init a new connect
449 //
450 //
451 //
452 // Parameters: pSdoConHandle_p = pointer for the new connection handle
453 // uiTargetNodeId_p = NodeId of the target node
454 //
455 //
456 // Returns: tEplKernel = Errorcode
457 //
458 //
459 // State:
460 //
461 //---------------------------------------------------------------------------
462 tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
463 unsigned int uiTargetNodeId_p)
464 {
465 tEplKernel Ret;
466 unsigned int uiCount;
467 unsigned int uiFreeCon;
468 tEplSdoUdpCon *pSdoUdpCon;
469
470 Ret = kEplSuccessful;
471
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);
480
481 goto Exit;
482 } else if ((pSdoUdpCon->m_ulIpAddr == 0)
483 && (pSdoUdpCon->m_uiPort == 0)) {
484 uiFreeCon = uiCount;
485 }
486 uiCount++;
487 pSdoUdpCon++;
488 }
489
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
499
500 // set handle
501 *pSdoConHandle_p = (uiFreeCon | EPL_SDO_UDP_HANDLE);
502
503 }
504
505 Exit:
506 return Ret;
507
508 }
509
510 //---------------------------------------------------------------------------
511 //
512 // Function: EplSdoUdpuSendData
513 //
514 // Description: send data using exisiting connection
515 //
516 //
517 //
518 // Parameters: SdoConHandle_p = connection handle
519 // pSrcData_p = pointer to data
520 // dwDataSize_p = number of databyte
521 // -> without asend-header!!!
522 //
523 // Returns: tEplKernel = Errorcode
524 //
525 //
526 // State:
527 //
528 //---------------------------------------------------------------------------
529 tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
530 tEplFrame * pSrcData_p, DWORD dwDataSize_p)
531 {
532 tEplKernel Ret;
533 int iError;
534 unsigned int uiArray;
535 struct sockaddr_in Addr;
536
537 Ret = kEplSuccessful;
538
539 uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
540 if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
541 Ret = kEplSdoUdpInvalidHdl;
542 goto Exit;
543 }
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);
550
551 // calc size
552 dwDataSize_p += EPL_ASND_HEADER_SIZE;
553
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
560
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;
566
567 #if (TARGET_SYSTEM == _WIN32_)
568 // leave critical section for process function
569 LeaveCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
570 #endif
571
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;
583 }
584
585 Exit:
586 return Ret;
587
588 }
589
590 //---------------------------------------------------------------------------
591 //
592 // Function: EplSdoUdpuDelCon
593 //
594 // Description: delete connection from intern structure
595 //
596 //
597 //
598 // Parameters: SdoConHandle_p = connection handle
599 //
600 // Returns: tEplKernel = Errorcode
601 //
602 //
603 // State:
604 //
605 //---------------------------------------------------------------------------
606 tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
607 {
608 tEplKernel Ret;
609 unsigned int uiArray;
610
611 uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
612
613 if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
614 Ret = kEplSdoUdpInvalidHdl;
615 goto Exit;
616 } else {
617 Ret = kEplSuccessful;
618 }
619
620 // delete connection
621 SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr = 0;
622 SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_uiPort = 0;
623
624 Exit:
625 return Ret;
626 }
627
628 //=========================================================================//
629 // //
630 // P R I V A T E F U N C T I O N S //
631 // //
632 //=========================================================================//
633
634 //---------------------------------------------------------------------------
635 //
636 // Function: EplSdoUdpThread
637 //
638 // Description: thread check socket for new data
639 //
640 //
641 //
642 // Parameters: lpParameter = pointer to parameter type tEplSdoUdpThreadPara
643 //
644 //
645 // Returns: DWORD = errorcode
646 //
647 //
648 // State:
649 //
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
656 {
657
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;
666
667 #if (TARGET_SYSTEM == _WIN32_)
668 pInstance = (tEplSdoUdpInstance *) lpParameter;
669
670 for (;;)
671 #elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
672 pInstance = (tEplSdoUdpInstance *) pArg_p;
673 daemonize("EplSdoUdpThread");
674 allow_signal(SIGTERM);
675
676 for (; pInstance->m_iTerminateThread == 0;)
677 #endif
678
679 {
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;
691 }
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;
710 }
711
712 if ((pInstance->m_aSdoAbsUdpConnection[iCount].
713 m_ulIpAddr == 0)
714 && (pInstance->
715 m_aSdoAbsUdpConnection[iCount].
716 m_uiPort == 0)
717 && (iFreeEntry == 0xFFFF))
718 {
719 iFreeEntry = iCount;
720 }
721
722 iCount++;
723 }
724
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
760 }
761
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));
777 }
778 } // end of if(iError!=SOCKET_ERROR)
779 } // end of for(;;)
780
781 #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
782 complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
783 #endif
784
785 return 0;
786 }
787
788 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
789
790 // EOF
This page took 0.047473 seconds and 5 git commands to generate.