build static method
Build an outgoing packet.
Implementation
static Future<MiIOPacket> build(
final int deviceId,
final List<int> token, {
final Map<String, dynamic>? payload,
int? stamp,
}) async {
assert(token.length == 16);
stamp ??= MiIO.instance.stampOf(deviceId) ?? 600;
Uint8List binary;
if (payload != null) {
// Variable sized payload.
final binPayload = await encrypt(
utf8.encode(jsonEncode(payload)),
token,
);
binary = Uint8List(0x20 + binPayload.length)..setAll(0x20, binPayload);
} else {
// Header only packet.
binary = Uint8List(0x20);
}
// 2 bytes magic.
binary[0] = magic >> 8;
binary[1] = magic & 0xFF;
// 2 bytes length.
binary[2] = binary.length >> 8;
binary[3] = binary.length & 0xFF;
// 4 bytes unknown field `0x00000000`.
binary.fillRange(4, 8, 0);
// 4 bytes device ID.
var deviceIdToWrite = deviceId;
for (var i = 11; i >= 8; --i, deviceIdToWrite >>= 8) {
binary[i] = deviceIdToWrite & 0xFF;
}
// 4 bytes stamp.
var stampToWrite = stamp;
for (var i = 15; i >= 12; --i, stampToWrite >>= 8) {
binary[i] = stampToWrite & 0xFF;
}
// Initialize checksum field with token.
binary.setAll(16, token);
// 16 bytes MD5 checksum.
final checksum = md5.convert(binary).bytes;
binary.setAll(16, checksum);
return MiIOPacket._(
length: binary.length,
unknown: 0x00000000,
deviceId: deviceId,
stamp: stamp,
token: token,
checksum: checksum,
payload: payload,
binary: binary,
);
}