Feat/add js repo to monorepo (#683)

* feat: move js repo into web monorepo

* added readme

* Update packages/core/README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/transport-http/README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/transport-web-bluetooth/README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Dan Ditomaso
2025-06-26 11:52:57 -04:00
committed by GitHub
co-authored by Copilot
parent 1c13343e8a
commit 72edb1897f
34 changed files with 3249 additions and 24 deletions
+135
View File
@@ -0,0 +1,135 @@
import crc16ccitt from "crc/calculators/crc16ccitt";
import { create, toBinary } from "@bufbuild/protobuf";
import * as Protobuf from "@meshtastic/protobufs";
//if counter > 35 then reset counter/clear/error/reject promise
type XmodemProps = (toRadio: Uint8Array, id?: number) => Promise<number>;
export class Xmodem {
private sendRaw: XmodemProps;
private rxBuffer: Uint8Array[];
private txBuffer: Uint8Array[];
private textEncoder: TextEncoder;
private counter: number;
constructor(sendRaw: XmodemProps) {
this.sendRaw = sendRaw;
this.rxBuffer = [];
this.txBuffer = [];
this.textEncoder = new TextEncoder();
this.counter = 0;
}
async downloadFile(filename: string): Promise<number> {
return await this.sendCommand(
Protobuf.Xmodem.XModem_Control.STX,
this.textEncoder.encode(filename),
0,
);
}
async uploadFile(filename: string, data: Uint8Array): Promise<number> {
for (let i = 0; i < data.length; i += 128) {
this.txBuffer.push(data.slice(i, i + 128));
}
return await this.sendCommand(
Protobuf.Xmodem.XModem_Control.SOH,
this.textEncoder.encode(filename),
0,
);
}
async sendCommand(
command: Protobuf.Xmodem.XModem_Control,
buffer?: Uint8Array,
sequence?: number,
crc16?: number,
): Promise<number> {
const toRadio = create(Protobuf.Mesh.ToRadioSchema, {
payloadVariant: {
case: "xmodemPacket",
value: {
buffer,
control: command,
seq: sequence,
crc16: crc16,
},
},
});
return await this.sendRaw(toBinary(Protobuf.Mesh.ToRadioSchema, toRadio));
}
async handlePacket(packet: Protobuf.Xmodem.XModem): Promise<number> {
await new Promise((resolve) => setTimeout(resolve, 100));
switch (packet.control) {
case Protobuf.Xmodem.XModem_Control.NUL: {
// nothing
break;
}
case Protobuf.Xmodem.XModem_Control.SOH: {
this.counter = packet.seq;
if (this.validateCrc16(packet)) {
this.rxBuffer[this.counter] = packet.buffer;
return this.sendCommand(Protobuf.Xmodem.XModem_Control.ACK);
}
return await this.sendCommand(
Protobuf.Xmodem.XModem_Control.NAK,
undefined,
packet.seq,
);
}
case Protobuf.Xmodem.XModem_Control.STX: {
break;
}
case Protobuf.Xmodem.XModem_Control.EOT: {
// end of transmission
break;
}
case Protobuf.Xmodem.XModem_Control.ACK: {
this.counter++;
if (this.txBuffer[this.counter - 1]) {
return this.sendCommand(
Protobuf.Xmodem.XModem_Control.SOH,
this.txBuffer[this.counter - 1],
this.counter,
crc16ccitt(this.txBuffer[this.counter - 1] ?? new Uint8Array()),
);
}
if (this.counter === this.txBuffer.length + 1) {
return this.sendCommand(Protobuf.Xmodem.XModem_Control.EOT);
}
this.clear();
break;
}
case Protobuf.Xmodem.XModem_Control.NAK: {
return this.sendCommand(
Protobuf.Xmodem.XModem_Control.SOH,
this.txBuffer[this.counter],
this.counter,
crc16ccitt(this.txBuffer[this.counter - 1] ?? new Uint8Array()),
);
}
case Protobuf.Xmodem.XModem_Control.CAN: {
this.clear();
break;
}
case Protobuf.Xmodem.XModem_Control.CTRLZ: {
break;
}
}
return Promise.resolve(0);
}
validateCrc16(packet: Protobuf.Xmodem.XModem): boolean {
return crc16ccitt(packet.buffer) === packet.crc16;
}
clear() {
this.counter = 0;
this.rxBuffer = [];
this.txBuffer = [];
}
}