summaryrefslogtreecommitdiff
path: root/libvxi11client
diff options
context:
space:
mode:
authordaniel <danieruru@gmail.com>2013-01-10 19:51:28 +0900
committerdaniel <danieruru@gmail.com>2013-01-10 19:51:28 +0900
commit845db4b79f9b72592e662a6daa5917f84ff12e04 (patch)
tree4de44da03ac0e7e009c9fec3fe299af2158e442d /libvxi11client
parentbd451ce0f4855bc2dfd8c19b1f17a5cd60eb6650 (diff)
the interrupt channel works now.
Diffstat (limited to 'libvxi11client')
-rw-r--r--libvxi11client/Makefile5
-rw-r--r--libvxi11client/libvxi11client.c108
2 files changed, 110 insertions, 3 deletions
diff --git a/libvxi11client/Makefile b/libvxi11client/Makefile
index 560fb7a..b313b63 100644
--- a/libvxi11client/Makefile
+++ b/libvxi11client/Makefile
@@ -1,9 +1,10 @@
-CFLAGS = -Wall -std=gnu99
+CFLAGS = -Wall -std=gnu99 `pkg-config --cflags gthread-2.0`
+LFLAGS = `pkg-config --libs gthread-2.0`
all: client
client: libvxi11client.o vxi11_clnt.o vxi11_xdr.o client.o
- $(CC) $(CFLAGS) -o $@ $^
+ $(CC) -o $@ $^ $(LFLAGS)
client.o: client.c libvxi11client.h
$(CC) $(CFLAGS) -c $<
diff --git a/libvxi11client/libvxi11client.c b/libvxi11client/libvxi11client.c
index 7b69fc5..d0eef3d 100644
--- a/libvxi11client/libvxi11client.c
+++ b/libvxi11client/libvxi11client.c
@@ -1,6 +1,8 @@
#include <stdbool.h>
#include <rpc/rpc.h>
#include <netinet/in.h>
+#include <glib.h>
+#include <poll.h>
#include "vxi11.h"
#define DEBUG
@@ -25,6 +27,54 @@ static CLIENT* clnt = NULL;
static CLIENT* abortclnt = NULL;
static Device_Link link;
+void *
+device_intr_srq_1_svc(Device_SrqParms *argp, struct svc_req *rqstp) {
+#ifdef DEBUG
+ printf("device_intr_srq_1_svc()\n");
+#endif
+ static char * result;
+ return (void *) &result;
+}
+
+static void device_intr_1(struct svc_req *rqstp, register SVCXPRT *transp) {
+ union {
+ Device_SrqParms device_intr_srq_1_arg;
+ } argument;
+ char *result;
+ xdrproc_t _xdr_argument, _xdr_result;
+ char *(*local)(char *, struct svc_req *);
+
+ switch (rqstp->rq_proc) {
+ case NULLPROC:
+ (void) svc_sendreply(transp, (xdrproc_t) xdr_void, (char *) NULL);
+ return;
+
+ case device_intr_srq:
+ _xdr_argument = (xdrproc_t) xdr_Device_SrqParms;
+ _xdr_result = (xdrproc_t) xdr_void;
+ local = (char *(*)(char *, struct svc_req *)) device_intr_srq_1_svc;
+ break;
+
+ default:
+ svcerr_noproc(transp);
+ return;
+ }
+ memset((char *) &argument, 0, sizeof(argument));
+ if (!svc_getargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
+ svcerr_decode(transp);
+ return;
+ }
+ result = (*local)((char *) &argument, rqstp);
+ if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
+ svcerr_systemerr(transp);
+ }
+ if (!svc_freeargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
+ fprintf(stderr, "%s", "unable to free arguments");
+ exit(1);
+ }
+ return;
+}
+
static Device_Flags vxi11_generateflags(bool waitlock, bool end, bool termchrset) {
Device_Flags flags = 0;
if (waitlock)
@@ -282,6 +332,54 @@ int vxi11_unlock() {
return -(error->error);
}
+static gpointer interruptthreadfunc(gpointer data) {
+#ifdef DEBUG
+ printf("Interrupt channel thread started\n");
+#endif
+ SVCXPRT *transp;
+ transp = svctcp_create(RPC_ANYSOCK, 0, 0);
+ if (transp == NULL) {
+ fprintf(stderr, "%s", "cannot create tcp service.");
+ return 0;
+ }
+
+#ifdef DEBUG
+ printf("Interrupt channel on port %d tcp\n", transp->xp_port);
+#endif
+
+ if (!svc_register(transp, DEVICE_INTR, DEVICE_INTR_VERSION, device_intr_1, 0)) {
+ fprintf(stderr, "%s", "unable to register (DEVICE_INTR, DEVICE_INTR_VERSION, tcp).\n");
+ return 0;
+ }
+ *((u_short*) data) = transp->xp_port;
+
+ int no_of_fds;
+ int i;
+ struct pollfd pollfd_set[1024];
+
+ //svc_run();
+ // stolen from: http://pic.dhe.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.commtechref%2Fdoc%2Fcommtrf1%2Fsvc_getreq_poll.htm
+ while (1) {
+ /* initialize the pollfd_set array and
+ get no of file descriptors in "no_of_fds"*/
+
+ /* Keep polling on file descriptors */
+ switch (i = poll(pollfd_set, no_of_fds, -1)) {
+ case -1:
+ case 0:
+ continue;
+ default:
+ /* Handle RPC request on each file descriptor */
+ svc_getreq_poll(pollfd_set, i);
+ }
+ }
+
+#ifdef DEBUG
+ printf("Interrupt channel thread ended\n");
+#endif
+ return NULL;
+}
+
/**
* create an interrupt channel from the connected device
*/
@@ -289,10 +387,18 @@ int vxi11_create_intr_chan() {
if (clnt == NULL)
return 0;
+ u_short port = 0;
+ g_thread_init(NULL);
+ GThread* interruptthread = g_thread_create(interruptthreadfunc, &port, false, NULL);
+
+ sleep(2);
+
+ //
+
struct sockaddr_in myaddress;
get_myaddress(&myaddress);
- Device_RemoteFunc remotefunc = { .hostAddr = myaddress.sin_addr.s_addr, .hostPort = 0x0, .progNum = DEVICE_INTR,
+ 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)