L'applicazione prevede differenti modalità di funzionamento, ognuna delle quali garantisce un diverso livello di privacy.
Nella modalità di funzionamento ***A*** ogni qual volta si verifica un contatto l'applicazione si occupa di notificare immediatamente l'evento al server in modo tale che esso possa essere aggiunto al database remoto.
Questa modalità è quella meno *privacy friendly* in quanto la comunicazione avviene in *real-time* e all'interno del messaggio scambiato viene riportato sia l'UUID dell'utente sia quello della persona incontrata.
La modalità ***B*** prevede lo scambio delle stesse informazioni previste per la modalità precedente, ma solo se richiesto dalle autorità sanitarie.
In questo modo non solo si evita che i dati siano catturati dal server in *real-time*, ma si espongono le informazioni dell'utente solo quando queste sono strettamente necessarie.
Sia in questa modalità, che nella precedente si è scelto di non ruotare gli UUID identificativi degli utenti in modo da facilitare la generazione del grafo sul server.
Questa soluzione può mettere a repentaglio la privacy degli utenti ed essere sfruttata da *avversari* per ottenere informazioni sulle abitudini degli utilizzatori[^catena-negozi].
[^catena-negozi]: Per esempio una catena di negozi attraverso l'impiego di uno scanner bluetooth potrebbe ricostruire la *fedeltà* degli utenti, conoscere i settori del negozio preferiti ecc.
L'ultima modalità, la ***C***, è quella che tutela maggiormente la privacy degli utilizzatori attraverso due accorgimenti:
La generazione degli UUID avviene attraverso una derivazione deterministica come visto nella @sec:tcn-protocol, in modo tale da avere lo stesso livello di privacy di una soluzione randomica, ma con una migliore scalabilità.
Mentre il matching locale permette di condividere il minor numero di informazioni possibili e solo quando questo è strettamente necessario.
Infatti in questa modalità l'applicazione carica le informazioni sul server solo in seguito alla richiesta delle autorità sanitarie.
Inoltre a differenza delle prime due modalità è previsto l'upload unicamente degli UUID che il dispositivo ha assunto nel tempo, in questo modo il server non è in grado di conoscere o ricavare i contatti avuti dall'utente.
L'interazione tra l'hardware bluetooth del dispositivo e l'applicazione è stata gestita attraverso l'impiego della libreria *Android Beacon Library*@AndroidBeaconLibrary che permette di gestire più facilmente le operazioni con beacon bluetooth.
Inoltre per rendere l'applicazione più funzionale, e quindi garantirne il funzionamento anche in background o a schermo spento è stato utilizzato un *foreground service*@ServicesOverview, che consente di mantenere in *primo piano* le operazioni di trasmissione e scansione anche quando l'applicazione non lo è.
Data la natura variegata di Android, le diverse implementazioni del sistema operativo adoperate dai vari produttori non si comportano sempre nello stesso modo, motivo per il quale alcuni dispositivi tenderanno a terminare, o mettere in pausa ugualmente l'applicazione[^dont-kill-my-app].
Potendo opera unicamente nello spazio utente non è stato possibile superare questi limiti.
[^dont-kill-my-app]: Molti produttori Android per aumentare la durata della batteria dei propri dispositivi tendono a stoppare e ridurre le funzionalità delle applicazioni. Maggiori dettagli possono essere trovati al seguente link \url{https://dontkillmyapp.com}.
Tutte le funzionalità legate al bluetooth sono state *incapsulate* all'interno della classe `BluetoothManager`.
L'interfaccia di questa classe espone due metodi, `startService()` e `stopService()` che consentono di avviare e stoppare sia la scansione che la trasmissione del beacon.
Poiché queste operazioni vanno ad interagire con le funzionalità del sistema operativo, l'istanza di questa classe deve essere collegata ad un oggetto di tipo `Context`.
Si è scelto di collegare l'oggetto `BluetoothManager` all'*application* e non ad una `Activity` in quanto i servizi devono essere utilizzati anche quando non sono presenti *activity* in *foreground*.
Per questo motivo è stata sviluppata anche una classe `BluetoothApplication` che va ad estendere le funzionalità di `Application` e fornisce a sua volta due metodi di start e stop che vanno a richiamare quelli esposti da `BluetoothManager` in modo tale da rendere possibile il controllo dei servizi legati al bluetooth anche da altre componenti dell'applicazione.
Infatti la libreria permette di trasmettere un beacon con una frequenza di 1 *Hz*, 3 *Hz* o 10 *Hz*.
Fortunatamente questi vincoli non si sono rilevati troppo limitanti infatti la frequenza di un Hertz, quindi un beacon trasmetto ogni secondo, permette di avere una buona trasmissione e di risparmiare batteria.
Inoltre in fase di scanning evita che siano registrate più interazioni nello stesso ciclo.
Sempre attraverso l'API di Android è stata settata la potenza di trasmissione del beacon.
Anche in questo caso la scelta era limitata a poche alternative:
- HIGH
- MEDIUM
- LOW
- ULTRA_LOW
Com'è possibile dedurre anche dai nomi dei vari livelli, l'API non fornisce nessuna stima quantitativa[^dispositivi-non-omogenei], ma solo delle indicazioni qualitative delle intensità del segnale trasmesso.
L'individuazione del livello più adatto è stata svolta per via sperimentale utilizzando cinque dispositivi differenti.
I due livelli più alti sono stati immediatamente scartati in quanto permettevano di rilevare i beacon a distanze elevate cosa che avrebbe minato la bontà dell'applicazione.
Con il livello ULTRA_LOW si è notato che venivano rilevate unicamente le interazioni inferiori al metro in contesti *free space*.
Poiché l'organizzazione mondiale della sanità raccomanda una distanza di almeno un metro @AdvicePublicCOVID19 questo livello di trasmissione non consente di rilevare contatti potenzialmente a rischio.
Per questo motivo si è scelto di utilizzare il livello LOW che permette di rilevare contatti fino a circa due metri.
[^dispositivi-non-omogenei]: D'altronde, data la natura non omogenea dei vari dispositivi Android, una stima quantitativa sarebbe stata impossibile da ottenere.
In particolare è stato possibile settare sia l'intervallo temporale che deve intercorrere tra una scansione e la successiva, sia la durata della singola scansione.
Si è scelto di far trascorrere un minuto tra una scansione e la prossima e di avere una scansione della durata di un secondo.
Per quanto detto già in precedenza in base ai vari dispositivi e alle varie condizioni di funzionamento l'intervallo tra una scansione e la successiva potrebbe essere più ampio rispetto a quello stabilito.
Quando l'applicazione rivela un beacon nelle vicinanze esso viene trasmesso ad un'ulteriore componente applicativa tramite l'impiego del `LocalBroadcastManager`@BroadcastsOverview.
Questa componente non consuma direttamente il beacon, ma ha il compito di smistarlo ad ulteriori componenti in base alla modalità di funzionamento dell'applicazione.
Il codice necessario a smistare i dati di contatto è stato riportato nel @lst:contact-receiver.
Come si può notare nella linea 2, la prima operazione consiste nel recupero dei dati di contatto dall'`Intent`, mentre dalla linea 7 si seleziona la funzione da invocare in base alla modalità di funzionamento.
Mentre nel caso delle modalità *B* e *C* il beacon viene consumato dalla classe `StoreReceiver` la quale si occupa della memorizzazione permanente del contatto all'interno di un database locale.
In base all'intensità dell segnale (***rssi***) misurato dal dispositivo ricevente è possibile ottenere una stima della distanza che intercorre tra chi invia il beacon e chi lo riceve attraverso l'@eq:distanza.
Per poter calcolare la distanza è necessario conoscere anche il valore di $n$ e $TxPower$.
$n$ è una costante che generalmente assume valori compresi tra uno e quattro e ci permette di modellare i diversi ambienti in cui si può operare.
$TxPower$ è la potenza di trasmissione nominale che si misurerebbe alla distanza di un metro dalla sorgente del segnale.
Il valore di $TxPower$ deve essere precedentemente ricavato per ogni emettitore e deve essere inviato all'interno del beacon bluetooth.
Lavorando con dispositivi eterogenei tra di loro non è stato possibile calcolare in modo esatto questo valore ma si è scelto di utilizzare un valore che mediamente si adattasse a tutti i dispositivi utilizzati in fase di test.