Skip to content
Snippets Groups Projects
Select Git revision
  • main
  • SCAN-820
  • 4.0
  • v3.8.10
  • v3.8.9
  • v3.8.8
  • v3.8.7
  • v3.8.6
  • v3.8.5
  • v3.8.4
  • v3.8.3
  • v3.8.2
  • Salsa-3.8.1
  • Salsa-3.8.0
  • Salsa-3.7.0
  • Salsa-3.6.4
  • Salsa-3.6.3
  • Salsa-3.6.2
  • Salsa-3.6.1
  • Salsa-3.5.32
  • Salsa-3.5.30
  • Salsa-3.5.25
  • Salsa-3.5.24
23 results

pom.xml

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    LinuxSocketLecroy.cpp 10.94 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.
    //
    //******************************************************************************************
    
    
    //- INCLUDE
    #include <iostream>
    #include "SocketLecroy.h"
    #include <sys/time.h>
    #include <time.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/ioctl.h>
    #include <netinet/in.h>
    #include <netinet/tcp.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdio.h>
    
    #include <sys/select.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <cstdio>
    
    static int  hSocket;
    static int  sTimeout = 1;       //- second(s)
    static char sCurrentAddress[256];
    static int  sConnectedFlag = false;
    
    const int CMD_BUF_LEN = 8192;
    static char   sCommandBuffer[CMD_BUF_LEN];
    
    //- 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)
    {
      struct sockaddr_in serverAddr;
      int result;
      const int resp = 1;
      fd_set wr_set;
      FD_ZERO(&wr_set);
    
      struct 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)) == -1) //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( ).");
      }
    
      FD_SET(hSocket, &wr_set);
      argp = 1;//-non blocking mode
      ioctl(hSocket, FIONBIO, &argp);
    
      int opts;
      opts = fcntl (hSocket, F_GETFL);
      if (opts >= 0)
        opts = (opts | O_NONBLOCK);
      fcntl (hSocket, F_SETFL, opts);
      //connect(hSocket, (SOCKADDR FAR *) &serverAddr, sockAddrSize);
      int status = ::connect(hSocket, ( sockaddr *)&serverAddr, sizeof(serverAddr));
    
      if(status < 0)  // We are not connected : so retry
      {
        if(errno == EINPROGRESS) // But the connection is in progress
        {
          int nb = 0;
          struct timespec time_to_sleep, time_remaining;
    
          while(nb++ < 5) // We will attempt to connect every 100 ms for 5 times max.
          {
            status = ::connect (hSocket, ( sockaddr *)&serverAddr, sizeof(serverAddr));
    
            if(status != 0) // Still not connected
            {
              if(errno == EALREADY) // This is the right error !
              {
                time_to_sleep.tv_sec = 0;
                time_to_sleep.tv_nsec = 15000000L;
                nanosleep(&time_to_sleep, &time_remaining);  // Sleep for 150 ms
              }
            }// Connection is OK.
            else
              break;
          }//TODO : throw ; // Too much attempts, so failure !
        }// TODO : throw ; // Not the right error, so failure !
      }// Connected at first attempt !
    
    
      result = select(hSocket, NULL, &wr_set, NULL, &tval);
      argp = 0;//-blocking mode
      ioctl(hSocket, FIONBIO, &argp);
      //- connect to server (scope)
      if (result < 0)
      {
        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) throw (lecroy::SocketException)
    {
      if (sConnectedFlag)
      {
        close(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;
      unsigned int accum, space_left, bytes_more, buf_count;
      char tmpStr[256];
      char *idxPtr;
      fd_set rd_set;
      FD_ZERO(&rd_set);
      struct 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( ).");
    
      FD_SET(hSocket, &rd_set);
      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 < 0)
        {
          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);
    
        //- 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;
    }