-
Notifications
You must be signed in to change notification settings - Fork 250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow for more TOTP credentials and enable cycling backwards through codes #356
base: main
Are you sure you want to change the base?
Conversation
The `uint8_t` could store a maximum offset of 255, which would represent around 13 credentials with a key size of 20 bytes. I ran into this limitation. The `uint16_t` allows for more than 3000 credentials and some other limit of the watch's memory is probably reached before that point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if you aren't using EVENT_LIGHT_LONG_PRESS
for anything, that adding LED functionality would at least prevent losing a feature. Something like this from the thermistor sensor:
case EVENT_LIGHT_LONG_PRESS:
movement_illuminate_led();
break;
Your comment said
The light could also be activated at the same time, but I decided
against this since the cases where someone would require their TOTP
credentials while relying on the LED light to read them seemed very
unlikely to occur.
I can tell you as a dad trying to put their kid down at night, but trying to log into something on their phone with a credential on their watch, that I use this feature frequently :)
EDIT: To specify, I'm looking at movement/watch_faces/complication/totp_face.c
on line 142.
EDIT 2: Updated quote so I'm not misrepresenting author comment.
Using a long press for the light seems reasonable to me. I will change that. Thanks for your feedback and also for the reference of how the other face did it. I really though it to be unlikely for someone to use this. Whenever there would be some kind of screen I would have expected it to provide enough light to read the watch. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested in emulator with my current TOTP config was successful, and worked as I expected. I've only commented on small documentation things now, but functionally I think the code is sound and easier to understand than before.
Thank you. The missing comment was an oversight. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, and good work!
@WesleyAC or @joeycastillo will probably want to take a look and they can merge this in. |
I provide all my changes under the MIT license which the rest of this project uses right now. (To avoid someone having to explicitly ask like in #334.) I did not feel like adding a license text to the individual file would add anything. By not adding it I'm implicitly using the project license anyways. |
I squashed all the various smaller corrections together and properly separated the commit with the credential changes from the commit with the backwards cycling changes. |
When storing many TOTP credentials, it could get bothersome to keep all the arrays synchronized. Now there are the `credentials` array which holds most of the parameters and the `keys` array which is a concession to not have the storage waste or the malloc that would be required when storing the key in the `totp_parameters_t` struct along with everything else. Additionally there is a helper program found at `utils/totp_face_helper.py` which properly transforms the key from its base32 representation into the form expected by the TOTP watch face.
It is helpful to be able to go back to the previous credential by pressing the light button. Pressing the light button longer (for more than half a second) activates the LED.
I had a previous version of these changes already running on hardware and these changes also worked fine in the simulator, but now I deployed exactly these commits to hardware and they still work as expected. And as a motivation for the changed format, see the following comparison of my credentials in the new style and the old one.
|
Hello! I see you have lifted the arbitrary limitation by increasing the size of the offset variable. I submitted PR #369 which renders that variable obsolete. I implemented proper structured access to the records. The offsets are implied by the data and array structures and so it is no longer necessary to manually keep track of them. It works like this: 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 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);
} Would you like to work together to merge our improvements? |
Sure. I'd suggest you rebase your changes on top of my branch and then post your patches (in full git format, with authorship information) or a link to your branch here and I add the changes to my branch. Then we can go from there. I don't have much time in the next ~1 week but will take a look afterwards and make changes or suggestions. |
Implemented. static totp_t credentials[] = {
CREDENTIAL(2F, "JBSWY3DPEHPK3PXP", SHA1, 30),
CREDENTIAL(AC, "JBSWY3DPEHPK3PXP", SHA1, 30),
}; It will even warn the user if the symbol is too long!
They are now anonymous. |
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: joeycastillo#356 (comment)
Aggregates the TOTP credentials into a data structure, making it easier to define and use the credentials. Also incorporate backwards movement code from another branch. Co-authored-by: Max Zettlmeißl <max@zettlmeissl.de> Tested-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> Signed-off-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> GitHub-Pull-Request: joeycastillo#369 GitHub-Related-Pull-Request: joeycastillo#356
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: joeycastillo#356 (comment)
Aggregates the TOTP credentials into a data structure, making it easier to define and use the credentials. Also incorporate backwards movement code from another branch. Co-authored-by: Max Zettlmeißl <max@zettlmeissl.de> Tested-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> Signed-off-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> GitHub-Pull-Request: joeycastillo#369 GitHub-Related-Pull-Request: joeycastillo#356
Aggregates the TOTP credentials into a data structure, making it easier to define and use the credentials. Also incorporate backwards movement code from another branch. Co-authored-by: Max Zettlmeißl <max@zettlmeissl.de> Tested-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> Signed-off-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> GitHub-Pull-Request: joeycastillo#369 GitHub-Related-Pull-Request: joeycastillo#356
Aggregates the TOTP credentials into a data structure, making it easier to define and use the credentials. Also incorporate backwards movement code from another branch. Co-authored-by: Max Zettlmeißl <max@zettlmeissl.de> Tested-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> Signed-off-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> GitHub-Pull-Request: joeycastillo#369 GitHub-Related-Pull-Request: joeycastillo#356
Aggregates the TOTP credentials into a data structure, making it easier to define and use the credentials. Also incorporate backwards movement code from another branch. Co-authored-by: Max Zettlmeißl <max@zettlmeissl.de> Tested-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> Signed-off-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> GitHub-Pull-Request: joeycastillo#369 GitHub-Related-Pull-Request: joeycastillo#356
I have incorporated commit 055d9c9 into my branch and am now running it on real hardware. No issues so far. |
Aggregates the TOTP credentials into a data structure, making it easier to define and use the credentials. Also incorporate backwards movement code from another branch. Co-authored-by: Max Zettlmeißl <max@zettlmeissl.de> Tested-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> Tested-on-hardware-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> Signed-off-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> GitHub-Pull-Request: joeycastillo#369 GitHub-Related-Pull-Request: joeycastillo#356
I'm not sure what to say about this now that your changes got merged. I'm sure you meant well and most of your changes were good, but you also dropped essential parts of my changes. You just merge the easy cycling commit and dropped the changes which would still improve the definition of new credentials in the new state of the main branch. I guess I will just resubmit them and hope that this time nobody comes along who changes things differently and then pesters the maintainers until they merge it. |
I apologize if what I did was inappropriate. It was not my intention to offend you. It's just that you said you weren't going to have much time to focus on this so I went ahead and tried to do as much as I could. I thought it was best to reduce the scope of the changes due to the feedback I received in my clock face refactoring PR. Too many changes made it difficult to review, I had to remove some features. That's why I didn't integrate your complete change set. I will be merging more PRs in the next branch and I plan to revisit this one. The Python script in particular can improve things even further and also reduce memory usage. I also took your suggestions seriously: I came up with a macro that makes it easy and safe to define credentials, and used compound literals in order to avoid the need to name the arrays to begin with or even have the arrays at all. I did not follow your suggestion to move the structure to the header but I had a good reason for that: no code outside that file references the structure, making it implicitly implementation internal. Still, your work has been merged into the main branch, which should be cause for celebration. It was only slightly changed for integration purposes but I ensured you retained authorship, made sure to fully credit you in multiple places, and also fully complied with all terms of the MIT license under which we are releasing our code. I even updated the copyrights to include everyone who ever contributed to the file. So I'm not sure what the problem is. If there's something I forgot to do, simply point it out and I will get it done. I don't appreciate you calling me a pest. I'm new here but I'm very enthusiastic about this project and I really want to see it succeed. It's true that I was anxious to see the improvements merged. However, that was due to enthusiasm, not entitlement. I actually asked a couple of times in the discord about this: I was worried my actions were excessive but nobody really said anything. Surely atax1a would have told me to stop pestering them if that was the case. I would have stopped had they told me to and I gave the maintainers ample opportunity to do so. Hell, I'm giving them that oppotunity right now, in public. |
That is true and I appreciate it.
The biggest thing that I'm missing are the default values which I had defined for the
I'm sorry. I did not mean it that harsh. I was previously not aware of pest being a possible root of the word pestering. You got to try to see how I felt. I patiently waited for weeks for someone to review my changes. And then you came along, made changes to the same place and expedited the process by opening multiple issues and merging the things. |
Do you mean the ability to omit the algorithm and period? Like this: static totp_t credentials[] = {
CREDENTIAL(2F, "JBSWY3DPEHPK3PXP"),
CREDENTIAL(AC, "JBSWY3DPEHPK3PXP"),
}; If so I agree with you. I thought your approach was quite clever too but in the end I opted for the shorter functional syntax. What do you think of defining an additional function for the defaults? static totp_t credentials[] = {
DEFAULT_CREDENTIAL(2F, "JBSWY3DPEHPK3PXP"),
DEFAULT_CREDENTIAL(AC, "JBSWY3DPEHPK3PXP"),
CREDENTIAL(TO, "JBSWY3DPEHPK3PXP", SHA1, 30),
CREDENTIAL(R2, "JBSWY3DPEHPK3PXP", SHA1, 30),
}; Or maybe: static totp_t credentials[] = {
CREDENTIAL(2F, "JBSWY3DPEHPK3PXP"),
CREDENTIAL(AC, "JBSWY3DPEHPK3PXP"),
FULL_CREDENTIAL(TO, "JBSWY3DPEHPK3PXP", SHA1, 30),
FULL_CREDENTIAL(R2, "JBSWY3DPEHPK3PXP", SHA1, 30),
}; The default macro can be defined in terms of the full macro.
Your script improves the code. I achieved the lack of arrays by placing the base 32 string in the ROM and decoding it to RAM when initializing the watch face at runtime. The script pre-computes them and generates the code, freeing up the memory. Unfortunately the macros aren't powerful enough to pre-compute the arrays. I wish C had a Zig-like
I apologize for that too. Truth is I started writing all these PRs without checking whether the features I wanted were already being worked on. I too ended up wasting a bunch of time. I fixed that though by going through every PR and familiarizing myself with them. I'm also watching this repository for new PRs. It shouldn't happen again. |
Exactly.
I'm not too fond of the first suggestion, at least not if the name is longer. I think most people who were not involved in writing any of this would then just use I think if the explicit version is to be kept, I'd name it Oh, I just saw that your second suggestion is pretty much what I described. So yes, that one would be what I had in mind:
Yes, that was the idea behind it. Also I did not want to add the complexity of decoding the base32 string at runtime (although it is already handled similarly in the |
I just remembered something. We can have a clean single function interface. While exploring the musl codebase, I came across this wonderful piece of C preprocessor wizardry: #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
#define __SYSCALL_CONCAT_X(a,b) a##b
#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b)
#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__) The most important macros are Here's how they're expanded:
We can use this principle to implement a general Would you like to implement it? |
Yeah. I did it that way because I looked at the LFS face and saw there was precedent for it. In that case it's necessary because of the parsing work but I didn't see much reason not to do it in the normal face as well. I want to eventually merge them both into one.
Your script is a fine solution. We just gotta integrate it with the build system somehow. Then we can make it generate a header that gets automatically included by the TOTP face. I haven't fully explored the makefiles yet but I will. |
Nice find.
I'm not too keen on wrestling C preprocessor macros right now. Go ahead an implement it if you want to. If you don't, then I will probably get around to it in a few weeks. |
Understood.
Sure thing. |
* Fixed incorrect conversion from UNIX timestamp to watch_date_time. * Print memory percentages this gives better idea of memories used. * new face: Tuning tones Add a new face that plays out tones that can be used as a reference when tuning musical instruments. * Turn on the funky segment of pos 0 for char '@' * add new COLOR flag * update alternate firmware for new board color * Add a volume slider in the simulator * Save the selected skin of the simulator in local storage * fix signal tunes not firing in background, and split out foreground/background chime functions * move buzzer enabled detection logic into movement for movement_play_signal/tune this way watch faces don't have to disable/enable the buzzer themselves before calling movement_play_signal() and movement_play_tune() * use movement_play_signal for default tune (fixes background signal) * Don't allow building without setting board color. Fixes: joeycastillo#288 * add compile-time options for all preferences to movement_config * Set default board color for GH workflow. I've chosen blue arbitrarily. * Update timer_face.c Corrects the data type of the standard values in order to be able to configure seconds as well. * new standard firmware for october boards * Add Couch-To-5k training face * Add sound to pause/resume button * Add minute repeater decimal face * moon_phase_face: Make alarm long-press reset to current day. * Add solstice_face. * Add simple_coin_flip_face. * Add day_night_percentage_face. * day_night_percentage_face: Calculate rise/set/daylen only once per day. * day_night_percentage_face: Use PM indicator instead of DA/NI. This allows for use of the weekday digits for displaying the weekday. * day_night_percentage_face: Clear seconds digits when entering LE mode. * Add save_load_face. * day_one_face: cleanup * day_one_face: allow years until 2080 This is the same limit introduced in commit 7fd51ca * day_one_face: enable quick cycle through settings This allows the alarm button to be held down in the date settings and quickly cycle through the dates instead of having to push for each single increment like in other faces. * day_one_face: show set date on short alarm button press * Improve simulator page design * Fix simulator and hardware divergence in callback handling (joeycastillo#252) When using the simulator, I encountered cases where the light would become stuck on, and the watch would be unresponsive. In particular, this would occur when pressing the light button on the sunrise sunset watch face. I appears that this is caused by a divergence in out the callback mask is interpreted by the hardware interface, and in the simulator in the following function. void watch_rtc_disable_matching_periodic_callbacks(uint8_t mask) In particular, a mask of 0xFE is intended to disable all except the 128hz callback at index 0, but instead disables all except the 1hz callback at index 7 in the simulator. * sunrise_sunset_face: Fix use of uninitialized memory. This was causing a crash in the simulator when setting the location. Fixes: joeycastillo#198 * Fit naming conventions * Resign when the entering LE * Simulator: Allow typing a, l & m in console input These keys are the shortcuts to "press" the alarm, light and mode buttons. However, they prevent these letters from being input in the debug console to send filesystem commands. Strangely, there was already some code to allow typing these letters in the console output, but not in the input. * Simulator: Allow sending debug command with Enter * Simulator: Add keyboard arrows as buttons shortcuts * Fix missing documentation for many clock faces: * Move from .c to .h as needed for consistency. * When missing from both, copy from pull request or wiki. * When missing entirely, infer functionality from source code. * Kitchen Conversions Face * fix undefined behavior found by clang's sanitize * make the zero in wyoscan a little more visually appealing * make it clear that the movement_state contains indexes * use a pointer to the watch face in the app loop instead of indirecting through the index each time, and also recalculate can_sleep based on the timeout loop call. * clean up trailing whitespace in movement.c * make the watch-face a global in movement.c, actually * work around silicon erratum in TRNG * work around silicon erratum in SUPC/VREG * fix simulator build by declaring Trng type as a void pointer * address SysTick erratum, which can hard-fault the chip * make the HAL sleep function obey the chip documentation the sleep mode doesn't get set immediately, and needs to be waited upon. * make any unknown interrupts/faults reset the microcontroller * delete stray line of code that messed with correction profile while adjusting cadence * USB Improvements * Introduce shell module for basic serial shell with argument parsing * Introduce shell_cmd_list module for basic compile-time command registration * Harden USB handling to hang less and drop fewer inputs - Service tud_task() with periodic TC0 timer interrupt - Service cdc_task() with periodic TC1 timer interrupt - Handle shell servicing in main app loop - Add a circular buffering layer for reads/writes * Change newline prints to also send carriage return * Refactor filesystem commands for shell subsystem * Introduce new shell commands: - 'help' command - 'flash' command to reset into bootloader - 'stress' command to stress CDC writes Testing: * Shell validated on Sensor Watch Blue w/ Linux host * Shell validated in emscripten emulator * Tuned by spamming inputs during `stress` cmd until stack didn't crash * Handle visibility for tomato watchface (cherry picked from commit 547e8248ba3538693ee8c587a92ffece7b40d1a2) * Revert "Merge pull request joeycastillo#283 from neutralinsomniac/fix_hourly_chime_background" This reverts commit 5c94111, reversing changes made to bc9b4ce. * Use legacy buzzer functions when playing default tune. This allows the default tune to be played in LE mode. Fixes: joeycastillo#275 * Enable custom signal tones in LE mode. This makes movement_play_signal synchronous when in LE mode, despite using the underlying asynchronous API. It's a bit of a hack, but it should work well enough for now. This also moves the enabling/disabling of the buzzer into the movement_play_signal function, so that watch faces no longer have to do it. * buzzer: fix simulator build, refactor sequence_length. * movement: Use LE mode code to keep buzzer awake, instead of sleeping. * fix alternate firmware script * template: fix compiler warning on watch_face_index as mentioned in PR 269 * Revert "make the watch-face a global in movement.c, actually" This reverts commit 0e801ed. * annotate TRNG erratum, address review comment * annotate SysTick erratum * annotate voltage regulation erratum * annotate SLEEPCFG-register detail * Change inactivity deadlines: add 10 minutes and remove 2 days. (joeycastillo#365) I like to use the ten minute timeout on my watch and there are other people who have similar interests in a lower deadline. The two day deadline had to go to still accommodate the change within the three bit index. The default setting is still the one hour timeout. * faces/totp: define TOTP data structure Aggregates all the data necessary for TOTP generation. * 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. * faces/totp: update example data to new structure The data definitions are much shorter and easier to read now. * 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. * faces/totp: define current TOTP data function Selects the appropriate TOTP data structure given the TOTP watch face state. * 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. * 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. * 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 * faces/pulsometer: implement advanced pulsometer Implements an advanced pulsometer that can be recalibrated by the user. The main clock face now displays the measured pulses per minute. The day of month digits now display the pulsometer calibration. The light button now cycles through integer graduations which now range from 1 to 39 pulses per minute. Long presses of the light button cycle by 10 instead of 1. The watch face's responsiveness to input has been carefully optimized. The code has been reorganized and generally improved. * faces/pulsometer: document the advanced pulsometer Thoroughly document the new advanced pulsometer watch face by describing what it is and how it works. * faces/pulsometer: update copyrights and credits Update the copyrights to include full name attribution to all who contributed to the pulsometer watch face, including myself. Also add an SPDX license identifier header comment to the files. * faces/pulsometer: move structure definition Instances of the pulsometer state structure are only passed to the pulsometer itself and only via the opaque context pointer. No other code uses it. There is no need to expose it in a header file so make it an implementation detail of the watch face. * faces: rename simple_clock_face to clock_face It's not actually so simple and will only gain features from now on. Just "clock face" also feels more canonical. * faces/clock: move structure definition Instances of the clock state structure are only passed to the clock face itself and only via the opaque context pointer. No other code uses it. Thus there is no need to expose it in a header file. So make it an implementation detail of the watch face by localizing it inside the translation unit. * faces/clock: define general indication function Sets or clears the specified indicator based on some boolean value. * faces/clock: simplify alarm indication function Deduplicates state in the clock state and movement settings. Makes the code simpler. Also makes it use the correct indicator. For some reason it had been switched with the hourly chime indicator. WATCH_INDICATOR_BELL The small bell indicating that an alarm is set. WATCH_INDICATOR_SIGNAL The hourly signal indicator. Also useful for indicating that sensors are on. * faces/clock: simplify signal indication function Simplifies the code and makes it use the correct indicator. For some reason it had been switched with the alarm indicator. WATCH_INDICATOR_BELL The small bell indicating that an alarm is set. WATCH_INDICATOR_SIGNAL The hourly signal indicator. Also useful for indicating that sensors are on. * faces/clock: simplify 24h indication function Simplifies the code by adding a dedicated function for this. * faces/clock: simplify PM indication function Simplifies the code by adding dedicated functions for this. * faces/clock: refactor daily battery check Move the code in question to a dedicated function. Better organized. Add overridable preprocessor definition for the low battery threshold. * faces/clock: simplify LAP indication function Simplifies the code by adding a dedicated function for this. Also documents the meaning of the LAP indicator: Low Available Power. * faces/clock: refactor low power tick function Simplifies the code by defining dedicated functions and separating the case from the main ones. Also use the snprintf function since the buffer size is known. * faces/clock: refactor tick tock animation code Simplifies the code by defining dedicated functions for this. * faces/clock: refactor full time display code Simplifies the code by defining dedicated functions for this. * faces/clock: refactor partial time display code Simplifies the code by defining dedicated functions for this. * faces/clock: reorder periodic battery check Check the battery after the time has been updated. Place all the indication code next to each other. * faces/clock: refactor clock display code Simplifies the code by defining dedicated functions for this. * faces/clock: refactor time signal toggling code Simplifies the code by defining dedicated functions for this. * faces/clock: indicate alarm only when necessary The alarm state is not modified within the clock face. Therefore, it only needs to be set when the face is activated. * faces/clock: indicate low power only when needed There is no need to set the indicator on every clock tick. Indicate only when the battery is checked. * 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. * 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! * faces/totp: rename initializer macro to credential Shorter and far more expressive. * faces/totp: delete leading underscores Makes for cleaner symbols. * faces/clock: update copyrights and credits Update the copyrights to include full name attribution to all who contributed to the clock watch face, including myself. Also add an SPDX license identifier header comment to the files. * faces/clock: add 24h only feature The clock watch face can now be configured at build time to only display the time in 24h mode. Also enabled in forced 24h mode. This should result in smaller code size due to dead code elimination. * 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 <matheus.a.m.moreira@gmail.com> * faces/totp: update copyrights 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: joeycastillo#356 (comment) * faces/pulsometer: remember pulsometer calibration Avoid resetting it to default when the face is activated. Set the default pulsometer calibration once, only when the face is first set up. This makes it remember the calibration set by the user. It will no longer overwrite it. * faces/pulsometer: remember pulsometer measurement Avoid resetting it to zero when the face is activated. Initialize the variables once when the face is first set up. This makes it remember the last measurement taken by the user. It will no longer be overwritten when the watch face activates. * movement: convert can_sleep an automatic variable It is a simple boolean value and its scope is limited to the function. There is no reason that I can think of for it to be a static variable. * movement: fix unintended timeout short circuiting Currently, movement drops time out events in case the previous loop indicates that sleep is not possible due to short circuiting behavior of logical and in C: if the left-hand side is false, the right hand side is not evaluated at all, which means the loop is not called. This was not intended to happen. Fix it by storing the result in a second boolean variable and working out the logic after the fact. * faces: restore simple_clock_face Restore the original simple clock face as requested. --------- Signed-off-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> Co-authored-by: Konrad Rieck <konrad@mlsec.org> Co-authored-by: Per Waagø <perwaago@gmail.com> Co-authored-by: Hugo Chargois <hugo.chargois@free.fr> Co-authored-by: joeycastillo <joeycastillo@utexas.edu> Co-authored-by: Jeremy O'Brien <neutral@fastmail.com> Co-authored-by: Wesley Aptekar-Cassels <me@wesleyac.com> Co-authored-by: madhogs <x3dh4vhf@duck.com> Co-authored-by: LtKeks <LtKeks@users.noreply.github.com> Co-authored-by: Ekaitz Zarraga <ekaitz@elenq.tech> Co-authored-by: Brian Blakley <bblakley@gmail.com> Co-authored-by: Christian Buschau <cbuschau@d00t.de> Co-authored-by: Victor Graf <nategraf1@gmail.com> Co-authored-by: Alex Utter <ooterness@gmail.com> Co-authored-by: PrimmR <93214758+PrimmR@users.noreply.github.com> Co-authored-by: Alex Maestas <git@se30.xyz> Co-authored-by: Edward Shin <contact@edwardsh.in> Co-authored-by: Pietro F. Maggi <pfm@pietromaggi.com> Co-authored-by: CarpeNoctem <cryptomax@pm.me> Co-authored-by: Wesley Ellis <tahnok@gmail.com> Co-authored-by: Max Zettlmeißl <max@zettlmeissl.de> Co-authored-by: madhogs <59648482+madhogs@users.noreply.github.com> Co-authored-by: Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com>
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: joeycastillo#356 (comment)
When settings up and using the TOTP face I came across some warts.
I increased the rather low limit of credentials which I ran into (previously around 13 with a key size of 20 bytes) to above 3000. Additionally it now is possible to cycle backwards through the codes by pressing the light button.
Those two things were in my local copy anyways, but I thought other people might appreciate them as well.
And since I wanted to submit these patches, I was motivated to tackle the rather repetitive configuration of the face too. When changing credentials and moving them around I found it rather frustrating to keep all the arrays in sync.
The algorithm now defaults to SHA1, the timestep to 30 seconds and the key size to 20.
Those were the values which occurred most often in my TOTP credentials.
The number of arrays was reduced to two, which was a concession I had to make to avoid malloc and storage waste. (If I had chosen a static array for the keys, I would probably have picked a size of 40, since the biggest one of my keys is 35 bytes. But there is no key size limit in the standard and there are ridiculously big keys (128 bytes) in the wild.)