summaryrefslogtreecommitdiff
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
parentbd451ce0f4855bc2dfd8c19b1f17a5cd60eb6650 (diff)
the interrupt channel works now.
-rw-r--r--instr-daemon.c8
-rw-r--r--libvxi11client/Makefile5
-rw-r--r--libvxi11client/libvxi11client.c108
-rw-r--r--vxi11_server.c20
-rw-r--r--vxi11_svc.c51
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");