From e6f31688466664d5cb75a0e1603bd42a00e710bd Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Sat, 29 Apr 2000 19:53:34 +0000 Subject: New test from Eric Norum to exercise RPC/XDR. --- rpc_demo/Makefile | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ rpc_demo/Makefile.host | 26 +++++++++++++++++ rpc_demo/README | 58 +++++++++++++++++++++++++++++++++++++ rpc_demo/init.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ rpc_demo/msg.x | 12 ++++++++ rpc_demo/msg_main.c | 64 +++++++++++++++++++++++++++++++++++++++++ rpc_demo/msg_proc.c | 24 ++++++++++++++++ rpc_demo/rprintmsg.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 413 insertions(+) create mode 100644 rpc_demo/Makefile create mode 100644 rpc_demo/Makefile.host create mode 100644 rpc_demo/README create mode 100644 rpc_demo/init.c create mode 100644 rpc_demo/msg.x create mode 100644 rpc_demo/msg_main.c create mode 100644 rpc_demo/msg_proc.c create mode 100644 rpc_demo/rprintmsg.c diff --git a/rpc_demo/Makefile b/rpc_demo/Makefile new file mode 100644 index 0000000..f923bb6 --- /dev/null +++ b/rpc_demo/Makefile @@ -0,0 +1,77 @@ +# +# Makefile for RTEMS RPC server or client +# +# To build an RTEMS RPC server +# make +# To build an RTEMS RPC client +# `make SERVER=hostname' +# where `hostname' is the name of the RPC server +# +SAMPLE=rpc +PGM=${ARCH}/$(SAMPLE).exe + +MANAGERS=io event semaphore timer + +# C source names, if any, go here -- minus the .c +ifdef SERVER +C_PIECES= init rprintmsg msg_clnt +else +C_PIECES= init msg_main msg_proc +endif +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +DOCTYPES= +DOCS=$(DOCTYPES:%=$(SAMPLE).%) + +SRCS=$(DOCS) $(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +PRINT_SRCS=$(DOCS) + +PGM=${ARCH}/$(SAMPLE).exe + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +ifdef SERVER +DEFINES += "-DSERVER=$(SERVER)" +endif +DEFINES += -Dmain=rtems_main +#CPPFLAGS += -I../ftp.FreeBSD.org/pub/FreeBSD/branches/-current/src/include +#CPPFLAGS += -I../ftp.FreeBSD.org/pub/FreeBSD/branches/-current/src/sys +CFLAGS += +CFLAGS_OPTIMIZE_V += + +LD_PATHS += +#LD_LIBS += ../ftp.FreeBSD.org/pub/FreeBSD/branches/-current/src/lib/libc/rpc/o-optimize/librpc.a +#LD_LIBS += ../ftp.FreeBSD.org/pub/FreeBSD/branches/-current/src/lib/libc/xdr/o-optimize/libxdr.a + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: ${ARCH} $(SRCS) $(PGM) + +${PGM}: $(OBJS) $(LINK_FILES) + $(make-exe) + +foo: + echo $(RTEMS_BSP) +# Install the program(s), appending _g or _p as appropriate. +# for include files, just use $(INSTALL) +install: all + $(INSTALL_VARIANT) -m 555 ${PGM} ${PROJECT_RELEASE}/tests diff --git a/rpc_demo/Makefile.host b/rpc_demo/Makefile.host new file mode 100644 index 0000000..5f18def --- /dev/null +++ b/rpc_demo/Makefile.host @@ -0,0 +1,26 @@ +CFLAGS += -g + +all: server rprintmsg + +rprintmsg: rprintmsg.o msg_clnt.o + $(CC) $(CFLAGS) -o rprintmsg rprintmsg.o msg_clnt.o + +server: msg_main.o msg_proc.o + $(CC) $(CFLAGS) -o server msg_main.o msg_proc.o + +clean: + rm -f rprintmsg server \ + msg_main.o msg_server.o msg_proc.o \ + rprintmsg.o msg_clnt.o \ + msg_server.h msg_clnt.c msg.h + +msg_main.o: msg.h msg_server.h + +msg.h: msg.x + rpcgen -h msg.x >msg.h + +msg_server.h: msg.x + rpcgen -m msg.x >msg_server.h + +msg_clnt.c: msg.x + rpcgen -l msg.x >msg_clnt.c diff --git a/rpc_demo/README b/rpc_demo/README new file mode 100644 index 0000000..a386124 --- /dev/null +++ b/rpc_demo/README @@ -0,0 +1,58 @@ +INTRODUCTION +============ +Example RPC server and client. + +The test programs are symmetrical: + - The client runs on the host machine or on the RTEMS target. + - The server runs on the host machine or on the RTEMS target. + + +BUILDING +======== +You must have rpcgen installed on your host machine. + +You must build the host tools first: + make -f Makefile.host + +Then you can build the RTEMS version of the server + make +or you can buile the RTEMS version of the client + make SERVER=hostname +where hostname is the name of the machine running the RPC server. + + +RUNNING +======= +1) Server on RTEMS machine, client on host machine: + Download and run the server code on the RTEMS machine + Run the client on the host machine + ./rprintmsg rtems_hostname "Some message to print" + +2) Server on host machine, client on RTEMS machine: + Start server on host machine + ./server + Download and run the client code on the RTEMS machine + + +CHANGING +======== +If you want to try out more or different remote procedures: + 1) Make the changes to msg.x. + 2) Make the corresponding server changes to msg_proc.c. + 3) Make the corresponding client changes to rprintmsg.c. + + +FILES +===== +init.c - RTEMS configuration/initial task. +msg.x - Source file for rpcgen. +msg_main.c - Server main routine -- RTEMS or host. +msg_proc.c - Example implementation of RPC server-side routines. +rprintmsg.c - Client main routine -- RTEMS or host. + + +CLEANUP +======= +To clean up the results of the build process: + make clean + make -f Makefile.host clean diff --git a/rpc_demo/init.c b/rpc_demo/init.c new file mode 100644 index 0000000..4ef82cf --- /dev/null +++ b/rpc_demo/init.c @@ -0,0 +1,78 @@ +/* + * RTEMS configuration/initialization + */ + +#include +#include +#include +#include + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define STACK_CHECKER_ON 1 +#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER +#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 2 +#define CONFIGURE_MAXIMUM_SEMAPHORES 20 +#define CONFIGURE_MAXIMUM_TASKS 12 + +#define CONFIGURE_MICROSECONDS_PER_TICK 20000 + +#define CONFIGURE_INIT_TASK_PRIORITY 99 +#define CONFIGURE_INIT_TASK_STACK_SIZE (16*1024) +#define CONFIGURE_INIT + +rtems_task Init(rtems_task_argument argument); + +#include + +/* + * Network configuration + */ +#define NETWORK_TASK_PRIORITY 50 +static struct rtems_bsdnet_ifconfig netdriver_config = { + RTEMS_BSP_NETWORK_DRIVER_NAME, + RTEMS_BSP_NETWORK_DRIVER_ATTACH, +}; + +struct rtems_bsdnet_config rtems_bsdnet_config = { + &netdriver_config, /* Network interface */ + rtems_bsdnet_do_bootp, /* Use BOOTP to get network configuration */ + NETWORK_TASK_PRIORITY, /* Network task priority */ +}; + +#ifdef SERVER +#define T(x) __TXT(x) +#define __TXT(s) #s +static char *av[] = { + "RPC client", + T(SERVER), + "Test Message", + NULL +}; +#else +static char *av[] = { + "RPC server", + NULL +}; +#endif +static int ac = (sizeof av / sizeof av[0]) - 1; + +extern int rtems_main (int argc, char **argv); + +rtems_task +Init (rtems_task_argument ignored) +{ + rtems_bsdnet_initialize_network (); + rtems_bsdnet_synchronize_ntp (0, 0); + + rtems_main (ac, av); + printf ("*** RPC Test Finish ***\n"); + exit (0); +} + +/* + * Dummy portmapper routines + */ +pmap_set () { ; } +pmap_unset () { ; } diff --git a/rpc_demo/msg.x b/rpc_demo/msg.x new file mode 100644 index 0000000..ec7dbe6 --- /dev/null +++ b/rpc_demo/msg.x @@ -0,0 +1,12 @@ +#ifdef RPC_HDR +%#define TCP_PORT 15376 +#endif + +program MESSAGEPROC +{ + version MESSAGEVERS + { + int printmessage(string) = 1; + int printnum(int) = 2; + } = 1; +} = 99; diff --git a/rpc_demo/msg_main.c b/rpc_demo/msg_main.c new file mode 100644 index 0000000..58b0f7e --- /dev/null +++ b/rpc_demo/msg_main.c @@ -0,0 +1,64 @@ +/* + * This server runs on the RTEMS target or on the host machine. + * + * W. Eric Norum + * eric@cls.usask.ca + */ + +#include "msg.h" +#include +#include +#include +#include +#include +#include + +#include "msg_server.h" + +int +main (int argc, char **argv) +{ + int sock; + struct sockaddr_in myAddr; + SVCXPRT *transp; + + /* + * Create socket + */ + sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock < 0) { + perror ("socket creation problem"); + return 1; + } + + /* + * Bind to local address + */ + myAddr.sin_family = htons (AF_INET); + myAddr.sin_port = htons (TCP_PORT); + myAddr.sin_addr.s_addr = htonl (INADDR_ANY); + if (bind (sock, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) { + perror ("bind problem"); + return 2; + } + + /* + * Create TCP server + */ + transp = svctcp_create(sock, 0, 0); + if (transp == NULL) { + fprintf (stderr, "cannot create tcp service."); + return 1; + } + if (!svc_register(transp, MESSAGEPROC, MESSAGEVERS, messageproc_1, 0)) { + fprintf (stderr, "unable to register (MESSAGEPROC, MESSAGEVERS, tcp).\n"); + return 3; + } + + /* + * Run server + */ + svc_run (); + fprintf (stderr, "svc_run returned"); + return 0; +} diff --git a/rpc_demo/msg_proc.c b/rpc_demo/msg_proc.c new file mode 100644 index 0000000..229fedf --- /dev/null +++ b/rpc_demo/msg_proc.c @@ -0,0 +1,24 @@ +/* + * Server-side implementation of remote procedure calls + */ +#include +#include "msg.h" + +int * +printmessage_1_svc(char **argp, struct svc_req *rqstp) +{ + static int result; + + result = printf ("WOW -- RPC WORKS: `%s'\n", *argp); + return &result; +} + +int * +printnum_1_svc(int *argp, struct svc_req *rqstp) +{ + static int result; + + printf ("The number you sent is %d.\n", *argp); + result = *argp * *argp; + return &result; +} diff --git a/rpc_demo/rprintmsg.c b/rpc_demo/rprintmsg.c new file mode 100644 index 0000000..708e853 --- /dev/null +++ b/rpc_demo/rprintmsg.c @@ -0,0 +1,74 @@ +/* + * This client runs on the RTEMS target or on the host machine. + * + * W. Eric Norum + * eric@cls.usask.ca + */ +#include +#include +#include +#include "msg.h" + +int +main (int argc, char **argv) +{ + struct hostent *hp; + struct sockaddr_in farAddr; + int sock = -1; + CLIENT *c1; + int *result; + char *server; + char *message; + int itmp; + + /* + * Process arguments + */ + if (argc != 3) { + fprintf (stderr, "Usage: %s server message\n", argv[0]); + return 1; + } + server = argv[1]; + message = argv[2]; + hp = gethostbyname (server); + if (hp == NULL) { + fprintf (stderr, "No server %s\n", server); + return 2; + } + + /* + * Set up server address + */ + farAddr.sin_family = hp->h_addrtype; + farAddr.sin_port = htons (TCP_PORT); + memcpy((char*)&farAddr.sin_addr, hp->h_addr, hp->h_length); + + /* + * Create connection to server + */ + c1 = clnttcp_create (&farAddr, MESSAGEPROC, MESSAGEVERS, &sock, 0, 0); + if (c1 == NULL) { + clnt_pcreateerror (server); + return 3; + } + + /* + * Call remote procedures + */ + result = printmessage_1 (&message, c1); + if (result == NULL) { + clnt_perror (c1, server); + return 4; + } + printf ("Printed %d characters on %s.\n", *result, server); + + itmp = 12; + result = printnum_1 (&itmp, c1); + if (result == NULL) { + clnt_perror (c1, server); + return 5; + } + printf ("Result is %d.\n", *result); + + return 0; +} -- cgit v1.2.3