summaryrefslogtreecommitdiff
path: root/gps+/gps_class.cpp
diff options
context:
space:
mode:
authorwatcherhd <watcherhd@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb>2011-04-21 14:14:52 +0000
committerwatcherhd <watcherhd@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb>2011-04-21 14:14:52 +0000
commitcb4a46e7fbe62d788e66ed6121c717a2d22a4d7c (patch)
tree30df260fdc5a1b5a7049c2f8cac8b7ef17513d6d /gps+/gps_class.cpp
parent19b6f534d2e784a1e120bf52c4aa07004798f473 (diff)
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
Diffstat (limited to 'gps+/gps_class.cpp')
-rw-r--r--gps+/gps_class.cpp337
1 files changed, 337 insertions, 0 deletions
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 <windows.h>
+#include <stdio.h>
+
+#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