|
#include "StdAfx.h"
#include "GPSDevice.h"
CGPSDevice * CGPSDevice::s_pInstance = NULL;
#define MAX_WAIT 5000
#define MAX_AGE 3000
#define GPS_CONTROLLER_EVENT_COUNT 3
CGPSDevice::CGPSDevice(void)
{
m_pSink = NULL;
m_hGPS_Device = NULL;
m_hNewLocationData = NULL;
m_hDeviceStateChange = NULL;
m_hExitThread = NULL;
}
CGPSDevice::~CGPSDevice(void)
{
}
CGPSDevice * CGPSDevice::Instance()
{
if( CGPSDevice::s_pInstance == NULL )
{
s_pInstance = new CGPSDevice();
}
return CGPSDevice::s_pInstance;
}
DWORD WINAPI CGPSDevice::GPSThreadProc(__opt LPVOID lpParameter)
{
DWORD dwRet = 0;
GPS_POSITION gps_Position = {0};
GPS_DEVICE gps_Device = {0};
CGPSDevice * pDevice = (CGPSDevice*) lpParameter;
HANDLE gpsHandles[GPS_CONTROLLER_EVENT_COUNT] =
{ pDevice->m_hNewLocationData,
pDevice->m_hDeviceStateChange,
pDevice->m_hExitThread
};
gps_Position.dwSize = sizeof(gps_Position);
gps_Position.dwVersion = GPS_VERSION_1;
gps_Device.dwVersion = GPS_VERSION_1;
gps_Device.dwSize = sizeof(gps_Device);
do
{
dwRet = WaitForMultipleObjects(
GPS_CONTROLLER_EVENT_COUNT,
gpsHandles, FALSE, INFINITE);
if (dwRet == WAIT_OBJECT_0)
{
dwRet = GPSGetPosition(
pDevice->m_hGPS_Device,
&gps_Position, MAX_AGE, 0);
if (ERROR_SUCCESS != dwRet)
continue;
else
pDevice->m_pSink->SetGPSPosition(gps_Position);
}
else if (dwRet == WAIT_OBJECT_0 + 1)
{
dwRet = GPSGetDeviceState(&gps_Device);
if (ERROR_SUCCESS != dwRet)
continue;
else
pDevice->m_pSink->SetGPSDeviceInfo(gps_Device);
}
else if (dwRet == WAIT_OBJECT_0 + 2)
break;
else
ASSERT(0);
} while( TRUE );
return 0;
}
HRESULT CGPSDevice::StartThread()
{
HRESULT hr = E_FAIL;
DWORD dwRet = 0;
m_hNewLocationData = CreateEvent(NULL, FALSE, FALSE, NULL);
if ( m_hNewLocationData )
{
m_hDeviceStateChange = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hDeviceStateChange)
{
m_hExitThread = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hExitThread)
{
m_hThread = ::CreateThread(NULL, NULL,
GPSThreadProc, this, NULL, &m_dwThreadID);
if ( m_hThread )
hr = S_OK;
}
}
}
if( FAILED(hr) )
{
dwRet = GetLastError();
hr = HRESULT_FROM_WIN32(dwRet);
}
if (FAILED(hr))
{
if (m_hNewLocationData)
{
CloseHandle(m_hNewLocationData);
m_hNewLocationData = NULL;
}
if (m_hDeviceStateChange)
{
CloseHandle(m_hDeviceStateChange);
m_hDeviceStateChange = NULL;
}
if (m_hExitThread)
{
CloseHandle(m_hExitThread);
m_hExitThread = NULL;
}
}
return hr;
}
HRESULT CGPSDevice::StopThread()
{
HRESULT hr = E_FAIL;
DWORD dwRet = 0;
if( SetEvent(m_hExitThread) )
{
dwRet = WaitForSingleObject(m_hThread, MAX_WAIT);
if(WAIT_OBJECT_0 == dwRet)
hr = S_OK;
}
if( FAILED(hr) )
{
dwRet = GetLastError();
hr = HRESULT_FROM_WIN32(dwRet);
}
if (m_hNewLocationData)
{
CloseHandle(m_hNewLocationData);
m_hNewLocationData = NULL;
}
if (m_hDeviceStateChange)
{
CloseHandle(m_hDeviceStateChange);
m_hDeviceStateChange = NULL;
}
if (m_hExitThread)
{
CloseHandle(m_hExitThread);
m_hExitThread = NULL;
}
if (m_hThread)
{
CloseHandle(m_hThread);
m_hThread = NULL;
m_dwThreadID = 0;
}
return hr;
}
HRESULT CGPSDevice::TurnOn(IGPSSink * pSink)
{
if( !pSink )
return E_INVALIDARG;
CGPSDevice * pDevice = Instance();
//We already have a device opened
if( pDevice->m_hGPS_Device )
return E_UNEXPECTED;
if( pDevice->m_pSink != NULL )
return E_UNEXPECTED;
pDevice->m_pSink = pSink;
HRESULT hr = pDevice->StartThread();
if( SUCCEEDED(hr) )
{
pDevice->m_hGPS_Device = GPSOpenDevice(
pDevice->m_hNewLocationData,
pDevice->m_hDeviceStateChange,
NULL, NULL);
if( pDevice->m_hGPS_Device )
hr = S_OK;
else
hr = HRESULT_FROM_WIN32(GetLastError());
}
if( FAILED(hr) )
TurnOff();
return hr;
}
HRESULT CGPSDevice::TurnOff()
{
CGPSDevice * pDevice = Instance();
if( !pDevice->m_hGPS_Device )
return E_UNEXPECTED;
HRESULT hr = pDevice->StopThread();
pDevice->m_pSink = NULL;
DWORD dwRet = GPSCloseDevice(pDevice->m_hGPS_Device);
pDevice->m_hGPS_Device = NULL;
if( SUCCEEDED(hr) )
{
if( ERROR_SUCCESS != dwRet )
hr = HRESULT_FROM_WIN32(GetLastError());
}
return hr;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.