UNPKG

pxt-common-packages

Version:
164 lines (138 loc) 4.79 kB
namespace pxsim { export interface RadioBoard extends EventBusBoard { radioState: RadioState; } export function getRadioState() { return (board() as any as RadioBoard).radioState; } export interface PacketBuffer { payload: SimulatorRadioPacketPayload; rssi: number; serial: number; time: number; } // Extends interface in pxt-core export interface SimulatorRadioPacketPayload { bufferData?: Uint8Array; } export interface RadioDAL { ID_RADIO: number; RADIO_EVT_DATAGRAM: number; } export class RadioDatagram { datagram: PacketBuffer[] = []; lastReceived: PacketBuffer = RadioDatagram.defaultPacket(); // this value is unset until the user decide to set the RSSI via the simulator UI private _rssi: number; constructor(private runtime: Runtime, public dal: RadioDAL) { this._rssi = undefined; // not set yet } get rssi() { return this._rssi; } set rssi(value: number) { this._rssi = value | 0; } queue(packet: PacketBuffer) { if (this.datagram.length < 4) this.datagram.push(packet); (<EventBusBoard>runtime.board).bus.queue(this.dal.ID_RADIO, this.dal.RADIO_EVT_DATAGRAM); } send(payload: SimulatorRadioPacketPayload) { const state = getRadioState(); Runtime.postMessage(<SimulatorRadioPacketMessage>{ type: "radiopacket", broadcast: true, rssi: this._rssi || -75, serial: state.transmitSerialNumber ? pxsim.control.deviceSerialNumber() : 0, time: new Date().getTime(), payload }) } recv(): PacketBuffer { let r = this.datagram.shift(); if (!r) r = RadioDatagram.defaultPacket(); return this.lastReceived = r; } onReceived(handler: RefAction) { pxtcore.registerWithDal(this.dal.ID_RADIO, this.dal.RADIO_EVT_DATAGRAM, handler); this.recv(); } private static defaultPacket(): PacketBuffer { return { rssi: -1, serial: 0, time: 0, payload: { type: -1, groupId: 0, bufferData: new Uint8Array(0) } }; } } export class RadioState { power = 0; transmitSerialNumber = false; datagram: RadioDatagram; groupId: number; band: number; enable: boolean; constructor(private readonly runtime: Runtime, private readonly board: BaseBoard, dal: RadioDAL) { this.datagram = new RadioDatagram(runtime, dal); this.power = 6; // default value this.groupId = 0; this.band = 7; // https://github.com/lancaster-university/microbit-dal/blob/master/inc/core/MicroBitConfig.h#L320 this.enable = true; this.board.addMessageListener(this.handleMessage.bind(this)) } private handleMessage(msg: SimulatorMessage) { if (msg.type == "radiopacket") { let packet = <SimulatorRadioPacketMessage>msg; this.receivePacket(packet); } } public setGroup(id: number) { if (this.enable) { this.groupId = id & 0xff; // byte only } } setTransmitPower(power: number) { if (this.enable) { power = power | 0; this.power = Math.max(0, Math.min(7, power)); } } setTransmitSerialNumber(sn: boolean) { this.transmitSerialNumber = !!sn; } setFrequencyBand(band: number) { if (this.enable) { band = band | 0; if (band < 0 || band > 83) return; this.band = band; } } off() { this.enable = false; } on() { this.enable = true; } raiseEvent(id: number, eventid: number) { if (this.enable) { Runtime.postMessage(<SimulatorEventBusMessage>{ type: "eventbus", broadcast: true, id, eventid, power: this.power, group: this.groupId }) } } receivePacket(packet: SimulatorRadioPacketMessage) { if (this.enable) { if (this.groupId == packet.payload.groupId) { this.datagram.queue(packet) } } } } }