Dati da dispositivi con orologi non affidabili

2

Esistono approcci fattibili per gestire i dati provenienti da dispositivi con orologi inaffidabili?

Abbiamo un sistema di database in esecuzione su un server centrale. L'ultima aggiunta al sistema è un sacco di scanner di codici a barre mobili con Android. Stiamo creando un'app specifica e i dispositivi saranno completamente bloccati in modo che l'utente possa interagire solo con questa app (quindi non accedere a nessuna impostazione).

Nel complesso è molto semplice, i dispositivi si connetteranno utilizzando una dock Ethernet e scaricheranno un elenco di elementi da spostare insieme alle loro destinazioni. L'utente esegue la scansione degli articoli nella destinazione e raccoglie una firma per la consegna. Una volta connesso al dock, verrà aggiornata la posizione di tutti gli elementi consegnati, insieme alla firma e al timestamp della mossa.

Il piano era che l'app avrebbe impostato l'orologio del dispositivo dall'ora del server ogni volta che era collegato al dock. Purtroppo, Android non consente alle app di impostare l'ora (l'autorizzazione SET_TIME è consentita solo per le app di sistema). Inoltre, la rete è incredibilmente bloccata, quindi non possiamo fare affidamento sulla sincronizzazione integrata, e i dispositivi hanno solo una connessione di rete quando sono ancorati nella base Ethernet in ogni caso.

Quindi, dato che i dispositivi potrebbero avere orologi arbitrariamente non corretti, c'è un modo in cui possiamo correggerli quando i dati vengono caricati? Sarebbe possibile tenere un registro sul server dell'orologio per ogni dispositivo ogni volta che viene connesso.

In molti modi questo problema potrebbe essere applicato a qualsiasi applicazione con funzionalità offline. Che cosa fai con i dati relativi al tempo da un dispositivo con un orologio inaffidabile o non affidabile?

Non è troppo difficile correggere un tempo costantemente non corretto, ma sembra del tutto impossibile se si considera che il dispositivo potrebbe perdere completamente il tempo se la batteria si scarica. Un problema simile si presenta per un dispositivo non affidabile - se l'utente può cambiare l'orologio arbitrariamente.

Sono state effettuate ricerche su questo problema?

    
posta SystemParadox 26.06.2016 - 22:01
fonte

3 risposte

9

In realtà c'è un bel po 'che puoi fare per recuperare qualcosa vicino al tempo reale della maggior parte dei tuoi eventi.

Android offre alcuni strumenti utili su cui lavorare, in particolare gli intenti trasmessi quando il dispositivo completa un avvio, quando l'orologio del sistema cambia e quando è imminente uno spegnimento. Ti dà anche un modo per controllare la quantità di tempo reale che è trascorso dall'avvio (che ottieni chiamando elapsedRealtime() o elapsedRealtimeNanos() ). Questo è un valore che il sistema garantisce aumenterà monotonicamente. Il trucco consiste nel fare affidamento il più possibile su questo e il meno possibile sull'orologio di sistema, ma registrare entrambi con ogni evento.

Probabilmente questo è meglio spiegato con l'esempio, quindi supponiamo che la tua applicazione registri questi eventi (i numeri sono veri secondi dall'avvio):

018 Boot #1
200 Scan #1
215 Sync #1; server says it's 03:15:22
247 Scan #2
335 Scan #3
430 Halt #1

Durante la sincronizzazione a 215, è abbastanza facile capire che la scansione 1 è avvenuta 15 secondi prima dell'orario previsto, presumibilmente affidabile di 03:15:22.

Passa un certo periodo di tempo sconosciuto e il dispositivo registra più eventi prima della prossima sincronizzazione:

020 Boot #2
432 Scan #4
606 Scan #5
901 Halt #2

(Another unknown amount of time passes)

016 Boot #3
117 Scan #6
208 Sync #2; Server says it's really 23:05:46

Se ti sei fermato al momento in cui il server ti ha dato a 215, poi quando torni per sincronizzare due stivali in un secondo momento, puoi lavorare in avanti dalla sincronizzazione n. 1 e scoprire che le scansioni 2 e 3 sono avvenute 32 e 120 secondi dopo 03 : 15: 22. (Tuttavia, non è possibile trarre conclusioni sugli eventi accaduti dopo l'interruzione 1.) La scansione 6 viene eseguita allo stesso modo della scansione 1; è successo 91 secondi prima della sincronizzazione 2

Questo lascia le scansioni 4 e 5, che sono un problema perché non c'era un riferimento temporale affidabile durante quel ciclo di avvio / arresto da utilizzare per trasformare i numeri di avvio dall'ora in data e ora assolute. Qui è dove devi passare all'orologio di sistema.

Se stai registrando l'ora del sistema con i tuoi eventi, puoi utilizzare un timestamp che ritieni affidabile per raggiungere in avanti o indietro un intervallo di avvio / arresto senza guardare la differenza di clock di sistema tra le soste e gli stivali.

Se l'orologio di sistema all'avvio è maggiore di quello registrato all'arresto precedente (o all'installazione / aggiornamento dell'app, un evento dovresti registrare anche tu), le probabilità sono in realtà piuttosto buone che sia giusto. Salvo manomissioni fisiche, avvio di altri carichi del sistema operativo, ecc., La modifica dell'orologio mentre il dispositivo è inattivo è difficile. Poiché la maggior parte dei dispositivi Android si spegne molto prima che la batteria sia completamente scarica, di solito c'è abbastanza succo per mantenere l'orologio in funzione per parecchio tempo. (Durante la scrittura di questo, ho avviato un dispositivo che non aveva abbastanza batteria per l'avvio senza alimentazione esterna.Non era stato acceso in almeno tre mesi, e senza accesso a reti mobili o WiFi, l'orologio era solo un pochi minuti fuori dal tempo reale.)

Se l'orologio mostra un tempo all'avvio prima dell'ultimo evento registrato, non c'è modo di recuperare in modo affidabile i tempi per le scansioni avvenute durante l'intervallo di avvio / arresto. Quello che fai con queste scansioni è una decisione politica.

    
risposta data 27.06.2016 - 00:56
fonte
1

Un modo semplice (ma approssimativo) di avvicinarsi a questo è registrare l'offset di ogni dispositivo ogni volta che si sincronizza.

Quando inserisci i dati nel tuo database master, utilizza il valore di offset più recente per il dispositivo per regolare il tempo registrato.

Senza un orologio di riferimento affidabile sul dispositivo, non è nemmeno possibile garantire che due azioni registrate dallo stesso dispositivo avvengano in un ordine specifico usando solo un valore di clock.

    
risposta data 27.06.2016 - 00:15
fonte
1

Alla fine, se non ti fraintendessi, hai la seguente situazione:

  • Il dispositivo Android ha un orologio impostato su un orario potenzialmente casuale / errato.
  • Non ci sono altre connessioni di rete quando le distribuisci nel dock (probabilmente durante la notte o al mattino).

Pertanto, presumo che l'unico valore sconosciuto sia l'offset temporale tra l'orologio del dispositivo locale e l'ora effettiva.

Proverò a utilizzare l'offset tra tempo effettivo e tempo del dispositivo per determinare i timestamp reali, essenzialmente il suggerimento di Harry:

  • Quindi ogni volta che si collega il dispositivo, può richiedere l'ora corrente attuale.

    Diciamo che sono le 6:30.

  • In quel momento l'orologio interno del dispositivo è impostato su 8:00.

  • Questo ora ci consente di determinare l'offset tra le due volte, in questo caso sarebbe +1: 30.

  • Quindi, se un cliente riceve il suo pacco alle 10:10 (ora del dispositivo), è possibile utilizzare l'offset determinato in precedenza per sapere che il pacco è effettivamente arrivato alle 8:40 del mattino (1:30 "prima").

  • Naturalmente è compito dell'implementazione se archiviare le ore nell'orario del dispositivo o in tempo reale.

  • Si noti che ignoriamo completamente la data. Dovresti considerare anche questo, se alcuni di questi viaggi impiegano più di 24 ore.

Tuttavia, Android dovrebbe essere in grado di sincronizzare l'ora del sistema utilizzando un server orario NTP. Anche se l'utente non può aprire l'app dell'orologio, questa dovrebbe essere sincronizzata in background ogni volta che c'è una connessione di rete. In quanto tale, l'intero problema potrebbe effettivamente essere un non-problema.

    
risposta data 27.06.2016 - 10:43
fonte

Leggi altre domande sui tag