📄 comport.c
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2007, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description:// Serial port handler.// Driver for handling serial port (RS232) communication.// ---// Change History:// 2006/01/04 Martin D. Flynn// -Initial release// 2006/01/16 Martin D. Flynn// -Changed client/server 'pipe' device names// 2006/01/27 Martin D. Flynn// -Added support for 'ttyUSB#' named devices// 2007/01/28 Martin D. Flynn// -Made some changes to the way that pipes are initialized to emulate// ComPort. (handling of pipes appear to be different for different// versions of Linux).// -Specifying 'CPIPE'/'SPIPE' now properly defaults to 'CPIPE0'/'SPIPE0'.// -WindowsCE port// 2007/02/01 Martin D. Flynn// -Code cleanup// -Removed 'COMPORT_SUPPORT_SOCKET' code (which wasn't used anyway)// 2007/03/11 Martin D. Flynn// -Put back 'COMPORT_SUPPORT_SOCKET' code (somebody found it useful :-)// -Changed socket support port base to '32000' (see comport.h)// -Added support for reading data from NMEAD - port 1155 (special thanks to // Tomasz Rostanski for the information on this). // See "http://home.hiwaay.net/~taylorc/gps/nmea-server/" for details on// support for NMEAD ("NMEA Server").// ----------------------------------------------------------------------------#include "stdafx.h" // TARGET_WINCE#define SKIP_TRANSPORT_MEDIA_CHECK // only if TRANSPORT_MEDIA not used in this file #include "custom/defaults.h"#include <stdio.h>#include <string.h>#include <stdarg.h>#include <ctype.h>#if defined(TARGET_WINCE)# include <winsock2.h>#else# include <unistd.h># include <fcntl.h># include <errno.h># include <sys/ioctl.h># include <sys/poll.h># include <sys/types.h># include <sys/stat.h># include <sys/select.h>#endif#include "custom/log.h"#include "tools/stdtypes.h"#include "tools/utctools.h"#include "tools/strtools.h"#include "tools/comport.h"#if defined(TARGET_WINCE)# if defined(COMPORT_SUPPORT_PIPE)# undef COMPORT_SUPPORT_PIPE# endif# if defined(COMPORT_SUPPORT_CONSOLE)# undef COMPORT_SUPPORT_CONSOLE# endif# if defined(COMPORT_SUPPORT_SOCKET)# undef COMPORT_SUPPORT_SOCKET# endif#endif#if defined(COMPORT_SUPPORT_SOCKET)# include <netdb.h># include <netinet/in.h># include <sys/socket.h>#endif// ----------------------------------------------------------------------------#if defined(TARGET_WINCE)static int errno = 0;static char errnoStr[32];static const char *strerror(int err){ sprintf(errnoStr, "%d", err); return errnoStr;}#endif// ----------------------------------------------------------------------------// http://www.virtualblueness.net/serial/serial.html#if defined(TARGET_CYGWIN)// This works on Cygwin# define BYTES_AVAIL_IOCTIL_REQUEST TIOCINQ // Cygwin# define USE_COM_NAMES // use "COM#" names on Cygwin//# define VTIME_SUPPORTED <-- Cygwin does not properly support VTIME #elif defined(TARGET_GUMSTIX) || defined(TARGET_LINUX)// This works fine on Linux and GumStix# include <asm/ioctls.h># define BYTES_AVAIL_IOCTIL_REQUEST FIONREAD // Linux/GumStix (undefined on Cygwin)//# define USE_COM_NAMES <--- use 'ttyS#' names on Linux# define VTIME_SUPPORTED#elif defined(TARGET_WINCE)# define BYTES_AVAIL_IOCTIL_REQUEST FIONREAD // WinCE//# define VTIME_SUPPORTED <-- not supported on WinCE#else# define BYTES_AVAIL_IOCTIL_REQUEST FIONREAD//# define VTIME_SUPPORTED#endif#define BYTES_AVAIL_IOCTL// ----------------------------------------------------------------------------// Comm simulation pipe files#if defined(COMPORT_SUPPORT_PIPE)/* ComPort pipe support */// These files must exist before this feature can be used# define COM_PIPE_CLIENT_FILE "/tmp/comPipe_C."# define COM_PIPE_SERVER_FILE "/tmp/comPipe_S."#endif// ----------------------------------------------------------------------------// local platform comport device file name// Note: These names may be case-sensitive and must match the exact device name.#define ComDev_COM "COM" // COM# devices#define ComDev_VCA "VCA" // VCA# devices#if defined(TARGET_GUMSTIX) || defined(TARGET_CYGWIN) || defined(TARGET_LINUX)# define ComDev_DIR "/dev/" // device directory# define ComDev_ttyS "ttyS" // serial devices# define ComDev_ttyUSB "ttyUSB" // USB devices#endif#if defined(TARGET_GUMSTIX) && defined(COMPORT_SUPPORT_BLUETOOTH)# define ComDev_rfcomm0 "rfcomm0" // Bluetooth device #endif// ----------------------------------------------------------------------------/* non-WinCE data formats */#define PARITY_8N1 (0)#define PARITY_7E1 (1)#define PARITY_7O1 (2)// ----------------------------------------------------------------------------/* return Bluetooth device address/id */#if defined(COMPORT_SUPPORT_BLUETOOTH) && defined(SUPPORT_UInt64)UInt64 comPortGetBluetoothAddress(){# if defined(TARGET_WINCE) // BT_ADDR is equivalent to UInt64 //BT_ADDR btaddr; // 'BthReadLocalAddr' can't be found by the linker //if (BthReadLocalAddr(&btaddr) == ERROR_SUCCESS) { // return (UInt64)btaddr; //}# else // TODO: find Bluetooth ID# endif return 0L;}#endif/* return true if this is a Bluetooth port */// TODO: may not be fully supported on this platform#if defined(COMPORT_SUPPORT_BLUETOOTH)utBool comPortIsBluetooth(ComPort_t *com){ return (com && PORT_IsBLUETOOTH(com->port))? utTrue : utFalse;}#endif/* test for active/ready BT serial connection */#if defined(COMPORT_SUPPORT_BLUETOOTH)utBool comPortIsBluetoothReady(ComPort_t *com){ /* comport open */ if (!comPortIsOpen(com)) { // not open, not connected return utFalse; } /* not bluetooth? */ if (!PORT_IsBLUETOOTH(com->port)) { // assume true, if this port isn't bluetooth return utTrue; //return com->hwFlow? comPortGetCTS(com) : utTrue; } // TODO: this test for serial connectivity is platform dependent // default to 'connected' return utTrue;}#endif// ----------------------------------------------------------------------------/* return the port for the specified name */static Int32 _comPortPortForName(const char *portName){ /* initial filtering */ int portNameLen = portName? strlen(portName) : 0; if (portNameLen <= 0) { return -1L; } /* parsing vars */ const char *p = portName; const char *pnum = (char*)0; int dft = -1, base = 0; Int32 type = COMTYPE_STANDARD;#if defined(COMPORT_SUPPORT_CONSOLE) // Console serial emulator if (strEqualsIgnoreCase(p, ComName_CONSOLE)) { pnum = p + strlen(ComName_CONSOLE); dft = 0; // no port follows "console" base = 0; type = COMTYPE_CONSOLE; } else#endif#if defined(COMPORT_SUPPORT_PIPE) // Client Pipe serial emulator if (strStartsWithIgnoreCase(p, ComName_CPIPE)) { // cpipe# pnum = p + strlen(ComName_CPIPE); dft = 0; // default to "cpipe0" base = 0; type = COMTYPE_CPIPE; } else#endif#if defined(COMPORT_SUPPORT_PIPE) // Server Pipe serial emulator if (strStartsWithIgnoreCase(p, ComName_SPIPE)) { // spipe# pnum = p + strlen(ComName_SPIPE); dft = 0; // default to "spipe0" base = 0; type = COMTYPE_SPIPE; } else#endif#if defined(COMPORT_SUPPORT_SOCKET) // Client socket serial emulator if (strStartsWithIgnoreCase(p, ComName_CSOCK)) { // csock# pnum = p + strlen(ComName_CSOCK); dft = 0; // default to "csock0" base = 0; type = COMTYPE_CSOCK; } else // Client socket serial emulator if (strStartsWithIgnoreCase(p, ComName_NMEAD)) { // nmead# pnum = p + strlen(ComName_NMEAD); // this value is stored, but ignored dft = 0; // default to "nmead0" base = 0; type = COMTYPE_NMEAD; } else // Server socket serial emulator if (strStartsWithIgnoreCase(p, ComName_SSOCK)) { // ssock# pnum = p + strlen(ComName_SSOCK); dft = 0; // default to "ssock0" base = 0; type = COMTYPE_SSOCK; } else#endif#if defined(TARGET_GUMSTIX) // Gumstix FFUART if (strEqualsIgnoreCase(p, ComName_FFUART)) { pnum = p + strlen(ComName_FFUART); dft = 0; // FFUART == TTYS0 base = 0; type = COMTYPE_STANDARD; } else#endif#if defined(TARGET_GUMSTIX) // Gumstix BTUART if (strEqualsIgnoreCase(p, ComName_BTUART)) { pnum = p + strlen(ComName_BTUART); dft = 1; // BTUART == TTYS1 base = 0; type = COMTYPE_STANDARD; } else#endif#if defined(TARGET_GUMSTIX) // Gumstix STUART if (strEqualsIgnoreCase(p, ComName_STUART)) { pnum = p + strlen(ComName_STUART); dft = 2; // STUART == TTYS2 base = 0; type = COMTYPE_STANDARD; } else#endif#if defined(TARGET_GUMSTIX) // Gumstix HWUART if (strEqualsIgnoreCase(p, ComName_HWUART)) { pnum = p + strlen(ComName_HWUART); dft = 3; // HWUART == TTYS3 base = 0; type = COMTYPE_STANDARD; } else#endif#if defined(COMPORT_SUPPORT_BLUETOOTH) // Gumstix Bluetooth if (strEqualsIgnoreCase(p, ComName_RFCOMM0)) { pnum = p + strlen(ComName_RFCOMM0);# if defined(TARGET_GUMSTIX) dft = 3; // RFCOMM0 == TTYS3# else dft = 0; // RFCOMM0 == platform dependent here# endif base = 0; // indexes start at '0' for "rfcomm0" devices type = COMTYPE_BLUETOOTH; } else#endif#if defined(COMPORT_SUPPORT_BLUETOOTH) // Bluetooth if (strStartsWithIgnoreCase(p,ComName_BTH)) { pnum = p + strlen(ComName_BTH); dft = -1; // must be a valid # base = 1; // indexes start at '1' for "BTH" devices type = COMTYPE_BLUETOOTH; } else#endif#if defined(COMPORT_SUPPORT_BLUETOOTH) // Bluetooth if (strStartsWithIgnoreCase(p,ComName_BT)) { pnum = p + strlen(ComName_BT); dft = -1; // must be a valid # base = 1; // indexes start at '1' for "BT" devices type = COMTYPE_BLUETOOTH; } else#endif // COM serial port if (strStartsWithIgnoreCase(p, ComDev_COM)) { pnum = p + strlen(ComDev_COM); dft = -1; // must be a valid # base = 1; // indexes start at '1' for "COM" devices type = COMTYPE_STANDARD; } else #if defined(COMPORT_SUPPORT_USB) // USB serial port if (strStartsWithIgnoreCase(p,ComName_USB)) { pnum = p + strlen(ComName_USB); dft = -1; // must be a valid # base = 1; // indexes start at '1' for "USB" devices type = COMTYPE_USB; } else#endif // 'ttyS' serial port if (strStartsWithIgnoreCase(p, ComName_TTYS)) { pnum = p + strlen(ComName_TTYS); dft = -1; // must be a valid # base = 0; // indexes start at '0' for "ttyS" devices type = COMTYPE_STANDARD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -