From 67907e4e5c2b3347a37e9488549216f71e1a57b2 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 20 Feb 2024 23:10:13 -0300 Subject: faces/totp: define TOTP data structure Aggregates all the data necessary for TOTP generation. --- movement/watch_faces/complication/totp_face.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index 242820d7..d634baa3 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -29,6 +29,14 @@ #include "watch_utility.h" #include "TOTP.h" +typedef struct { + unsigned char labels[2]; + hmac_alg algorithm; + uint32_t period; + size_t key_length; + uint8_t *key; +} totp_t; + //////////////////////////////////////////////////////////////////////////////// // Enter your TOTP key data below static const uint8_t num_keys = 2; -- cgit v1.2.3 From 8a7d9326cf274003a6e92c9ca800173ec7292fec Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 20 Feb 2024 23:12:53 -0300 Subject: faces/totp: define TOTP struct initializer macro Generates a compound initializer for the given TOTP parameters. Lessens repetition and allows functional definitions of TOTP records. --- movement/watch_faces/complication/totp_face.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index d634baa3..89619208 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -37,6 +37,15 @@ typedef struct { uint8_t *key; } totp_t; +#define TOTP_INITIALIZER(label_1, label_2, key_array, algo, timestep) \ + (const totp_t) { \ + .key = (key_array), \ + .key_length = sizeof(key_array), \ + .period = (timestep), \ + .labels = { (label_1), (label_2) }, \ + .algorithm = (algo), \ + } + //////////////////////////////////////////////////////////////////////////////// // Enter your TOTP key data below static const uint8_t num_keys = 2; -- cgit v1.2.3 From a99f6a716f73957c19070ec091a61f1ab8a01042 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 20 Feb 2024 23:15:15 -0300 Subject: faces/totp: update example data to new structure The data definitions are much shorter and easier to read now. --- movement/watch_faces/complication/totp_face.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index 89619208..dcdc957d 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -48,27 +48,20 @@ typedef struct { //////////////////////////////////////////////////////////////////////////////// // Enter your TOTP key data below -static const uint8_t num_keys = 2; -static uint8_t keys[] = { + +static uint8_t key_1[] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef, // 1 - JBSWY3DPEHPK3PXP - 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef, // 2 - JBSWY3DPEHPK3PXP -}; -static const uint8_t key_sizes[] = { - 10, - 10, -}; -static const uint32_t timesteps[] = { - 30, - 30, }; -static const char labels[][2] = { - { '2', 'F' }, - { 'A', 'C' }, + +static uint8_t key_2[] = { + 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef, // 2 - JBSWY3DPEHPK3PXP }; -static const hmac_alg algorithms[] = { - SHA1, - SHA1, + +static totp_t totp_data[] = { + TOTP_INITIALIZER('2', 'F', key_1, SHA1, 30), + TOTP_INITIALIZER('A', 'C', key_2, SHA1, 30), }; + // END OF KEY DATA. //////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 48e7fb1a7cd7e78c5ad2d8b3819425a05fa0c641 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 20 Feb 2024 23:16:41 -0300 Subject: faces/totp: define TOTP data array size function Computes the size of the array of TOTP records. The compiler will likely evaluate it at compile time. --- movement/watch_faces/complication/totp_face.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index dcdc957d..4ab77c37 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -65,6 +65,10 @@ static totp_t totp_data[] = { // END OF KEY DATA. //////////////////////////////////////////////////////////////////////////////// +static inline size_t _totp_num(void) { + return sizeof(totp_data) / sizeof(*totp_data); +} + static void _update_display(totp_state_t *totp_state) { char buf[14]; div_t result; -- cgit v1.2.3 From bbb920a5d81f04e55dac3dbc2b9034fde22c7e4c Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 20 Feb 2024 23:18:00 -0300 Subject: faces/totp: define current TOTP data function Selects the appropriate TOTP data structure given the TOTP watch face state. --- movement/watch_faces/complication/totp_face.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index 4ab77c37..8af5fbc4 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -65,6 +65,10 @@ static totp_t totp_data[] = { // END OF KEY DATA. //////////////////////////////////////////////////////////////////////////////// +static inline totp_t *_totp_current(totp_state_t *totp_state) { + return &totp_data[totp_state->current_index]; +} + static inline size_t _totp_num(void) { return sizeof(totp_data) / sizeof(*totp_data); } -- cgit v1.2.3 From 79cfe315ffd27e45bc54571e03c8d622745e6df3 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 20 Feb 2024 23:20:21 -0300 Subject: faces/totp: update watch face logic for new struct Using the new structured TOTP record data structure allows the TOTP watch face to statically and implicitly compute the total number of defined TOTP records. Users can now simply add new keys and records in the designated area and the watch face will compile and automatically use them with no need to maintain a separate array size variable. Less chance of mistakes. --- movement/watch_faces/complication/totp_face.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index 8af5fbc4..e7e90281 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -77,14 +77,15 @@ static void _update_display(totp_state_t *totp_state) { char buf[14]; div_t result; uint8_t valid_for; + totp_t *totp = _totp_current(totp_state); - result = div(totp_state->timestamp, timesteps[totp_state->current_index]); + result = div(totp_state->timestamp, totp->period); if (result.quot != totp_state->steps) { totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp); totp_state->steps = result.quot; } - valid_for = timesteps[totp_state->current_index] - result.rem; - sprintf(buf, "%c%c%2d%06lu", labels[totp_state->current_index][0], labels[totp_state->current_index][1], valid_for, totp_state->current_code); + valid_for = totp->period - result.rem; + sprintf(buf, "%c%c%2d%06lu", totp->labels[0], totp->labels[1], valid_for, totp_state->current_code); watch_display_string(buf, 0); } @@ -99,7 +100,8 @@ void totp_face_activate(movement_settings_t *settings, void *context) { (void) settings; memset(context, 0, sizeof(totp_state_t)); totp_state_t *totp_state = (totp_state_t *)context; - TOTP(keys, key_sizes[0], timesteps[0], algorithms[0]); + totp_t *totp = _totp_current(totp_state); + TOTP(totp->key, totp->key_length, totp->period, totp->algorithm); totp_state->timestamp = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60); totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp); } @@ -119,15 +121,14 @@ bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void movement_move_to_face(0); break; case EVENT_ALARM_BUTTON_UP: - if (totp_state->current_index + 1 < num_keys) { - totp_state->current_key_offset += key_sizes[totp_state->current_index]; + if (totp_state->current_index + 1 < _totp_num()) { totp_state->current_index++; } else { // wrap around to first key - totp_state->current_key_offset = 0; totp_state->current_index = 0; } - TOTP(keys + totp_state->current_key_offset, key_sizes[totp_state->current_index], timesteps[totp_state->current_index], algorithms[totp_state->current_index]); + totp_t *totp = _totp_current(totp_state); + TOTP(totp->key, totp->key_length, totp->period, totp->algorithm); _update_display(totp_state); break; case EVENT_ALARM_BUTTON_DOWN: -- cgit v1.2.3 From 0ebd94c4e17bddb4220c4772168ac1d87cbd9523 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 20 Feb 2024 23:24:01 -0300 Subject: faces/totp: delete unused structure field The TOTP watch face now keeps track of each key separately. There is no need to compute offsets at runtime. --- movement/watch_faces/complication/totp_face.h | 1 - 1 file changed, 1 deletion(-) diff --git a/movement/watch_faces/complication/totp_face.h b/movement/watch_faces/complication/totp_face.h index 1248f716..e103b824 100644 --- a/movement/watch_faces/complication/totp_face.h +++ b/movement/watch_faces/complication/totp_face.h @@ -60,7 +60,6 @@ typedef struct { uint8_t steps; uint32_t current_code; uint8_t current_index; - uint8_t current_key_offset; } totp_state_t; void totp_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); -- cgit v1.2.3 From 1c0050c97b510224f35be9fe502397c387e59061 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 21 Feb 2024 01:52:31 -0300 Subject: faces/totp: update copyright and license data Update the copyrights to include full name attribution to all who contributed to this watch face, including myself. Also add an SPDX license identifier header comment to the files. https://spdx.org/licenses/MIT.html --- movement/watch_faces/complication/totp_face.c | 10 +++++++++- movement/watch_faces/complication/totp_face.h | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index e7e90281..97c1ffeb 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -1,7 +1,15 @@ +/* SPDX-License-Identifier: MIT */ + /* * MIT License * - * Copyright (c) 2022 Wesley Ellis (https://github.com/tahnok) + * Copyright © 2021 Wesley Ellis (https://github.com/tahnok) + * Copyright © 2021-2023 Joey Castillo + * Copyright © 2022 Jack Bond-Preston + * Copyright © 2023 Alex Utter + * Copyright © 2023 Emilien Court + * Copyright © 2023 Jeremy O'Brien + * Copyright © 2024 Matheus Afonso Martins Moreira (https://www.matheusmoreira.com/) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/movement/watch_faces/complication/totp_face.h b/movement/watch_faces/complication/totp_face.h index e103b824..9332435c 100644 --- a/movement/watch_faces/complication/totp_face.h +++ b/movement/watch_faces/complication/totp_face.h @@ -1,7 +1,14 @@ +/* SPDX-License-Identifier: MIT */ + /* * MIT License * - * Copyright (c) 2022 Wesley Ellis (https://github.com/tahnok) + * Copyright © 2021 Wesley Ellis (https://github.com/tahnok) + * Copyright © 2021-2022 Joey Castillo + * Copyright © 2022 Alexsander Akers + * Copyright © 2022 Jack Bond-Preston + * Copyright © 2023 Alex Utter + * Copyright © 2024 Matheus Afonso Martins Moreira (https://www.matheusmoreira.com/) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal -- cgit v1.2.3 From d70511515e986427ab4c73e14458de01e24aa3b8 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 25 Feb 2024 22:23:38 -0300 Subject: faces/totp: decode secrets when setting up This allows the user to easily copy the base32 encoded secrets into the TOTP record initializers. They will be decoded once at runtime when the face is being set up by the movement framework. Also rename the array of TOTP records to credentials. Much better. --- movement/watch_faces/complication/totp_face.c | 51 +++++++++++++++++---------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index 97c1ffeb..83126a1a 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -36,19 +36,20 @@ #include "watch.h" #include "watch_utility.h" #include "TOTP.h" +#include "base32.h" typedef struct { unsigned char labels[2]; hmac_alg algorithm; uint32_t period; size_t key_length; - uint8_t *key; + unsigned char *key; } totp_t; #define TOTP_INITIALIZER(label_1, label_2, key_array, algo, timestep) \ (const totp_t) { \ - .key = (key_array), \ - .key_length = sizeof(key_array), \ + .key = ((unsigned char *) key_array), \ + .key_length = sizeof(key_array) - 1, \ .period = (timestep), \ .labels = { (label_1), (label_2) }, \ .algorithm = (algo), \ @@ -57,28 +58,20 @@ typedef struct { //////////////////////////////////////////////////////////////////////////////// // Enter your TOTP key data below -static uint8_t key_1[] = { - 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef, // 1 - JBSWY3DPEHPK3PXP -}; - -static uint8_t key_2[] = { - 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef, // 2 - JBSWY3DPEHPK3PXP -}; - -static totp_t totp_data[] = { - TOTP_INITIALIZER('2', 'F', key_1, SHA1, 30), - TOTP_INITIALIZER('A', 'C', key_2, SHA1, 30), +static totp_t credentials[] = { + TOTP_INITIALIZER('2', 'F', "JBSWY3DPEHPK3PXP", SHA1, 30), + TOTP_INITIALIZER('A', 'C', "JBSWY3DPEHPK3PXP", SHA1, 30), }; // END OF KEY DATA. //////////////////////////////////////////////////////////////////////////////// static inline totp_t *_totp_current(totp_state_t *totp_state) { - return &totp_data[totp_state->current_index]; + return &credentials[totp_state->current_index]; } -static inline size_t _totp_num(void) { - return sizeof(totp_data) / sizeof(*totp_data); +static inline size_t totp_total(void) { + return sizeof(credentials) / sizeof(*credentials); } static void _update_display(totp_state_t *totp_state) { @@ -98,10 +91,30 @@ static void _update_display(totp_state_t *totp_state) { watch_display_string(buf, 0); } +static void totp_face_decode_secrets(void) { + for (size_t n = totp_total(), i = 0; i < n; ++i) { + totp_t *totp = &credentials[i]; + unsigned char *key = totp->key; + + totp->key = malloc(UNBASE32_LEN(totp->key_length)); + totp->key_length = base32_decode(key, totp->key); + + if (totp->key_length == 0) { + free(totp->key); + continue; + } + } +} + void totp_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; (void) watch_face_index; - if (*context_ptr == NULL) *context_ptr = malloc(sizeof(totp_state_t)); + + if (*context_ptr == NULL) { + totp_state_t *totp = malloc(sizeof(totp_state_t)); + totp_face_decode_secrets(); + *context_ptr = totp; + } } void totp_face_activate(movement_settings_t *settings, void *context) { @@ -129,7 +142,7 @@ bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void movement_move_to_face(0); break; case EVENT_ALARM_BUTTON_UP: - if (totp_state->current_index + 1 < _totp_num()) { + if (totp_state->current_index + 1 < totp_total()) { totp_state->current_index++; } else { // wrap around to first key -- cgit v1.2.3 From 46a4076f9ee1c7546040c9484baa17fda7fe246a Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 25 Feb 2024 22:40:32 -0300 Subject: faces/totp: improve TOTP initializer labeling It now generates the string literal from the preprocessor token. Even warns the user if the string is too long! --- movement/watch_faces/complication/totp_face.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index 83126a1a..2edabd83 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -46,12 +46,12 @@ typedef struct { unsigned char *key; } totp_t; -#define TOTP_INITIALIZER(label_1, label_2, key_array, algo, timestep) \ +#define TOTP_INITIALIZER(label, key_array, algo, timestep) \ (const totp_t) { \ .key = ((unsigned char *) key_array), \ .key_length = sizeof(key_array) - 1, \ .period = (timestep), \ - .labels = { (label_1), (label_2) }, \ + .labels = (#label), \ .algorithm = (algo), \ } @@ -59,8 +59,8 @@ typedef struct { // Enter your TOTP key data below static totp_t credentials[] = { - TOTP_INITIALIZER('2', 'F', "JBSWY3DPEHPK3PXP", SHA1, 30), - TOTP_INITIALIZER('A', 'C', "JBSWY3DPEHPK3PXP", SHA1, 30), + TOTP_INITIALIZER(2F, "JBSWY3DPEHPK3PXP", SHA1, 30), + TOTP_INITIALIZER(AC, "JBSWY3DPEHPK3PXP", SHA1, 30), }; // END OF KEY DATA. -- cgit v1.2.3 From 238709e1d9ad702e6a9418e827b8588c00d20a78 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 25 Feb 2024 22:46:45 -0300 Subject: faces/totp: rename initializer macro to credential Shorter and far more expressive. --- movement/watch_faces/complication/totp_face.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index 2edabd83..ac73c55e 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -46,7 +46,7 @@ typedef struct { unsigned char *key; } totp_t; -#define TOTP_INITIALIZER(label, key_array, algo, timestep) \ +#define CREDENTIAL(label, key_array, algo, timestep) \ (const totp_t) { \ .key = ((unsigned char *) key_array), \ .key_length = sizeof(key_array) - 1, \ @@ -59,8 +59,8 @@ typedef struct { // Enter your TOTP key data below static totp_t credentials[] = { - TOTP_INITIALIZER(2F, "JBSWY3DPEHPK3PXP", SHA1, 30), - TOTP_INITIALIZER(AC, "JBSWY3DPEHPK3PXP", SHA1, 30), + CREDENTIAL(2F, "JBSWY3DPEHPK3PXP", SHA1, 30), + CREDENTIAL(AC, "JBSWY3DPEHPK3PXP", SHA1, 30), }; // END OF KEY DATA. -- cgit v1.2.3 From 4633be0845aab21603f0f09e1ab026c74e7fc547 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 25 Feb 2024 22:55:55 -0300 Subject: faces/totp: delete leading underscores Makes for cleaner symbols. --- movement/watch_faces/complication/totp_face.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index ac73c55e..35e435c6 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -66,7 +66,7 @@ static totp_t credentials[] = { // END OF KEY DATA. //////////////////////////////////////////////////////////////////////////////// -static inline totp_t *_totp_current(totp_state_t *totp_state) { +static inline totp_t *totp_current(totp_state_t *totp_state) { return &credentials[totp_state->current_index]; } @@ -74,11 +74,11 @@ static inline size_t totp_total(void) { return sizeof(credentials) / sizeof(*credentials); } -static void _update_display(totp_state_t *totp_state) { +static void totp_display(totp_state_t *totp_state) { char buf[14]; div_t result; uint8_t valid_for; - totp_t *totp = _totp_current(totp_state); + totp_t *totp = totp_current(totp_state); result = div(totp_state->timestamp, totp->period); if (result.quot != totp_state->steps) { @@ -121,7 +121,7 @@ void totp_face_activate(movement_settings_t *settings, void *context) { (void) settings; memset(context, 0, sizeof(totp_state_t)); totp_state_t *totp_state = (totp_state_t *)context; - totp_t *totp = _totp_current(totp_state); + totp_t *totp = totp_current(totp_state); TOTP(totp->key, totp->key_length, totp->period, totp->algorithm); totp_state->timestamp = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60); totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp); @@ -136,7 +136,7 @@ bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void totp_state->timestamp++; // fall through case EVENT_ACTIVATE: - _update_display(totp_state); + totp_display(totp_state); break; case EVENT_TIMEOUT: movement_move_to_face(0); @@ -148,9 +148,9 @@ bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void // wrap around to first key totp_state->current_index = 0; } - totp_t *totp = _totp_current(totp_state); + totp_t *totp = totp_current(totp_state); TOTP(totp->key, totp->key_length, totp->period, totp->algorithm); - _update_display(totp_state); + totp_display(totp_state); break; case EVENT_ALARM_BUTTON_DOWN: case EVENT_ALARM_LONG_PRESS: -- cgit v1.2.3 From 26e1b7bdc4ae4c76ce6e424091bf573d6d61059a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Zettlmei=C3=9Fl?= Date: Sun, 21 Jan 2024 00:15:01 +0100 Subject: faces/totp: allow moving backwards through codes Adds the ability to cycle back to the previous credential with LIGHT. Long pressing LIGHT activates the LED. Co-authored-by: Matheus Afonso Martins Moreira --- movement/watch_faces/complication/totp_face.c | 18 +++++++++++++++++- movement/watch_faces/complication/totp_face.h | 2 ++ movement/watch_faces/complication/totp_face_lfs.c | 15 ++++++++++++++- movement/watch_faces/complication/totp_face_lfs.h | 2 ++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index 35e435c6..b0a4f5c5 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -130,6 +130,7 @@ void totp_face_activate(movement_settings_t *settings, void *context) { bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { (void) settings; totp_state_t *totp_state = (totp_state_t *)context; + totp_t *totp; switch (event.event_type) { case EVENT_TICK: @@ -148,12 +149,27 @@ bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void // wrap around to first key totp_state->current_index = 0; } - totp_t *totp = totp_current(totp_state); + totp = totp_current(totp_state); + TOTP(totp->key, totp->key_length, totp->period, totp->algorithm); + totp_display(totp_state); + break; + case EVENT_LIGHT_BUTTON_UP: + if (totp_state->current_index == 0) { + // Wrap around to the last credential. + totp_state->current_index = totp_total() - 1; + } else { + totp_state->current_index--; + } + totp = totp_current(totp_state); TOTP(totp->key, totp->key_length, totp->period, totp->algorithm); totp_display(totp_state); break; case EVENT_ALARM_BUTTON_DOWN: case EVENT_ALARM_LONG_PRESS: + case EVENT_LIGHT_BUTTON_DOWN: + break; + case EVENT_LIGHT_LONG_PRESS: + movement_illuminate_led(); break; default: movement_default_loop_handler(event, settings); diff --git a/movement/watch_faces/complication/totp_face.h b/movement/watch_faces/complication/totp_face.h index 9332435c..8bde4713 100644 --- a/movement/watch_faces/complication/totp_face.h +++ b/movement/watch_faces/complication/totp_face.h @@ -58,6 +58,8 @@ * o Once finished, remove the two provided examples. * * If you have more than one secret key, press ALARM to cycle through them. + * Press LIGHT to cycle in the other direction or keep it pressed longer to + * activate the light. */ #include "movement.h" diff --git a/movement/watch_faces/complication/totp_face_lfs.c b/movement/watch_faces/complication/totp_face_lfs.c index 4066ac48..820ad52e 100644 --- a/movement/watch_faces/complication/totp_face_lfs.c +++ b/movement/watch_faces/complication/totp_face_lfs.c @@ -163,7 +163,7 @@ static void totp_face_lfs_read_file(char *filename) { continue; } - // If we found a probably valid TOTP record, keep it. + // If we found a probably valid TOTP record, keep it. if (totp_records[num_totp_records].secret_size) { num_totp_records += 1; } else { @@ -255,8 +255,21 @@ bool totp_face_lfs_loop(movement_event_t event, movement_settings_t *settings, v totp_face_set_record(totp_state, (totp_state->current_index + 1) % num_totp_records); totp_face_display(totp_state); break; + case EVENT_LIGHT_BUTTON_UP: + if (totp_state->current_index - 1 >= 0) { + totp_face_set_record(totp_state, totp_state->current_index - 1); + } else { + // Wrap around to the last record. + totp_face_set_record(totp_state, num_totp_records - 1); + } + totp_face_display(totp_state); + break; case EVENT_ALARM_BUTTON_DOWN: case EVENT_ALARM_LONG_PRESS: + case EVENT_LIGHT_BUTTON_DOWN: + break; + case EVENT_LIGHT_LONG_PRESS: + movement_illuminate_led(); break; default: movement_default_loop_handler(event, settings); diff --git a/movement/watch_faces/complication/totp_face_lfs.h b/movement/watch_faces/complication/totp_face_lfs.h index 64c6ce15..72ae2460 100644 --- a/movement/watch_faces/complication/totp_face_lfs.h +++ b/movement/watch_faces/complication/totp_face_lfs.h @@ -47,6 +47,8 @@ * to modify the URI. * * If you have more than one secret key, press ALARM to cycle through them. + * Press LIGHT to cycle in the other direction or keep it pressed longer to + * activate the light. */ #include "movement.h" -- cgit v1.2.3 From 92baa2200faa7e120c81f15dc97f8a451282e86b Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 5 Mar 2024 03:03:25 -0300 Subject: faces/totp: update copyrights MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the copyrights to include full name attribution to Max Zettlmeißl whose code I've incorporated and who has explicitly licensed it as MIT. Max Zettlmeißl (@maxz) commented on 2024-01-20: > I provide all my changes under the MIT license GitHub-Comment: https://github.com/joeycastillo/Sensor-Watch/pull/356#issuecomment-1902114306 --- movement/watch_faces/complication/totp_face.c | 1 + movement/watch_faces/complication/totp_face.h | 1 + 2 files changed, 2 insertions(+) diff --git a/movement/watch_faces/complication/totp_face.c b/movement/watch_faces/complication/totp_face.c index b0a4f5c5..40b083dd 100644 --- a/movement/watch_faces/complication/totp_face.c +++ b/movement/watch_faces/complication/totp_face.c @@ -10,6 +10,7 @@ * Copyright © 2023 Emilien Court * Copyright © 2023 Jeremy O'Brien * Copyright © 2024 Matheus Afonso Martins Moreira (https://www.matheusmoreira.com/) + * Copyright © 2024 Max Zettlmeißl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/movement/watch_faces/complication/totp_face.h b/movement/watch_faces/complication/totp_face.h index 8bde4713..af269e92 100644 --- a/movement/watch_faces/complication/totp_face.h +++ b/movement/watch_faces/complication/totp_face.h @@ -9,6 +9,7 @@ * Copyright © 2022 Jack Bond-Preston * Copyright © 2023 Alex Utter * Copyright © 2024 Matheus Afonso Martins Moreira (https://www.matheusmoreira.com/) + * Copyright © 2024 Max Zettlmeißl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal -- cgit v1.2.3