mmiBlkLangDB.c: non-ASCII char fixes
literal non-ASCII characters in strings replaced with C octal escapes
line source
+ − /*
+ − +------------------------------------------------------------------------------
+ − | File: socket.c
+ − +------------------------------------------------------------------------------
+ − | Copyright 2002 Texas Instruments Berlin, AG
+ − | All rights reserved.
+ − |
+ − | This file is confidential and a trade secret of Texas
+ − | Instruments Berlin, AG
+ − | The receipt of or possession of this file does not convey
+ − | any rights to reproduce or disclose its contents or to
+ − | manufacture, use, or sell anything it may describe, in
+ − | whole, or in part, without the specific written consent of
+ − | Texas Instruments Berlin, AG.
+ − +-----------------------------------------------------------------------------
+ − | Purpose : This Modul contains the socket driver adaptation
+ − +-----------------------------------------------------------------------------
+ − */
+ −
+ − #ifdef _VXWORKS_
+ − #define GNU_COMPILER
+ − #endif
+ −
+ − #undef SOCK_TRACE
+ −
+ − #undef SOCKET_DEBUG
+ −
+ − /*==== INCLUDES =============================================================*/
+ −
+ − #if defined _NUCLEUS_ || defined _TOOLS_ /* socket-driver running on windows OS */
+ − /*lint -e717 suppress info do...while(0); */
+ − /*lint -esym(550,rc) suppress info not accessed */
+ − /*lint -e813, suppress Info 813: auto variable has size > 100 -> uncritical in this context */
+ − /*lint -e801, suppress Info 801: Use of goto is deprecated */
+ − #include <windows.h>
+ − #include <winsock.h>
+ − #include <stdio.h>
+ − #ifdef SOCK_TRACE
+ − #include <stdio.h>
+ − #include <fcntl.h>
+ − #include <io.h>
+ − #endif /* SOCK_TRACE */
+ − #endif /* #ifdef _NUCLEUS_ */
+ −
+ − #ifdef _PSOS_ /* socket-driver running on pSOS */
+ − #define _PNA_30_BACK
+ − #include <psos.h>
+ − #include "bsp.h"
+ − #include <pna.h>
+ − #include <prepc.h>
+ − #include <rescfg.h>
+ − #endif /* #ifdef _PSOS_ */
+ −
+ − #ifdef _VXWORKS_
+ − #include "vxWorks.h"
+ − #include "sockLib.h"
+ − #include "inetLib.h"
+ − #include "ioLib.h"
+ − #include "selectLib.h"
+ − #include "errnoLib.h"
+ − #include "logLib.h"
+ − /* undefine the MALLOC and FREE of VxWorks to avoid warnings */
+ − #undef MALLOC
+ − #undef FREE
+ − #endif /* _VXWORKS_ */
+ −
+ − /* More operating systems go here */
+ −
+ − #ifdef _LINUX_
+ − #include <sys/types.h>
+ − #include <sys/socket.h>
+ − #include <netinet/in.h>
+ − #include <netinet/tcp.h>
+ − #include <sys/ioctl.h>
+ − #include <errno.h>
+ − #include <netdb.h>
+ − #endif
+ −
+ − #ifdef _SOLARIS_
+ − #include <sys/types.h>
+ − #include <sys/socket.h>
+ − #include <netinet/in.h>
+ − #include <netinet/tcp.h>
+ − #include <sys/ioctl.h>
+ − #include <errno.h>
+ − #include <netdb.h>
+ − #include <sys/filio.h>
+ − #endif
+ −
+ − #ifndef OLD_FRAME
+ − #include "typedefs.h"
+ − #include "os.h"
+ − #endif
+ −
+ − #include "socket.h"
+ − #include "tools.h"
+ − #include "vsi.h"
+ − #include "drvconf.h"
+ − #include "tstheader.h"
+ −
+ − /*==== DEFINITIONS ==========================================================*/
+ −
+ − #define MAX_PENDING_CONNECTS 5 /* The backlog allowed for listen() */
+ − #define SEND_TIMEOUTUSEC 500 /* minimal timeout value for sending*/
+ − #define INVALID_HANDLE NULL
+ − #define INVALID_SIGNALTYPE 0
+ − #define NO_FLAGS_SET 0 /* Used with recv()/send() */
+ − #define MAX_ETH_LEN (1500-40) /* Maximum size of a Ethernet packet without IP headers */
+ − #define WRBUF_LEN 2048
+ −
+ − #define ALLOWED_SOCKET_SIGNALS (DRV_SIGTYPE_READ|DRV_SIGTYPE_CONNECT|DRV_SIGTYPE_DISCONNECT)
+ −
+ − #if defined _NUCLEUS_ || defined _TOOLS_
+ − typedef ULONG SIZETYPE;
+ − #define GETTIME(t) (t = GetTickCount())
+ − #define GETREADSIZE(sok,psiz) ioctlsocket(sok, FIONREAD,(ULONG*)psiz)
+ − #define READ_SOCKET(s,b,l) recv((s),(b),(int)(l),NO_FLAGS_SET)
+ − #define WRITE_SOCKET(s,b,l) send((s),(const char*)(b),(l),NO_FLAGS_SET)
+ − #define CLOSE_SOCKET(s) closesocket(s)
+ − #endif /* #ifdef _NUCLEUS_ */
+ −
+ − #ifdef _PSOS_
+ − typedef int SOCKET;
+ − typedef int SIZETYPE;
+ − typedef struct hostent HOSTENT;
+ − #define h_addr h_addr_list[0]
+ − typedef HOSTENT * PHOSTENT;
+ − #define FAR /**/
+ − #define SOCKADDR_IN struct sockaddr_in
+ − #define SOCKET_ERROR (-1)
+ − #define INVALID_SOCKET (-1)
+ − #define GETTIME(t) os_GetTime (0, &(t))
+ − #define GETREADSIZE(sok,psiz) ioctl(sok, FIOREAD,(char*)psiz)
+ − #define READ_SOCKET(s,b,l) recv((s),(b),(int)(l),NO_FLAGS_SET)
+ − #define WRITE_SOCKET(s,b,l) send((s),(char *)(b),(int)(l),NO_FLAGS_SET)
+ − #define CLOSE_SOCKET(s) close(s)
+ − #endif /* #ifdef _PSOS_ */
+ −
+ − #ifdef _VXWORKS_
+ − #define SOCKADDR_IN struct sockaddr_in
+ − #define FAR /* nil */
+ − #define SOCKET_ERROR ERROR
+ − #define INVALID_SOCKET ERROR
+ − typedef int SOCKET;
+ − typedef int SIZETYPE;
+ − #define GETTIME(t) os_GetTime (0, &(t))
+ − #define GETREADSIZE(sok,psiz) ioctl(sok, FIONREAD, (int)psiz)
+ − #define READ_SOCKET(s,b,l) recv((s), (b), (int)(l), NO_FLAGS_SET)
+ − #define WRITE_SOCKET(s,b,l) send((s), (char *)(b), (int)(l), NO_FLAGS_SET)
+ − #define CLOSE_SOCKET(s) close(s)
+ − #endif /* _VXWORKS_ */
+ −
+ − #if defined (_LINUX_) || defined (_SOLARIS_)
+ − #define SOCKADDR_IN struct sockaddr_in
+ − #define FAR /* nil */
+ − #define SOCKET_ERROR (-1)
+ − #define INVALID_SOCKET (-1)
+ − typedef int SIZETYPE;
+ − #define GETTIME(t) os_GetTime (0, &(t))
+ − #define GETREADSIZE(sok,psiz) ioctl(sok, FIONREAD, (int)psiz)
+ − #define READ_SOCKET(s,b,l) recv((s), (b), (int)(l), NO_FLAGS_SET)
+ − #define WRITE_SOCKET(s,b,l) send((s), (char *)(b), (int)(l), NO_FLAGS_SET)
+ − #define CLOSE_SOCKET(s) close(s)
+ − #endif /* _VXWORKS_ */
+ −
+ − #define PORT_NO 6392
+ − #define TX_BUFFER_SIZE 8192
+ − #define RX_BUFFER_SIZE 8192
+ − #define TX_TIMEOUT_MSEC 10000
+ − #define RX_TIMEOUT_MSEC 10000
+ −
+ − #ifdef _VXWORKS_
+ − #define SOCKET_PRIO 115
+ − #define SOCKET_STACK 8192
+ − #elif defined _PSOS_
+ − #define SOCKET_PRIO 110
+ − #define SOCKET_STACK 1024
+ − #elif defined _TOOLS_
+ − #define SOCKET_PRIO 1
+ − #define SOCKET_STACK 1024
+ − #else
+ − #define SOCKET_PRIO 1
+ − #define SOCKET_STACK 1024
+ − #endif
+ −
+ − #define TI_MODE 0x0001
+ −
+ − /*==== TYPES ================================================================*/
+ − typedef enum
+ − {
+ − SST_PL0, /* 0 bytes of packet length read*/
+ − SST_PL1, /* 1 bytes of packet length read*/
+ − SST_DATA0, /* 0 bytes of data read*/
+ − SST_DATAx /* not all data read */
+ − } T_SOCK_STATE;
+ −
+ − typedef struct
+ − {
+ − USHORT Connect;
+ − SOCKET Listener;
+ − SOCKET Socket;
+ − USHORT EnabledSignals;
+ − OS_HANDLE ThreadID ;
+ − USHORT SocketHandle;
+ − T_DRV_CB_FUNC Callback;
+ − } Client_Type;
+ −
+ − /*==== EXTERNALS ============================================================*/
+ − EXTERN BOOL socket_flush;
+ −
+ − /*==== LOCAL VARS ===========================================================*/
+ −
+ − LOCAL socket_DCB_Type L_DCB ;
+ − LOCAL Client_Type L_ClientData ;
+ − LOCAL BOOL L_ThreadActive ;
+ − LOCAL T_DRV_SIGNAL SocketSignal;
+ − LOCAL UBYTE wrbuf[WRBUF_LEN+2];
+ − LOCAL UBYTE *wrbuf_pos = wrbuf;
+ − T_SOCK_STATE sock_state = SST_PL0;
+ −
+ − #ifdef SOCK_TRACE
+ − ULONG fh_sock = -1;
+ − LOCAL char stbuf[80];
+ − #endif
+ −
+ − LOCAL BOOL isLittleEndian = TRUE;
+ − int tst_socket; /* for psos */
+ − int tst_socket_initialized; /* flag for pSOS */
+ − int tst_socket_in_TxLen; /* for pSOS */
+ −
+ −
+ − /*==== DIAGNOSTICS ==========================================================*/
+ −
+ − #ifdef SOCKET_DEBUG
+ − #include <STDIO.H>
+ − static char *logfile = "socket.log";
+ − static char *bufferfullfile = "bufferfull.log";
+ − static char *inprocessfile = "inprogress.log";
+ − static char *noconnectfile1 = "noconnect1.log";
+ − static char *noconnectfile2 = "noconnect2.log";
+ − static char *noconnectfile3 = "noconnect3.log";
+ − static char *readerrorfile = "readerror.log";
+ − static FILE *fp = NULL;
+ − #endif /* SOCKET_DEBUG */
+ −
+ − /*==== END DIAGNOSTICS ======================================================*/
+ −
+ − extern USHORT ext_data_pool_handle;
+ −
+ − GLOBAL ULONG drv_socket_task_stack_size = SOCKET_STACK;
+ − GLOBAL USHORT drv_socket_task_prio = SOCKET_PRIO;
+ −
+ − /*==== PRIVATE FUNCTIONS ====================================================*/
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : L_CreateThread
+ − +------------------------------------------------------------------------------
+ − | Description : This function creates a thread.
+ − |
+ − | Parameters : ThreadFunc - pointer to the function beeing a thread
+ − |
+ − | Return : FALSE - Thread not created
+ − | TRUE - Thread create (Thread ID stored in
+ − | L_ClientData.ThreadID
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − #ifdef OLD_FRAME
+ − BOOL L_CreateThread (USHORT (*ThreadFunc)(USHORT,ULONG))
+ − {
+ − return (CreateThread ((LPSECURITY_ATTRIBUTES) NULL,
+ − 0,
+ − (LPTHREAD_START_ROUTINE)ThreadFunc,
+ − (LPVOID) NULL,
+ − 0,
+ − &L_ClientData.ThreadID) != NULL);
+ − }
+ − #else
+ − BOOL L_CreateThread (void (*ThreadFunc)(T_HANDLE,ULONG))
+ − {
+ − if ( os_CreateTask (0, (char*)"SOCKET", ThreadFunc, drv_socket_task_stack_size, drv_socket_task_prio, &L_ClientData.ThreadID, ext_data_pool_handle) < 0L )
+ − return FALSE;
+ − if ( os_StartTask (0, L_ClientData.ThreadID, 0) < 0 )
+ − return FALSE ;
+ −
+ − return TRUE;
+ − }
+ − #endif
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : L_SetSocketBuffer
+ − +------------------------------------------------------------------------------
+ − | Description : This function sets the IP read and write buffer
+ − |
+ − | Parameters : in_TxLen - size of transmission buffer
+ − | in_RxLen - size of receiver buffer
+ − |
+ − | Return : FALSE - either the read or write buffer could not
+ − | be set.
+ − | TRUE - OK
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL BOOL L_SetSocketBuffer (USHORT in_TxLen, USHORT in_RxLen)
+ − {
+ − int in_TxLen1 = (int) in_TxLen;
+ − int in_RxLen1 = (int) in_RxLen;
+ − #ifndef _PSOS_
+ − int nodelay = TRUE;
+ − #if defined (_VXWORKS_) || defined (_LINUX_) || defined (_SOLARIS_)
+ − struct linger nolinger = {0, 0};
+ − #else
+ − int linger = TRUE;
+ − #endif
+ − int rc=0;
+ −
+ − if (in_TxLen > 0)
+ − {
+ − if ( (rc=setsockopt(L_ClientData.Socket, SOL_SOCKET, SO_SNDBUF,
+ − (char*)&in_TxLen1, sizeof(in_TxLen1))) != 0)
+ − {
+ − #ifdef _VXWORKS_
+ − rc = errnoGet ();
+ − #else
+ − #if defined (_LINUX_) || defined (_SOLARIS_)
+ − rc = errno;
+ − #else
+ − rc = WSAGetLastError();
+ − #endif
+ − #endif
+ − #if defined _NUCLEUS_ || defined _TOOLS_
+ − printf("SOCKET: setsockopt() returned error code %d\n", rc);
+ − #endif
+ − return FALSE ;
+ − }
+ − }
+ − #if defined (_VXWORKS_) || defined (_LINUX_) || defined (_SOLARIS_)
+ − if (setsockopt(L_ClientData.Socket, SOL_SOCKET, SO_LINGER,
+ − (char*)&nolinger, sizeof(nolinger)))
+ − #else
+ − if (setsockopt(L_ClientData.Socket, SOL_SOCKET, (int)SO_DONTLINGER,
+ − (char*)&linger, sizeof(linger)))
+ − #endif
+ − return FALSE ;
+ − if (setsockopt(L_ClientData.Socket, IPPROTO_TCP, TCP_NODELAY,
+ − (char*)&nodelay, sizeof(nodelay)))
+ − return FALSE ;
+ −
+ − #else /* PSOS */
+ − tst_socket_in_TxLen = in_TxLen;
+ − #endif /* PSOS */
+ − if (in_RxLen > 0)
+ − {
+ − if (setsockopt(L_ClientData.Socket, SOL_SOCKET, SO_RCVBUF,
+ − (char *) &in_RxLen1, sizeof(in_RxLen1)))
+ − return FALSE ;
+ − }
+ −
+ − return TRUE ;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : L_Disconnect
+ − +------------------------------------------------------------------------------
+ − | Description : This function is called when the connection to the peer entity
+ − | is lost. If the release signal is set a signal is generated.
+ − |
+ − | Parameters : -
+ − |
+ − | Return : -
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL void L_Disconnect (void)
+ − {
+ −
+ − L_ClientData.Connect = FALSE;
+ − if (L_ClientData.EnabledSignals != INVALID_SIGNALTYPE)
+ − {
+ − SocketSignal.SignalType = DRV_SIGTYPE_DISCONNECT;
+ − SocketSignal.DrvHandle = L_ClientData.SocketHandle;
+ − (*L_ClientData.Callback)(&SocketSignal) ;
+ − }
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : L_AsyncSelect
+ − +------------------------------------------------------------------------------
+ − | Description : This function waits (blocking) for either something to read
+ − | or an execption on the socket.
+ − |
+ − | Parameters : -
+ − |
+ − | Return : FALSE - failure on the socket
+ − | TRUE - a read event was signalled
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL BOOL L_AsyncSelect (void)
+ − {
+ − fd_set fd_r ;
+ − fd_set fd_e ;
+ − int status, rc;
+ −
+ − /* wait for possibility to read */
+ − FD_ZERO(&fd_r);
+ − FD_SET(L_ClientData.Socket, &fd_r);
+ − FD_ZERO(&fd_e);
+ − FD_SET(L_ClientData.Socket, &fd_e);
+ −
+ − status = select(FD_SETSIZE, &fd_r, NULL, &fd_e, (struct timeval *) 0);
+ −
+ − if (status > 0)
+ − {
+ − if (!FD_ISSET (L_ClientData.Socket, &fd_e))
+ − {
+ − if (L_ClientData.Callback != NULL)
+ − {
+ − if (FD_ISSET (L_ClientData.Socket, &fd_r))
+ − {
+ − SIZETYPE size ;
+ −
+ − if ((rc = GETREADSIZE( L_ClientData.Socket, &size)) != 0 || !size)
+ − {
+ − #ifdef SOCK_TRACE
+ − if (fh_sock != -1)
+ − {
+ − char sstop[10];
+ − ULONG stop = GetTickCount();
+ −
+ − sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000);
+ − sprintf(stbuf, "reset at %s rc=%d size=%d left %d \n",
+ − sstop, rc, size,
+ − wrbuf_pos-wrbuf);
+ − write (fh_sock, stbuf, strlen(stbuf));
+ − /* close(fh_sock);
+ − fh_sock = -1; */
+ − }
+ − #endif
+ − os_SuspendTask ( 0, 2 );
+ − CLOSE_SOCKET (L_ClientData.Socket);
+ − L_ClientData.Socket = INVALID_SOCKET;
+ − wrbuf_pos = wrbuf;
+ − sock_state = SST_PL0;
+ − return FALSE ;
+ − }
+ −
+ − /* Indicate that it is possible to read something */
+ − if (L_ClientData.EnabledSignals & DRV_SIGTYPE_READ)
+ − {
+ − SocketSignal.SignalType = DRV_SIGTYPE_READ;
+ − SocketSignal.DrvHandle = L_ClientData.SocketHandle;
+ − (*L_ClientData.Callback)(&SocketSignal) ;
+ − }
+ − }
+ − }
+ − return TRUE ;
+ − }
+ − }
+ − return FALSE;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : L_ClientThread
+ − +------------------------------------------------------------------------------
+ − | Description : This function is a thread used if the driver is configured to
+ − | be a client.
+ − |
+ − | Parameters : -
+ − |
+ − | Return : -
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − void L_ClientThread (T_HANDLE Handle, ULONG Value )
+ − {
+ − L_ThreadActive = TRUE ;
+ −
+ − L_SetSocketBuffer (L_DCB.tx_buffer_size, L_DCB.rx_buffer_size) ;
+ −
+ − /*-------------------------------------
+ − Listen what's goning on on the socket
+ − -------------------------------------*/
+ − while (L_ThreadActive)
+ − if (!L_AsyncSelect())
+ − {
+ − L_ThreadActive = FALSE ;
+ − L_Disconnect() ;
+ − }
+ − }
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : L_ServerThread
+ − +------------------------------------------------------------------------------
+ − | Description : This function is a thread used if the driver is configured to
+ − | be a server. It serves only one client. It cycles between
+ − | two modes, wait for a client to connect and listening on the
+ − | connection for any further action.
+ − | The thread exits when the flag L_ThreadActive is set to false.
+ − |
+ − | Parameters : -
+ − |
+ − | Return : -
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − void L_ServerThread (T_HANDLE TaskHandle, ULONG Value)
+ − {
+ − BOOL BufferSizeSet;
+ − SOCKADDR_IN local_sin; /* Local socket - internet style */
+ − #ifdef _VXWORKS_
+ − SOCKADDR_IN clientAddr; /* client */
+ − int sockAddrSize = sizeof (struct sockaddr_in);
+ −
+ − memset ((char *) &local_sin, 0, sockAddrSize);
+ − local_sin.sin_len = (u_char) sockAddrSize;
+ − #endif/* _VXWORKS_ */
+ − L_ClientData.Listener = socket (AF_INET, SOCK_STREAM, 0);
+ − if (L_ClientData.Listener == INVALID_SOCKET)
+ − goto error;
+ −
+ − if (L_DCB.port == SOCKET_INVALID_PORT)
+ − goto error;
+ −
+ − local_sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ − local_sin.sin_family = AF_INET;
+ − local_sin.sin_port = htons(L_DCB.port); /* Convert to network ordering */
+ −
+ − /*-------------------------------------------
+ − Associate an address with a socket. (bind)
+ − -------------------------------------------*/
+ − #ifdef _PSOS_
+ − if (bind (L_ClientData.Listener, (struct sockaddr_in*) &local_sin, sizeof(local_sin)) != 0)
+ − #else
+ − #ifdef _VXWORKS_
+ − /* Look at the following cast of local_sin.
+ − * This is from VxWorks Network 5.4 Programmer’s Guide, example 7-1, page 131
+ − */
+ − if (bind (L_ClientData.Listener, (struct sockaddr*) &local_sin, sockAddrSize) == ERROR)
+ − #else /* _VXWORKS_ */
+ − if (bind (L_ClientData.Listener, (const struct sockaddr FAR *) &local_sin, sizeof(local_sin)) != 0)
+ − #endif /* _VXWORKS_ */
+ − #endif
+ − {
+ − CLOSE_SOCKET (L_ClientData.Listener);
+ − goto error;
+ − }
+ − #ifdef _VXWORKS_
+ − if (listen (L_ClientData.Listener, MAX_PENDING_CONNECTS) == ERROR)
+ − #else /* _VXWORKS_ */
+ − if (listen (L_ClientData.Listener, MAX_PENDING_CONNECTS) != 0)
+ − #endif /* _VXWORKS_ */
+ − {
+ − CLOSE_SOCKET (L_ClientData.Listener);
+ − goto error;
+ − }
+ −
+ − BufferSizeSet = FALSE ;
+ − L_ThreadActive = TRUE ;
+ −
+ − while (L_ThreadActive)
+ − {
+ − /*-------------------------------------
+ − Wait for somebody to connect
+ − -------------------------------------*/
+ − if (L_ClientData.Socket != INVALID_SOCKET)
+ − {
+ − #ifdef SOCK_TRACE
+ − if (fh_sock != -1)
+ − {
+ − char sstop[10];
+ − ULONG stop = GetTickCount();
+ −
+ − sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000);
+ − sprintf(stbuf, "close at %s socket=%d\n",
+ − sstop, L_ClientData.Socket);
+ − write (fh_sock, stbuf, strlen(stbuf));
+ − /* close(fh_sock);
+ − fh_sock = -1; */
+ − }
+ − #endif
+ − CLOSE_SOCKET (L_ClientData.Socket);
+ − L_ClientData.Socket = INVALID_SOCKET;
+ − wrbuf_pos = wrbuf;
+ − sock_state = SST_PL0;
+ − }
+ − #ifdef _VXWORKS_
+ − if ((L_ClientData.Socket = accept (L_ClientData.Listener,
+ − (struct sockaddr *) &clientAddr,
+ − &sockAddrSize)) != ERROR)
+ − #else /* _VXWORKS_ */
+ − L_ClientData.Socket = accept(L_ClientData.Listener, NULL, NULL) ;
+ − if (L_ClientData.Socket != INVALID_SOCKET)
+ − #endif /* _VXWORKS_ */
+ − {
+ − #ifdef SOCK_TRACE
+ − if (fh_sock == -1)
+ − fh_sock = open("SOCK_S.dbg", O_WRONLY| O_TEXT| O_TRUNC| O_CREAT, 0666);
+ − if (fh_sock != -1)
+ − {
+ − char sstop[10];
+ − ULONG stop = GetTickCount();
+ −
+ − sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000);
+ − sprintf(stbuf, "accept at %s socket=%d listener=%d\n",
+ − sstop, L_ClientData.Socket, L_ClientData.Listener);
+ − write (fh_sock, stbuf, strlen(stbuf));
+ − }
+ − #endif
+ −
+ − #ifdef _PSOS_
+ − {
+ − ULONG tid;
+ − int err;
+ − /* for pSOS */
+ − /* wait for TST task */
+ − while( t_ident( FRM_TST_NAME, 0, &tid ) != 0 )
+ − tm_wkafter( 10 );
+ −
+ − tst_socket = shr_socket( L_ClientData.Socket, (int)tid );
+ − if( tst_socket < 0 )
+ − {
+ − err = errno;
+ − goto error;
+ − }
+ − }
+ − #endif
+ −
+ − if (!BufferSizeSet)
+ − L_SetSocketBuffer (L_DCB.tx_buffer_size, L_DCB.rx_buffer_size) ;
+ −
+ − /* Signalisiere Connect */
+ − L_ClientData.Connect = TRUE;
+ − if (L_ClientData.EnabledSignals & DRV_SIGTYPE_CONNECT)
+ − {
+ − SocketSignal.SignalType = DRV_SIGTYPE_CONNECT;
+ − SocketSignal.DrvHandle = L_ClientData.SocketHandle;
+ − (*L_ClientData.Callback)(&SocketSignal) ;
+ − }
+ −
+ − /*-------------------------------------
+ − Listen what's goning on on the socket
+ − -------------------------------------*/
+ − while (L_ThreadActive)
+ − if (!L_AsyncSelect())
+ − {
+ − L_Disconnect() ;
+ − break ;
+ − }
+ − }
+ − }
+ −
+ − error:
+ − #ifndef OLD_FRAME
+ − for(;;)
+ − os_SuspendTask( 0, 1000 );
+ − #endif
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_Create
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to set up the driver to act as a
+ − | server. The function tries to initialize the socket, creates
+ − | a thread in which it awaits first awaits the establishement
+ − | of a connection by a client. As soon as a client has
+ − | connected a signal (SOCKET_CONNECTED) is generated (call
+ − | socket_SetSignal() to activate a signal). From this time the
+ − | driver is able to send data (socket_write()) to the client and
+ − | to read received data (socket_read()). To get notified about
+ − | the reception of data the apropriate signal has to be set.
+ − | In the case of a successful completion the driver returns
+ − | DRV_OK.
+ − | If the driver is already busy DRV_INPROCESS is returned.
+ − | If the driver is not configured, the function returns
+ − | DRV_ NOTCONFIGURED.
+ − |
+ − | Parameters : -
+ − |
+ − | Return : DRV_OK - Function successful
+ − | DRV_INPROCESS - The driver is currently reading data.
+ − | The data is incomplete.
+ − | DRV_NOTCONFIGURED - The driver is not yet configured
+ − | SOCKET_ERRORUNSPEC - Error occured during initialization
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL UBYTE L_CreateServer (void)
+ − {
+ − if (!L_CreateThread (L_ServerThread))
+ − {
+ − CLOSE_SOCKET (L_ClientData.Listener);
+ − return SOCKET_ERRUNSPEC;
+ − }
+ − #ifdef _TOOLS_
+ − printf("SOCKET: now listening on port %i ...\n",L_DCB.port);
+ − #endif
+ −
+ − return DRV_OK ;
+ − }
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_WriteToOS
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to write data to the driver of operating
+ − | system.
+ − | The parameter thr_BufferSize contains the number of
+ − | characters to write. In the case of a successful completion,
+ − | the function returns DRV_OK.
+ − |
+ − | Parameters : in_BufferPtr - This parameter points to the buffer
+ − | that is passed to the driver for
+ − | further processing
+ − | thr_BufferSize - number of characters to write.
+ − |
+ − | Return : DRV_OK - Function successful
+ − | DRV_INPROCESS - Driver is busy writing data
+ − | SOCKET_NOCONNECT - Connection not available
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL UBYTE socket_WriteToOS (void* in_BufferPtr, USHORT thr_BufferSize)
+ − {
+ − int err;
+ − USHORT c_written;
+ − #ifndef _PSOS_
+ − fd_set fd_w;
+ − fd_set fd_e;
+ − struct timeval tv;
+ −
+ − if (L_ClientData.Socket == INVALID_SOCKET)
+ − return SOCKET_NOCONNECT;
+ −
+ − if ( L_ClientData.Connect == FALSE )
+ − return SOCKET_NOCONNECT ;
+ −
+ − tv.tv_sec = (int)(L_DCB.tx_timeout_msec / 1000) ;
+ − tv.tv_usec = SEND_TIMEOUTUSEC ;
+ −
+ − FD_ZERO(&fd_w);
+ − FD_SET(L_ClientData.Socket, &fd_w);
+ − FD_ZERO(&fd_e);
+ − FD_SET(L_ClientData.Socket, &fd_e);
+ −
+ − if (select(FD_SETSIZE, NULL, &fd_w, &fd_e, &tv) <= 0)
+ − {
+ − #ifdef SOCKET_DEBUG
+ − char buffer[200];
+ − char *ptr = in_BufferPtr;
+ − char c = ptr[21];
+ − fp = fopen(inprocessfile, "at");
+ − if ( *ptr == 'P' )
+ − ptr[21] = 0;
+ − else
+ − ptr[thr_BufferSize] = 0;
+ − strcpy (buffer, "errno:" );
+ − sprintf (&buffer[6], "%8d", WSAGetLastError() );
+ − buffer[14] = ' ';
+ − memcpy (&buffer[15], ptr, (thr_BufferSize)+1);
+ − fprintf (fp, "%s\n", buffer );
+ − ptr[21] = c;
+ − fclose(fp);
+ − #endif /* SOCKET_DEBUG */
+ − #ifdef _VXWORKS_
+ − err = errnoGet ();
+ − #else /* _VXWORKS_ */
+ − err = errno;
+ − printf("SOCKET: socket write failed with error code: %d\n",err );
+ − #endif /* _VXWORKS_ */
+ −
+ − return DRV_INPROCESS ;
+ − }
+ −
+ − if (FD_ISSET (L_ClientData.Socket, &fd_e))
+ − {
+ − #ifdef SOCKET_DEBUG
+ − char buffer[200];
+ − char *ptr = in_BufferPtr;
+ − char c = ptr[21];
+ − fp = fopen(noconnectfile1, "at");
+ − if ( *ptr == 'P' )
+ − ptr[21] = 0;
+ − else
+ − ptr[thr_BufferSize] = 0;
+ − strcpy (buffer, "errno:" );
+ − sprintf (&buffer[6], "%8d", WSAGetLastError() );
+ − buffer[14] = ' ';
+ − memcpy (&buffer[15], ptr, (thr_BufferSize)+1);
+ − fprintf (fp, "%s\n", buffer );
+ − ptr[21] = c;
+ − fclose(fp);
+ − #endif /* SOCKET_DEBUG */
+ − return SOCKET_NOCONNECT ;
+ − }
+ −
+ − /*---------------------------------
+ − Send the data
+ − ---------------------------------*/
+ − c_written = (USHORT) WRITE_SOCKET(L_ClientData.Socket, in_BufferPtr, (USHORT)thr_BufferSize);
+ −
+ − if (c_written == (USHORT)SOCKET_ERROR || c_written != thr_BufferSize)
+ − {
+ − #ifdef SOCKET_DEBUG
+ − char buffer[200];
+ − char *ptr = in_BufferPtr;
+ − char c = ptr[21];
+ − fp = fopen(noconnectfile2, "at");
+ − if ( *ptr == 'P' )
+ − ptr[21] = 0;
+ − else
+ − ptr[thr_BufferSize] = 0;
+ − strcpy (buffer, "errno:" );
+ − sprintf (&buffer[6], "%8d", WSAGetLastError() );
+ − buffer[14] = ' ';
+ − memcpy (&buffer[15], ptr, (thr_BufferSize)+1);
+ − fprintf (fp, "%s\n", buffer );
+ − ptr[21] = c;
+ − fclose(fp);
+ − #endif /* SOCKET_DEBUG */
+ − return SOCKET_NOCONNECT ;
+ − }
+ −
+ − #ifdef SOCK_TRACE
+ − if (fh_sock != -1)
+ − {
+ − char sstop[10];
+ − ULONG stop = GetTickCount();
+ −
+ − sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000);
+ − sprintf(stbuf, "sent %d at %s\n",
+ − thr_BufferSize,
+ − sstop);
+ − write (fh_sock, stbuf, strlen(stbuf));
+ − }
+ − #endif
+ − return DRV_OK ;
+ −
+ − #else
+ −
+ − /* pSOS */
+ −
+ − /*---------------------------------
+ − Send the data
+ − ---------------------------------*/
+ − c_written = (USHORT) WRITE_SOCKET(tst_socket, in_BufferPtr, (USHORT)thr_BufferSize);
+ −
+ − if (c_written == (USHORT)SOCKET_ERROR || c_written != thr_BufferSize)
+ − {
+ − err = errno;
+ − return SOCKET_NOCONNECT ;
+ − }
+ −
+ − return DRV_OK ;
+ − #endif /* _PSOS_ */
+ − }
+ −
+ − /*==== PUBLIC FUNCTIONS =====================================================*/
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_Exit
+ − +------------------------------------------------------------------------------
+ − | Description : The function is called when the driver functionality is no
+ − | longer required. The function "de-allocates" the resources
+ − | and releases active connections. The driver terminates
+ − | regardless of any outstanding data to be sent.
+ − |
+ − | Parameters : -
+ − |
+ − | Return : -
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − void socket_Exit (void)
+ − {
+ − os_DestroyTask ( 0, L_ClientData.ThreadID );
+ − socket_Close() ;
+ − }
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_Open
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to establish a connection to server or
+ − | activate the driver to act as a server, using the settings of
+ − | the socket_DCB. A hostname must be specified to open a
+ − | connection to a server, in this case the driver runs in the
+ − | client mode. If no hostname is specified the driver will run in
+ − | server mode. In the server mode it serves a single client. As
+ − | soon as a client is connected the CONNECT signal is generated.
+ − | In case of a successful completion the driver is no able to send
+ − | data (socket_write()) to the peer entity and to read data
+ − | received from the peer entity (socket_read()). To get notified
+ − | about the reception of data the appropriate signal has to be set
+ − | (socket_SetSignal()).
+ − | In the case of a successful completion the driver returns DRV_OK.
+ − | If the driver is already busy DRV_INPROCESS is returned.
+ − | If the driver is not configured, the function returns
+ − | DRV_NOTCONFIGURED.
+ − | If an error occurs while establishing the requested mode, the
+ − | function returns SOCKET_ERRUNSPEC.
+ − |
+ − | Parameters : -
+ − |
+ − | Return : DRV_OK - Function successful
+ − | DRV_INPROCESS - The driver is currently reading data.
+ − | The data is incomplete.
+ − | DRV_NOTCONFIGURED - The driver is not yet configured
+ − | SOCKET_ERRUNSPEC - Error occured during initialization
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − USHORT socket_Open (void)
+ − {
+ − SOCKADDR_IN dest_sin; /* DESTination Socket INternet */
+ − SOCKET connectsocket;
+ − #ifdef _VXWORKS_
+ − int sockAddrSize;
+ − #else /* _VXWORKS_ */
+ − #if defined (_LINUX_) || defined (_SOLARIS_)
+ − struct hostent* phe;
+ − #else
+ − PHOSTENT phe;
+ − #endif
+ − #endif /* _VXWORKS_ */
+ − if (L_ThreadActive)
+ − {
+ − return DRV_INPROCESS ;
+ − }
+ −
+ − /*---------------------------------
+ − if no hostname is specified we
+ − open as a server
+ − ---------------------------------*/
+ − if (!*L_DCB.hostname)
+ − {
+ − return L_CreateServer() ;
+ − }
+ −
+ − connectsocket = socket (AF_INET, SOCK_STREAM, 0);
+ − if (connectsocket == INVALID_SOCKET)
+ − {
+ − return SOCKET_ERRUNSPEC;
+ − }
+ −
+ − #ifdef _PSOS_
+ −
+ − if ( !gethostbyname(L_DCB.hostname, phe))
+ − {
+ − CLOSE_SOCKET(connectsocket);
+ − return SOCKET_ERRUNSPEC;
+ − }
+ −
+ − #else /* _PSOS_ */
+ − #ifdef _VXWORKS_
+ − sockAddrSize = sizeof (struct sockaddr_in);
+ − memset((char *) &dest_sin, 0, sockAddrSize);
+ − dest_sin.sin_len = (u_char) sockAddrSize;
+ − dest_sin.sin_family = AF_INET;
+ − dest_sin.sin_port = htons(L_DCB.port);
+ − if (((dest_sin.sin_addr.s_addr = inet_addr (L_DCB.hostname)) == ERROR) &&
+ − ((dest_sin.sin_addr.s_addr = hostGetByName (L_DCB.hostname)) == ERROR))
+ − {
+ − CLOSE_SOCKET(connectsocket);
+ − return SOCKET_ERRUNSPEC;
+ − }
+ − #else /* _VXWORKS_ */
+ − phe = gethostbyname(L_DCB.hostname);
+ − if (!phe)
+ − {
+ − #ifdef _TOOLS_
+ − printf("SOCKET: host %s not found ;-(\n",L_DCB.hostname);
+ − #endif
+ − CLOSE_SOCKET(connectsocket);
+ − return SOCKET_ERRUNSPEC;
+ − }
+ − #endif /* _VXWORKS_ */
+ − #endif /* _PSOS_ */
+ −
+ − #ifndef _VXWORKS_
+ − memset(&dest_sin, 0, sizeof(struct sockaddr_in));
+ − memcpy((char*)&(dest_sin.sin_addr), phe->h_addr, (unsigned int)((int)(phe->h_length)));
+ − dest_sin.sin_family = AF_INET;
+ − if ( L_DCB.config & TI_MODE )
+ − dest_sin.sin_port = L_DCB.port;
+ − else
+ − dest_sin.sin_port = htons(L_DCB.port);
+ − #endif /* _VXWORKS_ */
+ −
+ − #ifdef _PSOS_
+ − if (connect (connectsocket, (struct sockaddr_in*) &dest_sin, sizeof(dest_sin)))
+ − #else /* _PSOS_ */
+ − #ifdef _VXWORKS_
+ − if (connect (connectsocket, (struct sockaddr*) &dest_sin, sockAddrSize) == ERROR)
+ − #else /* _VXWORKS_ */
+ − #if defined (_LINUX_) || defined (_SOLARIS_)
+ − if (connect (connectsocket, (struct sockaddr*) &dest_sin,
+ − sizeof(dest_sin)))
+ − #else
+ − if (connect (connectsocket, (const PSOCKADDR) &dest_sin,
+ − sizeof(dest_sin)))
+ − #endif
+ − #endif /* _VXWORKS_ */
+ − #endif /* defined(_PSOS_) || defined(_VXWORKS_) */
+ − {
+ − #ifdef _TOOLS_
+ − printf("SOCKET: connection to %s on port %i failed ;-(\n",L_DCB.hostname,L_DCB.port);
+ − #endif
+ − CLOSE_SOCKET(connectsocket);
+ − return SOCKET_ERRUNSPEC;
+ − }
+ − #ifdef _TOOLS_
+ − printf("SOCKET: successfully connected to %s on port %i\n",L_DCB.hostname,L_DCB.port);
+ − #endif
+ −
+ − if (!L_CreateThread (L_ClientThread))
+ − {
+ − CLOSE_SOCKET (L_ClientData.Listener);
+ − return SOCKET_ERRUNSPEC;
+ − }
+ −
+ − L_ClientData.Socket = connectsocket ;
+ − L_ClientData.Connect = TRUE;
+ − if (L_ClientData.EnabledSignals & DRV_SIGTYPE_CONNECT)
+ − {
+ − SocketSignal.SignalType = DRV_SIGTYPE_CONNECT;
+ − SocketSignal.DrvHandle = L_ClientData.SocketHandle;
+ − (*L_ClientData.Callback)(&SocketSignal) ;
+ − }
+ − return DRV_OK ;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_Close
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used by a client to close the connection or
+ − | by server to shut down the server functionality.
+ − | In case of a successful completion the connection is shutdown
+ − | and neither socket_Read nor socket_Write will be successful.
+ − | To get notified about the termination of a connection the
+ − | appropriate signal has to be set (socket_SetSignal()).
+ − |
+ − | Parameters : -
+ − |
+ − | Return : -
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − USHORT socket_Close (void)
+ − {
+ − L_ThreadActive = FALSE ;
+ −
+ − #ifdef SOCK_TRACE
+ − if (fh_sock != -1)
+ − {
+ − char sstop[10];
+ − ULONG stop = GetTickCount();
+ −
+ − sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000);
+ − sprintf(stbuf, "socket_Close at %s socket=%d listener=%d\n",
+ − sstop, L_ClientData.Socket, L_ClientData.Listener);
+ − write (fh_sock, stbuf, strlen(stbuf));
+ − }
+ − #endif
+ − if (L_ClientData.Socket != INVALID_SOCKET)
+ − {
+ − CLOSE_SOCKET (L_ClientData.Socket);
+ − L_ClientData.Socket = INVALID_SOCKET;
+ − }
+ −
+ − if (L_ClientData.Listener != INVALID_SOCKET)
+ − CLOSE_SOCKET (L_ClientData.Listener);
+ −
+ − L_ClientData.ThreadID = 0 ;
+ − return DRV_OK;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_Read_with_Timeout
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to read data from the USART driver.
+ − | For more details see socket_Read()
+ − |
+ − | Return: >= 0 - Number of bytes read
+ − | SOCKET_ERROR - error occurred
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL ULONG socket_Read_with_Timeout( void* destBuf, ULONG reqLen )
+ − {
+ − ULONG timeout,
+ − totalBytes = 0,
+ − stop_timeout ;
+ − int readBytes,
+ − attempts = 0;
+ −
+ − /* calculate timeout time */
+ − GETTIME( stop_timeout );
+ − stop_timeout = stop_timeout + L_DCB.rx_timeout_msec ;
+ −
+ − /* read nonblocking until requested data is read or timeout */
+ − do
+ − {
+ − readBytes = (SHORT)READ_SOCKET( L_ClientData.Socket,
+ − ((char *)destBuf) + totalBytes,
+ − reqLen - totalBytes );
+ −
+ − if( readBytes < 0 || readBytes == SOCKET_ERROR )
+ − {
+ − #ifdef SOCKET_DEBUG
+ − #ifndef _PSOS_
+ − fp = fopen(readerrorfile, "at");
+ − fprintf (fp, "WSAGetLastError returned: %8d", WSAGetLastError() );
+ − fclose(fp);
+ − #endif
+ − #endif /* SOCKET_DEBUG */
+ − return 0;
+ − }
+ − else
+ − {
+ − totalBytes += (unsigned int)readBytes;
+ −
+ − GETTIME (timeout) ;
+ −
+ − if( totalBytes < reqLen )
+ − {
+ − if (attempts++) /* try to get data by two consecutive accesses
+ − then sleep (but this should not be necessary) */
+ − {
+ − #ifdef OLD_FRAME
+ − Sleep (1) ;
+ − #else
+ − os_SuspendTask ( 0, 1 );
+ − #endif
+ − }
+ − }
+ − else
+ − {
+ − return totalBytes;
+ − }
+ − }
+ − } while (timeout < stop_timeout);
+ −
+ − return 0;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_Read
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to read data from the USART driver. The
+ − | data is copied into the buffer to which out_BufferPtr points.
+ − | The parameter *thr_BufferSizePtr contains the size of the
+ − | buffer in characters.
+ − | In the case of a successful completion, the driver's buffer
+ − | is cleared. The driver keeps the data available when calling
+ − | the function drv_Look().
+ − | If the driver is not configured, the function returns
+ − | DRV_NOTCONFIGURED.
+ − |
+ − | NOTE: When calling the function with a buffer size of 0, the
+ − | function will return DRV_OK. The size of the buffer
+ − | needed to store the available data is stored in the
+ − | parameter *thr_BufferSizePtr. In this case, the
+ − | out_BufferPtr can be set to NULL.
+ − |
+ − |
+ − | Parameters : out_BufferPtr - This parameter points to the buffer
+ − | wherein the data is to be copied
+ − | thr_BufferSizePtr - On call: number of characters to
+ − | read. If the function returns DRV_OK,
+ − | it contains the number of characters
+ − | read. If the function returns
+ − | DRV_INPROCESS, it contains 0.
+ − |
+ − | Return : DRV_OK - Function successful
+ − | DRV_INPROCESS - The driver is currently reading data.
+ − | The data is incomplete.
+ − | DRV_NOTCONFIGURED - The driver is not yet configured
+ − | SOCKET_NOCONNECT - Connection not available
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − USHORT socket_Read (void* out_BufferPtr, ULONG* thr_BufferSizePtr)
+ − {
+ − #ifdef _VXWORKS_
+ − SIZETYPE pending_data_size = 0;
+ − #else
+ − ULONG pending_data_size = 0;
+ − #endif
+ − ULONG bytesToRead, bytesReq;
+ − int rc;
+ − static USHORT packet_size;
+ − union
+ − {
+ − USHORT s;
+ − UBYTE b[2];
+ − } conv;
+ − #ifdef SOCKET_DEBUG
+ − static ULONG BytesRead = 0;
+ − #endif
+ − #ifdef SOCK_TRACE
+ − static ULONG start;
+ − static ULONG lasttime = 0;
+ − #endif
+ −
+ − bytesReq = *thr_BufferSizePtr;
+ − *thr_BufferSizePtr = 0; /* no bytes returned yet */
+ − while ( (rc = (GETREADSIZE( L_ClientData.Socket, &pending_data_size ))) == 0 &&
+ − pending_data_size > 0 )
+ − {
+ − switch (sock_state)
+ − {
+ − case SST_PL0:
+ − #ifdef SOCK_TRACE
+ − GETTIME (start) ;
+ − #endif
+ − packet_size = 0;
+ − if (pending_data_size >= 2)
+ − {
+ − bytesToRead = 2;
+ − sock_state = SST_DATA0;
+ − }
+ − else
+ − {
+ − bytesToRead = 1;
+ − sock_state = SST_PL1;
+ − }
+ − if ( !(L_DCB.config & TI_MODE) )
+ − {
+ − if (socket_Read_with_Timeout(&packet_size, bytesToRead) != bytesToRead)
+ − {
+ − sock_state = SST_PL0;
+ − return SOCKET_NOCONNECT;
+ − }
+ − }
+ − break;
+ − case SST_PL1:
+ − if (socket_Read_with_Timeout(((char*)&packet_size)+1, 1) != 1)
+ − {
+ − sock_state = SST_PL0;
+ − return SOCKET_NOCONNECT;
+ − }
+ − sock_state = SST_DATA0;
+ − break;
+ − case SST_DATA0:
+ − if ( !(L_DCB.config & TI_MODE) && isLittleEndian )
+ − {
+ − conv.b[0] = *(((UBYTE*)&packet_size)+1); /* LSB */
+ − conv.b[1] = * (UBYTE*)&packet_size; /* MSB */
+ − packet_size = conv.s;
+ − }
+ − /*lint -fallthrough*/
+ − case SST_DATAx:
+ − /* now read the packet payload or a part of it */
+ − if ( L_DCB.config & TI_MODE )
+ − {
+ − bytesToRead = (pending_data_size < bytesReq) ? pending_data_size : bytesReq;
+ − }
+ − else
+ − {
+ − bytesToRead = (packet_size < bytesReq) ? packet_size : bytesReq;
+ − if (pending_data_size < bytesToRead)
+ − bytesToRead = pending_data_size;
+ − }
+ − if( (*thr_BufferSizePtr =
+ − socket_Read_with_Timeout( ((char *)out_BufferPtr), bytesToRead )) !=
+ − bytesToRead )
+ − {
+ − *thr_BufferSizePtr = 0;
+ − if ( !(L_DCB.config & TI_MODE) )
+ − sock_state = SST_PL0;
+ − return SOCKET_NOCONNECT;
+ − }
+ − #ifdef SOCK_TRACE
+ − if (fh_sock != -1 && sock_state == SST_DATA0 && bytesToRead >= 13)
+ − {
+ − char split[10+1];
+ − char sstart[20], sstop[20];
+ − static ULONG c_received = 0;
+ − ULONG len = packet_size;
+ − ULONG stop = GetTickCount();
+ −
+ − if (((char*)out_BufferPtr)[13] == 'T')
+ − {
+ − memcpy(split, ((char*)out_BufferPtr)+9, 7);
+ − split[7] = '\0';
+ − }
+ − else
+ − {
+ − memcpy(split, ((char*)out_BufferPtr)+9, 4);
+ − split[4] = '\0';
+ − }
+ − if (start != lasttime)
+ − {
+ − if (lasttime - start > 11)
+ − sprintf(sstart, "->%d %03d:%03d\n", c_received, (start/1000) % 1000, start % 1000);
+ − else
+ − sprintf(sstart, "%03d:%03d\n", (start/1000) % 1000, start % 1000);
+ − c_received = 0;
+ − }
+ − c_received += packet_size + 2;
+ − if (start != stop)
+ − {
+ − sprintf(sstop, "->%d %03d:%03d\n", c_received, (stop/1000) % 1000, stop % 1000);
+ − c_received = 0;
+ − }
+ − sprintf(stbuf, "%s%d %s\n%s",
+ − (start != lasttime) ? sstart : "",
+ − packet_size + 2, split,
+ − (start != stop) ? sstop : "");
+ − write (fh_sock, stbuf, strlen(stbuf));
+ − lasttime = stop;
+ − }
+ − #endif
+ − if ( !(L_DCB.config & TI_MODE) )
+ − {
+ − if (*thr_BufferSizePtr == packet_size)
+ − sock_state = SST_PL0;
+ − else
+ − {
+ − packet_size -= (USHORT)*thr_BufferSizePtr;
+ − sock_state = SST_DATAx;
+ − }
+ − }
+ − return DRV_OK;
+ − /*lint -e527 suppress Warning -- Unreachable */
+ − break;
+ − /*lint +e527 */
+ − } /* switch */
+ − } /* while */
+ − if (rc)
+ − {
+ − sock_state = SST_PL0;
+ − return SOCKET_NOCONNECT;
+ − }
+ − #ifdef SOCKET_DEBUG
+ − {
+ − static char Buffer[2000];
+ − memcpy (Buffer+BytesRead,out_BufferPtr,*thr_BufferSizePtr);
+ − BytesRead += *thr_BufferSizePtr;
+ − if ( (Buffer[0] == 'P') )
+ − {
+ − OS_TIME time;
+ − char c = Buffer[21];
+ − fp = fopen(logfile, "at");
+ − Buffer[21] = 0;
+ − os_GetTime ( 0, &time );
+ − fprintf (fp, "P%ld IN: %s\n", time/10, &Buffer[9] );
+ − Buffer[21] = c;
+ − fclose(fp);
+ − }
+ − }
+ −
+ − #endif
+ − return DRV_OK ;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_Write
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to write data to the driver. The
+ − | parameter *thr_BufferSizePtr contains the number of
+ − | characters to write. In the case of a successful completion,
+ − | the function returns DRV_OK.
+ − | If the data cannot be written because the storage capacity of
+ − | the driver has been exhausted, the function returns
+ − | DRV_BUFFER_FULL and the maximum number of characters that can
+ − | be written in *thr_BufferSizePtr.
+ − | If the driver is currently busy writing data and therefore
+ − | cannot accept further data to be written, it returns
+ − | DRV_INPROCESS and sets the parameter *thr_BufferSizePtr to 0.
+ − | If the driver is not configured, the function returns
+ − | DRV_ NOTCONFIGURED.
+ − |
+ − | NOTE: When calling the function with a buffer size of 0, the
+ − | function will return the number of characters that can be
+ − | written in the parameter *thr_BufferSizePtr. In this
+ − | case, the in_BufferPtr can be set to NULL.
+ − |
+ − | Parameters : in_BufferPtr - This parameter points to the buffer
+ − | that is passed to the driver for
+ − | further processing
+ − | thr_BufferSizePtr - On call: number of characters to
+ − | write. If the function returns
+ − | DRV_BUFFER_FULL, it contains the
+ − | maximum number of characters that can
+ − | be written. If the function returns
+ − | DRV_OK, it contains the number of
+ − | characters written. If the function
+ − | returns DRV_INPROCESS, it contains 0.
+ − |
+ − |
+ − | Return : DRV_OK - Function successful
+ − | DRV_BUFFER_FULL - Not enough space
+ − | DRV_INPROCESS - Driver is busy writing data
+ − | DRV_NOTCONFIGURED - The driver is not yet configured
+ − | SOCKET_NOCONNECT - Connection not available
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − /*lint -esym(613,auxb) suppress warning possibly use off NULL pointer auxb */
+ − /*lint -esym(644,auxb) suppress warning possibly not initialized */
+ − /*lint -e668 suppress warning possibly passing NULL pointer to memcpy */
+ − USHORT socket_Write (void* in_BufferPtr, ULONG* thr_BufferSizePtr)
+ − {
+ − UBYTE rc = DRV_OK;
+ − int max_len, rest;
+ − char * auxb;
+ − ULONG buffer_size;
+ −
+ − buffer_size = *thr_BufferSizePtr & ~PRIM_FLAG_MASK;
+ −
+ − #ifndef _PSOS_
+ − #ifdef SOCKET_DEBUG
+ − UBYTE Prim = 0;
+ − {
+ − char *ptr = in_BufferPtr;
+ − if ( *ptr == 'P' )
+ − {
+ − OS_TIME time;
+ − char c = ptr[21];
+ − fp = fopen(logfile, "at");
+ − ptr[21] = 0;
+ − os_GetTime ( 0, &time );
+ − fprintf (fp, "P%ld OUT: %s\n", time/10, &ptr[9] );
+ − ptr[21] = c;
+ − fclose(fp);
+ − Prim = 1;
+ − }
+ − }
+ − #endif /* SOCKET_DEBUG */
+ − #else /* _PSOS */
+ − if( !tst_socket_initialized )
+ − {
+ − if (tst_socket_in_TxLen > 0)
+ − {
+ − int nodelay = TRUE;
+ − if (setsockopt(tst_socket, SOL_SOCKET, SO_SNDBUF,
+ − (char*)&tst_socket_in_TxLen, sizeof(tst_socket_in_TxLen)))
+ − return DRV_INITFAILURE;
+ − if (setsockopt(tst_socket, IPPROTO_TCP, TCP_NODELAY,
+ − (char*)&nodelay, sizeof(nodelay)))
+ − return DRV_INITFAILURE;
+ − }
+ − tst_socket_initialized = 1;
+ − }
+ − #endif /* _PSOS_ */
+ −
+ − if ( L_DCB.config & TI_MODE )
+ − {
+ − /* add TI-MUX header */
+ − auxb=(char*)malloc(buffer_size+2);
+ − memcpy((void*)(auxb+2),in_BufferPtr,buffer_size);
+ − auxb[0]=19; /* assigned to L23 */
+ − auxb[1]=(char)buffer_size;
+ − in_BufferPtr=auxb;
+ − buffer_size+=2;
+ − }
+ −
+ − max_len = (L_DCB.tx_buffer_size < WRBUF_LEN) ? L_DCB.tx_buffer_size : WRBUF_LEN;
+ − if (max_len < (int)buffer_size)
+ − {
+ − #ifndef _PSOS_
+ − #ifdef SOCKET_DEBUG
+ − char buffer[200];
+ − char *ptr = in_BufferPtr;
+ − char c = ptr[21];
+ − fp = fopen(bufferfullfile, "at");
+ − if ( *ptr == 'P' )
+ − ptr[21] = 0;
+ − else
+ − ptr[buffer_size] = 0;
+ − strcpy (buffer, "errno:" );
+ − sprintf (&buffer[6], "%8d", WSAGetLastError() );
+ − buffer[14] = ' ';
+ − memcpy (&buffer[15], ptr, (buffer_size)+1);
+ − fprintf (fp, "%s\n", buffer );
+ − ptr[21] = c;
+ − fclose(fp);
+ − #endif /* SOCKET_DEBUG */
+ − #endif /* _PSOS_ */
+ − if ( L_DCB.config & TI_MODE )
+ − free(auxb);
+ − *thr_BufferSizePtr = (unsigned int)max_len |
+ − (*thr_BufferSizePtr & PRIM_FLAG_MASK) ;
+ − return DRV_BUFFER_FULL ;
+ − }
+ −
+ − rest = MAX_ETH_LEN - (wrbuf_pos - wrbuf);
+ − if (buffer_size + 2 >= (unsigned int)rest) /* more than maximum ethernet packet size needed ?*/
+ − {
+ − /*---------------------------------
+ − send the buffer
+ − ---------------------------------*/
+ − rc = socket_WriteToOS(wrbuf, (USHORT)(wrbuf_pos - wrbuf));
+ − wrbuf_pos = wrbuf;
+ −
+ − if (rc != DRV_OK)
+ − {
+ − if ( L_DCB.config & TI_MODE )
+ − free(auxb);
+ − *thr_BufferSizePtr = (*thr_BufferSizePtr & PRIM_FLAG_MASK) ;
+ − return rc;
+ − }
+ − }
+ −
+ − if ( !(L_DCB.config & TI_MODE) )
+ − {
+ − /*------------------------------------------------
+ − put the size of the data into buffer (MSB first)
+ − ------------------------------------------------*/
+ − if (isLittleEndian)
+ − {
+ − *wrbuf_pos = *(((UBYTE*)&buffer_size)+1); /* MSB */
+ − *(wrbuf_pos+1) = * (UBYTE*)&buffer_size; /* LSB */
+ − }
+ − else
+ − *((USHORT*)wrbuf_pos) = (USHORT)buffer_size;
+ − wrbuf_pos += 2;
+ − }
+ − /*---------------------------------
+ − put the data itself into buffer
+ − ---------------------------------*/
+ − memcpy(wrbuf_pos, in_BufferPtr, (size_t)buffer_size);
+ − wrbuf_pos += buffer_size;
+ −
+ − if (socket_flush)
+ − {
+ − /*---------------------------------
+ − send the buffer
+ − ---------------------------------*/
+ − rc = socket_WriteToOS(wrbuf, (USHORT)(wrbuf_pos - wrbuf));
+ − wrbuf_pos = wrbuf;
+ − socket_flush = 0;
+ −
+ − if (rc != DRV_OK)
+ − {
+ − *thr_BufferSizePtr = (*thr_BufferSizePtr & PRIM_FLAG_MASK) ;
+ − }
+ − }
+ −
+ − if ( L_DCB.config & TI_MODE )
+ − {
+ − free(auxb);
+ − }
+ − return rc ;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_Flush
+ − +------------------------------------------------------------------------------
+ − | Description : This function flushes the socket write buffer where data
+ − | is stored until a complete packet can be sent or the
+ − | transmission is forced by an external setting of the
+ − | socket_flush flag.
+ − |
+ − | Parameters : ---
+ − |
+ − | Return : DRV_OK - Function completed successfully
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − USHORT socket_Flush ( void )
+ − {
+ − ULONG len = 0;
+ −
+ − socket_flush = 1;
+ − return ( socket_Write(NULL, &len) );
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_SetSignal
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to define a single or multiple signals
+ − | that is/are indicated to the process when the event identified
+ − | in the signal information data type as SignalType occurs. The
+ − | USART uses only the standard signals defined in [C_8415.0026].
+ − | To remove a signal, call the function socket_ResetSignal().
+ − | If one of the parameters of the signal information data is
+ − | invalid, the function returns DRV_INVALID_PARAMS.
+ − | If no signal call-back function has been defined at the time
+ − | of initialization, the driver returns DRV_SIGFCT_NOTAVAILABLE.
+ − |
+ − | Parameters : in_SignalIDPtr - Pointer to the signal information
+ − | data
+ − |
+ − | Return : DRV_OK - Function completed successfully
+ − | DRV_INVALID_PARAMS - One or more parameters are out of
+ − | range or invalid
+ − | DRV_SIGFCT_NOTAVAILABLE - Event signaling functionality is
+ − | not available
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − USHORT socket_SetSignal (USHORT SignalType)
+ − {
+ − if (L_ClientData.Callback == NULL)
+ − return DRV_SIGFCT_NOTAVAILABLE ;
+ −
+ − if (SignalType & ALLOWED_SOCKET_SIGNALS)
+ − L_ClientData.EnabledSignals |= SignalType;
+ − else
+ − return DRV_INVALID_PARAMS ;
+ − return DRV_OK ;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_ResetSignal
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to remove previously set single or
+ − | multiple signals. The signals that are removed are identified
+ − | by the Signal Information Data element called SignalType. All
+ − | other elements of the Signal Information Data must be
+ − | identical to the signal(s) that are to be removed (process
+ − | handle and signal value). If the SignalID provided cannot be
+ − | located, the function returns DRV_INVALID_PARAMS.
+ − | If no signal call-back function has been defined at the time
+ − | of initialization, the driver returns DRV_SIGFCT_NOTAVAILABLE.
+ − |
+ − | Parameters : in_SignalIDPtr - Pointer to the signal information
+ − | data
+ − |
+ − | Return : DRV_OK - Function completed successfully
+ − | DRV_INVALID_PARAMS - One or more parameters are out of
+ − | range or invalid
+ − | DRV_SIGFCT_NOTAVAILABLE - Event signaling functionality is
+ − | not available
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − USHORT socket_ResetSignal (USHORT SignalType)
+ − {
+ − if (L_ClientData.Callback == NULL)
+ − return DRV_SIGFCT_NOTAVAILABLE ;
+ −
+ − if (SignalType & ALLOWED_SOCKET_SIGNALS)
+ − L_ClientData.EnabledSignals &= ~SignalType;
+ − else
+ − return DRV_INVALID_PARAMS ;
+ −
+ − return DRV_OK ;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_SetConfig
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to configure the driver (port,
+ − | transmission rate, flow control, etc). The driver can be
+ − | configured at any one time before a connection is opened. The
+ − | parameters that can be configured are included in the USART's
+ − | device control block socket_DCB_Type. For detailed information
+ − | about the contents of the device control block, refer to
+ − | Chapter 2.1.1. If any value of the configuration is out of
+ − | range or invalid in combination with any other value of the
+ − | configuration, the function returns DRV_INVALID_PARAMS.
+ − | Call the socket_GetConfig() function to retrieve the driver's
+ − | configuration.
+ − | The driver needs to be configured after initialization. Only
+ − | the following functions can be called while the driver is not
+ − | configured: socket_Clear, socket_SetSignal and socket_GetSignal.
+ − | All other functions return DRV_NOTCONFIGURED.
+ − |
+ − | Parameters : in_DCBPtr - Pointer to the driver control block
+ − |
+ − | Return : DRV_OK - Function completed successfully
+ − | DRV_INVALID_PARAMS - One or more parameters are out of
+ − | range or invalid
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − USHORT socket_SetConfig (char* in_DCBPtr)
+ − {
+ − char token [SOCKET_MAX_LEN_HOSTNAME+1];
+ − USHORT port;
+ − unsigned int len;
+ −
+ − if ( (len = GetNextToken (in_DCBPtr, token, " #")) == 0)
+ − {
+ − return DRV_INVALID_PARAMS;
+ − }
+ − else
+ − {
+ − in_DCBPtr += (len+1);
+ − }
+ −
+ − port = (USHORT)atoi(token);
+ −
+ − if ( (len = GetNextToken (in_DCBPtr, token, " #")) == 0)
+ − {
+ − return DRV_INVALID_PARAMS;
+ − }
+ − else
+ − {
+ − in_DCBPtr += (len+1);
+ − }
+ −
+ − if ( !strcmp ( DRV_TI_MODE, token ) )
+ − {
+ − L_DCB.config = TI_MODE;
+ − sock_state = SST_DATAx;
+ − }
+ − else if ( !strcmp ( DRV_DEFAULT, token ) )
+ − {
+ − L_DCB.config = 0;
+ − sock_state = SST_PL0;
+ − }
+ − else
+ − return DRV_INVALID_PARAMS;
+ −
+ − if ( (len = GetNextToken (in_DCBPtr, token, " #")) == 0 )
+ − {
+ − #ifdef _TOOLS_
+ − gethostname (token,SOCKET_MAX_LEN_HOSTNAME);
+ − #endif /* _TOOLS_ */
+ − }
+ −
+ − if (L_ThreadActive)
+ − {
+ − /* check if host is already used */
+ − if (strcmp(L_DCB.hostname, token)==0 && L_DCB.port==port)
+ − {
+ − #ifdef _TOOLS_
+ − printf("SOCKET: keeping connection to host %s on port %u\n",L_DCB.hostname,L_DCB.port);
+ − #endif
+ − return DRV_OK;
+ − }
+ −
+ − socket_Close();
+ − }
+ −
+ − L_DCB.port=port;
+ − strcpy ( L_DCB.hostname, token);
+ −
+ − if (socket_Open () != DRV_OK)
+ − {
+ − return DRV_INVALID_PARAMS ;
+ − }
+ −
+ − return DRV_OK ;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_GetConfig
+ − +------------------------------------------------------------------------------
+ − | Description : This function is used to retrieve the configuration of the
+ − | driver. The configuration is returned in the driver control
+ − | block to which the pointer provided out_DCBPtr points. For
+ − | detailed information about the contents of the device control
+ − | block, refer to Chapter 2.1.1. The configuration can be
+ − | requested at any one time.
+ − | If the driver is not configured, the function returns
+ − | DRV_ NOTCONFIGURED.
+ − |
+ − | Parameters : out_DCBPtr - Pointer to the driver control block
+ − |
+ − | Return : DRV_OK - Function completed successfully
+ − | DRV_INVALID_PARAMS - One or more parameters are out of
+ − | range or invalid
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − USHORT socket_GetConfig (socket_DCB_Type* out_DCBPtr)
+ − {
+ − if (out_DCBPtr == NULL)
+ − return DRV_INVALID_PARAMS ;
+ −
+ − memcpy (out_DCBPtr, &L_DCB, sizeof (L_DCB)) ;
+ − return DRV_OK ;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : socket_Init
+ − +------------------------------------------------------------------------------
+ − | Description : The function initializes the internal data of the driver.
+ − | The function returns DRV_INITIALIZED if the driver has
+ − | already been initialized and is ready to be used or is
+ − | already in use. In the case of an initialization failure,
+ − | i.e. the driver cannot be used, the function returns
+ − | DRV_INITFAILURE.
+ − |
+ − | Parameters : in_SignalCBPtr - This parameter points to the function that
+ − | is called at the time an event that is to
+ − | be signaled occurs. This value can be set
+ − | to NULL if event signaling should not be
+ − | possible.
+ − |
+ − | Return : DRV_OK - Initialization successful
+ − | DRV_INITIALIZED - Driver already initialized
+ − | DRV_INITFAILURE - Initialization failed
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL USHORT socket_Init ( USHORT DrvHandle, T_DRV_CB_FUNC CallbackFunc, T_DRV_EXPORT const **DrvInfo )
+ − {
+ − static const T_DRV_EXPORT Socket_Info =
+ − {
+ − "SOCKET",
+ − 0,
+ − {
+ − #ifdef _TOOLS_
+ − socket_Init,
+ − #endif
+ − socket_Exit,
+ − socket_Read,
+ − socket_Write,
+ − NULL,
+ − NULL,
+ − socket_Flush,
+ − socket_SetSignal,
+ − socket_ResetSignal,
+ − socket_SetConfig,
+ − NULL,
+ − NULL,
+ − }
+ − };
+ − union
+ − {
+ − USHORT s;
+ − UBYTE b[2];
+ − } test;
+ −
+ − #ifndef _PSOS_
+ − #if defined (_VXWORKS_) || defined (_LINUX_) || defined (_SOLARIS_)
+ − /* ToDo: vxWorks-libs initiieren
+ − sockLib
+ − inetLib
+ − */
+ − #else /* _VXWORKS_ */
+ − WSADATA WSAData;
+ − if (WSAStartup(MAKEWORD(1,1), &WSAData))
+ − return DRV_INITFAILURE;
+ − #endif /* _VXWORKS_ */
+ − #endif
+ −
+ − test.s = 1;
+ − isLittleEndian = (test.b[0] == 1);
+ −
+ − L_ThreadActive = FALSE ;
+ − L_DCB.config = 0;
+ − L_DCB.port = 6392;
+ − L_DCB.tx_buffer_size = TX_BUFFER_SIZE;
+ − L_DCB.rx_buffer_size = RX_BUFFER_SIZE ;
+ − L_DCB.tx_timeout_msec = TX_TIMEOUT_MSEC;
+ − L_DCB.rx_timeout_msec = RX_TIMEOUT_MSEC;
+ − *L_DCB.hostname = 0 ;
+ − L_ClientData.Connect = FALSE;
+ − L_ClientData.SocketHandle = DrvHandle;
+ − L_ClientData.Socket = INVALID_SOCKET ;
+ − L_ClientData.Listener = INVALID_SOCKET ;
+ − #ifdef _PSOS_
+ − tst_socket = INVALID_SOCKET ;
+ − tst_socket_initialized = 0;
+ − tst_socket_in_TxLen = 0;
+ − #endif
+ −
+ − L_ClientData.Callback = CallbackFunc ;
+ − L_ClientData.EnabledSignals = ALLOWED_SOCKET_SIGNALS ;
+ − *DrvInfo = &Socket_Info;
+ − #ifdef SOCKET_DEBUG
+ − fp = fopen(logfile,"wt");
+ − fclose(fp);
+ − fp = fopen(inprocessfile,"wt");
+ − fclose(fp);
+ − fp = fopen(bufferfullfile,"wt");
+ − fclose(fp);
+ − fp = fopen(noconnectfile1,"wt");
+ − fclose(fp);
+ − fp = fopen(noconnectfile2,"wt");
+ − fclose(fp);
+ − fp = fopen(noconnectfile3,"wt");
+ − fclose(fp);
+ − fp = fopen(readerrorfile,"wt");
+ − fclose(fp);
+ − #endif /* SOCKET_DEBUG */
+ − return DRV_OK ;
+ − }
+ −
+ − /*==== END OF FILE ==========================================================*/
+ −