|
|
| version 1.1, 2004/03/26 13:58:51 | version 1.8, 2012/01/23 04:23:10 |
|---|---|
| Line 1 | Line 1 |
| /* $Id$ */ | |
| /* | /* |
| * Copyright (c) 2004 NONAKA Kimihiro | * Copyright (c) 2004 NONAKA Kimihiro |
| * All rights reserved. | * All rights reserved. |
| Line 12 | Line 10 |
| * 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. |
| * 3. The name of the author may not be used to endorse or promote products | |
| * derived from this software without specific prior written permission. | |
| * | * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| Line 42 | Line 38 |
| typedef struct { | typedef struct { |
| int hdl; | int hdl; |
| struct termios tio; | |
| } _CMSER, *CMSER; | } _CMSER, *CMSER; |
| const UINT32 cmserial_speed[10] = { | const UINT32 cmserial_speed[10] = { |
| Line 94 serialgetstat(COMMNG self) | Line 92 serialgetstat(COMMNG self) |
| int rv; | int rv; |
| rv = ioctl(serial->hdl, TIOCMGET, &status); | rv = ioctl(serial->hdl, TIOCMGET, &status); |
| if (rv < 0) { | |
| VERBOSE(("serialgetstat: ioctl: %s", strerror(errno))); | |
| return 0x20; | |
| } | |
| if (!(status & TIOCM_DSR)) { | if (!(status & TIOCM_DSR)) { |
| VERBOSE(("serialgetstat: DSR is disable")); | VERBOSE(("serialgetstat: DSR is disable")); |
| return 0x20; | return 0x20; |
| Line 118 serialrelease(COMMNG self) | Line 120 serialrelease(COMMNG self) |
| { | { |
| CMSER serial = (CMSER)(self + 1); | CMSER serial = (CMSER)(self + 1); |
| tcsetattr(serial->hdl, TCSANOW, &serial->tio); | |
| close(serial->hdl); | close(serial->hdl); |
| _MFREE(self); | _MFREE(self); |
| } | } |
| /* ---- interface */ | /* ---- interface */ |
| #if defined(SERIAL_DEBUG) | |
| static void | |
| print_status(const struct termios *tio) | |
| { | |
| char *csstr; | |
| int cs; | |
| speed_t ispeed = cfgetispeed(tio); | |
| speed_t ospeed = cfgetospeed(tio); | |
| g_printerr(" ispeed %d", ispeed); | |
| g_printerr(" ospeed %d", ospeed); | |
| g_printerr("%s", "\r\n"); | |
| g_printerr(" %cIGNBRK", (tio->c_iflag & IGNBRK) ? '+' : '-'); | |
| g_printerr(" %cBRKINT", (tio->c_iflag & BRKINT) ? '+' : '-'); | |
| g_printerr(" %cIGNPAR", (tio->c_iflag & IGNPAR) ? '+' : '-'); | |
| g_printerr(" %cPARMRK", (tio->c_iflag & PARMRK) ? '+' : '-'); | |
| g_printerr(" %cINPCK", (tio->c_iflag & INPCK) ? '+' : '-'); | |
| g_printerr(" %cISTRIP", (tio->c_iflag & ISTRIP) ? '+' : '-'); | |
| g_printerr(" %cINLCR", (tio->c_iflag & INLCR) ? '+' : '-'); | |
| g_printerr(" %cIGNCR", (tio->c_iflag & IGNCR) ? '+' : '-'); | |
| g_printerr(" %cICRNL", (tio->c_iflag & ICRNL) ? '+' : '-'); | |
| g_printerr(" %cIXON", (tio->c_iflag & IXON) ? '+' : '-'); | |
| g_printerr(" %cIXOFF", (tio->c_iflag & IXOFF) ? '+' : '-'); | |
| g_printerr(" %cIXANY", (tio->c_iflag & IXANY) ? '+' : '-'); | |
| g_printerr(" %cIMAXBEL", (tio->c_iflag & IMAXBEL) ? '+' : '-'); | |
| g_printerr("%s", "\r\n"); | |
| g_printerr(" %cOPOST", (tio->c_oflag & OPOST) ? '+' : '-'); | |
| g_printerr(" %cONLCR", (tio->c_oflag & ONLCR) ? '+' : '-'); | |
| #ifdef OXTABS | |
| g_printerr(" %cOXTABS", (tio->c_oflag & OXTABS) ? '+' : '-'); | |
| #endif | |
| #ifdef TABDLY | |
| g_printerr(" %cTABDLY", (tio->c_oflag & TABDLY) == XTABS ? '+' : '-'); | |
| #endif | |
| #ifdef ONOEOT | |
| g_printerr(" %cONOEOT", (tio->c_oflag & ONOEOT) ? '+' : '-'); | |
| #endif | |
| g_printerr("%s", "\r\n"); | |
| cs = tio->c_cflag & CSIZE; | |
| switch (cs) { | |
| case CS5: | |
| csstr = "5"; | |
| break; | |
| case CS6: | |
| csstr = "6"; | |
| break; | |
| case CS7: | |
| csstr = "7"; | |
| break; | |
| case CS8: | |
| csstr = "8"; | |
| break; | |
| default: | |
| csstr = "?"; | |
| break; | |
| } | |
| g_printerr(" cs%s", csstr); | |
| g_printerr(" %cCSTOPB", (tio->c_cflag & CSTOPB) ? '+' : '-'); | |
| g_printerr(" %cCREAD", (tio->c_cflag & CREAD) ? '+' : '-'); | |
| g_printerr(" %cPARENB", (tio->c_cflag & PARENB) ? '+' : '-'); | |
| g_printerr(" %cPARODD", (tio->c_cflag & PARODD) ? '+' : '-'); | |
| g_printerr(" %cHUPCL", (tio->c_cflag & HUPCL) ? '+' : '-'); | |
| g_printerr(" %cCLOCAL", (tio->c_cflag & CLOCAL) ? '+' : '-'); | |
| #ifdef CCTS_OFLOW | |
| g_printerr(" %cCCTS_OFLOW", (tio->c_cflag & CCTS_OFLOW) ? '+' : '-'); | |
| #endif | |
| g_printerr(" %cCRTSCTS", (tio->c_cflag & CRTSCTS) ? '+' : '-'); | |
| #ifdef CRTS_IFLOW | |
| g_printerr(" %cCRTS_IFLOW", (tio->c_cflag & CRTS_IFLOW) ? '+' : '-'); | |
| #endif | |
| #ifdef MDMBUF | |
| g_printerr(" %cMDMBUF", (tio->c_cflag & MDMBUF) ? '+' : '-'); | |
| #endif | |
| g_printerr(" %cECHOKE", (tio->c_lflag & ECHOKE) ? '+' : '-'); | |
| g_printerr(" %cECHOE", (tio->c_lflag & ECHOE) ? '+' : '-'); | |
| g_printerr(" %cECHO", (tio->c_lflag & ECHO) ? '+' : '-'); | |
| g_printerr(" %cECHONL", (tio->c_lflag & ECHONL) ? '+' : '-'); | |
| g_printerr(" %cECHOPRT", (tio->c_lflag & ECHOPRT) ? '+' : '-'); | |
| g_printerr(" %cECHOCTL", (tio->c_lflag & ECHOCTL) ? '+' : '-'); | |
| g_printerr(" %cISIG", (tio->c_lflag & ISIG) ? '+' : '-'); | |
| g_printerr(" %cICANON", (tio->c_lflag & ICANON) ? '+' : '-'); | |
| #ifdef ALTWERASE | |
| g_printerr(" %cALTWERASE", (tio->c_lflag & ALTWERASE) ? '+' : '-'); | |
| #endif | |
| g_printerr(" %cIEXTEN", (tio->c_lflag & IEXTEN) ? '+' : '-'); | |
| g_printerr("%s", "\r\n"); | |
| #ifdef EXTPROC | |
| g_printerr(" %cEXTPROC", (tio->c_lflag & EXTPROC) ? '+' : '-'); | |
| #endif | |
| g_printerr(" %cTOSTOP", (tio->c_lflag & TOSTOP) ? '+' : '-'); | |
| g_printerr(" %cFLUSHO", (tio->c_lflag & FLUSHO) ? '+' : '-'); | |
| #ifdef NOKERNINFO | |
| g_printerr(" %cNOKERNINFO", (tio->c_lflag & NOKERNINFO) ? '+' : '-'); | |
| #endif | |
| g_printerr(" %cPENDIN", (tio->c_lflag & PENDIN) ? '+' : '-'); | |
| g_printerr(" %cNOFLSH", (tio->c_lflag & NOFLSH) ? '+' : '-'); | |
| g_printerr("%s", "\r\n"); | |
| } | |
| #endif | |
| COMMNG | COMMNG |
| cmserial_create(UINT port, BYTE param, UINT32 speed) | cmserial_create(UINT port, BYTE param, UINT32 speed) |
| Line 133 cmserial_create(UINT port, BYTE param, U | Line 240 cmserial_create(UINT port, BYTE param, U |
| B9600, B19200, B38400, B57600, B115200 | B9600, B19200, B38400, B57600, B115200 |
| }; | }; |
| static const int csize[] = { CS5, CS6, CS7, CS8 }; | static const int csize[] = { CS5, CS6, CS7, CS8 }; |
| struct termios options; | struct termios options, origopt; |
| COMMNG ret; | COMMNG ret; |
| CMSER serial; | CMSER serial; |
| int hdl; | int hdl; |
| Line 157 cmserial_create(UINT port, BYTE param, U | Line 264 cmserial_create(UINT port, BYTE param, U |
| VERBOSE(("cmserial_create: open failure %s, %s", np2oscfg.com[port].mout, strerror(errno))); | VERBOSE(("cmserial_create: open failure %s, %s", np2oscfg.com[port].mout, strerror(errno))); |
| goto cscre_failure; | goto cscre_failure; |
| } | } |
| fcntl(hdl, F_SETFL, 0); | |
| if (!isatty(hdl)) { | |
| VERBOSE(("cmserial_create: not terminal file descriptor (%s)", strerror(errno))); | |
| goto cscre_close; | |
| } | |
| /* get current options for the port */ | /* get current options for the port */ |
| tcgetattr(hdl, &options); | tcgetattr(hdl, &options); |
| origopt = options; | |
| /* set the baud rates */ | /* baud rates */ |
| for (i = 0; i < NELEMENTS(cmserial_speed); i++) { | for (i = 0; i < NELEMENTS(cmserial_speed); i++) { |
| if (cmserial_speed[i] >= speed) { | if (cmserial_speed[i] >= speed) { |
| VERBOSE(("cmserial_create: spped = %d", cmserial_speed[i])); | VERBOSE(("cmserial_create: spped = %d", cmserial_speed[i])); |
| Line 176 cmserial_create(UINT port, BYTE param, U | Line 288 cmserial_create(UINT port, BYTE param, U |
| cfsetispeed(&options, cmserial_cflag[i]); | cfsetispeed(&options, cmserial_cflag[i]); |
| cfsetospeed(&options, cmserial_cflag[i]); | cfsetospeed(&options, cmserial_cflag[i]); |
| /* set the character size bits */ | /* character size bits */ |
| options.c_cflag &= ~CSIZE; | options.c_cflag &= ~CSIZE; |
| options.c_cflag |= csize[(param >> 2) & 3]; | options.c_cflag |= csize[(param >> 2) & 3]; |
| VERBOSE(("cmserial_create: charactor size = %d", csize[(param >> 2) & 3])); | VERBOSE(("cmserial_create: charactor size = %d", csize[(param >> 2) & 3])); |
| /* set parity check */ | /* parity check */ |
| switch (param & 0x30) { | switch (param & 0x30) { |
| case 0x10: | case 0x10: |
| VERBOSE(("cmserial_create: odd parity")); | VERBOSE(("cmserial_create: odd parity")); |
| options.c_cflag |= PARENB; | options.c_cflag |= PARENB | PARODD; |
| options.c_cflag |= PARODD; | |
| options.c_cflag &= ~CSTOPB; | |
| options.c_iflag |= INPCK | ISTRIP; | options.c_iflag |= INPCK | ISTRIP; |
| break; | break; |
| Line 195 cmserial_create(UINT port, BYTE param, U | Line 305 cmserial_create(UINT port, BYTE param, U |
| VERBOSE(("cmserial_create: even parity")); | VERBOSE(("cmserial_create: even parity")); |
| options.c_cflag |= PARENB; | options.c_cflag |= PARENB; |
| options.c_cflag &= ~PARODD; | options.c_cflag &= ~PARODD; |
| options.c_cflag &= ~CSTOPB; | |
| options.c_iflag |= INPCK | ISTRIP; | options.c_iflag |= INPCK | ISTRIP; |
| break; | break; |
| default: | default: |
| VERBOSE(("cmserial_create: non parity")); | VERBOSE(("cmserial_create: non parity")); |
| options.c_cflag &= ~PARENB; | options.c_cflag &= ~PARENB; |
| options.c_cflag &= ~CSTOPB; | |
| options.c_iflag &= ~(INPCK | ISTRIP); | options.c_iflag &= ~(INPCK | ISTRIP); |
| break; | break; |
| } | } |
| /* set stop bits XXX */ | /* stop bits */ |
| #if 0 | |
| switch (param & 0xc0) { | switch (param & 0xc0) { |
| case 0x80: | case 0x80: |
| dcb.StopBits = ONE5STOPBITS; | VERBOSE(("cmserial_create: stop bits: 1.5")); |
| break; | break; |
| case 0xc0: | case 0xc0: |
| dcb.StopBits = TWOSTOPBITS; | VERBOSE(("cmserial_create: stop bits: 2")); |
| options.c_cflag |= CSTOPB; | |
| break; | break; |
| default: | default: |
| dcb.StopBits = ONESTOPBIT; | VERBOSE(("cmserial_create: stop bits: 1")); |
| options.c_cflag &= ~CSTOPB; | |
| break; | break; |
| } | } |
| /* set misc flag */ | |
| cfmakeraw(&options); | |
| options.c_cflag |= CLOCAL | CREAD; | |
| options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); | |
| #if defined(SERIAL_DEBUG) | |
| print_status(&options); | |
| #endif | #endif |
| ret = (COMMNG)_MALLOC(sizeof(_COMMNG) + sizeof(_CMSER), "SERIAL"); | ret = (COMMNG)_MALLOC(sizeof(_COMMNG) + sizeof(_CMSER), "SERIAL"); |
| Line 230 cmserial_create(UINT port, BYTE param, U | Line 347 cmserial_create(UINT port, BYTE param, U |
| goto cscre_close; | goto cscre_close; |
| } | } |
| /* set misc flag */ | |
| options.c_cflag |= CLOCAL | CREAD; /* enable recv and local mode */ | |
| options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* raw input */ | |
| options.c_oflag &= ~OPOST; /* raw output */ | |
| /* set the new options for the port */ | /* set the new options for the port */ |
| tcsetattr(hdl, TCSANOW, &options); | tcsetattr(hdl, TCSANOW, &options); |
| #if 0 | |
| /* set Non-blocking I/O mode */ | |
| fcntl(hdl, F_SETFL, FNDELAY); | |
| #endif | |
| #if 1 | #if 1 |
| ret->connect = COMCONNECT_MIDI; | ret->connect = COMCONNECT_MIDI; |
| #else | #else |
| Line 255 cmserial_create(UINT port, BYTE param, U | Line 362 cmserial_create(UINT port, BYTE param, U |
| ret->release = serialrelease; | ret->release = serialrelease; |
| serial = (CMSER)(ret + 1); | serial = (CMSER)(ret + 1); |
| serial->hdl = hdl; | serial->hdl = hdl; |
| serial->tio = origopt; | |
| return ret; | return ret; |
| cscre_close: | cscre_close: |