@v5x/serial 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -9
- package/dist/VexCRC.d.ts +0 -11
- package/dist/VexConnection.d.ts +30 -8
- package/dist/VexDevice.d.ts +11 -2
- package/dist/VexDeviceState.d.ts +23 -14
- package/dist/VexError.d.ts +4 -1
- package/dist/VexEvent.d.ts +15 -10
- package/dist/VexFirmware.d.ts +4 -2
- package/dist/VexFirmwareVersion.d.ts +4 -43
- package/dist/VexIniConfig.d.ts +0 -1
- package/dist/VexPacketBase.d.ts +5 -2
- package/dist/VexPacketEncoder.d.ts +11 -30
- package/dist/VexPacketModels.d.ts +0 -11
- package/dist/VexPacketView.d.ts +2 -0
- package/dist/index.cjs +680 -1046
- package/dist/index.cjs.map +16 -16
- package/dist/index.js +672 -1039
- package/dist/index.js.map +16 -16
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -19,12 +19,14 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
19
19
|
}
|
|
20
20
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
21
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
if (mod && typeof mod === "object" || typeof mod === "function") {
|
|
23
|
+
for (let key of __getOwnPropNames(mod))
|
|
24
|
+
if (!__hasOwnProp.call(to, key))
|
|
25
|
+
__defProp(to, key, {
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
27
|
+
enumerable: true
|
|
28
|
+
});
|
|
29
|
+
}
|
|
28
30
|
if (canCache)
|
|
29
31
|
cache.set(mod, to);
|
|
30
32
|
return to;
|
|
@@ -62,7 +64,7 @@ var __export = (target, all) => {
|
|
|
62
64
|
};
|
|
63
65
|
|
|
64
66
|
// ../../node_modules/.bun/neverthrow@8.2.0/node_modules/neverthrow/dist/index.cjs.js
|
|
65
|
-
var require_index_cjs = __commonJS((exports2)
|
|
67
|
+
var require_index_cjs = __commonJS(function(exports2) {
|
|
66
68
|
var defaultErrorConfig = {
|
|
67
69
|
withStackTrace: false
|
|
68
70
|
};
|
|
@@ -850,6 +852,7 @@ var SelectDashScreen;
|
|
|
850
852
|
// src/VexError.ts
|
|
851
853
|
class VexSerialError extends Error {
|
|
852
854
|
kind;
|
|
855
|
+
ackType = undefined;
|
|
853
856
|
constructor(kind, message) {
|
|
854
857
|
super(message);
|
|
855
858
|
this.name = "VexSerialError";
|
|
@@ -872,9 +875,11 @@ class VexInvalidArgumentError extends VexSerialError {
|
|
|
872
875
|
}
|
|
873
876
|
|
|
874
877
|
class VexProtocolError extends VexSerialError {
|
|
875
|
-
|
|
878
|
+
ackType;
|
|
879
|
+
constructor(message, ackType) {
|
|
876
880
|
super("protocol", message);
|
|
877
881
|
this.name = "VexProtocolError";
|
|
882
|
+
this.ackType = ackType;
|
|
878
883
|
}
|
|
879
884
|
}
|
|
880
885
|
|
|
@@ -934,9 +939,19 @@ class VexEventEmitter {
|
|
|
934
939
|
this.handlerMap.set(eventName, listeners);
|
|
935
940
|
}
|
|
936
941
|
emit(eventName, data) {
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
942
|
+
const errors = [];
|
|
943
|
+
for (const callback of [...this.handlerMap.get(eventName) ?? []]) {
|
|
944
|
+
try {
|
|
945
|
+
callback(data);
|
|
946
|
+
} catch (error) {
|
|
947
|
+
errors.push(error);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
if (errors.length === 1)
|
|
951
|
+
throw errors[0];
|
|
952
|
+
if (errors.length > 1) {
|
|
953
|
+
throw new AggregateError(errors, `listeners for ${String(eventName)} failed`);
|
|
954
|
+
}
|
|
940
955
|
}
|
|
941
956
|
clearListeners() {
|
|
942
957
|
this.handlerMap.clear();
|
|
@@ -949,17 +964,20 @@ class VexEventTarget {
|
|
|
949
964
|
this.emitter = new VexEventEmitter;
|
|
950
965
|
}
|
|
951
966
|
emit(eventName, data) {
|
|
952
|
-
this.emitter.emit(
|
|
967
|
+
this.emitter.emit(this.normalizeEventName(eventName), data);
|
|
953
968
|
}
|
|
954
969
|
on(eventName, listener) {
|
|
955
|
-
this.emitter.on(
|
|
970
|
+
this.emitter.on(this.normalizeEventName(eventName), listener);
|
|
956
971
|
}
|
|
957
972
|
remove(eventName, listener) {
|
|
958
|
-
this.emitter.remove(
|
|
973
|
+
this.emitter.remove(this.normalizeEventName(eventName), listener);
|
|
959
974
|
}
|
|
960
975
|
clearListeners() {
|
|
961
976
|
this.emitter.clearListeners();
|
|
962
977
|
}
|
|
978
|
+
normalizeEventName(eventName) {
|
|
979
|
+
return String(eventName);
|
|
980
|
+
}
|
|
963
981
|
}
|
|
964
982
|
|
|
965
983
|
// src/VexConnection.ts
|
|
@@ -977,42 +995,32 @@ class Packet {
|
|
|
977
995
|
}
|
|
978
996
|
|
|
979
997
|
class DeviceBoundPacket extends Packet {
|
|
998
|
+
static COMMAND_ID;
|
|
999
|
+
static COMMAND_EXTENDED_ID;
|
|
980
1000
|
get commandId() {
|
|
981
1001
|
return this.constructor.COMMAND_ID;
|
|
982
1002
|
}
|
|
983
1003
|
get commandExtendedId() {
|
|
984
1004
|
return this.constructor.COMMAND_EXTENDED_ID;
|
|
985
1005
|
}
|
|
986
|
-
static COMMAND_ID;
|
|
987
|
-
static COMMAND_EXTENDED_ID;
|
|
988
1006
|
constructor(payload) {
|
|
989
|
-
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
if (payload === undefined) {
|
|
993
|
-
this.data = Packet.ENCODER.cdcCommand(me.COMMAND_ID);
|
|
994
|
-
} else {
|
|
995
|
-
this.data = Packet.ENCODER.cdcCommandWithData(me.COMMAND_ID, payload);
|
|
996
|
-
}
|
|
997
|
-
} else {
|
|
998
|
-
if (payload === undefined) {
|
|
999
|
-
this.data = Packet.ENCODER.cdc2Command(me.COMMAND_ID, me.COMMAND_EXTENDED_ID);
|
|
1000
|
-
} else {
|
|
1001
|
-
this.data = Packet.ENCODER.cdc2CommandWithData(me.COMMAND_ID, me.COMMAND_EXTENDED_ID, payload);
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1007
|
+
const { COMMAND_ID: cmd, COMMAND_EXTENDED_ID: ext } = new.target;
|
|
1008
|
+
const encoder = Packet.ENCODER;
|
|
1009
|
+
super(ext === undefined ? payload === undefined ? encoder.cdcCommand(cmd) : encoder.cdcCommandWithData(cmd, payload) : payload === undefined ? encoder.cdc2Command(cmd, ext) : encoder.cdc2CommandWithData(cmd, ext, payload));
|
|
1004
1010
|
}
|
|
1005
1011
|
}
|
|
1006
1012
|
|
|
1007
1013
|
class HostBoundPacket extends Packet {
|
|
1008
|
-
|
|
1014
|
+
static COMMAND_ID;
|
|
1015
|
+
static COMMAND_EXTENDED_ID;
|
|
1016
|
+
ack;
|
|
1009
1017
|
payloadSize;
|
|
1010
1018
|
ackIndex;
|
|
1011
1019
|
constructor(data) {
|
|
1012
1020
|
super(data);
|
|
1013
1021
|
this.payloadSize = Packet.ENCODER.getPayloadSize(this.data);
|
|
1014
|
-
|
|
1015
|
-
this.ack = this.data[this.ackIndex
|
|
1022
|
+
this.ackIndex = Packet.ENCODER.getHostHeaderLength(this.data) + 1;
|
|
1023
|
+
this.ack = this.data[this.ackIndex];
|
|
1016
1024
|
}
|
|
1017
1025
|
static isValidPacket(data, n) {
|
|
1018
1026
|
const ack = data[n + 1];
|
|
@@ -1021,309 +1029,50 @@ class HostBoundPacket extends Packet {
|
|
|
1021
1029
|
}
|
|
1022
1030
|
|
|
1023
1031
|
// src/VexCRC.ts
|
|
1024
|
-
var
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
33560,
|
|
1051
|
-
45947,
|
|
1052
|
-
41818,
|
|
1053
|
-
54205,
|
|
1054
|
-
50076,
|
|
1055
|
-
62463,
|
|
1056
|
-
58334,
|
|
1057
|
-
9314,
|
|
1058
|
-
13379,
|
|
1059
|
-
1056,
|
|
1060
|
-
5121,
|
|
1061
|
-
25830,
|
|
1062
|
-
29895,
|
|
1063
|
-
17572,
|
|
1064
|
-
21637,
|
|
1065
|
-
42346,
|
|
1066
|
-
46411,
|
|
1067
|
-
34088,
|
|
1068
|
-
38153,
|
|
1069
|
-
58862,
|
|
1070
|
-
62927,
|
|
1071
|
-
50604,
|
|
1072
|
-
54669,
|
|
1073
|
-
13907,
|
|
1074
|
-
9842,
|
|
1075
|
-
5649,
|
|
1076
|
-
1584,
|
|
1077
|
-
30423,
|
|
1078
|
-
26358,
|
|
1079
|
-
22165,
|
|
1080
|
-
18100,
|
|
1081
|
-
46939,
|
|
1082
|
-
42874,
|
|
1083
|
-
38681,
|
|
1084
|
-
34616,
|
|
1085
|
-
63455,
|
|
1086
|
-
59390,
|
|
1087
|
-
55197,
|
|
1088
|
-
51132,
|
|
1089
|
-
18628,
|
|
1090
|
-
22757,
|
|
1091
|
-
26758,
|
|
1092
|
-
30887,
|
|
1093
|
-
2112,
|
|
1094
|
-
6241,
|
|
1095
|
-
10242,
|
|
1096
|
-
14371,
|
|
1097
|
-
51660,
|
|
1098
|
-
55789,
|
|
1099
|
-
59790,
|
|
1100
|
-
63919,
|
|
1101
|
-
35144,
|
|
1102
|
-
39273,
|
|
1103
|
-
43274,
|
|
1104
|
-
47403,
|
|
1105
|
-
23285,
|
|
1106
|
-
19156,
|
|
1107
|
-
31415,
|
|
1108
|
-
27286,
|
|
1109
|
-
6769,
|
|
1110
|
-
2640,
|
|
1111
|
-
14899,
|
|
1112
|
-
10770,
|
|
1113
|
-
56317,
|
|
1114
|
-
52188,
|
|
1115
|
-
64447,
|
|
1116
|
-
60318,
|
|
1117
|
-
39801,
|
|
1118
|
-
35672,
|
|
1119
|
-
47931,
|
|
1120
|
-
43802,
|
|
1121
|
-
27814,
|
|
1122
|
-
31879,
|
|
1123
|
-
19684,
|
|
1124
|
-
23749,
|
|
1125
|
-
11298,
|
|
1126
|
-
15363,
|
|
1127
|
-
3168,
|
|
1128
|
-
7233,
|
|
1129
|
-
60846,
|
|
1130
|
-
64911,
|
|
1131
|
-
52716,
|
|
1132
|
-
56781,
|
|
1133
|
-
44330,
|
|
1134
|
-
48395,
|
|
1135
|
-
36200,
|
|
1136
|
-
40265,
|
|
1137
|
-
32407,
|
|
1138
|
-
28342,
|
|
1139
|
-
24277,
|
|
1140
|
-
20212,
|
|
1141
|
-
15891,
|
|
1142
|
-
11826,
|
|
1143
|
-
7761,
|
|
1144
|
-
3696,
|
|
1145
|
-
65439,
|
|
1146
|
-
61374,
|
|
1147
|
-
57309,
|
|
1148
|
-
53244,
|
|
1149
|
-
48923,
|
|
1150
|
-
44858,
|
|
1151
|
-
40793,
|
|
1152
|
-
36728,
|
|
1153
|
-
37256,
|
|
1154
|
-
33193,
|
|
1155
|
-
45514,
|
|
1156
|
-
41451,
|
|
1157
|
-
53516,
|
|
1158
|
-
49453,
|
|
1159
|
-
61774,
|
|
1160
|
-
57711,
|
|
1161
|
-
4224,
|
|
1162
|
-
161,
|
|
1163
|
-
12482,
|
|
1164
|
-
8419,
|
|
1165
|
-
20484,
|
|
1166
|
-
16421,
|
|
1167
|
-
28742,
|
|
1168
|
-
24679,
|
|
1169
|
-
33721,
|
|
1170
|
-
37784,
|
|
1171
|
-
41979,
|
|
1172
|
-
46042,
|
|
1173
|
-
49981,
|
|
1174
|
-
54044,
|
|
1175
|
-
58239,
|
|
1176
|
-
62302,
|
|
1177
|
-
689,
|
|
1178
|
-
4752,
|
|
1179
|
-
8947,
|
|
1180
|
-
13010,
|
|
1181
|
-
16949,
|
|
1182
|
-
21012,
|
|
1183
|
-
25207,
|
|
1184
|
-
29270,
|
|
1185
|
-
46570,
|
|
1186
|
-
42443,
|
|
1187
|
-
38312,
|
|
1188
|
-
34185,
|
|
1189
|
-
62830,
|
|
1190
|
-
58703,
|
|
1191
|
-
54572,
|
|
1192
|
-
50445,
|
|
1193
|
-
13538,
|
|
1194
|
-
9411,
|
|
1195
|
-
5280,
|
|
1196
|
-
1153,
|
|
1197
|
-
29798,
|
|
1198
|
-
25671,
|
|
1199
|
-
21540,
|
|
1200
|
-
17413,
|
|
1201
|
-
42971,
|
|
1202
|
-
47098,
|
|
1203
|
-
34713,
|
|
1204
|
-
38840,
|
|
1205
|
-
59231,
|
|
1206
|
-
63358,
|
|
1207
|
-
50973,
|
|
1208
|
-
55100,
|
|
1209
|
-
9939,
|
|
1210
|
-
14066,
|
|
1211
|
-
1681,
|
|
1212
|
-
5808,
|
|
1213
|
-
26199,
|
|
1214
|
-
30326,
|
|
1215
|
-
17941,
|
|
1216
|
-
22068,
|
|
1217
|
-
55628,
|
|
1218
|
-
51565,
|
|
1219
|
-
63758,
|
|
1220
|
-
59695,
|
|
1221
|
-
39368,
|
|
1222
|
-
35305,
|
|
1223
|
-
47498,
|
|
1224
|
-
43435,
|
|
1225
|
-
22596,
|
|
1226
|
-
18533,
|
|
1227
|
-
30726,
|
|
1228
|
-
26663,
|
|
1229
|
-
6336,
|
|
1230
|
-
2273,
|
|
1231
|
-
14466,
|
|
1232
|
-
10403,
|
|
1233
|
-
52093,
|
|
1234
|
-
56156,
|
|
1235
|
-
60223,
|
|
1236
|
-
64286,
|
|
1237
|
-
35833,
|
|
1238
|
-
39896,
|
|
1239
|
-
43963,
|
|
1240
|
-
48026,
|
|
1241
|
-
19061,
|
|
1242
|
-
23124,
|
|
1243
|
-
27191,
|
|
1244
|
-
31254,
|
|
1245
|
-
2801,
|
|
1246
|
-
6864,
|
|
1247
|
-
10931,
|
|
1248
|
-
14994,
|
|
1249
|
-
64814,
|
|
1250
|
-
60687,
|
|
1251
|
-
56684,
|
|
1252
|
-
52557,
|
|
1253
|
-
48554,
|
|
1254
|
-
44427,
|
|
1255
|
-
40424,
|
|
1256
|
-
36297,
|
|
1257
|
-
31782,
|
|
1258
|
-
27655,
|
|
1259
|
-
23652,
|
|
1260
|
-
19525,
|
|
1261
|
-
15522,
|
|
1262
|
-
11395,
|
|
1263
|
-
7392,
|
|
1264
|
-
3265,
|
|
1265
|
-
61215,
|
|
1266
|
-
65342,
|
|
1267
|
-
53085,
|
|
1268
|
-
57212,
|
|
1269
|
-
44955,
|
|
1270
|
-
49082,
|
|
1271
|
-
36825,
|
|
1272
|
-
40952,
|
|
1273
|
-
28183,
|
|
1274
|
-
32310,
|
|
1275
|
-
20053,
|
|
1276
|
-
24180,
|
|
1277
|
-
11923,
|
|
1278
|
-
16050,
|
|
1279
|
-
3793,
|
|
1280
|
-
7920
|
|
1281
|
-
];
|
|
1032
|
+
var POLYNOMIAL_CRC32 = 79764919;
|
|
1033
|
+
var POLYNOMIAL_CRC16 = 4129;
|
|
1034
|
+
function genTable16() {
|
|
1035
|
+
const table = new Uint16Array(256);
|
|
1036
|
+
for (let i = 0;i < 256; i++) {
|
|
1037
|
+
let acc = i << 8;
|
|
1038
|
+
for (let j = 0;j < 8; j++) {
|
|
1039
|
+
acc = (acc & 32768) !== 0 ? acc << 1 ^ POLYNOMIAL_CRC16 : acc << 1;
|
|
1040
|
+
}
|
|
1041
|
+
table[i] = acc & 65535;
|
|
1042
|
+
}
|
|
1043
|
+
return table;
|
|
1044
|
+
}
|
|
1045
|
+
function genTable32() {
|
|
1046
|
+
const table = new Uint32Array(256);
|
|
1047
|
+
for (let i = 0;i < 256; i++) {
|
|
1048
|
+
let acc = i << 24;
|
|
1049
|
+
for (let j = 0;j < 8; j++) {
|
|
1050
|
+
acc = (acc & 2147483648) !== 0 ? acc << 1 ^ POLYNOMIAL_CRC32 : acc << 1;
|
|
1051
|
+
}
|
|
1052
|
+
table[i] = acc;
|
|
1053
|
+
}
|
|
1054
|
+
return table;
|
|
1055
|
+
}
|
|
1056
|
+
var CRC16_TABLE = genTable16();
|
|
1057
|
+
var CRC32_TABLE = genTable32();
|
|
1282
1058
|
|
|
1283
1059
|
class CrcGenerator {
|
|
1284
|
-
crc32Table;
|
|
1285
|
-
static POLYNOMIAL_CRC32 =
|
|
1286
|
-
static POLYNOMIAL_CRC16 =
|
|
1287
|
-
constructor() {
|
|
1288
|
-
this.crc32Table = new Uint32Array(256);
|
|
1289
|
-
this.crc32GenTable();
|
|
1290
|
-
}
|
|
1060
|
+
crc32Table = CRC32_TABLE;
|
|
1061
|
+
static POLYNOMIAL_CRC32 = POLYNOMIAL_CRC32;
|
|
1062
|
+
static POLYNOMIAL_CRC16 = POLYNOMIAL_CRC16;
|
|
1291
1063
|
crc16(buf, initValue) {
|
|
1292
|
-
|
|
1293
|
-
let
|
|
1294
|
-
|
|
1295
|
-
let j;
|
|
1296
|
-
for (j = 0;j < numberOfBytes; j++) {
|
|
1297
|
-
i = (accumulator >>> 8 ^ buf[j]) & 255;
|
|
1298
|
-
accumulator = (accumulator << 8 ^ CRC16TABLE[i]) >>> 0;
|
|
1299
|
-
}
|
|
1300
|
-
return (accumulator & 65535) >>> 0;
|
|
1301
|
-
}
|
|
1302
|
-
crc32GenTable() {
|
|
1303
|
-
let i;
|
|
1304
|
-
let j;
|
|
1305
|
-
let crcAccumulator;
|
|
1306
|
-
for (i = 0;i < 256; i++) {
|
|
1307
|
-
crcAccumulator = i << 24;
|
|
1308
|
-
for (j = 0;j < 8; j++) {
|
|
1309
|
-
if ((crcAccumulator & 2147483648) !== 0)
|
|
1310
|
-
crcAccumulator = crcAccumulator << 1 ^ CrcGenerator.POLYNOMIAL_CRC32;
|
|
1311
|
-
else
|
|
1312
|
-
crcAccumulator = crcAccumulator << 1;
|
|
1313
|
-
}
|
|
1314
|
-
this.crc32Table[i] = crcAccumulator;
|
|
1064
|
+
let acc = initValue;
|
|
1065
|
+
for (let j = 0;j < buf.length; j++) {
|
|
1066
|
+
acc = (acc << 8 ^ CRC16_TABLE[(acc >>> 8 ^ buf[j]) & 255]) >>> 0;
|
|
1315
1067
|
}
|
|
1068
|
+
return acc & 65535;
|
|
1316
1069
|
}
|
|
1317
1070
|
crc32(buf, initValue) {
|
|
1318
|
-
|
|
1319
|
-
let
|
|
1320
|
-
|
|
1321
|
-
let j;
|
|
1322
|
-
for (j = 0;j < numberOfBytes; j++) {
|
|
1323
|
-
i = (crcAccumulator >>> 24 ^ buf[j]) & 255;
|
|
1324
|
-
crcAccumulator = (crcAccumulator << 8 ^ this.crc32Table[i]) >>> 0;
|
|
1071
|
+
let acc = initValue;
|
|
1072
|
+
for (let j = 0;j < buf.length; j++) {
|
|
1073
|
+
acc = (acc << 8 ^ CRC32_TABLE[(acc >>> 24 ^ buf[j]) & 255]) >>> 0;
|
|
1325
1074
|
}
|
|
1326
|
-
return
|
|
1075
|
+
return acc >>> 0;
|
|
1327
1076
|
}
|
|
1328
1077
|
}
|
|
1329
1078
|
|
|
@@ -1415,9 +1164,8 @@ class VexFirmwareVersion {
|
|
|
1415
1164
|
}
|
|
1416
1165
|
static fromString(version) {
|
|
1417
1166
|
const parts = version.toLowerCase().replace(/b/g, "").split(".").map((x) => parseInt(x, 10));
|
|
1418
|
-
while (parts.length < 4)
|
|
1167
|
+
while (parts.length < 4)
|
|
1419
1168
|
parts.push(0);
|
|
1420
|
-
}
|
|
1421
1169
|
return new VexFirmwareVersion(parts[0], parts[1], parts[2], parts[3]);
|
|
1422
1170
|
}
|
|
1423
1171
|
static fromUint8Array(data, offset = 0, reverse = false) {
|
|
@@ -1447,24 +1195,23 @@ class VexFirmwareVersion {
|
|
|
1447
1195
|
return `${this.toUserString()}.b${this.beta}`;
|
|
1448
1196
|
}
|
|
1449
1197
|
compare(that) {
|
|
1450
|
-
const
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
return buildComp;
|
|
1460
|
-
} else if (betaComp !== 0) {
|
|
1461
|
-
return betaComp;
|
|
1198
|
+
for (const [a, b] of [
|
|
1199
|
+
[this.major, that.major],
|
|
1200
|
+
[this.minor, that.minor],
|
|
1201
|
+
[this.build, that.build],
|
|
1202
|
+
[this.beta, that.beta]
|
|
1203
|
+
]) {
|
|
1204
|
+
const delta = a - b;
|
|
1205
|
+
if (delta !== 0)
|
|
1206
|
+
return delta;
|
|
1462
1207
|
}
|
|
1463
1208
|
return 0;
|
|
1464
1209
|
}
|
|
1465
1210
|
}
|
|
1466
1211
|
|
|
1467
1212
|
// src/VexPacketView.ts
|
|
1213
|
+
var textDecoder = new TextDecoder("UTF-8");
|
|
1214
|
+
|
|
1468
1215
|
class PacketView extends DataView {
|
|
1469
1216
|
position = 0;
|
|
1470
1217
|
littleEndianDefault = true;
|
|
@@ -1477,14 +1224,10 @@ class PacketView extends DataView {
|
|
|
1477
1224
|
return view;
|
|
1478
1225
|
}
|
|
1479
1226
|
nextInt8() {
|
|
1480
|
-
|
|
1481
|
-
this.position += 1;
|
|
1482
|
-
return result;
|
|
1227
|
+
return this.getInt8(this.position++);
|
|
1483
1228
|
}
|
|
1484
1229
|
nextUint8() {
|
|
1485
|
-
|
|
1486
|
-
this.position += 1;
|
|
1487
|
-
return result;
|
|
1230
|
+
return this.getUint8(this.position++);
|
|
1488
1231
|
}
|
|
1489
1232
|
nextInt16(littleEndian = this.littleEndianDefault) {
|
|
1490
1233
|
const result = this.getInt16(this.position, littleEndian);
|
|
@@ -1507,37 +1250,28 @@ class PacketView extends DataView {
|
|
|
1507
1250
|
return result;
|
|
1508
1251
|
}
|
|
1509
1252
|
nextString(length) {
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
result += String.fromCharCode(this.nextUint8());
|
|
1513
|
-
}
|
|
1253
|
+
const result = textDecoder.decode(new Uint8Array(this.buffer, this.byteOffset + this.position, length));
|
|
1254
|
+
this.position += length;
|
|
1514
1255
|
return result;
|
|
1515
1256
|
}
|
|
1516
1257
|
nextNTBS(length) {
|
|
1517
|
-
|
|
1518
|
-
const
|
|
1519
|
-
|
|
1520
|
-
if (this.byteLength <= this.position)
|
|
1521
|
-
break;
|
|
1522
|
-
const g = this.nextUint8();
|
|
1523
|
-
if (g === 0)
|
|
1524
|
-
break;
|
|
1525
|
-
result += String.fromCharCode(g);
|
|
1526
|
-
}
|
|
1527
|
-
this.position = lastPosition + length;
|
|
1258
|
+
const start = this.position;
|
|
1259
|
+
const result = this.nextVarNTBS(length);
|
|
1260
|
+
this.position = start + length;
|
|
1528
1261
|
return result;
|
|
1529
1262
|
}
|
|
1530
1263
|
nextVarNTBS(length) {
|
|
1531
|
-
|
|
1264
|
+
const start = this.position;
|
|
1265
|
+
let byteLength = 0;
|
|
1532
1266
|
for (let i = 0;i < length; i++) {
|
|
1533
1267
|
if (this.byteLength <= this.position)
|
|
1534
1268
|
break;
|
|
1535
1269
|
const g = this.nextUint8();
|
|
1536
1270
|
if (g === 0)
|
|
1537
1271
|
break;
|
|
1538
|
-
|
|
1272
|
+
byteLength++;
|
|
1539
1273
|
}
|
|
1540
|
-
return
|
|
1274
|
+
return textDecoder.decode(new Uint8Array(this.buffer, this.byteOffset + start, byteLength));
|
|
1541
1275
|
}
|
|
1542
1276
|
nextVersion(reverse = false) {
|
|
1543
1277
|
const result = VexFirmwareVersion.fromUint8Array(new Uint8Array(this.buffer, this.byteOffset, this.byteLength), this.position, reverse);
|
|
@@ -1548,42 +1282,33 @@ class PacketView extends DataView {
|
|
|
1548
1282
|
|
|
1549
1283
|
// src/VexPacketModels.ts
|
|
1550
1284
|
var textEncoder = new TextEncoder;
|
|
1285
|
+
function filePayload(a, b, fileName) {
|
|
1286
|
+
const payload = new Uint8Array(26);
|
|
1287
|
+
payload[0] = a;
|
|
1288
|
+
payload[1] = b;
|
|
1289
|
+
payload.set(encodeFixedText(fileName, "Filename", 23), 2);
|
|
1290
|
+
return payload;
|
|
1291
|
+
}
|
|
1292
|
+
var clamp100 = (value) => value !== undefined && value > 100 ? 100 : value;
|
|
1551
1293
|
|
|
1552
1294
|
class Query1H2DPacket extends DeviceBoundPacket {
|
|
1553
1295
|
static COMMAND_ID = 33;
|
|
1554
1296
|
static COMMAND_EXTENDED_ID = undefined;
|
|
1555
|
-
constructor() {
|
|
1556
|
-
super(undefined);
|
|
1557
|
-
}
|
|
1558
1297
|
}
|
|
1559
1298
|
|
|
1560
1299
|
class SystemVersionH2DPacket extends DeviceBoundPacket {
|
|
1561
1300
|
static COMMAND_ID = 164;
|
|
1562
1301
|
static COMMAND_EXTENDED_ID = undefined;
|
|
1563
|
-
constructor() {
|
|
1564
|
-
super(undefined);
|
|
1565
|
-
}
|
|
1566
1302
|
}
|
|
1567
1303
|
|
|
1568
1304
|
class UpdateMatchModeH2DPacket extends DeviceBoundPacket {
|
|
1569
1305
|
static COMMAND_ID = 88;
|
|
1570
1306
|
static COMMAND_EXTENDED_ID = 193;
|
|
1571
1307
|
constructor(mode, matchClock) {
|
|
1572
|
-
|
|
1573
|
-
switch (mode) {
|
|
1574
|
-
case "autonomous":
|
|
1575
|
-
bit1 = 10;
|
|
1576
|
-
break;
|
|
1577
|
-
case "driver":
|
|
1578
|
-
bit1 = 8;
|
|
1579
|
-
break;
|
|
1580
|
-
case "disabled":
|
|
1581
|
-
bit1 = 11;
|
|
1582
|
-
}
|
|
1308
|
+
const bit1 = mode === "autonomous" ? 10 : mode === "driver" ? 8 : 11;
|
|
1583
1309
|
const payload = new Uint8Array(5);
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
view.setUint32(1, matchClock, true);
|
|
1310
|
+
payload[0] = bit1 & 15;
|
|
1311
|
+
new DataView(payload.buffer).setUint32(1, matchClock, true);
|
|
1587
1312
|
super(payload);
|
|
1588
1313
|
}
|
|
1589
1314
|
}
|
|
@@ -1591,18 +1316,13 @@ class UpdateMatchModeH2DPacket extends DeviceBoundPacket {
|
|
|
1591
1316
|
class GetMatchStatusH2DPacket extends DeviceBoundPacket {
|
|
1592
1317
|
static COMMAND_ID = 88;
|
|
1593
1318
|
static COMMAND_EXTENDED_ID = 194;
|
|
1594
|
-
constructor() {
|
|
1595
|
-
super(undefined);
|
|
1596
|
-
}
|
|
1597
1319
|
}
|
|
1598
1320
|
|
|
1599
1321
|
class GetRadioModeH2DPacket extends DeviceBoundPacket {
|
|
1600
1322
|
static COMMAND_ID = 88;
|
|
1601
1323
|
static COMMAND_EXTENDED_ID = 65;
|
|
1602
1324
|
constructor(mode) {
|
|
1603
|
-
|
|
1604
|
-
payload[0] = mode;
|
|
1605
|
-
super(payload);
|
|
1325
|
+
super(Uint8Array.of(mode));
|
|
1606
1326
|
}
|
|
1607
1327
|
}
|
|
1608
1328
|
|
|
@@ -1610,9 +1330,7 @@ class FileControlH2DPacket extends DeviceBoundPacket {
|
|
|
1610
1330
|
static COMMAND_ID = 86;
|
|
1611
1331
|
static COMMAND_EXTENDED_ID = 16;
|
|
1612
1332
|
constructor(a, b) {
|
|
1613
|
-
|
|
1614
|
-
payload.set([a, b], 0);
|
|
1615
|
-
super(payload);
|
|
1333
|
+
super(Uint8Array.of(a, b));
|
|
1616
1334
|
}
|
|
1617
1335
|
}
|
|
1618
1336
|
|
|
@@ -1622,25 +1340,21 @@ class InitFileTransferH2DPacket extends DeviceBoundPacket {
|
|
|
1622
1340
|
constructor(operation, target, vendor, options, binary, addr, name, type, version = new VexFirmwareVersion(1, 0, 0, 0)) {
|
|
1623
1341
|
const payload = new Uint8Array(52);
|
|
1624
1342
|
const view = new DataView(payload.buffer);
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1343
|
+
payload[0] = operation;
|
|
1344
|
+
payload[1] = target;
|
|
1345
|
+
payload[2] = vendor;
|
|
1346
|
+
payload[3] = options;
|
|
1629
1347
|
view.setUint32(4, binary.length, true);
|
|
1630
1348
|
view.setUint32(8, addr, true);
|
|
1631
1349
|
view.setUint32(12, operation === 1 /* WRITE */ ? Packet.ENCODER.crcgen.crc32(binary, 0) : 0, true);
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
ext ??= "";
|
|
1636
|
-
ext = ext === "gz" ? "bin" : ext;
|
|
1350
|
+
let ext = /(?:\.([^.]+))?$/.exec(name)?.[1] ?? "";
|
|
1351
|
+
if (ext === "gz")
|
|
1352
|
+
ext = "bin";
|
|
1637
1353
|
payload.set(encodeFixedText(type ?? ext, "File type", 4), 16);
|
|
1638
1354
|
const timestamp = (Date.now() / 1000 >>> 0) - PacketEncoder.J2000_EPOCH;
|
|
1639
1355
|
view.setUint32(20, timestamp, true);
|
|
1640
1356
|
payload.set(version.toUint8Array(), 24);
|
|
1641
|
-
|
|
1642
|
-
payload.set(nameEncoded, 28);
|
|
1643
|
-
view.setUint8(51, 0);
|
|
1357
|
+
payload.set(encodeFixedText(name, "Filename", 23), 28);
|
|
1644
1358
|
super(payload);
|
|
1645
1359
|
}
|
|
1646
1360
|
}
|
|
@@ -1649,9 +1363,7 @@ class ExitFileTransferH2DPacket extends DeviceBoundPacket {
|
|
|
1649
1363
|
static COMMAND_ID = 86;
|
|
1650
1364
|
static COMMAND_EXTENDED_ID = 18;
|
|
1651
1365
|
constructor(action) {
|
|
1652
|
-
|
|
1653
|
-
payload[0] = action;
|
|
1654
|
-
super(payload);
|
|
1366
|
+
super(Uint8Array.of(action));
|
|
1655
1367
|
}
|
|
1656
1368
|
}
|
|
1657
1369
|
|
|
@@ -1660,8 +1372,7 @@ class WriteFileH2DPacket extends DeviceBoundPacket {
|
|
|
1660
1372
|
static COMMAND_EXTENDED_ID = 19;
|
|
1661
1373
|
constructor(addr, buf) {
|
|
1662
1374
|
const payload = new Uint8Array(4 + buf.length);
|
|
1663
|
-
|
|
1664
|
-
view.setUint32(0, addr, true);
|
|
1375
|
+
new DataView(payload.buffer).setUint32(0, addr, true);
|
|
1665
1376
|
payload.set(buf, 4);
|
|
1666
1377
|
super(payload);
|
|
1667
1378
|
}
|
|
@@ -1683,11 +1394,7 @@ class LinkFileH2DPacket extends DeviceBoundPacket {
|
|
|
1683
1394
|
static COMMAND_ID = 86;
|
|
1684
1395
|
static COMMAND_EXTENDED_ID = 21;
|
|
1685
1396
|
constructor(vendor, fileName, options) {
|
|
1686
|
-
|
|
1687
|
-
const payload = new Uint8Array(26);
|
|
1688
|
-
payload.set([vendor, options], 0);
|
|
1689
|
-
payload.set(str, 2);
|
|
1690
|
-
super(payload);
|
|
1397
|
+
super(filePayload(vendor, options, fileName));
|
|
1691
1398
|
}
|
|
1692
1399
|
}
|
|
1693
1400
|
|
|
@@ -1695,9 +1402,7 @@ class GetDirectoryFileCountH2DPacket extends DeviceBoundPacket {
|
|
|
1695
1402
|
static COMMAND_ID = 86;
|
|
1696
1403
|
static COMMAND_EXTENDED_ID = 22;
|
|
1697
1404
|
constructor(vendor) {
|
|
1698
|
-
|
|
1699
|
-
payload.set([vendor, 0], 0);
|
|
1700
|
-
super(payload);
|
|
1405
|
+
super(Uint8Array.of(vendor, 0));
|
|
1701
1406
|
}
|
|
1702
1407
|
}
|
|
1703
1408
|
|
|
@@ -1705,9 +1410,7 @@ class GetDirectoryEntryH2DPacket extends DeviceBoundPacket {
|
|
|
1705
1410
|
static COMMAND_ID = 86;
|
|
1706
1411
|
static COMMAND_EXTENDED_ID = 23;
|
|
1707
1412
|
constructor(index) {
|
|
1708
|
-
|
|
1709
|
-
payload.set([index, 0], 0);
|
|
1710
|
-
super(payload);
|
|
1413
|
+
super(Uint8Array.of(index, 0));
|
|
1711
1414
|
}
|
|
1712
1415
|
}
|
|
1713
1416
|
|
|
@@ -1715,17 +1418,8 @@ class LoadFileActionH2DPacket extends DeviceBoundPacket {
|
|
|
1715
1418
|
static COMMAND_ID = 86;
|
|
1716
1419
|
static COMMAND_EXTENDED_ID = 24;
|
|
1717
1420
|
constructor(vendor, actionId, fileNameOrSlotNumber) {
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
fileName = fileNameOrSlotNumber;
|
|
1721
|
-
} else {
|
|
1722
|
-
fileName = "___s_" + (fileNameOrSlotNumber - 1) + ".bin";
|
|
1723
|
-
}
|
|
1724
|
-
const encodedName = encodeFixedText(fileName, "Filename", 23);
|
|
1725
|
-
const payload = new Uint8Array(26);
|
|
1726
|
-
payload.set([vendor, actionId], 0);
|
|
1727
|
-
payload.set(encodedName, 2);
|
|
1728
|
-
super(payload);
|
|
1421
|
+
const fileName = typeof fileNameOrSlotNumber === "string" ? fileNameOrSlotNumber : `___s_${fileNameOrSlotNumber - 1}.bin`;
|
|
1422
|
+
super(filePayload(vendor, actionId, fileName));
|
|
1729
1423
|
}
|
|
1730
1424
|
}
|
|
1731
1425
|
|
|
@@ -1733,11 +1427,7 @@ class GetFileMetadataH2DPacket extends DeviceBoundPacket {
|
|
|
1733
1427
|
static COMMAND_ID = 86;
|
|
1734
1428
|
static COMMAND_EXTENDED_ID = 25;
|
|
1735
1429
|
constructor(vendor, fileName, options) {
|
|
1736
|
-
|
|
1737
|
-
const payload = new Uint8Array(26);
|
|
1738
|
-
payload.set([vendor, options], 0);
|
|
1739
|
-
payload.set(encodedName, 2);
|
|
1740
|
-
super(payload);
|
|
1430
|
+
super(filePayload(vendor, options, fileName));
|
|
1741
1431
|
}
|
|
1742
1432
|
}
|
|
1743
1433
|
|
|
@@ -1745,11 +1435,7 @@ class EraseFileH2DPacket extends DeviceBoundPacket {
|
|
|
1745
1435
|
static COMMAND_ID = 86;
|
|
1746
1436
|
static COMMAND_EXTENDED_ID = 27;
|
|
1747
1437
|
constructor(vendor, fileName) {
|
|
1748
|
-
|
|
1749
|
-
const payload = new Uint8Array(26);
|
|
1750
|
-
payload.set([vendor, 128], 0);
|
|
1751
|
-
payload.set(encodedName, 2);
|
|
1752
|
-
super(payload);
|
|
1438
|
+
super(filePayload(vendor, 128, fileName));
|
|
1753
1439
|
}
|
|
1754
1440
|
}
|
|
1755
1441
|
|
|
@@ -1757,11 +1443,7 @@ class GetProgramSlotInfoH2DPacket extends DeviceBoundPacket {
|
|
|
1757
1443
|
static COMMAND_ID = 86;
|
|
1758
1444
|
static COMMAND_EXTENDED_ID = 28;
|
|
1759
1445
|
constructor(vendor, fileName) {
|
|
1760
|
-
|
|
1761
|
-
const payload = new Uint8Array(26);
|
|
1762
|
-
payload.set([vendor, 0], 0);
|
|
1763
|
-
payload.set(encodedName, 2);
|
|
1764
|
-
super(payload);
|
|
1446
|
+
super(filePayload(vendor, 0, fileName));
|
|
1765
1447
|
}
|
|
1766
1448
|
}
|
|
1767
1449
|
|
|
@@ -1769,9 +1451,7 @@ class FileClearUpH2DPacket extends DeviceBoundPacket {
|
|
|
1769
1451
|
static COMMAND_ID = 86;
|
|
1770
1452
|
static COMMAND_EXTENDED_ID = 30;
|
|
1771
1453
|
constructor(vendor) {
|
|
1772
|
-
|
|
1773
|
-
payload.set([vendor, 0], 0);
|
|
1774
|
-
super(payload);
|
|
1454
|
+
super(Uint8Array.of(vendor, 0));
|
|
1775
1455
|
}
|
|
1776
1456
|
}
|
|
1777
1457
|
|
|
@@ -1779,9 +1459,7 @@ class FileFormatH2DPacket extends DeviceBoundPacket {
|
|
|
1779
1459
|
static COMMAND_ID = 86;
|
|
1780
1460
|
static COMMAND_EXTENDED_ID = 31;
|
|
1781
1461
|
constructor() {
|
|
1782
|
-
|
|
1783
|
-
payload.set([68, 67, 66, 65], 0);
|
|
1784
|
-
super(payload);
|
|
1462
|
+
super(Uint8Array.of(68, 67, 66, 65));
|
|
1785
1463
|
}
|
|
1786
1464
|
}
|
|
1787
1465
|
|
|
@@ -1793,33 +1471,21 @@ class GetSystemFlagsH2DPacket extends DeviceBoundPacket {
|
|
|
1793
1471
|
class GetDeviceStatusH2DPacket extends DeviceBoundPacket {
|
|
1794
1472
|
static COMMAND_ID = 86;
|
|
1795
1473
|
static COMMAND_EXTENDED_ID = 33;
|
|
1796
|
-
constructor() {
|
|
1797
|
-
super(undefined);
|
|
1798
|
-
}
|
|
1799
1474
|
}
|
|
1800
1475
|
|
|
1801
1476
|
class GetSystemStatusH2DPacket extends DeviceBoundPacket {
|
|
1802
1477
|
static COMMAND_ID = 86;
|
|
1803
1478
|
static COMMAND_EXTENDED_ID = 34;
|
|
1804
|
-
constructor() {
|
|
1805
|
-
super(undefined);
|
|
1806
|
-
}
|
|
1807
1479
|
}
|
|
1808
1480
|
|
|
1809
1481
|
class GetFdtStatusH2DPacket extends DeviceBoundPacket {
|
|
1810
1482
|
static COMMAND_ID = 86;
|
|
1811
1483
|
static COMMAND_EXTENDED_ID = 35;
|
|
1812
|
-
constructor() {
|
|
1813
|
-
super(undefined);
|
|
1814
|
-
}
|
|
1815
1484
|
}
|
|
1816
1485
|
|
|
1817
1486
|
class GetLogCountH2DPacket extends DeviceBoundPacket {
|
|
1818
1487
|
static COMMAND_ID = 86;
|
|
1819
1488
|
static COMMAND_EXTENDED_ID = 36;
|
|
1820
|
-
constructor() {
|
|
1821
|
-
super(undefined);
|
|
1822
|
-
}
|
|
1823
1489
|
}
|
|
1824
1490
|
|
|
1825
1491
|
class ReadLogPageH2DPacket extends DeviceBoundPacket {
|
|
@@ -1837,18 +1503,13 @@ class ReadLogPageH2DPacket extends DeviceBoundPacket {
|
|
|
1837
1503
|
class GetRadioStatusH2DPacket extends DeviceBoundPacket {
|
|
1838
1504
|
static COMMAND_ID = 86;
|
|
1839
1505
|
static COMMAND_EXTENDED_ID = 38;
|
|
1840
|
-
constructor() {
|
|
1841
|
-
super(undefined);
|
|
1842
|
-
}
|
|
1843
1506
|
}
|
|
1844
1507
|
|
|
1845
1508
|
class ScreenCaptureH2DPacket extends DeviceBoundPacket {
|
|
1846
1509
|
static COMMAND_ID = 86;
|
|
1847
1510
|
static COMMAND_EXTENDED_ID = 40;
|
|
1848
1511
|
constructor(e) {
|
|
1849
|
-
|
|
1850
|
-
payload[0] = e;
|
|
1851
|
-
super(payload);
|
|
1512
|
+
super(Uint8Array.of(e));
|
|
1852
1513
|
}
|
|
1853
1514
|
}
|
|
1854
1515
|
|
|
@@ -1869,10 +1530,7 @@ class SelectDashH2DPacket extends DeviceBoundPacket {
|
|
|
1869
1530
|
static COMMAND_ID = 86;
|
|
1870
1531
|
static COMMAND_EXTENDED_ID = 43;
|
|
1871
1532
|
constructor(screen, port) {
|
|
1872
|
-
|
|
1873
|
-
payload[0] = screen;
|
|
1874
|
-
payload[1] = port;
|
|
1875
|
-
super(payload);
|
|
1533
|
+
super(Uint8Array.of(screen, port));
|
|
1876
1534
|
}
|
|
1877
1535
|
}
|
|
1878
1536
|
|
|
@@ -1880,9 +1538,8 @@ class ReadKeyValueH2DPacket extends DeviceBoundPacket {
|
|
|
1880
1538
|
static COMMAND_ID = 86;
|
|
1881
1539
|
static COMMAND_EXTENDED_ID = 46;
|
|
1882
1540
|
constructor(key) {
|
|
1883
|
-
const encodedKey = encodeFixedText(key, "Key", 31);
|
|
1884
1541
|
const payload = new Uint8Array(32);
|
|
1885
|
-
payload.set(
|
|
1542
|
+
payload.set(encodeFixedText(key, "Key", 31), 0);
|
|
1886
1543
|
super(payload);
|
|
1887
1544
|
}
|
|
1888
1545
|
}
|
|
@@ -1906,17 +1563,11 @@ class WriteKeyValueH2DPacket extends DeviceBoundPacket {
|
|
|
1906
1563
|
class GetSlot1to4InfoH2DPacket extends DeviceBoundPacket {
|
|
1907
1564
|
static COMMAND_ID = 86;
|
|
1908
1565
|
static COMMAND_EXTENDED_ID = 49;
|
|
1909
|
-
constructor() {
|
|
1910
|
-
super(undefined);
|
|
1911
|
-
}
|
|
1912
1566
|
}
|
|
1913
1567
|
|
|
1914
1568
|
class GetSlot5to8InfoH2DPacket extends DeviceBoundPacket {
|
|
1915
1569
|
static COMMAND_ID = 86;
|
|
1916
1570
|
static COMMAND_EXTENDED_ID = 50;
|
|
1917
|
-
constructor() {
|
|
1918
|
-
super(undefined);
|
|
1919
|
-
}
|
|
1920
1571
|
}
|
|
1921
1572
|
|
|
1922
1573
|
class FactoryStatusH2DPacket extends DeviceBoundPacket {
|
|
@@ -1928,9 +1579,7 @@ class FactoryEnableH2DPacket extends DeviceBoundPacket {
|
|
|
1928
1579
|
static COMMAND_ID = 86;
|
|
1929
1580
|
static COMMAND_EXTENDED_ID = 255;
|
|
1930
1581
|
constructor() {
|
|
1931
|
-
|
|
1932
|
-
payload.set([77, 76, 75, 74], 0);
|
|
1933
|
-
super(payload);
|
|
1582
|
+
super(Uint8Array.of(77, 76, 75, 74));
|
|
1934
1583
|
}
|
|
1935
1584
|
}
|
|
1936
1585
|
|
|
@@ -1972,8 +1621,7 @@ class MatchModeReplyD2HPacket extends HostBoundPacket {
|
|
|
1972
1621
|
modebit;
|
|
1973
1622
|
constructor(data) {
|
|
1974
1623
|
super(data);
|
|
1975
|
-
|
|
1976
|
-
this.modebit = dataView.nextUint8();
|
|
1624
|
+
this.modebit = PacketView.fromPacket(this).nextUint8();
|
|
1977
1625
|
}
|
|
1978
1626
|
}
|
|
1979
1627
|
|
|
@@ -1999,31 +1647,27 @@ class MatchStatusReplyD2HPacket extends HostBoundPacket {
|
|
|
1999
1647
|
rxSignalQuality;
|
|
2000
1648
|
constructor(data) {
|
|
2001
1649
|
super(data);
|
|
2002
|
-
const
|
|
1650
|
+
const view = PacketView.fromPacket(this);
|
|
2003
1651
|
const n = this.ackIndex;
|
|
2004
|
-
this.rssi =
|
|
2005
|
-
this.systemStatusBits =
|
|
2006
|
-
this.radioStatusBits =
|
|
2007
|
-
this.fieldStatusBits =
|
|
2008
|
-
this.matchClock =
|
|
2009
|
-
this.brainBatteryPercent =
|
|
2010
|
-
this.controllerBatteryPercent =
|
|
2011
|
-
this.partnerControllerBatteryPercent =
|
|
2012
|
-
this.pad =
|
|
2013
|
-
this.buttons =
|
|
2014
|
-
this.activeProgram =
|
|
2015
|
-
this.radioType =
|
|
2016
|
-
this.radioChannel =
|
|
2017
|
-
this.radioSlot =
|
|
2018
|
-
this.
|
|
2019
|
-
this.
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
if (endIdx > -1) {
|
|
2024
|
-
rawStr = rawStr.substr(0, endIdx);
|
|
2025
|
-
}
|
|
2026
|
-
this.robotName = rawStr;
|
|
1652
|
+
this.rssi = view.nextInt8();
|
|
1653
|
+
this.systemStatusBits = view.nextUint16();
|
|
1654
|
+
this.radioStatusBits = view.nextUint16();
|
|
1655
|
+
this.fieldStatusBits = view.nextUint8();
|
|
1656
|
+
this.matchClock = view.nextUint8();
|
|
1657
|
+
this.brainBatteryPercent = view.nextUint8();
|
|
1658
|
+
this.controllerBatteryPercent = view.nextUint8();
|
|
1659
|
+
this.partnerControllerBatteryPercent = view.nextUint8();
|
|
1660
|
+
this.pad = view.nextUint8();
|
|
1661
|
+
this.buttons = view.nextUint16();
|
|
1662
|
+
this.activeProgram = view.nextUint8();
|
|
1663
|
+
this.radioType = view.nextUint8();
|
|
1664
|
+
this.radioChannel = view.nextUint8();
|
|
1665
|
+
this.radioSlot = view.nextUint8();
|
|
1666
|
+
this.controllerFlags = view.getUint8(n + 28);
|
|
1667
|
+
this.rxSignalQuality = view.getUint8(n + 29);
|
|
1668
|
+
const raw = new TextDecoder("UTF-8").decode(this.data.slice(n + 18, n + this.payloadSize + 28));
|
|
1669
|
+
const end = raw.indexOf("\x00");
|
|
1670
|
+
this.robotName = end > -1 ? raw.slice(0, end) : raw;
|
|
2027
1671
|
}
|
|
2028
1672
|
}
|
|
2029
1673
|
|
|
@@ -2040,10 +1684,10 @@ class InitFileTransferReplyD2HPacket extends HostBoundPacket {
|
|
|
2040
1684
|
crc32;
|
|
2041
1685
|
constructor(data) {
|
|
2042
1686
|
super(data);
|
|
2043
|
-
const
|
|
2044
|
-
this.windowSize =
|
|
2045
|
-
this.fileSize =
|
|
2046
|
-
this.crc32 =
|
|
1687
|
+
const view = PacketView.fromPacket(this);
|
|
1688
|
+
this.windowSize = view.nextUint16();
|
|
1689
|
+
this.fileSize = view.nextUint32();
|
|
1690
|
+
this.crc32 = view.nextUint32();
|
|
2047
1691
|
}
|
|
2048
1692
|
}
|
|
2049
1693
|
|
|
@@ -2065,13 +1709,10 @@ class ReadFileReplyD2HPacket extends HostBoundPacket {
|
|
|
2065
1709
|
buf;
|
|
2066
1710
|
constructor(data) {
|
|
2067
1711
|
super(data);
|
|
2068
|
-
const
|
|
2069
|
-
this.addr =
|
|
1712
|
+
const view = PacketView.fromPacket(this);
|
|
1713
|
+
this.addr = view.nextUint32();
|
|
2070
1714
|
this.length = this.payloadSize - 8;
|
|
2071
|
-
this.buf = this.data.slice(
|
|
2072
|
-
}
|
|
2073
|
-
static isValidPacket(data, n) {
|
|
2074
|
-
return super.isValidPacket(data, n);
|
|
1715
|
+
this.buf = this.data.slice(view.position, view.position + this.length).buffer;
|
|
2075
1716
|
}
|
|
2076
1717
|
}
|
|
2077
1718
|
|
|
@@ -2086,8 +1727,7 @@ class GetDirectoryFileCountReplyD2HPacket extends HostBoundPacket {
|
|
|
2086
1727
|
count;
|
|
2087
1728
|
constructor(data) {
|
|
2088
1729
|
super(data);
|
|
2089
|
-
|
|
2090
|
-
this.count = dataView.nextUint16();
|
|
1730
|
+
this.count = PacketView.fromPacket(this).nextUint16();
|
|
2091
1731
|
}
|
|
2092
1732
|
}
|
|
2093
1733
|
|
|
@@ -2097,19 +1737,19 @@ class GetDirectoryEntryReplyD2HPacket extends HostBoundPacket {
|
|
|
2097
1737
|
file;
|
|
2098
1738
|
constructor(data) {
|
|
2099
1739
|
super(data);
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
}
|
|
1740
|
+
if (this.payloadSize <= 4)
|
|
1741
|
+
return;
|
|
1742
|
+
const view = PacketView.fromPacket(this);
|
|
1743
|
+
this.file = {
|
|
1744
|
+
index: view.nextUint8(),
|
|
1745
|
+
size: view.nextUint32(),
|
|
1746
|
+
loadAddress: view.nextUint32(),
|
|
1747
|
+
crc32: view.nextUint32(),
|
|
1748
|
+
type: view.nextString(4),
|
|
1749
|
+
timestamp: view.nextUint32() + PacketEncoder.J2000_EPOCH,
|
|
1750
|
+
version: view.nextVersion(),
|
|
1751
|
+
filename: view.nextNTBS(32)
|
|
1752
|
+
};
|
|
2113
1753
|
}
|
|
2114
1754
|
}
|
|
2115
1755
|
|
|
@@ -2124,18 +1764,18 @@ class GetFileMetadataReplyD2HPacket extends HostBoundPacket {
|
|
|
2124
1764
|
file;
|
|
2125
1765
|
constructor(data) {
|
|
2126
1766
|
super(data);
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
}
|
|
1767
|
+
if (this.payloadSize <= 4)
|
|
1768
|
+
return;
|
|
1769
|
+
const view = PacketView.fromPacket(this);
|
|
1770
|
+
view.nextUint8();
|
|
1771
|
+
this.file = {
|
|
1772
|
+
size: view.nextUint32(),
|
|
1773
|
+
loadAddress: view.nextUint32(),
|
|
1774
|
+
crc32: view.nextUint32(),
|
|
1775
|
+
type: view.nextString(4),
|
|
1776
|
+
timestamp: view.nextUint32() + PacketEncoder.J2000_EPOCH,
|
|
1777
|
+
version: view.nextVersion()
|
|
1778
|
+
};
|
|
2139
1779
|
}
|
|
2140
1780
|
}
|
|
2141
1781
|
|
|
@@ -2151,9 +1791,9 @@ class GetProgramSlotInfoReplyD2HPacket extends HostBoundPacket {
|
|
|
2151
1791
|
slot;
|
|
2152
1792
|
constructor(data) {
|
|
2153
1793
|
super(data);
|
|
2154
|
-
const
|
|
2155
|
-
this.slot =
|
|
2156
|
-
this.requestedSlot =
|
|
1794
|
+
const view = PacketView.fromPacket(this);
|
|
1795
|
+
this.slot = view.nextUint8();
|
|
1796
|
+
this.requestedSlot = view.nextUint8();
|
|
2157
1797
|
}
|
|
2158
1798
|
}
|
|
2159
1799
|
|
|
@@ -2171,40 +1811,32 @@ class GetSystemFlagsReplyD2HPacket extends HostBoundPacket {
|
|
|
2171
1811
|
static COMMAND_ID = 86;
|
|
2172
1812
|
static COMMAND_EXTENDED_ID = 32;
|
|
2173
1813
|
flags;
|
|
2174
|
-
radioSearching;
|
|
1814
|
+
radioSearching = false;
|
|
2175
1815
|
radioQuality;
|
|
2176
1816
|
controllerBatteryPercent;
|
|
2177
1817
|
partnerControllerBatteryPercent;
|
|
2178
1818
|
battery;
|
|
2179
|
-
currentProgram;
|
|
1819
|
+
currentProgram = 0;
|
|
2180
1820
|
constructor(data) {
|
|
2181
1821
|
super(data);
|
|
2182
|
-
const
|
|
2183
|
-
this.
|
|
2184
|
-
this.currentProgram = 0;
|
|
2185
|
-
this.flags = dataView.nextUint32();
|
|
1822
|
+
const view = PacketView.fromPacket(this);
|
|
1823
|
+
this.flags = view.nextUint32();
|
|
2186
1824
|
const hasPartner = (8192 & this.flags) !== 0;
|
|
2187
1825
|
const hasRadio = (1536 & this.flags) === 1536;
|
|
2188
|
-
const byte1 =
|
|
2189
|
-
const byte2 =
|
|
1826
|
+
const byte1 = view.nextUint8();
|
|
1827
|
+
const byte2 = view.nextUint8();
|
|
2190
1828
|
if (this.payloadSize === 11) {
|
|
2191
|
-
this.battery = 8 * (byte1 & 15);
|
|
2192
|
-
if ((this.flags & 256) !== 0 || hasRadio)
|
|
2193
|
-
this.controllerBatteryPercent = 8 * (byte1 >> 4 & 15);
|
|
1829
|
+
this.battery = clamp100(8 * (byte1 & 15));
|
|
1830
|
+
if ((this.flags & 256) !== 0 || hasRadio) {
|
|
1831
|
+
this.controllerBatteryPercent = clamp100(8 * (byte1 >> 4 & 15));
|
|
1832
|
+
}
|
|
2194
1833
|
if (hasRadio)
|
|
2195
|
-
this.radioQuality = 8 * (byte2 & 15);
|
|
1834
|
+
this.radioQuality = clamp100(8 * (byte2 & 15));
|
|
2196
1835
|
this.radioSearching = (this.flags & 1536) === 512;
|
|
2197
|
-
if (hasPartner)
|
|
2198
|
-
this.partnerControllerBatteryPercent = 8 * (byte2 >> 4 & 15);
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
this.battery = 100;
|
|
2202
|
-
if (this.controllerBatteryPercent != null && this.controllerBatteryPercent > 100)
|
|
2203
|
-
this.controllerBatteryPercent = 100;
|
|
2204
|
-
if (this.radioQuality != null && this.radioQuality > 100)
|
|
2205
|
-
this.radioQuality = 100;
|
|
2206
|
-
if (this.partnerControllerBatteryPercent != null && this.partnerControllerBatteryPercent > 100)
|
|
2207
|
-
this.partnerControllerBatteryPercent = 100;
|
|
1836
|
+
if (hasPartner) {
|
|
1837
|
+
this.partnerControllerBatteryPercent = clamp100(8 * (byte2 >> 4 & 15));
|
|
1838
|
+
}
|
|
1839
|
+
this.currentProgram = view.nextUint8();
|
|
2208
1840
|
}
|
|
2209
1841
|
}
|
|
2210
1842
|
}
|
|
@@ -2216,17 +1848,17 @@ class GetDeviceStatusReplyD2HPacket extends HostBoundPacket {
|
|
|
2216
1848
|
devices;
|
|
2217
1849
|
constructor(data) {
|
|
2218
1850
|
super(data);
|
|
2219
|
-
const
|
|
2220
|
-
this.count =
|
|
1851
|
+
const view = PacketView.fromPacket(this);
|
|
1852
|
+
this.count = view.nextUint8();
|
|
2221
1853
|
this.devices = [];
|
|
2222
1854
|
for (let i = 0;i < this.count; i++) {
|
|
2223
1855
|
this.devices.push({
|
|
2224
|
-
port:
|
|
2225
|
-
type:
|
|
2226
|
-
status:
|
|
2227
|
-
betaversion:
|
|
2228
|
-
version:
|
|
2229
|
-
bootversion:
|
|
1856
|
+
port: view.nextUint8(),
|
|
1857
|
+
type: view.nextUint8(),
|
|
1858
|
+
status: view.nextUint8(),
|
|
1859
|
+
betaversion: view.nextUint8(),
|
|
1860
|
+
version: view.nextUint16(),
|
|
1861
|
+
bootversion: view.nextUint16()
|
|
2230
1862
|
});
|
|
2231
1863
|
}
|
|
2232
1864
|
}
|
|
@@ -2238,48 +1870,42 @@ class GetSystemStatusReplyD2HPacket extends HostBoundPacket {
|
|
|
2238
1870
|
systemVersion;
|
|
2239
1871
|
cpu0Version;
|
|
2240
1872
|
cpu1Version;
|
|
2241
|
-
nxpVersion;
|
|
1873
|
+
nxpVersion = VexFirmwareVersion.allZero();
|
|
2242
1874
|
touchVersion;
|
|
2243
|
-
uniqueId;
|
|
2244
|
-
sysflags;
|
|
2245
|
-
eventBrain;
|
|
2246
|
-
romBootloaderActive;
|
|
2247
|
-
ramBootloaderActive;
|
|
2248
|
-
goldenVersion;
|
|
1875
|
+
uniqueId = 1234;
|
|
1876
|
+
sysflags = [0, 0, 0, 0, 0, 0, 0];
|
|
1877
|
+
eventBrain = false;
|
|
1878
|
+
romBootloaderActive = false;
|
|
1879
|
+
ramBootloaderActive = false;
|
|
1880
|
+
goldenVersion = VexFirmwareVersion.allZero();
|
|
2249
1881
|
constructor(data) {
|
|
2250
1882
|
super(data);
|
|
2251
|
-
const
|
|
2252
|
-
|
|
2253
|
-
this.systemVersion =
|
|
2254
|
-
this.cpu0Version =
|
|
2255
|
-
this.cpu1Version =
|
|
2256
|
-
this.touchVersion =
|
|
2257
|
-
this.uniqueId = 1234;
|
|
2258
|
-
this.sysflags = [0, 0, 0, 0, 0, 0, 0];
|
|
2259
|
-
this.goldenVersion = VexFirmwareVersion.allZero();
|
|
2260
|
-
this.nxpVersion = VexFirmwareVersion.allZero();
|
|
2261
|
-
this.eventBrain = false;
|
|
2262
|
-
this.romBootloaderActive = false;
|
|
2263
|
-
this.ramBootloaderActive = false;
|
|
1883
|
+
const view = PacketView.fromPacket(this);
|
|
1884
|
+
view.nextUint8();
|
|
1885
|
+
this.systemVersion = view.nextVersion();
|
|
1886
|
+
this.cpu0Version = view.nextVersion();
|
|
1887
|
+
this.cpu1Version = view.nextVersion();
|
|
1888
|
+
this.touchVersion = view.nextVersion(true);
|
|
2264
1889
|
if (this.payloadSize > 25) {
|
|
2265
|
-
this.uniqueId =
|
|
1890
|
+
this.uniqueId = view.nextUint32();
|
|
2266
1891
|
this.sysflags = [
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
1892
|
+
view.nextUint8(),
|
|
1893
|
+
view.nextUint8(),
|
|
1894
|
+
view.nextUint8(),
|
|
1895
|
+
view.nextUint8(),
|
|
1896
|
+
view.nextUint8(),
|
|
2272
1897
|
0,
|
|
2273
|
-
|
|
1898
|
+
view.nextUint8()
|
|
2274
1899
|
];
|
|
2275
|
-
|
|
2276
|
-
this.
|
|
2277
|
-
this.
|
|
2278
|
-
|
|
2279
|
-
|
|
1900
|
+
const flags6 = this.sysflags[6];
|
|
1901
|
+
this.eventBrain = (1 & flags6) !== 0;
|
|
1902
|
+
this.romBootloaderActive = (2 & flags6) !== 0;
|
|
1903
|
+
this.ramBootloaderActive = (4 & flags6) !== 0;
|
|
1904
|
+
view.nextUint16();
|
|
1905
|
+
this.goldenVersion = view.nextVersion();
|
|
2280
1906
|
}
|
|
2281
1907
|
if (this.payloadSize > 37) {
|
|
2282
|
-
this.nxpVersion =
|
|
1908
|
+
this.nxpVersion = view.nextVersion();
|
|
2283
1909
|
}
|
|
2284
1910
|
}
|
|
2285
1911
|
}
|
|
@@ -2291,17 +1917,17 @@ class GetFdtStatusReplyD2HPacket extends HostBoundPacket {
|
|
|
2291
1917
|
status;
|
|
2292
1918
|
constructor(data) {
|
|
2293
1919
|
super(data);
|
|
2294
|
-
const
|
|
2295
|
-
this.count =
|
|
1920
|
+
const view = PacketView.fromPacket(this);
|
|
1921
|
+
this.count = view.nextUint8();
|
|
2296
1922
|
this.status = [];
|
|
2297
1923
|
for (let i = 0;i < this.count; i++) {
|
|
2298
1924
|
this.status.push({
|
|
2299
|
-
index:
|
|
2300
|
-
type:
|
|
2301
|
-
status:
|
|
2302
|
-
betaversion:
|
|
2303
|
-
version:
|
|
2304
|
-
bootversion:
|
|
1925
|
+
index: view.nextUint8(),
|
|
1926
|
+
type: view.nextUint8(),
|
|
1927
|
+
status: view.nextUint8(),
|
|
1928
|
+
betaversion: view.nextUint8(),
|
|
1929
|
+
version: view.nextUint16(),
|
|
1930
|
+
bootversion: view.nextUint16()
|
|
2305
1931
|
});
|
|
2306
1932
|
}
|
|
2307
1933
|
}
|
|
@@ -2313,9 +1939,9 @@ class GetLogCountReplyD2HPacket extends HostBoundPacket {
|
|
|
2313
1939
|
count;
|
|
2314
1940
|
constructor(data) {
|
|
2315
1941
|
super(data);
|
|
2316
|
-
const
|
|
2317
|
-
|
|
2318
|
-
this.count =
|
|
1942
|
+
const view = PacketView.fromPacket(this);
|
|
1943
|
+
view.nextUint8();
|
|
1944
|
+
this.count = view.nextUint32();
|
|
2319
1945
|
}
|
|
2320
1946
|
}
|
|
2321
1947
|
|
|
@@ -2327,20 +1953,19 @@ class ReadLogPageReplyD2HPacket extends HostBoundPacket {
|
|
|
2327
1953
|
entries;
|
|
2328
1954
|
constructor(data) {
|
|
2329
1955
|
super(data);
|
|
2330
|
-
const
|
|
2331
|
-
const
|
|
2332
|
-
|
|
2333
|
-
this.
|
|
2334
|
-
this.count = dataView.nextUint16();
|
|
1956
|
+
const view = PacketView.fromPacket(this);
|
|
1957
|
+
const size = view.nextUint8();
|
|
1958
|
+
this.offset = view.nextUint32();
|
|
1959
|
+
this.count = view.nextUint16();
|
|
2335
1960
|
this.entries = [];
|
|
2336
|
-
let j =
|
|
1961
|
+
let j = this.ackIndex + 8;
|
|
2337
1962
|
for (let i = 0;i < this.count; i++) {
|
|
2338
1963
|
this.entries.push({
|
|
2339
|
-
code:
|
|
2340
|
-
type:
|
|
2341
|
-
desc:
|
|
2342
|
-
spare:
|
|
2343
|
-
time:
|
|
1964
|
+
code: view.getUint8(j),
|
|
1965
|
+
type: view.getUint8(j + 1),
|
|
1966
|
+
desc: view.getUint8(j + 2),
|
|
1967
|
+
spare: view.getUint8(j + 3),
|
|
1968
|
+
time: view.getUint32(j + 4, true)
|
|
2344
1969
|
});
|
|
2345
1970
|
j += size;
|
|
2346
1971
|
}
|
|
@@ -2357,13 +1982,12 @@ class GetRadioStatusReplyD2HPacket extends HostBoundPacket {
|
|
|
2357
1982
|
timeslot;
|
|
2358
1983
|
constructor(data) {
|
|
2359
1984
|
super(data);
|
|
2360
|
-
const
|
|
2361
|
-
|
|
2362
|
-
this.
|
|
2363
|
-
this.
|
|
2364
|
-
this.
|
|
2365
|
-
this.
|
|
2366
|
-
this.timeslot = this.data[n + 7];
|
|
1985
|
+
const view = PacketView.fromPacket(this);
|
|
1986
|
+
this.device = view.nextUint8();
|
|
1987
|
+
this.quality = view.nextUint16();
|
|
1988
|
+
this.strength = view.nextInt16();
|
|
1989
|
+
this.channel = this.data[this.ackIndex + 6];
|
|
1990
|
+
this.timeslot = this.data[this.ackIndex + 7];
|
|
2367
1991
|
}
|
|
2368
1992
|
}
|
|
2369
1993
|
|
|
@@ -2388,8 +2012,7 @@ class ReadKeyValueReplyD2HPacket extends HostBoundPacket {
|
|
|
2388
2012
|
value;
|
|
2389
2013
|
constructor(data) {
|
|
2390
2014
|
super(data);
|
|
2391
|
-
|
|
2392
|
-
this.value = dataView.nextVarNTBS(255);
|
|
2015
|
+
this.value = PacketView.fromPacket(this).nextVarNTBS(255);
|
|
2393
2016
|
}
|
|
2394
2017
|
}
|
|
2395
2018
|
|
|
@@ -2405,20 +2028,18 @@ class GetSlot1to4InfoReplyD2HPacket extends HostBoundPacket {
|
|
|
2405
2028
|
slots;
|
|
2406
2029
|
constructor(data, start = 1) {
|
|
2407
2030
|
super(data);
|
|
2408
|
-
const
|
|
2409
|
-
this.slotFlags =
|
|
2031
|
+
const view = PacketView.fromPacket(this);
|
|
2032
|
+
this.slotFlags = view.nextUint8();
|
|
2410
2033
|
this.slots = [];
|
|
2411
2034
|
for (let i = 0;i < 4; i++) {
|
|
2412
|
-
|
|
2413
|
-
if (!hasData)
|
|
2035
|
+
if ((this.slotFlags & 1 << start - 1 + i) === 0)
|
|
2414
2036
|
continue;
|
|
2415
|
-
const
|
|
2416
|
-
const nameLen =
|
|
2417
|
-
const name = dataView.nextString(nameLen);
|
|
2037
|
+
const icon = view.nextUint16();
|
|
2038
|
+
const nameLen = view.nextUint8();
|
|
2418
2039
|
this.slots.push({
|
|
2419
2040
|
slot: start + i,
|
|
2420
|
-
icon
|
|
2421
|
-
name
|
|
2041
|
+
icon,
|
|
2042
|
+
name: view.nextString(nameLen)
|
|
2422
2043
|
});
|
|
2423
2044
|
}
|
|
2424
2045
|
}
|
|
@@ -2440,9 +2061,9 @@ class FactoryStatusReplyD2HPacket extends HostBoundPacket {
|
|
|
2440
2061
|
percent;
|
|
2441
2062
|
constructor(data) {
|
|
2442
2063
|
super(data);
|
|
2443
|
-
const
|
|
2444
|
-
this.status =
|
|
2445
|
-
this.percent =
|
|
2064
|
+
const view = PacketView.fromPacket(this);
|
|
2065
|
+
this.status = view.nextUint8();
|
|
2066
|
+
this.percent = view.nextUint8();
|
|
2446
2067
|
}
|
|
2447
2068
|
}
|
|
2448
2069
|
|
|
@@ -2453,6 +2074,7 @@ class FactoryEnableReplyD2HPacket extends HostBoundPacket {
|
|
|
2453
2074
|
|
|
2454
2075
|
// src/VexPacketEncoder.ts
|
|
2455
2076
|
var textEncoder2 = new TextEncoder;
|
|
2077
|
+
var HEADER_TO_DEVICE = Uint8Array.of(201, 54, 184, 71);
|
|
2456
2078
|
function encodeFixedText(value, field, maxBytes) {
|
|
2457
2079
|
const encoded = textEncoder2.encode(value);
|
|
2458
2080
|
if (encoded.byteLength > maxBytes) {
|
|
@@ -2466,92 +2088,96 @@ class PacketEncoder {
|
|
|
2466
2088
|
static HEADER_TO_DEVICE = [201, 54, 184, 71];
|
|
2467
2089
|
static HEADER_TO_HOST = [170, 85];
|
|
2468
2090
|
static J2000_EPOCH = 946684800;
|
|
2469
|
-
vexVersion;
|
|
2470
|
-
crcgen;
|
|
2471
|
-
allPacketsTable =
|
|
2091
|
+
vexVersion = 0;
|
|
2092
|
+
crcgen = new CrcGenerator;
|
|
2093
|
+
allPacketsTable = new Map;
|
|
2472
2094
|
static getInstance() {
|
|
2473
|
-
|
|
2474
|
-
Packet.ENCODER = new PacketEncoder;
|
|
2475
|
-
}
|
|
2095
|
+
Packet.ENCODER ??= new PacketEncoder;
|
|
2476
2096
|
return Packet.ENCODER;
|
|
2477
2097
|
}
|
|
2478
2098
|
constructor() {
|
|
2479
|
-
|
|
2480
|
-
this.crcgen = new CrcGenerator;
|
|
2481
|
-
Object.values(exports_VexPacketModels).forEach((packet) => {
|
|
2099
|
+
for (const packet of Object.values(exports_VexPacketModels)) {
|
|
2482
2100
|
if (typeof packet === "function" && packet.prototype instanceof HostBoundPacket) {
|
|
2483
|
-
const
|
|
2484
|
-
this.allPacketsTable
|
|
2101
|
+
const type = packet;
|
|
2102
|
+
let byExtendedId = this.allPacketsTable.get(type.COMMAND_ID);
|
|
2103
|
+
if (byExtendedId === undefined) {
|
|
2104
|
+
byExtendedId = new Map;
|
|
2105
|
+
this.allPacketsTable.set(type.COMMAND_ID, byExtendedId);
|
|
2106
|
+
}
|
|
2107
|
+
byExtendedId.set(type.COMMAND_EXTENDED_ID, type);
|
|
2485
2108
|
}
|
|
2486
|
-
}
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
getPacketType(commandId, commandExtendedId) {
|
|
2112
|
+
if (commandId === undefined)
|
|
2113
|
+
return;
|
|
2114
|
+
return this.allPacketsTable.get(commandId)?.get(commandExtendedId);
|
|
2487
2115
|
}
|
|
2488
2116
|
createHeader(buf) {
|
|
2489
2117
|
if (buf === undefined || buf.byteLength < PacketEncoder.HEADERS_LENGTH) {
|
|
2490
2118
|
buf = new ArrayBuffer(PacketEncoder.HEADERS_LENGTH);
|
|
2491
2119
|
}
|
|
2492
2120
|
const h = new Uint8Array(buf);
|
|
2493
|
-
h.set(
|
|
2121
|
+
h.set(HEADER_TO_DEVICE);
|
|
2494
2122
|
return h;
|
|
2495
2123
|
}
|
|
2496
2124
|
cdcCommand(cmd) {
|
|
2497
|
-
const
|
|
2498
|
-
|
|
2499
|
-
h
|
|
2125
|
+
const h = new Uint8Array(5);
|
|
2126
|
+
h.set(HEADER_TO_DEVICE);
|
|
2127
|
+
h[4] = cmd;
|
|
2500
2128
|
return h;
|
|
2501
2129
|
}
|
|
2502
2130
|
cdcCommandWithData(cmd, data) {
|
|
2503
|
-
const
|
|
2504
|
-
|
|
2505
|
-
h
|
|
2506
|
-
h
|
|
2131
|
+
const h = new Uint8Array(6 + data.length);
|
|
2132
|
+
h.set(HEADER_TO_DEVICE);
|
|
2133
|
+
h[4] = cmd;
|
|
2134
|
+
h[5] = data.length;
|
|
2135
|
+
h.set(data, 6);
|
|
2507
2136
|
return h;
|
|
2508
2137
|
}
|
|
2509
2138
|
cdc2Command(cmd, ext) {
|
|
2510
|
-
const
|
|
2511
|
-
|
|
2512
|
-
h
|
|
2513
|
-
|
|
2514
|
-
h
|
|
2139
|
+
const h = new Uint8Array(9);
|
|
2140
|
+
h.set(HEADER_TO_DEVICE);
|
|
2141
|
+
h[4] = cmd;
|
|
2142
|
+
h[5] = ext;
|
|
2143
|
+
h[6] = 0;
|
|
2144
|
+
this.appendCrc16(h);
|
|
2515
2145
|
return h;
|
|
2516
2146
|
}
|
|
2517
2147
|
cdc2CommandBufferLength(data) {
|
|
2518
|
-
|
|
2519
|
-
if (data.length > 127)
|
|
2520
|
-
length += 1;
|
|
2521
|
-
return length;
|
|
2148
|
+
return PacketEncoder.HEADERS_LENGTH + data.length + 5 + (data.length > 127 ? 1 : 0);
|
|
2522
2149
|
}
|
|
2523
2150
|
cdc2CommandWithData(cmd, ext, data) {
|
|
2524
|
-
const
|
|
2525
|
-
|
|
2151
|
+
const h = new Uint8Array(this.cdc2CommandBufferLength(data));
|
|
2152
|
+
h.set(HEADER_TO_DEVICE);
|
|
2153
|
+
h[4] = cmd;
|
|
2154
|
+
h[5] = ext;
|
|
2526
2155
|
if (data.length < 128) {
|
|
2527
|
-
h
|
|
2528
|
-
h.set(data,
|
|
2156
|
+
h[6] = data.length;
|
|
2157
|
+
h.set(data, 7);
|
|
2529
2158
|
} else {
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
h.set(
|
|
2533
|
-
h.set(data, PacketEncoder.HEADERS_LENGTH + 4);
|
|
2159
|
+
h[6] = data.length >>> 8 | 128;
|
|
2160
|
+
h[7] = data.length & 255;
|
|
2161
|
+
h.set(data, 8);
|
|
2534
2162
|
}
|
|
2535
|
-
|
|
2536
|
-
h.set([crc >>> 8, crc & 255], buf.byteLength - 2);
|
|
2163
|
+
this.appendCrc16(h);
|
|
2537
2164
|
return h;
|
|
2538
2165
|
}
|
|
2166
|
+
appendCrc16(h) {
|
|
2167
|
+
const crc = this.crcgen.crc16(h.subarray(0, h.length - 2), 0);
|
|
2168
|
+
h[h.length - 2] = crc >>> 8;
|
|
2169
|
+
h[h.length - 1] = crc & 255;
|
|
2170
|
+
}
|
|
2539
2171
|
validateHeader(data) {
|
|
2540
|
-
return
|
|
2172
|
+
return data[0] === PacketEncoder.HEADER_TO_HOST[0] && data[1] === PacketEncoder.HEADER_TO_HOST[1];
|
|
2541
2173
|
}
|
|
2542
2174
|
validateMessageCdc(data) {
|
|
2543
|
-
const
|
|
2544
|
-
|
|
2545
|
-
return this.crcgen.crc16(message, 0) === lastTwoBytes;
|
|
2175
|
+
const crc = (data[data.byteLength - 2] << 8) + data[data.byteLength - 1];
|
|
2176
|
+
return this.crcgen.crc16(data.subarray(0, data.byteLength - 2), 0) === crc;
|
|
2546
2177
|
}
|
|
2547
2178
|
getPayloadSize(data) {
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
if ((128 & a) !== 0) {
|
|
2551
|
-
t = 127 & a;
|
|
2552
|
-
a = data[4];
|
|
2553
|
-
}
|
|
2554
|
-
return (t << 8) + a;
|
|
2179
|
+
const a = data[3];
|
|
2180
|
+
return (a & 128) === 0 ? a : ((a & 127) << 8) + data[4];
|
|
2555
2181
|
}
|
|
2556
2182
|
getHostHeaderLength(data) {
|
|
2557
2183
|
return (data[3] & 128) === 0 ? 4 : 5;
|
|
@@ -2588,6 +2214,9 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2588
2214
|
super();
|
|
2589
2215
|
this.serial = serial;
|
|
2590
2216
|
}
|
|
2217
|
+
reportWarning(message, details) {
|
|
2218
|
+
this.emit("warning", { message, details });
|
|
2219
|
+
}
|
|
2591
2220
|
async close() {
|
|
2592
2221
|
if (this._closePromise)
|
|
2593
2222
|
return this._closePromise;
|
|
@@ -2650,7 +2279,7 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2650
2279
|
try {
|
|
2651
2280
|
await port.close();
|
|
2652
2281
|
} catch (e) {
|
|
2653
|
-
|
|
2282
|
+
this.reportWarning("failed to close the serial port", e);
|
|
2654
2283
|
}
|
|
2655
2284
|
}
|
|
2656
2285
|
if (this._wasConnected) {
|
|
@@ -2659,29 +2288,28 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2659
2288
|
}
|
|
2660
2289
|
}
|
|
2661
2290
|
open(use = 0, askUser = true) {
|
|
2662
|
-
if (this.port !== undefined) {
|
|
2663
|
-
return errAsyncVex(new VexIoError("Already connected."));
|
|
2664
|
-
}
|
|
2665
2291
|
return new import_neverthrow.ResultAsync(this._open(use, askUser));
|
|
2666
2292
|
}
|
|
2667
2293
|
async _open(use, askUser) {
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
return this.filters.find((f) => (f.usbVendorId === undefined || f.usbVendorId === info.usbVendorId) && (f.usbProductId === undefined || f.usbProductId === info.usbProductId));
|
|
2673
|
-
}).filter((candidate) => candidate.readable === null);
|
|
2674
|
-
port = ports[use];
|
|
2294
|
+
if (this._closePromise !== null)
|
|
2295
|
+
await this._closePromise;
|
|
2296
|
+
if (this.port !== undefined) {
|
|
2297
|
+
return import_neverthrow.err(new VexIoError("Already connected."));
|
|
2675
2298
|
}
|
|
2299
|
+
const ports = (await this.serial.getPorts()).filter((p) => {
|
|
2300
|
+
const info = p.getInfo();
|
|
2301
|
+
return this.filters.find((f) => (f.usbVendorId === undefined || f.usbVendorId === info.usbVendorId) && (f.usbProductId === undefined || f.usbProductId === info.usbProductId));
|
|
2302
|
+
}).filter((candidate) => candidate.readable === null);
|
|
2303
|
+
let port = ports[use];
|
|
2676
2304
|
if (port == null && askUser) {
|
|
2677
2305
|
try {
|
|
2678
2306
|
port = await this.serial.requestPort({ filters: this.filters });
|
|
2679
2307
|
} catch {}
|
|
2680
2308
|
}
|
|
2681
2309
|
if (port == null)
|
|
2682
|
-
return import_neverthrow.ok(
|
|
2310
|
+
return import_neverthrow.ok("no-port");
|
|
2683
2311
|
if (port.readable != null)
|
|
2684
|
-
return import_neverthrow.ok(
|
|
2312
|
+
return import_neverthrow.ok("busy");
|
|
2685
2313
|
try {
|
|
2686
2314
|
this.port = port;
|
|
2687
2315
|
await port.open({ baudRate: 115200 });
|
|
@@ -2694,15 +2322,12 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2694
2322
|
this.startReader();
|
|
2695
2323
|
this._wasConnected = true;
|
|
2696
2324
|
this.emit("connected", undefined);
|
|
2697
|
-
return import_neverthrow.ok(
|
|
2698
|
-
} catch {
|
|
2325
|
+
return import_neverthrow.ok("opened");
|
|
2326
|
+
} catch (e) {
|
|
2699
2327
|
await this.close();
|
|
2700
|
-
return import_neverthrow.
|
|
2328
|
+
return import_neverthrow.err(toVexSerialError(e, "io"));
|
|
2701
2329
|
}
|
|
2702
2330
|
}
|
|
2703
|
-
writeData(rawData, resolve, timeout = 1000) {
|
|
2704
|
-
this.writeDataAsync(rawData, timeout).then(resolve);
|
|
2705
|
-
}
|
|
2706
2331
|
async writeDataAsync(rawData, timeout = 1000) {
|
|
2707
2332
|
return new Promise((resolve) => {
|
|
2708
2333
|
if (this.writer === undefined) {
|
|
@@ -2733,6 +2358,14 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2733
2358
|
});
|
|
2734
2359
|
});
|
|
2735
2360
|
}
|
|
2361
|
+
request(packet, ReplyType, timeout = 1000) {
|
|
2362
|
+
return new import_neverthrow.ResultAsync((async () => {
|
|
2363
|
+
const result = await this.writeDataAsync(packet, timeout);
|
|
2364
|
+
if (result instanceof ReplyType)
|
|
2365
|
+
return import_neverthrow.ok(result);
|
|
2366
|
+
return import_neverthrow.err(new VexProtocolError(expectedReplyMessage(packet, ReplyType, result), typeof result === "number" ? result : undefined));
|
|
2367
|
+
})());
|
|
2368
|
+
}
|
|
2736
2369
|
async readData(cache, expectedSize) {
|
|
2737
2370
|
if (this.reader == null)
|
|
2738
2371
|
throw new Error("No reader");
|
|
@@ -2773,39 +2406,56 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2773
2406
|
if (!thePacketEncoder.validateMessageCdc(cache))
|
|
2774
2407
|
throw new Error("Invalid message CDC");
|
|
2775
2408
|
}
|
|
2776
|
-
let
|
|
2777
|
-
let
|
|
2778
|
-
let
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
if (wantedCmdId !== undefined && wantedCmdId !== cmdId || wantedCmdExId !== undefined && wantedCmdExId !== cmdExId) {
|
|
2409
|
+
let matchIdx = -1;
|
|
2410
|
+
let untypedIdx = -1;
|
|
2411
|
+
for (let i = 0;i < this.callbacksQueue.length; i++) {
|
|
2412
|
+
const candidate = this.callbacksQueue[i];
|
|
2413
|
+
if (candidate.wantedCommandId === undefined && candidate.wantedCommandExId === undefined) {
|
|
2414
|
+
if (untypedIdx === -1)
|
|
2415
|
+
untypedIdx = i;
|
|
2784
2416
|
continue;
|
|
2785
2417
|
}
|
|
2786
|
-
|
|
2418
|
+
if ((candidate.wantedCommandId === undefined || candidate.wantedCommandId === cmdId) && (candidate.wantedCommandExId === undefined || candidate.wantedCommandExId === cmdExId)) {
|
|
2419
|
+
matchIdx = i;
|
|
2420
|
+
break;
|
|
2421
|
+
}
|
|
2787
2422
|
}
|
|
2788
|
-
if (
|
|
2789
|
-
|
|
2423
|
+
if (matchIdx === -1)
|
|
2424
|
+
matchIdx = untypedIdx;
|
|
2425
|
+
if (matchIdx === -1) {
|
|
2426
|
+
this.reportWarning("received a reply with no matching request", {
|
|
2427
|
+
commandId: cmdId,
|
|
2428
|
+
commandExtendedId: cmdExId,
|
|
2429
|
+
ack
|
|
2430
|
+
});
|
|
2790
2431
|
continue;
|
|
2791
2432
|
}
|
|
2433
|
+
const callbackInfo = this.callbacksQueue[matchIdx];
|
|
2434
|
+
const wantedCmdId = callbackInfo.wantedCommandId;
|
|
2435
|
+
const wantedCmdExId = callbackInfo.wantedCommandExId;
|
|
2792
2436
|
const data = cache.slice(0, sliceIdx);
|
|
2793
|
-
const PackageType = thePacketEncoder.
|
|
2794
|
-
if (wantedCmdId === undefined
|
|
2437
|
+
const PackageType = thePacketEncoder.getPacketType(wantedCmdId, wantedCmdExId);
|
|
2438
|
+
if (wantedCmdId === undefined || PackageType === undefined) {
|
|
2439
|
+
if (wantedCmdId !== undefined) {
|
|
2440
|
+
this.reportWarning("no packet class is registered for the wanted command", { commandId: wantedCmdId, commandExtendedId: wantedCmdExId });
|
|
2441
|
+
}
|
|
2795
2442
|
callbackInfo.callback(data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength));
|
|
2796
2443
|
} else {
|
|
2797
2444
|
if (!hasExtId || PackageType.isValidPacket(data, n)) {
|
|
2798
2445
|
callbackInfo.callback(new PackageType(data));
|
|
2799
2446
|
} else {
|
|
2800
|
-
|
|
2447
|
+
this.reportWarning("reply failed packet validation; delivering its ack instead", { commandId: cmdId, commandExtendedId: cmdExId, ack });
|
|
2801
2448
|
callbackInfo.callback(ack);
|
|
2802
2449
|
}
|
|
2803
2450
|
}
|
|
2804
2451
|
clearTimeout(callbackInfo.timeout);
|
|
2805
|
-
this.callbacksQueue.splice(
|
|
2452
|
+
this.callbacksQueue.splice(matchIdx, 1);
|
|
2806
2453
|
} catch (e) {
|
|
2807
2454
|
if (!(e instanceof Error && e.message === "No data")) {
|
|
2808
|
-
|
|
2455
|
+
this.reportWarning("reader loop stopped by a read error", {
|
|
2456
|
+
error: e,
|
|
2457
|
+
pendingBytes: cache
|
|
2458
|
+
});
|
|
2809
2459
|
}
|
|
2810
2460
|
await this.close();
|
|
2811
2461
|
break;
|
|
@@ -2814,19 +2464,10 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2814
2464
|
}
|
|
2815
2465
|
}
|
|
2816
2466
|
query1() {
|
|
2817
|
-
return
|
|
2818
|
-
const result = await this.writeDataAsync(new Query1H2DPacket, 100);
|
|
2819
|
-
return result instanceof Query1ReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("query1 was not acknowledged"));
|
|
2820
|
-
})());
|
|
2467
|
+
return this.request(new Query1H2DPacket, Query1ReplyD2HPacket, 100);
|
|
2821
2468
|
}
|
|
2822
2469
|
getSystemVersion() {
|
|
2823
|
-
return new
|
|
2824
|
-
const result = await this.writeDataAsync(new SystemVersionH2DPacket);
|
|
2825
|
-
if (result instanceof SystemVersionReplyD2HPacket) {
|
|
2826
|
-
return import_neverthrow.ok(result.version);
|
|
2827
|
-
}
|
|
2828
|
-
return import_neverthrow.err(new VexProtocolError("system version was not acknowledged"));
|
|
2829
|
-
})());
|
|
2470
|
+
return this.request(new SystemVersionH2DPacket, SystemVersionReplyD2HPacket).map((result) => result.version);
|
|
2830
2471
|
}
|
|
2831
2472
|
}
|
|
2832
2473
|
|
|
@@ -2853,34 +2494,19 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
2853
2494
|
}
|
|
2854
2495
|
}
|
|
2855
2496
|
getDeviceStatus() {
|
|
2856
|
-
return
|
|
2857
|
-
const result = await this.writeDataAsync(new GetDeviceStatusH2DPacket);
|
|
2858
|
-
return result instanceof GetDeviceStatusReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("device status was not acknowledged"));
|
|
2859
|
-
})());
|
|
2497
|
+
return this.request(new GetDeviceStatusH2DPacket, GetDeviceStatusReplyD2HPacket);
|
|
2860
2498
|
}
|
|
2861
2499
|
getRadioStatus() {
|
|
2862
|
-
return
|
|
2863
|
-
const result = await this.writeDataAsync(new GetRadioStatusH2DPacket);
|
|
2864
|
-
return result instanceof GetRadioStatusReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("radio status was not acknowledged"));
|
|
2865
|
-
})());
|
|
2500
|
+
return this.request(new GetRadioStatusH2DPacket, GetRadioStatusReplyD2HPacket);
|
|
2866
2501
|
}
|
|
2867
2502
|
getSystemFlags() {
|
|
2868
|
-
return
|
|
2869
|
-
const result = await this.writeDataAsync(new GetSystemFlagsH2DPacket);
|
|
2870
|
-
return result instanceof GetSystemFlagsReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("system flags were not acknowledged"));
|
|
2871
|
-
})());
|
|
2503
|
+
return this.request(new GetSystemFlagsH2DPacket, GetSystemFlagsReplyD2HPacket);
|
|
2872
2504
|
}
|
|
2873
2505
|
getSystemStatus(timeout = 1000) {
|
|
2874
|
-
return
|
|
2875
|
-
const result = await this.writeDataAsync(new GetSystemStatusH2DPacket, timeout);
|
|
2876
|
-
return result instanceof GetSystemStatusReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("system status was not acknowledged"));
|
|
2877
|
-
})());
|
|
2506
|
+
return this.request(new GetSystemStatusH2DPacket, GetSystemStatusReplyD2HPacket, timeout);
|
|
2878
2507
|
}
|
|
2879
2508
|
getMatchStatus() {
|
|
2880
|
-
return
|
|
2881
|
-
const result = await this.writeDataAsync(new GetMatchStatusH2DPacket);
|
|
2882
|
-
return result instanceof MatchStatusReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("match status was not acknowledged"));
|
|
2883
|
-
})());
|
|
2509
|
+
return this.request(new GetMatchStatusH2DPacket, MatchStatusReplyD2HPacket);
|
|
2884
2510
|
}
|
|
2885
2511
|
uploadProgramToDevice(iniConfig, binFileBuf, coldFileBuf, progressCallback) {
|
|
2886
2512
|
return wrapTransfer(this, () => this._uploadProgramToDevice(iniConfig, binFileBuf, coldFileBuf, progressCallback));
|
|
@@ -2941,23 +2567,23 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
2941
2567
|
async _downloadFileToHostUnlocked(request, downloadTarget, progressCallback) {
|
|
2942
2568
|
const { filename, vendor, loadAddress, size } = request;
|
|
2943
2569
|
let nextAddress = loadAddress ?? USER_FLASH_USR_CODE_START;
|
|
2944
|
-
const
|
|
2945
|
-
if (
|
|
2946
|
-
return import_neverthrow.err(
|
|
2947
|
-
}
|
|
2570
|
+
const p1Result = await this.request(new InitFileTransferH2DPacket(2 /* READ */, downloadTarget, vendor, 0 /* NONE */, new Uint8Array, nextAddress, filename, ""), InitFileTransferReplyD2HPacket);
|
|
2571
|
+
if (p1Result.isErr())
|
|
2572
|
+
return import_neverthrow.err(p1Result.error);
|
|
2948
2573
|
let transferFailed = true;
|
|
2949
2574
|
let result = import_neverthrow.ok(new Uint8Array);
|
|
2950
2575
|
try {
|
|
2576
|
+
const p1 = p1Result.value;
|
|
2951
2577
|
const fileSize = size ?? p1.fileSize;
|
|
2952
2578
|
const bufferChunkSize = getTransferChunkSize(p1.windowSize);
|
|
2953
2579
|
let bufferOffset = 0;
|
|
2954
2580
|
const fileBuf = new Uint8Array(fileSize);
|
|
2955
2581
|
while (bufferOffset < fileSize) {
|
|
2956
2582
|
const requestedSize = Math.min(bufferChunkSize, fileSize - bufferOffset);
|
|
2957
|
-
const
|
|
2958
|
-
if (
|
|
2959
|
-
throw
|
|
2960
|
-
|
|
2583
|
+
const p2Result = await this.request(new ReadFileH2DPacket(nextAddress, requestedSize), ReadFileReplyD2HPacket, 3000);
|
|
2584
|
+
if (p2Result.isErr())
|
|
2585
|
+
throw p2Result.error;
|
|
2586
|
+
const p2 = p2Result.value;
|
|
2961
2587
|
if (p2.addr !== nextAddress) {
|
|
2962
2588
|
throw new VexTransferError(`ReadFileReplyD2HPacket returned address ${p2.addr}, expected ${nextAddress}`);
|
|
2963
2589
|
}
|
|
@@ -2975,11 +2601,12 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
2975
2601
|
result = import_neverthrow.err(e instanceof VexSerialError ? e : toVexSerialError(e, "transfer"));
|
|
2976
2602
|
} finally {
|
|
2977
2603
|
try {
|
|
2978
|
-
await this.
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2604
|
+
const exitResult = await this.request(new ExitFileTransferH2DPacket(3 /* EXIT_HALT */), ExitFileTransferReplyD2HPacket, 30000);
|
|
2605
|
+
if (!transferFailed && exitResult.isErr())
|
|
2606
|
+
result = import_neverthrow.err(exitResult.error);
|
|
2607
|
+
} catch (e) {
|
|
2608
|
+
if (!transferFailed)
|
|
2609
|
+
result = import_neverthrow.err(toVexSerialError(e, "io"));
|
|
2983
2610
|
}
|
|
2984
2611
|
}
|
|
2985
2612
|
return result;
|
|
@@ -3004,22 +2631,20 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
3004
2631
|
downloadTarget = downloadTarget ?? 1 /* FILE_TARGET_QSPI */;
|
|
3005
2632
|
vendor = vendor ?? 1 /* USER */;
|
|
3006
2633
|
let nextAddress = loadAddress ?? USER_FLASH_USR_CODE_START;
|
|
3007
|
-
const
|
|
3008
|
-
if (
|
|
3009
|
-
return import_neverthrow.err(
|
|
3010
|
-
|
|
2634
|
+
const p1Result = await this.request(new InitFileTransferH2DPacket(1 /* WRITE */, downloadTarget, vendor, 1 /* OVERWRITE */, buf, nextAddress, filename, exttype), InitFileTransferReplyD2HPacket);
|
|
2635
|
+
if (p1Result.isErr())
|
|
2636
|
+
return import_neverthrow.err(p1Result.error);
|
|
2637
|
+
const p1 = p1Result.value;
|
|
3011
2638
|
const bufferChunkSize = getTransferChunkSize(p1.windowSize);
|
|
3012
2639
|
let bufferOffset = 0;
|
|
3013
2640
|
let lastBlock = false;
|
|
3014
2641
|
let transferFailed = true;
|
|
3015
|
-
let exitReply;
|
|
3016
2642
|
let result = import_neverthrow.ok(false);
|
|
3017
2643
|
try {
|
|
3018
2644
|
if (linkedFile !== undefined) {
|
|
3019
|
-
const
|
|
3020
|
-
if (
|
|
3021
|
-
throw
|
|
3022
|
-
}
|
|
2645
|
+
const p3Result = await this.request(new LinkFileH2DPacket(linkedFile.vendor ?? 1 /* USER */, linkedFile.filename, 0), LinkFileReplyD2HPacket, 1e4);
|
|
2646
|
+
if (p3Result.isErr())
|
|
2647
|
+
throw p3Result.error;
|
|
3023
2648
|
}
|
|
3024
2649
|
while (!lastBlock) {
|
|
3025
2650
|
let tmpbuf;
|
|
@@ -3031,23 +2656,21 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
3031
2656
|
tmpbuf.set(buf.subarray(bufferOffset, buf.byteLength));
|
|
3032
2657
|
lastBlock = true;
|
|
3033
2658
|
}
|
|
3034
|
-
const
|
|
3035
|
-
if (
|
|
3036
|
-
throw
|
|
3037
|
-
if (progressCallback != null)
|
|
3038
|
-
progressCallback(bufferOffset, buf.byteLength);
|
|
2659
|
+
const p2Result = await this.request(new WriteFileH2DPacket(nextAddress, tmpbuf), WriteFileReplyD2HPacket, 3000);
|
|
2660
|
+
if (p2Result.isErr())
|
|
2661
|
+
throw p2Result.error;
|
|
3039
2662
|
bufferOffset += bufferChunkSize;
|
|
3040
2663
|
nextAddress += bufferChunkSize;
|
|
2664
|
+
progressCallback?.(Math.min(bufferOffset, buf.byteLength), buf.byteLength);
|
|
3041
2665
|
}
|
|
3042
|
-
progressCallback?.(buf.byteLength, buf.byteLength);
|
|
3043
2666
|
transferFailed = false;
|
|
3044
2667
|
} catch (e) {
|
|
3045
2668
|
result = import_neverthrow.err(e instanceof VexSerialError ? e : toVexSerialError(e, "transfer"));
|
|
3046
2669
|
} finally {
|
|
3047
2670
|
try {
|
|
3048
|
-
|
|
2671
|
+
const exitResult = await this.request(new ExitFileTransferH2DPacket(transferFailed ? 3 /* EXIT_HALT */ : autoRun ? 1 /* EXIT_RUN */ : 3 /* EXIT_HALT */), ExitFileTransferReplyD2HPacket, 30000);
|
|
3049
2672
|
if (!transferFailed) {
|
|
3050
|
-
result =
|
|
2673
|
+
result = exitResult.map(() => true);
|
|
3051
2674
|
}
|
|
3052
2675
|
} catch (cleanupError) {
|
|
3053
2676
|
if (!transferFailed) {
|
|
@@ -3069,14 +2692,20 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
3069
2692
|
}
|
|
3070
2693
|
let result;
|
|
3071
2694
|
try {
|
|
3072
|
-
const
|
|
3073
|
-
result =
|
|
2695
|
+
const eraseResult = await this.request(new EraseFileH2DPacket(vendor, filename), EraseFileReplyD2HPacket);
|
|
2696
|
+
result = eraseResult.map(() => {
|
|
2697
|
+
return;
|
|
2698
|
+
});
|
|
3074
2699
|
} catch (e) {
|
|
3075
2700
|
result = import_neverthrow.err(toVexSerialError(e, "io"));
|
|
3076
|
-
}
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
2701
|
+
}
|
|
2702
|
+
try {
|
|
2703
|
+
const exitResult = await this.request(new ExitFileTransferH2DPacket(3 /* EXIT_HALT */), ExitFileTransferReplyD2HPacket, 30000);
|
|
2704
|
+
if (result.isOk() && exitResult.isErr())
|
|
2705
|
+
result = import_neverthrow.err(exitResult.error);
|
|
2706
|
+
} catch (e) {
|
|
2707
|
+
if (result.isOk())
|
|
2708
|
+
result = import_neverthrow.err(toVexSerialError(e, "io"));
|
|
3080
2709
|
}
|
|
3081
2710
|
return result;
|
|
3082
2711
|
}));
|
|
@@ -3085,23 +2714,26 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
3085
2714
|
return new import_neverthrow.ResultAsync(this.withFileTransfer(async () => {
|
|
3086
2715
|
let result;
|
|
3087
2716
|
try {
|
|
3088
|
-
const
|
|
3089
|
-
result =
|
|
2717
|
+
const clearResult = await this.request(new FileClearUpH2DPacket(1 /* USER */), FileClearUpReplyD2HPacket, 30000);
|
|
2718
|
+
result = clearResult.map(() => {
|
|
2719
|
+
return;
|
|
2720
|
+
});
|
|
3090
2721
|
} catch (e) {
|
|
3091
2722
|
result = import_neverthrow.err(toVexSerialError(e, "io"));
|
|
3092
|
-
}
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
2723
|
+
}
|
|
2724
|
+
try {
|
|
2725
|
+
const exitResult = await this.request(new ExitFileTransferH2DPacket(3 /* EXIT_HALT */), ExitFileTransferReplyD2HPacket, 30000);
|
|
2726
|
+
if (result.isOk() && exitResult.isErr())
|
|
2727
|
+
result = import_neverthrow.err(exitResult.error);
|
|
2728
|
+
} catch (e) {
|
|
2729
|
+
if (result.isOk())
|
|
2730
|
+
result = import_neverthrow.err(toVexSerialError(e, "io"));
|
|
3096
2731
|
}
|
|
3097
2732
|
return result;
|
|
3098
2733
|
}));
|
|
3099
2734
|
}
|
|
3100
2735
|
captureScreenSetup() {
|
|
3101
|
-
return
|
|
3102
|
-
const result = await this.writeDataAsync(new ScreenCaptureH2DPacket(0));
|
|
3103
|
-
return result instanceof ScreenCaptureReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("screen capture was rejected"));
|
|
3104
|
-
})());
|
|
2736
|
+
return this.request(new ScreenCaptureH2DPacket(0), ScreenCaptureReplyD2HPacket);
|
|
3105
2737
|
}
|
|
3106
2738
|
captureScreen(progressCallback) {
|
|
3107
2739
|
return wrapTransfer(this, () => this._captureScreen(progressCallback));
|
|
@@ -3122,37 +2754,22 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
3122
2754
|
return import_neverthrow.ok(convertScreenCapture(framebuffer.value));
|
|
3123
2755
|
}
|
|
3124
2756
|
setMatchMode(mode) {
|
|
3125
|
-
return new
|
|
3126
|
-
const result = await this.writeDataAsync(new UpdateMatchModeH2DPacket(mode, 0));
|
|
3127
|
-
return result instanceof MatchModeReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("setMatchMode was not acknowledged"));
|
|
3128
|
-
})());
|
|
2757
|
+
return this.request(new UpdateMatchModeH2DPacket(mode, 0), MatchModeReplyD2HPacket);
|
|
3129
2758
|
}
|
|
3130
2759
|
runProgram(value) {
|
|
3131
2760
|
return this.loadProgram(value);
|
|
3132
2761
|
}
|
|
3133
2762
|
loadProgram(value) {
|
|
3134
|
-
return new
|
|
3135
|
-
const result = await this.writeDataAsync(new LoadFileActionH2DPacket(1 /* USER */, 0 /* RUN */, value));
|
|
3136
|
-
return result instanceof LoadFileActionReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("loadProgram was not acknowledged"));
|
|
3137
|
-
})());
|
|
2763
|
+
return this.request(new LoadFileActionH2DPacket(1 /* USER */, 0 /* RUN */, value), LoadFileActionReplyD2HPacket);
|
|
3138
2764
|
}
|
|
3139
2765
|
stopProgram() {
|
|
3140
|
-
return new
|
|
3141
|
-
const result = await this.writeDataAsync(new LoadFileActionH2DPacket(1 /* USER */, 128 /* STOP */, ""));
|
|
3142
|
-
return result instanceof LoadFileActionReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("stopProgram was not acknowledged"));
|
|
3143
|
-
})());
|
|
2766
|
+
return this.request(new LoadFileActionH2DPacket(1 /* USER */, 128 /* STOP */, ""), LoadFileActionReplyD2HPacket);
|
|
3144
2767
|
}
|
|
3145
2768
|
mockTouch(x, y, press) {
|
|
3146
|
-
return new
|
|
3147
|
-
const result = await this.writeDataAsync(new SendDashTouchH2DPacket(x, y, press));
|
|
3148
|
-
return result instanceof SendDashTouchReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("mockTouch was not acknowledged"));
|
|
3149
|
-
})());
|
|
2769
|
+
return this.request(new SendDashTouchH2DPacket(x, y, press), SendDashTouchReplyD2HPacket);
|
|
3150
2770
|
}
|
|
3151
2771
|
openScreen(screen, port) {
|
|
3152
|
-
return new
|
|
3153
|
-
const result = await this.writeDataAsync(new SelectDashH2DPacket(screen, port));
|
|
3154
|
-
return result instanceof SelectDashReplyD2HPacket ? import_neverthrow.ok(result) : import_neverthrow.err(new VexProtocolError("openScreen was not acknowledged"));
|
|
3155
|
-
})());
|
|
2772
|
+
return this.request(new SelectDashH2DPacket(screen, port), SelectDashReplyD2HPacket);
|
|
3156
2773
|
}
|
|
3157
2774
|
}
|
|
3158
2775
|
function binaryArrayJoin(left, right) {
|
|
@@ -3194,8 +2811,16 @@ function wrapTransfer(conn, operation) {
|
|
|
3194
2811
|
}
|
|
3195
2812
|
}));
|
|
3196
2813
|
}
|
|
3197
|
-
function
|
|
3198
|
-
|
|
2814
|
+
function expectedReplyMessage(packet, ReplyType, reply) {
|
|
2815
|
+
const expected = `expected ${ReplyType.name} for ${packet.constructor.name}`;
|
|
2816
|
+
if (typeof reply === "number")
|
|
2817
|
+
return `${expected}; received ${ackTypeName(reply)}`;
|
|
2818
|
+
if (reply instanceof ArrayBuffer)
|
|
2819
|
+
return `${expected}; received raw ArrayBuffer`;
|
|
2820
|
+
return `${expected}; received ${reply.constructor.name}`;
|
|
2821
|
+
}
|
|
2822
|
+
function ackTypeName(ackType) {
|
|
2823
|
+
return `AckType.${AckType[ackType] ?? "UNKNOWN"} (${ackType})`;
|
|
3199
2824
|
}
|
|
3200
2825
|
// src/VexDeviceState.ts
|
|
3201
2826
|
var import_neverthrow4 = __toESM(require_index_cjs(), 1);
|
|
@@ -3206,9 +2831,6 @@ var MAX_CATALOG_BYTES = 4 * 1024;
|
|
|
3206
2831
|
var MAX_VEXOS_BYTES = 64 * 1024 * 1024;
|
|
3207
2832
|
var MAX_FIRMWARE_IMAGE_BYTES = 32 * 1024 * 1024;
|
|
3208
2833
|
var MAX_AGGREGATE_IMAGE_BYTES = 48 * 1024 * 1024;
|
|
3209
|
-
function fromAsyncFn(fn) {
|
|
3210
|
-
return new import_neverthrow2.ResultAsync(fn());
|
|
3211
|
-
}
|
|
3212
2834
|
function downloadFileFromInternet(link, options = {}) {
|
|
3213
2835
|
const { maxBytes = Number.POSITIVE_INFINITY, timeout = 30000 } = options;
|
|
3214
2836
|
if (maxBytes <= 0) {
|
|
@@ -3217,7 +2839,7 @@ function downloadFileFromInternet(link, options = {}) {
|
|
|
3217
2839
|
if (timeout < 0) {
|
|
3218
2840
|
return import_neverthrow2.errAsync(new VexInvalidArgumentError("timeout must be non-negative"));
|
|
3219
2841
|
}
|
|
3220
|
-
return
|
|
2842
|
+
return new import_neverthrow2.ResultAsync(runDownload(link, maxBytes, timeout));
|
|
3221
2843
|
}
|
|
3222
2844
|
async function runDownload(link, maxBytes, timeout) {
|
|
3223
2845
|
const controller = new AbortController;
|
|
@@ -3284,7 +2906,7 @@ function sleepUntilAsync(f, timeout, interval = 20) {
|
|
|
3284
2906
|
if (interval <= 0) {
|
|
3285
2907
|
return import_neverthrow2.errAsync(new VexInvalidArgumentError("interval must be positive"));
|
|
3286
2908
|
}
|
|
3287
|
-
return
|
|
2909
|
+
return new import_neverthrow2.ResultAsync(runSleepUntilAsync(f, timeout, interval));
|
|
3288
2910
|
}
|
|
3289
2911
|
async function runSleepUntilAsync(f, timeout, interval) {
|
|
3290
2912
|
const deadline = Date.now() + timeout;
|
|
@@ -3309,7 +2931,7 @@ function sleepUntil(f, timeout, interval = 20) {
|
|
|
3309
2931
|
if (interval <= 0) {
|
|
3310
2932
|
return import_neverthrow2.errAsync(new VexInvalidArgumentError("interval must be positive"));
|
|
3311
2933
|
}
|
|
3312
|
-
return
|
|
2934
|
+
return new import_neverthrow2.ResultAsync(runSleepUntil(f, timeout, interval));
|
|
3313
2935
|
}
|
|
3314
2936
|
async function runSleepUntil(f, timeout, interval) {
|
|
3315
2937
|
const deadline = Date.now() + timeout;
|
|
@@ -3336,6 +2958,59 @@ function sleep(ms) {
|
|
|
3336
2958
|
async function sleepInner(ms) {
|
|
3337
2959
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3338
2960
|
}
|
|
2961
|
+
async function flashFactoryImage(conn, options, pcb) {
|
|
2962
|
+
const { image, label, downloadTarget } = options;
|
|
2963
|
+
pcb(`FACTORY ENB ${label}`, 0, 0);
|
|
2964
|
+
const enableReply = await conn.request(new FactoryEnableH2DPacket, FactoryEnableReplyD2HPacket);
|
|
2965
|
+
if (enableReply.isErr())
|
|
2966
|
+
return import_neverthrow2.err(enableReply.error);
|
|
2967
|
+
const writeRequest = {
|
|
2968
|
+
filename: "null.bin",
|
|
2969
|
+
vendor: 1 /* USER */,
|
|
2970
|
+
loadAddress: USER_FLASH_USR_CODE_START,
|
|
2971
|
+
buf: image.buf,
|
|
2972
|
+
downloadTarget,
|
|
2973
|
+
exttype: "bin",
|
|
2974
|
+
autoRun: true,
|
|
2975
|
+
linkedFile: undefined
|
|
2976
|
+
};
|
|
2977
|
+
const upload = await conn.uploadFileToDevice(writeRequest, (c, t) => {
|
|
2978
|
+
pcb(`UPLOAD ${label}`, c, t);
|
|
2979
|
+
});
|
|
2980
|
+
if (upload.isErr())
|
|
2981
|
+
return import_neverthrow2.err(upload.error);
|
|
2982
|
+
if (!upload.value) {
|
|
2983
|
+
return import_neverthrow2.err(new VexFirmwareError(`${label} upload was rejected by device`));
|
|
2984
|
+
}
|
|
2985
|
+
const deadline = Date.now() + 120000;
|
|
2986
|
+
while (Date.now() < deadline) {
|
|
2987
|
+
const statusReply = await conn.request(new FactoryStatusH2DPacket, FactoryStatusReplyD2HPacket, 1e4);
|
|
2988
|
+
if (statusReply.isErr())
|
|
2989
|
+
return import_neverthrow2.err(statusReply.error);
|
|
2990
|
+
reportFactoryStatus(label, statusReply.value, pcb);
|
|
2991
|
+
if (statusReply.value.status === 0 && statusReply.value.percent === 100) {
|
|
2992
|
+
return import_neverthrow2.ok(undefined);
|
|
2993
|
+
}
|
|
2994
|
+
await sleepInner(500);
|
|
2995
|
+
}
|
|
2996
|
+
return import_neverthrow2.err(new VexFirmwareError(`${label} factory status timed out`));
|
|
2997
|
+
}
|
|
2998
|
+
function reportFactoryStatus(label, reply, pcb) {
|
|
2999
|
+
switch (reply.status) {
|
|
3000
|
+
case 2:
|
|
3001
|
+
pcb(`ERASE ${label}`, reply.percent, 100);
|
|
3002
|
+
break;
|
|
3003
|
+
case 3:
|
|
3004
|
+
pcb(`WRITE ${label}`, reply.percent, 100);
|
|
3005
|
+
break;
|
|
3006
|
+
case 4:
|
|
3007
|
+
pcb(`VERIFY ${label}`, reply.percent, 100);
|
|
3008
|
+
break;
|
|
3009
|
+
case 8:
|
|
3010
|
+
pcb(`FINISHING ${label}`, reply.percent, 100);
|
|
3011
|
+
break;
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3339
3014
|
async function extractFirmwareImages(usingVersion, vexos) {
|
|
3340
3015
|
const { unzip } = await import("unzipit");
|
|
3341
3016
|
const { entries } = await unzip(vexos);
|
|
@@ -3383,7 +3058,7 @@ async function extractFirmwareImages(usingVersion, vexos) {
|
|
|
3383
3058
|
return ordered;
|
|
3384
3059
|
}
|
|
3385
3060
|
function uploadFirmware(state, publicUrl = "https://content.vexrobotics.com/vexos/public/V5/", usingVersion, progressCallback) {
|
|
3386
|
-
return
|
|
3061
|
+
return new import_neverthrow2.ResultAsync(runUploadFirmware(state, publicUrl, usingVersion, progressCallback));
|
|
3387
3062
|
}
|
|
3388
3063
|
async function runUploadFirmware(state, publicUrl, usingVersion, progressCallback) {
|
|
3389
3064
|
const device = state._instance;
|
|
@@ -3425,12 +3100,7 @@ async function runUploadFirmware(state, publicUrl, usingVersion, progressCallbac
|
|
|
3425
3100
|
return import_neverthrow2.err(toVexSerialError(e, "firmware"));
|
|
3426
3101
|
}
|
|
3427
3102
|
pcb("UNZIP VEXOS", 1, 1);
|
|
3428
|
-
return state.
|
|
3429
|
-
pcb("FACTORY ENB BOOT", 0, 0);
|
|
3430
|
-
const result = await conn.writeDataAsync(new FactoryEnableH2DPacket);
|
|
3431
|
-
if (!(result instanceof FactoryEnableReplyD2HPacket)) {
|
|
3432
|
-
return import_neverthrow2.err(new VexProtocolError("FactoryEnableH2DPacket failed"));
|
|
3433
|
-
}
|
|
3103
|
+
return state.withRefreshPaused(async () => {
|
|
3434
3104
|
const boot = images.find((image) => image.name.endsWith("BOOT.bin"));
|
|
3435
3105
|
if (boot === undefined) {
|
|
3436
3106
|
return import_neverthrow2.err(new VexFirmwareError("VEXos archive is missing BOOT.bin"));
|
|
@@ -3439,105 +3109,20 @@ async function runUploadFirmware(state, publicUrl, usingVersion, progressCallbac
|
|
|
3439
3109
|
if (assertImage === undefined) {
|
|
3440
3110
|
return import_neverthrow2.err(new VexFirmwareError("VEXos archive is missing assets.bin"));
|
|
3441
3111
|
}
|
|
3442
|
-
const
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
return import_neverthrow2.err(bootUpload.error);
|
|
3457
|
-
if (!bootUpload.value)
|
|
3458
|
-
return import_neverthrow2.ok(false);
|
|
3459
|
-
const bootDeadline = Date.now() + 120000;
|
|
3460
|
-
let bootComplete = false;
|
|
3461
|
-
while (Date.now() < bootDeadline) {
|
|
3462
|
-
const result3 = await conn.writeDataAsync(new FactoryStatusH2DPacket, 1e4);
|
|
3463
|
-
if (result3 instanceof FactoryStatusReplyD2HPacket) {
|
|
3464
|
-
switch (result3.status) {
|
|
3465
|
-
case 2:
|
|
3466
|
-
pcb("ERASE BOOT", result3.percent, 100);
|
|
3467
|
-
break;
|
|
3468
|
-
case 3:
|
|
3469
|
-
pcb("WRITE BOOT", result3.percent, 100);
|
|
3470
|
-
break;
|
|
3471
|
-
case 4:
|
|
3472
|
-
pcb("VERIFY BOOT", result3.percent, 100);
|
|
3473
|
-
break;
|
|
3474
|
-
case 8:
|
|
3475
|
-
pcb("FINISHING BOOT", result3.percent, 100);
|
|
3476
|
-
break;
|
|
3477
|
-
}
|
|
3478
|
-
if (result3.status === 0 && result3.percent === 100) {
|
|
3479
|
-
bootComplete = true;
|
|
3480
|
-
break;
|
|
3481
|
-
}
|
|
3482
|
-
} else {
|
|
3483
|
-
return import_neverthrow2.ok(false);
|
|
3484
|
-
}
|
|
3485
|
-
await sleepInner(500);
|
|
3486
|
-
}
|
|
3487
|
-
if (!bootComplete)
|
|
3488
|
-
return import_neverthrow2.ok(false);
|
|
3489
|
-
pcb("FACTORY ENB ASSERT", 0, 0);
|
|
3490
|
-
const result5 = await conn.writeDataAsync(new FactoryEnableH2DPacket);
|
|
3491
|
-
if (!(result5 instanceof FactoryEnableReplyD2HPacket)) {
|
|
3492
|
-
return import_neverthrow2.err(new VexProtocolError("FactoryEnableH2DPacket failed"));
|
|
3493
|
-
}
|
|
3494
|
-
const assertWriteRequest = {
|
|
3495
|
-
filename: "null.bin",
|
|
3496
|
-
vendor: 1 /* USER */,
|
|
3497
|
-
loadAddress: USER_FLASH_USR_CODE_START,
|
|
3498
|
-
buf: assertImage.buf,
|
|
3499
|
-
downloadTarget: 13 /* FILE_TARGET_A1 */,
|
|
3500
|
-
exttype: "bin",
|
|
3501
|
-
autoRun: true,
|
|
3502
|
-
linkedFile: undefined
|
|
3503
|
-
};
|
|
3504
|
-
const assertUpload = await conn.uploadFileToDevice(assertWriteRequest, (c, t) => {
|
|
3505
|
-
pcb("UPLOAD ASSERT", c, t);
|
|
3506
|
-
});
|
|
3507
|
-
if (assertUpload.isErr())
|
|
3508
|
-
return import_neverthrow2.err(assertUpload.error);
|
|
3509
|
-
if (!assertUpload.value)
|
|
3510
|
-
return import_neverthrow2.ok(false);
|
|
3511
|
-
const assertDeadline = Date.now() + 120000;
|
|
3512
|
-
let assertComplete = false;
|
|
3513
|
-
while (Date.now() < assertDeadline) {
|
|
3514
|
-
const result7 = await conn.writeDataAsync(new FactoryStatusH2DPacket, 1e4);
|
|
3515
|
-
if (result7 instanceof FactoryStatusReplyD2HPacket) {
|
|
3516
|
-
switch (result7.status) {
|
|
3517
|
-
case 2:
|
|
3518
|
-
pcb("ERASE ASSERT", result7.percent, 100);
|
|
3519
|
-
break;
|
|
3520
|
-
case 3:
|
|
3521
|
-
pcb("WRITE ASSERT", result7.percent, 100);
|
|
3522
|
-
break;
|
|
3523
|
-
case 4:
|
|
3524
|
-
pcb("VERIFY ASSERT", result7.percent, 100);
|
|
3525
|
-
break;
|
|
3526
|
-
case 8:
|
|
3527
|
-
pcb("FINISHING ASSERT", result7.percent, 100);
|
|
3528
|
-
break;
|
|
3529
|
-
}
|
|
3530
|
-
if (result7.status === 0 && result7.percent === 100) {
|
|
3531
|
-
assertComplete = true;
|
|
3532
|
-
break;
|
|
3533
|
-
}
|
|
3534
|
-
} else {
|
|
3535
|
-
return import_neverthrow2.ok(false);
|
|
3536
|
-
}
|
|
3537
|
-
await sleepInner(500);
|
|
3538
|
-
}
|
|
3539
|
-
if (!assertComplete)
|
|
3540
|
-
return import_neverthrow2.ok(false);
|
|
3112
|
+
const bootFlash = await flashFactoryImage(conn, {
|
|
3113
|
+
image: boot,
|
|
3114
|
+
label: "BOOT",
|
|
3115
|
+
downloadTarget: 14 /* FILE_TARGET_B1 */
|
|
3116
|
+
}, pcb);
|
|
3117
|
+
if (bootFlash.isErr())
|
|
3118
|
+
return import_neverthrow2.err(bootFlash.error);
|
|
3119
|
+
const assetsFlash = await flashFactoryImage(conn, {
|
|
3120
|
+
image: assertImage,
|
|
3121
|
+
label: "ASSETS",
|
|
3122
|
+
downloadTarget: 13 /* FILE_TARGET_A1 */
|
|
3123
|
+
}, pcb);
|
|
3124
|
+
if (assetsFlash.isErr())
|
|
3125
|
+
return import_neverthrow2.err(assetsFlash.error);
|
|
3541
3126
|
return import_neverthrow2.ok(true);
|
|
3542
3127
|
});
|
|
3543
3128
|
}
|
|
@@ -3550,8 +3135,7 @@ function getValue(state, key) {
|
|
|
3550
3135
|
if (conn == null || !conn.isConnected) {
|
|
3551
3136
|
return import_neverthrow3.err(new VexNotConnectedError);
|
|
3552
3137
|
}
|
|
3553
|
-
|
|
3554
|
-
return result instanceof ReadKeyValueReplyD2HPacket ? import_neverthrow3.ok(result.value) : import_neverthrow3.err(new VexProtocolError("getValue was not acknowledged"));
|
|
3138
|
+
return conn.request(new ReadKeyValueH2DPacket(key), ReadKeyValueReplyD2HPacket).map((result) => result.value);
|
|
3555
3139
|
})());
|
|
3556
3140
|
}
|
|
3557
3141
|
function setValue(state, key, value) {
|
|
@@ -3560,8 +3144,9 @@ function setValue(state, key, value) {
|
|
|
3560
3144
|
if (conn == null || !conn.isConnected) {
|
|
3561
3145
|
return import_neverthrow3.err(new VexNotConnectedError);
|
|
3562
3146
|
}
|
|
3563
|
-
|
|
3564
|
-
|
|
3147
|
+
return conn.request(new WriteKeyValueH2DPacket(key, value), WriteKeyValueReplyD2HPacket).map(() => {
|
|
3148
|
+
return;
|
|
3149
|
+
});
|
|
3565
3150
|
})());
|
|
3566
3151
|
}
|
|
3567
3152
|
function listFiles(state, vendor = 1 /* USER */) {
|
|
@@ -3570,26 +3155,24 @@ function listFiles(state, vendor = 1 /* USER */) {
|
|
|
3570
3155
|
if (conn == null || !conn.isConnected) {
|
|
3571
3156
|
return import_neverthrow3.err(new VexNotConnectedError);
|
|
3572
3157
|
}
|
|
3573
|
-
const
|
|
3574
|
-
if (
|
|
3575
|
-
return import_neverthrow3.err(
|
|
3576
|
-
}
|
|
3158
|
+
const countResult = await conn.request(new GetDirectoryFileCountH2DPacket(vendor), GetDirectoryFileCountReplyD2HPacket);
|
|
3159
|
+
if (countResult.isErr())
|
|
3160
|
+
return import_neverthrow3.err(countResult.error);
|
|
3577
3161
|
const files = [];
|
|
3578
|
-
for (let i = 0;i <
|
|
3579
|
-
const
|
|
3580
|
-
if (
|
|
3581
|
-
return import_neverthrow3.err(
|
|
3582
|
-
|
|
3583
|
-
if (result2.file != null) {
|
|
3162
|
+
for (let i = 0;i < countResult.value.count; i++) {
|
|
3163
|
+
const entryResult = await conn.request(new GetDirectoryEntryH2DPacket(i), GetDirectoryEntryReplyD2HPacket);
|
|
3164
|
+
if (entryResult.isErr())
|
|
3165
|
+
return import_neverthrow3.err(entryResult.error);
|
|
3166
|
+
if (entryResult.value.file != null) {
|
|
3584
3167
|
files.push({
|
|
3585
|
-
filename:
|
|
3168
|
+
filename: entryResult.value.file.filename,
|
|
3586
3169
|
vendor,
|
|
3587
|
-
loadAddress:
|
|
3588
|
-
size:
|
|
3589
|
-
crc32:
|
|
3590
|
-
type:
|
|
3591
|
-
timestamp:
|
|
3592
|
-
version:
|
|
3170
|
+
loadAddress: entryResult.value.file.loadAddress,
|
|
3171
|
+
size: entryResult.value.file.size,
|
|
3172
|
+
crc32: entryResult.value.file.crc32,
|
|
3173
|
+
type: entryResult.value.file.type,
|
|
3174
|
+
timestamp: entryResult.value.file.timestamp,
|
|
3175
|
+
version: entryResult.value.file.version
|
|
3593
3176
|
});
|
|
3594
3177
|
}
|
|
3595
3178
|
}
|
|
@@ -3625,10 +3208,10 @@ function listProgram(state) {
|
|
|
3625
3208
|
time: n,
|
|
3626
3209
|
requestedSlot: -1
|
|
3627
3210
|
};
|
|
3628
|
-
const
|
|
3629
|
-
if (
|
|
3630
|
-
program.slot =
|
|
3631
|
-
program.requestedSlot =
|
|
3211
|
+
const slotInfo = await conn.request(new GetProgramSlotInfoH2DPacket(1 /* USER */, program.binfile), GetProgramSlotInfoReplyD2HPacket);
|
|
3212
|
+
if (slotInfo.isOk()) {
|
|
3213
|
+
program.slot = slotInfo.value.slot;
|
|
3214
|
+
program.requestedSlot = slotInfo.value.requestedSlot;
|
|
3632
3215
|
}
|
|
3633
3216
|
programList.push(program);
|
|
3634
3217
|
}
|
|
@@ -3647,7 +3230,7 @@ function readFile(state, request, downloadTarget = 1 /* FILE_TARGET_QSPI */, pro
|
|
|
3647
3230
|
} else {
|
|
3648
3231
|
handle = request;
|
|
3649
3232
|
}
|
|
3650
|
-
return state.
|
|
3233
|
+
return state.withRefreshPaused(() => conn.downloadFileToHost(handle, downloadTarget, progressCallback));
|
|
3651
3234
|
})());
|
|
3652
3235
|
}
|
|
3653
3236
|
function removeFile(state, request) {
|
|
@@ -3656,7 +3239,7 @@ function removeFile(state, request) {
|
|
|
3656
3239
|
if (conn == null || !conn.isConnected) {
|
|
3657
3240
|
return import_neverthrow3.err(new VexNotConnectedError);
|
|
3658
3241
|
}
|
|
3659
|
-
return state.
|
|
3242
|
+
return state.withRefreshPaused(() => conn.removeFile(request));
|
|
3660
3243
|
})());
|
|
3661
3244
|
}
|
|
3662
3245
|
function removeAllFiles(state) {
|
|
@@ -3665,7 +3248,7 @@ function removeAllFiles(state) {
|
|
|
3665
3248
|
if (conn == null || !conn.isConnected) {
|
|
3666
3249
|
return import_neverthrow3.err(new VexNotConnectedError);
|
|
3667
3250
|
}
|
|
3668
|
-
return state.
|
|
3251
|
+
return state.withRefreshPaused(() => conn.removeAllFiles());
|
|
3669
3252
|
})());
|
|
3670
3253
|
}
|
|
3671
3254
|
function uploadProgram(state, iniConfig, binFileBuf, coldFileBuf, progressCallback) {
|
|
@@ -3678,7 +3261,7 @@ async function runUploadProgram(state, iniConfig, binFileBuf, coldFileBuf, progr
|
|
|
3678
3261
|
return import_neverthrow3.err(new VexNotConnectedError);
|
|
3679
3262
|
}
|
|
3680
3263
|
let switchedToDownload = false;
|
|
3681
|
-
return state.
|
|
3264
|
+
return state.withRefreshPaused(async () => {
|
|
3682
3265
|
try {
|
|
3683
3266
|
if (device.isV5Controller) {
|
|
3684
3267
|
await sleep(250);
|
|
@@ -3737,7 +3320,7 @@ function writeFile(state, request, progressCallback) {
|
|
|
3737
3320
|
if (conn == null || !conn.isConnected) {
|
|
3738
3321
|
return import_neverthrow3.err(new VexNotConnectedError);
|
|
3739
3322
|
}
|
|
3740
|
-
return state.
|
|
3323
|
+
return state.withRefreshPaused(() => conn.uploadFileToDevice(request, progressCallback));
|
|
3741
3324
|
})());
|
|
3742
3325
|
}
|
|
3743
3326
|
function captureScreen(state, progressCallback) {
|
|
@@ -3746,7 +3329,7 @@ function captureScreen(state, progressCallback) {
|
|
|
3746
3329
|
if (conn == null || !conn.isConnected) {
|
|
3747
3330
|
return import_neverthrow3.err(new VexNotConnectedError);
|
|
3748
3331
|
}
|
|
3749
|
-
return state.
|
|
3332
|
+
return state.withRefreshPaused(() => conn.captureScreen(progressCallback));
|
|
3750
3333
|
})());
|
|
3751
3334
|
}
|
|
3752
3335
|
|
|
@@ -3769,10 +3352,13 @@ class VexSerialDevice extends VexEventTarget {
|
|
|
3769
3352
|
class V5SerialDeviceState {
|
|
3770
3353
|
_instance;
|
|
3771
3354
|
refreshPauseDepth = 0;
|
|
3772
|
-
get
|
|
3355
|
+
get isRefreshPaused() {
|
|
3773
3356
|
return this.refreshPauseDepth > 0;
|
|
3774
3357
|
}
|
|
3775
|
-
|
|
3358
|
+
get isFileTransferring() {
|
|
3359
|
+
return this.isRefreshPaused;
|
|
3360
|
+
}
|
|
3361
|
+
async withRefreshPaused(operation) {
|
|
3776
3362
|
this.refreshPauseDepth++;
|
|
3777
3363
|
try {
|
|
3778
3364
|
return await operation();
|
|
@@ -3780,6 +3366,9 @@ class V5SerialDeviceState {
|
|
|
3780
3366
|
this.refreshPauseDepth--;
|
|
3781
3367
|
}
|
|
3782
3368
|
}
|
|
3369
|
+
async withFileTransfer(operation) {
|
|
3370
|
+
return this.withRefreshPaused(operation);
|
|
3371
|
+
}
|
|
3783
3372
|
brain = {
|
|
3784
3373
|
activeProgram: 0,
|
|
3785
3374
|
battery: {
|
|
@@ -3809,7 +3398,8 @@ class V5SerialDeviceState {
|
|
|
3809
3398
|
},
|
|
3810
3399
|
{
|
|
3811
3400
|
battery: 0,
|
|
3812
|
-
isAvailable: false
|
|
3401
|
+
isAvailable: false,
|
|
3402
|
+
isCharging: false
|
|
3813
3403
|
}
|
|
3814
3404
|
];
|
|
3815
3405
|
devices = [];
|
|
@@ -3832,8 +3422,14 @@ class V5SerialDeviceState {
|
|
|
3832
3422
|
|
|
3833
3423
|
class V5Brain {
|
|
3834
3424
|
state;
|
|
3425
|
+
batteryFacade;
|
|
3426
|
+
buttonFacade;
|
|
3427
|
+
settingsFacade;
|
|
3835
3428
|
constructor(state) {
|
|
3836
3429
|
this.state = state;
|
|
3430
|
+
this.batteryFacade = new V5Battery(state);
|
|
3431
|
+
this.buttonFacade = new V5BrainButton(state);
|
|
3432
|
+
this.settingsFacade = new V5BrainSettings(state);
|
|
3837
3433
|
}
|
|
3838
3434
|
get isRunningProgram() {
|
|
3839
3435
|
return this.activeProgram !== 0;
|
|
@@ -3866,9 +3462,8 @@ class V5Brain {
|
|
|
3866
3462
|
const reply = await conn.runProgram(slot);
|
|
3867
3463
|
if (reply.isErr())
|
|
3868
3464
|
return import_neverthrow4.err(reply.error);
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
this.state.brain.activeProgram = slotNumber;
|
|
3465
|
+
if (typeof slot === "number")
|
|
3466
|
+
this.state.brain.activeProgram = slot;
|
|
3872
3467
|
return import_neverthrow4.ok(undefined);
|
|
3873
3468
|
})());
|
|
3874
3469
|
}
|
|
@@ -3885,10 +3480,10 @@ class V5Brain {
|
|
|
3885
3480
|
})());
|
|
3886
3481
|
}
|
|
3887
3482
|
get battery() {
|
|
3888
|
-
return
|
|
3483
|
+
return this.batteryFacade;
|
|
3889
3484
|
}
|
|
3890
3485
|
get button() {
|
|
3891
|
-
return
|
|
3486
|
+
return this.buttonFacade;
|
|
3892
3487
|
}
|
|
3893
3488
|
get cpu0Version() {
|
|
3894
3489
|
return this.state.brain.cpu0Version;
|
|
@@ -3900,7 +3495,7 @@ class V5Brain {
|
|
|
3900
3495
|
return this.state.brain.isAvailable;
|
|
3901
3496
|
}
|
|
3902
3497
|
get settings() {
|
|
3903
|
-
return
|
|
3498
|
+
return this.settingsFacade;
|
|
3904
3499
|
}
|
|
3905
3500
|
get systemVersion() {
|
|
3906
3501
|
return this.state.brain.systemVersion;
|
|
@@ -4055,18 +3650,29 @@ class V5Radio {
|
|
|
4055
3650
|
}
|
|
4056
3651
|
changeChannel(channel) {
|
|
4057
3652
|
return new import_neverthrow4.ResultAsync((async () => {
|
|
4058
|
-
const
|
|
4059
|
-
|
|
3653
|
+
const conn = this.state._instance.connection;
|
|
3654
|
+
if (conn == null || !conn.isConnected) {
|
|
3655
|
+
return import_neverthrow4.err(new VexNotConnectedError);
|
|
3656
|
+
}
|
|
3657
|
+
return conn.request(new FileControlH2DPacket(1, channel), FileControlReplyD2HPacket).map(() => {
|
|
3658
|
+
return;
|
|
3659
|
+
});
|
|
4060
3660
|
})());
|
|
4061
3661
|
}
|
|
4062
3662
|
}
|
|
4063
3663
|
|
|
4064
3664
|
// src/VexDevice.ts
|
|
4065
3665
|
var import_neverthrow5 = __toESM(require_index_cjs(), 1);
|
|
3666
|
+
function unrefTimerIfPossible(timer) {
|
|
3667
|
+
if (typeof timer !== "object" || timer === null || !("unref" in timer))
|
|
3668
|
+
return;
|
|
3669
|
+
const unref = timer.unref;
|
|
3670
|
+
if (typeof unref === "function")
|
|
3671
|
+
unref.call(timer);
|
|
3672
|
+
}
|
|
4066
3673
|
|
|
4067
3674
|
class V5SerialDevice extends VexSerialDevice {
|
|
4068
3675
|
autoReconnect = true;
|
|
4069
|
-
autoRefresh = true;
|
|
4070
3676
|
pauseRefreshOnFileTransfer = true;
|
|
4071
3677
|
_isReconnecting = false;
|
|
4072
3678
|
_isDisconnecting = false;
|
|
@@ -4074,19 +3680,45 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4074
3680
|
state = new V5SerialDeviceState(this);
|
|
4075
3681
|
_disposed = false;
|
|
4076
3682
|
_refreshGeneration = 0;
|
|
4077
|
-
|
|
3683
|
+
_autoRefresh = false;
|
|
3684
|
+
_isLastRefreshComplete = true;
|
|
3685
|
+
_brain = new V5Brain(this.state);
|
|
3686
|
+
_controllers = [
|
|
3687
|
+
new V5Controller(this.state, 0),
|
|
3688
|
+
new V5Controller(this.state, 1)
|
|
3689
|
+
];
|
|
3690
|
+
_radio = new V5Radio(this.state);
|
|
3691
|
+
_deviceFacades = [];
|
|
3692
|
+
constructor(defaultSerial, autoRefresh = false) {
|
|
4078
3693
|
super(defaultSerial);
|
|
4079
|
-
|
|
3694
|
+
this.autoRefresh = autoRefresh;
|
|
3695
|
+
}
|
|
3696
|
+
get autoRefresh() {
|
|
3697
|
+
return this._autoRefresh;
|
|
3698
|
+
}
|
|
3699
|
+
set autoRefresh(value) {
|
|
3700
|
+
if (this._autoRefresh === value)
|
|
3701
|
+
return;
|
|
3702
|
+
this._autoRefresh = value;
|
|
3703
|
+
if (value) {
|
|
3704
|
+
this._startRefreshInterval();
|
|
3705
|
+
} else {
|
|
3706
|
+
this._stopRefreshInterval();
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
_startRefreshInterval() {
|
|
3710
|
+
if (this._refreshInterval !== undefined || this._disposed)
|
|
3711
|
+
return;
|
|
4080
3712
|
this._refreshInterval = setInterval(() => {
|
|
4081
3713
|
if (this._disposed)
|
|
4082
3714
|
return;
|
|
4083
|
-
if (this.
|
|
3715
|
+
if (this._autoRefresh && this._isLastRefreshComplete) {
|
|
4084
3716
|
if (!this.isConnected) {
|
|
4085
3717
|
this.state.brain.isAvailable = false;
|
|
4086
3718
|
return;
|
|
4087
3719
|
}
|
|
4088
|
-
if (!this.pauseRefreshOnFileTransfer || !this.state.
|
|
4089
|
-
|
|
3720
|
+
if (!this.pauseRefreshOnFileTransfer || !this.state.isRefreshPaused) {
|
|
3721
|
+
this._isLastRefreshComplete = false;
|
|
4090
3722
|
(async () => {
|
|
4091
3723
|
try {
|
|
4092
3724
|
const r = await this.refresh();
|
|
@@ -4095,27 +3727,37 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4095
3727
|
} catch (error) {
|
|
4096
3728
|
this.emit("error", error);
|
|
4097
3729
|
} finally {
|
|
4098
|
-
|
|
3730
|
+
this._isLastRefreshComplete = true;
|
|
4099
3731
|
}
|
|
4100
3732
|
})();
|
|
4101
3733
|
}
|
|
4102
3734
|
}
|
|
4103
3735
|
}, 200);
|
|
3736
|
+
unrefTimerIfPossible(this._refreshInterval);
|
|
3737
|
+
}
|
|
3738
|
+
_stopRefreshInterval() {
|
|
3739
|
+
if (this._refreshInterval === undefined)
|
|
3740
|
+
return;
|
|
3741
|
+
clearInterval(this._refreshInterval);
|
|
3742
|
+
this._refreshInterval = undefined;
|
|
4104
3743
|
}
|
|
4105
3744
|
get isV5Controller() {
|
|
4106
3745
|
return this.deviceType === 1283 /* V5_CONTROLLER */;
|
|
4107
3746
|
}
|
|
4108
3747
|
get brain() {
|
|
4109
|
-
return
|
|
3748
|
+
return this._brain;
|
|
4110
3749
|
}
|
|
4111
3750
|
get controllers() {
|
|
4112
|
-
return
|
|
3751
|
+
return this._controllers;
|
|
4113
3752
|
}
|
|
4114
3753
|
get devices() {
|
|
4115
3754
|
const rtn = [];
|
|
4116
|
-
for (let i = 1;i
|
|
4117
|
-
if (this.state.devices[i] != null)
|
|
4118
|
-
|
|
3755
|
+
for (let i = 1;i < this.state.devices.length; i++) {
|
|
3756
|
+
if (this.state.devices[i] != null) {
|
|
3757
|
+
const facade = this._deviceFacades[i] ?? new V5SmartDevice(this.state, i);
|
|
3758
|
+
this._deviceFacades[i] = facade;
|
|
3759
|
+
rtn.push(facade);
|
|
3760
|
+
}
|
|
4119
3761
|
}
|
|
4120
3762
|
return rtn;
|
|
4121
3763
|
}
|
|
@@ -4140,7 +3782,7 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4140
3782
|
})());
|
|
4141
3783
|
}
|
|
4142
3784
|
get radio() {
|
|
4143
|
-
return
|
|
3785
|
+
return this._radio;
|
|
4144
3786
|
}
|
|
4145
3787
|
mockTouch(x, y, press) {
|
|
4146
3788
|
return new import_neverthrow5.ResultAsync((async () => {
|
|
@@ -4161,7 +3803,7 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4161
3803
|
if (conn != null) {
|
|
4162
3804
|
if (!conn.isConnected) {
|
|
4163
3805
|
const opened = await conn.open();
|
|
4164
|
-
if (opened.isErr() || opened.value !==
|
|
3806
|
+
if (opened.isErr() || opened.value !== "opened") {
|
|
4165
3807
|
return import_neverthrow5.err(new VexIoError("failed to open the supplied connection"));
|
|
4166
3808
|
}
|
|
4167
3809
|
}
|
|
@@ -4180,10 +3822,10 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4180
3822
|
await c.close();
|
|
4181
3823
|
return import_neverthrow5.err(result.error);
|
|
4182
3824
|
}
|
|
4183
|
-
if (result.value ===
|
|
3825
|
+
if (result.value === "no-port") {
|
|
4184
3826
|
return import_neverthrow5.err(new VexNotConnectedError("no V5 device was found"));
|
|
4185
3827
|
}
|
|
4186
|
-
if (
|
|
3828
|
+
if (result.value === "busy") {
|
|
4187
3829
|
await c.close();
|
|
4188
3830
|
continue;
|
|
4189
3831
|
}
|
|
@@ -4215,10 +3857,6 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4215
3857
|
this.autoReconnect = false;
|
|
4216
3858
|
this.autoRefresh = false;
|
|
4217
3859
|
this._disposed = true;
|
|
4218
|
-
if (this._refreshInterval !== undefined) {
|
|
4219
|
-
clearInterval(this._refreshInterval);
|
|
4220
|
-
this._refreshInterval = undefined;
|
|
4221
|
-
}
|
|
4222
3860
|
await this.disconnect();
|
|
4223
3861
|
}
|
|
4224
3862
|
reconnect(timeout = 0) {
|
|
@@ -4254,9 +3892,9 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4254
3892
|
await c.close();
|
|
4255
3893
|
return import_neverthrow5.err(result.error);
|
|
4256
3894
|
}
|
|
4257
|
-
if (result.value ===
|
|
3895
|
+
if (result.value === "no-port")
|
|
4258
3896
|
break;
|
|
4259
|
-
if (
|
|
3897
|
+
if (result.value === "busy") {
|
|
4260
3898
|
await c.close();
|
|
4261
3899
|
continue;
|
|
4262
3900
|
}
|
|
@@ -4299,7 +3937,10 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4299
3937
|
if (this.connection == null)
|
|
4300
3938
|
return;
|
|
4301
3939
|
this.connection.on("disconnected", (_data) => {
|
|
4302
|
-
if (this.
|
|
3940
|
+
if (this._isDisconnecting)
|
|
3941
|
+
return;
|
|
3942
|
+
this.emit("disconnected", undefined);
|
|
3943
|
+
if (this.autoReconnect) {
|
|
4303
3944
|
this.reconnect().mapErr((e) => this.emit("error", e));
|
|
4304
3945
|
}
|
|
4305
3946
|
});
|
|
@@ -4397,7 +4038,8 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4397
4038
|
},
|
|
4398
4039
|
{
|
|
4399
4040
|
battery: controller1Battery,
|
|
4400
|
-
isAvailable: controller1Available
|
|
4041
|
+
isAvailable: controller1Available,
|
|
4042
|
+
isCharging: (flags2 & 128) !== 0
|
|
4401
4043
|
}
|
|
4402
4044
|
],
|
|
4403
4045
|
radio: {
|
|
@@ -4464,23 +4106,22 @@ class IniSectionBuilder extends BaseIniBuilder {
|
|
|
4464
4106
|
this.keyTransform = keyTransform;
|
|
4465
4107
|
}
|
|
4466
4108
|
addSingleObjProperty(key, maxValueLength) {
|
|
4467
|
-
|
|
4109
|
+
const value = this.object[key];
|
|
4110
|
+
if (value == null || value.toString().length === 0)
|
|
4468
4111
|
return;
|
|
4469
4112
|
const formattedKey = this.keyTransform(key).padEnd(12).slice(0, 12);
|
|
4470
|
-
const trimmedVal =
|
|
4113
|
+
const trimmedVal = value.toString().slice(0, maxValueLength);
|
|
4471
4114
|
const escapedVal = trimmedVal.replace(/["\\\u0000-\u001f\u007f]/g, (character) => `\\x${character.charCodeAt(0).toString(16).padStart(2, "0")}`);
|
|
4472
4115
|
this.addLine(`${formattedKey} = "${escapedVal}"`);
|
|
4473
4116
|
}
|
|
4474
4117
|
addObjProperty(key, maxValueLength) {
|
|
4475
|
-
const
|
|
4476
|
-
for (const k of keys) {
|
|
4118
|
+
for (const k of Array.isArray(key) ? key : [key]) {
|
|
4477
4119
|
this.addSingleObjProperty(k, maxValueLength);
|
|
4478
4120
|
}
|
|
4479
4121
|
return this;
|
|
4480
4122
|
}
|
|
4481
4123
|
addAllObjProps(maxValueLength) {
|
|
4482
|
-
const
|
|
4483
|
-
for (const k of keys) {
|
|
4124
|
+
for (const k of Object.keys(this.object)) {
|
|
4484
4125
|
this.addSingleObjProperty(k, maxValueLength);
|
|
4485
4126
|
}
|
|
4486
4127
|
return this;
|
|
@@ -4509,21 +4150,15 @@ class ProgramIniConfig {
|
|
|
4509
4150
|
date: "",
|
|
4510
4151
|
timezone: "0"
|
|
4511
4152
|
};
|
|
4512
|
-
config = {};
|
|
4153
|
+
config = { 22: "adi" };
|
|
4513
4154
|
controller1 = {};
|
|
4514
4155
|
controller2 = {};
|
|
4515
|
-
constructor() {
|
|
4516
|
-
this.config = {
|
|
4517
|
-
22: "adi"
|
|
4518
|
-
};
|
|
4519
|
-
}
|
|
4520
4156
|
setProgramDate(date) {
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
const
|
|
4524
|
-
const
|
|
4525
|
-
|
|
4526
|
-
this.program.timezone = (d.getTimezoneOffset() > 0 ? "-" : "+") + this.dec2(tzh) + ":" + this.dec2(tzm);
|
|
4157
|
+
this.program.date = date.toISOString();
|
|
4158
|
+
const offset = Math.abs(date.getTimezoneOffset());
|
|
4159
|
+
const hours = offset / 60 >>> 0;
|
|
4160
|
+
const minutes = offset - hours * 60;
|
|
4161
|
+
this.program.timezone = (date.getTimezoneOffset() > 0 ? "-" : "+") + this.dec2(hours) + ":" + this.dec2(minutes);
|
|
4527
4162
|
}
|
|
4528
4163
|
createIni() {
|
|
4529
4164
|
if (this.program.date.length === 0) {
|
|
@@ -4532,10 +4167,9 @@ class ProgramIniConfig {
|
|
|
4532
4167
|
return new IniFileBuilder().addComment("").addComment("VEX program ini file").addComment("Generated by Vex V5 Serial Protocol Library").addComment("").addSection(new IniSectionBuilder("project", this.project).addObjProperty("ide", 16)).addComment("").addSection(new IniSectionBuilder("program", this.program).addObjProperty("name", 32).addObjProperty("description", 256).addObjProperty("icon", 16).addObjProperty("iconalt", 16).addObjProperty("slot", 16)).addComment("").addSection(new IniSectionBuilder("config", this.config, (k) => "port_" + this.dec2(k)).addAllObjProps()).addComment("").addSection(new IniSectionBuilder("controller_1", this.controller1).addAllObjProps()).addComment("").addSection(new IniSectionBuilder("controller_2", this.controller2).addAllObjProps()).getContent();
|
|
4533
4168
|
}
|
|
4534
4169
|
dec2(value) {
|
|
4535
|
-
|
|
4536
|
-
return str.toUpperCase();
|
|
4170
|
+
return (value % 100).toString(10).padStart(2, "0").toUpperCase();
|
|
4537
4171
|
}
|
|
4538
4172
|
}
|
|
4539
4173
|
|
|
4540
|
-
//# debugId=
|
|
4174
|
+
//# debugId=6C653363AF816C0D64756E2164756E21
|
|
4541
4175
|
//# sourceMappingURL=index.cjs.map
|