summaryrefslogtreecommitdiff
path: root/libvxi11client/libvxi11client.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvxi11client/libvxi11client.c')
-rw-r--r--libvxi11client/libvxi11client.c225
1 files changed, 113 insertions, 112 deletions
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;