/*! @brief getメソッドのメッセージを処理する. @param[in] received 受信したメッセージ @param[in] iter レスポンスを格納するイテレータ */ static void in_received_get_battery_handler(DictionaryIterator *received) { DBG_LOG(APP_LOG_LEVEL_DEBUG, "in_received_get_battery_handler"); Tuple *attributeTuple = dict_find(received, KEY_ATTRIBUTE); if (attributeTuple != NULL) { switch (attributeTuple->value->uint8) { case BATTERY_ATTRIBUTE_ALL: { // 加速度センサーが動いている場合には、一瞬止める orientation_service_pause(); entry_log( "get", "BATTERY_ATTRIBUTE_ALL" ) ; BatteryChargeState state = battery_state_service_peek(); // チャージングフラグ int charging = state.is_plugged ? BATTERY_CHARGING_ON : BATTERY_CHARGING_OFF; mq_kv_set(KEY_PARAM_BATTERY_CHARGING, charging); // パーセンテージ // pebbleのバッテリーは、0-100になっている。 // dconnectでは、0.0-1.0の浮動少数なので変換が必要。 // ただし、C側で変換するのは手間なので、JavaまたはiOS側で行うこととする。 mq_kv_set(KEY_PARAM_BATTERY_LEVEL, state.charge_percent); } break; case BATTERY_ATTRIBUTE_CHARING: { // 加速度センサーが動いている場合には、一瞬止める orientation_service_pause(); entry_log( "get", "BATTERY_ATTRIBUTE_CHARING" ) ; BatteryChargeState state = battery_state_service_peek(); int charging = state.is_plugged ? BATTERY_CHARGING_ON : BATTERY_CHARGING_OFF; // チャージングフラグ mq_kv_set(KEY_PARAM_BATTERY_CHARGING, charging); } break; case BATTERY_ATTRIBUTE_LEVEL: { // 加速度センサーが動いている場合には、一瞬止める orientation_service_pause(); entry_log( "get", "BATTERY_ATTRIBUTE_LEVEL" ) ; BatteryChargeState state = battery_state_service_peek(); // パーセンテージ mq_kv_set(KEY_PARAM_BATTERY_LEVEL, state.charge_percent); } break; default: entry_log( "get", "BATTERY error" ) ; // not support pebble_set_error_code(ERROR_NOT_SUPPORT_ATTRIBUTE); break; } } }
/*! @brief delete method, Key Event Profile message handler. @param[in] received Received message. */ static void in_received_delete_key_event_handler(DictionaryIterator *received) { Tuple *attributeTuple = dict_find(received, KEY_ATTRIBUTE); switch (attributeTuple->value->uint8) { case KEY_EVENT_ATTRIBUTE_ON_DOWN: entry_log2( "ON_DOWN", "del_handler" ) ; event_flag_on_down = false; if (event_flag_on_up == false && window != NULL) { key_event_window_uninit(); } break; case KEY_EVENT_ATTRIBUTE_ON_UP: entry_log2( "ON_UP", "del_handler" ) ; event_flag_on_up = false; if (event_flag_on_down == false && window != NULL) { key_event_window_uninit(); } break; default: // not support entry_log( "not support", "orientation" ) ; pebble_set_error_code(ERROR_NOT_SUPPORT_ATTRIBUTE); break; } }
/*! @brief deleteメソッド,eventsプロファイルのメッセージを処理する. @param[in] received 受信したメッセージ @param[in] iter レスポンスを格納するイテレータ */ static void in_received_delete_event_handler(DictionaryIterator *received, DictionaryIterator *iter) { DBG_LOG(APP_LOG_LEVEL_DEBUG, "in_received_delete_event_handler"); Tuple *attributeTuple = dict_find(received, KEY_ATTRIBUTE); switch (attributeTuple->value->uint8) { case SYSTEM_ATTRIBUTE_EVENTS: entry_log( "delete", "system/events" ) ; battery_service_unsubscribe_force() ; orientation_service_unsubscribe_force(); pebble_sniff_interval_reduced(); return ; default: entry_log( "error", "system/events?"); pebble_set_error_code(iter, ERROR_NOT_SUPPORT_ATTRIBUTE); break; } }
/*! @brief バッテリーの状態が変化した場合に呼び出されるコールバック関数 @param[in] state バッテリーの状態 */ static void in_event_battery_handler(BatteryChargeState state) { bool is_charging_changed, is_battery_changed ; if( get_changed_status( &last_state, &state, &is_charging_changed, &is_battery_changed ) == false ) { return ; } if( is_charging_changed && event_onchargingchange ) { entry_log( "event","onchargingchange" ) ; DBG_LOG(APP_LOG_LEVEL_DEBUG, "event_onchargingchange %d",(int)state.is_plugged); send_battery_charging( state.is_plugged ) ; } if( is_battery_changed && event_onbatterychange ) { entry_log( "event","onbatterychange" ) ; send_battery_percent( state.charge_percent ) ; } last_state = state ; return ; }
int in_received_canvas_handler(DictionaryIterator *received) { DBG_LOG(APP_LOG_LEVEL_DEBUG, "in_received_canvas_handler"); Tuple *actionTuple = dict_find(received, KEY_ACTION); switch (actionTuple->value->uint8) { case ACTION_DELETE: entry_log("delete bitmap", "start"); in_received_delete_canvas_handler(received); break; case ACTION_GET: case ACTION_PUT: case ACTION_POST: default: entry_log("canvas ", "NOT_SUPPORT"); pebble_set_error_code(ERROR_NOT_SUPPORT_ACTION); break; } return RETURN_SYNC; }
/*! @brief 充電状態を送信する。 @param[in] charging 充電中は true */ static void send_battery_charging( bool charging ) { if (!mq_push()) { entry_log( "error", "send_battery_charging" ) ; return; } // 加速度センサーが動いている場合には、一瞬止める orientation_service_pause(); mq_kv_set(KEY_ACTION, ACTION_EVENT); mq_kv_set(KEY_PROFILE, PROFILE_BATTERY); mq_kv_set(KEY_ATTRIBUTE, BATTERY_ATTRIBUTE_ON_CHARGING_CHANGE); mq_kv_set(KEY_PARAM_BATTERY_CHARGING, charging); send_message(); pebble_sniff_interval_normal(); entry_log( "send", "battery_charging" ) ; }
/*! @brief 充電容量を送信する。 @param[in] percent 充電容量(%) */ static void send_battery_percent( int percent ) { // 加速度センサーが動いている場合には、一瞬止める orientation_service_pause(); if (!mq_push()) { entry_log( "error", "send_battery_percent" ) ; return; } mq_kv_set(KEY_ACTION, ACTION_EVENT); mq_kv_set(KEY_PROFILE, PROFILE_BATTERY); mq_kv_set(KEY_ATTRIBUTE, BATTERY_ATTRIBUTE_ON_BATTERY_CHANGE); mq_kv_set(KEY_PARAM_BATTERY_LEVEL, percent); send_message(); pebble_sniff_interval_normal(); entry_log( "send", "send_battery_percent" ) ; }
/*! @brief deleteメソッドのメッセージを処理する. @param[in] received 受信したメッセージ @param[in] iter レスポンスを格納するイテレータ */ static void in_received_delete_battery_handler(DictionaryIterator *received) { DBG_LOG(APP_LOG_LEVEL_DEBUG, "in_received_delete_battery_handler"); Tuple *attributeTuple = dict_find(received, KEY_ATTRIBUTE); switch (attributeTuple->value->uint8) { case BATTERY_ATTRIBUTE_ON_CHARGING_CHANGE: entry_log( "delete battery", "ON_CHARGING_CHANGE" ) ; event_onchargingchange = false ; service_unsubscribe() ; break; case BATTERY_ATTRIBUTE_ON_BATTERY_CHANGE: entry_log( "delete battery", "ON_BATTERY_CHANGE" ) ; event_onbatterychange = false ; service_unsubscribe() ; break; default: // not support pebble_set_error_code(ERROR_NOT_SUPPORT_ATTRIBUTE); break; } }
/*! @brief putメソッドのメッセージを処理する. @param[in] received 受信したメッセージ @param[in] iter レスポンスを格納するイテレータ */ static void in_received_put_battery_handler(DictionaryIterator *received) { DBG_LOG(APP_LOG_LEVEL_DEBUG, "in_received_put_battery_handler"); Tuple *attributeTuple = dict_find(received, KEY_ATTRIBUTE); switch (attributeTuple->value->uint8) { case BATTERY_ATTRIBUTE_ON_CHARGING_CHANGE: entry_log( "put battery", "ON_CHARGING_CHANGE" ) ; event_onchargingchange = true ; last_state = battery_state_service_peek(); battery_state_service_subscribe(&in_event_battery_handler); break; case BATTERY_ATTRIBUTE_ON_BATTERY_CHANGE: entry_log( "put battery", "ON_BATTERY_CHANGE" ) ; event_onbatterychange = true ; last_state = battery_state_service_peek(); battery_state_service_subscribe(&in_event_battery_handler); break; default: entry_log( "put battery", "not support" ) ; pebble_set_error_code(ERROR_NOT_SUPPORT_ATTRIBUTE); break; } }
/*! @brief メッセージ送信処理。 */ void send_message() { DBG_LOG(APP_LOG_LEVEL_DEBUG, "send_message"); DictionaryIterator *iter = NULL; app_message_outbox_begin(&iter); if (iter == NULL) { // 送信用イテレータの作成に失敗 //entry_log( "error", "outbox_begin" ) ; DBG_LOG(APP_LOG_LEVEL_DEBUG, "send_message_error: outbox_begin"); return; } int k = 0, v = 0; bool more = mq_kv_get_first(&k, &v); while (more) { if (k == KEY_PARAM_SETTING_DATE) { time_t timer = time(NULL); struct tm *local = localtime(&timer); char str[64]; // ポインタにしないとTupletCStringがエラーを出す char *p = str; int year = local->tm_year + 1900; int month = local->tm_mon + 1; int day = local->tm_mday; int hour = local->tm_hour; int min = local->tm_min; int sec = local->tm_sec; // RFC 3339に合わせて変換を行う snprintf(str, sizeof(str), "%4d-%02d-%02dT%02d:%02d:%02d", year, month, day, hour, min, sec); entry_log("get setting/date", str); Tuplet dateTuple = TupletCString(KEY_PARAM_SETTING_DATE, p); dict_write_tuplet(iter, &dateTuple); } else { Tuplet tuple = TupletInteger(k, v); dict_write_tuplet(iter, &tuple); } more = mq_kv_get_next(&k, &v); } // データ終了 dict_write_end(iter); // データ送信 AppMessageResult res = app_message_outbox_send(); DBG_LOG(APP_LOG_LEVEL_DEBUG, "res:%d", res); }
/*! @brief deleteメソッド,DeviceOrientationプロファイルのメッセージを処理する. @param[in] received 受信したメッセージ @param[in] iter レスポンスを格納するイテレータ */ static void in_received_delete_device_orientation_handler(DictionaryIterator *received) { Tuple *attributeTuple = dict_find(received, KEY_ATTRIBUTE); switch (attributeTuple->value->uint8) { case DEVICE_ORIENTATION_ATTRIBUTE_ON_DEVICE_ORIENTATION: accel_data_service_unsubscribe(); pebble_sniff_interval_reduced(); break; default: // not support entry_log( "not support", "orientation" ) ; pebble_set_error_code(ERROR_NOT_SUPPORT_ATTRIBUTE); break; } }
static void in_received_put_vibration_handler(DictionaryIterator *received) { DBG_LOG(APP_LOG_LEVEL_DEBUG, "in_received_put_vibration_handler"); Tuple *attributeTuple = dict_find(received, KEY_ATTRIBUTE); switch (attributeTuple->value->uint8) { case VIBRATION_ATTRIBUTE_VIBRATE: { Tuple *lenTuple = dict_find(received, KEY_PARAM_VIBRATION_LEN); Tuple *patternTuple = dict_find(received, KEY_PARAM_VIBRATION_PATTERN); if (lenTuple == NULL && patternTuple == NULL) { vibes_short_pulse(); } else { int length = (int) lenTuple->value->uint16; if (length == 0) { entry_log( "put", "vibration" ) ; vibes_short_pulse(); } else { char *pattern = (char *) patternTuple->value->data; if (vibration_parse_pattern(pattern, length) == VIB_PATTERN_ERROR) { pebble_set_error_code(ERROR_ILLEGAL_PARAMETER); } else { VibePattern pat = { .durations = vib_data, .num_segments = length, }; entry_log( "put", "vibration" ) ; vibes_enqueue_custom_pattern(pat); } } } } break; default: // not support pebble_set_error_code(ERROR_NOT_SUPPORT_ATTRIBUTE); break; } }
/*! @brief Message processing for key event profile. @param[in] received Received message. @retval RETURN_SYNC Synchronous. @retval RETURN_ASYNC Asynchronous. */ int in_received_key_event_handler(DictionaryIterator *received) { Tuple *actionTuple = dict_find(received, KEY_ACTION); switch (actionTuple->value->uint8) { case ACTION_PUT: entry_log2( "put", "keyevent" ) ; in_received_put_key_event_handler(received); break; case ACTION_DELETE: entry_log( "delete", "keyevent" ) ; in_received_delete_key_event_handler(received); break; default: // not support. pebble_set_error_code(ERROR_NOT_SUPPORT_ACTION); break; } return RETURN_SYNC; }
int in_received_system_handler(DictionaryIterator *received, DictionaryIterator *iter) { DBG_LOG(APP_LOG_LEVEL_DEBUG, "in_received_system_handler"); Tuple *actionTuple = dict_find(received, KEY_ACTION); switch (actionTuple->value->uint8) { case ACTION_DELETE: in_received_delete_event_handler(received, iter); break; case ACTION_GET: case ACTION_POST: case ACTION_PUT: default: entry_log( "error", "system/events"); // not support. pebble_set_error_code(iter, ERROR_NOT_SUPPORT_ACTION); break; } return RETURN_SYNC; }
/*! @brief 加速度の値を取得するコールバック関数。 @param[in] data 加速度データ @param[in] num_samples サンプル数 */ static void in_event_accel_handler(AccelData *data, uint32_t num_samples) { if (outbox_wait_flag != 0) { int32_t t = get_current_time(); if (t - last_event_time > 1500) { outbox_wait_flag = 0; } else { return ; } } if (!mq_push()) { entry_log( "error", "in_event_accel_handler" ); return; } int32_t t = get_current_time(); int32_t interval = t - last_event_time; last_event_time = t; pebble_sniff_interval_normal(); mq_kv_set(KEY_ACTION, ACTION_EVENT); mq_kv_set(KEY_PROFILE, PROFILE_DEVICE_ORIENTATION); mq_kv_set(KEY_ATTRIBUTE, DEVICE_ORIENTATION_ATTRIBUTE_ON_DEVICE_ORIENTATION); mq_kv_set(KEY_PARAM_DEVICE_ORIENTATION_X, data->x); mq_kv_set(KEY_PARAM_DEVICE_ORIENTATION_Y, data->y); mq_kv_set(KEY_PARAM_DEVICE_ORIENTATION_Z, data->z); mq_kv_set(KEY_PARAM_DEVICE_ORIENTATION_INTERVAL, interval); counter_for_log ++ ; { char title[ 20 ] ; snprintf( title, sizeof( title), "accel %d",counter_for_log ) ; char buf[ 30 ] ; snprintf( buf, sizeof( buf), "X%d Y%d Z%d", data->x, data->y, data->z ) ; replace_last_log( title, buf) ; } send_message(); }
int in_received_device_orientation_handler(DictionaryIterator *received) { Tuple *actionTuple = dict_find(received, KEY_ACTION); switch (actionTuple->value->uint8) { case ACTION_PUT: entry_log2( "put", "orientation" ) ; counter_for_log = 0 ; last_event_time = get_current_time(); outbox_wait_flag = 0 ; in_received_put_device_orientation_handler(received); break; case ACTION_DELETE: entry_log( "delete", "orientation" ) ; in_received_delete_device_orientation_handler(received); break; default: // not support. pebble_set_error_code(ERROR_NOT_SUPPORT_ACTION); break; } return RETURN_SYNC; }
int in_received_battery_handler(DictionaryIterator *received) { DBG_LOG(APP_LOG_LEVEL_DEBUG, "in_received_battery_handler"); Tuple *actionTuple = dict_find(received, KEY_ACTION); switch (actionTuple->value->uint8) { case ACTION_GET: in_received_get_battery_handler(received); break; case ACTION_PUT: in_received_put_battery_handler(received); break; case ACTION_DELETE: in_received_delete_battery_handler(received); break; case ACTION_POST: default: entry_log( "battery ", "NOT_SUPPORT" ) ; // not support. pebble_set_error_code(ERROR_NOT_SUPPORT_ACTION); break; } return RETURN_SYNC; }