VPN termux about China.net

try.cc

/*
   Affix - Bluetooth Protocol Stack for Linux
   Copyright (C) 2001 Nokia Corporation
   Authors:
           Christian Plog <plog@informatik.uni-bonn.de>
    emulation part:
        Imre Deak <imre.deak@nokia.com>
           Dmitry Kasatkin <dmitry.kasatkin@nokia.com>

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2 of the License, or (at your
   option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

/*
   $Id: btmodem.c,v 1.4 2003/03/14 10:47:40 kds Exp $

   Modem multiplexer/emulator

   Fixes:
           Dmitry Kasatkin        :

*/       

#include <syslog.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

//#include <affix/btcore.h>

/* The size of the read buffer: */
#define BUFFER_SIZE 1024

/* Global variables, are used in subroutines: */
char *mddev;        /* name of the serial device for the modem*/
char *bty;        /* name of the serial device emulation on the bluetoothconnection */
char *mdbuf;        /* buffer for data read from the modem but not yet delivered to the bluetooth device */
char *btbuf;        /* buffer for data read from the bluetooth device but not yet delivered to the modem */
int   btfd;        /* the file handle of the bluetooth serial device */
int   mdfd;        /* the file handle of the serial device for the modem */
int   verbose;        /* does the user want comments? */
int   logging;        /* does the user want logs? */
char *logfile;        /* the name of the logfile */
FILE *logfp;        /* file handle for the logfile */
char *logtext;        /* used for construction of the strings to log */
int   silent;        /* whether to be silent on stdout or not */
long  btrxcount;    /* bytes received over bluetooth */
long  bttxcount;    /* bytes send over bluetooth */
long  mdrxcount;    /* bytes received over the modem line */
long  mdtxcount;    /* bytes send over the modem line */
int   crtscts;        /* use RTS/CTS instead of XON/XOFF */

int val;

#define TIMEOUT 30000

// reads from device, one character at a time with a fixed timeout
int read_line_nonblk(int fd, char *buf, int max_size)
{
        int     i;
        fd_set  fset_rd;
        struct  timeval tv;
        int     res;

        if (max_size < 1)
                return -1;
        for (i = 0; i < max_size - 1; i++) {
                FD_ZERO(&fset_rd);
                FD_SET(fd, &fset_rd);
                tv.tv_sec = 0;
                tv.tv_usec = TIMEOUT * 1000;
                if (select(fd + 1, &fset_rd, NULL, NULL, &tv) <= 0)
                        return i;
                if ((res = read(fd, &buf[i], 1)) <= 0)
                        return -1;
                buf[i + 1] = '\0';
        if (buf[i] == '\n' || buf[i] == '\r')
                        return i + 1;
        }
        return -1;
}

void nsleep(int sec, int nsec)
{
    struct timespec req;

    req.tv_sec = sec;
    req.tv_nsec = nsec;    /* 1msec */
    nanosleep(&req, NULL);
}

int write_to_modem(int fd, char *buf, int size)
{
    int i;

    for (i = 0; i < size; i++) {
        if (write(fd, buf++, 1) != 1)
            return -1;
        nsleep(0, 500000);
    }
    return 0;
}

#define CARRIER_STR "\r\nCARRIER\r\n"
#define CONNECT_STR "\r\nCONNECT 9600\r\n"
#define OK_STR "\r\nOK\r\n"

int emulate(void)
{
    static char     buf[512];
    struct termios    term;

    openlog(NULL/*"btmodem"*/, 0, LOG_USER);
    if (tcgetattr(1, &term) != 0) {
        syslog(LOG_ERR, "tcgetattr failed.\n");
        goto failed;
    }
    cfmakeraw(&term);
    term.c_cflag |= CRTSCTS;
    if (tcsetattr(1, TCSANOW, &term) != 0) {
        syslog(LOG_ERR, "tcsetattr failed.\n");
        goto failed;
    }
    for (;;) {
        int i;
        int res = read_line_nonblk(0, buf, sizeof(buf));
        if (res <= 0) {
            syslog(LOG_ERR, "input failed.\n");
            goto failed;
        }
        syslog(LOG_DEBUG, "Got %s\n", buf);
        for (i = 0; i < (int)strlen(buf); i++)
            buf[i] = toupper(buf[i]);
        if (strncmp(buf, "AT", 2) == 0) {
            if (strncmp(buf, "ATD", 3) == 0 || strstr(buf, "DT") || strstr(buf, "DP")) {
                nsleep(1, 0);
                syslog(LOG_DEBUG, "Send %s %s", CARRIER_STR, CONNECT_STR);
                if (write_to_modem(1, CARRIER_STR, sizeof(CARRIER_STR) - 1) != 0 ||
                    write_to_modem(1, CONNECT_STR, sizeof(CONNECT_STR) - 1) != 0) {
                    syslog(LOG_ERR, "write to modem failed.\n");
                    goto failed;
                }
#if 0
                syslog(LOG_DEBUG, "Set CD\n");
                val = TIOCM_CD;
                if (ioctl(1, TIOCMBIS, &val) != 0) {
                    syslog(LOG_ERR, "failed to set CD. errno=%d\n", errno);
                    goto failed;
                }
#endif
                break;
            } else {
                syslog(LOG_DEBUG, "Send OK\\r");
                if (write_to_modem(1, OK_STR, sizeof(OK_STR) - 1) != 0) {
                    syslog(LOG_ERR, "write to modem failed.\n");
                    goto failed;
                }
            }
        } else if (strncmp(buf, "CLIENT", 6) == 0) {
            syslog(LOG_DEBUG, "Send CLIENTSERVER\n");
            write(1, "CLIENTSERVER", 12);
            break;
        } else {
            syslog(LOG_DEBUG, "Send ERROR\n");
            write(1, "\r\nERROR\r\n", 9);
        }
    }
    closelog();
    return 0;
failed:
    closelog();
    return -1;
}

/* Writes the string to the log facilities - always expects complete lines! */
void logit(char *logtext)
{
    if (silent != 1) {
        printf(logtext);
        printf("\n");
        fflush(stdout);
    }
    if (logging) {
        fprintf(logfp, "btmodem [%d]: ", getpid());
        fprintf(logfp, logtext);
        fprintf(logfp, "\n");
        fflush(logfp);
    }
}

/* Frees all used ressources: */
void free_ressources(void)
{
    if (verbose)
        logit("Freeing buffer for modem data");
    if (mdbuf)
        free(mdbuf);
    if (verbose)
        logit("Freeing buffer for bluetooth data");
    if (btbuf)
        free(btbuf);
    if (verbose)
        logit("Closeing modem device");
    if (mdfd)
        close(mdfd);
    if (verbose)
        logit("Closing bluetooth serial device");
    if (btfd)
        close(btfd);
    if (verbose)
        logit("Freeing buffer for devicename of modem");
    if (mddev)
        free(mddev);
    if (verbose)
        logit("Freeing buffer for devicename of bluetooth serial device");
    if (bty)
        free(bty);
    if (verbose)
        logit("Freeing buffer for name of log file");
    if (logfile)
        free(logfile);
    if (logtext)
        free(logtext);
    if (verbose)
        logit("Closing log file");
    if (logfp)
        fclose(logfp);
    fflush(stdout);
}

/* Handles breaks: */
void handle_interruption(int sig)
{
    if (sig == 2)
        printf("\nInterrupted\n");
    else
        printf("\nAborted!\n");
    fflush(stdout);
    free_ressources();
    exit(0);
}

/* Shows all the parameters: */
void usage(void)
{
    printf("Syntax: btmodem [-e] [-b bluetooth] [-h] [-l [logfile]] [-m modem] [-q] [-v [-v]] [-x [count]]\n");
    printf("        -e              Modem emulation (use stdin/stdout). -m is not used\n");
    printf("        -b client       The device name of the client serial connection,\n");
    printf("                        usually over a bluetooth connection.\n");
    printf("                        Default: /dev/bty0\n");
    printf("        -h              Use hardware flow control (RTS/CTS) instead of the\n");
    printf("                        default XON/XOFF\n");
    printf("        -l [logfile]    Log in a file. The default name for the logfile is\n");
    printf("                        /var/log/btmodem\n");
    printf("        -m modem        The device name of the serial port on which the modem\n");
    printf("                        is connected. The defualt is: /dev/ttyS0\n");
    printf("        -q              Quiet mode - do not show any messages on stdout.\n");
    printf("                        This has no influence on the information written in\n");
    printf("                        the logfile\n");
    printf("        -v              Verbose mode: Show a lot of information as output on\n");
    printf("                        stdout and in the logfile if logging is activated\n");
    printf("                        REMARK: usually only important status messages are\n");
    printf("                                shown.\n");
    printf("                        WARNING: if both -q and -v are set, -q takes\n");
    printf("                                 precedence!\n");
    printf("        -v -v           Higher verbosity: Show Even more information,\n");
    printf("                        including all data transmitted in verbatim form\n");
    printf("        -x [count]      Show the data as hexdump (always, regardless of\n");
    printf("                        verbosity. If the quiet mode is set, don't show the\n");
    printf("                        hexdump on the screen). The hexdump is written to the\n");
    printf("                        logfile. If -v -v and -x is set, the data will be\n");
    printf("                        shown twice, once verbatim and once as hexdump. count\n");
    printf("                        is the number of bytes shown in each line.\n");
    printf("                        Default: 16\n");
}

/* Setup for the serial ports: */
void modem_setup(int desc)
{
    struct termios settings;
    int result;

    result = tcgetattr(desc, &settings);
    if (result < 0) {
        perror ("error in tcgetattr");
        return;
    }

    cfmakeraw(&settings);
    if (result < 0) {
        perror ("error in cfmakeraw");
        return;
    }

    settings.c_cflag &= ~(PARENB | CSIZE | CSTOPB);
    settings.c_cflag |= (CS8);
    if (crtscts) {
        settings.c_cflag |= (CRTSCTS);
        settings.c_iflag &= ~(IXON | IXOFF);
        logit("Using hardware flow control");
    } else {
        settings.c_cflag &= ~(CRTSCTS);
        settings.c_iflag |= (IXON | IXOFF);
        logit("Using software flow control");
    }
    settings.c_lflag &= ~(ECHO | ICANON);
//    cfsetspeed(&settings, B115200);
    result = tcsetattr (desc, TCSANOW, &settings);
    if (result < 0) {
        perror ("error in tcgetattr");
        return;
    }
}

/* Makes an hexdump out of buffer and prints it with loggit   */
/* each line will contain linewidth bytes with two signs each */
void print_hexdump(unsigned char *buffer, int bufsize, int linewidth, int modemin)
{
    char *helpbuffer;
    int   i, pos;

    if (!linewidth)
        return;

    helpbuffer = (char *)malloc(linewidth * 3 + 1);
    memset(helpbuffer, 0, linewidth * 3 + 1);

    pos = 0;
    if (modemin)
        helpbuffer[0] = '>';
    else
        helpbuffer[0] = '<';
    for (i = 0; i < bufsize; i++) {
        pos++;
        snprintf(helpbuffer + strlen(helpbuffer), linewidth * 3 + 1 - strlen(helpbuffer), "%.2X ", buffer[i]);
        /* If line is long enough, then print the line and start a new one: */
        if (pos == linewidth) {
            pos = 0;
            logit(helpbuffer);
            memset(helpbuffer, 0, linewidth * 3 + 1);
            if (modemin)
                helpbuffer[0] = '>';
            else
                helpbuffer[0] = '<';
        }
    }
    /* If at least one sign is in the buffer, then print it: */
    if (pos > 0)
        logit(helpbuffer);

    free(helpbuffer);
}

int main(int argc, char **argv)
{
    int    param;                   /* Command line option to parse */
    int    endprog;                 /* whether to abort the main loop */
    int    mddata;               /* count of bytes read and buffered from the modem */
    int    btdata;           /* count of bytes read and buffered from the bluetooth device */
    int    mdrxsize;           /* count of bytes now read from the modem */
    int    btrxsize;       /* count of bytes now read from the bluetooth device */
    int    mdtxsize;          /* count of bytes writen to the modem */
    int    bttxsize;      /* count of bytes writen to the bluetooth device */
    int    mdsig;     /* the new signal stats on the modem lines */
    int    oldmdsig;        /* the old signal stats on the modem lines */
    int    btsig; /* the new signal stats on the bluetooth lines */
    int    oldbtsig;        /* the old signal stats on the bluetooth lines */
    int    setmdsig;         /* which signals to set on the modem lines */
    int    setbtsig;     /* which signals to set on the bluetooth lines */
    int    unsetmdsig;       /* which signals to unset on the modem lines */
    int    unsetbtsig;   /* which signals to unset on the bluetooth lines */
    int    maxhandle;               /* the maximum file handle (neccessary for select) */
    int    hexdumplinewidth;        /* number of chars in each line of an hexdump */
    fd_set readfds;
    fd_set writefds;
    struct timeval tv;
    int    emu = 0;

    openlog(NULL/*argv[0]*/, 0, LOG_DAEMON);
//    BTINFO("%s %s started.", argv[0], affix_version);

    if (argc == 1) {
        usage();
        return 0;
    }

    /* Initialize all variables: */
    mddev = NULL;
    bty = NULL;
    mdfd = 0;
    btfd = 0;
    endprog = 0;
    mdbuf = NULL;
    btbuf = NULL;
    verbose = 0;
    oldmdsig = 0;
    oldbtsig = 0;
    logging = 0;
    logfile = NULL;
    logfp = 0;
    logtext = 0;
    silent = 0;
    crtscts = 0;
    hexdumplinewidth = 0;
    mdtxcount = mdrxcount = btrxcount = bttxcount = 0;

    /* Read the command line parameters: */
    while ((param = getopt(argc, argv, "eb:hl::m:qvx::?")) != -1) {
        switch (param) {
            case 'e':
                emu = 1;
                break;
            case 'b': /* Get the string with the bluetooth bty: */
                bty = (char *)malloc(strlen(optarg)+1);
                memset(bty, 0, strlen(optarg)+1);
                memcpy(bty, optarg, strlen(optarg));
                break;
            case 'h':
                crtscts = 1;
                break;
            case 'l':
                logging = 1;
                if (optarg != 0) {
                    logfile = (char *)malloc(strlen(optarg)+1);
                    memset(logfile, 0, strlen(optarg)+1);
                    memcpy(logfile, optarg, strlen(optarg));
                } else {
                    logfile = (char *)malloc(19);
                    memset(logfile, 0, 19);
                    memcpy(logfile, "/var/log/btmodem", 18);
                }
                break;
            case 'm': /* Get the string with the modem tty: */
                mddev = (char *)malloc(strlen(optarg)+1);
                memset(mddev, 0, strlen(optarg)+1);
                memcpy(mddev, optarg, strlen(optarg));
                break;
            case 'q':
                silent = 1;
                break;
            case 'v':
                verbose++;
                break;
            case 'x':
                hexdumplinewidth = 16;
                if (optarg != 0) {
                    hexdumplinewidth = atoi(optarg);
                }
                break;
            case '?':
            default:
                free_ressources();
                usage();
                exit(1);
        }
    }

    if (emu)
        return emulate();

    logtext = (char *)malloc(BUFFER_SIZE);
    memset(logtext, 0, BUFFER_SIZE);

    /* Open the logfile: */
    if (logging) {
        logfp = fopen(logfile, "a");
        if (logfp == NULL) {
            perror("Unable to open logfile");
            handle_interruption(0);
        }
    }

    /* Set the devicenames to default values, if not yet initialized: */
    if (bty == NULL) {
        bty = (char *)malloc(10);
        memset(bty, 0, 10);
        memcpy(bty, "/sdcard/blue/", 9);
    }
    if (mddev == NULL) {
        mddev = (char *)malloc(11);
        memset(mddev, 0, 11);
        memcpy(mddev, "/sdcard/blue/", 10);
    }

    snprintf(logtext, BUFFER_SIZE, "Connecting bluetooth serial connection on device %s with modem on device %s",
            bty, mddev);
    logit(logtext);
    memset(logtext, 0, BUFFER_SIZE);

    if (verbose)
        logit("Installing signal handler for interruption");
    signal(SIGINT, &handle_interruption);
    fflush(stdout);

    /* Open the devices */
    btfd = open(bty, O_RDWR);
    mdfd = open(mddev, O_RDWR);
    if (btfd == -1) {
        perror("Unable to open bluetooth serial device");
        handle_interruption(0);
    }
    if (mdfd == -1) {
        perror("Unable to open modem device");
        handle_interruption(0);
    }
    /* Initialize the serial connection to the modem: */
    modem_setup(mdfd);
    modem_setup(btfd);

    snprintf(logtext, BUFFER_SIZE, "Opened devices %s and %s successfully", bty, mddev);
    logit(logtext);
    memset(logtext, 0, BUFFER_SIZE);

    /* Make them nonblocking */

    val = fcntl(mdfd, F_GETFL, 0);
    fcntl(mdfd, F_SETFL, val | O_NONBLOCK);

    val = fcntl(btfd, F_GETFL, 0);
    fcntl(btfd, F_SETFL, val | O_NONBLOCK);


    /* Get the maximal file descriptor for select: */
    if (mdfd > btfd)
        maxhandle = mdfd;
    else
        maxhandle = btfd;

    /* Initialize the buffers: */
    mdbuf = (char *)malloc(BUFFER_SIZE);
    btbuf = (char *)malloc(BUFFER_SIZE);
    memset(mdbuf, 0, BUFFER_SIZE);
    memset(btbuf, 0, BUFFER_SIZE);
    btdata = 0;
    mddata = 0;
    mdrxsize = 0;
    btrxsize = 0;
    if (verbose > 1)
        logit("Buffers for data created and initialized");

    /* Initialize the bluetooth connection with the modem stat */
    ioctl(mdfd, TIOCMGET, &oldmdsig);
    /* Check DSR stat: */
    snprintf(logtext, BUFFER_SIZE, "Initializing lines on bluetooth connection: DSR: ");
    if ((oldmdsig & TIOCM_DSR) == TIOCM_DSR)    {
        snprintf(logtext+strlen(logtext), BUFFER_SIZE - strlen(logtext), "1, ");
        setbtsig |= TIOCM_DTR;
    } else {
        snprintf(logtext+strlen(logtext), BUFFER_SIZE - strlen(logtext), "0, ");
        unsetbtsig |= TIOCM_DTR;
    }
    /* Check RI stat: */
    snprintf(logtext+strlen(logtext), BUFFER_SIZE - strlen(logtext), "RI: ");
    if ((oldmdsig & TIOCM_RI) == TIOCM_RI) {
        snprintf(logtext+strlen(logtext), BUFFER_SIZE - strlen(logtext), "1, ");
        setbtsig |= TIOCM_RI;
    } else {
        snprintf(logtext+strlen(logtext), BUFFER_SIZE - strlen(logtext), "0, ");
        unsetbtsig |= TIOCM_RI;
    }
    /* Check CAR stat: */
    snprintf(logtext+strlen(logtext), BUFFER_SIZE - strlen(logtext), "CAR: ");
    if ((oldmdsig & TIOCM_CAR) == TIOCM_CAR) {
        snprintf(logtext+strlen(logtext), BUFFER_SIZE - strlen(logtext), "1");
        setbtsig |= TIOCM_CAR;
    } else {
        snprintf(logtext+strlen(logtext), BUFFER_SIZE - strlen(logtext), "0");
        unsetbtsig |= TIOCM_CAR;
    }
    if (verbose)
        logit(logtext);
    memset(logtext, 0, BUFFER_SIZE);
    ioctl(btfd, TIOCMBIS, &setbtsig);
    ioctl(btfd, TIOCMBIC, &unsetbtsig);

    ioctl(btfd, TIOCMGET, &oldbtsig);

    /*
     * The main loop of the program.
     * Runs until interupted
     */

    while (endprog == 0) {

        /* Read the signals on the devices: */
        ioctl(mdfd, TIOCMGET, &mdsig);
        ioctl(btfd, TIOCMGET, &btsig);

        /* If the signals differ from the old ones,
           check if some signals must be set on the other side: */
        if (btsig != oldbtsig) {
            snprintf(logtext, BUFFER_SIZE, "Line change on bluetooth side: ");
            setmdsig = 0;
            unsetmdsig = 0;
            /* Check if stat of DSR has changed: */
            if ((btsig & TIOCM_DSR) != (oldbtsig & TIOCM_DSR))    {
                snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "DTR -> ");
                if ((btsig & TIOCM_DSR) == TIOCM_DSR) {
                    setmdsig |= TIOCM_DTR;
                    snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "1 ");
                } else {
                    unsetmdsig |= TIOCM_DTR;
                    snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "0 ");
                }
            }
            if (verbose)
                logit(logtext);
            memset(logtext, 0, BUFFER_SIZE);
            ioctl(mdfd, TIOCMBIS, &setmdsig);
            ioctl(mdfd, TIOCMBIC, &unsetmdsig);
            oldbtsig = btsig;
        }
        if (mdsig != oldmdsig) {
            snprintf(logtext, BUFFER_SIZE, "Line change on modemside: ");
            setbtsig = 0;
            unsetbtsig = 0;
            /* Check if DSR has changed: */
            if ((mdsig & TIOCM_DSR) != (oldmdsig & TIOCM_DSR))    {
                snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "DSR -> ");
                if ((mdsig & TIOCM_DSR) == TIOCM_DSR) {
                    setbtsig |= TIOCM_DTR;
                    snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "1 ");
                } else {
                    unsetbtsig |= TIOCM_DTR;
                    snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "0 ");
                }
            }
            /* Check if RI has changed: */
            if ((mdsig & TIOCM_RI) != (oldmdsig & TIOCM_RI)) {
                snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "RI -> ");
                if ((mdsig & TIOCM_RI) == TIOCM_RI) {
                    setbtsig |= TIOCM_RI;
                    snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "1 ");
                } else {
                    unsetbtsig |= TIOCM_RI;
                    snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "0 ");
                }
            }
            /* Check if CAR has changed: */
            if ((mdsig & TIOCM_CAR) != (oldmdsig & TIOCM_CAR)) {
                snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "CAR -> ");
                if ((mdsig & TIOCM_CAR) == TIOCM_CAR) {
                    setbtsig |= TIOCM_CAR;
                    snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "1 ");
                } else {
                    unsetbtsig |= TIOCM_CAR;
                    snprintf(logtext + strlen(logtext), BUFFER_SIZE - strlen(logtext), "0 ");
                }
            }
            if (verbose)
                logit(logtext);
            memset(logtext, 0, BUFFER_SIZE);
            ioctl(btfd, TIOCMBIS, &setbtsig);
            ioctl(btfd, TIOCMBIC, &unsetbtsig);
            oldmdsig = mdsig;
        }

        /* Handle the data on the serial devices: */
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);

        /* Check only for data if we can read something: */
        if (btdata < BUFFER_SIZE)
            FD_SET(btfd, &readfds);
        if (mddata < BUFFER_SIZE)
            FD_SET(mdfd, &readfds);

        /* Check if we can write data - as long as we have some: */
        if (mddata > 0)
            FD_SET(btfd, &writefds);
        if (btdata > 0)
            FD_SET(mdfd, &writefds);

        /* Now check the file handles: */
        tv.tv_sec = 0;
        tv.tv_usec = 10000;

        select(maxhandle+1, &readfds, &writefds, NULL, &tv);

        /* First write data, if possible: */
        /* to the modem: */
        if (FD_ISSET(mdfd, &writefds)) {
            /* Try to write, ignore error: */
            if ((mdtxsize = write(mdfd, btbuf, btdata)) == -1) {
                /* NO ERRORHANDLING! */
            } else {
                /* If verbosity is high enough, show the data: */
                if (verbose > 1) {
                    snprintf(logtext, BUFFER_SIZE, "Data written to modem");
                    logit(logtext);
                    memset(logtext, 0, BUFFER_SIZE);
                    memcpy(logtext, btbuf, btdata);
                    logit(logtext);
                    memset(logtext, 0, BUFFER_SIZE);
                }
                /* If asked for, print an hexdump of the data: */
    //            print_hexdump(btbuf, btdata, hexdumplinewidth, 1);
                /* If only partial written, copy the rest to the beginning: */
                if (mdtxsize != btdata) {
                    memmove(btbuf, btbuf + mdtxsize, btdata - mdtxsize);
                }
                /* Decrease the byte count for the buffer: */
                btdata -= mdtxsize;
                mdtxcount += mdtxsize;
            }
        }
        /* to the bluetooth device: */
        if (FD_ISSET(btfd, &writefds)) {
            /* Try to write, ignore error: */
            if ((bttxsize = write(btfd, mdbuf, mddata)) == -1) {
                /* NO ERRORHANDLING! */
            } else {
                /* If verbosity is high enough, show the data: */
                if (verbose > 1) {
                    snprintf(logtext, BUFFER_SIZE, "Data written to bluetooth");
                    logit(logtext);
                    memset(logtext, 0, BUFFER_SIZE);
                    memcpy(logtext, mdbuf, mddata);
                    logit(logtext);
                    memset(logtext, 0, BUFFER_SIZE);
                }
                /* If asked for, print an hexdump of the data: */
    //            print_hexdump(mdbuf, mddata, hexdumplinewidth, 0);
                /* If only partial written, copy the rest to the beginning: */
                if (bttxsize != mddata) {
                    memmove(mdbuf, mdbuf + bttxsize, mddata - bttxsize);
                }
                /* Decrease the byte count for the buffer: */
                mddata -= bttxsize;
                bttxcount += bttxsize;
            }
        }
        /* Now read the data - if there is data and there is space in the buffers: */
        /* from the modem: */
        if (FD_ISSET(mdfd, &readfds)) {
            /* Try to read the data, ignore error: */
            if ((mdrxsize = read(mdfd, mdbuf + mddata, BUFFER_SIZE - mddata)) == -1) {
                /* NO ERRORHANDLING! */
            } else {
                if (verbose > 1) {
                    snprintf(logtext, BUFFER_SIZE, "Data read from modem");
                    logit(logtext);
                    memset(logtext, 0, BUFFER_SIZE);
                }
                mddata += mdrxsize;
                mdrxcount += mdrxsize;
            }
        }
        /* from the bluetooth device: */
        if (FD_ISSET(btfd, &readfds)) {
            /* Try to read the data, ignore error: */
            if ((btrxsize = read(btfd, btbuf + btdata, BUFFER_SIZE - btdata)) == -1) {
                /* NO ERRORHANDLING! */
            } else {
                if (verbose > 1) {
                    snprintf(logtext, BUFFER_SIZE, "Data read from bluetooth");
                    logit(logtext);
                    memset(logtext, 0, BUFFER_SIZE);
                } else if (btrxsize == 0) {
                    /* Check for null packets to close the socket: */
                    endprog = 1;
                }
                btdata += btrxsize;
                btrxcount += btrxsize;
            }
        }
    }

    logit("Connection closed");
    snprintf(logtext, BUFFER_SIZE, "Modem stats: %ld bytes received, %ld bytes sent",
            mdrxcount, mdtxcount);
    logit(logtext);
    memset(logtext, 0, BUFFER_SIZE);
    snprintf(logtext, BUFFER_SIZE, "Bluetooth stats: %ld bytes received, %ld bytes sent",
            btrxcount, bttxcount);
    logit(logtext);
    memset(logtext, 0, BUFFER_SIZE);

    free_ressources();
    return 0;
}

No comments:

Post a Comment