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

📄 serialio-posix.cpp

📁 Powerful and Portable GPS application -- support Linux, Windows, Windows CE GPS navigation and Map m
💻 CPP
字号:
/* *  Roadnav *  SerialIO-POSIX.cpp * *  Copyright (c) 2004 - 2007 Richard L. Lynch <rllynch@users.sourceforge.net> * *  This program is free software; you can redistribute it and/or *  modify it under the terms of version 2 of the GNU General Public License *  as published by the Free Software Foundation. * *  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */  ///////////////////////////////////////////////////////////////////////////////// \file////// Serial support functions for POSIX compliant OSes.////// Works under Linux, also reported to work under Mac OSX./////////////////////////////////////////////////////////////////////////////////#ifdef HAVE_CONFIG_H#  include <config.h>#endif#include <wx/wx.h>#include "libroadnav/Debug.h"#include "SerialIO.h"#include "App.h"#if defined(__LINUX__) || defined(__DARWIN__) || defined(__FREEBSD__) || defined(__SUN__)#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_TERMIOS_H#include <termios.h>#endif#ifdef HAVE_DIRENT_H#include <dirent.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_SYS_FCNTL_H#include <sys/fcntl.h>#endif#ifdef HAVE_ERRNO_H#include <errno.h>#endifstatic int g_hCom = -1;static wxString g_strSerialError;#if defined(__DARWIN__) && defined(HAVE_IOKIT_IOBSD_H) && defined(HAVE_IOKIT_IOKITLIB_H) && defined(HAVE_IOKIT_SERIAL_IOSERIALKEYS_H) && defined(HAVE_COREFOUNDATION_COREFOUNDATION_H)#define USE_IOKIT#endif#ifdef USE_IOKIT#include <stdio.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <errno.h>#include <paths.h>#include <termios.h>#include <sysexits.h>#include <sys/param.h>#include <sys/select.h>#include <sys/time.h>#include <time.h>#include <CoreFoundation/CoreFoundation.h>#include <IOKit/IOKitLib.h>#include <IOKit/serial/IOSerialKeys.h>#include <IOKit/IOBSD.h>bool MakeOSXSerialEnumerator(io_iterator_t * matchingServices){	kern_return_t kernResult;	mach_port_t	masterPort;	CFMutableDictionaryRef classesToMatch;		kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);		if (KERN_SUCCESS !=	kernResult)		return true;		// Serial devices are instances	of class IOSerialBSDClient.	classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);		if (classesToMatch != NULL)		CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));	kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, matchingServices);	if (KERN_SUCCESS !=	kernResult)		return true;	return false;}bool EnumerateOSXSerialPort(io_iterator_t serialPortIterator, int iDesiredPort, char * deviceFilePath, CFIndex maxPathSize){	io_object_t modemService;	int iCurrentPort = 0;		// Initialize the returned path	*deviceFilePath = 0;		// Iterate across all modems found.	while ((modemService = IOIteratorNext(serialPortIterator)))	{		CFTypeRef deviceFilePathAsCFString;		deviceFilePathAsCFString = IORegistryEntryCreateCFProperty(modemService, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);					if (deviceFilePathAsCFString)		{			Boolean result;			result = CFStringGetCString((CFStringRef) deviceFilePathAsCFString, deviceFilePath, maxPathSize, kCFStringEncodingASCII);							CFRelease(deviceFilePathAsCFString);			if (result)			{				// conversion successful				if (strcmp(deviceFilePath, "/dev/cu.modem"))				{					// it's not cu.modem					if (iCurrentPort == iDesiredPort)						return false;					iCurrentPort++;				}			}		}				IOObjectRelease(modemService);	}	return true;}#endifwxString GetLastSerialIOError(){	return g_strSerialError;}//////////////////////////////////////////////////////////////////////////////////// \brief Get the name of the nth serial port in the computer/////////////////////////////////////////////////////////////////////////////////wxString EnumSerialPort(int n){#ifdef USE_IOKIT	io_iterator_t serialPortIterator;	char deviceFilePath[MAXPATHLEN];		if (!MakeOSXSerialEnumerator(&serialPortIterator))	{		if (!EnumerateOSXSerialPort(serialPortIterator, n, deviceFilePath, sizeof(deviceFilePath)))		{			return wxString(deviceFilePath, *wxConvCurrent);		}		IOObjectRelease(serialPortIterator); // Release the iterator.	}		return wxT("");#else	struct dirent ** sdNameList;	int nNameList;		// get list of files	// can't use wxDir since it doesn't understand virtual filesystems under OSX.	nNameList = scandir("/dev", &sdNameList, NULL, NULL);		if (nNameList > 0)	{		// current entry in list		int iEntry = 0;				// number of viable entries seen		int iCount = 0;				for (iEntry = 0; iEntry < nNameList; iEntry++)		{			int hCom;			bool bFileNameOkay = false;						// ensure the filename looks right#if defined(__DARWIN__)			if (!strncmp(sdNameList[iEntry]->d_name, "cu.", 3))				bFileNameOkay = true;						// Don't list the modem			if (!strcmp(sdNameList[iEntry]->d_name, "cu.modem"))				bFileNameOkay = false;				#else			if (!strncmp(sdNameList[iEntry]->d_name, "ttyS", 4))				bFileNameOkay = true;			if (!strncmp(sdNameList[iEntry]->d_name, "ttyUSB", 6))				bFileNameOkay = true;#endif			if (bFileNameOkay)			{				char szFullFileName[256];								*szFullFileName = 0;								if (strlen(sdNameList[iEntry]->d_name) < 250)				{					sprintf(szFullFileName, "/dev/%s", sdNameList[iEntry]->d_name);										// try to open					hCom = open(szFullFileName, O_RDWR);										if (hCom >= 0)					{						struct termios sPTS;												// can we get its attributes?						if (!tcgetattr(hCom, &sPTS))						{							// looks good then														iCount++;														// is this the one?							if (iCount > n)							{								// yes, store name																int iFreeEntry;								wxString strRtn = wxString(szFullFileName, *wxConvCurrent);																// free the results from scandir								for (iFreeEntry = 0; iFreeEntry < nNameList; iFreeEntry++)									free(sdNameList[iFreeEntry]);								free(sdNameList);								// close the file															close(hCom);								return strRtn;							}						}						close(hCom);					}				}			}		}		// free the results from scandir		int iFreeEntry;		for (iFreeEntry = 0; iFreeEntry < nNameList; iFreeEntry++)			free(sdNameList[iFreeEntry]);		free(sdNameList);	}	return wxT("");#endif}//////////////////////////////////////////////////////////////////////////////////// \brief Initialize serial port (Linux)/////////////////////////////////////////////////////////////////////////////////bool InitSerialIO(){	struct termios sPTS;	wxString strPort;	int sbBaudRate;	int iBaudRate;	LibRoadnavDebug0(wxT("SerialIO"), wxT("Initializing"));	g_pConfig->Read(wxT("GPSSerialPort"), &strPort, wxT(""));	g_pConfig->Read(wxT("GPSBaudRate"), &iBaudRate, 4800);		switch (iBaudRate)	{		case 1200:			sbBaudRate = B1200;			break;		case 2400:			sbBaudRate = B2400;			break;		case 4800:			sbBaudRate = B4800;			break;		case 9600:			sbBaudRate = B9600;			break;		case 19200:			sbBaudRate = B19200;			break;		case 38400:			sbBaudRate = B38400;			break;		default:			iBaudRate = 0;			sbBaudRate = 0;	}	if (strPort == wxT("") || iBaudRate <= 0)	{		LibRoadnavDebug2(wxT("SerialIO"), wxT("Input parameters invalid (%s, %d)"), strPort.c_str(), iBaudRate);		g_strSerialError = wxT("Invalid serial port or baud rate");		g_hCom = -1;		return true;	}	LibRoadnavDebug2(wxT("SerialIO"), wxT("Trying to open %s at %d"), strPort.c_str(), iBaudRate);		g_hCom = open(strPort.mb_str(*wxConvCurrent), O_RDWR);		if (g_hCom < 0)	{		g_strSerialError = wxString(strerror(errno), *wxConvCurrent);		LibRoadnavDebug2(wxT("SerialIO"), wxT("Error opening %s: %s"), strPort.c_str(), g_strSerialError.c_str());		return true;	}			tcgetattr(g_hCom, &sPTS);	cfsetospeed(&sPTS, sbBaudRate);	cfsetispeed(&sPTS, sbBaudRate);	tcsetattr(g_hCom, TCSANOW, &sPTS);		fcntl(g_hCom, F_SETFL, O_NONBLOCK);		return false;}//////////////////////////////////////////////////////////////////////////////////// \brief Read up to nBuffer bytes into szBuffer (Linux).////// Should block if nothing is available, and return as soon as anything is/// available./////////////////////////////////////////////////////////////////////////////////int ReadSerial(char * szBuffer, int nBuffer){	int n;			LibRoadnavDebug1(wxT("SerialIO"), wxT("Trying to read %d bytes"), nBuffer);	if (g_hCom < 0)	{		LibRoadnavDebug0(wxT("SerialIO"), wxT("Invalid handle"));		wxThread::Sleep(1000);		*szBuffer = 0;		return 0;	}		n = read(g_hCom, szBuffer, nBuffer - 1);		LibRoadnavDebug1(wxT("SerialIO"), wxT("Got %d bytes"), n);	if (n < 0)	{		g_strSerialError = wxString(strerror(errno), *wxConvCurrent);		LibRoadnavDebug1(wxT("SerialIO"), wxT("Error reading: %s"), g_strSerialError.c_str());		n = 0;		wxThread::Sleep(100);	}			szBuffer[n] = 0;	return n;}//////////////////////////////////////////////////////////////////////////////////// \brief Clean up serial stuff (Linux)/////////////////////////////////////////////////////////////////////////////////bool ShutdownSerialIO(){	LibRoadnavDebug0(wxT("SerialIO"), wxT("Shutting down"));	if (g_hCom >= 0)	{		close(g_hCom);		g_hCom = -1;	}		return false;}#endif

⌨️ 快捷键说明

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