zwave-js
Version:
Z-Wave driver written entirely in JavaScript/TypeScript
88 lines • 3.27 kB
JavaScript
import { StateMachine, } from "@zwave-js/core";
function to(state) {
return { newState: state };
}
export function createTransportServiceRXMachine(datagramSize, firstSegmentSize) {
const initialState = {
value: "receive",
};
const receivedBytes = [
// When the machine is started, we've already received the first segment
...(Array.from({ length: firstSegmentSize })
.fill(true)),
// The rest of the segments are still missing
...(Array.from({ length: datagramSize - firstSegmentSize })
.fill(false)),
];
function markReceived(offset, length) {
for (let i = offset; i < offset + length; i++) {
receivedBytes[i] = true;
}
}
function isComplete() {
return receivedBytes.every(Boolean);
}
function hasReceivedLastSegment() {
return receivedBytes.at(-1);
}
function hasHole() {
return receivedBytes.lastIndexOf(true)
> receivedBytes.indexOf(false);
}
const transitions = (state) => (input) => {
if (input.value === "abort") {
if (state.value !== "success" && state.value !== "failure") {
return to({ value: "failure", done: true });
}
return;
}
switch (state.value) {
case "receive": {
if (input.value === "segment") {
markReceived(input.offset, input.length);
if (isComplete()) {
return to({ value: "success", done: true });
}
else if (hasReceivedLastSegment() && hasHole()) {
return to({
value: "requestMissing",
offset: receivedBytes.indexOf(false),
});
}
else {
return to({ value: "receive" });
}
}
else if (input.value === "timeout") {
// One or more segments are missing, start requesting them
return to({
value: "requestMissing",
offset: receivedBytes.indexOf(false),
});
}
break;
}
case "requestMissing": {
if (input.value === "segment") {
markReceived(input.offset, input.length);
if (isComplete()) {
return to({ value: "success", done: true });
}
else {
// still not complete, request the next missing segment
return to({
value: "requestMissing",
offset: receivedBytes.indexOf(false),
});
}
}
else if (input.value === "timeout") {
// Give up
return to({ value: "failure", done: true });
}
}
}
};
return new StateMachine(initialState, transitions);
}
//# sourceMappingURL=TransportServiceMachine.js.map