# HG changeset patch # User Mychaela Falconia # Date 1492998182 0 # Node ID db9ee7745cddc4ae91d29f15f6147f8ba18ee62f # Parent 31d43f0e469a4bebb57ab05b26de468025fe8570 fc-cmu200d: socket handling skeleton added diff -r 31d43f0e469a -r db9ee7745cdd rfcal/cmu200/Makefile --- a/rfcal/cmu200/Makefile Mon Apr 24 00:45:54 2017 +0000 +++ b/rfcal/cmu200/Makefile Mon Apr 24 01:43:02 2017 +0000 @@ -3,7 +3,7 @@ PROGS= fc-cmu200d fc-serscpi INSTBIN=/opt/freecalypso/bin -CMU200D_OBJS= init.o main.o openport.o sercmd.o +CMU200D_OBJS= init.o main.o openport.o sercmd.o session.o socket.o SERSCPI_OBJS= openport.o sertool.o all: ${PROGS} diff -r 31d43f0e469a -r db9ee7745cdd rfcal/cmu200/main.c --- a/rfcal/cmu200/main.c Mon Apr 24 00:45:54 2017 +0000 +++ b/rfcal/cmu200/main.c Mon Apr 24 01:43:02 2017 +0000 @@ -27,7 +27,9 @@ bind_socket_pathname = argv[3]; else bind_socket_pathname = default_socket_pathname; - - /* to be continued */ - exit(0); + create_listener_socket(); + for (;;) { + get_socket_connection(); + handle_session(); + } } diff -r 31d43f0e469a -r db9ee7745cdd rfcal/cmu200/session.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rfcal/cmu200/session.c Mon Apr 24 01:43:02 2017 +0000 @@ -0,0 +1,51 @@ +/* + * This module contains the code that handles a single local socket + * connection session. + */ + +#include +#include +#include +#include +#include + +extern int activesock; + +handle_command() +{ + char readbuf[256], linebuf[256]; + int cc, pos; + + for (pos = 0; ; ) { + cc = read(activesock, readbuf, sizeof readbuf); + if (cc <= 0) { + printf("Client program closed connection\n"); + return(1); + } + if (pos + cc > sizeof linebuf) { + send_socket_response("-Command too long\n"); + return(1); + } + bcopy(readbuf, linebuf + pos, cc); + pos += cc; + if (linebuf[pos-1] == '\n') + break; + } + linebuf[pos-1] = '\0'; + printf("Client command: %s\n", linebuf); + /* actual command handling will go here */ + return(0); +} + +handle_session() +{ + int rc; + + send_socket_response("+CMU200 interface daemon ready\n"); + for (;;) { + rc = handle_command(); + if (rc) + break; + } + close(activesock); +} diff -r 31d43f0e469a -r db9ee7745cdd rfcal/cmu200/socket.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rfcal/cmu200/socket.c Mon Apr 24 01:43:02 2017 +0000 @@ -0,0 +1,80 @@ +/* + * This module handles the local UNIX domain socket interface for fc-cmu200d. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int listener, activesock; + +extern char *bind_socket_pathname; + +create_listener_socket() +{ + /* local socket binding voodoo copied from osmocon */ + struct sockaddr_un local; + unsigned int namelen; + int rc; + + listener = socket(AF_UNIX, SOCK_STREAM, 0); + if (listener < 0) { + perror("socket(AF_UNIX, SOCK_STREAM, 0)"); + exit(1); + } + + local.sun_family = AF_UNIX; + strncpy(local.sun_path, bind_socket_pathname, sizeof(local.sun_path)); + local.sun_path[sizeof(local.sun_path) - 1] = '\0'; + unlink(local.sun_path); + + /* we use the same magic that X11 uses in Xtranssock.c for + * calculating the proper length of the sockaddr */ +#if defined(BSD44SOCKETS) || defined(__UNIXWARE__) + local.sun_len = strlen(local.sun_path); +#endif +#if defined(BSD44SOCKETS) || defined(SUN_LEN) + namelen = SUN_LEN(&local); +#else + namelen = strlen(local.sun_path) + + offsetof(struct sockaddr_un, sun_path) + 1; +#endif + + rc = bind(listener, (struct sockaddr *) &local, namelen); + if (rc != 0) { + perror("bind on local socket"); + exit(1); + } + rc = listen(listener, 1); + if (rc != 0) { + perror("listen"); + exit(1); + } + return(0); +} + +get_socket_connection() +{ + struct sockaddr_un un_addr; + socklen_t len; + + len = sizeof(un_addr); + activesock = accept(listener, (struct sockaddr *) &un_addr, &len); + if (activesock < 0) { + perror("socket accept"); + exit(1); + } + printf("Accepted local socket connection\n"); + return(0); +} + +send_socket_response(str) + char *str; +{ + write(activesock, str, strlen(str)); +}