⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comport.c

📁 Open DMT Client C Source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* comm state */    //logINFO(LOGSRC,"comPortOpen: SetCommState ...");    DCB portDcb;    memset(&portDcb, 0, sizeof(DCB));    portDcb.DCBlength           = sizeof(DCB);    GetCommState(com->portId, &portDcb);    portDcb.BaudRate            = com->speed;    portDcb.fBinary             = TRUE;    portDcb.fParity             = (_dtaParity != NOPARITY)? TRUE : FALSE;    portDcb.fOutxCtsFlow        = hwFlow? TRUE : FALSE;    portDcb.fOutxDsrFlow        = hwFlow? TRUE : FALSE;    portDcb.fDtrControl         = dtrControl;    portDcb.fDsrSensitivity     = FALSE;    portDcb.fTXContinueOnXoff   = TRUE;    portDcb.fOutX               = FALSE;        // software flow control not supported    portDcb.fInX                = FALSE;        // software flow control not supported    portDcb.fErrorChar          = FALSE;    portDcb.fNull               = FALSE;        // discard nulls on read    portDcb.fRtsControl         = rtsControl;    portDcb.fAbortOnError       = FALSE;    portDcb.XonLim              = 0;            // software flow control not supported    portDcb.XoffLim             = 0;            // software flow control not supported    portDcb.ByteSize            = _dtaBits;     // 7/8 data bits    portDcb.Parity              = _dtaParity;   // NOPARITY(0), ODDPARITY(1), EVENPARITY(2)    portDcb.StopBits            = _dtaStop;     // 1/2 stop bit    portDcb.XonChar             = 0;            // software flow control not supported    portDcb.XoffChar            = 0;            // software flow control not supported    portDcb.ErrorChar           = 0;            // not used?    portDcb.EofChar             = 0;            // not used?    portDcb.EvtChar             = 0;            // not used?    SetCommState(com->portId, &portDcb);    /* timeouts */    //logINFO(LOGSRC,"comPortOpen: SetCommTimeouts ...");    if (!comPortSetTimeouts(com, 300L, 400L, 500L)) {        logERROR(LOGSRC,"Unable to set ComPort timeouts ...");        comPortClose(com);        com->error = COMERR_INIT;        return (ComPort_t*)0;    }    /* success? */    com->open = utTrue;    return com;}#else// NOTE: port number indexes start at '0'ComPort_t *comPortOpen(ComPort_t *com, const char *portName, long bps, const char *dataFmt, utBool hwFlow){    /* null structure? */    if (!com) {        // internal error        logWARNING(LOGSRC,"ComPort structure is 'null'");        return (ComPort_t*)0;    }    /* clear structure */    comPortInitStruct(com);        /* port */    com->port = _comPortPortForName(portName);    if (com->port < 0L) {        // internal error        logWARNING(LOGSRC,"Unrecognized port name: %s", portName);        com->error = COMERR_INIT;        strCopy(com->name, sizeof(com->name), portName, -1);        return (ComPort_t*)0;    }    _comPortNameForPort(com->name, com->port);    _comPortDeviceForPort(com->dev, com->port);    logDEBUG(LOGSRC,"ComPort name=%s, port=0x%04lX, dev=%s", com->name, com->port, com->dev);    /* special ports */#if defined(COMPORT_SUPPORT_CONSOLE)    if (PORT_IsCONSOLE(com->port)) {        com->read_fd    = fileno(stdin);        com->write_fd   = fileno(stdout);        com->open       = utTrue;        comPortResetSTDIN();     // disable echo & buffering        comPortResetSTDOUT();    // disable buffering        return com;    }#endif#if defined(COMPORT_SUPPORT_PIPE)    if (PORT_IsSPIPE(com->port) || PORT_IsCPIPE(com->port)) {        char pipeFile0[64], pipeFile1[64];        if (PORT_IsSPIPE(com->port)) {            int pipePort = PORT_Index0(com->port);            sprintf(pipeFile0, "%s%d", COM_PIPE_CLIENT_FILE, pipePort);            sprintf(pipeFile1, "%s%d", COM_PIPE_SERVER_FILE, pipePort);        } else {            int pipePort = PORT_Index0(com->port);            sprintf(pipeFile1, "%s%d", COM_PIPE_CLIENT_FILE, pipePort);            sprintf(pipeFile0, "%s%d", COM_PIPE_SERVER_FILE, pipePort);        }        /*int err0 =*/ mkfifo(pipeFile0, 0777);        /*int err1 =*/ mkfifo(pipeFile1, 0777);        // Note: Opening a named pipe may block indefinitely until the far end of the        // pipe is also openned!  Use with caution!  (O_NONBLOCK)        if (PORT_IsSPIPE(com->port)) {            logDEBUG(LOGSRC,"Openning ComPort server pipe: W(%s) R(%s)", pipeFile1, pipeFile0);            com->write_fd = open(pipeFile1, O_WRONLY, 0);            com->read_fd  = open(pipeFile0, O_RDONLY, 0);        } else {            logDEBUG(LOGSRC,"Openning ComPort client pipe: W(%s) R(%s)", pipeFile1, pipeFile0);            com->read_fd  = open(pipeFile0, O_RDONLY, 0);            com->write_fd = open(pipeFile1, O_WRONLY, 0);        }        if ((com->read_fd >= 0) && (com->write_fd >= 0)) {            logDEBUG(LOGSRC,"ComPort pipe openned: W(%s) R(%s)", pipeFile1, pipeFile0);            com->open = utTrue;            return com;        } else {            logWARNING(LOGSRC,"Unable to open pipe: W(%s) R(%s)", pipeFile1, pipeFile0);            if (com->read_fd  >= 0) { close(com->read_fd ); com->read_fd  = -1; }            if (com->write_fd >= 0) { close(com->write_fd); com->write_fd = -1; }            com->error = COMERR_INIT;            return (ComPort_t*)0;        }    }#endif#if defined(COMPORT_SUPPORT_SOCKET)    if (PORT_IsCSOCK(com->port) || PORT_IsNMEAD(com->port)) {        const char *sockHost = CSOCK_SOCKET_HOST;        int sockPort = PORT_IsNMEAD(com->port)? NMEAD_SOCKET_PORT : (PORT_Index0(com->port) + CSOCK_SOCKET_PORT_BASE);        logINFO(LOGSRC,"Openning client socket [%s:%d] ...", sockHost, sockPort);        com->read_fd = socket(AF_INET, SOCK_STREAM, 0); // SOCK_DGRAM        if (com->read_fd <= -1) {            // unable to open socket            logWARNING(LOGSRC,"Unable to open Comport socket");            com->error = COMERR_INIT;            return (ComPort_t*)0;        }        struct hostent *he = gethostbyname(sockHost);        if (he == NULL) {  // get the host info            // unable to resolve host            logWARNING(LOGSRC,"Unable to resolve Comport socket host");            close(com->read_fd);            com->read_fd = -1;            com->error = COMERR_INIT;            return (ComPort_t*)0;        }        struct sockaddr_in their_addr;      // connector's address information        their_addr.sin_family = AF_INET;    // host byte order        their_addr.sin_port = htons(sockPort);  // short, network byte order        their_addr.sin_addr = *((struct in_addr *)he->h_addr);        memset(&(their_addr.sin_zero), 0, sizeof(their_addr.sin_zero));  // (8) zero the rest of the struct        if (connect(com->read_fd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) < 0) {            // Unable to connect to specified host:port            logINFO(LOGSRC,"Unable to open connection to %s:%d", sockHost, sockPort);            close(com->read_fd);            com->read_fd = -1;            com->error = COMERR_INIT;            return (ComPort_t*)0;        }        com->write_fd = com->read_fd;        com->open = utTrue;        return com;    } else    if (PORT_IsSSOCK(com->port)) {        int yes = 1;        struct sockaddr_in my_addr;    // my address information        int sockPort = PORT_Index0(com->port) + CSOCK_SOCKET_PORT_BASE;        logINFO(LOGSRC,"Openning server socket [%d] ...", sockPort);        int server_fd = socket(AF_INET, SOCK_STREAM, 0); // SOCK_DGRAM        if (server_fd <= -1) {            // unable to open socket            logWARNING(LOGSRC,"Unable to open Comport server socket");            com->error = COMERR_INIT;            return (ComPort_t*)0;        }        if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {            // Unable to set server socket options            logWARNING(LOGSRC,"Unable to set Comport server socket options");            close(server_fd);            com->error = COMERR_INIT;            return (ComPort_t*)0;        }        my_addr.sin_family = AF_INET;         // host byte order        my_addr.sin_port = htons(sockPort);   // short, network byte order        my_addr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP        memset(&my_addr.sin_zero, 0, 8); // zero the rest of the struct        if (bind(server_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {            // Unable to bind server to specified port            logWARNING(LOGSRC,"Unable to bind Comport server socket port");            close(server_fd);            com->error = COMERR_INIT;            return (ComPort_t*)0;        }        if (listen(server_fd, 1) == -1) {            // Unable to listen on specified port            logWARNING(LOGSRC,"Unable to listen on Comport server socket port");            close(server_fd);            com->error = COMERR_INIT;            return (ComPort_t*)0;        }        struct sockaddr_in clientAddr;        int alen = sizeof(clientAddr);        com->read_fd = accept(server_fd, (struct sockaddr *)&clientAddr, &alen);        if (com->read_fd <= -1) {            // client accept failed            logWARNING(LOGSRC,"Unable to accept on Comport server socket port");            close(server_fd);            com->error = COMERR_INIT;            return (ComPort_t*)0;        }        com->write_fd = com->read_fd;        com->open = utTrue;        //close(server_fd);        return com;    }#endif        /* speed */    com->bps = bps;    switch (bps) {        case   BPS_1200: com->speed =   B1200; break;        case   BPS_2400: com->speed =   B2400; break;        case   BPS_4800: com->speed =   B4800; break;        case   BPS_9600: com->speed =   B9600; break;        case  BPS_19200: com->speed =  B19200; break;        case  BPS_38400: com->speed =  B38400; break;        case  BPS_57600: com->speed =  B57600; break;#if defined(B76800)        case  BPS_76800: com->speed =  B76800; break; // undefined on Cygwin#endif        case BPS_115200: com->speed = B115200; break;#if defined(B921600)        case BPS_921600: com->speed = B921600; break; // BlueTooth 'default' speed#endif        default:            // this would be an internal error            logWARNING(LOGSRC,"Unsupport BPS: %s %ld\n", com->dev, com->bps);            com->error = COMERR_SPEED;            return (ComPort_t*)0;    }    /* parse "dataFmt" */    int parity = PARITY_8N1;    if (!dataFmt || !*dataFmt || strEqualsIgnoreCase(dataFmt,DTAFMT_8N1)) {        // 8 data bits, no parity, 1 stop bit (default)        parity = PARITY_8N1;    } else    if (strEqualsIgnoreCase(dataFmt,DTAFMT_8O1)) {        // 8 data bits, odd parity, 1 stop bit (non-standard)        // not yet supported        logWARNING(LOGSRC,"Format not yet supported: %s", dataFmt);    } else    if (strEqualsIgnoreCase(dataFmt,DTAFMT_8E1)) {        // 8 data bits, odd parity, 1 stop bit (non-standard)        // not yet supported        logWARNING(LOGSRC,"Format not yet supported: %s", dataFmt);    } else    if (strEqualsIgnoreCase(dataFmt,DTAFMT_7N2)) {        // 7 data bits, no parity, 2 stop bits        // not yet supported        logWARNING(LOGSRC,"Format not yet supported: %s", dataFmt);    } else    if (strEqualsIgnoreCase(dataFmt,DTAFMT_7E1)) {        // 7 data bits, even parity, 1 stop bits        parity = PARITY_7E1;    } else    if (strEqualsIgnoreCase(dataFmt,DTAFMT_7O1)) {        // 7 data bits, even parity, 1 stop bits        parity = PARITY_7O1;    } else {        logWARNING(LOGSRC,"Unrecognized data format: %s", dataFmt);    }    /* open */    //logDEBUG(LOGSRC,"Openning ComPort port=0x%04lX, dev=%s", com->port, com->dev);    com->read_fd = open(com->dev, O_RDWR | O_NOCTTY);    if (com->read_fd < 0) {        // device is currently unavailable (or doesn't exist)        logWARNING(LOGSRC,"Unable to open ComPort: %s [%s]", com->dev, strerror(errno));        com->error = COMERR_INIT;        return (ComPort_t*)0;    }    com->write_fd = com->read_fd; // comport read/write file descriptor is the same    logDEBUG(LOGSRC,"Openned ComPort port=0x%04lX, dev=%s", com->port, com->dev);    /* set up blocking/non-blocking read */    fcntl(com->read_fd, F_SETFL, 0);             // blocking reads    //fcntl(com->read_fd, F_SETFL, FNDELAY);     // non blocking reads        /* ComPort configuration */    struct termios options;    tcgetattr(com->read_fd, &options);        /* BPS */    cfsetispeed(&options, com->speed);    cfsetospeed(&options, com->speed);        /* control options 'c_cflag' */    com->hwFlow = hwFlow;    options.c_cflag |= CREAD;           // enable receiver    options.c_cflag |= CLOCAL;          // local mode    if (hwFlow) {        options.c_cflag |= CRTSCTS;     // enable hardware flow control    } else {        options.c_cflag &= ~CRTSCTS;    // disable hardware flow control    }    if (parity == PARITY_7E1) {        // PARITY_7E1        options.c_cflag |= PARENB;      // enable parity        options.c_cflag &= ~PARODD;     // even parity        options.c_cflag &= ~CSTOPB;     // 1 stop bit        options.c_cflag &= ~CSIZE;      // [char size mask]        options.c_cflag |= CS7;         // 7 bit    } else    if (parity == PARITY_7O1) {        // PARITY_7O1        options.c_cflag |= PARENB;      // enable parity        options.c_cflag |= PARODD;      // odd parity        options.c_cflag &= ~CSTOPB;     // 1 stop bit        options.c_cflag &= ~CSIZE;      // [char size mask]        options.c_cflag |= CS7;         // 7 bit    } else {        // PARITY_8N1        options.c_cflag &= ~PARENB;     // disable parity        options.c_cflag &= ~CSTOPB;     // 1 stop bit        options.c_cflag &= ~CSIZE;      // [char size mask]        options.c_cflag |= CS8;         // 8 bit    }    options.c_cflag |= HUPCL;           // drop DTR when port is closed  //options.c_cflag &= LOBLK;           // don't block job ctl output (undefined on Cygwin)        /* input options 'c_iflag' */    options.c_iflag &= ~(IGNBRK | BRKINT); // ignore break    options.c_iflag &= ~(IXON | IXOFF | IXANY); // no software flow control    options.c_iflag &= ~PARMRK;         // don't mark parity errors    options.c_iflag &= ~IGNCR;          // don't ignore CR    options.c_iflag &= ~INLCR;          // don't map NL to CR    options.c_iflag &= ~ICRNL;          // don't map CR to NL    if (options.c_cflag & PARENB) {        options.c_iflag |= INPCK;       // enable parity checking        options.c_iflag |= ISTRIP;      // strip parity bit (7th bit)    } else {        options.c_iflag &= ~INPCK;      // DISable parity checking        options.c_iflag &= ~ISTRIP;     // don't strip parity bit    }        /* local options 'c_lflag' */    options.c_lflag &= ~ICANON;         // set raw mode    options.c_lflag &= ~(ECHO | ECHONL); // no echo    options.c_lflag &= ~ISIG;           // disable SIG* interrupt signals    options.c_lflag &= ~IEXTEN;         // disable extended functions    /* read timeouts  'c_cc' */    options.c_cc[VMIN]  = 0;            // no minimum number of characters to read    options.c_cc[VTIME] = 0;            // (deciseconds) 0=block forever (unless FNDELAY was set)        /* output options */    options.c_oflag &= ~OPOST;          // raw output        /* set ComPort options */    // TCSANOW   - changes occur immediately    // TCSADRAIN - changes occur after output is transmitted    // TCSAFLUSH - changes occur after output is transmitted, input discarded    if (tcsetattr(com->write_fd, TCSANOW, &options) != 0) {        logWARNING(LOGSRC,"ComPort init failed: %s [%s]", com->dev, strerror(errno));        // continue    }    // From the 'tcsetattr' man page:    // Note that tcsetattr() returns success if any of the requested changes could be    // successfully carried out.  Therefore, when making multiple changes it may be     // necessary to follow this call with a further call to tcgetattr() to check that     // all changes have been performed successfully.        /* other default options */#if defined(VTIME_SUPPORTED)    // VTIME doesn't work on Cygwin    comPortAddOptions(com, COMOPT_VTIMEOUT);#endif    /* return structure */    com->open = utTrue;    return com;}#endif // defined(TARGET_WINCE)#if defined(TARGET_WINCE)// not yet implemented#elseComPort_t *comPortReopen(ComPort_t *com){    if (!com) {        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -