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; }
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; }
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; }
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*/ }
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; }
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 */ }