SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
agilentwaveform2sdds.cpp File Reference

Detailed Description

Capture and save waveform data from Agilent oscilloscopes to SDDS format.

This program communicates with Agilent oscilloscopes over Ethernet using the VXI-11 protocol. It retrieves waveform data and saves it in the SDDS (Self Describing Data Set) format. Users can specify the IP address, output filename, and the channel to capture data from. Additional options allow customization of timeout, sample rate, acquisition points, and averaging parameters.

Usage

./agilentwaveform2sdds -ip <ip_address>
-f <output_file>
-c <scope_channel>
[-t <milliseconds>]
[-s <sample_rate>]
[-n <points>]
[-a <num_to_average>]

Options

Required Description
-ip IP address of the oscilloscope (e.g., 128.243.74.232).
-f Filename (without extension) for saving the waveform data.
-c Scope channel to capture data from (e.g., 1, 2, A, B).
Optional Description
-t Timeout duration in milliseconds (default: 10000 ms).
-s Set the sample rate (e.g., 1e9 for 1 GS/s).
-n Minimum number of acquisition points.
-a Number to average (use <=0 for none).

Incompatibilities

  • -s (sample rate) and -n (number of points) are mutually dependent:
    • If neither is specified, defaults are used.
    • If one is specified, the other is calculated based on time range.
  • -t must be a positive value and defaults to 10000 ms if not set.

Requirements

  • The -c argument must correspond to valid channels recognized by the oscilloscope.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
Based on software by Steve Sharples, Univ. of Nottingham. Modified by R. Soliday and N. Kuklev.

Definition in file agilentwaveform2sdds.cpp.

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <memory>
#include <rpc/rpc.h>
#include <pthread.h>
#include "SDDS.h"

Go to the source code of this file.

Functions

bool sc (const char *con, const char *var)
 
int agilent_init (CLINK *clink)
 
int agilent_set_averages (CLINK *clink, int no_averages)
 
void agilent_set_for_auto (CLINK *clink)
 
long agilent_get_data (CLINK *clink, char chan, char *buf, unsigned long buf_len, unsigned long timeout)
 
long agilent_get_data (CLINK *clink, char chan, int digitise, char *buf, unsigned long buf_len, unsigned long timeout)
 
int agilent_get_preamble (CLINK *clink, char *buf, unsigned long buf_len)
 
void agilent_scope_channel_str (char chan, char *source)
 
int agilent_set_for_capture (CLINK *clink, double s_rate, long npoints, unsigned long timeout)
 
long agilent_calculate_no_of_bytes (CLINK *clink, char chan, unsigned long timeout)
 
int vxi11_open_device (const char *ip, CLINK *clink)
 
int vxi11_open_device (const char *ip, CLINK *clink, char *device)
 
int vxi11_open_device (const char *ip, CLIENT **client, VXI11_LINK **link, char *device)
 
int vxi11_open_link (const char *ip, CLIENT **client, VXI11_LINK **link, char *device)
 
int vxi11_send (CLINK *clink, const char *cmd)
 
int vxi11_send (CLINK *clink, const char *cmd, unsigned long len)
 
int vxi11_send (CLIENT *client, VXI11_LINK *link, const char *cmd)
 
int vxi11_send (CLIENT *client, VXI11_LINK *link, const char *cmd, unsigned long len)
 
int vxi11_close_device (const char *ip, CLINK *clink)
 
int vxi11_close_device (const char *ip, CLIENT *client, VXI11_LINK *link)
 
int vxi11_close_link (const char *ip, CLIENT *client, VXI11_LINK *link)
 
double vxi11_obtain_double_value (CLINK *clink, const char *cmd)
 
double vxi11_obtain_double_value (CLINK *clink, const char *cmd, unsigned long timeout)
 
long vxi11_send_and_receive (CLINK *clink, const char *cmd, char *buf, unsigned long buf_len, unsigned long timeout)
 
long vxi11_receive (CLINK *clink, char *buffer, unsigned long len)
 
long vxi11_receive (CLINK *clink, char *buffer, unsigned long len, unsigned long timeout)
 
long vxi11_obtain_long_value (CLINK *clink, const char *cmd, unsigned long timeout)
 
long vxi11_obtain_long_value (CLINK *clink, const char *cmd)
 
long vxi11_receive_data_block (CLINK *clink, char *buffer, unsigned long len, unsigned long timeout)
 
enum clnt_stat create_link_1 (Create_LinkParms *argp, Create_LinkResp *clnt_res, CLIENT *clnt)
 
enum clnt_stat device_write_1 (Device_WriteParms *argp, Device_WriteResp *clnt_res, CLIENT *clnt)
 
enum clnt_stat destroy_link_1 (Device_Link *argp, Device_Error *clnt_res, CLIENT *clnt)
 
enum clnt_stat device_read_1 (Device_ReadParms *argp, Device_ReadResp *clnt_res, CLIENT *clnt)
 
bool_t xdr_Create_LinkParms (XDR *xdrs, Create_LinkParms *objp)
 
bool_t xdr_Create_LinkResp (XDR *xdrs, Create_LinkResp *objp)
 
bool_t xdr_Device_ErrorCode (XDR *xdrs, Device_ErrorCode *objp)
 
bool_t xdr_Device_Link (XDR *xdrs, Device_Link *objp)
 
bool_t xdr_Device_WriteParms (XDR *xdrs, Device_WriteParms *objp)
 
bool_t xdr_Device_WriteResp (XDR *xdrs, Device_WriteResp *objp)
 
bool_t xdr_Device_Flags (XDR *xdrs, Device_Flags *objp)
 
bool_t xdr_Device_Error (XDR *xdrs, Device_Error *objp)
 
bool_t xdr_Device_ReadParms (XDR *xdrs, Device_ReadParms *objp)
 
bool_t xdr_Device_ReadResp (XDR *xdrs, Device_ReadResp *objp)
 
int main (int argc, char **argv)
 
long vxi11_receive (CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len, unsigned long timeout)
 

Function Documentation

◆ agilent_calculate_no_of_bytes()

long agilent_calculate_no_of_bytes ( CLINK * clink,
char chan,
unsigned long timeout )

Definition at line 1323 of file agilentwaveform2sdds.cpp.

1326 {
1327 char cmd[256] = {0};
1328 char source[20] = {0};
1329 double hinterval = 0.0, time_range = 0.0;
1330 double srat = 0.0;
1331 long no_of_bytes = 0;
1332 char etim_result[256] = {0};
1333
1334 // First we need to digitize, to get the correct values for the
1335 // waveform data. This is a pain in the ass.
1336 agilent_scope_channel_str(chan, source);
1337 std::snprintf(cmd, sizeof(cmd), ":WAV:SOURCE %s", source);
1338 vxi11_send(clink, cmd);
1339 vxi11_send(clink, ":DIG");
1340
1341 /* Now find the info we need to calculate the number of points */
1342 hinterval = vxi11_obtain_double_value(clink, ":WAV:XINC?", timeout);
1343 time_range = vxi11_obtain_double_value(clink, ":TIM:RANGE?");
1344
1345 /* Are we in equivalent time (ETIM) mode? If so, the value of ACQ:SRAT will
1346 * be meaningless, and there's a different formula */
1347 vxi11_send_and_receive(clink, ":ACQ:MODE?", etim_result, sizeof(etim_result), VXI11_READ_TIMEOUT);
1348 /* Equivalent time (ETIM) mode: */
1349 if (std::strncmp("ETIM", etim_result, 4) == 0) {
1350 no_of_bytes = static_cast<long>(2 * ((time_range / hinterval) + 0.5));
1351 } else {
1352 srat = vxi11_obtain_double_value(clink, ":ACQ:SRAT?");
1353
1354 no_of_bytes = static_cast<long>(2 * (((time_range - (1 / srat)) / hinterval) + 1) + 0.5);
1355 /* 2x because 2 bytes per data point
1356 * +0.5 to round up when casting as a long
1357 * -(1/srat) and +1 so that both raw data, and interpolated (sinx/x) data works */

◆ agilent_get_data() [1/2]

long agilent_get_data ( CLINK * clink,
char chan,
char * buf,
unsigned long buf_len,
unsigned long timeout )

Definition at line 1017 of file agilentwaveform2sdds.cpp.

◆ agilent_get_data() [2/2]

long agilent_get_data ( CLINK * clink,
char chan,
int digitise,
char * buf,
unsigned long buf_len,
unsigned long timeout )

Definition at line 1021 of file agilentwaveform2sdds.cpp.

1024 {
1025 char source[20] = {0};
1026 char cmd[256] = {0};
1027 int ret = 0;
1028 long bytes_returned = 0;
1029
1030 agilent_scope_channel_str(chan, source);
1031 std::snprintf(cmd, sizeof(cmd), ":WAV:SOURCE %s", source);
1032 ret = vxi11_send(clink, cmd);
1033 if (ret < 0) {
1034 std::fprintf(stderr, "Error: Could not send ':WAV:SOURCE %s' command.\n", source);
1035 return ret;
1036 }
1037
1038 if (digitise != 0) {
1039 ret = vxi11_send(clink, ":DIG");
1040 if (ret < 0) {
1041 std::fprintf(stderr, "Warning: Failed to digitize.\n");
1042 }
1043 }
1044
1045 do {
1046 ret = vxi11_send(clink, ":WAV:DATA?");
1047 if (ret < 0) {
1048 std::fprintf(stderr, "Warning: Failed to send ':WAV:DATA?' command.\n");
1049 return ret;
1050 }
1051 bytes_returned = vxi11_receive_data_block(clink, buf, buf_len, timeout);
1052 } while (bytes_returned == -VXI11_NULL_READ_RESP);
1053 /* We have to check for this after a :DIG because it could take a very long time */
1054 /* We should probably handle ret, but keeping it consistent with original code */

◆ agilent_get_preamble()

int agilent_get_preamble ( CLINK * clink,
char * buf,
unsigned long buf_len )

Definition at line 1056 of file agilentwaveform2sdds.cpp.

1059 {
1060 int ret;
1061 long bytes_returned;
1062
1063 ret = vxi11_send(clink, ":WAV:PRE?");
1064 if (ret < 0) {
1065 std::fprintf(stderr, "Error: Could not send ':WAV:PRE?' command.\n");
1066 return ret;
1067 }
1068
1069 bytes_returned = vxi11_receive(clink, buf, buf_len);

◆ agilent_init()

int agilent_init ( CLINK * clink)

Definition at line 610 of file agilentwaveform2sdds.cpp.

613 {
614 int ret;
615 ret = vxi11_send(clink, ":SYSTEM:HEADER 0");
616 if (ret < 0) {
617 std::fprintf(stderr, "Error: Could not send ':SYSTEM:HEADER 0' command.\n");
618 return ret;
619 }
620 vxi11_send(clink, ":ACQUIRE:COMPLETE 100");
621 if (SDDS_IsBigEndianMachine() == 0) {
622 vxi11_send(clink, ":WAVEFORM:BYTEORDER LSBFIRST");
623 } else {
624 vxi11_send(clink, ":WAVEFORM:BYTEORDER MSBFIRST");
625 }
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.

◆ agilent_scope_channel_str()

void agilent_scope_channel_str ( char chan,
char * source )

Definition at line 1071 of file agilentwaveform2sdds.cpp.

1074 {
1075 switch (chan) {
1076 case 'A':
1077 case 'a':
1078 std::strcpy(source, "FUNC1");
1079 break;
1080 case 'B':
1081 case 'b':
1082 std::strcpy(source, "FUNC2");
1083 break;
1084 case 'C':
1085 case 'c':
1086 std::strcpy(source, "FUNC3");
1087 break;
1088 case 'D':
1089 case 'd':
1090 std::strcpy(source, "FUNC4");
1091 break;
1092 case '1':
1093 std::strcpy(source, "CHAN1");
1094 break;
1095 case '2':
1096 std::strcpy(source, "CHAN2");
1097 break;
1098 case '3':
1099 std::strcpy(source, "CHAN3");
1100 break;
1101 case '4':
1102 std::strcpy(source, "CHAN4");
1103 break;
1104 default:
1105 std::fprintf(stderr, "Warning: Unknown channel '%c'. Using channel 1.\n", chan);
1106 std::strcpy(source, "CHAN1");

◆ agilent_set_averages()

int agilent_set_averages ( CLINK * clink,
int no_averages )

Definition at line 736 of file agilentwaveform2sdds.cpp.

739 {
740 char cmd[256];
741
742 if (no_averages <= 0) {
743 return vxi11_send(clink, ":ACQ:AVER 0");
744 } else {
745 std::snprintf(cmd, sizeof(cmd), ":ACQ:COUNT %d", no_averages);
746 if (vxi11_send(clink, cmd) != 0) {
747 std::fprintf(stderr, "Warning: Failed to set acquisition count.\n");
748 return -1;
749 }

◆ agilent_set_for_auto()

void agilent_set_for_auto ( CLINK * clink)

Definition at line 751 of file agilentwaveform2sdds.cpp.

◆ agilent_set_for_capture()

int agilent_set_for_capture ( CLINK * clink,
double s_rate,
long npoints,
unsigned long timeout )

Definition at line 1169 of file agilentwaveform2sdds.cpp.

1172 {
1173 long actual_npoints = 0; /* actual number of points returned */
1174 double time_range = 0.0;
1175 double auto_srat = 0.0; /* sample rate whilst on auto setting */
1176 long auto_npoints = 0; /* no of points whilst on auto setting */
1177 double expected_s_rate = 0.0; /* based on s_rate passed to us, or npoints */
1178 double actual_s_rate = 0.0; /* what it ends up as */
1179 double xinc = 0.0; /* xincrement (only need for ETIM mode) */
1180 char cmd[256] = {0};
1181 char etim_result[256] = {0};
1182 int ret_val = 0;
1183 int not_enough_memory = 0;
1184
1185 /* First we need to find out if we're in "ETIM" (equivalent time) mode,
1186 * because things are done differently. You can't set the sample rate,
1187 * and if you query it, you get a meaningless answer. You must work out
1188 * what the effective sample rate is from the waveform xincrement. A
1189 * pain in the ass, quite frankly. */
1190
1191 vxi11_send_and_receive(clink, ":ACQ:MODE?", etim_result, sizeof(etim_result), VXI11_READ_TIMEOUT);
1192
1193 /* Equivalent time (ETIM) mode: */
1194 if (std::strncmp("ETIM", etim_result, 4) == 0) {
1195 /* Find out the time range displayed on the screen */
1196 time_range = vxi11_obtain_double_value(clink, ":TIM:RANGE?");
1197
1198 /* Find the xincrement, whilst we're still in auto (points) mode */
1199 auto_npoints = vxi11_obtain_long_value(clink, ":ACQ:POINTS?");
1200
1201 /* Set the no of acquisition points to manual */
1202 vxi11_send(clink, ":ACQ:POINTS:AUTO 0");
1203
1204 if (npoints <= 0) { // if we've not been passed a value for npoints
1205 npoints = auto_npoints;
1206 }
1207 /* Remember we want at LEAST the number of points specified.
1208 * To some extent, the xinc value is determined by the
1209 * number of points. So to get the best xinc value we ask
1210 * for double what we actually want. */
1211 std::snprintf(cmd, sizeof(cmd), ":ACQ:POINTS %ld", (2 * npoints) - 1);
1212 vxi11_send(clink, cmd);
1213
1214 /* Unfortunately we have to do a :DIG, to make sure our changes have
1215 * been registered */
1216 vxi11_send(clink, ":DIG");
1217
1218 /* Find the xincrement is now*/
1219 xinc = vxi11_obtain_double_value(clink, ":WAV:XINC?", timeout);
1220
1221 /* Work out the number of points there _should_ be to cover the time range */
1222 actual_npoints = static_cast<long>((time_range / xinc) + 0.5);
1223
1224 /* Set the number of points accordingly. Hopefully the
1225 * xincrement won't have changed! */
1226 std::snprintf(cmd, sizeof(cmd), ":ACQ:POINTS %ld", actual_npoints);
1227 vxi11_send(clink, cmd);
1228
1229 /* This is a bit anal... we can work out very easily what the equivalent
1230 * sampling rate is (1 / xinc); the scope seems to store this value
1231 * somewhere, even though it doesn't use it. We may as well write it
1232 * to the scope, in case some user program asks for it while in
1233 * equivalent time mode. Should not be depended upon, though! */
1234
1235 std::snprintf(cmd, sizeof(cmd), ":ACQ:SRAT %G", (1 / xinc));
1236 vxi11_send(clink, cmd);
1237 }
1238
1239 /* Real time (RTIM, NORM or PDET) mode: */
1240 else {
1241 /* First find out what the sample rate is set to.
1242 * Each time you switch from auto to manual for either of these, the
1243 * scope remembers the values from last time you set these manually.
1244 * This is not very useful to us. We want to be able to set either the
1245 * sample rate (and derive npoints from that and the timebase), or the
1246 * minimum number of points (and derive the sample rate) or let
1247 * the scope choose sensible values for both of these. We only want to
1248 * capture the data for the time period displayed on the scope screen,
1249 * which is equal to the time range. If you leave the scope to do
1250 * everything auto, then it always acquires a bit more than what's on
1251 * the screen.
1252 */
1253 auto_srat = vxi11_obtain_double_value(clink, ":ACQ:SRAT?");
1254
1255 /* Set the sample rate (SRAT) and no of acquisition points to manual */
1256 vxi11_send(clink, ":ACQ:SRAT:AUTO 0;:ACQ:POINTS:AUTO 0");
1257
1258 /* Find out the time range displayed on the screen */
1259 time_range = vxi11_obtain_double_value(clink, ":TIM:RANGE?");
1260
1261 /* If we've not been passed a sample rate (ie s_rate <= 0) then... */
1262 if (s_rate <= 0) {
1263 /* ... if we've not been passed npoints, let scope set rate */
1264 if (npoints <= 0) {
1265 s_rate = auto_srat;
1266 }
1267 /* ... otherwise set the sample rate based on no of points. */
1268 else {
1269 s_rate = static_cast<double>(npoints) / time_range;
1270 }
1271 }
1272 /* We make a note here of what we're expecting the sample rate to be.
1273 * If it has to change for any reason (dodgy value, or not enough
1274 * memory) we will know about it.
1275 */
1276 expected_s_rate = s_rate;
1277
1278 /* Now we set the number of points to acquire. Of course, the scope
1279 * may not have enough memory to acquire all the points, so we just
1280 * sit in a loop, reducing the sample rate each time, until it's happy.
1281 */
1282 do {
1283 /* Send scope our desired sample rate. */
1284 std::snprintf(cmd, sizeof(cmd), ":ACQ:SRAT %G", s_rate);
1285 vxi11_send(clink, cmd);
1286 /* Scope will choose next highest allowed rate.
1287 * Find out what this is */
1288 actual_s_rate = vxi11_obtain_double_value(clink, ":ACQ:SRAT?");
1289
1290 /* Calculate the number of points on display (and round up for rounding errors) */
1291 npoints = static_cast<long>((time_range * actual_s_rate) + 0.5);
1292
1293 /* Set the number of points accordingly */
1294 /* Note this won't necessarily be the no of points you receive, eg if you have
1295 * sin(x)/x interpolation turned on, you will probably get more. */
1296 std::snprintf(cmd, sizeof(cmd), ":ACQ:POINTS %ld", npoints);
1297 vxi11_send(clink, cmd);
1298
1299 /* We should do a check, see if there's enough memory */
1300 actual_npoints = vxi11_obtain_long_value(clink, ":ACQ:POINTS?");
1301
1302 if (actual_npoints < npoints) {
1303 not_enough_memory = 1;
1304 ret_val = -1; /* We should report this fact to the calling function */
1305 s_rate = s_rate * 0.75 * (static_cast<double>(actual_npoints) / static_cast<double>(npoints));
1306 } else {
1307 not_enough_memory = 0;
1308 }
1309 } while (not_enough_memory == 1);
1310 /* Will possibly remove the explicit printf's here, maybe leave it up to the
1311 * calling function to spot potential problems (the user may not care!) */
1312 if (actual_s_rate != expected_s_rate) {
1313 // std::printf("Warning: the sampling rate has been adjusted,\n");
1314 // std::printf("from %g to %g, because ", expected_s_rate, actual_s_rate);
1315 if (ret_val == -1) {
1316 // std::printf("there was not enough memory.\n");
1317 } else {
1318 // std::printf("because %g Sa/s is not a valid sample rate.\n", expected_s_rate);
1319 ret_val = -2;
1320 }
1321 }

◆ create_link_1()

enum clnt_stat create_link_1 ( Create_LinkParms * argp,
Create_LinkResp * clnt_res,
CLIENT * clnt )

Definition at line 526 of file agilentwaveform2sdds.cpp.

529 {
530 return clnt_call(clnt, create_link,
531 reinterpret_cast<xdrproc_t>(xdr_Create_LinkParms), reinterpret_cast<caddr_t>(argp),

◆ destroy_link_1()

enum clnt_stat destroy_link_1 ( Device_Link * argp,
Device_Error * clnt_res,
CLIENT * clnt )

Definition at line 811 of file agilentwaveform2sdds.cpp.

814 {
815 return clnt_call(clnt, destroy_link,
816 reinterpret_cast<xdrproc_t>(xdr_Device_Link), reinterpret_cast<caddr_t>(argp),

◆ device_read_1()

enum clnt_stat device_read_1 ( Device_ReadParms * argp,
Device_ReadResp * clnt_res,
CLIENT * clnt )

Definition at line 918 of file agilentwaveform2sdds.cpp.

921 {
922 return clnt_call(clnt, device_read,
923 reinterpret_cast<xdrproc_t>(xdr_Device_ReadParms), reinterpret_cast<caddr_t>(argp),

◆ device_write_1()

enum clnt_stat device_write_1 ( Device_WriteParms * argp,
Device_WriteResp * clnt_res,
CLIENT * clnt )

Definition at line 699 of file agilentwaveform2sdds.cpp.

702 {
703 return clnt_call(clnt, device_write,
704 reinterpret_cast<xdrproc_t>(xdr_Device_WriteParms), reinterpret_cast<caddr_t>(argp),

◆ main()

int main ( int argc,
char ** argv )

Definition at line 211 of file agilentwaveform2sdds.cpp.

214 {
215 const char *progname;
216 const char *serverIP = nullptr;
217 char chnl = '\0'; /* we use '1' to '4' for channels, and 'A' to 'D' for FUNC[1...4] */
218 FILE *f_wf = nullptr;
219 char wfname[256] = {0};
220 long buf_size = 0;
221 char *buf = nullptr;
222 unsigned long timeout = VXI11_DEFAULT_TIMEOUT; /* in ms (= 10 seconds) */
223
224 long bytes_returned = 0;
225 bool got_ip = false;
226 bool got_scope_channel = false;
227 bool got_file = false;
228 bool got_no_averages = false;
229 int no_averages = 0;
230 int index = 1;
231 double s_rate = 0.0;
232 long npoints = 0;
233 double actual_s_rate = 0.0;
234 long actual_npoints = 0;
235 CLINK *clink = nullptr; /* client link (actually a structure containing CLIENT and VXI11_LINK pointers) */
236
237 short val = 0;
238 double vgain = 0.0, voffset = 0.0, hinterval = 0.0, hoffset = 0.0;
239 long i = 0;
240
241 clink = new (std::nothrow) CLINK; /* allocate some memory */
242 if (!clink) {
243 std::fprintf(stderr, "Error: Memory allocation for CLINK failed.\n");
244 return EXIT_FAILURE;
245 }
246
247 progname = argv[0];
248
249 while (index < argc) {
250 if (sc(argv[index], "-filename") || sc(argv[index], "-f") || sc(argv[index], "-file")) {
251 if (index + 1 >= argc) {
252 std::fprintf(stderr, "Error: Missing value for %s.\n", argv[index]);
253 delete clink;
254 return EXIT_FAILURE;
255 }
256 std::snprintf(wfname, sizeof(wfname), "%s.sdds", argv[++index]);
257 got_file = true;
258 continue;
259 }
260
261 if (sc(argv[index], "-ip") || sc(argv[index], "-ip_address") || sc(argv[index], "-IP")) {
262 if (index + 1 >= argc) {
263 std::fprintf(stderr, "Error: Missing value for %s.\n", argv[index]);
264 delete clink;
265 return EXIT_FAILURE;
266 }
267 serverIP = argv[++index];
268 got_ip = true;
269 continue;
270 }
271
272 if (sc(argv[index], "-channel") || sc(argv[index], "-c") || sc(argv[index], "-scope_channel")) {
273 if (index + 1 >= argc) {
274 std::fprintf(stderr, "Error: Missing value for %s.\n", argv[index]);
275 delete clink;
276 return EXIT_FAILURE;
277 }
278 std::sscanf(argv[++index], "%c", &chnl);
279 got_scope_channel = true;
280 continue;
281 }
282
283 if (sc(argv[index], "-sample_rate") || sc(argv[index], "-s") || sc(argv[index], "-rate")) {
284 if (index + 1 >= argc) {
285 std::fprintf(stderr, "Error: Missing value for %s.\n", argv[index]);
286 delete clink;
287 return EXIT_FAILURE;
288 }
289 std::sscanf(argv[++index], "%lg", &s_rate);
290 continue;
291 }
292
293 if (sc(argv[index], "-no_points") || sc(argv[index], "-n") || sc(argv[index], "-points")) {
294 if (index + 1 >= argc) {
295 std::fprintf(stderr, "Error: Missing value for %s.\n", argv[index]);
296 delete clink;
297 return EXIT_FAILURE;
298 }
299 std::sscanf(argv[++index], "%ld", &npoints);
300 continue;
301 }
302
303 if (sc(argv[index], "-averages") || sc(argv[index], "-a") || sc(argv[index], "-aver")) {
304 if (index + 1 >= argc) {
305 std::fprintf(stderr, "Error: Missing value for %s.\n", argv[index]);
306 delete clink;
307 return EXIT_FAILURE;
308 }
309 std::sscanf(argv[++index], "%d", &no_averages);
310 got_no_averages = true;
311 continue;
312 }
313
314 if (sc(argv[index], "-timeout") || sc(argv[index], "-t")) {
315 if (index + 1 >= argc) {
316 std::fprintf(stderr, "Error: Missing value for %s.\n", argv[index]);
317 delete clink;
318 return EXIT_FAILURE;
319 }
320 std::sscanf(argv[++index], "%lu", &timeout);
321 continue;
322 }
323
324 std::fprintf(stderr, "Warning: Unknown argument %s skipped.\n", argv[index]);
325 index++;
326 }
327
328 if (!got_file || !got_scope_channel || !got_ip) {
329 std::fprintf(stderr, "%s: Grabs a waveform from an Agilent scope via Ethernet.\n", progname);
330 std::fprintf(stderr, "Usage: %s [required arguments] [optional arguments]\n\n", progname);
331 std::fprintf(stderr, "Required Arguments:\n");
332 std::fprintf(stderr, " -ip, -ip_address, -IP IP address of the scope (e.g., 128.243.74.232)\n");
333 std::fprintf(stderr, " -f, -filename, -file Filename (without extension)\n");
334 std::fprintf(stderr, " -c, -channel, -scope_channel Scope channel (1,2,3,4,A,B,C,D)\n\n");
335 std::fprintf(stderr, "Optional Arguments:\n");
336 std::fprintf(stderr, " -t, -timeout Timeout in milliseconds (default: 10000 ms)\n");
337 std::fprintf(stderr, " -s, -sample_rate, -rate Set sample rate (e.g., 1e9 for 1 GS/s)\n");
338 std::fprintf(stderr, " -n, -no_points, -points Set minimum number of acquisition points\n");
339 std::fprintf(stderr, " -a, -averages, -aver Set number of averages (<=0 means none)\n\n");
340 std::fprintf(stderr, "Output:\n");
341 std::fprintf(stderr, " filename.sdds ASCII data of waveform\n\n");
342 std::fprintf(stderr, "Example:\n");
343 std::fprintf(stderr, " %s -ip 128.243.74.232 -f output -c 2 -s 1e9\n", progname);
344 delete clink;
345 return EXIT_FAILURE;
346 }
347
348 f_wf = std::fopen(wfname, "w");
349 if (f_wf != nullptr) {
350 if (vxi11_open_device(serverIP, clink) != 0) {
351 std::fprintf(stderr, "Error: Failed to open device.\n");
352 delete clink;
353 return EXIT_FAILURE;
354 }
355
356 if (agilent_init(clink) != 0) {
357 std::fprintf(stderr, "Error: Initialization failed.\n");
358 vxi11_close_device(serverIP, clink);
359 delete clink;
360 return EXIT_FAILURE;
361 }
362
363 agilent_set_for_capture(clink, s_rate, npoints, timeout);
364
365 if (got_no_averages) {
366 if (agilent_set_averages(clink, no_averages) != 0) {
367 std::fprintf(stderr, "Warning: Failed to set averages.\n");
368 }
369 }
370
371 buf_size = agilent_calculate_no_of_bytes(clink, chnl, timeout);
372 buf = new (std::nothrow) char[buf_size];
373 if (!buf) {
374 std::fprintf(stderr, "Error: Memory allocation for buffer failed.\n");
375 vxi11_close_device(serverIP, clink);
376 delete clink;
377 return EXIT_FAILURE;
378 }
379
380 hinterval = vxi11_obtain_double_value(clink, ":WAV:XINC?", timeout);
381 hoffset = vxi11_obtain_double_value(clink, ":WAV:XORIGIN?");
382 vgain = vxi11_obtain_double_value(clink, ":WAV:YINC?");
383 voffset = vxi11_obtain_double_value(clink, ":WAV:YORIGIN?");
384
385 bytes_returned = agilent_get_data(clink, chnl, 0, buf, buf_size, timeout);
386 if (bytes_returned <= 0) {
387 std::fprintf(stderr, "Error: Problem reading the data.\n");
388 std::fclose(f_wf);
389 delete[] buf;
390 vxi11_close_device(serverIP, clink);
391 delete clink;
392 return EXIT_FAILURE;
393 }
394
395 actual_s_rate = vxi11_obtain_double_value(clink, ":ACQ:SRAT?");
396 actual_npoints = vxi11_obtain_long_value(clink, ":ACQ:POINTS?");
397 std::printf("Sample rate used: %g (%g GSa/s); acquisition points: %ld\n", actual_s_rate, (actual_s_rate / 1e9), actual_npoints);
398
399 agilent_set_for_auto(clink);
400
401 /* Writing SDDS header */
402 std::fprintf(f_wf, "SDDS1\n");
403 std::fprintf(f_wf, "&parameter name=VerticalGain, type=double, &end\n");
404 std::fprintf(f_wf, "&parameter name=VerticalOffset, type=double, &end\n");
405 std::fprintf(f_wf, "&parameter name=HorizontalInterval, type=double, &end\n");
406 std::fprintf(f_wf, "&parameter name=HorizontalOffset, type=double, &end\n");
407 std::fprintf(f_wf, "&column name=Index, type=long, &end\n");
408 std::fprintf(f_wf, "&column name=Waveform, type=double, &end\n");
409 std::fprintf(f_wf, "&column name=Timebase, type=double, &end\n");
410 std::fprintf(f_wf, "&column name=DelayedTimebase, type=double, &end\n");
411 std::fprintf(f_wf, "&data mode=ascii, &end\n");
412 std::fprintf(f_wf, "%lg\n", vgain);
413 std::fprintf(f_wf, "%lg\n", voffset);
414 std::fprintf(f_wf, "%lg\n", hinterval);
415 std::fprintf(f_wf, "%lg\n", hoffset);
416 std::fprintf(f_wf, "\t%ld\n", bytes_returned / 2);
417
418 for (i = 0; i < bytes_returned; i += 2) {
419 std::memcpy(&val, buf + i, 2);
420 std::fprintf(f_wf, "%ld %lg %lg %lg\n", (i / 2), val * vgain - voffset, (i / 2) * hinterval, (i / 2) * hinterval + hoffset);
421 }
422
423 std::fclose(f_wf);
424 delete[] buf;
425
426 vxi11_close_device(serverIP, clink);
427 delete clink;
428 return EXIT_SUCCESS;
429 } else {
430 std::fprintf(stderr, "Error: Could not open file '%s' for writing.\n", wfname);
431 delete clink;

◆ sc()

bool sc ( const char * con,
const char * var )

Definition at line 434 of file agilentwaveform2sdds.cpp.

◆ vxi11_close_device() [1/2]

int vxi11_close_device ( const char * ip,
CLIENT * client,
VXI11_LINK * link )

Definition at line 785 of file agilentwaveform2sdds.cpp.

788 {
789 int ret;
790
791 ret = vxi11_close_link(ip, client, link);
792
793 clnt_destroy(client);

◆ vxi11_close_device() [2/2]

int vxi11_close_device ( const char * ip,
CLINK * clink )

Definition at line 755 of file agilentwaveform2sdds.cpp.

755 :ACQ:SRAT:AUTO 1;:ACQ:POINTS:AUTO 1;:RUN");
756}
757
758int vxi11_close_device(const char *ip, CLINK *clink) {
759 int l, ret;
760 int device_no = -1;
761
762 /* Which instrument are we referring to? */
763 for (l = 0; l < VXI11_MAX_CLIENTS; l++) {
764 if (std::strcmp(ip, VXI11_IP_ADDRESS[l]) == 0) {
765 device_no = l;
766 break;
767 }
768 }
769 /* Something's up if we can't find the IP address! */
770 if (device_no == -1) {
771 std::fprintf(stderr, "vxi11_close_device: error: No record of opening device with IP %s.\n", ip);
772 ret = -4;
773 } else { /* Found the IP, there's more than one link to that instrument,
774 * so keep track and just close the link */
775 if (VXI11_LINK_COUNT[device_no] > 1) {
776 ret = vxi11_close_link(ip, clink->client, clink->link);
777 VXI11_LINK_COUNT[device_no]--;
778 }
779 /* Found the IP, it's the last link, so close the device (link
780 * AND client) */
781 else {
782 ret = vxi11_close_device(ip, clink->client, clink->link);
783 }

◆ vxi11_close_link()

int vxi11_close_link ( const char * ip,
CLIENT * client,
VXI11_LINK * link )

Definition at line 795 of file agilentwaveform2sdds.cpp.

798 {
799 Device_Error dev_error;
800 std::memset(&dev_error, 0, sizeof(dev_error));
801
802 if (destroy_link_1(&link->lid, &dev_error, client) != RPC_SUCCESS) {
803#ifdef __APPLE__
804 clnt_perror(client, const_cast<char *>(ip));
805#else
806 clnt_perror(client, ip);
807#endif
808 return -1;
809 }

◆ vxi11_obtain_double_value() [1/2]

double vxi11_obtain_double_value ( CLINK * clink,
const char * cmd )

Definition at line 818 of file agilentwaveform2sdds.cpp.

◆ vxi11_obtain_double_value() [2/2]

double vxi11_obtain_double_value ( CLINK * clink,
const char * cmd,
unsigned long timeout )

Definition at line 822 of file agilentwaveform2sdds.cpp.

825 {
826 char buf[50] = {0}; /* 50=arbitrary length... more than enough for one number in ascii */
827 double val = 0.0;
828 if (vxi11_send_and_receive(clink, cmd, buf, sizeof(buf), timeout) != 0) {
829 std::fprintf(stderr, "Warning: Failed to obtain double value for command '%s'. Returning 0.0.\n", cmd);
830 return 0.0;
831 }

◆ vxi11_obtain_long_value() [1/2]

long vxi11_obtain_long_value ( CLINK * clink,
const char * cmd )

Definition at line 1013 of file agilentwaveform2sdds.cpp.

◆ vxi11_obtain_long_value() [2/2]

long vxi11_obtain_long_value ( CLINK * clink,
const char * cmd,
unsigned long timeout )

Definition at line 1003 of file agilentwaveform2sdds.cpp.

1006 {
1007 char buf[50] = {0}; /* 50=arbitrary length... more than enough for one number in ascii */
1008 if (vxi11_send_and_receive(clink, cmd, buf, sizeof(buf), timeout) != 0) {
1009 std::fprintf(stderr, "Warning: Failed to obtain long value for command '%s'. Returning 0.\n", cmd);
1010 return 0;

◆ vxi11_open_device() [1/3]

int vxi11_open_device ( const char * ip,
CLIENT ** client,
VXI11_LINK ** link,
char * device )

Definition at line 445 of file agilentwaveform2sdds.cpp.

448 {
449
450#ifdef __APPLE__
451 *client = clnt_create(const_cast<char *>(ip), DEVICE_CORE, DEVICE_CORE_VERSION, "tcp");
452#else
453 *client = clnt_create(ip, DEVICE_CORE, DEVICE_CORE_VERSION, "tcp");
454#endif
455
456 if (*client == nullptr) {
457#ifdef __APPLE__
458 clnt_pcreateerror(const_cast<char *>(ip));
459#else
460 clnt_pcreateerror(ip);
461#endif
462 return -1;
463 }

◆ vxi11_open_device() [2/3]

int vxi11_open_device ( const char * ip,
CLINK * clink )

Definition at line 438 of file agilentwaveform2sdds.cpp.

441 {
442 char device[6];
443 std::strncpy(device, "inst0", sizeof(device));

◆ vxi11_open_device() [3/3]

int vxi11_open_device ( const char * ip,
CLINK * clink,
char * device )

Definition at line 465 of file agilentwaveform2sdds.cpp.

468 {
469 int ret;
470 int l;
471 int device_no = -1;
472
473 for (l = 0; l < VXI11_MAX_CLIENTS; l++) {
474 if (std::strcmp(ip, VXI11_IP_ADDRESS[l]) == 0) {
475 device_no = l;
476 break;
477 }
478 }
479
480 if (device_no < 0) {
481 if (VXI11_DEVICE_NO >= VXI11_MAX_CLIENTS) {
482 std::fprintf(stderr, "Error: Maximum of %d clients allowed.\n", VXI11_MAX_CLIENTS);
483 ret = -VXI11_MAX_CLIENTS;
484 } else {
485 ret = vxi11_open_device(ip, &(clink->client), &(clink->link), device);
486 std::strncpy(VXI11_IP_ADDRESS[VXI11_DEVICE_NO], ip, sizeof(VXI11_IP_ADDRESS[0]) - 1);
487 VXI11_IP_ADDRESS[VXI11_DEVICE_NO][sizeof(VXI11_IP_ADDRESS[0]) - 1] = '\0'; // Ensure null-termination
488 VXI11_CLIENT_ADDRESS[VXI11_DEVICE_NO] = clink->client;
489 VXI11_LINK_COUNT[VXI11_DEVICE_NO] = 1;
490 VXI11_DEVICE_NO++;
491 }
492 } else {
493 clink->client = VXI11_CLIENT_ADDRESS[device_no];
494 ret = vxi11_open_link(ip, &(clink->client), &(clink->link), device);
495 VXI11_LINK_COUNT[device_no]++;

◆ vxi11_open_link()

int vxi11_open_link ( const char * ip,
CLIENT ** client,
VXI11_LINK ** link,
char * device )

Definition at line 497 of file agilentwaveform2sdds.cpp.

500 {
501
502 Create_LinkParms link_parms;
503
504 /* Set link parameters */
505 link_parms.clientId = reinterpret_cast<intptr_t>(*client);
506 link_parms.lockDevice = 0;
507 link_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT;
508 link_parms.device = device;
509
510 *link = new (std::nothrow) Create_LinkResp();
511 if (!*link) {
512 std::fprintf(stderr, "Error: Memory allocation for Create_LinkResp failed.\n");
513 return -2;
514 }
515
516 if (create_link_1(&link_parms, *link, *client) != RPC_SUCCESS) {
517#ifdef __APPLE__
518 clnt_perror(*client, const_cast<char *>(ip));
519#else
520 clnt_perror(*client, ip);
521#endif
522 delete *link;
523 *link = nullptr;
524 return -2;

◆ vxi11_receive() [1/3]

long vxi11_receive ( CLIENT * client,
VXI11_LINK * link,
char * buffer,
unsigned long len,
unsigned long timeout )

Definition at line 860 of file agilentwaveform2sdds.cpp.

863 {
864 Device_ReadParms read_parms;
865 Device_ReadResp read_resp;
866 long curr_pos = 0;
867
868 read_parms.lid = link->lid;
869 read_parms.requestSize = len;
870 read_parms.io_timeout = timeout; /* in ms */
871 read_parms.lock_timeout = timeout; /* in ms */
872 read_parms.flags = 0;
873 read_parms.termChar = 0;
874
875 do {
876 std::memset(&read_resp, 0, sizeof(read_resp));
877
878 read_resp.data.data_val = buffer + curr_pos;
879 read_parms.requestSize = len - curr_pos; // Never request more total data than originally specified in len
880
881 if (device_read_1(&read_parms, &read_resp, client) != RPC_SUCCESS) {
882 return -VXI11_NULL_READ_RESP; /* there is nothing to read. Usually occurs after sending a query
883 which times out on the instrument. If we don't check this first,
884 then the following line causes a seg fault */
885 }
886 if (read_resp.error != 0) {
887 /* Read failed for reason specified in error code.
888 * 0 no error
889 * 4 invalid link identifier
890 * 11 device locked by another link
891 * 15 I/O timeout
892 * 17 I/O error
893 * 23 abort
894 */
895
896 std::fprintf(stderr, "vxi11_user: read error: %d\n", static_cast<int>(read_resp.error));
897 return -(read_resp.error);
898 }
899
900 if ((static_cast<unsigned long>(curr_pos + read_resp.data.data_len) <= len)) {
901 curr_pos += read_resp.data.data_len;
902 }
903 if ((read_resp.reason & RCV_END_BIT) || (read_resp.reason & RCV_CHR_BIT)) {
904 break;
905 } else if ((static_cast<unsigned long>(curr_pos) == len)) {
906 std::fprintf(stderr, "vxi11_user: read error: buffer too small. Read %ld bytes without hitting terminator.\n", curr_pos);
907 return -100;
908 }

◆ vxi11_receive() [2/3]

long vxi11_receive ( CLINK * clink,
char * buffer,
unsigned long len )

Definition at line 910 of file agilentwaveform2sdds.cpp.

◆ vxi11_receive() [3/3]

long vxi11_receive ( CLINK * clink,
char * buffer,
unsigned long len,
unsigned long timeout )

Definition at line 914 of file agilentwaveform2sdds.cpp.

◆ vxi11_receive_data_block()

long vxi11_receive_data_block ( CLINK * clink,
char * buffer,
unsigned long len,
unsigned long timeout )

Definition at line 1108 of file agilentwaveform2sdds.cpp.

1111 {
1112 /* I'm not sure what the maximum length of this header is, I'll assume it's
1113 * 11 (#9 + 9 digits) */
1114 unsigned long necessary_buffer_size;
1115 char *in_buffer = nullptr;
1116 int ret = 0;
1117 int ndigits = 0;
1118 unsigned long returned_bytes = 0;
1119 int l = 0;
1120 char scan_cmd[20] = {0};
1121 necessary_buffer_size = len + 12;
1122 in_buffer = new (std::nothrow) char[necessary_buffer_size];
1123 if (!in_buffer) {
1124 std::fprintf(stderr, "Error: Memory allocation for in_buffer failed.\n");
1125 return -3;
1126 }
1127 ret = vxi11_receive(clink, in_buffer, necessary_buffer_size, timeout);
1128 if (ret < 0) {
1129 delete[] in_buffer;
1130 return ret;
1131 }
1132 if (in_buffer[0] != '#') {
1133 std::fprintf(stderr, "vxi11_user: data block error: data block does not begin with '#'\n");
1134 std::fprintf(stderr, "First 20 characters received were: '");
1135 for (l = 0; l < 20 && l < static_cast<int>(necessary_buffer_size); l++) {
1136 std::fprintf(stderr, "%c", in_buffer[l]);
1137 }
1138 std::fprintf(stderr, "'\n");
1139 delete[] in_buffer;
1140 return -3;
1141 }
1142
1143 /* first find out how many digits */
1144 if (std::sscanf(in_buffer, "#%1d", &ndigits) != 1) {
1145 std::fprintf(stderr, "vxi11_user: Failed to parse number of digits in data block header.\n");
1146 delete[] in_buffer;
1147 return -3;
1148 }
1149 /* some instruments, if there is a problem acquiring the data, return only "#0" */
1150 if (ndigits > 0) {
1151 /* now that we know, we can convert the next <ndigits> bytes into an unsigned long */
1152 std::snprintf(scan_cmd, sizeof(scan_cmd), "##%dlu", ndigits);
1153 if (std::sscanf(in_buffer, scan_cmd, &returned_bytes) != 1) {
1154 std::fprintf(stderr, "vxi11_user: Failed to parse number of returned bytes.\n");
1155 delete[] in_buffer;
1156 return -3;
1157 }
1158 if (returned_bytes > len) {
1159 std::fprintf(stderr, "vxi11_user: Received more bytes than buffer can hold.\n");
1160 delete[] in_buffer;
1161 return -3;
1162 }
1163 std::memcpy(buffer, in_buffer + (ndigits + 2), returned_bytes);
1164 delete[] in_buffer;
1165 return static_cast<long>(returned_bytes);
1166 } else {
1167 delete[] in_buffer;

◆ vxi11_send() [1/4]

int vxi11_send ( CLIENT * client,
VXI11_LINK * link,
const char * cmd )

Definition at line 635 of file agilentwaveform2sdds.cpp.

◆ vxi11_send() [2/4]

int vxi11_send ( CLIENT * client,
VXI11_LINK * link,
const char * cmd,
unsigned long len )

Definition at line 639 of file agilentwaveform2sdds.cpp.

642 {
643 Device_WriteParms write_parms;
644 int bytes_left = static_cast<int>(len);
645 char *send_cmd;
646
647 send_cmd = new (std::nothrow) char[len];
648 if (!send_cmd) {
649 std::fprintf(stderr, "Error: Memory allocation for send_cmd failed.\n");
650 return -VXI11_NULL_WRITE_RESP;
651 }
652 std::memcpy(send_cmd, cmd, len);
653
654 write_parms.lid = link->lid;
655 write_parms.io_timeout = VXI11_DEFAULT_TIMEOUT;
656 write_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT;
657
658 /* We can only write (link->maxRecvSize) bytes at a time, so we sit in a loop,
659 * writing a chunk at a time, until we're done. */
660
661 do {
662 Device_WriteResp write_resp;
663 std::memset(&write_resp, 0, sizeof(write_resp));
664
665 if (static_cast<unsigned int>(bytes_left) <= link->maxRecvSize) {
666 write_parms.flags = 8;
667 write_parms.data.data_len = bytes_left;
668 } else {
669 write_parms.flags = 0;
670 /* We need to check that maxRecvSize is a sane value (ie >0). Believe it
671 * or not, on some versions of Agilent Infiniium scope firmware the scope
672 * returned "0", which breaks Rule B.6.3 of the VXI-11 protocol. Nevertheless
673 * we need to catch this, otherwise the program just hangs. */
674 if (link->maxRecvSize > 0) {
675 write_parms.data.data_len = link->maxRecvSize;
676 } else {
677 write_parms.data.data_len = 4096; /* pretty much anything should be able to cope with 4kB */
678 }
679 }
680 write_parms.data.data_val = send_cmd + (len - bytes_left);
681
682 if (device_write_1(&write_parms, &write_resp, client) != RPC_SUCCESS) {
683 delete[] send_cmd;
684 return -VXI11_NULL_WRITE_RESP; /* The instrument did not acknowledge the write, just completely
685 dropped it. There was no vxi11 comms error as such, the
686 instrument is just being rude. Usually occurs when the instrument
687 is busy. If we don't check this first, then the following
688 line causes a seg fault */
689 }
690 if (write_resp.error != 0) {
691 std::fprintf(stderr, "vxi11_user: write error: %d\n", static_cast<int>(write_resp.error));
692 delete[] send_cmd;
693 return -(write_resp.error);
694 }
695 bytes_left -= write_resp.size;
696 } while (bytes_left > 0);
697

◆ vxi11_send() [3/4]

int vxi11_send ( CLINK * clink,
const char * cmd )

Definition at line 627 of file agilentwaveform2sdds.cpp.

◆ vxi11_send() [4/4]

int vxi11_send ( CLINK * clink,
const char * cmd,
unsigned long len )

Definition at line 631 of file agilentwaveform2sdds.cpp.

◆ vxi11_send_and_receive()

long vxi11_send_and_receive ( CLINK * clink,
const char * cmd,
char * buf,
unsigned long buf_len,
unsigned long timeout )

Definition at line 833 of file agilentwaveform2sdds.cpp.

836 {
837 int ret;
838 long bytes_returned;
839 do {
840 ret = vxi11_send(clink, cmd);
841 if (ret != 0) {
842 if (ret != -VXI11_NULL_WRITE_RESP) {
843 std::fprintf(stderr, "Error: Could not send command '%s'. Function vxi11_send returned %d.\n", cmd, ret);
844 return -1;
845 } else {
846 std::fprintf(stderr, "Info: VXI11_NULL_WRITE_RESP in vxi11_send_and_receive, resending query.\n");
847 }
848 }
849
850 bytes_returned = vxi11_receive(clink, buf, buf_len, timeout);
851 if (bytes_returned <= 0) {
852 if (bytes_returned > -VXI11_NULL_READ_RESP) {
853 std::fprintf(stderr, "Error: Problem reading reply for command '%s'. Function vxi11_receive returned %ld.\n", cmd, bytes_returned);
854 return -2;
855 } else {
856 std::fprintf(stderr, "Info: VXI11_NULL_READ_RESP in vxi11_send_and_receive, resending query.\n");
857 }
858 }

◆ xdr_Create_LinkParms()

bool_t xdr_Create_LinkParms ( XDR * xdrs,
Create_LinkParms * objp )

Definition at line 533 of file agilentwaveform2sdds.cpp.

536 {
537
538#if defined(SOLARIS) && !defined(_LP64)
539 long *buf;
540#else
541 int32_t *buf;
542#endif
543
544 if (xdrs->x_op == XDR_ENCODE) {
545 buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT);
546 if (buf == nullptr) {
547 if (!xdr_long(xdrs, &objp->clientId))
548 return FALSE;
549 if (!xdr_bool(xdrs, &objp->lockDevice))
550 return FALSE;
551 if (!xdr_u_long(xdrs, &objp->lock_timeout))
552 return FALSE;
553
554 } else {
555 IXDR_PUT_INT32(buf, objp->clientId);
556 IXDR_PUT_BOOL(buf, objp->lockDevice);
557 IXDR_PUT_U_INT32(buf, objp->lock_timeout);
558 }
559 if (!xdr_string(xdrs, &objp->device, ~0))
560 return FALSE;
561 return TRUE;
562 } else if (xdrs->x_op == XDR_DECODE) {
563 buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT);
564 if (buf == nullptr) {
565 if (!xdr_long(xdrs, &objp->clientId))
566 return FALSE;
567 if (!xdr_bool(xdrs, &objp->lockDevice))
568 return FALSE;
569 if (!xdr_u_long(xdrs, &objp->lock_timeout))
570 return FALSE;
571
572 } else {
573 objp->clientId = IXDR_GET_INT32(buf);
574 objp->lockDevice = IXDR_GET_BOOL(buf);
575 objp->lock_timeout = IXDR_GET_U_INT32(buf);
576 }
577 if (!xdr_string(xdrs, &objp->device, ~0))
578 return FALSE;
579 return TRUE;
580 }
581
582 if (!xdr_long(xdrs, &objp->clientId))
583 return FALSE;
584 if (!xdr_bool(xdrs, &objp->lockDevice))
585 return FALSE;
586 if (!xdr_u_long(xdrs, &objp->lock_timeout))
587 return FALSE;
588 if (!xdr_string(xdrs, &objp->device, ~0))

◆ xdr_Create_LinkResp()

bool_t xdr_Create_LinkResp ( XDR * xdrs,
Create_LinkResp * objp )

Definition at line 590 of file agilentwaveform2sdds.cpp.

593 {
594 if (!xdr_Device_ErrorCode(xdrs, &objp->error))
595 return FALSE;
596 if (!xdr_Device_Link(xdrs, &objp->lid))
597 return FALSE;
598 if (!xdr_u_short(xdrs, &objp->abortPort))
599 return FALSE;
600 if (!xdr_u_long(xdrs, &objp->maxRecvSize))

◆ xdr_Device_Error()

bool_t xdr_Device_Error ( XDR * xdrs,
Device_Error * objp )

Definition at line 732 of file agilentwaveform2sdds.cpp.

◆ xdr_Device_ErrorCode()

bool_t xdr_Device_ErrorCode ( XDR * xdrs,
Device_ErrorCode * objp )

Definition at line 602 of file agilentwaveform2sdds.cpp.

◆ xdr_Device_Flags()

bool_t xdr_Device_Flags ( XDR * xdrs,
Device_Flags * objp )

Definition at line 728 of file agilentwaveform2sdds.cpp.

◆ xdr_Device_Link()

bool_t xdr_Device_Link ( XDR * xdrs,
Device_Link * objp )

Definition at line 606 of file agilentwaveform2sdds.cpp.

◆ xdr_Device_ReadParms()

bool_t xdr_Device_ReadParms ( XDR * xdrs,
Device_ReadParms * objp )

Definition at line 925 of file agilentwaveform2sdds.cpp.

928 {
929#if defined(SOLARIS) && !defined(_LP64)
930 long *buf;
931#else
932 int32_t *buf;
933#endif
934
935 if (xdrs->x_op == XDR_ENCODE) {
936 if (!xdr_Device_Link(xdrs, &objp->lid))
937 return FALSE;
938 buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT);
939 if (buf == nullptr) {
940 if (!xdr_u_long(xdrs, &objp->requestSize))
941 return FALSE;
942 if (!xdr_u_long(xdrs, &objp->io_timeout))
943 return FALSE;
944 if (!xdr_u_long(xdrs, &objp->lock_timeout))
945 return FALSE;
946
947 } else {
948 IXDR_PUT_U_INT32(buf, objp->requestSize);
949 IXDR_PUT_U_INT32(buf, objp->io_timeout);
950 IXDR_PUT_U_INT32(buf, objp->lock_timeout);
951 }
952 if (!xdr_Device_Flags(xdrs, &objp->flags))
953 return FALSE;
954 if (!xdr_char(xdrs, &objp->termChar))
955 return FALSE;
956 return TRUE;
957 } else if (xdrs->x_op == XDR_DECODE) {
958 if (!xdr_Device_Link(xdrs, &objp->lid))
959 return FALSE;
960 buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT);
961 if (buf == nullptr) {
962 if (!xdr_u_long(xdrs, &objp->requestSize))
963 return FALSE;
964 if (!xdr_u_long(xdrs, &objp->io_timeout))
965 return FALSE;
966 if (!xdr_u_long(xdrs, &objp->lock_timeout))
967 return FALSE;
968
969 } else {
970 objp->requestSize = IXDR_GET_U_INT32(buf);
971 objp->io_timeout = IXDR_GET_U_INT32(buf);
972 objp->lock_timeout = IXDR_GET_U_INT32(buf);
973 }
974 if (!xdr_Device_Flags(xdrs, &objp->flags))
975 return FALSE;
976 if (!xdr_char(xdrs, &objp->termChar))
977 return FALSE;
978 return TRUE;
979 }
980
981 if (!xdr_Device_Link(xdrs, &objp->lid))
982 return FALSE;
983 if (!xdr_u_long(xdrs, &objp->requestSize))
984 return FALSE;
985 if (!xdr_u_long(xdrs, &objp->io_timeout))
986 return FALSE;
987 if (!xdr_u_long(xdrs, &objp->lock_timeout))
988 return FALSE;
989 if (!xdr_Device_Flags(xdrs, &objp->flags))
990 return FALSE;
991 if (!xdr_char(xdrs, &objp->termChar))

◆ xdr_Device_ReadResp()

bool_t xdr_Device_ReadResp ( XDR * xdrs,
Device_ReadResp * objp )

Definition at line 993 of file agilentwaveform2sdds.cpp.

996 {
997 if (!xdr_Device_ErrorCode(xdrs, &objp->error))
998 return FALSE;
999 if (!xdr_long(xdrs, &objp->reason))
1000 return FALSE;
1001 if (!xdr_bytes(xdrs, &objp->data.data_val, reinterpret_cast<u_int *>(&objp->data.data_len), ~0))

◆ xdr_Device_WriteParms()

bool_t xdr_Device_WriteParms ( XDR * xdrs,
Device_WriteParms * objp )

Definition at line 706 of file agilentwaveform2sdds.cpp.

709 {
710 if (!xdr_Device_Link(xdrs, &objp->lid))
711 return FALSE;
712 if (!xdr_u_long(xdrs, &objp->io_timeout))
713 return FALSE;
714 if (!xdr_u_long(xdrs, &objp->lock_timeout))
715 return FALSE;
716 if (!xdr_Device_Flags(xdrs, &objp->flags))
717 return FALSE;
718 if (!xdr_bytes(xdrs, &objp->data.data_val, reinterpret_cast<u_int *>(&objp->data.data_len), ~0))

◆ xdr_Device_WriteResp()

bool_t xdr_Device_WriteResp ( XDR * xdrs,
Device_WriteResp * objp )

Definition at line 720 of file agilentwaveform2sdds.cpp.

723 {
724 if (!xdr_Device_ErrorCode(xdrs, &objp->error))
725 return FALSE;
726 if (!xdr_u_long(xdrs, &objp->size))