blob: b409c9b7be486b720fbbea6ed36a12c967148f4a [file] [log] [blame]
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001/****************************************************************************
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
Daniel Krueger9d7164c2008-12-19 11:41:57 -080071#include "user/EplSdoUdpu.h"
72
73#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
74
Daniel Krueger9d7164c2008-12-19 11:41:57 -080075#include "SocketLinuxKernel.h"
76#include <linux/completion.h>
77#include <linux/sched.h>
Daniel Krueger9d7164c2008-12-19 11:41:57 -080078
Daniel Krueger9d7164c2008-12-19 11:41:57 -080079/***************************************************************************/
80/* */
81/* */
82/* G L O B A L D E F I N I T I O N S */
83/* */
84/* */
85/***************************************************************************/
86
87//---------------------------------------------------------------------------
88// const defines
89//---------------------------------------------------------------------------
90
91#ifndef EPL_SDO_MAX_CONNECTION_UDP
92#define EPL_SDO_MAX_CONNECTION_UDP 5
93#endif
94
95//---------------------------------------------------------------------------
96// local types
97//---------------------------------------------------------------------------
98
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -080099typedef struct {
100 unsigned long m_ulIpAddr; // in network byte order
101 unsigned int m_uiPort; // in network byte order
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800102
103} tEplSdoUdpCon;
104
105// instance table
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800106typedef struct {
107 tEplSdoUdpCon m_aSdoAbsUdpConnection[EPL_SDO_MAX_CONNECTION_UDP];
108 tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
109 SOCKET m_UdpSocket;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800110
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800111 struct completion m_CompletionUdpThread;
112 int m_ThreadHandle;
113 int m_iTerminateThread;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800114} tEplSdoUdpInstance;
115
116//---------------------------------------------------------------------------
117// modul globale vars
118//---------------------------------------------------------------------------
119
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800120static tEplSdoUdpInstance SdoUdpInstance_g;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800121
122//---------------------------------------------------------------------------
123// local function prototypes
124//---------------------------------------------------------------------------
125
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800126static int EplSdoUdpThread(void *pArg_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800127
128/***************************************************************************/
129/* */
130/* */
131/* C L A S S <EPL-SDO-UDP-Layer> */
132/* */
133/* */
134/***************************************************************************/
135//
136// Description: Protocolabstraction layer for UDP
137//
138//
139/***************************************************************************/
140
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800141//=========================================================================//
142// //
143// P U B L I C F U N C T I O N S //
144// //
145//=========================================================================//
146
147//---------------------------------------------------------------------------
148//
149// Function: EplSdoUdpuInit
150//
151// Description: init first instance of the module
152//
153//
154//
155// Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
156// callback-function
157//
158//
159// Returns: tEplKernel = Errorcode
160//
161//
162// State:
163//
164//---------------------------------------------------------------------------
Greg Kroah-Hartmand10f4692009-03-23 10:45:12 -0700165tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800166{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800167 tEplKernel Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800168
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800169 Ret = EplSdoUdpuAddInstance(fpReceiveCb_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800170
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800171 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800172}
173
174//---------------------------------------------------------------------------
175//
176// Function: EplSdoUdpuAddInstance
177//
178// Description: init additional instance of the module
179// înit socket and start Listen-Thread
180//
181//
182//
183// Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
184// callback-function
185//
186//
187// Returns: tEplKernel = Errorcode
188//
189//
190// State:
191//
192//---------------------------------------------------------------------------
Greg Kroah-Hartmand10f4692009-03-23 10:45:12 -0700193tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800194{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800195 tEplKernel Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800196
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800197 // set instance variables to 0
198 EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800199
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800200 Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800201
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800202 // save pointer to callback-function
203 if (fpReceiveCb_p != NULL) {
204 SdoUdpInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
205 } else {
206 Ret = kEplSdoUdpMissCb;
207 goto Exit;
208 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800209
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800210 init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
211 SdoUdpInstance_g.m_iTerminateThread = 0;
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800212 SdoUdpInstance_g.m_ThreadHandle = 0;
213 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800214
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800215 Ret = EplSdoUdpuConfig(INADDR_ANY, 0);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800216
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800217 Exit:
218 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800219}
220
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800221//---------------------------------------------------------------------------
222//
223// Function: EplSdoUdpuDelInstance
224//
225// Description: del instance of the module
226// del socket and del Listen-Thread
227//
228//
229//
230// Parameters:
231//
232//
233// Returns: tEplKernel = Errorcode
234//
235//
236// State:
237//
238//---------------------------------------------------------------------------
Greg Kroah-Hartmand10f4692009-03-23 10:45:12 -0700239tEplKernel EplSdoUdpuDelInstance(void)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800240{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800241 tEplKernel Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800242
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800243 Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800244
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800245 if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
246 // close thread
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800247 SdoUdpInstance_g.m_iTerminateThread = 1;
248 /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
249 send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
250 wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800251 SdoUdpInstance_g.m_ThreadHandle = 0;
252 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800253
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800254 if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
255 // close socket
256 closesocket(SdoUdpInstance_g.m_UdpSocket);
257 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
258 }
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800259 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800260}
261
262//---------------------------------------------------------------------------
263//
264// Function: EplSdoUdpuConfig
265//
266// Description: reconfigurate socket with new IP-Address
267// -> needed for NMT ResetConfiguration
268//
269// Parameters: ulIpAddr_p = IpAddress in platform byte order
270// uiPort_p = port number in platform byte order
271//
272//
273// Returns: tEplKernel = Errorcode
274//
275//
276// State:
277//
278//---------------------------------------------------------------------------
Greg Kroah-Hartmand10f4692009-03-23 10:45:12 -0700279tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800280{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800281 tEplKernel Ret;
282 struct sockaddr_in Addr;
283 int iError;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800284
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800285 Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800286
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800287 if (uiPort_p == 0) { // set UDP port to default port number
288 uiPort_p = EPL_C_SDO_EPL_PORT;
289 } else if (uiPort_p > 65535) {
290 Ret = kEplSdoUdpSocketError;
291 goto Exit;
292 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800293
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800294 if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800295
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800296 // close old thread
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800297 SdoUdpInstance_g.m_iTerminateThread = 1;
298 /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
299 send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
300 wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
301 SdoUdpInstance_g.m_iTerminateThread = 0;
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800302 SdoUdpInstance_g.m_ThreadHandle = 0;
303 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800304
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800305 if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
306 // close socket
307 iError = closesocket(SdoUdpInstance_g.m_UdpSocket);
308 SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
309 if (iError != 0) {
310 Ret = kEplSdoUdpSocketError;
311 goto Exit;
312 }
313 }
314 // create Socket
315 SdoUdpInstance_g.m_UdpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
316 if (SdoUdpInstance_g.m_UdpSocket == INVALID_SOCKET) {
317 Ret = kEplSdoUdpNoSocket;
318 EPL_DBGLVL_SDO_TRACE0("EplSdoUdpuConfig: socket() failed\n");
319 goto Exit;
320 }
321 // bind socket
322 Addr.sin_family = AF_INET;
323 Addr.sin_port = htons((unsigned short)uiPort_p);
324 Addr.sin_addr.s_addr = htonl(ulIpAddr_p);
325 iError =
326 bind(SdoUdpInstance_g.m_UdpSocket, (struct sockaddr *)&Addr,
327 sizeof(Addr));
328 if (iError < 0) {
329 //iError = WSAGetLastError();
330 EPL_DBGLVL_SDO_TRACE1
331 ("EplSdoUdpuConfig: bind() finished with %i\n", iError);
332 Ret = kEplSdoUdpNoSocket;
333 goto Exit;
334 }
335 // create Listen-Thread
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800336 SdoUdpInstance_g.m_ThreadHandle =
337 kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g, CLONE_KERNEL);
338 if (SdoUdpInstance_g.m_ThreadHandle == 0) {
339 Ret = kEplSdoUdpThreadError;
340 goto Exit;
341 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800342
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800343 Exit:
344 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800345
346}
347
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800348//---------------------------------------------------------------------------
349//
350// Function: EplSdoUdpuInitCon
351//
352// Description: init a new connect
353//
354//
355//
356// Parameters: pSdoConHandle_p = pointer for the new connection handle
357// uiTargetNodeId_p = NodeId of the target node
358//
359//
360// Returns: tEplKernel = Errorcode
361//
362//
363// State:
364//
365//---------------------------------------------------------------------------
Greg Kroah-Hartmand10f4692009-03-23 10:45:12 -0700366tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
367 unsigned int uiTargetNodeId_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800368{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800369 tEplKernel Ret;
370 unsigned int uiCount;
371 unsigned int uiFreeCon;
372 tEplSdoUdpCon *pSdoUdpCon;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800373
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800374 Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800375
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800376 // get free entry in control structure
377 uiCount = 0;
378 uiFreeCon = EPL_SDO_MAX_CONNECTION_UDP;
379 pSdoUdpCon = &SdoUdpInstance_g.m_aSdoAbsUdpConnection[0];
380 while (uiCount < EPL_SDO_MAX_CONNECTION_UDP) {
381 if ((pSdoUdpCon->m_ulIpAddr & htonl(0xFF)) == htonl(uiTargetNodeId_p)) { // existing connection to target node found
382 // set handle
383 *pSdoConHandle_p = (uiCount | EPL_SDO_UDP_HANDLE);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800384
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800385 goto Exit;
386 } else if ((pSdoUdpCon->m_ulIpAddr == 0)
387 && (pSdoUdpCon->m_uiPort == 0)) {
388 uiFreeCon = uiCount;
389 }
390 uiCount++;
391 pSdoUdpCon++;
392 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800393
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800394 if (uiFreeCon == EPL_SDO_MAX_CONNECTION_UDP) {
395 // error no free handle
396 Ret = kEplSdoUdpNoFreeHandle;
397 } else {
398 pSdoUdpCon =
399 &SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiFreeCon];
400 // save infos for connection
401 pSdoUdpCon->m_uiPort = htons(EPL_C_SDO_EPL_PORT);
402 pSdoUdpCon->m_ulIpAddr = htonl(0xC0A86400 | uiTargetNodeId_p); // 192.168.100.uiTargetNodeId_p
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800403
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800404 // set handle
405 *pSdoConHandle_p = (uiFreeCon | EPL_SDO_UDP_HANDLE);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800406
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800407 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800408
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800409 Exit:
410 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800411
412}
413
414//---------------------------------------------------------------------------
415//
416// Function: EplSdoUdpuSendData
417//
418// Description: send data using exisiting connection
419//
420//
421//
422// Parameters: SdoConHandle_p = connection handle
423// pSrcData_p = pointer to data
424// dwDataSize_p = number of databyte
425// -> without asend-header!!!
426//
427// Returns: tEplKernel = Errorcode
428//
429//
430// State:
431//
432//---------------------------------------------------------------------------
Greg Kroah-Hartmand10f4692009-03-23 10:45:12 -0700433tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
Greg Kroah-Hartmand539cfb2009-03-23 12:51:37 -0700434 tEplFrame *pSrcData_p, u32 dwDataSize_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800435{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800436 tEplKernel Ret;
437 int iError;
438 unsigned int uiArray;
439 struct sockaddr_in Addr;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800440
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800441 Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800442
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800443 uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
444 if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
445 Ret = kEplSdoUdpInvalidHdl;
446 goto Exit;
447 }
448 //set message type
449 AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, 0x06); // SDO
450 // target node id (for Udp = 0)
451 AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, 0x00);
452 // set source-nodeid (for Udp = 0)
453 AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800454
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800455 // calc size
456 dwDataSize_p += EPL_ASND_HEADER_SIZE;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800457
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800458 // call sendto
459 Addr.sin_family = AF_INET;
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800460 Addr.sin_port =
461 (unsigned short)SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].
462 m_uiPort;
463 Addr.sin_addr.s_addr =
464 SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800465
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800466 iError = sendto(SdoUdpInstance_g.m_UdpSocket, // sockethandle
467 (const char *)&pSrcData_p->m_le_bMessageType, // data to send
468 dwDataSize_p, // number of bytes to send
469 0, // flags
470 (struct sockaddr *)&Addr, // target
471 sizeof(struct sockaddr_in)); // sizeof targetadress
472 if (iError < 0) {
473 EPL_DBGLVL_SDO_TRACE1
474 ("EplSdoUdpuSendData: sendto() finished with %i\n", iError);
475 Ret = kEplSdoUdpSendError;
476 goto Exit;
477 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800478
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800479 Exit:
480 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800481
482}
483
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800484//---------------------------------------------------------------------------
485//
486// Function: EplSdoUdpuDelCon
487//
488// Description: delete connection from intern structure
489//
490//
491//
492// Parameters: SdoConHandle_p = connection handle
493//
494// Returns: tEplKernel = Errorcode
495//
496//
497// State:
498//
499//---------------------------------------------------------------------------
Greg Kroah-Hartmand10f4692009-03-23 10:45:12 -0700500tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800501{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800502 tEplKernel Ret;
503 unsigned int uiArray;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800504
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800505 uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800506
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800507 if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
508 Ret = kEplSdoUdpInvalidHdl;
509 goto Exit;
510 } else {
511 Ret = kEplSuccessful;
512 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800513
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800514 // delete connection
515 SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr = 0;
516 SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_uiPort = 0;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800517
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800518 Exit:
519 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800520}
521
522//=========================================================================//
523// //
524// P R I V A T E F U N C T I O N S //
525// //
526//=========================================================================//
527
528//---------------------------------------------------------------------------
529//
530// Function: EplSdoUdpThread
531//
532// Description: thread check socket for new data
533//
534//
535//
536// Parameters: lpParameter = pointer to parameter type tEplSdoUdpThreadPara
537//
538//
Greg Kroah-Hartmand539cfb2009-03-23 12:51:37 -0700539// Returns: u32 = errorcode
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800540//
541//
542// State:
543//
544//---------------------------------------------------------------------------
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800545static int EplSdoUdpThread(void *pArg_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800546{
547
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800548 tEplSdoUdpInstance *pInstance;
549 struct sockaddr_in RemoteAddr;
550 int iError;
551 int iCount;
552 int iFreeEntry;
Greg Kroah-Hartman2ed53cf2009-03-23 12:36:38 -0700553 u8 abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800554 unsigned int uiSize;
555 tEplSdoConHdl SdoConHdl;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800556
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800557 pInstance = (tEplSdoUdpInstance *) pArg_p;
558 daemonize("EplSdoUdpThread");
559 allow_signal(SIGTERM);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800560
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800561 for (; pInstance->m_iTerminateThread == 0;)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800562
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800563 {
564 // wait for data
565 uiSize = sizeof(struct sockaddr);
566 iError = recvfrom(pInstance->m_UdpSocket, // Socket
567 (char *)&abBuffer[0], // buffer for data
568 sizeof(abBuffer), // size of the buffer
569 0, // flags
570 (struct sockaddr *)&RemoteAddr,
571 (int *)&uiSize);
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800572 if (iError == -ERESTARTSYS) {
573 break;
574 }
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800575 if (iError > 0) {
576 // get handle for higher layer
577 iCount = 0;
578 iFreeEntry = 0xFFFF;
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800579 while (iCount < EPL_SDO_MAX_CONNECTION_UDP) {
580 // check if this connection is already known
581 if ((pInstance->m_aSdoAbsUdpConnection[iCount].
582 m_ulIpAddr == RemoteAddr.sin_addr.s_addr)
583 && (pInstance->
584 m_aSdoAbsUdpConnection[iCount].
585 m_uiPort == RemoteAddr.sin_port)) {
586 break;
587 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800588
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800589 if ((pInstance->m_aSdoAbsUdpConnection[iCount].
590 m_ulIpAddr == 0)
591 && (pInstance->
592 m_aSdoAbsUdpConnection[iCount].
593 m_uiPort == 0)
594 && (iFreeEntry == 0xFFFF))
595 {
596 iFreeEntry = iCount;
597 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800598
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800599 iCount++;
600 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800601
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800602 if (iCount == EPL_SDO_MAX_CONNECTION_UDP) {
603 // connection unknown
604 // see if there is a free handle
605 if (iFreeEntry != 0xFFFF) {
606 // save adress infos
607 pInstance->
608 m_aSdoAbsUdpConnection[iFreeEntry].
609 m_ulIpAddr =
610 RemoteAddr.sin_addr.s_addr;
611 pInstance->
612 m_aSdoAbsUdpConnection[iFreeEntry].
613 m_uiPort = RemoteAddr.sin_port;
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800614 // call callback
615 SdoConHdl = iFreeEntry;
616 SdoConHdl |= EPL_SDO_UDP_HANDLE;
617 // offset 4 -> start of SDO Sequence header
618 pInstance->m_fpSdoAsySeqCb(SdoConHdl,
619 (tEplAsySdoSeq
620 *) &
621 abBuffer[4],
622 (iError -
623 4));
624 } else {
625 EPL_DBGLVL_SDO_TRACE0
626 ("Error in EplSdoUdpThread() no free handle\n");
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800627 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800628
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800629 } else {
630 // known connection
631 // call callback with correct handle
632 SdoConHdl = iCount;
633 SdoConHdl |= EPL_SDO_UDP_HANDLE;
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800634 // offset 4 -> start of SDO Sequence header
635 pInstance->m_fpSdoAsySeqCb(SdoConHdl,
636 (tEplAsySdoSeq *) &
637 abBuffer[4],
638 (iError - 4));
639 }
640 } // end of if(iError!=SOCKET_ERROR)
641 } // end of for(;;)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800642
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800643 complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800644 return 0;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800645}
646
647#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
648
649// EOF