diff options
-rw-r--r-- | instr-daemon.c | 8 | ||||
-rw-r--r-- | libvxi11client/Makefile | 5 | ||||
-rw-r--r-- | libvxi11client/libvxi11client.c | 108 | ||||
-rw-r--r-- | vxi11_server.c | 20 | ||||
-rw-r--r-- | vxi11_svc.c | 51 |
5 files changed, 120 insertions, 72 deletions
diff --git a/instr-daemon.c b/instr-daemon.c index 9b4e513..b0e05cd 100644 --- a/instr-daemon.c +++ b/instr-daemon.c @@ -293,11 +293,9 @@ int main(int argc, char **argv) g_timeout_add (20, (GSourceFunc) periodic_poll, NULL); g_timeout_add (100, (GSourceFunc) finish_boot, NULL); - //GThread *vxithread =(vxithreadfunc, NULL,false, NULL); - //if(vxithread == NULL) - // printf("Couldn't create vxi thread\n"); - - vxi_main(); + GThread *vxithread =g_thread_create(vxithreadfunc, NULL,false, NULL); + if(vxithread == NULL) + printf("Couldn't create vxi thread\n"); g_main_loop_run (loop); 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) diff --git a/vxi11_server.c b/vxi11_server.c index 06a8c44..0944b60 100644 --- a/vxi11_server.c +++ b/vxi11_server.c @@ -213,6 +213,8 @@ destroy_link_1_svc(Device_Link *argp, struct svc_req *rqstp) { return &result; } +static bool havechannel = false; + Device_Error * create_intr_chan_1_svc(Device_RemoteFunc *argp, struct svc_req *rqstp) { static Device_Error result; @@ -221,17 +223,16 @@ create_intr_chan_1_svc(Device_RemoteFunc *argp, struct svc_req *rqstp) { #ifdef DEBUG char clientaddressstring[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &argp->hostAddr, clientaddressstring, sizeof(clientaddressstring)); - printf("Client %s is asking for an interrupt connection on port %u\n", clientaddressstring, ntohs(argp->hostPort)); + printf("Client %s is asking for an interrupt connection on port %u\n", clientaddressstring, argp->hostPort); #endif - bool alreadyhavechannel = false; - if (alreadyhavechannel) { + if (havechannel) { result.error = ERR_CHANNELALREADYESTABLISHED; } else { struct sockaddr_in clientaddr; clientaddr.sin_family = AF_INET; - clientaddr.sin_port = argp->hostPort; + clientaddr.sin_port = htons(argp->hostPort); clientaddr.sin_addr.s_addr = argp->hostAddr; int sock = RPC_ANYSOCK; CLIENT* clnt = clnttcp_create(&clientaddr, DEVICE_INTR, DEVICE_INTR_VERSION, &sock, 0, 0); @@ -242,6 +243,7 @@ create_intr_chan_1_svc(Device_RemoteFunc *argp, struct svc_req *rqstp) { result.error = ERR_CHANNELNOTESTABLISHED; } else { + havechannel = true; result.error = 0; } } @@ -252,21 +254,13 @@ Device_Error * destroy_intr_chan_1_svc(void *argp, struct svc_req *rqstp) { static Device_Error result; printf("destroy_intr_chan_1_svc()\n"); - bool havechannel = false; if (!havechannel) { result.error = ERR_CHANNELNOTESTABLISHED; } else { + havechannel = false; result.error = 0; } return &result; } -/** - void * - device_intr_srq_1_svc(Device_SrqParms *argp, struct svc_req *rqstp) { - printf("device_intr_srq_1_svc()\n"); - static char * result; - return (void *) &result; - } - **/ diff --git a/vxi11_svc.c b/vxi11_svc.c index 96a967f..edc4212 100644 --- a/vxi11_svc.c +++ b/vxi11_svc.c @@ -186,48 +186,6 @@ static void device_core_1(struct svc_req *rqstp, register SVCXPRT *transp) { return; } -/* - 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; - }*/ - void vxi_main() { printf("VXI service started\n"); @@ -236,7 +194,6 @@ void vxi_main() { pmap_unset(DEVICE_ASYNC, DEVICE_ASYNC_VERSION); pmap_unset(DEVICE_CORE, DEVICE_CORE_VERSION); - //pmap_unset(DEVICE_INTR, DEVICE_INTR_VERSION); transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { @@ -251,10 +208,6 @@ void vxi_main() { fprintf(stderr, "%s", "unable to register (DEVICE_CORE, DEVICE_CORE_VERSION, udp)."); exit(1); } - //if (!svc_register(transp, DEVICE_INTR, DEVICE_INTR_VERSION, device_intr_1, IPPROTO_UDP)) { - // fprintf (stderr, "%s", "unable to register (DEVICE_INTR, DEVICE_INTR_VERSION, udp)."); - // exit(1); - //} transp = svctcp_create(RPC_ANYSOCK, 0, 0); if (transp == NULL) { @@ -269,10 +222,6 @@ void vxi_main() { fprintf(stderr, "%s", "unable to register (DEVICE_CORE, DEVICE_CORE_VERSION, tcp)."); exit(1); } - //if (!svc_register(transp, DEVICE_INTR, DEVICE_INTR_VERSION, device_intr_1, IPPROTO_TCP)) { - // fprintf (stderr, "%s", "unable to register (DEVICE_INTR, DEVICE_INTR_VERSION, tcp)."); - // exit(1); - //} svc_run(); fprintf(stderr, "%s", "svc_run returned"); |