Exemple #1
0
/**
  @brief Set the cursor to the element with the given data

  @return OpcUa_Null if no element is found
  @return OpcUa_Null if a_pList is null
  @return OpcUa_Null if a_pElementData is null
  @return a pointer to the user data that was found

  This function should use currtElement instead of tempElement so that
  when it returns the cursor is left pointing at the found element

  @param a_plist            [in]    Location of the list
  @param a_pElementData     [in]    Data to find
*/
OpcUa_Void* OpcUa_List_GetElement(OpcUa_List* a_pList, OpcUa_Void* a_pElementData)
{
    OpcUa_StatusCode   uStatus      = OpcUa_Good;
    OpcUa_ListElement* tempElement  = OpcUa_Null;

    OpcUa_DeclareErrorTraceModule(OpcUa_Module_List);

    OpcUa_GotoErrorIfArgumentNull(a_pList);
    OpcUa_GotoErrorIfArgumentNull(a_pElementData);

    tempElement = a_pList->firstElement;

    while(tempElement != OpcUa_Null)
    {
        if(tempElement->data == a_pElementData)
        {

            return tempElement->data;
        }

        tempElement = tempElement->nextElement;
    }


Error:
    return OpcUa_Null;
}
Exemple #2
0
/**
  @brief Deletes the current element performing all necessary list management
  However, the list element is added to a temporary list and must be removed manually

  QueueFirst and QueueLast have to be initialized to null before first use

  Takes no action if a_pList is null
  Takes no action if a_pList->currtElement is null

  @param a_pList        [in]    Location of the list
  @param a_ppQueueFirst [in]    First Element of the queue
  @param a_ppQueueLast  [in]    Last Element of the queue
*/
OPCUA_EXPORT
OpcUa_Void          OpcUa_List_EnQueueCurrentElement(OpcUa_List*         a_pList,
                                                     OpcUa_ListElement** a_ppQueueFirst,
                                                     OpcUa_ListElement** a_ppQueueLast)

{
    OpcUa_StatusCode    uStatus         = OpcUa_Good;
    OpcUa_ListElement*  deleteElement   = OpcUa_Null;

    OpcUa_DeclareErrorTraceModule(OpcUa_Module_List);

    OpcUa_GotoErrorIfArgumentNull(a_pList);
    OpcUa_GotoErrorIfArgumentNull(a_pList->currtElement);
    OpcUa_GotoErrorIfArgumentNull(a_ppQueueFirst);
    OpcUa_GotoErrorIfArgumentNull(a_ppQueueLast);

    deleteElement = a_pList->currtElement;

    if(deleteElement->prevElement)
    {
        deleteElement->prevElement->nextElement = deleteElement->nextElement;
    }

    if(deleteElement->nextElement)
    {
        deleteElement->nextElement->prevElement = deleteElement->prevElement;
    }

    a_pList->currtElement = deleteElement->nextElement;

    if(deleteElement == a_pList->firstElement)
    {
        a_pList->firstElement = deleteElement->nextElement;
    }

    if(deleteElement == a_pList->lastElement)
    {
        a_pList->lastElement = deleteElement->prevElement;
    }

    a_pList->uintNbElements--;

    deleteElement->prevElement = *a_ppQueueLast;
    deleteElement->nextElement = OpcUa_Null;

    if(*a_ppQueueFirst == OpcUa_Null)
    {
        *a_ppQueueFirst = deleteElement;
    }
    else
    {
        (*a_ppQueueLast)->nextElement = deleteElement;
    }

    *a_ppQueueLast = deleteElement;

Error:
    return;
}
/*============================================================================
 * Select usable socket. (maxfds ignored in win32)
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_RawSocket_Select(  OpcUa_RawSocket         a_MaxFds,
                                            OpcUa_P_Socket_Array*   a_pFdSetRead,
                                            OpcUa_P_Socket_Array*   a_pFdSetWrite,
                                            OpcUa_P_Socket_Array*   a_pFdSetException,
                                            OpcUa_TimeVal*          a_pTimeout)
{
    int                 apiResult  = 0;
    struct timeval      timeout;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "P_Select");

    OpcUa_ReferenceParameter(a_MaxFds);

    OpcUa_GotoErrorIfArgumentNull(a_pFdSetRead);
    OpcUa_GotoErrorIfArgumentNull(a_pFdSetWrite);
    OpcUa_GotoErrorIfArgumentNull(a_pFdSetException);

    timeout.tv_sec  = a_pTimeout->uintSeconds;
    timeout.tv_usec = a_pTimeout->uintMicroSeconds;

    apiResult = select( 0,
                        (fd_set*)a_pFdSetRead,
                        (fd_set*)a_pFdSetWrite,
                        (fd_set*)a_pFdSetException,
                        &timeout);

    if(apiResult == OPCUA_P_SOCKET_SOCKETERROR)
    {
        apiResult = WSAGetLastError();

        switch(apiResult)
        {
        case WSAENOTSOCK:
            {
                uStatus = OpcUa_BadInvalidArgument;
                break;
            }
        default:
            {
                uStatus = OpcUa_BadCommunicationError;
            }
        }
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
Exemple #4
0
/**
  @brief Moves the cursor to the previous element if existing and returns the userdata.

  @return OpcUa_Null if the cursor was pointing to the first element
  @return OpcUa_Null if a_pList is null
  @return OpcUa_Null if a_pList->currtElement is null
  @return the data from the previous element otherwise

  @param a_pList    [in]    Location of the list
*/
OpcUa_Void* OpcUa_List_GetPrevElement(OpcUa_List* a_pList)
{
    OpcUa_StatusCode uStatus = OpcUa_Good;
    OpcUa_DeclareErrorTraceModule(OpcUa_Module_List);
    OpcUa_GotoErrorIfArgumentNull(a_pList);
    OpcUa_GotoErrorIfArgumentNull(a_pList->currtElement);

    if(a_pList->currtElement->prevElement)
    {
        a_pList->currtElement = a_pList->currtElement->prevElement;
        return a_pList->currtElement->data;
    }

Error:
    return OpcUa_Null;
}
/*============================================================================
 * Get IP Address and Port Number of the Peer
 *===========================================================================*/
static OpcUa_StatusCode OpcUa_P_SocketService_UdpGetPeerInfo(  OpcUa_Socket  a_pSocket,
                                                               OpcUa_CharA*  a_achPeerInfoBuffer,
                                                               OpcUa_UInt32  a_uiPeerInfoBufferSize)
{
OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpGetPeerInfo");

    OpcUa_GotoErrorIfArgumentNull(a_pSocket);
    OpcUa_GotoErrorIfArgumentNull(a_achPeerInfoBuffer);
    OpcUa_ReferenceParameter(a_uiPeerInfoBufferSize);

    OpcUa_GotoErrorWithStatus(OpcUa_BadNotImplemented);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/*============================================================================
 * Bind to Socket
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_RawSocket_Bind(    OpcUa_RawSocket a_RawSocket,
                                            OpcUa_Int16     a_nPort)
{
    OpcUa_Int32         intSize    = 0;
    SOCKET              winSocket  = (SOCKET)OPCUA_P_SOCKET_INVALID;
    struct sockaddr_in  srv;
    struct sockaddr     *pName;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "P_Bind");

    OpcUa_GotoErrorIfArgumentNull(a_RawSocket);
    winSocket = (SOCKET)a_RawSocket;

    intSize = sizeof(struct sockaddr_in);
    OpcUa_MemSet(&srv, 0, intSize);

    srv.sin_addr.s_addr = INADDR_ANY;
    srv.sin_port        = htons(a_nPort);
    srv.sin_family      = AF_INET;
    pName               = (struct sockaddr*)&srv;

    if(bind(winSocket, pName, intSize) == OPCUA_P_SOCKET_SOCKETERROR)
    {
        uStatus = OpcUa_BadCommunicationError;
        goto Error;
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
Exemple #7
0
/**
  @brief Removes the element containing the specified user data from the list.
  The data itself is not deleted.

  @return OpcUa_BadInternalError if a_pList is null
  @return OpcUa_BadInternalError if a_pElementData is null
  @return OpcUa_Good on success;

  @param a_pList            [in]    Location of the list
  @param a_pElementData     [in]    Location of the data to remove from the list
*/
OpcUa_StatusCode OpcUa_List_DeleteElement(OpcUa_List* a_pList, OpcUa_Void* a_pElementData)
{
    OpcUa_StatusCode    uStatus             = OpcUa_BadNotFound; /* initialise with error */

    OpcUa_ListElement*  safeCurrentElement  = OpcUa_Null;
    OpcUa_Void*         currentElementData  = OpcUa_Null;

    OpcUa_DeclareErrorTraceModule(OpcUa_Module_List);

    OpcUa_GotoErrorIfArgumentNull(a_pList);
    OpcUa_GotoErrorIfArgumentNull(a_pElementData);

    /* current element is target */
    if((a_pList->currtElement != OpcUa_Null) && (a_pElementData == a_pList->currtElement->data))
    {
        OpcUa_List_DeleteCurrentElement(a_pList);
        return OpcUa_Good;
    }

    /* target may be elsewhere in the list */
    safeCurrentElement = a_pList->currtElement;

    /* begin search from start of list */
    OpcUa_List_ResetCurrent(a_pList);

    currentElementData = OpcUa_List_GetCurrentElement(a_pList);

    while(currentElementData != OpcUa_Null)
    {
        if(currentElementData == a_pElementData)
        {
            OpcUa_List_DeleteCurrentElement(a_pList);
            uStatus = OpcUa_Good;
            break;
        }
        else
        {
            currentElementData = OpcUa_List_GetNextElement(a_pList);
        }
    }

    /* restore prior cursor */
    a_pList->currtElement = safeCurrentElement;

Error:
    return uStatus;
}
/*============================================================================
 * Create a UDP sender socket
 *===========================================================================*/
OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_SocketUdp_CreateSender(  OpcUa_StringA    a_LocalIpAddress,
                                                                OpcUa_StringA    a_RemoteIpAddress,
                                                                OpcUa_Int16      a_RemotePort,
                                                                OpcUa_Byte       a_TimeToLive,
                                                                OpcUa_Socket*    a_pSocket)
{
    OpcUa_InternalUdpSocket* pInternalSocket = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "CreateUdpSender");

    OpcUa_ReturnErrorIfArgumentNull(a_pSocket);

    *a_pSocket = OpcUa_Null;

    OpcUa_GotoErrorIfArgumentNull(a_RemoteIpAddress);

    if(a_RemotePort == 0)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument);
    }

    pInternalSocket = (OpcUa_InternalUdpSocket*)OpcUa_P_Memory_Alloc(sizeof(OpcUa_InternalUdpSocket));
    OpcUa_GotoErrorIfAllocFailed(pInternalSocket);

    pInternalSocket->pSocketServiceTable      = &OpcUa_UdpSocketServiceTable;

    if(strchr(a_RemoteIpAddress, ':'))
    {
        uStatus = OpcUa_P_RawSocket_CreateUdpV6(&pInternalSocket->rawSocket,
                                                OpcUa_True,
                                                a_LocalIpAddress,
                                                a_RemoteIpAddress,
                                                a_RemotePort,
                                                a_TimeToLive);
        OpcUa_GotoErrorIfBad(uStatus);
    }
    else
    {
        uStatus = OpcUa_P_RawSocket_CreateUdp(&pInternalSocket->rawSocket,
                                              OpcUa_True,
                                              a_LocalIpAddress,
                                              a_RemoteIpAddress,
                                              a_RemotePort,
                                              a_TimeToLive);
        OpcUa_GotoErrorIfBad(uStatus);
    }

    *a_pSocket = pInternalSocket;

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pInternalSocket != OpcUa_Null)
    {
        OpcUa_P_Memory_Free(pInternalSocket);
    }

OpcUa_FinishErrorHandling;
}
/*============================================================================
 * Connect Socket for Client.
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_RawSocket_Connect( OpcUa_RawSocket a_RawSocket,
                                            OpcUa_Int16     a_nPort,
                                            OpcUa_StringA   a_sHost)
{
    int                 intSize   = 0;
    SOCKET              winSocket = (SOCKET)OPCUA_P_SOCKET_INVALID;
    struct sockaddr     *pName;
    struct sockaddr_in  srv;
    char*               localhost = "127.0.0.1";

OpcUa_InitializeStatus(OpcUa_Module_Socket, "P_Connect");

    OpcUa_GotoErrorIfArgumentNull(a_RawSocket);
    winSocket = (SOCKET)a_RawSocket;

    intSize = sizeof(struct sockaddr_in);
    OpcUa_MemSet(&srv, 0, intSize);

    if(!strcmp("localhost", a_sHost))
    {
        a_sHost = localhost;
    }

    srv.sin_addr.s_addr = inet_addr(a_sHost);

    if(srv.sin_addr.s_addr == INADDR_NONE)
    {
        return OpcUa_BadInvalidArgument;
    }

    srv.sin_port   = htons(a_nPort);
    srv.sin_family = AF_INET;

    pName = (struct sockaddr *) &srv;

    if(connect(winSocket, pName, intSize) == OPCUA_P_SOCKET_SOCKETERROR)
    {
        int result = OpcUa_P_RawSocket_GetLastError((OpcUa_RawSocket)winSocket);

        /* a connect takes some time and this "error" is common with nonblocking sockets */
        if(result == WSAEWOULDBLOCK || result == WSAEINPROGRESS)
        {
            uStatus = OpcUa_BadWouldBlock;
        }
        else
        {
            uStatus = OpcUa_BadCommunicationError;
        }
        goto Error;
    }

    uStatus = OpcUa_Good;

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/*============================================================================
 * Create a new signal socket
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_SocketManager_NewSignalSocket(OpcUa_SocketManager a_pSocketManager)
{
    OpcUa_InternalSocket*           pIntSignalSocket = OpcUa_Null;
    OpcUa_InternalSocketManager*    pInternalSocketManager      = (OpcUa_InternalSocketManager*)a_pSocketManager;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "NewSignalSocket");

    OpcUa_GotoErrorIfArgumentNull(a_pSocketManager);

    pIntSignalSocket = (OpcUa_InternalSocket*)OpcUa_SocketManager_FindFreeSocket(a_pSocketManager, OpcUa_True);

    if(pIntSignalSocket == OpcUa_Null)
    {
        uStatus = OpcUa_BadResourceUnavailable;
        goto Error;
    }

    uStatus = OpcUa_P_RawSocket_CreateSocketPair( &pIntSignalSocket->rawSocket,
                                                  &pInternalSocketManager->pCookie);
    OpcUa_GotoErrorIfBad(uStatus);

    pIntSignalSocket->Flags.EventMask =   OPCUA_SOCKET_CLOSE_EVENT
                                        | OPCUA_SOCKET_READ_EVENT
                                        | OPCUA_SOCKET_EXCEPT_EVENT
                                        | OPCUA_SOCKET_TIMEOUT_EVENT;

    uStatus = OpcUa_P_RawSocket_SetBlockMode (pIntSignalSocket->rawSocket, OpcUa_False);
    if (OpcUa_IsBad(uStatus))
    {
        OpcUa_P_RawSocket_Close(pIntSignalSocket->rawSocket);
        OpcUa_P_RawSocket_Close(pInternalSocketManager->pCookie);
        OpcUa_GotoErrorWithStatus(uStatus);
    }

    uStatus = OpcUa_P_RawSocket_SetBlockMode (pInternalSocketManager->pCookie, OpcUa_False);
    if (OpcUa_IsBad(uStatus))
    {
        OpcUa_P_RawSocket_Close(pIntSignalSocket->rawSocket);
        OpcUa_P_RawSocket_Close(pInternalSocketManager->pCookie);
        OpcUa_GotoErrorWithStatus(uStatus);
    }

    OPCUA_SOCKET_SETVALID(pIntSignalSocket);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pIntSignalSocket)
    {
        pIntSignalSocket->rawSocket = (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID;
        OPCUA_SOCKET_INVALIDATE(pIntSignalSocket);
    }

OpcUa_FinishErrorHandling;
}
Exemple #11
0
/**
  @brief Remove the first element, return its data, and reset the cursor
  This function is used along with OpcUa_List_AddElementToEnd to make the list
  behave like a queue

  @return OpcUa_Null if a_pList is null
  @return OpcUa_Null if the list is empty
  @return the user data from the first element otherwise

  @param a_pList    [in]    Location of the list
*/
OpcUa_Void* OpcUa_List_RemoveFirstElement(OpcUa_List* a_pList)
{
    OpcUa_StatusCode    uStatus         = 0;
    OpcUa_Void*         returnElement   = OpcUa_Null;

    OpcUa_DeclareErrorTraceModule(OpcUa_Module_List);

    OpcUa_GotoErrorIfArgumentNull(a_pList);
    OpcUa_GotoErrorIfArgumentNull(a_pList->firstElement);

    returnElement = a_pList->firstElement->data;
    a_pList->firstElement->data = OpcUa_Null;

    OpcUa_List_ResetCurrent(a_pList);
    OpcUa_List_DeleteCurrentElement(a_pList);

    return returnElement;
Error:
    return OpcUa_Null;
}
Exemple #12
0
/**
  @brief Deletes the current element performing all necessary list management
  However, user data is not deleted and must be removed manually

  Takes no action if a_pList is null
  Takes no action if a_pList->currtElement is null

  @param a_pList    [in]    Location of the list
*/
OpcUa_Void OpcUa_List_DeleteCurrentElement(OpcUa_List* a_pList)
{
    OpcUa_StatusCode    uStatus         = OpcUa_Good;
    OpcUa_ListElement*  deleteElement   = OpcUa_Null;

    OpcUa_DeclareErrorTraceModule(OpcUa_Module_List);

    OpcUa_GotoErrorIfArgumentNull(a_pList);
    OpcUa_GotoErrorIfArgumentNull(a_pList->currtElement);

    deleteElement = a_pList->currtElement;

    if(deleteElement->prevElement)
    {
        deleteElement->prevElement->nextElement = deleteElement->nextElement;
    }

    if(deleteElement->nextElement)
    {
        deleteElement->nextElement->prevElement = deleteElement->prevElement;
    }

    a_pList->currtElement = deleteElement->nextElement;

    if(deleteElement == a_pList->firstElement)
    {
        a_pList->firstElement = deleteElement->nextElement;
    }

    if(deleteElement == a_pList->lastElement)
    {
        a_pList->lastElement = deleteElement->prevElement;
    }

    OpcUa_ListElement_Delete(&deleteElement);
    a_pList->uintNbElements--;

Error:
    return;
}
Exemple #13
0
/**
  @brief Adds a new element with the given data into the List. The element is inserted as
  the first element.

  @return OpcUa_Good on success
  @return OpcUa_BadOutOfMemory if the allocation of the new element fails
  @return OpcUa_BadInvalidArgument if a_pList is null
  @return OpcUa_BadInvalidArgument if a_pElementData is null

  @param a_pList            [in]    Location of list
  @param a_pElementData     [in]    Location of user data
*/
OpcUa_StatusCode OpcUa_List_AddElement(OpcUa_List* a_pList, OpcUa_Void* a_pElementData)
{
    OpcUa_StatusCode    uStatus     = OpcUa_Good;
    OpcUa_ListElement*  pNewElement = OpcUa_Null;

    OpcUa_DeclareErrorTraceModule(OpcUa_Module_List);

    OpcUa_GotoErrorIfArgumentNull(a_pList);
    OpcUa_GotoErrorIfArgumentNull(a_pElementData);

    uStatus = OpcUa_ListElement_Create(&pNewElement);
    OpcUa_ReturnErrorIfBad(uStatus);

    if(pNewElement == OpcUa_Null)
    {
        return OpcUa_BadOutOfMemory;
    }

    pNewElement->data = a_pElementData;

    if(a_pList->firstElement)
    {
        a_pList->firstElement->prevElement = pNewElement;
        pNewElement->nextElement = a_pList->firstElement;
    }

    a_pList->firstElement = pNewElement;

    if(a_pList->lastElement == OpcUa_Null)
    {
        a_pList->lastElement = pNewElement;
    }

    a_pList->uintNbElements++;

    return OpcUa_Good;

Error:
    return uStatus;
}
/*============================================================================
 * Read UDP Socket.
 *===========================================================================*/
static OpcUa_StatusCode OpcUa_P_SocketService_UdpRead( OpcUa_Socket    a_pSocket,
                                                       OpcUa_Byte*     a_pBuffer,
                                                       OpcUa_UInt32    a_nBufferSize,
                                                       OpcUa_UInt32*   a_pBytesRead)
{
    OpcUa_InternalUdpSocket*   pInternalSocket     = (OpcUa_InternalUdpSocket*)a_pSocket;
    OpcUa_Int32                api_result;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpRead");

    OpcUa_GotoErrorIfArgumentNull(a_pSocket);
    OpcUa_GotoErrorIfArgumentNull(a_pBuffer);
    OpcUa_GotoErrorIfArgumentNull(a_pBytesRead);

    *a_pBytesRead = 0;

    api_result = OpcUa_P_RawSocket_Read(pInternalSocket->rawSocket, a_pBuffer, a_nBufferSize);
    if(api_result >= 0)
    {
        *a_pBytesRead = (OpcUa_UInt32)api_result;
    }
    else
    {
        api_result = OpcUa_P_RawSocket_GetLastError(pInternalSocket->rawSocket);
        switch(api_result)
        {
            case WSAEWOULDBLOCK:
                uStatus = OpcUa_BadWouldBlock;
                break;
            default:
                uStatus = OpcUa_BadCommunicationError;
                break;
        }
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/*============================================================================
 * Set socket user data
 *===========================================================================*/
static OpcUa_StatusCode OpcUa_P_SocketService_UdpSetUserData(OpcUa_Socket a_pSocket,
                                                             OpcUa_Void*  a_pvUserData)
{
OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpSetUserData");

    OpcUa_GotoErrorIfArgumentNull(a_pSocket);
    OpcUa_ReferenceParameter(a_pvUserData);

    OpcUa_GotoErrorWithStatus(OpcUa_BadNotImplemented);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/**
* @brief Builds a connection record for the given parameters and returns it.
*
* @return: Status Code;
*/
OpcUa_StatusCode OpcUa_TcpListener_ConnectionManager_AddConnection(
    OpcUa_TcpListener_ConnectionManager*    a_pConnectionManager,
    OpcUa_TcpListener_Connection*           a_pConnection)
{
    OpcUa_StatusCode    uStatus = OpcUa_Good;

    OpcUa_GotoErrorIfArgumentNull(a_pConnection);
    OpcUa_GotoErrorIfArgumentNull(a_pConnectionManager);
    OpcUa_GotoErrorIfArgumentNull(a_pConnectionManager->Connections);

    a_pConnection->ConnectTime = OPCUA_P_DATETIME_UTCNOW(); /* expiration of connection would be DisconnectTime+Lifetime */

    OpcUa_List_Enter(a_pConnectionManager->Connections);
    OpcUa_List_AddElement(a_pConnectionManager->Connections, a_pConnection);
    OpcUa_Trace(OPCUA_TRACE_LEVEL_DEBUG, "OpcUa_TcpListener_ConnectionManager_AddConnection: Connection added!\n");
    OpcUa_List_Leave(a_pConnectionManager->Connections);


    return OpcUa_Good;

Error:
    return OpcUa_Bad;
}
/*============================================================================
 * Close UDP Socket.
 *===========================================================================*/
static OpcUa_StatusCode OpcUa_P_SocketService_UdpClose(OpcUa_Socket a_pSocket)
{
    OpcUa_InternalUdpSocket* pInternalSocket = (OpcUa_InternalUdpSocket*)a_pSocket;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpClose");

    OpcUa_GotoErrorIfArgumentNull(a_pSocket);

    OpcUa_P_RawSocket_Close(pInternalSocket->rawSocket);
    OpcUa_P_Memory_Free(pInternalSocket);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/*============================================================================
 * Get last socket error
 *===========================================================================*/
static OpcUa_StatusCode OpcUa_P_SocketService_UdpGetLastError(OpcUa_Socket a_pSocket)
{
    OpcUa_InternalUdpSocket* pInternalSocket = (OpcUa_InternalUdpSocket*)a_pSocket;
    int                      err;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpGetLastError");

    OpcUa_GotoErrorIfArgumentNull(a_pSocket);
    
    err = OpcUa_P_RawSocket_GetLastError(pInternalSocket->rawSocket);
    switch(err)
    {
        case WSAEWOULDBLOCK:
            uStatus = OpcUa_BadWouldBlock;
            break;
        default:
            uStatus = OpcUa_BadCommunicationError;
            break;
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/*============================================================================
 * OpcUa_ProxyStub_ReInitialize
 *===========================================================================*/
OpcUa_StatusCode OPCUA_DLLCALL OpcUa_ProxyStub_ReInitialize(OpcUa_ProxyStubConfiguration* a_pProxyStubConfiguration)
{
OpcUa_InitializeStatus(OpcUa_Module_ProxyStub, "ReInitialize");

#if OPCUA_USE_SYNCHRONISATION
        OPCUA_P_MUTEX_LOCK(OpcUa_ProxyStub_g_hGlobalsMutex);
#endif /* OPCUA_USE_SYNCHRONISATION */

    OpcUa_GotoErrorIfArgumentNull(a_pProxyStubConfiguration);

    if((OpcUa_ProxyStub_g_uNoOfChannels != 0) || (OpcUa_ProxyStub_g_uNoOfEndpoints != 0))
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidState);
    }

    /* set global configuration object */
    OpcUa_ProxyStub_g_Configuration = *a_pProxyStubConfiguration;

    /* check for negative values and fall back to default values in opcua_config.h */
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxAlloc == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxAlloc                     = OPCUA_SERIALIZER_MAXALLOC; /* currently unused */
    }
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxStringLength == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxStringLength              = OPCUA_ENCODER_MAXSTRINGLENGTH;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxByteStringLength == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxByteStringLength          = OPCUA_ENCODER_MAXBYTESTRINGLENGTH;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxArrayLength == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxArrayLength               = OPCUA_ENCODER_MAXARRAYLENGTH;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxMessageSize == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxMessageSize               = OPCUA_ENCODER_MAXMESSAGELENGTH;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MinThreads == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MinThreads    = OPCUA_SECURELISTENER_THREADPOOL_MINTHREADS;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxThreads == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxThreads    = OPCUA_SECURELISTENER_THREADPOOL_MAXTHREADS;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxJobs == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxJobs       = OPCUA_SECURELISTENER_THREADPOOL_MAXJOBS;
    }
    if(OpcUa_ProxyStub_g_Configuration.iTcpListener_DefaultChunkSize == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iTcpListener_DefaultChunkSize            = OPCUA_TCPLISTENER_DEFAULTCHUNKSIZE;
    }
    if(OpcUa_ProxyStub_g_Configuration.iTcpConnection_DefaultChunkSize == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iTcpConnection_DefaultChunkSize          = OPCUA_TCPCONNECTION_DEFAULTCHUNKSIZE;
    }
    if(OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxChunkCount == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxChunkCount              = 0;
    }
    if(OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxMessageLength == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxMessageLength           = OPCUA_ENCODER_MAXMESSAGELENGTH;
    }

#if OPCUA_USE_SYNCHRONISATION
        OPCUA_P_MUTEX_UNLOCK(OpcUa_ProxyStub_g_hGlobalsMutex);
#endif /* OPCUA_USE_SYNCHRONISATION */

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

#if OPCUA_USE_SYNCHRONISATION
    OPCUA_P_MUTEX_UNLOCK(OpcUa_ProxyStub_g_hGlobalsMutex);
#endif /* OPCUA_USE_SYNCHRONISATION */

OpcUa_FinishErrorHandling;
}
/*============================================================================
 * OpcUa_P_PKIFactory_CreatePKIProvider
 *===========================================================================*/
OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_PKIFactory_CreatePKIProvider(OpcUa_Void*         a_pCertificateStoreConfig,
                                                                    OpcUa_PKIProvider*  a_pPkiProvider)
{
    OpcUa_P_OpenSSL_CertificateStore_Config*    pCertificateStoreCfg    = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_P_PKIFactory, "CreatePKIProvider");

    OpcUa_ReturnErrorIfArgumentNull(a_pCertificateStoreConfig);
    OpcUa_ReturnErrorIfArgumentNull(a_pPkiProvider);

    pCertificateStoreCfg = (OpcUa_P_OpenSSL_CertificateStore_Config*)a_pCertificateStoreConfig;
    a_pPkiProvider->Handle = a_pCertificateStoreConfig;

    switch(pCertificateStoreCfg->PkiType)
    {
    case OpcUa_NO_PKI:
        {
            a_pPkiProvider->OpenCertificateStore    = OpcUa_P_OpenSSL_PKI_NoSecurity_OpenCertificateStore;
            a_pPkiProvider->CloseCertificateStore   = OpcUa_P_OpenSSL_PKI_NoSecurity_CloseCertificateStore;
            a_pPkiProvider->ValidateCertificate     = OpcUa_P_OpenSSL_PKI_NoSecurity_ValidateCertificate;
            a_pPkiProvider->LoadCertificate         = OpcUa_P_OpenSSL_PKI_NoSecurity_LoadCertificate;
            a_pPkiProvider->SaveCertificate         = OpcUa_P_OpenSSL_PKI_NoSecurity_SaveCertificate;
            a_pPkiProvider->LoadPrivateKeyFromFile  = OpcUa_P_OpenSSL_PKI_NoSecurity_LoadPrivateKeyFromFile;
            a_pPkiProvider->ExtractCertificateData  = OpcUa_P_OpenSSL_PKI_NoSecurity_ExtractCertificateData;
            break;
        }
#if OPCUA_SUPPORT_PKI
#if OPCUA_SUPPORT_PKI_OVERRIDE
    case OpcUa_Override:
        {
            /* check if replacement for default is set and use it instead of the default */
            OpcUa_PKIProvider* pOverride = (OpcUa_PKIProvider*)pCertificateStoreCfg->Override;

            OpcUa_GotoErrorIfArgumentNull(pOverride);

            if(pOverride->OpenCertificateStore == OpcUa_Null)
            {
                a_pPkiProvider->OpenCertificateStore = OpcUa_P_OpenSSL_PKI_OpenCertificateStore;
            }
            else
            {
                a_pPkiProvider->OpenCertificateStore = pOverride->OpenCertificateStore;
            }

            if(pOverride->CloseCertificateStore == OpcUa_Null)
            {
                a_pPkiProvider->CloseCertificateStore = OpcUa_P_OpenSSL_PKI_CloseCertificateStore;
            }
            else
            {
                a_pPkiProvider->CloseCertificateStore = pOverride->CloseCertificateStore;
            }

            if(pOverride->ValidateCertificate == OpcUa_Null)
            {
                a_pPkiProvider->ValidateCertificate = OpcUa_P_OpenSSL_PKI_ValidateCertificate;
            }
            else
            {
                a_pPkiProvider->ValidateCertificate = pOverride->ValidateCertificate;
            }

            if(pOverride->LoadCertificate == OpcUa_Null)
            {
                a_pPkiProvider->LoadCertificate = OpcUa_P_OpenSSL_PKI_LoadCertificate;
            }
            else
            {
                a_pPkiProvider->LoadCertificate = pOverride->LoadCertificate;
            }

            if(pOverride->SaveCertificate == OpcUa_Null)
            {
                a_pPkiProvider->SaveCertificate = OpcUa_P_OpenSSL_PKI_SaveCertificate;
            }
            else
            {
                a_pPkiProvider->SaveCertificate = pOverride->SaveCertificate;
            }

            if(pOverride->LoadPrivateKeyFromFile == OpcUa_Null)
            {
                a_pPkiProvider->LoadPrivateKeyFromFile = OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile;
            }
            else
            {
                a_pPkiProvider->LoadPrivateKeyFromFile = pOverride->LoadPrivateKeyFromFile;
            }

            if(pOverride->ExtractCertificateData == OpcUa_Null)
            {
                a_pPkiProvider->ExtractCertificateData = OpcUa_P_OpenSSL_PKI_ExtractCertificateData;
            }
            else
            {
                a_pPkiProvider->ExtractCertificateData = pOverride->ExtractCertificateData;
            }
            break;
        }
#endif /* OPCUA_SUPPORT_PKI_OVERRIDE */
#if OPCUA_SUPPORT_PKI_OPENSSL
    case OpcUa_OpenSSL_PKI:
        {
            a_pPkiProvider->OpenCertificateStore    = OpcUa_P_OpenSSL_PKI_OpenCertificateStore;
            a_pPkiProvider->CloseCertificateStore   = OpcUa_P_OpenSSL_PKI_CloseCertificateStore;
            a_pPkiProvider->ValidateCertificate     = OpcUa_P_OpenSSL_PKI_ValidateCertificate;
            a_pPkiProvider->LoadCertificate         = OpcUa_P_OpenSSL_PKI_LoadCertificate;
            a_pPkiProvider->SaveCertificate         = OpcUa_P_OpenSSL_PKI_SaveCertificate;
            a_pPkiProvider->LoadPrivateKeyFromFile  = OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile;
            a_pPkiProvider->ExtractCertificateData  = OpcUa_P_OpenSSL_PKI_ExtractCertificateData;
            break;
        }
#endif /* OPCUA_SUPPORT_PKI_OPENSSL */
#if OPCUA_SUPPORT_PKI_WIN32
    case OpcUa_Win32_PKI:
        {
            a_pPkiProvider->OpenCertificateStore    = OpcUa_P_Win32_PKI_OpenCertificateStore;
            a_pPkiProvider->CloseCertificateStore   = OpcUa_P_Win32_PKI_CloseCertificateStore;
            a_pPkiProvider->ValidateCertificate     = OpcUa_P_Win32_PKI_ValidateCertificate;
            a_pPkiProvider->LoadCertificate         = OpcUa_P_Win32_PKI_LoadCertificate;
            a_pPkiProvider->SaveCertificate         = OpcUa_P_Win32_PKI_SaveCertificate;
            a_pPkiProvider->LoadPrivateKeyFromFile  = OpcUa_P_Win32_LoadPrivateKeyFromKeyStore;
            a_pPkiProvider->ExtractCertificateData  = OpcUa_P_OpenSSL_PKI_ExtractCertificateData;
            break;
        }
#endif /* OPCUA_SUPPORT_PKI_WIN32 */
#endif /* OPCUA_SUPPORT_PKI */
    default:
        {
            uStatus = OpcUa_BadNotSupported;
        }
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/*============================================================================
 * Create Socket.
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_RawSocket_Create(  OpcUa_RawSocket*    a_pRawSocket,
                                            OpcUa_Boolean       a_bNagleOff,
                                            OpcUa_Boolean       a_bKeepAliveOn)
{
    OpcUa_StatusCode    uStatus     = OpcUa_Good;
    int                 iFlag       = 1;
    OpcUa_Int           apiResult   = 0;
    SOCKET              WinSocket   = (SOCKET)OPCUA_P_SOCKET_INVALID;

#if OPCUA_P_SOCKET_SETTCPRCVBUFFERSIZE || OPCUA_P_SOCKET_SETTCPSNDBUFFERSIZE
    OpcUa_Int           iBufferSize = OPCUA_P_TCPRCVBUFFERSIZE;
#endif /* OPCUA_P_SOCKET_SETTCPRCVBUFFERSIZE || OPCUA_P_SOCKET_SETTCPSNDBUFFERSIZE */

    OpcUa_GotoErrorIfArgumentNull(a_pRawSocket);

    /* create socket through platform API */
    WinSocket = socket(AF_INET, SOCK_STREAM, 0);
    apiResult = OpcUa_P_RawSocket_GetLastError((OpcUa_RawSocket)WinSocket);

    /* check if socket creation was successful */
    if(     WinSocket == OPCUA_P_SOCKET_INVALID
        ||  apiResult != 0)
    {
        uStatus = OpcUa_BadCommunicationError;
        goto Error;
    }

    /* set socketoptions */
    if(a_bNagleOff)
    {
        if(OPCUA_P_SOCKET_SOCKETERROR == setsockopt(WinSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&iFlag, sizeof(int)))
        {
            uStatus = OpcUa_BadCommunicationError;
            goto Error;
        }
    }
    if(a_bKeepAliveOn)
    {
        /* set socket options */
        if(OPCUA_P_SOCKET_SOCKETERROR == setsockopt(WinSocket, IPPROTO_TCP,  SO_KEEPALIVE, (const char*)&iFlag, sizeof(int)))
        {
            uStatus = OpcUa_BadCommunicationError;
            goto Error;
        }
    }

#if 0
    if(OPCUA_P_SOCKET_SOCKETERROR == getsockopt(WinSocket, SOL_SOCKET,  SO_RCVBUF, (char*)&iBufferSize, &temp))
    {
        int result = OpcUa_P_RawSocket_GetLastError((OpcUa_RawSocket)WinSocket);
        uStatus = OpcUa_BadCommunicationError;
        goto Error;
    }
#endif

#if OPCUA_P_SOCKET_SETTCPRCVBUFFERSIZE
    iBufferSize = OPCUA_P_TCPRCVBUFFERSIZE;
    if(OPCUA_P_SOCKET_SOCKETERROR == setsockopt(WinSocket, SOL_SOCKET,  SO_RCVBUF, (const char*)&iBufferSize, sizeof(int)))
    {
        /*int result = OpcUa_P_RawSocket_GetLastError((OpcUa_RawSocket)WinSocket);*/
        uStatus = OpcUa_BadCommunicationError;
        goto Error;
    }
#endif /* OPCUA_P_SOCKET_SETTCPRCVBUFFERSIZE */

#if OPCUA_P_SOCKET_SETTCPSNDBUFFERSIZE
    iBufferSize = OPCUA_P_TCPSNDBUFFERSIZE;
    if(OPCUA_P_SOCKET_SOCKETERROR == setsockopt(WinSocket, SOL_SOCKET,  SO_SNDBUF, (const char*)&iBufferSize, sizeof(int)))
    {
        /*int result = OpcUa_P_RawSocket_GetLastError((OpcUa_RawSocket)WinSocket);*/
        uStatus = OpcUa_BadCommunicationError;
        goto Error;
    }
#endif /* OPCUA_P_SOCKET_SETTCPSNDBUFFERSIZE */

    *a_pRawSocket = (OpcUa_RawSocket)WinSocket;

    return OpcUa_Good;

Error:

    if(WinSocket != OPCUA_P_SOCKET_INVALID)
    {
        OpcUa_P_RawSocket_Close((OpcUa_RawSocket)WinSocket);
        *a_pRawSocket = (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID;
    }

    return uStatus;
}