From 0b21f56aca544765d50d2e086cfee0712902af11 Mon Sep 17 00:00:00 2001 From: alanacheff Date: Sun, 6 Oct 2024 20:52:43 +0000 Subject: [PATCH] Upload files to "src/c" --- src/c/basic.c | 488 ++++++++++++++++++++++++++++++++++++++++++++++ src/c/basic.h | 50 +++++ src/c/constants.c | 9 + src/c/constants.h | 19 ++ src/c/messaging.c | 110 +++++++++++ 5 files changed, 676 insertions(+) create mode 100644 src/c/basic.c create mode 100644 src/c/basic.h create mode 100644 src/c/constants.c create mode 100644 src/c/constants.h create mode 100644 src/c/messaging.c diff --git a/src/c/basic.c b/src/c/basic.c new file mode 100644 index 0000000..4fab50e --- /dev/null +++ b/src/c/basic.c @@ -0,0 +1,488 @@ +#include +#include "basic.h" +#include "constants.h" +#include "options.h" +#include "messaging.h" +#include + +#define DEBUG_DATE "Sun 02 Oct" +#define DEBUG_DAY "Sunday" +#define SCREEN_SHOT_HR 14 +#define SCREEN_SHOT_MIN 48 + +Options s_options; + +static TextLayer *s_hr_layer, *s_min_layer; + +static GFont s_time_font; +static GFont s_time_thin_font; +static GFont s_time_bold_font; + +static BitmapLayer *s_background_layer; +static GBitmap *s_background_bitmap; + +static BluetoothLayer *s_bluetooth_layer; + +static GFont s_date_font; +TextLayer *s_date_layer; +TextLayer *s_steps_layer; + +AppTimer *temp_display_timer; + +void set_hr_layer_color(GColor textColor) { + text_layer_set_text_color(s_hr_layer, textColor); +} + +void set_min_layer_color(GColor textColor) { + text_layer_set_text_color(s_min_layer, textColor); +} + +void set_wsd_layers_color(GColor textColor) { + text_layer_set_text_color(s_steps_layer, textColor); + text_layer_set_text_color(s_date_layer, textColor); +} + +static void init_window_background_color(){ + + window_set_background_color(s_main_window, GColorBlack); + text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorBlack); + + #ifdef PBL_COLOR // If on basalt + window_set_background_color(s_main_window, GColorFromHEX(s_options.background_color)); + text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorFromHEX(s_options.background_color)); + battery_bar_set_colors(GColorGreen, GColorYellow, GColorRed, GColorWhite); + #else + if (s_options.background_color == 0xFFFFFF) { + window_set_background_color(s_main_window, GColorWhite);//white + text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorWhite);//white + battery_bar_set_colors(GColorBlack, GColorBlack, GColorBlack, GColorBlack); + } + else if (s_options.background_color == 0x000000) {//black + window_set_background_color(s_main_window, GColorBlack); + text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorBlack); + battery_bar_set_colors(GColorWhite, GColorWhite, GColorWhite, GColorWhite); + } + else { //didn't select white or black, default to white + window_set_background_color(s_main_window, GColorBlack); + text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorBlack); + battery_bar_set_colors(GColorWhite, GColorWhite, GColorWhite, GColorWhite); + } + #endif + + layer_mark_dirty(text_layer_get_layer(s_bluetooth_battery_text_layer)); +} + +void init_static_row(TextLayer *label, GFont font) { + text_layer_set_background_color(label, GColorClear); + text_layer_set_text_color(label, GColorWhite); + text_layer_set_text_color(label, GColorFromHEX(s_options.wsd_color)); + + if (font) { + text_layer_set_font(label, font); + } +} + +void on_animation_stopped(Animation *anim, bool finished, void *context) { + //Free the memory used by the Animation + property_animation_destroy((PropertyAnimation*) anim); +} + +void animate_grect_layer(Layer *layer, GRect *start, GRect *finish, int duration, int delay) { + //Declare animation + PropertyAnimation *anim = property_animation_create_layer_frame(layer, start, finish); + + //Set characteristics + animation_set_duration((Animation*) anim, duration); + animation_set_delay((Animation*) anim, delay); + + //Set stopped handler to free memory + AnimationHandlers handlers = { + //The reference to the stopped handler is the only one in the array + .stopped = (AnimationStoppedHandler) on_animation_stopped + }; + animation_set_handlers((Animation*) anim, handlers, NULL); + + //Start animation! + animation_schedule((Animation*) anim); +} + +static void animate_text_layers_round() { + + // Steps moves in from bottom + GRect sins = GRect(20, 180, 60, 24); + GRect sinf = GRect(20, 122, 60, 24); + animate_grect_layer(text_layer_get_layer(s_steps_layer), &sins, &sinf, 1000, 0); + + GRect souts = GRect(20, 122, 60, 24); + GRect soutf = GRect(20, 180, 60, 24); + animate_grect_layer(text_layer_get_layer(s_steps_layer), &souts, &soutf, 1000, 5000); + + // Date moves in from bottom + GRect dins = GRect(100, 180, 60, 24); + GRect dinf = GRect(100, 122, 60, 24); + animate_grect_layer(text_layer_get_layer(s_date_layer), &dins, &dinf, 1000, 0); + + GRect douts = GRect(100, 122, 60, 24); + GRect doutf = GRect(100, 180, 60, 24); + animate_grect_layer(text_layer_get_layer(s_date_layer), &douts, &doutf, 1000, 5000); + + // Bluetooth & battery layers revealed at top + GRect bbins = GRect(0, 5, 200, 47); + GRect bbinf = GRect(0, -47, 200, 47); + animate_grect_layer(text_layer_get_layer(s_bluetooth_battery_text_layer), &bbins, &bbinf, 1000, 0); + + GRect bbouts = GRect(0, -47, 200, 47); + GRect bboutf = GRect(0, 5, 200, 47); + animate_grect_layer(text_layer_get_layer(s_bluetooth_battery_text_layer), &bbouts, &bboutf, 1000, 5000); +} + +static void animate_text_layers() { + + // Steps moves in from bottom + GRect sins = GRect(2, 180, 80, 24); + GRect sinf = GRect(2, 151, 80, 24); + animate_grect_layer(text_layer_get_layer(s_steps_layer), &sins, &sinf, 1000, 0); + + GRect souts = GRect(2, 151, 80, 24); + GRect soutf = GRect(2, 180, 80, 24); + animate_grect_layer(text_layer_get_layer(s_steps_layer), &souts, &soutf, 1000, 5000); + + // Date moves in from bottom + GRect dins = GRect(82, 180, 60, 24); + GRect dinf = GRect(82, 151, 60, 24); + animate_grect_layer(text_layer_get_layer(s_date_layer), &dins, &dinf, 1000, 0); + + GRect douts = GRect(82, 151, 60, 24); + GRect doutf = GRect(82, 180, 60, 24); + animate_grect_layer(text_layer_get_layer(s_date_layer), &douts, &doutf, 1000, 5000); + + // Bluetooth & battery layers revealed at top + GRect bbins = GRect(0, 0, 200, 35); + GRect bbinf = GRect(0, -35, 200, 35); + animate_grect_layer(text_layer_get_layer(s_bluetooth_battery_text_layer), &bbins, &bbinf, 1000, 0); + + GRect bbouts = GRect(0, -35, 200, 35); + GRect bboutf = GRect(0, 0, 200, 35); + animate_grect_layer(text_layer_get_layer(s_bluetooth_battery_text_layer), &bbouts, &bboutf, 1000, 5000); +} + +static void update_time(struct tm *tick_time, TimeUnits units_changed) { + static char date_buffer[16]; + const char *current_date_layer; + + // Create a long-lived buffer + static char hr_buffer[] = "00"; + static char min_buffer[] = "00"; + + // Write the current hours and minutes into the buffer + if(clock_is_24h_style() == true) { + //Use 2h hour format + strftime(hr_buffer, sizeof("00"), "%H", tick_time); + } else { + //Use 12 hour format + strftime(hr_buffer, sizeof("00"), "%I", tick_time); + } + strftime(min_buffer, sizeof("00"), "%M", tick_time); + + // Display this time on the TextLayer + text_layer_set_text(s_hr_layer, hr_buffer); + + // Display the seconds on the TextLayer + text_layer_set_text(s_min_layer, min_buffer); + + //add date layer + current_date_layer = text_layer_get_text(s_date_layer); + + if (current_date_layer != date_buffer) { + //get current date + strftime(date_buffer, sizeof(date_buffer), "%a %d %b", tick_time); + #if DEBUG + strftime(date_buffer, sizeof(date_buffer), DEBUG_DATE, tick_time); //for screen shots + #endif + text_layer_set_text(s_date_layer, date_buffer); + } +} + +static void update_steps() { + HealthMetric metric = HealthMetricStepCount; + time_t start = time_start_of_today(); + time_t end = time(NULL); + static char steps_buffer[32]; + + // Check the metric has data available for today + HealthServiceAccessibilityMask mask = health_service_metric_accessible(metric, + start, end); + + if(mask & HealthServiceAccessibilityMaskAvailable) { + // Data is available! + snprintf(steps_buffer, sizeof(steps_buffer), "s: %d", (int)health_service_sum_today(metric)); + + #if DEBUG + snprintf(steps_buffer, sizeof(steps_buffer), "s: 1%d", (int)health_service_sum_today(metric)); + #endif + + APP_LOG(APP_LOG_LEVEL_INFO, "Steps today: %d", + (int)health_service_sum_today(metric)); + // Display to user in correct units + text_layer_set_text(s_steps_layer, steps_buffer); + } else { + // No data recorded yet today + APP_LOG(APP_LOG_LEVEL_ERROR, "Data unavailable!"); + } +} + +static void tap_handler(AccelAxisType axis, int32_t direction) { + update_steps(); + #if defined(PBL_ROUND) + animate_text_layers_round(); + #else + animate_text_layers(); + #endif +} + +static void main_window_load(Window *window) { + + //set-retrieve watchface options + init_options(); + + // Create time TextLayer + #if defined(PBL_ROUND) + s_hr_layer = text_layer_create(GRect(35, 57, 57, 48)); + #else + s_hr_layer = text_layer_create(GRect(15, 50, 57, 48)); + #endif + text_layer_set_background_color(s_hr_layer, GColorClear); + text_layer_set_text_color(s_hr_layer, GColorFromHEX(s_options.hr_color)); + text_layer_set_text_alignment(s_hr_layer, GTextAlignmentRight); + text_layer_set_text(s_hr_layer, "00"); + + //Create GFont + s_time_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_REGULAR_48)); + s_time_thin_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_LIGHT_48)); + s_time_bold_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_BOLD_48)); + + if (s_options.hourFont == 2) { + text_layer_set_font(s_hr_layer, s_time_bold_font); + } + else if(s_options.hourFont == 0) { + text_layer_set_font(s_hr_layer, s_time_thin_font); + } + else { + text_layer_set_font(s_hr_layer, s_time_font); + } + + // Add it as a child layer to the Window's root layer + layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_hr_layer)); + + #if defined(PBL_ROUND) + s_min_layer = text_layer_create(GRect(95, 57, 57, 48)); + #else + s_min_layer = text_layer_create(GRect(75, 50, 57, 48)); + #endif + text_layer_set_background_color(s_min_layer, GColorClear); + text_layer_set_text_alignment(s_min_layer, GTextAlignmentLeft); + text_layer_set_text_color(s_min_layer, GColorFromHEX(s_options.min_color)); + + if (s_options.minutesFont == 2) { + text_layer_set_font(s_min_layer, s_time_bold_font); + } + else if(s_options.minutesFont == 0) { + text_layer_set_font(s_min_layer, s_time_thin_font); + } + else { + text_layer_set_font(s_min_layer, s_time_font); + } + + // Add it as a child layer to the Window's root layer + layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_min_layer)); + + //add Bluetooth layer + s_bluetooth_layer = bluetooth_layer_create(); + #if defined(PBL_ROUND) + bluetooth_set_position(GPoint(42, 41)); + #else + bluetooth_set_position(GPoint(2, 2)); + #endif + layer_add_child(window_get_root_layer(window), s_bluetooth_layer); + + //add battery layer + s_battery_layer = battery_bar_layer_create(); + battery_bar_set_percent_hidden(true); + battery_bar_set_icon_hidden(false); + #ifdef PBL_COLOR // If on basalt + battery_bar_set_colors(GColorGreen, GColorYellow, GColorRed, GColorWhite); + #endif + #if defined(PBL_ROUND) + battery_bar_set_position(GPoint(102, 42)); + #else + battery_bar_set_position(GPoint(102, 3)); + #endif + layer_add_child(window_get_root_layer(window), s_battery_layer); + + #if defined(PBL_ROUND) + s_bluetooth_battery_text_layer = text_layer_create(GRect(0, 5, 200, 47)); + #else + s_bluetooth_battery_text_layer = text_layer_create(GRect(0, 0, 200, 35)); + #endif + + #if defined(PBL_ROUND) + s_bluetooth_battery_text_layer = text_layer_create(GRect(0, 5, 200, 47)); + #else + s_bluetooth_battery_text_layer = text_layer_create(GRect(0, 0, 200, 35)); + #endif + + init_window_background_color(); + layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_bluetooth_battery_text_layer)); + + //date layer + #if defined(PBL_ROUND) + s_date_layer = text_layer_create(GRect(100, 180, 60, 24)); + #else + s_date_layer = text_layer_create(GRect(82, 180, 60, 24)); + #endif + text_layer_set_background_color(s_date_layer, GColorClear); + text_layer_set_text_color(s_date_layer, GColorFromHEX(s_options.wsd_color)); + text_layer_set_text_alignment(s_date_layer, GTextAlignmentRight); + s_date_font = fonts_get_system_font(FONT_KEY_GOTHIC_14); + //s_date_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DIGITAL_SEVEN_14)); + + //Apply to TextLayer + text_layer_set_font(s_date_layer, s_date_font); + layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_date_layer)); + + //steps layer + #if defined(PBL_ROUND) + s_steps_layer = text_layer_create(GRect(20, 180, 60, 24)); + #else + s_steps_layer = text_layer_create(GRect(2, 180, 80, 24)); + #endif + text_layer_set_background_color(s_steps_layer, GColorClear); + text_layer_set_text_color(s_steps_layer, GColorFromHEX(s_options.wsd_color)); + text_layer_set_text_alignment(s_steps_layer, GTextAlignmentLeft); + s_date_font = fonts_get_system_font(FONT_KEY_GOTHIC_14); + //s_steps_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DIGITAL_SEVEN_14)); + + //Apply to TextLayer + text_layer_set_font(s_steps_layer, s_date_font); + layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_steps_layer)); +} + +static void main_window_unload(Window *window) { + + //Destroy Bluetooth layer + bluetooth_layer_destroy(s_bluetooth_layer); + + //Destroy battery layer + battery_bar_layer_destroy(s_battery_layer); + + //Destroy GBitmap + gbitmap_destroy(s_background_bitmap); + + //Destroy BitmapLayer + bitmap_layer_destroy(s_background_layer); + + // Destroy TextLayers + text_layer_destroy(s_hr_layer); + text_layer_destroy(s_min_layer); + text_layer_destroy(s_bluetooth_battery_text_layer); +} + +static void health_handler(HealthEventType event, void *context) { + // Which type of event occurred? + switch(event) { + case HealthEventSignificantUpdate: + APP_LOG(APP_LOG_LEVEL_INFO, + "New HealthService HealthEventSignificantUpdate event"); + break; + case HealthEventMetricAlert: + //update_steps(); + APP_LOG(APP_LOG_LEVEL_INFO, + "New HealthService HealthEventSignificantUpdate event"); + break; + case HealthEventHeartRateUpdate: + APP_LOG(APP_LOG_LEVEL_INFO, + "New HealthService HealthEventHeartRateUpdate event"); + break; + case HealthEventMovementUpdate: + //update_steps(); + APP_LOG(APP_LOG_LEVEL_INFO, + "New HealthService HealthEventMovementUpdate event"); + break; + case HealthEventSleepUpdate: + APP_LOG(APP_LOG_LEVEL_INFO, + "New HealthService HealthEventSleepUpdate event"); + break; + } +} + +static void handle_minute_tick(struct tm *tick_time, TimeUnits units_changed) { + update_time(tick_time, units_changed); +} + +void handle_tick(struct tm *tick_time, TimeUnits units_changed) { + if (units_changed & MINUTE_UNIT) { + handle_minute_tick(tick_time, units_changed); + } +} + +static void init() { + // Create main Window element and assign to pointer + s_main_window = window_create(); + + // Set handlers to manage the elements inside the Window + window_set_window_handlers(s_main_window, (WindowHandlers) { + .load = main_window_load, + .unload = main_window_unload + }); + + // Show the Window on the watch, with animated=true + window_stack_push(s_main_window, true); + + app_message_register_inbox_received(inbox_received_callback); + app_message_register_inbox_dropped(message_dropped); + app_message_register_outbox_sent(message_out_success); + app_message_register_outbox_failed(message_out_failed); + + #if defined(PBL_BW) + app_message_open(175, 250); + #else + app_message_open(app_message_inbox_size_maximum(), app_message_outbox_size_maximum()); + #endif + + time_t t = time(NULL); + struct tm *time_now = localtime(&t); + #if DEBUG + time_now->tm_hour = SCREEN_SHOT_HR; //for screen shots + time_now->tm_min = SCREEN_SHOT_MIN; + #endif + handle_tick(time_now, MINUTE_UNIT); + + #if defined(PBL_HEALTH) + // Attempt to subscribe + if(!health_service_events_subscribe(health_handler, NULL)) { + APP_LOG(APP_LOG_LEVEL_ERROR, "Health not available!"); + } + #else + APP_LOG(APP_LOG_LEVEL_ERROR, "Health not available!"); + #endif + + accel_tap_service_subscribe(tap_handler); + + // Register with TickTimerService + tick_timer_service_subscribe(MINUTE_UNIT, handle_tick); +} + +static void deinit() { + //save watchface options + persist_write_data(KEY_OPTIONS, &s_options, sizeof(s_options)); + + + // Destroy Window + window_destroy(s_main_window); +} + +int main(void) { + init(); + app_event_loop(); + deinit(); +} \ No newline at end of file diff --git a/src/c/basic.h b/src/c/basic.h new file mode 100644 index 0000000..542a486 --- /dev/null +++ b/src/c/basic.h @@ -0,0 +1,50 @@ +#include +#include + +TextLayer *weather_layer1, *weather_layer2, *weather_layer_center; +TextLayer *s_bluetooth_battery_text_layer; +TextLayer *date_layer1, *date_layer2, *date_layer_center; +TextLayer *digital_time_layer; +TextLayer *battery_layer; +AppTimer *lohi_display_timer; +BatteryBarLayer *s_battery_layer; + +void init_static_row(TextLayer *label, GFont font); //creates/configures static (weather/date) display lines +void set_text_layers_color(GColor textColor); //sets color for text (weather, date, digital time) elements + +void set_hr_layer_color(GColor textColor); +void set_min_layer_color(GColor textColor); +void set_wsd_layers_color(GColor textColor); + +typedef struct { + int shake_for_lohi; + int tempF; + int tempFLo; + int tempFHi; + int tempC; + int tempCLo; + int tempCHi; + int display_weather; + int weather_use_GPS; + char weather_location[64]; + int use_celsius; + int weather_frequency; + int min_since_last_forecast; + int condition_code; + int display_digital_time; + int pebble_js_ready; + int hr_color; + int min_color; + int wsd_color; + int background_color; + int hourFont; + int minutesFont; + bool bluetooth_state; + time_t last_update; + char conditions[32]; + char last_weather_update12hr[16]; + char last_weather_update24hr[16]; +} Options; + +Window *s_main_window; +Layer *s_canvas_layer; diff --git a/src/c/constants.c b/src/c/constants.c new file mode 100644 index 0000000..c7e4314 --- /dev/null +++ b/src/c/constants.c @@ -0,0 +1,9 @@ +#include +#include "constants.h" + +const int DEFAULT_HR_COLOR = 0xFFFFFF; //white +const int DEFAULT_MIN_COLOR = 0xFF5500; //orange +const int DEFAULT_WSD_COLOR = 0xFFFFFF; //white +const int DEFAULT_BACKGROUND_COLOR = 0x000000; //black +const int DEFAULT_HOUR_FONT = 1; //regular +const int DEFAULT_MINUTES_FONT = 1; //regular \ No newline at end of file diff --git a/src/c/constants.h b/src/c/constants.h new file mode 100644 index 0000000..0965725 --- /dev/null +++ b/src/c/constants.h @@ -0,0 +1,19 @@ +#pragma once + + #define DEBUG 0 + + #define KEY_JS_READY 1 + #define KEY_HR_COLOR 2 + #define KEY_MIN_COLOR 3 + #define KEY_WSD_COLOR 4 + #define KEY_BACKGROUND_COLOR 5 + #define KEY_HOUR_FONT 6 + #define KEY_MINUTES_FONT 7 + #define KEY_OPTIONS 99 + + extern const int DEFAULT_HR_COLOR; + extern const int DEFAULT_MIN_COLOR; + extern const int DEFAULT_WSD_COLOR; + extern const int DEFAULT_BACKGROUND_COLOR; + extern const int DEFAULT_HOUR_FONT; + extern const int DEFAULT_MINUTES_FONT; \ No newline at end of file diff --git a/src/c/messaging.c b/src/c/messaging.c new file mode 100644 index 0000000..7632ade --- /dev/null +++ b/src/c/messaging.c @@ -0,0 +1,110 @@ +#include +#include "messaging.h" +#include "constants.h" +#include "basic.h" +//#include + +extern Options s_options; +extern Layer *s_canvas_layer; + +void send(int key, int value, int key2, int value2, int key3, char value3[64]){ + #if DEBUG + APP_LOG(APP_LOG_LEVEL_DEBUG, "send: s_options.pebble_js_ready: %d", s_options.pebble_js_ready); + #endif + if (s_options.pebble_js_ready) { + + DictionaryIterator *iterator; + app_message_outbox_begin(&iterator); + dict_write_int(iterator, key, &value, sizeof(int), true); + dict_write_int(iterator, key2, &value2, sizeof(int), true); + dict_write_cstring(iterator, key3, value3); + + app_message_outbox_send(); + } +} + +void inbox_received_callback(DictionaryIterator *iterator, void *context) { + + // Read first item + Tuple *t = dict_read_first(iterator); + + // For all items + while(t != NULL) { + // Which key was received? + switch(t->key) { + + case KEY_BACKGROUND_COLOR: + s_options.background_color = (int)t->value->int32; + window_set_background_color(s_main_window, GColorFromHEX(s_options.background_color)); + text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorFromHEX(s_options.background_color)); + break; + + case KEY_HR_COLOR: + s_options.hr_color = (int)t->value->int32; + set_hr_layer_color(GColorFromHEX(s_options.hr_color)); + break; + + case KEY_MIN_COLOR: + s_options.min_color = (int)t->value->int32; + set_min_layer_color(GColorFromHEX(s_options.min_color)); + break; + + case KEY_WSD_COLOR: + s_options.wsd_color = (int)t->value->int32; + set_wsd_layers_color(GColorFromHEX(s_options.wsd_color)); + #ifdef PBL_BW + battery_bar_set_colors(GColorFromHEX(s_options.wsd_color), GColorFromHEX(s_options.wsd_color), GColorFromHEX(s_options.wsd_color), GColorFromHEX(s_options.wsd_color)); + #endif + break; + + case KEY_HOUR_FONT: + s_options.hourFont = (int)t->value->int32; + break; + + case KEY_MINUTES_FONT: + s_options.minutesFont = (int)t->value->int32; + break; + + case KEY_JS_READY: + s_options.pebble_js_ready = (int)t->value->int32; + #if DEBUG + APP_LOG(APP_LOG_LEVEL_DEBUG, "inbox_received_callback: s_options.pebble_js_ready: %d", s_options.pebble_js_ready); + #endif + break; + } + // Look for next item + t = dict_read_next(iterator); + } +} + +char *translate_error(AppMessageResult result) { + switch (result) { + case APP_MSG_OK: return "APP_MSG_OK"; + case APP_MSG_SEND_TIMEOUT: return "APP_MSG_SEND_TIMEOUT"; + case APP_MSG_SEND_REJECTED: return "APP_MSG_SEND_REJECTED"; + case APP_MSG_NOT_CONNECTED: return "APP_MSG_NOT_CONNECTED"; + case APP_MSG_APP_NOT_RUNNING: return "APP_MSG_APP_NOT_RUNNING"; + case APP_MSG_INVALID_ARGS: return "APP_MSG_INVALID_ARGS"; + case APP_MSG_BUSY: return "APP_MSG_BUSY"; + case APP_MSG_BUFFER_OVERFLOW: return "APP_MSG_BUFFER_OVERFLOW"; + case APP_MSG_ALREADY_RELEASED: return "APP_MSG_ALREADY_RELEASED"; + case APP_MSG_CALLBACK_ALREADY_REGISTERED: return "APP_MSG_CALLBACK_ALREADY_REGISTERED"; + case APP_MSG_CALLBACK_NOT_REGISTERED: return "APP_MSG_CALLBACK_NOT_REGISTERED"; + case APP_MSG_OUT_OF_MEMORY: return "APP_MSG_OUT_OF_MEMORY"; + case APP_MSG_CLOSED: return "APP_MSG_CLOSED"; + case APP_MSG_INTERNAL_ERROR: return "APP_MSG_INTERNAL_ERROR"; + default: return "UNKNOWN ERROR"; + } +} + +void message_dropped(AppMessageResult reason, void *context) { + APP_LOG(APP_LOG_LEVEL_ERROR, "Dropped message! Reason given: %s", translate_error(reason)); +} + +void message_out_success(DictionaryIterator *iter, void *context) { + APP_LOG(APP_LOG_LEVEL_DEBUG, "Message sent."); +} + +void message_out_failed(DictionaryIterator *iter, AppMessageResult reason, void *context) { + APP_LOG(APP_LOG_LEVEL_DEBUG, "Failed to send message. Reason = %s", translate_error(reason)); +} \ No newline at end of file