Greg
   This sample program shows what I'm trying to accomplish.

I still owe you a reply for your previous posting

thanks
Bob Smith


/*
 * pxtest.c : This program demonstrates the use of a proxy device.
 *
 * The program generates some data once a second and tries to send
 * it to /dev/proxyout.  The original data is modified by adding
 * an offset to each input character.  The offset can be set or
 * viewed at the proxy device node /dev/proxyctrl.
 *
 * Typical usage might be
 *    sudo modprobe proxy
 *    PROXYDEV=`grep proxy /proc/devices | cut -d\  -f 1`
 *    sudo mknod /dev/proxyout c $PROXYDEV 0
 *    sudo mknod /dev/proxyctrl c $PROXYDEV 1
 *    sudo chmod 666 /dev/proxyout /dev/proxyctrl
 *    gcc -o pxtest pxtest.c
 *    ./pxtest &
 *    cat /dev/proxyout    # view the output
 *    (switch to another terminal window)
 *    cat /dev/proxyctrl   # what is the offset?
 *    echo 2 > /dev/proxyctrl  # set offset to 2
 */

#include <stdio.h>
#include <stdlib.h>
#include <termio.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <sys/fcntl.h>
#include <sys/time.h>


extern int errno;
#define PXBUFZS 100


int main (int argc, char *argv[])
{
    fd_set rfds;                /* for select() */
    fd_set wfds;                /* for select() */
    int    nfds;                /* for select() */
    struct timeval tv;          /* for select() */
    time_t now;                 /* source of input data */
    int    i;
    int    offset = 0;          /* configured via /dev/proxyctrl */
    int    outfd;               /* fd to /dev/proxyout */
    char   obuff[PXBUFZS];
    int    listener;            /* ==1 if someone is listening at /dev/proxyout 
*/
    int    ctrlfd = -1;         /* fd to /dev/proxyctrl */
    char   cbuff[PXBUFZS];      /* i/o buffer for /dev/proxyctrl */
    int    slret,wrret,rdret;   /* select() write() read() return value */


    outfd =  open("/dev/proxyout", (O_WRONLY | O_NDELAY) , 0);
    if (outfd < 0 ) {
        printf("Unable to open proxy output port\n");
        exit(1);
    }
    listener = 0;

    tv.tv_sec = 1;
    tv.tv_usec = 0;

    while(1) {
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);

        /* open, or reopen, the offset control port at /dev/proxyctrl */
        if (ctrlfd == -1) {
            ctrlfd =  open("/dev/proxyctrl", O_RDWR | O_NDELAY,0);
            if (ctrlfd < 0 ) {
                printf("Unable to open proxy control port\n");
                exit(1);
            }
        }
        FD_SET(ctrlfd, &rfds);
        FD_SET(ctrlfd, &wfds);

        /* If no one is listening, watch for a connection */
        if (listener == 0) {
            FD_SET(outfd, &wfds);
        }

        nfds = (outfd > ctrlfd) ? outfd : ctrlfd;

        slret = select((nfds + 1), &rfds, &wfds, (fd_set *)NULL, &tv);

        if (slret == 0) {
            /* Generate bogus data.  Real data might be coming from
             * an I2C read or from an accelerometer at the end of a
             * USB serial link.  For now, just use the current time */
            time(&now);
            ctime_r(&now, obuff);

            /* "process" the data by adding offset to each character */
            i = 0;
            while (obuff[i] != '\n') {
                obuff[i] = (char) (obuff[i] + offset);
                obuff[i] = (isprint(obuff[i])) ? obuff[i] : '_';
                i++;
            }

            /* Try to send the processed output to /dev/proxyout if possible */
            if (listener == 1) {
                wrret = write(outfd, obuff, strlen(obuff));
                if ((wrret == 0) || ((wrret < 0) && (errno == EAGAIN))) {
                    /* listener dropped off */
                    listener = 0;
                }
            }
            tv.tv_sec = 1;
            tv.tv_usec = 0;
        }

        /* Did a listener attach at /dev/proxyout? */
        if (FD_ISSET(outfd, &wfds)) {
            listener = 1;
        }

        /* Data on /dev/proxyctrl is marshalled as newline terminated ASCII
         * This is not a requirement.  Use binary, XML or whatever you need.
         * This demo forces a close but that too is not required. */

        /* Did anyone ask to read the offset value? */
        if (FD_ISSET(ctrlfd, &wfds)) {
            snprintf(cbuff, PXBUFZS, "%d\n", offset);
            write(ctrlfd, cbuff, strlen(cbuff));  /* send offset value */
            write(ctrlfd, cbuff, 0);              /* send EOF */
        }

        /* Is anyone trying to set the offset value? */
        if (FD_ISSET(ctrlfd, &rfds)) {
            rdret = read(ctrlfd, cbuff, PXBUFZS);
            if (rdret == 0) {
                close(ctrlfd);
                ctrlfd = -1;
            } else if ((rdret > 0) && (cbuff[rdret - 1] == '\n')) {
                /* buffer mgmt should be more than checking for ending \n */
                sscanf(cbuff, "%d", &offset);
            }
        }
    }
}


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to