wangzhibo
4 天以前 ae6f40460dcd56af6c5f60ba52c883854c3bac55
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
/*  Copyright (C) 2019-2024 Andreas Shimokawa, Cre3per, Damien Gaignon
 
    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 <https://www.gnu.org/licenses/>. */
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;
}