diff options
author | daniel <danieruru@gmail.com> | 2013-01-10 19:51:28 +0900 |
---|---|---|
committer | daniel <danieruru@gmail.com> | 2013-01-10 19:51:28 +0900 |
commit | 845db4b79f9b72592e662a6daa5917f84ff12e04 (patch) | |
tree | 4de44da03ac0e7e009c9fec3fe299af2158e442d /libvxi11client/libvxi11client.c | |
parent | bd451ce0f4855bc2dfd8c19b1f17a5cd60eb6650 (diff) |
the interrupt channel works now.
Diffstat (limited to 'libvxi11client/libvxi11client.c')
-rw-r--r-- | libvxi11client/libvxi11client.c | 108 |
1 files changed, 107 insertions, 1 deletions
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) |