From 148ad6125c1e3ed586c0c1e8f34189a5b0efc2ff Mon Sep 17 00:00:00 2001 From: Didier Arenzana Date: Fri, 8 Nov 2013 02:09:19 +0100 Subject: [PATCH 1/7] First commit of update to 2.0 SDK. authenticator.c is mostly done, the select button does not do anything, because editZone.c has not been changed yet. epoch is now directly obtained via time(), get_epoch_seconds is not needed anymore :) We still need to configure timezone, SDK does not support it yet. --- README.md | 10 +- appinfo.json | 22 +++ resources/{src => }/images/twostep_icon.png | Bin resources/src/resource_map.json | 10 - src/authenticator.c | 204 ++++++++++---------- src/editTzone.c | 15 +- 6 files changed, 134 insertions(+), 127 deletions(-) create mode 100644 appinfo.json rename resources/{src => }/images/twostep_icon.png (100%) delete mode 100644 resources/src/resource_map.json diff --git a/README.md b/README.md index a22b9b7..22b0101 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Authenticator ============= -Forked off 'authenticator' by IEF, which was forked off 'twostep' by pokey9000, this is Authenticator for Pebble, with patches from rigel314 +Forked off 'authenticator' by IEF, which was forked off 'twostep' by pokey9000, this is Authenticator for Pebble, with patches from rigel314, updated to PebbleSDK-2.0 by Didier Arenzana. generating multiple Time-based One-Time Passwords, much like Google Authenticator. @@ -21,11 +21,11 @@ label:secret 5. repeat this for all your keys (don't forget to remove the example) -6. Generate the config by running ./configuration.py +6. build the application by running pebble build -7. Build and install the application with ./waf build && python httpserver as usual +7. install by running pebble install 8. Done, you can find 'Authenticator' in your app menu for your Pebble. -The above is assuming you have the Pebble SDK installed and configured to compile watch apps. -If not, review: http://developer.getpebble.com/1/01_GetStarted/01_Step_2 +The above is assuming you have the Pebble SDK 2.0 installed and configured to compile watch apps. +If not, review: https://developer.getpebble.com/2/ diff --git a/appinfo.json b/appinfo.json new file mode 100644 index 0000000..95fd2b9 --- /dev/null +++ b/appinfo.json @@ -0,0 +1,22 @@ +{ + "uuid": "5b59ec4a-8a6b-4ff0-bd80-0038a151cd86", + "shortName": "Authenticator", + "longName": "Authenticator", + "companyName": "pokey9000/IEF/rigel314", + "versionCode": 1, + "versionLabel": "1.1.0", + "watchapp": { + "watchface": false + }, + "appKeys": {}, + "resources": { + "media": [ + { + "menuIcon": true, + "type": "png", + "name": "IMAGE_MENU_ICON", + "file": "images/twostep_icon.png" + } + ] + } +} diff --git a/resources/src/images/twostep_icon.png b/resources/images/twostep_icon.png similarity index 100% rename from resources/src/images/twostep_icon.png rename to resources/images/twostep_icon.png diff --git a/resources/src/resource_map.json b/resources/src/resource_map.json deleted file mode 100644 index 0da7e90..0000000 --- a/resources/src/resource_map.json +++ /dev/null @@ -1,10 +0,0 @@ - -{"friendlyVersion": "VERSION", - "versionDefName": "VERSION", - "media": [ - { "type": "png", - "defName": "IMAGE_MENU_ICON", - "file": "images/twostep_icon.png" - } - ] -} diff --git a/src/authenticator.c b/src/authenticator.c index ed912db..1a75dc4 100644 --- a/src/authenticator.c +++ b/src/authenticator.c @@ -1,6 +1,4 @@ -#include "pebble_os.h" -#include "pebble_app.h" -#include "pebble_fonts.h" +#include #include "configuration.h" @@ -12,25 +10,18 @@ extern void showEditTimeZone(); #define SHA1_SIZE 20 -#define MY_UUID { 0xA4, 0xA6, 0x13, 0xB5, 0x8A, 0x6B, 0x4F, 0xF0, 0xBD, 0x80, 0x00, 0x38, 0xA1, 0x51, 0xCD, 0x86 } -PBL_APP_INFO(MY_UUID, - "Authenticator", "pokey9000/IEF/rigel314", - 1, 1, /* App version */ - RESOURCE_ID_IMAGE_MENU_ICON, - APP_INFO_STANDARD_APP); +Window *window; -Window window; - -TextLayer label; -TextLayer token; -TextLayer ticker; +TextLayer *label; +TextLayer *token; +TextLayer *ticker; int curToken = 0; int tZone; bool changed; /* from sha1.c from liboauth */ -/* This code is public-domain - it is based on libcrypt +/* This code is public-domain - it is based on libcrypt * placed in the public domain by Wei Dai and other contributors. */ @@ -63,13 +54,13 @@ typedef struct sha1nfo { /* public API - prototypes - TODO: doxygen*/ /* -void sha1_init(sha1nfo *s); -void sha1_writebyte(sha1nfo *s, uint8_t data); -void sha1_write(sha1nfo *s, const char *data, size_t len); -uint8_t* sha1_result(sha1nfo *s); -void sha1_initHmac(sha1nfo *s, const uint8_t* key, int keyLength); -uint8_t* sha1_resultHmac(sha1nfo *s); -*/ + void sha1_init(sha1nfo *s); + void sha1_writebyte(sha1nfo *s, uint8_t data); + void sha1_write(sha1nfo *s, const char *data, size_t len); + uint8_t* sha1_result(sha1nfo *s); + void sha1_initHmac(sha1nfo *s, const uint8_t* key, int keyLength); + uint8_t* sha1_resultHmac(sha1nfo *s); + */ char* itoa(int val, int base){ static char buf[32] = {0}; @@ -106,7 +97,7 @@ uint32_t sha1_rol32(uint32_t number, uint8_t bits) { void sha1_hashBlock(sha1nfo *s) { uint8_t i; uint32_t a,b,c,d,e,t; - + a=s->state.w[0]; b=s->state.w[1]; c=s->state.w[2]; @@ -160,11 +151,11 @@ void sha1_write(sha1nfo *s, const char *data, size_t len) { void sha1_pad(sha1nfo *s) { // Implement SHA-1 padding (fips180-2 ยง5.1.1) - + // Pad with 0x80 followed by 0x00 until the end of the block sha1_addUncounted(s, 0x80); while (s->bufferOffset != 56) sha1_addUncounted(s, 0x00); - + // Append length in the last 8 bytes sha1_addUncounted(s, 0); // We're only using 32 bit lengths sha1_addUncounted(s, 0); // But SHA-1 supports 64 bit lengths @@ -180,7 +171,7 @@ uint8_t* sha1_result(sha1nfo *s) { int i; // Pad to complete the last block sha1_pad(s); - + // Swap byte order back for (i=0; i<5; i++) { uint32_t a,b; @@ -191,7 +182,7 @@ uint8_t* sha1_result(sha1nfo *s) { b|=a>>24; s->state.w[i]=b; } - + // Return pointer to hash (20 characters) return s->state.b; } @@ -229,39 +220,37 @@ uint8_t* sha1_resultHmac(sha1nfo *s) { return sha1_result(s); } - /* end sha1.c */ + // return seconds since epoch compensating for Pebble's lack of location // independent GMT int curSeconds=0; -uint32_t get_epoch_seconds() { - PblTm current_time; +uint32_t get_epoch_seconds(struct tm *current_time) { + //PblTm current_time; uint32_t unix_time; - get_time(¤t_time); + //get_time(¤t_time); // shamelessly stolen from WhyIsThisOpen's Unix Time source: http://forums.getpebble.com/discussion/4324/watch-face-unix-time /* Convert time to seconds since epoch. */ //curSeconds=current_time.tm_sec; unix_time = ((0-tZone)*3600) + /* time zone offset */ /* 0-tZone+current_time.tm_isdst if it ever starts working. */ - + current_time.tm_sec /* start with seconds */ - + current_time.tm_min*60 /* add minutes */ - + current_time.tm_hour*3600 /* add hours */ - + current_time.tm_yday*86400 /* add days */ - + (current_time.tm_year-70)*31536000 /* add years since 1970 */ - + ((current_time.tm_year-69)/4)*86400 /* add a day after leap years, starting in 1973 */ - ((current_time.tm_year-1)/100)*86400 /* remove a leap day every 100 years, starting in 2001 */ + ((current_time.tm_year+299)/400)*86400; /* add a leap day back every 400 years, starting in 2001*/ + + current_time->tm_sec /* start with seconds */ + + current_time->tm_min*60 /* add minutes */ + + current_time->tm_hour*3600 /* add hours */ + + current_time->tm_yday*86400 /* add days */ + + (current_time->tm_year-70)*31536000 /* add years since 1970 */ + + ((current_time->tm_year-69)/4)*86400 /* add a day after leap years, starting in 1973 */ - ((current_time->tm_year-1)/100)*86400 /* remove a leap day every 100 years, starting in 2001 */ + ((current_time->tm_year+299)/400)*86400; /* add a leap day back every 400 years, starting in 2001*/ unix_time /= 30; return unix_time; } +void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { -void handle_second_tick(AppContextRef ctx, PebbleTickEvent *t) { - - (void)t; - (void)ctx; - + /* to be cheked - could be much simpler now I guess */ + (void) units_changed; static char tokenText[] = "RYRYRY"; // Needs to be static because it's used by the system later. sha1nfo s; @@ -269,11 +258,14 @@ void handle_second_tick(AppContextRef ctx, PebbleTickEvent *t) { uint32_t otp; int i; uint32_t unix_time; + time_t current_time ; char sha1_time[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - PblTm curTime; - get_time(&curTime); - curSeconds = curTime.tm_sec; + if (tick_time == NULL) { + current_time=time(NULL) ; + tick_time = localtime(¤t_time); + } + curSeconds = tick_time->tm_sec; if(curSeconds == 0 || curSeconds == 30 || changed) { @@ -282,7 +274,7 @@ void handle_second_tick(AppContextRef ctx, PebbleTickEvent *t) { // TOTP uses seconds since epoch in the upper half of an 8 byte payload // TOTP is HOTP with a time based payload // HOTP is HMAC with a truncation function to get a short decimal key - unix_time = get_epoch_seconds(); + unix_time = get_epoch_seconds(tick_time); sha1_time[4] = (unix_time >> 24) & 0xFF; sha1_time[5] = (unix_time >> 16) & 0xFF; sha1_time[6] = (unix_time >> 8) & 0xFF; @@ -313,102 +305,106 @@ void handle_second_tick(AppContextRef ctx, PebbleTickEvent *t) { char *labelText = otplabels[curToken]; - text_layer_set_text(&label, labelText); - text_layer_set_text(&token, tokenText); + text_layer_set_text(label, labelText); + text_layer_set_text(token, tokenText); } if ((curSeconds>=0) && (curSeconds<30)) { - text_layer_set_text(&ticker, itoa((30-curSeconds),10)); + text_layer_set_text(ticker, itoa((30-curSeconds),10)); } else { - text_layer_set_text(&ticker, itoa((60-curSeconds),10)); + text_layer_set_text(ticker, itoa((60-curSeconds),10)); } } -void up_single_click_handler(ClickRecognizerRef recognizer, Window *window) { +void up_single_click_handler(ClickRecognizerRef recognizer, void *context) { + (void)recognizer ; + (void)context ; + if (curToken==0) { curToken=NUM_SECRETS-1; } else { curToken--; }; changed = true; - handle_second_tick(NULL,NULL); + handle_second_tick(NULL,SECOND_UNIT); } -void down_single_click_handler(ClickRecognizerRef recognizer, Window *window) { - (void)recognizer; - (void)window; - if ((curToken+1)==NUM_SECRETS) { - curToken=0; - } else { - curToken++; - }; +void down_single_click_handler(ClickRecognizerRef recognizer, void *context) { + (void)recognizer; + (void)context; + + curToken = (curToken + 1 ) % NUM_SECRETS ; changed = true; - handle_second_tick(NULL,NULL); + handle_second_tick(NULL,SECOND_UNIT); } -void select_single_click_handler(ClickRecognizerRef recognizer, Window *window) { +void select_single_click_handler(ClickRecognizerRef recognizer, void *context) { (void)recognizer; - (void)window; + (void)context; - showEditTimeZone(); + //showEditTimeZone(); } -void click_config_provider(ClickConfig **config, Window *window) { - (void)window; - - config[BUTTON_ID_UP]->click.handler = (ClickHandler) up_single_click_handler; - config[BUTTON_ID_UP]->click.repeat_interval_ms = 100; +void click_config_provider(void *context) { - config[BUTTON_ID_DOWN]->click.handler = (ClickHandler) down_single_click_handler; - config[BUTTON_ID_DOWN]->click.repeat_interval_ms = 100; - - config[BUTTON_ID_SELECT]->click.handler = (ClickHandler) select_single_click_handler; + // window_set_click_context(BUTTON_ID_UP, context); + window_single_repeating_click_subscribe(BUTTON_ID_UP, 100, up_single_click_handler); + window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 100, down_single_click_handler); + window_single_click_subscribe(BUTTON_ID_SELECT, select_single_click_handler); } -void handle_init(AppContextRef ctx) { - (void)ctx; + +void handle_init(void) { tZone = DEFAULT_TIME_ZONE; changed = true; - window_init(&window, "auth"); - window_stack_push(&window, true /* Animated */); - window_set_background_color(&window, GColorBlack); + window = window_create(); + window_stack_push(window, true /* Animated */); + window_set_background_color(window, GColorBlack); // Init the identifier label - text_layer_init(&label, GRect(5, 30, 144-4, 168-44)); - text_layer_set_text_color(&label, GColorWhite); - text_layer_set_background_color(&label, GColorClear); - text_layer_set_font(&label, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); + label=text_layer_create(GRect(5, 30, 144-4, 168-44)); + text_layer_set_text_color(label, GColorWhite); + text_layer_set_background_color(label, GColorClear); + text_layer_set_font(label, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); + + // Init the token label - text_layer_init(&token, GRect(10, 60, 144-4 /* width */, 168-44 /* height */)); - text_layer_set_text_color(&token, GColorWhite); - text_layer_set_background_color(&token, GColorClear); - text_layer_set_font(&token, fonts_get_system_font(FONT_KEY_BITHAM_34_MEDIUM_NUMBERS)); + token=text_layer_create(GRect(10, 60, 144-4 /* width */, 168-44 /* height */)); + text_layer_set_text_color(token, GColorWhite); + text_layer_set_background_color(token, GColorClear); + text_layer_set_font(token, fonts_get_system_font(FONT_KEY_BITHAM_34_MEDIUM_NUMBERS)); // Init the second ticker - text_layer_init(&ticker, GRect(60, 120, 144-4 /* width */, 168-44 /* height */)); - text_layer_set_text_color(&ticker, GColorWhite); - text_layer_set_background_color(&ticker, GColorClear); - text_layer_set_font(&ticker, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD)); + ticker=text_layer_create(GRect(60, 120, 144-4 /* width */, 168-44 /* height */)); + text_layer_set_text_color(ticker, GColorWhite); + text_layer_set_background_color(ticker, GColorClear); + text_layer_set_font(ticker, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD)); + + handle_second_tick(NULL, SECOND_UNIT); - handle_second_tick(ctx, NULL); - layer_add_child(&window.layer, &label.layer); - layer_add_child(&window.layer, &token.layer); - layer_add_child(&window.layer, &ticker.layer); + Layer *window_layer=window_get_root_layer(window); + layer_add_child(window_layer, text_layer_get_layer(label)); + layer_add_child(window_layer, text_layer_get_layer(token)); + layer_add_child(window_layer, text_layer_get_layer(ticker)); - window_set_click_config_provider(&window, (ClickConfigProvider) click_config_provider); + window_set_click_config_provider(window, (ClickConfigProvider) click_config_provider); } +void handle_deinit(void) { + APP_LOG(APP_LOG_LEVEL_DEBUG, "deinit called"); + tick_timer_service_unsubscribe(); + text_layer_destroy(label) ; + text_layer_destroy(token) ; + text_layer_destroy(ticker) ; + window_destroy(window); +} -void pbl_main(void *params) { - PebbleAppHandlers handlers = { - .init_handler = &handle_init, - .tick_info = { - .tick_handler = &handle_second_tick, - .tick_units = SECOND_UNIT - } - }; - app_event_loop(params, &handlers); +int main() { + handle_init(); + tick_timer_service_subscribe(SECOND_UNIT, handle_second_tick); + app_event_loop() ; + handle_deinit() ; } diff --git a/src/editTzone.c b/src/editTzone.c index 6d6ccf7..b76f7dc 100644 --- a/src/editTzone.c +++ b/src/editTzone.c @@ -1,14 +1,12 @@ -#include "pebble_os.h" -#include "pebble_app.h" -#include "pebble_fonts.h" +#include extern int tZone; extern bool changed; -Window setZoneW; -TextLayer setZoneW_zone; -TextLayer setZoneW_label; -TextLayer setZoneW_disclaim; +Window *setZoneW; +TextLayer *setZoneW_zone; +TextLayer *setZoneW_label; +TextLayer *setZoneW_disclaim; char gmt[7]; @@ -28,7 +26,7 @@ char* itoa2(int valIN, int base){ // 2 in the morning hack return &buf2[i]; } - +#if 0 void zone_up(ClickRecognizerRef recognizer, Window *window) { (void)recognizer; (void)window; @@ -98,3 +96,4 @@ void showEditTimeZone() changed = true; } +#endif From 7a59105bc5136ad10b98b64e9eee016680bbe4fd Mon Sep 17 00:00:00 2001 From: Didier Arenzana Date: Fri, 8 Nov 2013 02:34:09 +0100 Subject: [PATCH 2/7] disable get_epoch_seconds() --- src/authenticator.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/authenticator.c b/src/authenticator.c index 1a75dc4..6495df6 100644 --- a/src/authenticator.c +++ b/src/authenticator.c @@ -228,6 +228,8 @@ uint8_t* sha1_resultHmac(sha1nfo *s) { int curSeconds=0; +#if 0 +/* not needed anymore, we have time() ! */ uint32_t get_epoch_seconds(struct tm *current_time) { //PblTm current_time; uint32_t unix_time; @@ -246,10 +248,10 @@ uint32_t get_epoch_seconds(struct tm *current_time) { unix_time /= 30; return unix_time; } +#endif void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { - /* to be cheked - could be much simpler now I guess */ (void) units_changed; static char tokenText[] = "RYRYRY"; // Needs to be static because it's used by the system later. @@ -261,8 +263,10 @@ void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { time_t current_time ; char sha1_time[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + current_time=time(NULL); + unix_time=current_time + ((0-tZone)*3600) ; + unix_time /= 30; if (tick_time == NULL) { - current_time=time(NULL) ; tick_time = localtime(¤t_time); } curSeconds = tick_time->tm_sec; @@ -274,7 +278,7 @@ void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { // TOTP uses seconds since epoch in the upper half of an 8 byte payload // TOTP is HOTP with a time based payload // HOTP is HMAC with a truncation function to get a short decimal key - unix_time = get_epoch_seconds(tick_time); + //unix_time = get_epoch_seconds(tick_time); sha1_time[4] = (unix_time >> 24) & 0xFF; sha1_time[5] = (unix_time >> 16) & 0xFF; sha1_time[6] = (unix_time >> 8) & 0xFF; From c70dac3ac18cb00951ea69fde4e571cc38f9b809 Mon Sep 17 00:00:00 2001 From: Didier Arenzana Date: Fri, 8 Nov 2013 21:55:37 +0100 Subject: [PATCH 3/7] Fully functional Authenticator, ported to 2.0 SDK --- src/authenticator.c | 37 +++----------- src/editTzone.c | 116 ++++++++++++++++++++++++++------------------ 2 files changed, 75 insertions(+), 78 deletions(-) diff --git a/src/authenticator.c b/src/authenticator.c index 6495df6..19c0cb0 100644 --- a/src/authenticator.c +++ b/src/authenticator.c @@ -4,6 +4,7 @@ // defined in editTzone.c extern void showEditTimeZone(); +extern void destroyEditTimeZone(); // Truncate n decimal digits to 2^n for 6 digits #define DIGITS_TRUNCATE 1000000 @@ -222,34 +223,6 @@ uint8_t* sha1_resultHmac(sha1nfo *s) { /* end sha1.c */ - -// return seconds since epoch compensating for Pebble's lack of location -// independent GMT - -int curSeconds=0; - -#if 0 -/* not needed anymore, we have time() ! */ -uint32_t get_epoch_seconds(struct tm *current_time) { - //PblTm current_time; - uint32_t unix_time; - //get_time(¤t_time); - -// shamelessly stolen from WhyIsThisOpen's Unix Time source: http://forums.getpebble.com/discussion/4324/watch-face-unix-time - /* Convert time to seconds since epoch. */ - //curSeconds=current_time.tm_sec; - unix_time = ((0-tZone)*3600) + /* time zone offset */ /* 0-tZone+current_time.tm_isdst if it ever starts working. */ - + current_time->tm_sec /* start with seconds */ - + current_time->tm_min*60 /* add minutes */ - + current_time->tm_hour*3600 /* add hours */ - + current_time->tm_yday*86400 /* add days */ - + (current_time->tm_year-70)*31536000 /* add years since 1970 */ - + ((current_time->tm_year-69)/4)*86400 /* add a day after leap years, starting in 1973 */ - ((current_time->tm_year-1)/100)*86400 /* remove a leap day every 100 years, starting in 2001 */ + ((current_time->tm_year+299)/400)*86400; /* add a leap day back every 400 years, starting in 2001*/ - unix_time /= 30; - return unix_time; -} -#endif - void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { (void) units_changed; @@ -262,9 +235,10 @@ void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { uint32_t unix_time; time_t current_time ; char sha1_time[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int curSeconds; current_time=time(NULL); - unix_time=current_time + ((0-tZone)*3600) ; + unix_time=current_time + ((0-tZone)*3600) ; //still needed because time() is not GMT unix_time /= 30; if (tick_time == NULL) { tick_time = localtime(¤t_time); @@ -278,7 +252,6 @@ void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { // TOTP uses seconds since epoch in the upper half of an 8 byte payload // TOTP is HOTP with a time based payload // HOTP is HMAC with a truncation function to get a short decimal key - //unix_time = get_epoch_seconds(tick_time); sha1_time[4] = (unix_time >> 24) & 0xFF; sha1_time[5] = (unix_time >> 16) & 0xFF; sha1_time[6] = (unix_time >> 8) & 0xFF; @@ -346,7 +319,7 @@ void select_single_click_handler(ClickRecognizerRef recognizer, void *context) { (void)recognizer; (void)context; - //showEditTimeZone(); + showEditTimeZone(); } void click_config_provider(void *context) { @@ -399,6 +372,8 @@ void handle_init(void) { void handle_deinit(void) { APP_LOG(APP_LOG_LEVEL_DEBUG, "deinit called"); + + destroyEditTimeZone(); tick_timer_service_unsubscribe(); text_layer_destroy(label) ; text_layer_destroy(token) ; diff --git a/src/editTzone.c b/src/editTzone.c index b76f7dc..59156f9 100644 --- a/src/editTzone.c +++ b/src/editTzone.c @@ -3,7 +3,7 @@ extern int tZone; extern bool changed; -Window *setZoneW; +Window *setZoneW=NULL; TextLayer *setZoneW_zone; TextLayer *setZoneW_label; TextLayer *setZoneW_disclaim; @@ -26,74 +26,96 @@ char* itoa2(int valIN, int base){ // 2 in the morning hack return &buf2[i]; } -#if 0 -void zone_up(ClickRecognizerRef recognizer, Window *window) { + +void zone_up(ClickRecognizerRef recognizer, void *context) { (void)recognizer; - (void)window; + (void)context; if(tZone<24) tZone++; strcpy(gmt+3, itoa2(tZone,10)); - text_layer_set_text(&setZoneW_zone, gmt); + text_layer_set_text(setZoneW_zone, gmt); changed = true; } -void zone_down(ClickRecognizerRef recognizer, Window *window) { +void zone_down(ClickRecognizerRef recognizer, void *context) { (void)recognizer; - (void)window; + (void)context; if(tZone>-24) tZone--; strcpy(gmt+3, itoa2(tZone,10)); - text_layer_set_text(&setZoneW_zone, gmt); + text_layer_set_text(setZoneW_zone, gmt); changed = true; } -void zone_click_config_provider(ClickConfig **config, Window *window) { - (void)window; +void zone_click_config_provider(void *context) { - config[BUTTON_ID_UP]->click.handler = (ClickHandler) zone_up; - config[BUTTON_ID_UP]->click.repeat_interval_ms = 100; - - config[BUTTON_ID_DOWN]->click.handler = (ClickHandler) zone_down; - config[BUTTON_ID_DOWN]->click.repeat_interval_ms = 100; + window_single_repeating_click_subscribe(BUTTON_ID_UP, 100, zone_up); + window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 100, zone_down); + } -void showEditTimeZone() -{ - window_init(&setZoneW, "Set Time Zone"); - window_set_background_color(&setZoneW, GColorBlack); - +void create_setZoneW() { + setZoneW=window_create(); + Layer *setZoneW_layer=window_get_root_layer(setZoneW); + window_set_background_color(setZoneW, GColorBlack); + strcpy(gmt, "UTC"); strcpy(gmt+3, itoa2(tZone,10)); - - text_layer_init(&setZoneW_zone, GRect(0,50,144,48)); - text_layer_set_text(&setZoneW_zone, gmt); - text_layer_set_font(&setZoneW_zone, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); - text_layer_set_text_alignment(&setZoneW_zone, GTextAlignmentCenter); - setZoneW_zone.text_color = GColorWhite; - setZoneW_zone.background_color = GColorBlack; - layer_add_child(&setZoneW.layer, &setZoneW_zone.layer); + + setZoneW_zone=text_layer_create(GRect(0,50,144,48)); + + text_layer_set_text( setZoneW_zone, gmt); + text_layer_set_font( setZoneW_zone, + fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); + text_layer_set_text_alignment( setZoneW_zone, GTextAlignmentCenter); + text_layer_set_text_color( setZoneW_zone, GColorWhite); + text_layer_set_background_color(setZoneW_zone, GColorBlack); + + layer_add_child(setZoneW_layer, text_layer_get_layer(setZoneW_zone)); - text_layer_init(&setZoneW_label, GRect(0,5,144,48)); - text_layer_set_text(&setZoneW_label, "Change Time Zone"); - text_layer_set_font(&setZoneW_label, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD)); - text_layer_set_text_alignment(&setZoneW_label, GTextAlignmentCenter); - setZoneW_label.text_color = GColorWhite; - setZoneW_label.background_color = GColorBlack; - layer_add_child(&setZoneW.layer, &setZoneW_label.layer); - - text_layer_init(&setZoneW_disclaim, GRect(0,168-31,144,30)); - text_layer_set_text(&setZoneW_disclaim, "Not Persistant"); - text_layer_set_font(&setZoneW_disclaim, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); - text_layer_set_text_alignment(&setZoneW_disclaim, GTextAlignmentCenter); - setZoneW_disclaim.text_color = GColorWhite; - setZoneW_disclaim.background_color = GColorBlack; - layer_add_child(&setZoneW.layer, &setZoneW_disclaim.layer); - - window_set_click_config_provider(&setZoneW, (ClickConfigProvider) zone_click_config_provider); - window_stack_push(&setZoneW, true); + setZoneW_label=text_layer_create(GRect(0,5,144,48)); + + text_layer_set_text( setZoneW_label, "Change Time Zone"); + text_layer_set_font( setZoneW_label, + fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD)); + text_layer_set_text_alignment( setZoneW_label, GTextAlignmentCenter); + text_layer_set_text_color( setZoneW_label, GColorWhite); + text_layer_set_background_color(setZoneW_label, GColorBlack); + + layer_add_child(setZoneW_layer, text_layer_get_layer(setZoneW_label)); + + setZoneW_disclaim=text_layer_create(GRect(0,168-31,144,30)); + + text_layer_set_text( setZoneW_disclaim, "Not Persistant"); + text_layer_set_font( setZoneW_disclaim, + fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); + text_layer_set_text_alignment( setZoneW_disclaim, GTextAlignmentCenter); + text_layer_set_text_color( setZoneW_disclaim, GColorWhite); + text_layer_set_background_color(setZoneW_disclaim, GColorBlack); + + layer_add_child(setZoneW_layer, text_layer_get_layer(setZoneW_disclaim)); + + window_set_click_config_provider(setZoneW, (ClickConfigProvider) zone_click_config_provider); +} + +void destroyEditTimeZone() { + if (setZoneW == NULL) return ; + + text_layer_destroy(setZoneW_disclaim) ; + text_layer_destroy(setZoneW_label); + text_layer_destroy(setZoneW_zone); + window_destroy(setZoneW); + setZoneW=NULL ; +} + +void showEditTimeZone() +{ + APP_LOG(APP_LOG_LEVEL_DEBUG, "showEditTimeZone: setZoneW==%p", setZoneW); + if (setZoneW == NULL) create_setZoneW(); + window_stack_push(setZoneW, true); changed = true; } -#endif + From 35b026105a6c7495928045b7bc49530e7fe583a8 Mon Sep 17 00:00:00 2001 From: Didier Arenzana Date: Fri, 8 Nov 2013 23:09:24 +0100 Subject: [PATCH 4/7] make timezone and selected token persistent --- src/authenticator.c | 30 ++++++++++++++++++++++++++++-- src/editTzone.c | 13 ------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/authenticator.c b/src/authenticator.c index 19c0cb0..3105119 100644 --- a/src/authenticator.c +++ b/src/authenticator.c @@ -16,8 +16,15 @@ Window *window; TextLayer *label; TextLayer *token; TextLayer *ticker; -int curToken = 0; + +#define KEY_CURTOKEN 1 +int curToken; +int curToken_orig; + +#define KEY_TZONE 2 int tZone; +int tZone_orig; //used to track config changes + bool changed; /* from sha1.c from liboauth */ @@ -333,7 +340,14 @@ void click_config_provider(void *context) { void handle_init(void) { - tZone = DEFAULT_TIME_ZONE; + // get timezone from persistent storage, if found + tZone = persist_exists(KEY_TZONE) ? persist_read_int(KEY_TZONE) : DEFAULT_TIME_ZONE; + tZone_orig=tZone ; + + // get saved current token + curToken = persist_exists(KEY_CURTOKEN) ? persist_read_int(KEY_CURTOKEN) : 0 ; + curToken_orig = curToken; + changed = true; window = window_create(); @@ -373,6 +387,18 @@ void handle_init(void) { void handle_deinit(void) { APP_LOG(APP_LOG_LEVEL_DEBUG, "deinit called"); + //store timezone in persistence storage if needed + if (tZone != tZone_orig) { + if (tZone == DEFAULT_TIME_ZONE) persist_delete(KEY_TZONE) ; + else persist_write_int(KEY_TZONE, tZone) ; + } + + //save selected token + if (curToken != curToken_orig) { + if (curToken == 0) persist_delete(KEY_CURTOKEN); + else persist_write_int(KEY_CURTOKEN, curToken); + } + destroyEditTimeZone(); tick_timer_service_unsubscribe(); text_layer_destroy(label) ; diff --git a/src/editTzone.c b/src/editTzone.c index 59156f9..380483d 100644 --- a/src/editTzone.c +++ b/src/editTzone.c @@ -6,7 +6,6 @@ extern bool changed; Window *setZoneW=NULL; TextLayer *setZoneW_zone; TextLayer *setZoneW_label; -TextLayer *setZoneW_disclaim; char gmt[7]; @@ -86,24 +85,12 @@ void create_setZoneW() { layer_add_child(setZoneW_layer, text_layer_get_layer(setZoneW_label)); - setZoneW_disclaim=text_layer_create(GRect(0,168-31,144,30)); - - text_layer_set_text( setZoneW_disclaim, "Not Persistant"); - text_layer_set_font( setZoneW_disclaim, - fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); - text_layer_set_text_alignment( setZoneW_disclaim, GTextAlignmentCenter); - text_layer_set_text_color( setZoneW_disclaim, GColorWhite); - text_layer_set_background_color(setZoneW_disclaim, GColorBlack); - - layer_add_child(setZoneW_layer, text_layer_get_layer(setZoneW_disclaim)); - window_set_click_config_provider(setZoneW, (ClickConfigProvider) zone_click_config_provider); } void destroyEditTimeZone() { if (setZoneW == NULL) return ; - text_layer_destroy(setZoneW_disclaim) ; text_layer_destroy(setZoneW_label); text_layer_destroy(setZoneW_zone); window_destroy(setZoneW); From 292793607ed0e7160c9dfac9eee7d250d7c0a010 Mon Sep 17 00:00:00 2001 From: Didier Arenzana Date: Tue, 12 Nov 2013 22:24:42 +0100 Subject: [PATCH 5/7] add missing wscript --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 560ecae..951101a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,9 +8,12 @@ build .lock-waf* +# Ignore vi backups +*~ + # Ignore linked files/directories waf -wscript +resources/wscript tools include lib From 2b99e2dd26368fb18fcd10e6114d569ad4af422e Mon Sep 17 00:00:00 2001 From: Didier Arenzana Date: Tue, 12 Nov 2013 22:43:20 +0100 Subject: [PATCH 6/7] add wscript --- wscript | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 wscript diff --git a/wscript b/wscript new file mode 100644 index 0000000..0554dc8 --- /dev/null +++ b/wscript @@ -0,0 +1,24 @@ + +# +# This file is the default set of rules to compile a Pebble project. +# +# Feel free to customize this to your needs. +# + +top = '.' +out = 'build' + +def options(ctx): + ctx.load('pebble_sdk') + +def configure(ctx): + ctx.load('pebble_sdk') + +def build(ctx): + ctx.load('pebble_sdk') + + ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'), + target='pebble-app.elf') + + ctx.pbl_bundle(elf='pebble-app.elf', + js=ctx.path.ant_glob('src/js/**/*.js')) From ce1cfcd1376693ff9aa734fe762363d8952716c3 Mon Sep 17 00:00:00 2001 From: Didier Arenzana Date: Tue, 12 Nov 2013 22:51:42 +0100 Subject: [PATCH 7/7] do not track my Xcode project --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 560ecae..e3664a8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ build .lock-waf* +# Ignore xcode project +Pebble Authenticator + # Ignore linked files/directories waf wscript