Example #1
0
static int scpi_vxi_send(void *priv, const char *command)
{
	struct scpi_vxi *vxi = priv;
	Device_WriteResp *write_resp;
	Device_WriteParms write_parms;
	char *terminated_command;
	unsigned int len;

	terminated_command = g_strdup_printf("%s\r\n", command);
	len = strlen(terminated_command);

	write_parms.lid           = vxi->link;
	write_parms.io_timeout    = VXI_DEFAULT_TIMEOUT;
	write_parms.lock_timeout  = VXI_DEFAULT_TIMEOUT;
	write_parms.flags         = DF_END;
	write_parms.data.data_len = MIN(len, vxi->max_send_size);
	write_parms.data.data_val = terminated_command;

	if (!(write_resp = device_write_1(&write_parms, vxi->client))
	    || write_resp->error) {
		sr_err("Device write failed for %s with error %d",
		       vxi->address, write_resp ? write_resp->error : 0);
		return SR_ERR;
	}

	g_free(terminated_command);

	if (write_resp->size < len)
		sr_dbg("Only sent %d/%d bytes of SCPI command: '%s'.",
		       write_resp->size, len, command);
	else
		sr_spew("Successfully sent SCPI command: '%s'.", command);

	return SR_OK;
}
Example #2
0
static int scpi_vxi_send(void *priv, const char *command)
{
	struct scpi_vxi *vxi = priv;
	Device_WriteResp *write_resp;
	Device_WriteParms write_parms;
	unsigned long len;

	len = strlen(command);

	write_parms.lid           = vxi->link;
	write_parms.io_timeout    = VXI_DEFAULT_TIMEOUT_MS;
	write_parms.lock_timeout  = VXI_DEFAULT_TIMEOUT_MS;
	write_parms.flags         = DF_END;
	write_parms.data.data_len = MIN(len, vxi->max_send_size);
	write_parms.data.data_val = (char *)command;

	if (!(write_resp = device_write_1(&write_parms, vxi->client))
	    || write_resp->error) {
		sr_err("Device write failed for %s with error %ld",
		       vxi->address, write_resp ? write_resp->error : 0);
		return SR_ERR;
	}

	if (write_resp->size < len)
		sr_dbg("Only sent %lu/%lu bytes of SCPI command: '%s'.",
		       write_resp->size, len, command);
	else
		sr_spew("Successfully sent SCPI command: '%s'.", command);

	return SR_OK;
}
Example #3
0
int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd, unsigned long len) {
  Device_WriteParms write_parms;
  int	bytes_left = (int)len;
  char	*send_cmd;
  
  send_cmd = new char[len];
  memcpy(send_cmd, cmd, len);
  
  write_parms.lid			= link->lid;
  write_parms.io_timeout		= VXI11_DEFAULT_TIMEOUT;
  write_parms.lock_timeout	= VXI11_DEFAULT_TIMEOUT;
  
  /* We can only write (link->maxRecvSize) bytes at a time, so we sit in a loop,
   * writing a chunk at a time, until we're done. */
  
  do {
    Device_WriteResp write_resp;
    memset(&write_resp, 0, sizeof(write_resp));
    
    if ((unsigned int)bytes_left <= link->maxRecvSize) {
      write_parms.flags		= 8;
      write_parms.data.data_len	= bytes_left;
    }
    else {
      write_parms.flags		= 0;
      /* We need to check that maxRecvSize is a sane value (ie >0). Believe it
       * or not, on some versions of Agilent Infiniium scope firmware the scope
       * returned "0", which breaks Rule B.6.3 of the VXI-11 protocol. Nevertheless
       * we need to catch this, otherwise the program just hangs. */
      if (link->maxRecvSize > 0) {
        write_parms.data.data_len	= link->maxRecvSize;
      }
      else {
        write_parms.data.data_len	= 4096; /* pretty much anything should be able to cope with 4kB */
      }
    }
    write_parms.data.data_val	= send_cmd + (len - bytes_left);
    
    if(device_write_1(&write_parms, &write_resp, client) != RPC_SUCCESS) {
      delete[] send_cmd;
      return -VXI11_NULL_WRITE_RESP; /* The instrument did not acknowledge the write, just completely
                                        dropped it. There was no vxi11 comms error as such, the 
                                        instrument is just being rude. Usually occurs when the instrument
                                        is busy. If we don't check this first, then the following 
                                        line causes a seg fault */
    }
    if (write_resp . error != 0) {
      printf("vxi11_user: write error: %d\n",(int)(write_resp . error));
      delete[] send_cmd;
      return -(write_resp . error);
    }
    bytes_left -= write_resp . size;
  } while (bytes_left > 0);
  
  delete[] send_cmd;
  return 0;
}
Example #4
0
int	vxi11_close_link_client(const char *inputip, CLIENT *client, VXI11_LINK *link) {
Device_Error dev_error;
#ifdef __APPLE__
	char ip[strlen(inputip)];
	strcpy(ip, inputip);
#else
	const char *ip = inputip;
#endif


	memset(&dev_error, 0, sizeof(dev_error)); 

#ifdef __APPLE__
	if (destroy_link_1(&link->lid, client) == NULL) {
#else
	if (destroy_link_1(&link->lid, &dev_error, client) != RPC_SUCCESS) {
#endif
		clnt_perror(client,ip);
		return -1;
		}

	return 0;
	}


/* SEND FUNCTIONS *
 * ============== */

/* A _lot_ of the time we are sending text strings, and can safely rely on
 * strlen(cmd). */
int	vxi11_send_client(CLIENT *client, VXI11_LINK *link, const char *cmd) {
	return vxi11_send_data_client(client, link, cmd, strlen(cmd));
	}

/* We still need the version of the function where the length is set explicitly
 * though, for when we are sending fixed length data blocks. */
int	vxi11_send_data_client(CLIENT *client, VXI11_LINK *link, const char *cmd, unsigned long len) {
Device_WriteParms write_parms;
unsigned int	bytes_left = len;
char	*send_cmd;

	send_cmd = (char *)malloc(len);
	memcpy(send_cmd, cmd, len);

	write_parms.lid			= link->lid;
	write_parms.io_timeout		= VXI11_DEFAULT_TIMEOUT;
	write_parms.lock_timeout	= VXI11_DEFAULT_TIMEOUT;

/* We can only write (link->maxRecvSize) bytes at a time, so we sit in a loop,
 * writing a chunk at a time, until we're done. */

	do {
		Device_WriteResp write_resp;
		memset(&write_resp, 0, sizeof(write_resp));

		if (bytes_left <= link->maxRecvSize) {
			write_parms.flags		= 8;
			write_parms.data.data_len	= bytes_left;
			}
		else {
			write_parms.flags		= 0;
			/* We need to check that maxRecvSize is a sane value (ie >0). Believe it
			 * or not, on some versions of Agilent Infiniium scope firmware the scope
			 * returned "0", which breaks Rule B.6.3 of the VXI-11 protocol. Nevertheless
			 * we need to catch this, otherwise the program just hangs. */
			if (link->maxRecvSize > 0) {
				write_parms.data.data_len	= link->maxRecvSize;
				}
			else {
				write_parms.data.data_len	= 4096; /* pretty much anything should be able to cope with 4kB */
				}
			}
		write_parms.data.data_val	= send_cmd + (len - bytes_left);
		
#ifdef __APPLE__
		Device_WriteResp *tmp;
		if((tmp = device_write_1(&write_parms, client)) == NULL) {
#else
		if(device_write_1(&write_parms, &write_resp, client) != RPC_SUCCESS) {
#endif
			free(send_cmd);
			return -VXI11_NULL_WRITE_RESP; /* The instrument did not acknowledge the write, just completely
							  dropped it. There was no vxi11 comms error as such, the 
							  instrument is just being rude. Usually occurs when the instrument
							  is busy. If we don't check this first, then the following 
							  line causes a seg fault */
			}
#ifdef __APPLE__
		memcpy(&write_resp, tmp, sizeof(*tmp));
#endif
		if (write_resp.error != 0) {
			printf("vxi11_user: write error: %d\n", (int)write_resp.error);
			free(send_cmd);
			return -(write_resp.error);
			}
		bytes_left -= write_resp.size;
		} while (bytes_left > 0);

	free(send_cmd);
	return 0;
	}


/* RECEIVE FUNCTIONS *
 * ================= */

// It appeared that this function wasn't correctly dealing with more data available than specified in len.
// This patch attempts to fix this issue.	RDP 2007/8/13

/* wrapper, for default timeout */ 
long	vxi11_receive_client(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len) { 
	return vxi11_receive_timeout_client(client, link, buffer, len, VXI11_READ_TIMEOUT);
}

#define RCV_END_BIT	0x04	// An end indicator has been read
#define RCV_CHR_BIT	0x02	// A termchr is set in flags and a character which matches termChar is transferred
#define RCV_REQCNT_BIT	0x01	// requestSize bytes have been transferred.  This includes a request size of zero.

long	vxi11_receive_timeout_client(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len, unsigned long timeout) {
Device_ReadParms read_parms;
Device_ReadResp  read_resp;
unsigned long	curr_pos = 0;

	read_parms.lid			= link->lid;
	read_parms.requestSize		= len;
	read_parms.io_timeout		= timeout;	/* in ms */
	read_parms.lock_timeout		= timeout;	/* in ms */
	read_parms.flags		= 0;
	read_parms.termChar		= 0;

	do {
                memset(&read_resp, 0, sizeof(read_resp));

		read_parms.requestSize = len    - curr_pos;	// Never request more total data than originally specified in len

#ifdef __APPLE__
		Device_ReadResp *tmp;
		if((tmp = device_read_1(&read_parms, client)) == NULL) {
#else
		read_resp.data.data_val = buffer + curr_pos;
		if(device_read_1(&read_parms, &read_resp, client) != RPC_SUCCESS) {
#endif
			return -VXI11_NULL_READ_RESP; /* there is nothing to read. Usually occurs after sending a query
							 which times out on the instrument. If we don't check this first,
							 then the following line causes a seg fault */
			}
#ifdef __APPLE__
		memcpy(&read_resp, tmp, sizeof(*tmp));
                memcpy(buffer + curr_pos, read_resp.data.data_val, read_resp.data.data_len);
#endif
 		if (read_resp.error != 0) {
			/* Read failed for reason specified in error code.
			*  (From published VXI-11 protocol, section B.5.2)
			*  0	no error
			*  1	syntax error
			*  3	device not accessible
			*  4	invalid link identifier
			*  5	parameter error
			*  6	channel not established
			*  8	operation not supported
			*  9	out of resources
			*  11	device locked by another link
			*  12	no lock held by this link
			*  15	I/O timeout
			*  17	I/O error
			*  21	invalid address
			*  23	abort
			*  29	channel already established
			*/

			printf("vxi11_user: read error: %d\n", (int)read_resp.error);
			return -(read_resp.error);
			}

		if((curr_pos + read_resp.data.data_len) <= len) {
			curr_pos += read_resp.data.data_len;
			}
		if( (read_resp.reason & RCV_END_BIT) || (read_resp.reason & RCV_CHR_BIT) ) {
			break;
			}
		else if( curr_pos == len ) {
			printf("xvi11_user: read error: buffer too small. Read %d bytes without hitting terminator.\n", (int)curr_pos );
			return -100;
			}
		} while(1);
	return (curr_pos); /*actual number of bytes received*/

	}
Example #5
0
int vxi11_send(VXI11_CLINK * clink, const char *cmd, size_t len)
{
#ifdef WIN32
	ViStatus status;
	char buf[256];
	unsigned char *send_cmd;
#else
	Device_WriteParms write_parms;
	char *send_cmd;
#endif
	size_t bytes_left = len;
	ssize_t write_count;

#ifdef WIN32
	send_cmd = (unsigned char *)malloc(len);
	if (!send_cmd) {
		return 1;
	}
	memcpy(send_cmd, cmd, len);

	while (bytes_left > 0) {
		status =
		    viWrite(clink->session, send_cmd + (len - bytes_left),
			    bytes_left, &write_count);
		if (status == VI_SUCCESS) {
			bytes_left -= write_count;
		} else {
			free(send_cmd);
			viStatusDesc(clink->session, status, buf);
			printf("%s\n", buf);
			return status;
		}
	}
#else
	send_cmd = (char *)malloc(len);
	if (!send_cmd) {
		return 1;
	}
	memcpy(send_cmd, cmd, len);

	write_parms.lid = clink->link->lid;
	write_parms.io_timeout = VXI11_DEFAULT_TIMEOUT;
	write_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT;

/* We can only write (link->maxRecvSize) bytes at a time, so we sit in a loop,
 * writing a chunk at a time, until we're done. */

	do {
		Device_WriteResp write_resp;
		memset(&write_resp, 0, sizeof(write_resp));

		if (bytes_left <= clink->link->maxRecvSize) {
			write_parms.flags = 8;
			write_parms.data.data_len = bytes_left;
		} else {
			write_parms.flags = 0;
			/* We need to check that maxRecvSize is a sane value (ie >0). Believe it
			 * or not, on some versions of Agilent Infiniium scope firmware the scope
			 * returned "0", which breaks Rule B.6.3 of the VXI-11 protocol. Nevertheless
			 * we need to catch this, otherwise the program just hangs. */
			if (clink->link->maxRecvSize > 0) {
				write_parms.data.data_len =
				    clink->link->maxRecvSize;
			} else {
				write_parms.data.data_len = 4096;	/* pretty much anything should be able to cope with 4kB */
			}
		}
		write_parms.data.data_val = send_cmd + (len - bytes_left);

		if (device_write_1(&write_parms, &write_resp, clink->client) !=
		    RPC_SUCCESS) {
			free(send_cmd);
			return -VXI11_NULL_WRITE_RESP;	/* The instrument did not acknowledge the write, just completely
							   dropped it. There was no vxi11 comms error as such, the 
							   instrument is just being rude. Usually occurs when the instrument
							   is busy. If we don't check this first, then the following 
							   line causes a seg fault */
		}
		if (write_resp.error != 0) {
			printf("vxi11_user: write error: %d\n",
			       (int)write_resp.error);
			free(send_cmd);
			return -(write_resp.error);
		}
		bytes_left -= write_resp.size;
	} while (bytes_left > 0);
#endif
	free(send_cmd);

	return 0;
}
Example #6
0
void
device_core_1(char *host)
{
	CLIENT *clnt;
	Create_LinkResp  *result_1;
	Create_LinkParms  create_link_1_arg;
	Device_WriteResp  *result_2;
	Device_WriteParms  device_write_1_arg;
	Device_ReadResp  *result_3;
	Device_ReadParms  device_read_1_arg;
	Device_ReadStbResp  *result_4;
	Device_GenericParms  device_readstb_1_arg;
	Device_Error  *result_5;
	Device_GenericParms  device_trigger_1_arg;
	Device_Error  *result_6;
	Device_GenericParms  device_clear_1_arg;
	Device_Error  *result_7;
	Device_GenericParms  device_remote_1_arg;
	Device_Error  *result_8;
	Device_GenericParms  device_local_1_arg;
	Device_Error  *result_9;
	Device_LockParms  device_lock_1_arg;
	Device_Error  *result_10;
	Device_Link  device_unlock_1_arg;
	Device_Error  *result_11;
	Device_EnableSrqParms  device_enable_srq_1_arg;
	Device_DocmdResp  *result_12;
	Device_DocmdParms  device_docmd_1_arg;
	Device_Error  *result_13;
	Device_Link  destroy_link_1_arg;
	Device_Error  *result_14;
	Device_RemoteFunc  create_intr_chan_1_arg;
	Device_Error  *result_15;
	char *destroy_intr_chan_1_arg;

#ifndef	DEBUG
	clnt = clnt_create (host, DEVICE_CORE, DEVICE_CORE_VERSION, "udp");
	if (clnt == NULL) {
		clnt_pcreateerror (host);
		exit (1);
	}
#endif	/* DEBUG */

	result_1 = create_link_1(&create_link_1_arg, clnt);
	if (result_1 == (Create_LinkResp *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_2 = device_write_1(&device_write_1_arg, clnt);
	if (result_2 == (Device_WriteResp *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_3 = device_read_1(&device_read_1_arg, clnt);
	if (result_3 == (Device_ReadResp *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_4 = device_readstb_1(&device_readstb_1_arg, clnt);
	if (result_4 == (Device_ReadStbResp *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_5 = device_trigger_1(&device_trigger_1_arg, clnt);
	if (result_5 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_6 = device_clear_1(&device_clear_1_arg, clnt);
	if (result_6 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_7 = device_remote_1(&device_remote_1_arg, clnt);
	if (result_7 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_8 = device_local_1(&device_local_1_arg, clnt);
	if (result_8 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_9 = device_lock_1(&device_lock_1_arg, clnt);
	if (result_9 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_10 = device_unlock_1(&device_unlock_1_arg, clnt);
	if (result_10 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_11 = device_enable_srq_1(&device_enable_srq_1_arg, clnt);
	if (result_11 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_12 = device_docmd_1(&device_docmd_1_arg, clnt);
	if (result_12 == (Device_DocmdResp *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_13 = destroy_link_1(&destroy_link_1_arg, clnt);
	if (result_13 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_14 = create_intr_chan_1(&create_intr_chan_1_arg, clnt);
	if (result_14 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
	result_15 = destroy_intr_chan_1((void*)&destroy_intr_chan_1_arg, clnt);
	if (result_15 == (Device_Error *) NULL) {
		clnt_perror (clnt, "call failed");
	}
#ifndef	DEBUG
	clnt_destroy (clnt);
#endif	 /* DEBUG */
}