summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libvxi11client/client.c50
-rw-r--r--libvxi11client/libvxi11client.c225
-rw-r--r--libvxi11client/libvxi11client.h43
-rw-r--r--libvxi11client/perlbits/README2
4 files changed, 169 insertions, 151 deletions
diff --git a/libvxi11client/client.c b/libvxi11client/client.c
index 7deff6e..3a79e52 100644
--- a/libvxi11client/client.c
+++ b/libvxi11client/client.c
@@ -28,7 +28,7 @@ static char* geterrorstring(int errorcode) {
}
}
-static void interruptcallback(void) {
+static void interruptcallback(char* handle) {
printf("Interrupt fired\n");
}
@@ -41,16 +41,20 @@ int main(int argc, char *argv[]) {
exit(1);
}
+ vxi11_start_interrupt_server(interruptcallback);
+
+ Context ctx;
+
int err = 0;
- if ((err = vxi11_open(argv[1], NULL)) > 0) {
+ if ((err = vxi11_open(&ctx, argv[1], NULL)) > 0) {
/**
* Basic tests
*/
// write some bytes
- int byteswritten = vxi11_write(IDENTIFY, sizeof(IDENTIFY), false, false);
+ int byteswritten = vxi11_write(&ctx, IDENTIFY, sizeof(IDENTIFY), false, false);
if (byteswritten >= 0)
printf("Wrote %d bytes\n", byteswritten);
else
@@ -58,44 +62,44 @@ int main(int argc, char *argv[]) {
// read some bytes
char buffer[1024];
- int bytesread = vxi11_read(buffer, sizeof(buffer), false, false, 0);
+ int bytesread = vxi11_read(&ctx, buffer, sizeof(buffer), false, false, 0);
if (bytesread >= 0)
printf("Read %d bytes, %s\n", bytesread, buffer);
else
printf("Error reading data\n");
// trigger
- if (vxi11_trigger(false) > 0)
+ if (vxi11_trigger(&ctx, false) > 0)
printf("triggered\n");
// clear
- if (vxi11_clear(false) > 0)
+ if (vxi11_clear(&ctx, false) > 0)
printf("cleared\n");
// abort
- if ((err = vxi11_abort()) > 0)
+ if ((err = vxi11_abort(&ctx)) > 0)
printf("aborted\n");
else
printf("abort failed; %s\n", geterrorstring(err));
// lock
- if ((err = vxi11_lock(false)) > 0)
+ if ((err = vxi11_lock(&ctx, false)) > 0)
printf("locked\n");
// unlock
- if ((err = vxi11_unlock()) > 0)
+ if ((err = vxi11_unlock(&ctx)) > 0)
printf("unlocked\n");
// remote
- if ((err = vxi11_remote(false)) > 0)
+ if ((err = vxi11_remote(&ctx, false)) > 0)
printf("remote'd\n");
// local
- if ((err = vxi11_local(false)) > 0)
+ if ((err = vxi11_local(&ctx, false)) > 0)
printf("local'd\n");
// read the status byte
- int statusbyte = vxi11_readstatusbyte(false);
+ int statusbyte = vxi11_readstatusbyte(&ctx, false);
if (statusbyte >= 0)
printf("Status byte is 0x%02x\n", statusbyte);
else
@@ -107,9 +111,9 @@ int main(int argc, char *argv[]) {
// try locking twice
printf("-- Locking twice --\n");
- if ((err = vxi11_lock(false)) > 0) {
+ if ((err = vxi11_lock(&ctx, false)) > 0) {
printf("locked\n");
- if ((err = vxi11_lock(false)) > 0) {
+ if ((err = vxi11_lock(&ctx, false)) > 0) {
printf("locked again!!\n");
exit(1);
}
@@ -117,7 +121,7 @@ int main(int argc, char *argv[]) {
printf("Second lock failed; %s\n", geterrorstring(err));
}
}
- if ((err = vxi11_unlock()) > 0)
+ if ((err = vxi11_unlock(&ctx)) > 0)
printf("unlocked\n");
else {
printf("error unlocking; %s\n", geterrorstring(err));
@@ -128,7 +132,7 @@ int main(int argc, char *argv[]) {
// try unlocking unlocked device
printf("-- Unlocking when unlocked --\n");
- if ((err = vxi11_unlock()) > 0) {
+ if ((err = vxi11_unlock(&ctx)) > 0) {
printf("Unlocked!!\n");
exit(1);
}
@@ -139,11 +143,11 @@ int main(int argc, char *argv[]) {
// Interrupt channel tests
printf("-- Testing interrupt channel --\n");
// create interrupt channel
- if ((err = vxi11_create_intr_chan()) > 0) {
+ if ((err = vxi11_create_intr_chan(&ctx)) > 0) {
printf("Created interrupt channel\n");
// enable interrupts
- if ((err = vxi11_enable_srq(true, "handle", interruptcallback)) > 0)
+ if ((err = vxi11_enable_srq(&ctx, true, "handle")) > 0)
printf("Enabled interrupts\n");
else
printf("Error enabling interrupts; %s\n", geterrorstring(err));
@@ -151,13 +155,13 @@ int main(int argc, char *argv[]) {
sleep(10);
// disable interrupts
- if ((err = vxi11_enable_srq(false, NULL, NULL)) > 0)
+ if ((err = vxi11_enable_srq(&ctx, false, NULL)) > 0)
printf("Disabled interrupts\n");
else
printf("Error disabling interrupts; %s\n", geterrorstring(err));
// destroy interrupt channel
- if ((err = vxi11_destroy_intr_chan()) > 0)
+ if ((err = vxi11_destroy_intr_chan(&ctx)) > 0)
printf("Destroyed interrupt channel\n");
else
printf("Error destroying interrupt channel; %s\n", geterrorstring(err));
@@ -167,14 +171,16 @@ int main(int argc, char *argv[]) {
printf("\n");
// docmd
- if ((err = vxi11_docmd(0x00, false)) > 0)
+ if ((err = vxi11_docmd(&ctx, 0x00, false)) > 0)
printf("did command, should fail!\n");
else
printf("Error calling docmd; %s\n", geterrorstring(err));
// close
- if ((err = vxi11_close() > 0))
+ if ((err = vxi11_close(&ctx) > 0))
printf("Closed\n");
+
+ vxi11_stop_interrupt_server();
}
else {
printf("Error opening device; %s\n", geterrorstring(err));
diff --git a/libvxi11client/libvxi11client.c b/libvxi11client/libvxi11client.c
index 60e4609..8936545 100644
--- a/libvxi11client/libvxi11client.c
+++ b/libvxi11client/libvxi11client.c
@@ -4,6 +4,7 @@
#include <unistd.h>
#include <glib.h>
#include <poll.h>
+#include "libvxi11client.h"
#include "vxi11.h"
#define DEBUG
@@ -24,21 +25,10 @@
#define VXI11_DEFAULT_TIMEOUT 1000
-static CLIENT* clnt = NULL;
-static CLIENT* abortclnt = NULL;
-static Device_Link devicelink;
static GThread* interruptthread;
-static bool interruptchannelopen = false;
-static void (*interruptcallback)(void) = NULL;
-
-static void killinterruptthreadandwait() {
-#ifdef DEBUG
- printf("Waiting for interrupt thread to die\n");
-#endif
- interruptchannelopen = false;
- g_thread_join(interruptthread);
- interruptthread = NULL;
-}
+static void (*interruptcallback)(char*) = NULL;
+static bool interruptserverstarted = false;
+static unsigned int interruptserverport = -1;
void *
device_intr_srq_1_svc(Device_SrqParms *argp, struct svc_req *rqstp) {
@@ -47,7 +37,7 @@ device_intr_srq_1_svc(Device_SrqParms *argp, struct svc_req *rqstp) {
#endif
if (interruptcallback != NULL) {
- interruptcallback();
+ interruptcallback(argp->handle.handle_val);
}
static char * result;
@@ -109,29 +99,29 @@ static Device_Flags vxi11_generateflags(bool waitlock, bool end, bool termchrset
* $device is apparently used for VXI-11 -> GPIB gateways.. this is untested.
*/
-int vxi11_open(char* address, char* device) {
- clnt = clnt_create(address, DEVICE_CORE, DEVICE_CORE_VERSION, "tcp");
+int vxi11_open(Context* context, char* address, char* device) {
+ context->clnt = clnt_create(address, DEVICE_CORE, DEVICE_CORE_VERSION, "tcp");
- if (clnt == NULL)
+ if (context->clnt == NULL)
return 0;
else {
Create_LinkParms link_parms;
- link_parms.clientId = (long) clnt;
+ link_parms.clientId = (long) context->clnt;
link_parms.lockDevice = 0;
link_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT;
link_parms.device = device != NULL ? device : "device0";
- Create_LinkResp* linkresp = create_link_1(&link_parms, clnt);
+ Create_LinkResp* linkresp = create_link_1(&link_parms, context->clnt);
if (linkresp != NULL && linkresp->error == 0) {
- devicelink = linkresp->lid;
+ context->devicelink = linkresp->lid;
#ifdef DEBUG
printf("Link created, lid is %d, abort channel port %d\n", (int) linkresp->lid, linkresp->abortPort);
#endif
struct sockaddr_in serveraddr;
- if (clnt_control(clnt, CLGET_SERVER_ADDR, (char*) &serveraddr)) {
+ if (clnt_control(context->clnt, CLGET_SERVER_ADDR, (char*) &serveraddr)) {
#ifdef DEBUG
char addressstring[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &serveraddr.sin_addr, addressstring, sizeof(addressstring));
@@ -139,8 +129,8 @@ int vxi11_open(char* address, char* device) {
#endif
serveraddr.sin_port = htons(linkresp->abortPort);
int sock = RPC_ANYSOCK;
- abortclnt = clnttcp_create(&serveraddr, DEVICE_ASYNC, DEVICE_ASYNC_VERSION, &sock, 0, 0);
- if (abortclnt == NULL)
+ context->abortclnt = clnttcp_create(&serveraddr, DEVICE_ASYNC, DEVICE_ASYNC_VERSION, &sock, 0, 0);
+ if (context->abortclnt == NULL)
return 0;
}
@@ -148,6 +138,9 @@ int vxi11_open(char* address, char* device) {
// failed!
return 0;
+ context->interruptchannelopen = false;
+ context->interruptsenabled = false;
+
return 1;
}
else if (linkresp == NULL)
@@ -161,13 +154,13 @@ int vxi11_open(char* address, char* device) {
* read the status byte of the connected server
*/
-int vxi11_readstatusbyte(bool waitforlock) {
- if (clnt == NULL)
+int vxi11_readstatusbyte(Context* context, bool waitforlock) {
+ if (context->clnt == NULL)
return 0;
- Device_GenericParms params = { .lid = devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
+ Device_GenericParms params = { .lid = context->devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
.lock_timeout = VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT };
- Device_ReadStbResp* resp = device_readstb_1(&params, clnt);
+ Device_ReadStbResp* resp = device_readstb_1(&params, context->clnt);
if (resp != NULL && resp->error == 0)
return resp->stb;
@@ -181,16 +174,16 @@ int vxi11_readstatusbyte(bool waitforlock) {
* write to the connected device
*/
-int vxi11_write(char* data, unsigned int len, bool waitlock, bool end) {
- if (clnt == NULL)
+int vxi11_write(Context* context, char* data, unsigned int len, bool waitlock, bool end) {
+ if (context->clnt == NULL)
return 0;
- Device_WriteParms params = { .lid = devicelink, .io_timeout = VXI11_DEFAULT_TIMEOUT, .lock_timeout =
+ Device_WriteParms params = { .lid = context->devicelink, .io_timeout = VXI11_DEFAULT_TIMEOUT, .lock_timeout =
VXI11_DEFAULT_TIMEOUT, .flags = vxi11_generateflags(waitlock, end, false) };
params.data.data_len = len;
params.data.data_val = data;
- Device_WriteResp* resp = device_write_1(&params, clnt);
+ Device_WriteResp* resp = device_write_1(&params, context->clnt);
if (resp != NULL && resp->error == 0)
return resp->size;
else if (resp == NULL)
@@ -203,15 +196,15 @@ int vxi11_write(char* data, unsigned int len, bool waitlock, bool end) {
* read from the connected device
*/
-int vxi11_read(char* buffer, unsigned int bufferlen, bool waitlock, bool termchrset, char termchr) {
- if (clnt == NULL)
+int vxi11_read(Context* context, char* buffer, unsigned int bufferlen, bool waitlock, bool termchrset, char termchr) {
+ if (context->clnt == NULL)
return 0;
- Device_ReadParms params = { .lid = devicelink, .requestSize = 256, .io_timeout = VXI11_DEFAULT_TIMEOUT,
+ Device_ReadParms params = { .lid = context->devicelink, .requestSize = 256, .io_timeout = VXI11_DEFAULT_TIMEOUT,
.lock_timeout = VXI11_DEFAULT_TIMEOUT, .flags = vxi11_generateflags(waitlock, false, termchrset),
.termChar = termchrset ? termchr : 0 };
- Device_ReadResp* resp = device_read_1(&params, clnt);
+ Device_ReadResp* resp = device_read_1(&params, context->clnt);
if (resp != NULL && resp->error == 0) {
#ifdef DEBUG
printf("Got \"%s\" from server\n", resp->data.data_val);
@@ -230,18 +223,18 @@ int vxi11_read(char* buffer, unsigned int bufferlen, bool waitlock, bool termchr
*
*/
-int vxi11_docmd(unsigned long cmd, bool waitforlock) {
- if (clnt == NULL)
+int vxi11_docmd(Context* context, unsigned long cmd, bool waitforlock) {
+ if (context->clnt == NULL)
return 0;
- Device_DocmdParms params = { .lid = devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
+ Device_DocmdParms params = { .lid = context->devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
.io_timeout = VXI11_DEFAULT_TIMEOUT, .lock_timeout = VXI11_DEFAULT_TIMEOUT, .cmd = cmd, .network_order = 0,
.datasize = 0 };
params.data_in.data_in_len = 0;
params.data_in.data_in_val = NULL;
- Device_DocmdResp* resp = device_docmd_1(&params, clnt);
+ Device_DocmdResp* resp = device_docmd_1(&params, context->clnt);
if (resp != NULL && resp->error == 0)
return 1;
else if (resp == NULL)
@@ -254,13 +247,13 @@ int vxi11_docmd(unsigned long cmd, bool waitforlock) {
* trigger the connected device
*/
-int vxi11_trigger(bool waitforlock) {
- if (clnt == NULL)
+int vxi11_trigger(Context* context, bool waitforlock) {
+ if (context->clnt == NULL)
return 0;
- Device_GenericParms params = { .lid = devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
+ Device_GenericParms params = { .lid = context->devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
.lock_timeout = VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT };
- Device_Error* error = device_trigger_1(&params, clnt);
+ Device_Error* error = device_trigger_1(&params, context->clnt);
if (error->error == 0)
return 1;
@@ -272,12 +265,12 @@ int vxi11_trigger(bool waitforlock) {
* clear the connected device
*/
-int vxi11_clear(bool waitforlock) {
- if (clnt == NULL)
+int vxi11_clear(Context* context, bool waitforlock) {
+ if (context->clnt == NULL)
return 0;
- Device_GenericParms params = { .lid = devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
+ Device_GenericParms params = { .lid = context->devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
.lock_timeout = VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT };
- Device_Error* error = device_clear_1(&params, clnt);
+ Device_Error* error = device_clear_1(&params, context->clnt);
if (error != NULL && error->error == 0)
return 1;
else if (error == NULL)
@@ -290,12 +283,12 @@ int vxi11_clear(bool waitforlock) {
* remote the connected device
*/
-int vxi11_remote(bool waitforlock) {
- if (clnt == NULL)
+int vxi11_remote(Context* context, bool waitforlock) {
+ if (context->clnt == NULL)
return 0;
- Device_GenericParms params = { .lid = devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
+ Device_GenericParms params = { .lid = context->devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
.lock_timeout = VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT };
- Device_Error* error = device_remote_1(&params, clnt);
+ Device_Error* error = device_remote_1(&params, context->clnt);
if (error != NULL && error->error == 0)
return 1;
else if (error == NULL)
@@ -308,12 +301,12 @@ int vxi11_remote(bool waitforlock) {
* local the connected device
*/
-int vxi11_local(bool waitforlock) {
- if (clnt == NULL)
+int vxi11_local(Context* context, bool waitforlock) {
+ if (context->clnt == NULL)
return 0;
- Device_GenericParms params = { .lid = devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
+ Device_GenericParms params = { .lid = context->devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
.lock_timeout = VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT };
- Device_Error* error = device_local_1(&params, clnt);
+ Device_Error* error = device_local_1(&params, context->clnt);
if (error != NULL && error->error == 0)
return 1;
else if (error == NULL)
@@ -326,12 +319,12 @@ int vxi11_local(bool waitforlock) {
* lock the connected device
*/
-int vxi11_lock(bool waitforlock) {
- if (clnt == NULL)
+int vxi11_lock(Context* context, bool waitforlock) {
+ if (context->clnt == NULL)
return 0;
- Device_LockParms params = { .lid = devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
+ Device_LockParms params = { .lid = context->devicelink, .flags = vxi11_generateflags(waitforlock, false, false),
.lock_timeout = VXI11_DEFAULT_TIMEOUT };
- Device_Error* error = device_lock_1(&params, clnt);
+ Device_Error* error = device_lock_1(&params, context->clnt);
if (error != NULL && error->error == 0)
return 1;
else if (error == NULL)
@@ -344,10 +337,10 @@ int vxi11_lock(bool waitforlock) {
* unlock the connected device
*/
-int vxi11_unlock() {
- if (clnt == NULL)
+int vxi11_unlock(Context* context) {
+ if (context->clnt == NULL)
return 0;
- Device_Error* error = device_unlock_1(&devicelink, clnt);
+ Device_Error* error = device_unlock_1(&(context->devicelink), context->clnt);
if (error != NULL && error->error == 0)
return 1;
else if (error == NULL)
@@ -381,7 +374,7 @@ static gpointer interruptthreadfunc(gpointer data) {
struct pollfd *my_pollfd = NULL;
int last_max_pollfd = 0;
- while (interruptchannelopen) {
+ while (interruptserverstarted) {
int max_pollfd = svc_max_pollfd;
if (max_pollfd == 0 && svc_pollfd == NULL)
break;
@@ -423,61 +416,72 @@ static gpointer interruptthreadfunc(gpointer data) {
return NULL;
}
-/**
- * create an interrupt channel from the connected device
- */
-int vxi11_create_intr_chan() {
- if (interruptchannelopen)
- return 0;
- else if (clnt == NULL)
- return 0;
- else if (interruptthread != NULL)
- return 0;
-
- interruptchannelopen = true;
- unsigned int port = -1;
+int vxi11_start_interrupt_server(void (*callback)(char* handle)) {
+ interruptcallback = callback;
+ interruptserverstarted = true;
g_thread_init(NULL);
- interruptthread = g_thread_create(interruptthreadfunc, &port, true, NULL);
+ interruptthread = g_thread_create(interruptthreadfunc, &interruptserverport, true, NULL);
if (interruptthread == NULL)
return 0;
- while (port == -1) { // spin
+ while (interruptserverport == -1) { // spin
usleep(200);
};
+ return 1;
+}
+
+int vxi11_stop_interrupt_server() {
+#ifdef DEBUG
+ printf("Waiting for interrupt thread to die\n");
+#endif
+ interruptserverstarted = false;
+ g_thread_join(interruptthread);
+ interruptthread = NULL;
+ return 1;
+}
+
+/**
+ * create an interrupt channel from the connected device
+ */
+int vxi11_create_intr_chan(Context* context) {
+ if (context->clnt == NULL || context->interruptchannelopen)
+ return 0;
+ else if (interruptthread == NULL) {
+#ifdef DEBUG
+ printf("interrupt thread isn't running\n");
+#endif
+ return 0;
+ }
struct sockaddr_in myaddress;
get_myaddress(&myaddress);
- Device_RemoteFunc remotefunc = { .hostAddr = myaddress.sin_addr.s_addr, .hostPort = port, .progNum = DEVICE_INTR,
- .progVers = DEVICE_INTR_VERSION, .progFamily = DEVICE_TCP };
- Device_Error* error = create_intr_chan_1(&remotefunc, clnt);
- if (error != NULL && error->error == 0)
+ Device_RemoteFunc remotefunc = { .hostAddr = myaddress.sin_addr.s_addr, .hostPort = interruptserverport, .progNum =
+ DEVICE_INTR, .progVers = DEVICE_INTR_VERSION, .progFamily = DEVICE_TCP };
+ Device_Error* error = create_intr_chan_1(&remotefunc, context->clnt);
+ if (error != NULL && error->error == 0) {
+ context->interruptchannelopen = true;
return 1;
- else if (error == NULL) {
- killinterruptthreadandwait();
- return 0;
}
- else {
- killinterruptthreadandwait();
+ else if (error == NULL)
+ return 0;
+ else
return -(error->error);
- }
}
/**
* destroy an interrupt channel from the connected device
*/
-int vxi11_destroy_intr_chan() {
- if (!interruptchannelopen)
- return 0;
- else if (clnt == NULL)
+int vxi11_destroy_intr_chan(Context* context) {
+ if (context->clnt == NULL || !(context->interruptchannelopen))
return 0;
else if (interruptthread == NULL)
return 0;
- Device_Error* error = destroy_intr_chan_1(NULL, clnt);
+ Device_Error* error = destroy_intr_chan_1(NULL, context->clnt);
if (error != NULL && error->error == 0) {
- killinterruptthreadandwait();
+ context->interruptchannelopen = false;
return 1;
}
else if (error == NULL)
@@ -490,27 +494,24 @@ int vxi11_destroy_intr_chan() {
* enable interrupts
*/
-int vxi11_enable_srq(bool enable, char* handle, void (*callback)(void)) {
- if (!interruptchannelopen)
- return 0;
- else if (clnt == NULL)
+int vxi11_enable_srq(Context* context, bool enable, char* handle) {
+ if (context->clnt == NULL || !(context->interruptchannelopen))
return 0;
else if (interruptthread == NULL)
return 0;
- Device_EnableSrqParms params = { .lid = devicelink, .enable = enable };
+ Device_EnableSrqParms params = { .lid = context->devicelink, .enable = enable };
if (enable) {
if (handle != NULL) {
params.handle.handle_val = handle;
params.handle.handle_len = strlen(handle) + 1;
}
- interruptcallback = callback;
}
else {
params.handle.handle_val = NULL;
params.handle.handle_len = 0;
}
- Device_Error* error = device_enable_srq_1(&params, clnt);
+ Device_Error* error = device_enable_srq_1(&params, context->clnt);
if (error != NULL && error->error == 0) {
return 1;
}
@@ -524,10 +525,10 @@ int vxi11_enable_srq(bool enable, char* handle, void (*callback)(void)) {
* send an abort to the connected device
*/
-int vxi11_abort() {
- if (abortclnt == NULL)
+int vxi11_abort(Context* context) {
+ if (context->abortclnt == NULL)
return 0;
- Device_Error* error = device_abort_1(&devicelink, abortclnt);
+ Device_Error* error = device_abort_1(&(context->devicelink), context->abortclnt);
if (error != NULL && error->error == 0)
return 1;
else if (error == NULL)
@@ -540,15 +541,15 @@ int vxi11_abort() {
* close the current link and free the RPC client
*/
-int vxi11_close() {
- if (clnt == NULL)
+int vxi11_close(Context* context) {
+ if (context->clnt == NULL)
return 0;
- Device_Error* error = destroy_link_1(&devicelink, clnt);
- clnt_destroy(clnt);
- clnt = NULL;
- clnt_destroy(abortclnt);
- abortclnt = NULL;
+ Device_Error* error = destroy_link_1(&(context->devicelink), context->clnt);
+ clnt_destroy(context->clnt);
+ context->clnt = NULL;
+ clnt_destroy(context->abortclnt);
+ context->abortclnt = NULL;
if (error != NULL && error->error == 0)
return 1;
diff --git a/libvxi11client/libvxi11client.h b/libvxi11client/libvxi11client.h
index d94662e..27da46c 100644
--- a/libvxi11client/libvxi11client.h
+++ b/libvxi11client/libvxi11client.h
@@ -1,4 +1,5 @@
#include <stdbool.h>
+#include "vxi11.h"
#define ERR_SYNTAXERROR -1
#define ERR_DEVICENOTACCESSIBLE -3
@@ -15,19 +16,29 @@
#define ERR_ABORT -23
#define ERR_CHANNELALREADYESTABLISHED -29
-int vxi11_open(char* address, char* device);
-int vxi11_abort(void);
-int vxi11_trigger(bool waitforlock);
-int vxi11_clear(bool waitforlock);
-int vxi11_write(char* data, unsigned int len, bool waitlock, bool end);
-int vxi11_read(char* buffer, unsigned int bufferlen, bool waitlock, bool termchrset, char termchr);
-int vxi11_lock(bool waitforlock);
-int vxi11_unlock(void);
-int vxi11_local(bool waitforlock);
-int vxi11_remote(bool waitforlock);
-int vxi11_readstatusbyte(bool waitforlock);
-int vxi11_create_intr_chan(void);
-int vxi11_destroy_intr_chan(void);
-int vxi11_enable_srq(bool enable, char* handle, void (*callback)(void));
-int vxi11_docmd(unsigned long cmd, bool waitforlock);
-int vxi11_close(void);
+typedef struct {
+ CLIENT* clnt;
+ CLIENT* abortclnt;
+ Device_Link devicelink;
+ bool interruptchannelopen;
+ bool interruptsenabled;
+} Context;
+
+int vxi11_open(Context* context, char* address, char* device);
+int vxi11_abort(Context* context);
+int vxi11_trigger(Context* context, bool waitforlock);
+int vxi11_clear(Context* context, bool waitforlock);
+int vxi11_write(Context* context, char* data, unsigned int len, bool waitlock, bool end);
+int vxi11_read(Context* context, char* buffer, unsigned int bufferlen, bool waitlock, bool termchrset, char termchr);
+int vxi11_lock(Context* context, bool waitforlock);
+int vxi11_unlock(Context* context);
+int vxi11_local(Context* context, bool waitforlock);
+int vxi11_remote(Context* context, bool waitforlock);
+int vxi11_readstatusbyte(Context* context, bool waitforlock);
+int vxi11_create_intr_chan(Context* context);
+int vxi11_destroy_intr_chan(Context* context);
+int vxi11_enable_srq(Context* context, bool enable, char* handle);
+int vxi11_start_interrupt_server(void (*callback)(char* handle));
+int vxi11_stop_interrupt_server();
+int vxi11_docmd(Context* context, unsigned long cmd, bool waitforlock);
+int vxi11_close(Context* context);
diff --git a/libvxi11client/perlbits/README b/libvxi11client/perlbits/README
index a789fc8..ba3e278 100644
--- a/libvxi11client/perlbits/README
+++ b/libvxi11client/perlbits/README
@@ -2,7 +2,7 @@ VXI11-Client version 0.01
=========================
This module is a wrapper around a C library that uses libc's built in
-Sun RPC support to talk to VXI11 networked instruments.
+Sun RPC support to talk to VXI11 networked instruments.
It supports only one instrument at a time.