From cb4a46e7fbe62d788e66ed6121c717a2d22a4d7c Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 21 Apr 2011 14:14:52 +0000 Subject: svn.miranda.im is moving to a new home! git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@7 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- gps+/gps_class.cpp | 337 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 gps+/gps_class.cpp (limited to 'gps+/gps_class.cpp') diff --git a/gps+/gps_class.cpp b/gps+/gps_class.cpp new file mode 100644 index 0000000..9ab80a8 --- /dev/null +++ b/gps+/gps_class.cpp @@ -0,0 +1,337 @@ +/* + GPS+: Service plugin for Miranda IM + Copyright 2007-2008 persei + + persei@miranda.im + http://persei.miranda.im + http://svn.miranda.im/mainrepo/gps+ + + Using of code in another IM projects forbidden without author write permission + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include "gps_class.h" + +GPSWorker::GPSWorker() +{ + InitializeCriticalSection(&csInfoAccess); + + EnterCriticalSection(&csInfoAccess); + navInfo = new NavInfo; + gpsInfo = new GPSInfo; + LeaveCriticalSection(&csInfoAccess); + + hPortReader = INVALID_HANDLE_VALUE; + hPort = INVALID_HANDLE_VALUE; +} + +GPSWorker::~GPSWorker() +{ + if(hPortReader != INVALID_HANDLE_VALUE) Disconnect(); + + EnterCriticalSection(&csInfoAccess); + delete navInfo; + delete gpsInfo; + LeaveCriticalSection(&csInfoAccess); + + DeleteCriticalSection(&csInfoAccess); +} + +void GPSWorker::SetPort(int nPortN) +{ + if (nPortN > 0 && nPortN < 255) + { + char PortN[10]; + iPortN = nPortN; + + _ltoa(iPortN, PortN, 10); + strcpy(Port, "\\\\.\\COM"); + strcat(Port, PortN); + } +} + +int GPSWorker::GetPort() +{ + return iPortN; +} + +void GPSWorker::GetPortStr(char * PortStr) +{ + strcpy(PortStr, Port); +} + +void GPSWorker::GetNavInfo(NavInfo* retNavInfo) +{ + EnterCriticalSection(&csInfoAccess); + memcpy(retNavInfo, navInfo, sizeof(NavInfo)); + LeaveCriticalSection(&csInfoAccess); +} + +void GPSWorker::GetGPSInfo(GPSInfo* retGPSInfo) +{ + EnterCriticalSection(&csInfoAccess); + memcpy(retGPSInfo, gpsInfo, sizeof(GPSInfo)); + LeaveCriticalSection(&csInfoAccess); +} + +/* +//Return tokens count +int explode(char* sourceStr, char sep, char** tokens) +{ + int i; + char buf[255]; + buf[0] = 0; + for(i = 0; i < strlen(sourceStr); i++){ + if(sourceStr[i] != sep){ + + } + } +} +*/ + +float GeoCoordToDegrees(float geoCoord) +{ + float minutes = geoCoord - (int)(geoCoord / 100) * 100; + return ((int)(geoCoord / 100)) + (minutes / 60); +} + +int ParseTime(float time) +{ + int hours, minutes; + float seconds; + + hours = (int)(time / 1000); + minutes = (int)(time / 100) - hours * 100; + seconds = time - hours * 1000 - minutes * 100; + + return hours * 60 * 60 * 1000 + minutes * 60 * 1000 + (int)(seconds * 1000); +} + +int CheckCRC(char* infoStr) +{ + int recvCheckSum = 0, calcCheckSum = 0; + char checkStr[255]; + + sscanf(infoStr, "$%[1234567890,.QWERTYUIOPASDFGHJKLZXCVBNM-+]*%x", checkStr, &recvCheckSum); + + for(int i = 0; i < strlen(checkStr); i++) + { + calcCheckSum ^= checkStr[i]; + } + return !(calcCheckSum - recvCheckSum); +} + +void GPSWorker::ParseInfo(char* infoStr) +{ + if(infoStr[0] != '$') + { + WrongMessage++; + return; + } + if(CheckSum){ + if(!CheckCRC(infoStr)) { + return; + } + } + + if(WrongMessage == DisconnectOn){ + Disconnect(); + } + + WrongMessage = 0; + + if(strstr(infoStr, "$GPRMC")){ + float time = 0; + char valid = 0; + float latitude = 0; + char NorthSouth = 0; + float longtitude = 0; + char EastWest = 0; + float sog = 0; + float direction = 0; + int date = 0; + float magneticDeclination = 0; + char magneticEastWest = 0; + int checkSum = 0; + + sscanf(infoStr, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,%f,%d,%f,%c*%x", + &time, + &valid, + &latitude, + &NorthSouth, + &longtitude, + &EastWest, + &sog, + &direction, + &date, + &magneticDeclination, + &magneticEastWest, + &checkSum); + EnterCriticalSection(&csInfoAccess); + + navInfo->Latitude = (NorthSouth == 'N' ? 1 : -1) * GeoCoordToDegrees(latitude); + navInfo->Longtitude = (EastWest == 'E' ? 1 : -1) * GeoCoordToDegrees(longtitude); + navInfo->SOG = sog; + navInfo->Time = ParseTime(time); + navInfo->Direction = direction; + navInfo->MagneticDeclination = (magneticEastWest == 'E' ? 1 : -1) * magneticDeclination; + LeaveCriticalSection(&csInfoAccess); + } + if(strstr(infoStr, "$GPGGA")){ + float time = 0; + float latitude = 0; + char NorthSouth = 0; + float longtitude = 0; + char EastWest = 0; + int quality = 0; + int satCount = 0; + float hdop = 0; + + float altitude = 0; + char altMarker = 0; + float geoDiff = 0; + char geoDiffMarker = 0; + + float diffDataAge = 0; + int stantionId = 0; + int checkSum = 0; + + sscanf(infoStr, "$GPGGA,%f,%f,%c,%f,%c,%d,%d,%f,%f,%c,%f,%c,%d,%d*%x", + &time, + &latitude, + &NorthSouth, + &longtitude, + &EastWest, + &quality, + &satCount, + &hdop, + &altitude, + &altMarker, + &geoDiff, + &geoDiffMarker, + &diffDataAge, + &stantionId, + &checkSum); + + + EnterCriticalSection(&csInfoAccess); + + navInfo->Altitude = altitude; + navInfo->Latitude = (NorthSouth == 'N' ? 1 : -1) * GeoCoordToDegrees(latitude); + navInfo->Longtitude = (EastWest == 'E' ? 1 : -1) * GeoCoordToDegrees(longtitude); + navInfo->Quality = quality; + gpsInfo->SatCount = satCount; + navInfo->GeoDiff = geoDiff; + gpsInfo->HDOP = hdop; + navInfo->Time = ParseTime(time); + + LeaveCriticalSection(&csInfoAccess); + } +} + +DWORD __stdcall GPSWorker::PortReader(GPSWorker* th) +{ + char cBuf[2]; + char infoStr[1024]; + DWORD dwBytesRead; + + while(1){ + ReadFile(th->hPort, &cBuf, 1, &dwBytesRead, NULL); + cBuf[1] = 0; + if(dwBytesRead > 0){ + strcat(infoStr, cBuf); + if(cBuf[0] == '\n'){ + th->ParseInfo(infoStr); + infoStr[0] = 0; + } + } + } +} + +int GPSWorker::Connect() +{ + if(hPortReader != INVALID_HANDLE_VALUE) + return 2; + + WrongMessage = 0; + + hPort = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + + if (hPort == INVALID_HANDLE_VALUE) + return -1; + + else + { + hPortReader = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&GPSWorker::PortReader, + (LPVOID)this, 0, 0); + + DCB dcb; + GetCommState(hPort, &dcb); + dcb.BaudRate = CBR_4800; + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + if (!SetCommState(hPort, &dcb)){ + TerminateThread(hPortReader, 0); + CloseHandle(hPort); + + hPortReader = INVALID_HANDLE_VALUE; + hPort = INVALID_HANDLE_VALUE; + + return -2; + } + } + + return 1; +} + +void GPSWorker::Disconnect() +{ + if(hPortReader != INVALID_HANDLE_VALUE){ + EnterCriticalSection(&csInfoAccess); + TerminateThread(hPortReader, 0); + CloseHandle(hPort); + LeaveCriticalSection(&csInfoAccess); + + hPortReader = INVALID_HANDLE_VALUE; + hPort = INVALID_HANDLE_VALUE; + } +} + +int GPSWorker::ReConnect() +{ + Disconnect(); + return Connect(); +} + +int GPSWorker::IsConnected() +{ + return hPortReader != INVALID_HANDLE_VALUE; +} + +void GPSWorker::SetAutoDisconnect(int newDisconnOn) +{ + DisconnectOn = newDisconnOn; +} + +void GPSWorker::SetCheckSum(int newCheck) +{ + CheckSum = newCheck; +} \ No newline at end of file -- cgit v1.2.3