#define _GNU_SOURCE #include "vxi11.h" #include "vxi11_server.h" #include #include #include #include #include #include #include #include #define VXI11_DEFAULT_TIMEOUT 1000 #ifndef SIG_PF #define SIG_PF void(*)(int) #endif static void device_async_1(struct svc_req *rqstp, register SVCXPRT *transp) { union { Device_Link device_abort_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_abort: _xdr_argument = (xdrproc_t) xdr_Device_Link; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) device_abort_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 void device_core_1(struct svc_req *rqstp, register SVCXPRT *transp) { union { Create_LinkParms create_link_1_arg; Device_WriteParms device_write_1_arg; Device_ReadParms device_read_1_arg; Device_GenericParms device_readstb_1_arg; Device_GenericParms device_trigger_1_arg; Device_GenericParms device_clear_1_arg; Device_GenericParms device_remote_1_arg; Device_GenericParms device_local_1_arg; Device_LockParms device_lock_1_arg; Device_Link device_unlock_1_arg; Device_EnableSrqParms device_enable_srq_1_arg; Device_DocmdParms device_docmd_1_arg; Device_Link destroy_link_1_arg; Device_RemoteFunc create_intr_chan_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 create_link: _xdr_argument = (xdrproc_t) xdr_Create_LinkParms; _xdr_result = (xdrproc_t) xdr_Create_LinkResp; local = (char *(*)(char *, struct svc_req *)) create_link_1_svc; break; case device_write: _xdr_argument = (xdrproc_t) xdr_Device_WriteParms; _xdr_result = (xdrproc_t) xdr_Device_WriteResp; local = (char *(*)(char *, struct svc_req *)) device_write_1_svc; break; case device_read: _xdr_argument = (xdrproc_t) xdr_Device_ReadParms; _xdr_result = (xdrproc_t) xdr_Device_ReadResp; local = (char *(*)(char *, struct svc_req *)) device_read_1_svc; break; case device_readstb: _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; _xdr_result = (xdrproc_t) xdr_Device_ReadStbResp; local = (char *(*)(char *, struct svc_req *)) device_readstb_1_svc; break; case device_trigger: _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) device_trigger_1_svc; break; case device_clear: _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) device_clear_1_svc; break; case device_remote: _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) device_remote_1_svc; break; case device_local: _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) device_local_1_svc; break; case device_lock: _xdr_argument = (xdrproc_t) xdr_Device_LockParms; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) device_lock_1_svc; break; case device_unlock: _xdr_argument = (xdrproc_t) xdr_Device_Link; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) device_unlock_1_svc; break; case device_enable_srq: _xdr_argument = (xdrproc_t) xdr_Device_EnableSrqParms; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) device_enable_srq_1_svc; break; case device_docmd: _xdr_argument = (xdrproc_t) xdr_Device_DocmdParms; _xdr_result = (xdrproc_t) xdr_Device_DocmdResp; local = (char *(*)(char *, struct svc_req *)) device_docmd_1_svc; break; case destroy_link: _xdr_argument = (xdrproc_t) xdr_Device_Link; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) destroy_link_1_svc; break; case create_intr_chan: _xdr_argument = (xdrproc_t) xdr_Device_RemoteFunc; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) create_intr_chan_1_svc; break; case destroy_intr_chan: _xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_Device_Error; local = (char *(*)(char *, struct svc_req *)) destroy_intr_chan_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"); register SVCXPRT *transp; pmap_unset(DEVICE_ASYNC, DEVICE_ASYNC_VERSION); pmap_unset(DEVICE_CORE, DEVICE_CORE_VERSION); transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { fprintf(stderr, "%s", "cannot create udp service."); exit(1); } if (!svc_register(transp, DEVICE_ASYNC, DEVICE_ASYNC_VERSION, device_async_1, IPPROTO_UDP)) { fprintf(stderr, "%s", "unable to register (DEVICE_ASYNC, DEVICE_ASYNC_VERSION, udp)."); exit(1); } if (!svc_register(transp, DEVICE_CORE, DEVICE_CORE_VERSION, device_core_1, IPPROTO_UDP)) { fprintf(stderr, "%s", "unable to register (DEVICE_CORE, DEVICE_CORE_VERSION, udp)."); exit(1); } transp = svctcp_create(RPC_ANYSOCK, 0, 0); if (transp == NULL) { fprintf(stderr, "%s", "cannot create tcp service."); exit(1); } if (!svc_register(transp, DEVICE_ASYNC, DEVICE_ASYNC_VERSION, device_async_1, IPPROTO_TCP)) { fprintf(stderr, "%s", "unable to register (DEVICE_ASYNC, DEVICE_ASYNC_VERSION, tcp)."); exit(1); } if (!svc_register(transp, DEVICE_CORE, DEVICE_CORE_VERSION, device_core_1, IPPROTO_TCP)) { fprintf(stderr, "%s", "unable to register (DEVICE_CORE, DEVICE_CORE_VERSION, tcp)."); exit(1); } int i, j; struct pollfd *my_pollfd = NULL; int last_max_pollfd = 0; while (1) { int max_pollfd = svc_max_pollfd; if (max_pollfd == 0 && svc_pollfd == NULL) { break; } if (last_max_pollfd != max_pollfd) { struct pollfd *new_pollfd = realloc(my_pollfd, sizeof(struct pollfd) * max_pollfd); if (new_pollfd == NULL) { break; } my_pollfd = new_pollfd; last_max_pollfd = max_pollfd; } for (i = 0; i < max_pollfd; ++i) { my_pollfd[i].fd = svc_pollfd[i].fd; my_pollfd[i].events = svc_pollfd[i].events | POLLRDHUP; // add the "socket is dead" event my_pollfd[i].revents = 0; } j = poll(my_pollfd, max_pollfd, VXI11_DEFAULT_TIMEOUT); for (i = 0; i < max_pollfd; i++) { if (my_pollfd[i].revents & POLLRDHUP) { vxi11_deadsocketcallback(my_pollfd[i].fd); } } switch (j) { case -1: break; case 0: continue; default: svc_getreq_poll(my_pollfd, i); continue; } break; } //svc_run(); //fprintf(stderr, "%s", "svc_run returned"); }