6456f0b768
Not sure this patch is really needed since kernel_thread() is deprecated (and checkpatch.pl complains). But we should not use kernel_thread(CLONE_SIGHAND) if we are going to play with signals. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
651 lines
19 KiB
C
651 lines
19 KiB
C
/****************************************************************************
|
||
|
||
(c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
|
||
www.systec-electronic.com
|
||
|
||
Project: openPOWERLINK
|
||
|
||
Description: source file for SDO/UDP-Protocolabstractionlayer module
|
||
|
||
License:
|
||
|
||
Redistribution and use in source and binary forms, with or without
|
||
modification, are permitted provided that the following conditions
|
||
are met:
|
||
|
||
1. Redistributions of source code must retain the above copyright
|
||
notice, this list of conditions and the following disclaimer.
|
||
|
||
2. Redistributions in binary form must reproduce the above copyright
|
||
notice, this list of conditions and the following disclaimer in the
|
||
documentation and/or other materials provided with the distribution.
|
||
|
||
3. Neither the name of SYSTEC electronic GmbH nor the names of its
|
||
contributors may be used to endorse or promote products derived
|
||
from this software without prior written permission. For written
|
||
permission, please contact info@systec-electronic.com.
|
||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||
COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
POSSIBILITY OF SUCH DAMAGE.
|
||
|
||
Severability Clause:
|
||
|
||
If a provision of this License is or becomes illegal, invalid or
|
||
unenforceable in any jurisdiction, that shall not affect:
|
||
1. the validity or enforceability in that jurisdiction of any other
|
||
provision of this License; or
|
||
2. the validity or enforceability in other jurisdictions of that or
|
||
any other provision of this License.
|
||
|
||
-------------------------------------------------------------------------
|
||
|
||
$RCSfile: EplSdoUdpu.c,v $
|
||
|
||
$Author: D.Krueger $
|
||
|
||
$Revision: 1.8 $ $Date: 2008/10/17 15:32:32 $
|
||
|
||
$State: Exp $
|
||
|
||
Build Environment:
|
||
GCC V3.4
|
||
|
||
-------------------------------------------------------------------------
|
||
|
||
Revision History:
|
||
|
||
2006/06/26 k.t.: start of the implementation
|
||
|
||
****************************************************************************/
|
||
|
||
#include "user/EplSdoUdpu.h"
|
||
|
||
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
|
||
|
||
#include "SocketLinuxKernel.h"
|
||
#include <linux/completion.h>
|
||
#include <linux/sched.h>
|
||
|
||
/***************************************************************************/
|
||
/* */
|
||
/* */
|
||
/* G L O B A L D E F I N I T I O N S */
|
||
/* */
|
||
/* */
|
||
/***************************************************************************/
|
||
|
||
//---------------------------------------------------------------------------
|
||
// const defines
|
||
//---------------------------------------------------------------------------
|
||
|
||
#ifndef EPL_SDO_MAX_CONNECTION_UDP
|
||
#define EPL_SDO_MAX_CONNECTION_UDP 5
|
||
#endif
|
||
|
||
//---------------------------------------------------------------------------
|
||
// local types
|
||
//---------------------------------------------------------------------------
|
||
|
||
typedef struct {
|
||
unsigned long m_ulIpAddr; // in network byte order
|
||
unsigned int m_uiPort; // in network byte order
|
||
|
||
} tEplSdoUdpCon;
|
||
|
||
// instance table
|
||
typedef struct {
|
||
tEplSdoUdpCon m_aSdoAbsUdpConnection[EPL_SDO_MAX_CONNECTION_UDP];
|
||
tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
|
||
SOCKET m_UdpSocket;
|
||
|
||
struct completion m_CompletionUdpThread;
|
||
int m_ThreadHandle;
|
||
int m_iTerminateThread;
|
||
} tEplSdoUdpInstance;
|
||
|
||
//---------------------------------------------------------------------------
|
||
// modul globale vars
|
||
//---------------------------------------------------------------------------
|
||
|
||
static tEplSdoUdpInstance SdoUdpInstance_g;
|
||
|
||
//---------------------------------------------------------------------------
|
||
// local function prototypes
|
||
//---------------------------------------------------------------------------
|
||
|
||
static int EplSdoUdpThread(void *pArg_p);
|
||
|
||
/***************************************************************************/
|
||
/* */
|
||
/* */
|
||
/* C L A S S <EPL-SDO-UDP-Layer> */
|
||
/* */
|
||
/* */
|
||
/***************************************************************************/
|
||
//
|
||
// Description: Protocolabstraction layer for UDP
|
||
//
|
||
//
|
||
/***************************************************************************/
|
||
|
||
//=========================================================================//
|
||
// //
|
||
// P U B L I C F U N C T I O N S //
|
||
// //
|
||
//=========================================================================//
|
||
|
||
//---------------------------------------------------------------------------
|
||
//
|
||
// Function: EplSdoUdpuInit
|
||
//
|
||
// Description: init first instance of the module
|
||
//
|
||
//
|
||
//
|
||
// Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
|
||
// callback-function
|
||
//
|
||
//
|
||
// Returns: tEplKernel = Errorcode
|
||
//
|
||
//
|
||
// State:
|
||
//
|
||
//---------------------------------------------------------------------------
|
||
tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
|
||
{
|
||
tEplKernel Ret;
|
||
|
||
Ret = EplSdoUdpuAddInstance(fpReceiveCb_p);
|
||
|
||
return Ret;
|
||
}
|
||
|
||
//---------------------------------------------------------------------------
|
||
//
|
||
// Function: EplSdoUdpuAddInstance
|
||
//
|
||
// Description: init additional instance of the module
|
||
// <20>nit socket and start Listen-Thread
|
||
//
|
||
//
|
||
//
|
||
// Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
|
||
// callback-function
|
||
//
|
||
//
|
||
// Returns: tEplKernel = Errorcode
|
||
//
|
||
//
|
||
// State:
|
||
//
|
||
//---------------------------------------------------------------------------
|
||
tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
|
||
{
|
||
tEplKernel Ret;
|
||
|
||
// set instance variables to 0
|
||
EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
|
||
|
||
Ret = kEplSuccessful;
|
||
|
||
// save pointer to callback-function
|
||
if (fpReceiveCb_p != NULL) {
|
||
SdoUdpInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
|
||
} else {
|
||
Ret = kEplSdoUdpMissCb;
|
||
goto Exit;
|
||
}
|
||
|
||
init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
|
||
SdoUdpInstance_g.m_iTerminateThread = 0;
|
||
SdoUdpInstance_g.m_ThreadHandle = 0;
|
||
SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
|
||
|
||
Ret = EplSdoUdpuConfig(INADDR_ANY, 0);
|
||
|
||
Exit:
|
||
return Ret;
|
||
}
|
||
|
||
//---------------------------------------------------------------------------
|
||
//
|
||
// Function: EplSdoUdpuDelInstance
|
||
//
|
||
// Description: del instance of the module
|
||
// del socket and del Listen-Thread
|
||
//
|
||
//
|
||
//
|
||
// Parameters:
|
||
//
|
||
//
|
||
// Returns: tEplKernel = Errorcode
|
||
//
|
||
//
|
||
// State:
|
||
//
|
||
//---------------------------------------------------------------------------
|
||
tEplKernel EplSdoUdpuDelInstance(void)
|
||
{
|
||
tEplKernel Ret;
|
||
|
||
Ret = kEplSuccessful;
|
||
|
||
if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
|
||
// close thread
|
||
SdoUdpInstance_g.m_iTerminateThread = 1;
|
||
/* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
|
||
send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
|
||
wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
|
||
SdoUdpInstance_g.m_ThreadHandle = 0;
|
||
}
|
||
|
||
if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
|
||
// close socket
|
||
closesocket(SdoUdpInstance_g.m_UdpSocket);
|
||
SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
|
||
}
|
||
return Ret;
|
||
}
|
||
|
||
//---------------------------------------------------------------------------
|
||
//
|
||
// Function: EplSdoUdpuConfig
|
||
//
|
||
// Description: reconfigurate socket with new IP-Address
|
||
// -> needed for NMT ResetConfiguration
|
||
//
|
||
// Parameters: ulIpAddr_p = IpAddress in platform byte order
|
||
// uiPort_p = port number in platform byte order
|
||
//
|
||
//
|
||
// Returns: tEplKernel = Errorcode
|
||
//
|
||
//
|
||
// State:
|
||
//
|
||
//---------------------------------------------------------------------------
|
||
tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p)
|
||
{
|
||
tEplKernel Ret;
|
||
struct sockaddr_in Addr;
|
||
int iError;
|
||
|
||
Ret = kEplSuccessful;
|
||
|
||
if (uiPort_p == 0) { // set UDP port to default port number
|
||
uiPort_p = EPL_C_SDO_EPL_PORT;
|
||
} else if (uiPort_p > 65535) {
|
||
Ret = kEplSdoUdpSocketError;
|
||
goto Exit;
|
||
}
|
||
|
||
if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
|
||
|
||
// close old thread
|
||
SdoUdpInstance_g.m_iTerminateThread = 1;
|
||
/* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
|
||
send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
|
||
wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
|
||
SdoUdpInstance_g.m_iTerminateThread = 0;
|
||
SdoUdpInstance_g.m_ThreadHandle = 0;
|
||
}
|
||
|
||
if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
|
||
// close socket
|
||
iError = closesocket(SdoUdpInstance_g.m_UdpSocket);
|
||
SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
|
||
if (iError != 0) {
|
||
Ret = kEplSdoUdpSocketError;
|
||
goto Exit;
|
||
}
|
||
}
|
||
// create Socket
|
||
SdoUdpInstance_g.m_UdpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||
if (SdoUdpInstance_g.m_UdpSocket == INVALID_SOCKET) {
|
||
Ret = kEplSdoUdpNoSocket;
|
||
EPL_DBGLVL_SDO_TRACE0("EplSdoUdpuConfig: socket() failed\n");
|
||
goto Exit;
|
||
}
|
||
// bind socket
|
||
Addr.sin_family = AF_INET;
|
||
Addr.sin_port = htons((unsigned short)uiPort_p);
|
||
Addr.sin_addr.s_addr = htonl(ulIpAddr_p);
|
||
iError =
|
||
bind(SdoUdpInstance_g.m_UdpSocket, (struct sockaddr *)&Addr,
|
||
sizeof(Addr));
|
||
if (iError < 0) {
|
||
//iError = WSAGetLastError();
|
||
EPL_DBGLVL_SDO_TRACE1
|
||
("EplSdoUdpuConfig: bind() finished with %i\n", iError);
|
||
Ret = kEplSdoUdpNoSocket;
|
||
goto Exit;
|
||
}
|
||
// create Listen-Thread
|
||
SdoUdpInstance_g.m_ThreadHandle =
|
||
kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g,
|
||
CLONE_FS | CLONE_FILES);
|
||
if (SdoUdpInstance_g.m_ThreadHandle == 0) {
|
||
Ret = kEplSdoUdpThreadError;
|
||
goto Exit;
|
||
}
|
||
|
||
Exit:
|
||
return Ret;
|
||
|
||
}
|
||
|
||
//---------------------------------------------------------------------------
|
||
//
|
||
// Function: EplSdoUdpuInitCon
|
||
//
|
||
// Description: init a new connect
|
||
//
|
||
//
|
||
//
|
||
// Parameters: pSdoConHandle_p = pointer for the new connection handle
|
||
// uiTargetNodeId_p = NodeId of the target node
|
||
//
|
||
//
|
||
// Returns: tEplKernel = Errorcode
|
||
//
|
||
//
|
||
// State:
|
||
//
|
||
//---------------------------------------------------------------------------
|
||
tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
|
||
unsigned int uiTargetNodeId_p)
|
||
{
|
||
tEplKernel Ret;
|
||
unsigned int uiCount;
|
||
unsigned int uiFreeCon;
|
||
tEplSdoUdpCon *pSdoUdpCon;
|
||
|
||
Ret = kEplSuccessful;
|
||
|
||
// get free entry in control structure
|
||
uiCount = 0;
|
||
uiFreeCon = EPL_SDO_MAX_CONNECTION_UDP;
|
||
pSdoUdpCon = &SdoUdpInstance_g.m_aSdoAbsUdpConnection[0];
|
||
while (uiCount < EPL_SDO_MAX_CONNECTION_UDP) {
|
||
if ((pSdoUdpCon->m_ulIpAddr & htonl(0xFF)) == htonl(uiTargetNodeId_p)) { // existing connection to target node found
|
||
// set handle
|
||
*pSdoConHandle_p = (uiCount | EPL_SDO_UDP_HANDLE);
|
||
|
||
goto Exit;
|
||
} else if ((pSdoUdpCon->m_ulIpAddr == 0)
|
||
&& (pSdoUdpCon->m_uiPort == 0)) {
|
||
uiFreeCon = uiCount;
|
||
}
|
||
uiCount++;
|
||
pSdoUdpCon++;
|
||
}
|
||
|
||
if (uiFreeCon == EPL_SDO_MAX_CONNECTION_UDP) {
|
||
// error no free handle
|
||
Ret = kEplSdoUdpNoFreeHandle;
|
||
} else {
|
||
pSdoUdpCon =
|
||
&SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiFreeCon];
|
||
// save infos for connection
|
||
pSdoUdpCon->m_uiPort = htons(EPL_C_SDO_EPL_PORT);
|
||
pSdoUdpCon->m_ulIpAddr = htonl(0xC0A86400 | uiTargetNodeId_p); // 192.168.100.uiTargetNodeId_p
|
||
|
||
// set handle
|
||
*pSdoConHandle_p = (uiFreeCon | EPL_SDO_UDP_HANDLE);
|
||
|
||
}
|
||
|
||
Exit:
|
||
return Ret;
|
||
|
||
}
|
||
|
||
//---------------------------------------------------------------------------
|
||
//
|
||
// Function: EplSdoUdpuSendData
|
||
//
|
||
// Description: send data using exisiting connection
|
||
//
|
||
//
|
||
//
|
||
// Parameters: SdoConHandle_p = connection handle
|
||
// pSrcData_p = pointer to data
|
||
// dwDataSize_p = number of databyte
|
||
// -> without asend-header!!!
|
||
//
|
||
// Returns: tEplKernel = Errorcode
|
||
//
|
||
//
|
||
// State:
|
||
//
|
||
//---------------------------------------------------------------------------
|
||
tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
|
||
tEplFrame *pSrcData_p, u32 dwDataSize_p)
|
||
{
|
||
tEplKernel Ret;
|
||
int iError;
|
||
unsigned int uiArray;
|
||
struct sockaddr_in Addr;
|
||
|
||
Ret = kEplSuccessful;
|
||
|
||
uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
|
||
if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
|
||
Ret = kEplSdoUdpInvalidHdl;
|
||
goto Exit;
|
||
}
|
||
//set message type
|
||
AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, 0x06); // SDO
|
||
// target node id (for Udp = 0)
|
||
AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, 0x00);
|
||
// set source-nodeid (for Udp = 0)
|
||
AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
|
||
|
||
// calc size
|
||
dwDataSize_p += EPL_ASND_HEADER_SIZE;
|
||
|
||
// call sendto
|
||
Addr.sin_family = AF_INET;
|
||
Addr.sin_port =
|
||
(unsigned short)SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].
|
||
m_uiPort;
|
||
Addr.sin_addr.s_addr =
|
||
SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr;
|
||
|
||
iError = sendto(SdoUdpInstance_g.m_UdpSocket, // sockethandle
|
||
(const char *)&pSrcData_p->m_le_bMessageType, // data to send
|
||
dwDataSize_p, // number of bytes to send
|
||
0, // flags
|
||
(struct sockaddr *)&Addr, // target
|
||
sizeof(struct sockaddr_in)); // sizeof targetadress
|
||
if (iError < 0) {
|
||
EPL_DBGLVL_SDO_TRACE1
|
||
("EplSdoUdpuSendData: sendto() finished with %i\n", iError);
|
||
Ret = kEplSdoUdpSendError;
|
||
goto Exit;
|
||
}
|
||
|
||
Exit:
|
||
return Ret;
|
||
|
||
}
|
||
|
||
//---------------------------------------------------------------------------
|
||
//
|
||
// Function: EplSdoUdpuDelCon
|
||
//
|
||
// Description: delete connection from intern structure
|
||
//
|
||
//
|
||
//
|
||
// Parameters: SdoConHandle_p = connection handle
|
||
//
|
||
// Returns: tEplKernel = Errorcode
|
||
//
|
||
//
|
||
// State:
|
||
//
|
||
//---------------------------------------------------------------------------
|
||
tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
|
||
{
|
||
tEplKernel Ret;
|
||
unsigned int uiArray;
|
||
|
||
uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
|
||
|
||
if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
|
||
Ret = kEplSdoUdpInvalidHdl;
|
||
goto Exit;
|
||
} else {
|
||
Ret = kEplSuccessful;
|
||
}
|
||
|
||
// delete connection
|
||
SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr = 0;
|
||
SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_uiPort = 0;
|
||
|
||
Exit:
|
||
return Ret;
|
||
}
|
||
|
||
//=========================================================================//
|
||
// //
|
||
// P R I V A T E F U N C T I O N S //
|
||
// //
|
||
//=========================================================================//
|
||
|
||
//---------------------------------------------------------------------------
|
||
//
|
||
// Function: EplSdoUdpThread
|
||
//
|
||
// Description: thread check socket for new data
|
||
//
|
||
//
|
||
//
|
||
// Parameters: lpParameter = pointer to parameter type tEplSdoUdpThreadPara
|
||
//
|
||
//
|
||
// Returns: u32 = errorcode
|
||
//
|
||
//
|
||
// State:
|
||
//
|
||
//---------------------------------------------------------------------------
|
||
static int EplSdoUdpThread(void *pArg_p)
|
||
{
|
||
|
||
tEplSdoUdpInstance *pInstance;
|
||
struct sockaddr_in RemoteAddr;
|
||
int iError;
|
||
int iCount;
|
||
int iFreeEntry;
|
||
u8 abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
|
||
unsigned int uiSize;
|
||
tEplSdoConHdl SdoConHdl;
|
||
|
||
pInstance = (tEplSdoUdpInstance *) pArg_p;
|
||
daemonize("EplSdoUdpThread");
|
||
allow_signal(SIGTERM);
|
||
|
||
for (; pInstance->m_iTerminateThread == 0;)
|
||
|
||
{
|
||
// wait for data
|
||
uiSize = sizeof(struct sockaddr);
|
||
iError = recvfrom(pInstance->m_UdpSocket, // Socket
|
||
(char *)&abBuffer[0], // buffer for data
|
||
sizeof(abBuffer), // size of the buffer
|
||
0, // flags
|
||
(struct sockaddr *)&RemoteAddr,
|
||
(int *)&uiSize);
|
||
if (iError == -ERESTARTSYS) {
|
||
break;
|
||
}
|
||
if (iError > 0) {
|
||
// get handle for higher layer
|
||
iCount = 0;
|
||
iFreeEntry = 0xFFFF;
|
||
while (iCount < EPL_SDO_MAX_CONNECTION_UDP) {
|
||
// check if this connection is already known
|
||
if ((pInstance->m_aSdoAbsUdpConnection[iCount].
|
||
m_ulIpAddr == RemoteAddr.sin_addr.s_addr)
|
||
&& (pInstance->
|
||
m_aSdoAbsUdpConnection[iCount].
|
||
m_uiPort == RemoteAddr.sin_port)) {
|
||
break;
|
||
}
|
||
|
||
if ((pInstance->m_aSdoAbsUdpConnection[iCount].
|
||
m_ulIpAddr == 0)
|
||
&& (pInstance->
|
||
m_aSdoAbsUdpConnection[iCount].
|
||
m_uiPort == 0)
|
||
&& (iFreeEntry == 0xFFFF))
|
||
{
|
||
iFreeEntry = iCount;
|
||
}
|
||
|
||
iCount++;
|
||
}
|
||
|
||
if (iCount == EPL_SDO_MAX_CONNECTION_UDP) {
|
||
// connection unknown
|
||
// see if there is a free handle
|
||
if (iFreeEntry != 0xFFFF) {
|
||
// save adress infos
|
||
pInstance->
|
||
m_aSdoAbsUdpConnection[iFreeEntry].
|
||
m_ulIpAddr =
|
||
RemoteAddr.sin_addr.s_addr;
|
||
pInstance->
|
||
m_aSdoAbsUdpConnection[iFreeEntry].
|
||
m_uiPort = RemoteAddr.sin_port;
|
||
// call callback
|
||
SdoConHdl = iFreeEntry;
|
||
SdoConHdl |= EPL_SDO_UDP_HANDLE;
|
||
// offset 4 -> start of SDO Sequence header
|
||
pInstance->m_fpSdoAsySeqCb(SdoConHdl,
|
||
(tEplAsySdoSeq
|
||
*) &
|
||
abBuffer[4],
|
||
(iError -
|
||
4));
|
||
} else {
|
||
EPL_DBGLVL_SDO_TRACE0
|
||
("Error in EplSdoUdpThread() no free handle\n");
|
||
}
|
||
|
||
} else {
|
||
// known connection
|
||
// call callback with correct handle
|
||
SdoConHdl = iCount;
|
||
SdoConHdl |= EPL_SDO_UDP_HANDLE;
|
||
// offset 4 -> start of SDO Sequence header
|
||
pInstance->m_fpSdoAsySeqCb(SdoConHdl,
|
||
(tEplAsySdoSeq *) &
|
||
abBuffer[4],
|
||
(iError - 4));
|
||
}
|
||
} // end of if(iError!=SOCKET_ERROR)
|
||
} // end of for(;;)
|
||
|
||
complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
|
||
return 0;
|
||
}
|
||
|
||
#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
|
||
|
||
// EOF
|