summaryrefslogtreecommitdiffstats
path: root/movement
diff options
context:
space:
mode:
authorWesley Ellis <tahnok@gmail.com>2021-11-23 21:32:43 -0500
committerWesley Ellis <tahnok@gmail.com>2021-11-23 21:40:27 -0500
commit121e6fd165a03f9249100e73bdf658e545e10d25 (patch)
treec2d25a75058b88dbf6777180c2f0c5e5b9a001f1 /movement
parent653dd862b8bb6f40a55295e6fc9325b052d30b3d (diff)
downloadSensor-Watch-121e6fd165a03f9249100e73bdf658e545e10d25.tar.gz
Sensor-Watch-121e6fd165a03f9249100e73bdf658e545e10d25.tar.bz2
Sensor-Watch-121e6fd165a03f9249100e73bdf658e545e10d25.zip
optimize totp face and add countdown
Diffstat (limited to 'movement')
-rw-r--r--movement/watch_faces/complications/totp_face.c110
-rw-r--r--movement/watch_faces/complications/totp_face.h9
2 files changed, 35 insertions, 84 deletions
diff --git a/movement/watch_faces/complications/totp_face.c b/movement/watch_faces/complications/totp_face.c
index 2e8b5f66..017a774b 100644
--- a/movement/watch_faces/complications/totp_face.c
+++ b/movement/watch_faces/complications/totp_face.c
@@ -1,114 +1,58 @@
/**
- *
* TODO:
- * - this ONLY works if watch is set to UTC, probably worth including a TZ offset setting since it can be used by beats as well
- * - show how long code is valid for in upper right corner of LCD
- * - optimize code so that we don't calculating a new unix timestamp every second AND a new TOTP code
+ * - Add support for UTC offset in settings?
* - Support for multiple codes
*/
#include <stdlib.h>
#include <string.h>
#include "totp_face.h"
#include "watch.h"
+#include "watch_utility.h"
#include "TOTP.h"
// test key: JBSWY3DPEHPK3PXP
// Use https://cryptii.com/pipes/base32-to-hex to convert base32 to hex
// Use https://totp.danhersam.com/ to generate test codes for verification
-uint8_t hmacKey[] = {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef}; // Secret key
+static uint8_t hmacKey[] = {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef}; // Secret key
+
+
+static const uint8_t UTC_OFFSET = 5; // set to your current UTC offset
+static const uint32_t TIMESTEP = 30;
void totp_face_setup(movement_settings_t *settings, void ** context_ptr) {
(void) settings;
- (void) context_ptr;
- TOTP(hmacKey, sizeof(hmacKey), 30);
+ if (*context_ptr == NULL) *context_ptr = malloc(sizeof(totp_state_t));
+ TOTP(hmacKey, sizeof(hmacKey), TIMESTEP);
}
void totp_face_activate(movement_settings_t *settings, void *context) {
(void) settings;
- (void) context;
-}
-
-/**
- * @brief Get unix timestamp from component parts
- *
- * @param year
- * @param month
- * @param day
- * @param hour
- * @param minute
- * @param second
- * @return uint32_t
- *
- * Based on code by Josh Haberman for upb
- * from https://blog.reverberate.org/2020/05/12/optimizing-date-algorithms.html
- *
- * Essentially we need to calculate how many days have occured since year 0
- * including leap years! The following code does some clever calculations
- * of the number of february's then offsets based on how many leap years
- * there have been
- *
- * Once we have the number of days in the year, it's easy enough to add how
- * many days have happened in the current year, then convert that to seconds
- */
-uint32_t current_unix_time(uint32_t year, uint32_t month, uint32_t day,
- uint32_t hour, uint32_t minute, uint32_t second) {
- uint16_t DAYS_SO_FAR[] = {
- 0, // Jan
- 31, // Feb
- 59, // March
- 90, // April
- 120, // May
- 151, // June
- 181, // July
- 212, // August
- 243, // September
- 273, // October
- 304, // November
- 334 // December
- };
-
-
- uint32_t year_adj = year + 4800;
- uint32_t febs = year_adj - (month <= 2 ? 1 : 0); /* Februaries since base. */
- uint32_t leap_days = 1 + (febs / 4) - (febs / 100) + (febs / 400);
- uint32_t days = 365 * year_adj + leap_days + DAYS_SO_FAR[month - 1] + day - 1;
- days -= 2472692; /* Adjust to Unix epoch. */
-
- uint32_t timestamp = days * 86400;
- timestamp += hour * 3600;
- timestamp += minute * 60;
- timestamp += second;
-
- return timestamp;
-}
-
-uint32_t current_unix_time_from_rtc() {
- watch_date_time date_time = watch_rtc_get_date_time();
- return current_unix_time(
- date_time.unit.year + 2020, // year is stored starting in 2020
- date_time.unit.month,
- date_time.unit.day,
- date_time.unit.hour,
- date_time.unit.minute,
- date_time.unit.second
- );
+ memset(context, 0, sizeof(totp_state_t));
+ totp_state_t *totp_state = (totp_state_t *)context;
+ totp_state->timestamp = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), UTC_OFFSET);
+ totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp);
}
bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
(void) settings;
- (void) context;
+ totp_state_t *totp_state = (totp_state_t *)context;
char buf[14];
- watch_date_time date_time = watch_rtc_get_date_time();
+ uint8_t valid_for;
+ div_t result;
- uint32_t ts;
- uint32_t code;
switch (event.event_type) {
- case EVENT_ACTIVATE:
case EVENT_TICK:
- ts = current_unix_time_from_rtc();
- code = getCodeFromTimestamp(ts);
- sprintf(buf, "2f %lu", code);
+ totp_state->timestamp++;
+ // fall through
+ case EVENT_ACTIVATE:
+ result = div(totp_state->timestamp, TIMESTEP);
+ if (result.quot != totp_state->steps) {
+ totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp);
+ totp_state->steps = result.quot;
+ }
+ valid_for = TIMESTEP - result.rem;
+ sprintf(buf, "2f%2d%lu", valid_for, totp_state->current_code);
watch_display_string(buf, 0);
break;
@@ -134,4 +78,4 @@ bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void
void totp_face_resign(movement_settings_t *settings, void *context) {
(void) settings;
(void) context;
-} \ No newline at end of file
+}
diff --git a/movement/watch_faces/complications/totp_face.h b/movement/watch_faces/complications/totp_face.h
index 1fecb82a..0527627a 100644
--- a/movement/watch_faces/complications/totp_face.h
+++ b/movement/watch_faces/complications/totp_face.h
@@ -3,6 +3,13 @@
#include "movement.h"
+typedef struct {
+ uint32_t timestamp;
+ uint8_t steps;
+ uint32_t current_code;
+
+} totp_state_t;
+
void totp_face_setup(movement_settings_t *settings, void ** context_ptr);
void totp_face_activate(movement_settings_t *settings, void *context);
bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
@@ -16,4 +23,4 @@ static const watch_face_t totp_face = {
NULL
};
-#endif // TOTP_FACE_H_ \ No newline at end of file
+#endif // TOTP_FACE_H_