Skip to content
Snippets Groups Projects
Select Git revision
  • master
  • snapArchivingApi-1.8.4
  • snapArchivingApi-1.8.3
  • snapArchivingApi-1.8.2
  • snapArchivingApi-1.8.1
  • snapArchivingApi-1.8.0
  • snapArchivingApi-1.7.8
  • snapArchivingApi-1.7.7
  • snapArchivingApi-1.7.6
  • snapArchivingApi-1.7.5
  • snapArchivingApi-1.7.4
  • snapArchivingApi-1.7.3
  • snapArchivingApi-1.7.2
  • snapArchivingApi-1.7.1
  • trunk
  • snapArchivingApi-1.7.0
  • snapArchivingApi-1.6.6
  • snapArchivingApi-1.6.5
  • snapArchivingApi-1.6.4
  • release_1_6_3
  • release_1_6_2
21 results

pom.xml

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Win32SocketLecroy.cpp 9.24 KiB
    //*******************************************************************************
    //* Copyright (c) 2008-2014 Synchrotron SOLEIL
    //* All rights reserved. This program and the accompanying materials
    //* are made available under the terms of the GNU Lesser Public License v3
    //* which accompanies this distribution, and is available at
    //* http://www.gnu.org/licenses/lgpl.html
    //******************************************************************************
    //******************************************************************************************
    //
    //
    //		september 13, 2004 :  Source file for the communication in socket mode
    //
    //								with a Lecroy scope (avaiable for all models)
    //		
    //		author : X.Elattaoui
    //
    //		SocketLecroy.cpp: implementation of the SocketLecroy class.
    //
    //******************************************************************************************
    
    static int	hSocket;
    static int	sTimeout = 15;
    //static int	sWinsockInitFlag = FALSE;
    static char	sCurrentAddress[256];
    static int 	sConnectedFlag = false;
    const int	CMD_BUF_LEN	= 8192;
    static char sCommandBuffer[CMD_BUF_LEN];
    
    //- INCLUDE
    #include "SocketLecroy.h"
    
    //- init of the static instance
    SocketLecroy* SocketLecroy::SL_instance = 0;	//- ptr on the SocketLecroy instance
     
    SocketLecroy* SocketLecroy::get_instance()
    {
    	if( !SL_instance )
    		SL_instance = new SocketLecroy();
    
    	return SL_instance;
    }
    
    void SocketLecroy::delete_instance(SocketLecroy* SL_instance)
    {
    	if(SL_instance)
    	{
    		delete SL_instance ;
    		SL_instance = 0;
    	}
    }
    
    //- CTOR
    SocketLecroy::SocketLecroy()
    {
    	sConnectedFlag = false;
    }
    //- DTOR
    SocketLecroy::~SocketLecroy()
    {
       TCP_Disconnect();
    }
    
    //- Build the connection
    void SocketLecroy::TCP_Connect(char *ip_address) throw (lecroy::SocketException)
    {
    SOCKADDR_IN	serverAddr;
    int sockAddrSize = sizeof (SOCKADDR), result;
    const int resp = 1;
    fd_set wr_set = {1, {0}};
    TIMEVAL tval;
    unsigned long argp;
    char tmpStr[256];
    	
    	//- connection test
    	if (sConnectedFlag)
    		return;
    
    	::strcpy(sCurrentAddress, ip_address);
    	
    	tval.tv_sec = sTimeout;
    	tval.tv_usec = 0;	
    
        //- build server socket address
    	serverAddr.sin_family = AF_INET;
    	serverAddr.sin_port = htons (SERVER_PORT);
    			
    	if ( (serverAddr.sin_addr.s_addr = inet_addr(ip_address)) == -1 ) 
    	{
    		throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    										"Bad server address.",
    										"SocketLecroy::TCP_Connect( ).");
    	}
    
        //- create client's socket
    	if ( (hSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET )
    	{
    		throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    										"Unable to create client's socket.",
    										"SocketLecroy::TCP_Connect( ).");
    	}
    
    	if ( setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&resp, sizeof(resp)) != 0 )
    	{
    		throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    										"Unable to set socket option to TCP_NODELAY.",
    										"SocketLecroy::TCP_Connect( ).");
    	}
    
    	wr_set.fd_array[0] = hSocket;
    	
    	argp = 1;//-non blocking mode
    	ioctlsocket(hSocket, FIONBIO, &argp);
    
    	int status = connect(hSocket, (SOCKADDR FAR *) &serverAddr, sockAddrSize);
    	int error_code = WSAGetLastError();
    
    	//- already connected !
    	if ( status && error_code == WSAEISCONN )
    		return;
    	if( status != 0 )  // We are not connected : so retry
    	{
    		if ( error_code == WSAEINPROGRESS || error_code == WSAEWOULDBLOCK ) // But the connection is in progress
    		{
    			int nb = 0;
    			while ( nb++ < 5 ) // We will attempt to connect every 150 ms for 5 times max.
    			{
    				status = ::connect(hSocket, ( sockaddr *)&serverAddr, sizeof(serverAddr));
    				error_code = WSAGetLastError();
    				if ( status != 0 ) // Still not connected
    				{
    					if ( errno == WSAEISCONN ) // This is the right error !
    					{
    						Sleep(150);  // Sleep for 150 ms
    					}
    				}// Connection is OK.
    				else
    					break;
    			} //- end while // Too much attempts, so failure !
    			if ( nb >= 5 )
    			{
    				throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    					"Too much attempt to (re)build socket connection.",
    					"SocketLecroy::TCP_Connect( ).");
    			}
    		}// TODO : throw ; // Not the right error, so failure !
    	}// Connected at first attempt !
    	
    	result = select(hSocket, NULL, &wr_set, NULL, &tval);
    	
    	argp = 0;//-blocking mode
    	ioctlsocket(hSocket, FIONBIO, &argp);
    	
    	//- connect to server (scope)
    	if (result == SOCKET_ERROR)
    	{
    		sprintf(tmpStr, "Unable to make connection to IP:%s", ip_address);
    		throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    										tmpStr,
    										"SocketLecroy::TCP_Connect( ).");
    	}
    
    	sConnectedFlag = true;
    }
    
    
    //- DisconnectFromScope: disconnect from a network device
    void SocketLecroy::TCP_Disconnect(void) 
    {
    	if (sConnectedFlag)
    	{
    		closesocket(hSocket);
    		sConnectedFlag = FALSE;
    	}
    }
    
    //- Clear a connection
    void SocketLecroy::TCP_ClearDevice(void) throw (lecroy::SocketException)
    {
    	if ( !sConnectedFlag )
    		throw lecroy::SocketException("COMMUNICATION_BROKEN", 
    										"Disconnection already done.",
    										"SocketLecroy::TCP_ClearDevice( ).");
    	
    	TCP_Disconnect();
    	TCP_Connect(sCurrentAddress);	
    }
    
    //- Send commands to the remote device
    void SocketLecroy::TCP_WriteDevice(char *buf, int len, bool eoi_flag) throw (lecroy::SocketException)
    {
    TCP_HEADER header;
    int result, bytes_more, bytes_xferd;
    char *idxPtr;
    	
    	//- test connection
    	if ( !sConnectedFlag )
    		throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    										"Device not connected.",
    										"SocketLecroy::TCP_WriteDevice( ).");
    		
    	if (len < CMD_BUF_LEN)
    		strcpy(sCommandBuffer, buf);
    	
    	//- set the header info
    	header.bEOI_Flag = DATA_FLAG;
    	header.bEOI_Flag |= (eoi_flag)? EOI_FLAG:0;
    	header.reserved[0] = 1;
    	header.reserved[1] = 0;
    	header.reserved[2] = 0;
    	header.iLength = htonl(len);
    	
    	//- write the header first
    	if (send(hSocket, (char *) &header, sizeof(TCP_HEADER), 0) != sizeof(TCP_HEADER))
    	{
    		throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    										"Unable to send header info to the server.",
    										"SocketLecroy::TCP_WriteDevice( ).");
    	}
    	
    	bytes_more = len;
    	idxPtr = buf;
    	bytes_xferd = 0;
    	while (1)
    	{
    		//- then write the rest of the block
    		idxPtr = buf + bytes_xferd;	
    		
    		if ((result = send(hSocket, (char *) idxPtr, bytes_more, 0)) < 0)
    		{
    			throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    											"Unable to send data to the server.",
    											"SocketLecroy::TCP_WriteDevice( ).");
    		}
    		
    		bytes_xferd += result;
    		bytes_more -= result;
    		if (bytes_more <= 0)
    			break;
    	}
    }
    
    //- Read the device answer
    void SocketLecroy::TCP_ReadDevice(char *buf, int len, int *recv_count) throw (lecroy::SocketException)
    {
    TCP_HEADER header;
    int result, accum, space_left, bytes_more, buf_count;
    char tmpStr[256];
    char *idxPtr;
    fd_set rd_set = {1, {0}};
    TIMEVAL tval;
    	
    	//- test connection
    	if ( !sConnectedFlag )
    		throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    										"Device not connected.",
    										"SocketLecroy::TCP_ReadDevice( ).");
    	
    	*recv_count = 0;
    	
    	if (!buf)
    		throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    										"Buffer memory not allocated.",
    										"SocketLecroy::TCP_ReadDevice( ).");
    	
    	rd_set.fd_array[0] = hSocket;
    	tval.tv_sec = sTimeout;
    	tval.tv_usec = 0;	
    	
    	::memset(buf, 0, len);
    	buf_count = 0;
    	space_left = len;
    		
    	while (1)
    	{
    		result = select(hSocket, &rd_set, NULL, NULL, &tval);
    		if ( !result || result == SOCKET_ERROR)
    		{
    			TCP_ClearDevice();
    			throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    											"Read Timeout.",
    											"SocketLecroy::TCP_ReadDevice( ).");
    		}
    		//- get the header info first
    		accum = 0;
    		while (1)
    		{
    			::memset(&header, 0, sizeof(TCP_HEADER));
    			if ( (result = recv(hSocket, (char *) &header + accum, sizeof(header) - accum, 0)) < 0 )
    			{
    				TCP_ClearDevice();
    				throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    												"Unable to receive header info from the server.",
    												"SocketLecroy::TCP_ReadDevice( ).");
    			}
    			
    			accum += result;
    			if (accum>=sizeof(header))
    				break;
    		}
    	
    		header.iLength = ntohl(header.iLength);
    //		if (header.iLength < 1)
    //			return 0;
    	
    		//- only read to len amount
    		if ( header.iLength > space_left )
    		{
    			header.iLength = space_left;
    			throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    											"Read buffer size is too small.",
    											"SocketLecroy::TCP_ReadDevice( ).");
    		}
    	
    		//- read the rest of the block
    		accum = 0;
    		while (1)
    		{
    			idxPtr = buf + (buf_count + accum);
    			bytes_more = header.iLength - accum;
    			if ((space_left-accum) < TCP_MINIMUM_PACKET_SIZE)
    			{
    				TCP_ClearDevice();
    				sprintf(tmpStr, "Read buffer needs to be adjusted, must be minimum of %d bytes", TCP_MINIMUM_PACKET_SIZE);
    				throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    												tmpStr,
    												"SocketLecroy::TCP_ReadDevice( ).");
    			}
    			
    			if ( (result = recv(hSocket, (char *) idxPtr, (bytes_more>2048)?2048:bytes_more, 0)) < 0 )
    			{
    				TCP_ClearDevice();
    				//-MessageBox(0, "Unable to receive data from the server.", "ERROR", MB_OK);
    				throw lecroy::SocketException("COMMUNICATION_BROKEN ", 
    												"Unable to receive data from the server",
    												"SocketLecroy::TCP_ReadDevice( ).");
    			}
    
    			accum += result;
    			if (accum >= header.iLength)
    				break;
    			if ((accum + buf_count) >= len)
    				break;
    		}
    		buf_count += accum;
    		space_left -= accum;
    		
    		if (header.bEOI_Flag & EOI_FLAG)
    			break;
    		if (space_left <= 0)
    			break;
    	}
    	
    	*recv_count = buf_count;
    }