zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/hostapp/zlogtrace_ref/netcom_rserial/Makefile b/ap/hostapp/zlogtrace_ref/netcom_rserial/Makefile
new file mode 100755
index 0000000..05d74b2
--- /dev/null
+++ b/ap/hostapp/zlogtrace_ref/netcom_rserial/Makefile
@@ -0,0 +1,9 @@
+SUBEXEC = netserial
+all: $(SUBEXEC)
+
+REMOBJ=comm_serial.o comm_stty.o
+$(SUBEXEC): $(REMOBJ)
+	$(CC) $(LDFLAGS) -o $(SUBEXEC) $(REMOBJ)
+
+clean:
+	rm -f $(SUBEXEC) *.elf *.gdb *.o 
diff --git a/ap/hostapp/zlogtrace_ref/netcom_rserial/README.txt b/ap/hostapp/zlogtrace_ref/netcom_rserial/README.txt
new file mode 100755
index 0000000..06a7ac0
--- /dev/null
+++ b/ap/hostapp/zlogtrace_ref/netcom_rserial/README.txt
@@ -0,0 +1,149 @@
+---------

+

+The remserial program acts as a communications bridge between a TCP/IP

+network port and a Linux device such as a serial port.  Any character-oriented

+Linux /dev device will work.

+

+The program can also use pseudo-ttys as the device.  A pseudo-tty is like

+a serial port in that it has a /dev entry that can be opened by a program

+that expects a serial port device, except that instead of belonging to

+a physical serial device, the data can be intercepted by another program.

+The remserial program uses this to connect a network port to the

+"master" (programming) side of the pseudo-tty allowing the device driver

+(slave) side to be used by some program expecting a serial port.  See example

+3 below for details.

+

+The program can operate as a server accepting network connections from

+other machines, or as a client, connecting to remote machine that

+is running the remserial program or some other program that accepts

+a raw network connection.  The network connection passes data as-is,

+there is no control protocol over the network socket.

+

+Multiple copies of the program can run on the same computer at the same

+time assuming each is using a different network port and device.

+

+Some examples:

+

+1) Give access to a RS232 device over a network.

+

+The computer with the serial port connected to the device (such as a

+data aquisition device) runs the remserial program:

+

+	remserial -d -p 23000 -s "9600 raw" /dev/ttyS0 &

+

+This starts the program in daemon mode so that it runs in the background,

+it waits for connections on port 23000 and sets up the serial port

+/dev/ttyS0 at 9600 baud.  Network connections to port 23000 from any

+machine can then read and write to the device attached to the serial port.

+

+This can be started from /etc/rc.local or as an entry in /etc/inittab

+or set up as a system service with a file in /etc/rc.init/.

+

+2) Connect an RS232 device to a specified server.

+

+The computer with the serial port connected to the device (such as a

+data aquisition device) runs the remserial program:

+

+	remserial -d -r server-name -p 23000 -s "9600 raw" /dev/ttyS0 &

+

+This would be used with case number 1 above creating an end-to-end serial

+port connection.  What goes in the serial port on one machine would come

+out the serial port of the other machine.  The ports could be running at

+different baud rates or other serial port settings.

+

+3) Connect a Linux program that needs a serial port to a remote serial port.

+

+Some programs are written to communicate directly with a serial port such

+as some data aquisition programs.  The remserial program can use

+pseudo-ttys to fool the program into thinking that it is talking to a

+real serial port on the local machine:

+

+	remserial -d -r server-name -p 23000 -l /dev/remserial1 /dev/ptmx &

+

+This creates a file called /dev/remserial1 which can be used by the

+data aquisition application as its serial port.  Any data sent or received

+is passed to the remote server-name on port 23000 where a computer configured

+in case number 1 above passes it to a real serial port.

+

+The remserial program uses the special pseudo-tty master device /dev/ptmx

+(see man ptmx) which creates a slave device that looks like a normal

+serial port named /dev/pts/something.  Unfortunately, the actual device

+name created isn't consistent, so the remserial program creates a symbol

+link from the device name specified with the -l option to the /dev/pts/

+name that was created allowing the other application to be configured

+with a consistent device name.

+

+4) Server farm console control.

+

+Assuming multiple Linux servers (such as web servers) are set up to have a

+serial port as their console instead of a monitor/keyboard, their serial

+ports could be connected to a control server using a multi-port serial board.

+On the control server, a copy of remserial is run for each server:

+

+	remserial -d -p 23000 -s "115200 raw" /dev/ttyS0 &

+	remserial -d -p 23001 -s "115200 raw" /dev/ttyS1 &

+	remserial -d -p 23002 -s "115200 raw" /dev/ttyS2 &

+	remserial -d -p 23003 -s "115200 raw" /dev/ttyS3 &

+	etc.

+

+From any computer on the local network, use a telnet program to connect

+to the control server on the appropriate port:

+

+	telnet control-server-name 23002

+

+This would connect through the associated serial port to the desired server's

+console.  This example would then give the user console access to the 3rd

+server.

+

+Careful scripting such as using the Linux "expect" program could allow

+batches of commands to be run on each server.

+

+Other Linux program useful with remserial

+-----------------------------------------

+

+- nc - The netcat program is similar to remserial except that it creates

+  connections between network ports and command line standard input and

+  output.

+

+  For example, with case number 1 above, the following command run on

+  another computer will send the contents of the named file out the

+  serial port used by the remserial program:

+

+  nc server-name 23000 <file-name

+

+  Similarily, the following command will store incoming serial data in a file

+  until the program is manually interrupted:

+

+  nc server-name 23000 >file-name

+

+- telnet - The telnet program is normally used to log into a remote computer,

+  but when used with network ports other than number 23, it operates in a

+  raw data mode.

+

+  For example, with case number 1 above, the following command will allow

+  the user of the telnet program to see incoming serial port data and

+  type data on the keyboard to send to the serial port:

+

+  telnet server-name 23000

+

+  This is ideal for controlling the device connected to the serial port 

+  if it has some sort of command line interface usable over the serial port.

+

+

+remserial Usage:

+---------------

+

+remserial [-r machinename] [-p netport] [-s "stty params"] device

+

+-r machinename		The remote machine name to connect to.  If not

+			specified, then this is the server side.

+-p netport		Specifiy IP port# (default 23000)

+-s "stty params"	If serial port, specify stty parameters, see man stty

+-d			Run as daemon programs

+-x debuglevel		Set debug level, 0 is default, 1,2 give more info

+-l linkname		If the device is /dev/ptmx, creates a symbolic link

+                        to the corresponding slave pseudo-tty so that another

+			application has a static device name to use.

+-m max-connections	Maximum number of simultaneous client connections to allow

+device			Character oriented device node such as /dev/ttyS0.

+

diff --git a/ap/hostapp/zlogtrace_ref/netcom_rserial/comm_serial.c b/ap/hostapp/zlogtrace_ref/netcom_rserial/comm_serial.c
new file mode 100755
index 0000000..6b641b2
--- /dev/null
+++ b/ap/hostapp/zlogtrace_ref/netcom_rserial/comm_serial.c
@@ -0,0 +1,405 @@
+/*
+ * 
+ * Copyright (C) 2000  Paul Davis, pdavis@lpccomp.bc.ca
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This program acts as a bridge either between a socket(2) and a
+ * serial/parallel port or between a socket and a pseudo-tty.
+ */
+#include "../zlog_com.h"
+
+/**
+ * ºê¶¨Òå
+ */
+#define RECVBUF_MODEM_MAX_LEN   2048
+#define RECVBUF_SOCK_CLIENT_LEN  512
+
+/**
+ * Íⲿ±äÁ¿ÒýÓÃ
+ */
+extern char* ptsname(int fd);
+
+/**
+ * Íⲿº¯ÊýÒýÓÃ
+ */
+extern int set_tty(int fd, char *settings);
+
+/**
+ * È«¾Ö±äÁ¿¶¨Òå
+ */
+struct sockaddr_in addr, remoteaddr;
+int    devfd;
+int    *remotefd;
+char   *machinename;
+char   *sttyparms;
+char   *sdevname;
+char   *linkname;
+int    sockfd    = -1;
+int    port    = 23000;
+int    debug   = 0;
+int    isdaemon    = 0;
+int    curConnects = 0;
+int    maxConnects = 1;
+int    writeonly;
+
+fd_set  fdsread, fdsreaduse;
+struct  hostent *remotehost;
+char    devbuf[RECVBUF_MODEM_MAX_LEN];
+
+/**
+ * ¾Ö²¿º¯ÊýÉùÃ÷
+ */
+void zLogAgt_SigHandler(int sig);
+int zLogAgt_connect_to(struct sockaddr_in *addr);
+void usage(char *progname);
+void link_slave(int fd);
+
+/**
+ * @brief ÐźŴ¦Àíº¯Êý
+ * @param[in] sigÐźÅÖµ
+ * @return VOID
+ * @note
+ * @see 
+ */
+void zLogAgt_SigHandler(int sig)
+{
+    int i;
+
+    if (sockfd != -1)
+        close(sockfd);
+    
+    for (i=0; i<curConnects; i++)
+        close(remotefd[i]);
+    
+    if (devfd != -1)
+        close(devfd);
+    
+    if (linkname)
+        unlink(linkname);
+    
+    printf("Terminating on signal %d", sig);
+    exit(8);
+}
+
+void link_slave(int fd)
+{
+    char *slavename;
+    int status = grantpt(devfd);
+    if (status != -1)
+        status = unlockpt(devfd);
+    if (status != -1) {
+        slavename = ptsname(devfd);
+        if (slavename) {
+            // Safety first
+            unlink(linkname);
+            status = symlink(slavename, linkname);
+        }
+        else
+            status = -1;
+    }
+    if (status == -1) {
+        printf( "Cannot create link for pseudo-tty: %m");
+        exit(9);
+    }
+}
+
+/**
+ * @brief socketÍøÂçͨÐÅ´¦ÀíÁ÷³Ì
+ * @param[in] addr
+ * @return socket Ì×½Ó×Ö
+ * @note
+ * @see 
+ */
+int zLogAgt_connect_to(struct sockaddr_in *addr)
+{
+    int waitlogged = 0;
+    int stat;
+    int sockfd;
+    extern int errno;
+
+    if (debug > 0) {
+        unsigned long ip = ntohl(addr->sin_addr.s_addr);
+        printf("Trying to connect to %d.%d.%d.%d",
+            (int)(ip>>24)&0xff,
+            (int)(ip>>16)&0xff,
+            (int)(ip>>8)&0xff,
+            (int)(ip>>0)&0xff);
+    }
+
+    while (1) {
+        /* Open the socket for communications */
+        sockfd = socket(AF_INET, SOCK_STREAM, 6);
+        
+        if (sockfd == -1) {
+            printf( "Can't open socket: %m");
+            exit(10);
+        }
+
+        /* Try to connect to the remote server,
+           if it fails, keep trying */
+
+        stat = connect(sockfd, (struct sockaddr*)addr,
+            sizeof(struct sockaddr_in));
+        if (debug>1)
+            if (stat == -1)
+                printf( "Connect status %d, errno %d: %m\n", stat,errno);
+            else
+                printf( "Connect status %d\n", stat);
+
+        if (stat == 0)
+            break;
+        /* Write a message to printf once */
+        if (!waitlogged) {
+            printf(    "Waiting for server on %s port %d: %m",    machinename, port);
+            waitlogged = 1;
+        }
+        close(sockfd);
+        sleep(10);
+    }
+    if (waitlogged || debug > 0)
+        printf("Connected to server %s port %d", machinename, port);
+    
+    return sockfd;
+}
+
+/**
+ * main º¯Êý¶¨Òå
+ */
+ /**
+ * @brief net <-> serial ģʽÖ÷´¦Àíº¯Êý
+ * @param[in] usb É豸Îļþ¾ä±ú
+ * @return Á÷³Ì´¦Àí½á¹û
+ * @note
+ * @see 
+ */
+int zLogAgt_NetSerial_Main(int fd_usb)
+{
+    int result;
+    extern char *optarg;
+    extern int optind;
+    int maxfd = -1;
+    int devbytes;
+    int remoteaddrlen;
+    int waitlogged = 0;
+    register int i;
+    
+    PRINTF_DBG_INFO("Net and Serial Enter\n");
+
+    printf("sdevname=%s, port=%d, stty=%s\n",sdevname,port,sttyparms);//sdevname=/dev/ttyUSB0, port=23000, stty=921600 raw, optind=5
+
+    devfd = fd_usb;
+    
+    signal(SIGINT,  zLogAgt_SigHandler);
+    signal(SIGHUP,  zLogAgt_SigHandler);
+    signal(SIGTERM, zLogAgt_SigHandler);
+
+    remotefd = (int *) malloc (maxConnects * sizeof(int));
+    openlog("remserial", LOG_PID, LOG_USER);
+
+    if (linkname)
+        link_slave(devfd);
+
+    /* remserial  -r server-name -p 23000 -s "9600 raw" /dev/ttyS0 */
+    if (machinename) {
+        /* We are the client,
+           Find the IP address for the remote machine */
+        remotehost = gethostbyname(machinename);
+        if (!remotehost) {
+            printf("Couldn't determine address of %s\n", machinename);
+            exit(3);
+        }
+
+        /* Copy it into the addr structure */
+        addr.sin_family = AF_INET;
+        memcpy(&(addr.sin_addr), remotehost->h_addr_list[0],
+            sizeof(struct in_addr));
+        addr.sin_port = htons(port);
+
+        remotefd[curConnects++] = zLogAgt_connect_to(&addr);
+    }
+    else {
+        /* We are the server */
+        /* Open the initial socket for communications */
+        sockfd = socket(AF_INET, SOCK_STREAM, 6);
+        if (sockfd == -1) {
+            printf("Can't open socket: %m\n");
+            exit(4);
+        }
+
+        addr.sin_family = AF_INET;
+        //addr.sin_addr.s_addr = 0;
+        addr.sin_port = htons(port);
+        addr.sin_addr.s_addr = htonl(INADDR_ANY);
+     
+        /* Set up to listen on the given port */
+        if(bind(sockfd, (struct sockaddr*)(&addr),
+            sizeof(struct sockaddr_in)) < 0) {
+            printf("Couldn't bind port %d, aborting: %m",port);
+            exit(5);
+        }
+        if (debug > 1)
+            printf("Bound port\n");
+
+        /* Tell the system we want to listen on this socket */
+        result = listen(sockfd, 4);
+        if (result == -1) {
+            printf( "Socket listen failed: %m");
+            exit(6);
+        }
+
+        if (debug > 1)
+            printf("Done listen\n");
+    }
+
+    if (isdaemon) {
+        setsid();
+        close(0);
+        close(1);
+        close(2);
+    }
+
+    /* Set up the files/sockets for the select() call */
+    if (sockfd != -1) {
+        FD_SET(sockfd, &fdsread);
+        if (sockfd >= maxfd)
+            maxfd = sockfd + 1;
+    }
+
+    for (i = 0; i < curConnects; i++) {
+        FD_SET(remotefd[i], &fdsread);
+        if (remotefd[i] >= maxfd)
+            maxfd = remotefd[i] + 1;
+    }
+
+    if (!writeonly) {
+        FD_SET(devfd, &fdsread);
+        if (devfd >= maxfd)
+            maxfd = devfd + 1;
+    }
+
+    while (1) {
+        /* Wait for data from the listening socket, the device
+           or the remote connection */
+        fdsreaduse = fdsread;
+        if (select(maxfd, &fdsreaduse, NULL, NULL, NULL) == -1)
+            break;
+
+        /* Activity on the controlling socket, only on server */
+        if (!machinename && FD_ISSET(sockfd, &fdsreaduse)) {
+            int fd;
+
+            /* Accept the remote systems attachment */
+            remoteaddrlen = sizeof(struct sockaddr_in);
+            fd = accept(sockfd, (struct sockaddr*)(&remoteaddr), &remoteaddrlen);
+        
+            if (fd == -1)
+                printf("accept failed: \n");
+            else if (curConnects < maxConnects) {
+                unsigned long ip;
+                remotefd[curConnects++] = fd;
+                /* Tell select to watch this new socket */
+                FD_SET(fd, &fdsread);
+                if ( fd >= maxfd )
+                    maxfd = fd + 1;
+                ip = ntohl(remoteaddr.sin_addr.s_addr);
+                printf( "Connection from %d.%d.%d.%d\n",
+                    (int)(ip>>24)&0xff,
+                    (int)(ip>>16)&0xff,
+                    (int)(ip>>8)&0xff,
+                    (int)(ip>>0)&0xff);
+            }
+            else {
+                // Too many connections, just close it to reject
+                close(fd);
+            }
+        }
+
+        /* Data to read from the device */
+        if (FD_ISSET(devfd, &fdsreaduse)) {
+            devbytes = read(devfd, devbuf, RECVBUF_MODEM_MAX_LEN - 1);
+
+            if (debug > 1)
+                printf("Device: %d bytes\n", devbytes);
+            if (devbytes <= 0) {
+                if (debug > 0)
+                    printf("%s closed\n", sdevname);
+                close(devfd);
+                FD_CLR(devfd, &fdsread);
+                while (1) {
+                    devfd = open(sdevname, O_RDWR);
+                    if (devfd != -1)
+                        break;
+                    printf("Open of %s failed: %m\n", sdevname);
+                    if (errno != EIO)
+                        exit(7);
+                    sleep(1);
+                }
+                if (debug > 0)
+                    printf("%s re-opened", sdevname);
+                if (sttyparms)
+                    set_tty(devfd, sttyparms);
+                if (linkname)
+                    link_slave(devfd);
+                FD_SET(devfd, &fdsread);
+                if (devfd >= maxfd)
+                    maxfd = devfd + 1;
+            }
+            else
+                for (i = 0; i < curConnects; i++)
+                    write(remotefd[i], devbuf, devbytes);
+        }
+
+        if (debug > 1)
+            printf("read Remotefd data start\n");
+        /* Data to read from the remote system */
+        for (i = 0; i < curConnects; i++)
+            if (FD_ISSET(remotefd[i], &fdsreaduse)) {
+                devbytes = read(remotefd[i], devbuf, RECVBUF_SOCK_CLIENT_LEN);
+                //if ( debug>1 && devbytes>0 )
+                if (debug > 1)
+                    printf("Remote: %d bytes", devbytes);
+
+                if (devbytes == 0) {
+                    register int j;
+                    printf("Connection closed\n");
+                    close(remotefd[i]);
+                    FD_CLR(remotefd[i], &fdsread);
+                    curConnects--;
+                    
+                    for (j=i; j<curConnects; j++)
+                        remotefd[j] = remotefd[j+1];
+                    
+                    if (machinename) {
+                        /* Wait for the server again */
+                        remotefd[curConnects++] = zLogAgt_connect_to(&addr);
+                        FD_SET(remotefd[curConnects-1], &fdsread);
+                        if (remotefd[curConnects-1] >= maxfd)
+                            maxfd = remotefd[curConnects-1] + 1;
+                    }
+                }
+                else if (devfd != -1)
+                    /* Write the data to the device */
+                    write(devfd, devbuf, devbytes);
+        }
+    }
+    close(sockfd);
+    for (i=0; i<curConnects; i++)
+        close(remotefd[i]);
+
+    return 0;
+}
+
diff --git a/ap/hostapp/zlogtrace_ref/netcom_rserial/comm_stty.c b/ap/hostapp/zlogtrace_ref/netcom_rserial/comm_stty.c
new file mode 100755
index 0000000..9229ee0
--- /dev/null
+++ b/ap/hostapp/zlogtrace_ref/netcom_rserial/comm_stty.c
@@ -0,0 +1,275 @@
+/*
+ * remserial
+ * Copyright (C) 2000  Paul Davis
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include "../zlog_com.h"
+
+/**
+ * ºê¶¨Òå
+ */
+#define CFLG    0
+#define IFLG    1
+#define OFLG    2
+#define LFLG    3
+#define RFLG    4
+#define BFLG    5
+
+
+/**
+ * Íⲿ±äÁ¿ÒýÓÃ
+ */
+extern int errno;
+
+/**
+ * È«¾Ö±äÁ¿¶¨Òå
+ */
+static struct sttyset {
+    char *name;
+    int which;
+    int mask;
+    int value;
+} sttynames[] = {
+    { "raw",    RFLG,    0,     0},
+    { "0",      BFLG,    0,     B0},
+    { "50",     BFLG,    0,     B50},
+    { "75",     BFLG,    0,     B75},
+    { "110",    BFLG,    0,     B110},
+    { "134",    BFLG,    0,     B134},
+    { "150",    BFLG,    0,     B150},
+    { "200",    BFLG,    0,     B200},
+    { "300",    BFLG,    0,     B300},
+    { "600",    BFLG,    0,     B600},
+    { "1200",   BFLG,    0,     B1200},
+    { "1800",   BFLG,    0,     B1800},
+    { "2400",   BFLG,    0,     B2400},
+    { "4800",   BFLG,    0,     B4800},
+    { "9600",   BFLG,    0,     B9600},
+    { "19200",  BFLG,    0,     B19200},
+    { "38400",  BFLG,    0,     B38400},
+#ifdef B57600
+    { "57600",  BFLG,    0,     B57600},
+#endif
+#ifdef B115200
+    { "115200", BFLG,    0,     B115200},
+#endif
+#ifdef B230400
+    { "230400", BFLG,    0,     B230400},
+#endif
+    { "cs7",     CFLG,    CSIZE,     CS7},
+    { "cs8",     CFLG,    CSIZE,     CS8},
+    { "cstopb",  CFLG,    CSTOPB,    CSTOPB},
+    { "cread",   CFLG,    CREAD,     CREAD},
+    { "parenb",  CFLG,    PARENB,    PARENB},
+    { "parodd",  CFLG,    PARODD,    PARODD},
+    { "hubcl",   CFLG,    HUPCL,     HUPCL},
+    { "clocal",  CFLG,    CLOCAL,    CLOCAL},
+#ifdef CRTSCTS
+    { "crtscts", CFLG,    CRTSCTS,   CRTSCTS},
+#endif
+#ifdef ORTSFL
+    { "ortsfl",  CFLG,    ORTSFL,    ORTSFL},
+#endif
+#ifdef CTSFLOW
+    { "ctsflow", CFLG,    CTSFLOW,   CTSFLOW},
+#endif
+#ifdef RTSFLOW
+    { "rtsflow", CFLG,    RTSFLOW,   RTSFLOW},
+#endif
+    { "ignbrk",  IFLG,    IGNBRK,    IGNBRK},
+    { "brkint",  IFLG,    BRKINT,    BRKINT},
+    { "ignpar",  IFLG,    IGNPAR,    IGNPAR},
+    { "parmrk",  IFLG,    PARMRK,    PARMRK},
+    { "inpck",   IFLG,    INPCK,     INPCK},
+    { "istrip",  IFLG,    ISTRIP,    ISTRIP},
+    { "inlcr",   IFLG,    INLCR,     INLCR},
+    { "igncr",   IFLG,    IGNCR,     IGNCR},
+    { "icrnl",   IFLG,    ICRNL,     ICRNL},
+#ifdef IUCLC    // Missing on OSX, FreeBSD
+    { "iuclc",   IFLG,    IUCLC,     IUCLC},
+#endif
+    { "ixon",    IFLG,    IXON,      IXON},
+    { "ixany",   IFLG,    IXANY,     IXANY},
+    { "ixoff",   IFLG,    IXOFF,     IXOFF},
+#ifdef IMAXBEL
+    { "imaxbel", IFLG,    IMAXBEL,   IMAXBEL},
+#endif
+    { "opost",   OFLG,    OPOST,     OPOST},
+#ifdef ILCUC    // Missing on OSX, FreeBSD
+    { "olcuc",   OFLG,    OLCUC,     OLCUC},
+#endif
+    { "onlcr",   OFLG,    ONLCR,        ONLCR},
+    { "ocrnl",   OFLG,    OCRNL,        OCRNL},
+    { "onocr",   OFLG,    ONOCR,        ONOCR},
+    { "onlret",  OFLG,    ONLRET,        ONLRET},
+    { "ofil",    OFLG,    OFILL,        OFILL},
+    { "ofdel",   OFLG,    OFDEL,        OFDEL},
+    { "nl0",     OFLG,    NLDLY,        NL0},
+    { "nl1",     OFLG,    NLDLY,        NL1},
+    { "cr0",     OFLG,    CRDLY,        CR0},
+    { "cr1",     OFLG,    CRDLY,        CR1},
+    { "cr2",     OFLG,    CRDLY,        CR2},
+    { "cr3",     OFLG,    CRDLY,        CR3},
+    { "tab0",    OFLG,    TABDLY,       TAB0},
+    { "tab1",    OFLG,    TABDLY,       TAB1},
+    { "tab2",    OFLG,    TABDLY,       TAB2},
+    { "tab3",    OFLG,    TABDLY,       TAB3},
+    { "bs0",     OFLG,    BSDLY,        BS0},
+    { "bs1",     OFLG,    BSDLY,        BS1},
+    { "vt0",     OFLG,    VTDLY,        VT0},
+    { "vt1",     OFLG,    VTDLY,        VT1},
+    { "ff0",     OFLG,    FFDLY,        FF0},
+    { "ff1",     OFLG,    FFDLY,        FF1},
+    { "isig",    LFLG,    ISIG,         ISIG},
+    { "icanon",    LFLG,    ICANON,        ICANON},
+#ifdef XCASE    // Missing on OSX, FreeBSD
+    { "xcase",    LFLG,    XCASE,        XCASE},
+#endif
+    { "echo",      LFLG,    ECHO,        ECHO},
+    { "echoe",     LFLG,    ECHOE,        ECHOE},
+    { "echok",     LFLG,    ECHOK,        ECHOK},
+    { "echonl",    LFLG,    ECHONL,        ECHONL},
+    { "noflsh",    LFLG,    NOFLSH,        NOFLSH},
+    { "tostop",    LFLG,    TOSTOP,        TOSTOP},
+#ifdef ECHOCTL
+    { "echoctl",   LFLG,    ECHOCTL,    ECHOCTL},
+#endif
+#ifdef ECHOPRT
+    { "echoprt",   LFLG,    ECHOPRT,    ECHOPRT},
+#endif
+#ifdef ECHOKE
+    { "echoke",    LFLG,    ECHOKE,     ECHOKE},
+#endif
+#ifdef FLUSHO
+    { "flusho",    LFLG,    FLUSHO,     FLUSHO},
+#endif
+#ifdef PENDIN
+    { "pendin",    LFLG,    PENDIN,     PENDIN},
+#endif
+    { "iexten",    LFLG,    IEXTEN,     IEXTEN},
+#ifdef TOSTOP
+    { "tostop",    LFLG,    TOSTOP,     TOSTOP},
+#endif
+    { NULL,        0,       0,          0}
+};
+
+/**
+ * @brief ÉèÖÃttyÉ豸µÄ²¨ÌØÂÊ
+ * @param[in] term¡¢p¡¢turnon
+ * @return void
+ * @note
+ * @see 
+ */
+static void set_this_tty(struct termios *term, struct sttyset *p, int turnon)
+{
+    /*
+    pdebug(5,"set_this_tty: setting %s on? %d\n",p->name,turnon);
+    */
+    switch (p->which) {
+    case CFLG:
+        term->c_cflag &= ~(p->mask);
+        if (turnon)
+            term->c_cflag |= p->value;
+        break;
+    case IFLG:
+        term->c_iflag &= ~(p->mask);
+        if (turnon)
+            term->c_iflag |= p->value;
+        break;
+    case OFLG:
+        term->c_oflag &= ~(p->mask);
+        if (turnon)
+            term->c_oflag |= p->value;
+        break;
+    case LFLG:
+        term->c_lflag &= ~(p->mask);
+        if (turnon)
+            term->c_lflag |= p->value;
+        break;
+    case RFLG:
+        term->c_iflag = 0;
+        term->c_oflag = 0;
+        term->c_lflag = 0;
+        term->c_cc[VMIN] = 1;
+        term->c_cc[VTIME] = 0;
+        break;
+    case BFLG:
+        cfsetispeed(term, p->value);
+        cfsetospeed(term, p->value);
+        break;
+    }
+}
+
+/**
+ * @brief ÉèÖÃttyÉ豸µÄ²¨ÌØÂÊ
+ * @param[in] fdÉ豸ÎļþÃèÊö·û
+ * @param[in] settings ²¨ÌØÂÊÖµ
+ * @return ³É¹¦·µ»Ø0£¬Ê§°Ü·µ»Ø-1
+ * @note
+ * @see 
+ */
+int set_tty(int fd, char *settings)
+{
+    register char *p;
+    register char *s;
+    struct termios term;
+    register int i;
+    int mode;
+
+    printf("set_tty: baud rate is %s, and the default baud is %s\n", settings, ZLOG_DEFAULT_TTYBAUD);
+
+    if (tcgetattr(fd,&term) == -1) {
+        /*
+        pdebug(4,"set_tty: cannot get settings for fd %d, error %d\n",
+            fd,errno);
+        */
+        return -1;
+    }
+
+    s = strdup(settings);
+    p = strtok(s, " \t\n");
+    while (p) {
+        mode = 1;
+        if (*p == '-') {
+            mode = 0;
+            p++;
+        }
+        for (i=0; sttynames[i].name; i++) {
+            if (!strcmp(p,sttynames[i].name)) {
+                set_this_tty(&term,&sttynames[i],mode);
+                break;
+            }
+        }
+        p = strtok(NULL, " \t\n");
+    }
+    free(s);
+    if (tcsetattr(fd, TCSANOW, &term) == -1) {
+        /*
+        pdebug(4,"set_tty: cannot get settings for fd %d error %d\n",
+            fd,errno);
+        */
+        return -1;
+    }
+    else
+        return 0;
+}
+