/* Copyright (C) 2019-2021 Andreas Shimokawa, Cre3per This file is part of Gadgetbridge. Gadgetbridge is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gadgetbridge is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3; import java.util.UUID; public final class MakibesHR3Constants { public static final UUID UUID_SERVICE = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); public static final UUID UUID_CHARACTERISTIC_CONTROL = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e"); public static final UUID UUID_CHARACTERISTIC_REPORT = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e"); // Services and Characteristics // 00001801-0000-1000-8000-00805f9b34fb // 00002a05-0000-1000-8000-00805f9b34fb // 00001800-0000-1000-8000-00805f9b34fb // 00002a00-0000-1000-8000-00805f9b34fb // 00002a01-0000-1000-8000-00805f9b34fb // 00002a02-0000-1000-8000-00805f9b34fb // 00002a04-0000-1000-8000-00805f9b34fb // 00002aa6-0000-1000-8000-00805f9b34fb // 6e400001-b5a3-f393-e0a9-e50e24dcca9e // Nordic UART Service // 6e400002-b5a3-f393-e0a9-e50e24dcca9e // control (RX) // 6e400003-b5a3-f393-e0a9-e50e24dcca9e // report // 0000fee7-0000-1000-8000-00805f9b34fb // 0000fec9-0000-1000-8000-00805f9b34fb // 0000fea1-0000-1000-8000-00805f9b34fb // 0000fea2-0000-1000-8000-00805f9b34fb // Command structure // ab 00 [argument_count] ff [command] 80 [arguments] // where [argument_count] is [arguments].length + 3 // 80 might by different. public static final byte[] DATA_TEMPLATE = { (byte) 0xab, (byte) 0x00, (byte) 0, // argument_count (byte) 0xff, (byte) 0, // command (byte) 0x80 // ,arguments }; public static final int DATA_ARGUMENT_COUNT_INDEX = 2; public static final int DATA_COMMAND_INDEX = 4; public static final int DATA_ARGUMENTS_INDEX = 6; // blood oxygen percentage public static final byte[] RPRT_BLOOD_OXYGEN = new byte[]{ (byte) 0x31, (byte) 0x12 }; // blood oxygen percentage // blood oxygen percentage public static final byte[] RPRT_SINGLE_BLOOD_OXYGEN = new byte[]{ (byte) 0x31, (byte) 0x11 }; // steps might take up more bytes. I don't know which ones and I won't walk that much. // Only sent after we send CMD_51 // 00 (maybe also used for steps) // [steps hi] // [steps lo] // 00 // 00 // 01 (also was 0b. Maybe minutes of activity.) // 00 // 00 // 00 // 00 // 00 public static final byte[] RPRT_FITNESS = new byte[]{ (byte) 0x51, 0x08 }; // year (+2000) // month // day // hour // minute // heart rate // heart rate public static final byte[] RPRT_HEART_RATE_SAMPLE = new byte[]{ (byte) 0x51, (byte) 0x11 }; // WearFit says "walking" in the step details. This is probably also in here, but // I don't run :O // year (+2000) // month // day // hour (start of measurement. interval is 1h. Might be longer when running.) // 00 (either used for steps or minute) // accumulated steps (hi) // accumulated steps (lo) // 00 // 00 // ?? (changes whenever steps change. Ranges from 00 to 16.) // 00 // 00 // 00 // 00 public static final byte[] RPRT_STEPS_SAMPLE = new byte[]{ (byte) 0x51, (byte) 0x20 }; // enable (00/01) public static final byte RPRT_REVERSE_FIND_DEVICE = (byte) 0x7d; // The proximity sensor sees air.. public static final byte ARG_HEARTRATE_NO_TARGET = (byte) 0xff; // The hr sensor didn't find the heart rate yet. public static final byte ARG_HEARTRATE_NO_READING = (byte) 0x00; // heart rate public static final byte RPRT_HEARTRATE = (byte) 0x84; // charging (00/01) // battery percentage (step size is 20). public static final byte RPRT_BATTERY = (byte) 0x91; // firmware_major // firmware_minor // 37 // 00 // 00 // 00 // 00 // 00 // 00 // 20 // 0e public static final byte RPRT_SOFTWARE = (byte) 0x92; // 00 public static final byte CMD_FACTORY_RESET = (byte) 0x23; // enable (00/01) public static final byte[] CMD_SET_REAL_TIME_BLOOD_OXYGEN = new byte[]{ (byte) 0x31, (byte) 0x12 }; // After disabling, the watch replies with RPRT_SINGLE_BLOOD_OXYGEN // enable (00/01) public static final byte[] CMD_SET_SINGLE_BLOOD_OXYGEN = new byte[]{ (byte) 0x31, (byte) 0x11 }; // device replies with // {@link MakibesHR3Constants#RPRT_HEART_RATE_SAMPLE} // {@link MakibesHR3Constants#RPRT_STEPS_SAMPLE} (Only if steps are non-zero) // {@link MakibesHR3Constants#RPRT_FITNESS} // there are also multiple 6 * 00 reports // 00 // year (+2000) steps after // month steps after // day steps after // hour steps after // minute steps after // year (+2000) heart rate after // month heart rate after // day heart rate after // hour heart rate after // minute heart rate after public static final byte CMD_REQUEST_FITNESS = (byte) 0x51; // Manually sending this doesn't yield a reply. The heart rate history is sent in response to // CMD_CMD_REQUEST_FITNESS. // 00 // year (+2000) (probably not current) // month (not current!) // day (not current!) // hour (current) // minute (current) public static final byte CMD_52 = (byte) 0x52; // vibrates 6 times public static final byte CMD_FIND_DEVICE = (byte) 0x71; // WearFit writes uses other sources as well. They don't do anything though. public static final byte ARG_SEND_NOTIFICATION_SOURCE_CALL = (byte) 0x01; public static final byte ARG_SEND_NOTIFICATION_SOURCE_STOP_CALL = (byte) 0x02; public static final byte ARG_SEND_NOTIFICATION_SOURCE_MESSAGE = (byte) 0x03; public static final byte ARG_SEND_NOTIFICATION_SOURCE_QQ = (byte) 0x07; public static final byte ARG_SEND_NOTIFICATION_SOURCE_WECHAT = (byte) 0x09; public static final byte ARG_SEND_NOTIFICATION_SOURCE_WHATSAPP = (byte) 0x0a; public static final byte ARG_SEND_NOTIFICATION_SOURCE_LINE = (byte) 0x0e; public static final byte ARG_SEND_NOTIFICATION_SOURCE_TWITTER = (byte) 0x0f; public static final byte ARG_SEND_NOTIFICATION_SOURCE_FACEBOOK = (byte) 0x10; public static final byte ARG_SEND_NOTIFICATION_SOURCE_FACEBOOK2 = (byte) 0x11; public static final byte ARG_SEND_NOTIFICATION_SOURCE_WEIBO = (byte) 0x13; public static final byte ARG_SEND_NOTIFICATION_SOURCE_KAKOTALK = (byte) 0x14; // ARG_SET_NOTIFICATION_SOURCE_* // 02 (This is 00 and 01 during connection. Doesn't seem to do anything.) // ASCII public static final byte CMD_SEND_NOTIFICATION = (byte) 0x72; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_WEEKDAY = (byte) 0x1F; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_EVERY_DAY = (byte) 0x7F; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_ONE_TIME = (byte) 0x80; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_MONDAY = (byte) 0x01; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_TUESDAY = (byte) 0x02; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_WEDNESDAY = (byte) 0x04; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_THURSDAY = (byte) 0x08; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_FRIDAY = (byte) 0x10; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_SATURDAY = (byte) 0x20; public static final byte ARG_SET_ALARM_REMINDER_REPEAT_SUNDAY = (byte) 0x40; // reminder id starting at 0 // enable (00/01) // hour // minute // bit field of ARG_SET_ALARM_REMINDER_REPEAT_* public static final byte CMD_SET_ALARM_REMINDER = (byte) 0x73; public static final byte ARG_SET_PERSONAL_INFORMATION_UNIT_DISTANCE_MILES = (byte) 0x00; public static final byte ARG_SET_PERSONAL_INFORMATION_UNIT_DISTANCE_KILOMETERS = (byte) 0x01; // step length (in/cm) // step length (in/cm) // age (years) // height (in/cm) // weight (lb/kg) // ARG_SET_PERSONAL_INFORMATION_UNIT_DISTANCE_* // target step count (kilo) // 5a // 82 // 3c // 5a // 28 // b4 // 5d // 64 public static final byte CMD_SET_PERSONAL_INFORMATION = (byte) 0x74; // enable (00/01) // start hour // start minute // end hour // end minute // 2d public static final byte CMD_SET_SEDENTARY_REMINDER = (byte) 0x75; // enable (00/01) // start hour // start minute // end hour // end minute public static final byte CMD_SET_QUITE_HOURS = (byte) 0x76; // enable (00/01) public static final byte CMD_SET_HEADS_UP_SCREEN = (byte) 0x77; // Looks like enable/disable. public static final byte CMD_78 = (byte) 0x78; // The watch enters photograph mode, but doesn't appear to send a trigger signal. // enable (00/01) public static final byte CMD_SET_PHOTOGRAPH_MODE = (byte) 0x79; // enable (00/01) public static final byte CMD_SET_LOST_REMINDER = (byte) 0x7a; // 7b has 1 argument. Looks like enable/disable. public static final byte ARG_SET_TIMEMODE_24H = 0x00; public static final byte ARG_SET_TIMEMODE_12H = 0x01; // ARG_SET_TIMEMODE_* public static final byte CMD_SET_TIMEMODE = (byte) 0x7c; // 14 arguments. Watch might reply with RPRT_BATTERY. public static final byte CMD_7e = (byte) 0x7e; // 01 // fall hour // fall minute // awake hour // awake minute public static final byte CMD_SET_SLEEP_TIME = (byte) 0x7f; // enable (00/01) public static final byte CMD_SET_REAL_TIME_HEART_RATE = (byte) 0x84; // looks like enable/disable. public static final byte CMD_85 = (byte) 0x85; // 00 // year hi // year lo // month // day // hour // minute // second public static final byte CMD_SET_DATE_TIME = (byte) 0x93; // 3 arguments. Sent when saving personal information. public static final byte CMD_95 = (byte) 0x95; // looks like enable/disable. public static final byte CMD_96 = (byte) 0x96; // looks like enable/disable. public static final byte CMD_e5 = (byte) 0xe5; // If this is sent after {@link CMD_FACTORY_RESET}, it's a shutdown, not a reboot. // Rebooting resets the watch face and wallpaper. public static final byte CMD_REBOOT = (byte) 0xff; }