You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
4.9 KiB
186 lines
4.9 KiB
import { connType } from '@core/slices/appSlice';
|
|
import {
|
|
addChannel,
|
|
addChat,
|
|
addLogEvent,
|
|
addMessage,
|
|
addNode,
|
|
addPosition,
|
|
addRoute,
|
|
addUser,
|
|
resetState,
|
|
setDeviceStatus,
|
|
setLastMeshInterraction,
|
|
setMyNodeInfo,
|
|
setPreferences,
|
|
setReady,
|
|
updateLastInteraction,
|
|
} from '@core/slices/meshtasticSlice';
|
|
import { store } from '@core/store';
|
|
import {
|
|
IBLEConnection,
|
|
IHTTPConnection,
|
|
ISerialConnection,
|
|
Protobuf,
|
|
SettingsManager,
|
|
Types,
|
|
} from '@meshtastic/meshtasticjs';
|
|
|
|
type connectionType = IBLEConnection | IHTTPConnection | ISerialConnection;
|
|
|
|
export let connection: connectionType = new IHTTPConnection();
|
|
|
|
const state = store.getState().meshtastic;
|
|
export const connectionUrl = state.hostOverrideEnabled
|
|
? state.hostOverride
|
|
: import.meta.env.PROD
|
|
? window.location.hostname
|
|
: (import.meta.env.VITE_PUBLIC_DEVICE_IP as string) ?? 'meshtastic.local';
|
|
|
|
export const setConnection = async (conn: connType): Promise<void> => {
|
|
await connection.disconnect();
|
|
cleanupListeners();
|
|
switch (conn) {
|
|
case connType.HTTP:
|
|
connection = new IHTTPConnection();
|
|
break;
|
|
case connType.BLE:
|
|
connection = new IBLEConnection();
|
|
break;
|
|
case connType.SERIAL:
|
|
connection = new ISerialConnection();
|
|
break;
|
|
}
|
|
registerListeners();
|
|
const connectionParams = store.getState().app.connectionParams;
|
|
switch (conn) {
|
|
case connType.HTTP:
|
|
await connection.connect(connectionParams.HTTP);
|
|
break;
|
|
case connType.BLE:
|
|
await connection.connect(
|
|
// @ts-ignore tmp
|
|
connectionParams.BLE,
|
|
);
|
|
break;
|
|
case connType.SERIAL:
|
|
await connection.connect(
|
|
// @ts-ignore tmp
|
|
connectionParams.SERIAL,
|
|
);
|
|
break;
|
|
}
|
|
};
|
|
|
|
export const cleanupListeners = (): void => {
|
|
connection.onMeshPacket.cancelAll();
|
|
connection.onDeviceStatus.cancelAll();
|
|
connection.onMyNodeInfo.cancelAll();
|
|
connection.onUserPacket.cancelAll();
|
|
connection.onPositionPacket.cancelAll();
|
|
connection.onNodeInfoPacket.cancelAll();
|
|
connection.onAdminPacket.cancelAll();
|
|
connection.onMeshHeartbeat.cancelAll();
|
|
connection.onTextPacket.cancelAll();
|
|
};
|
|
|
|
const registerListeners = (): void => {
|
|
SettingsManager.debugMode = Protobuf.LogRecord_Level.TRACE;
|
|
|
|
connection.onLogEvent.subscribe((log) => {
|
|
store.dispatch(addLogEvent(log));
|
|
});
|
|
|
|
connection.onMeshPacket.subscribe((packet) => {
|
|
store.dispatch(
|
|
addRoute({
|
|
from: packet.from,
|
|
to:
|
|
packet.to === 0xffffffff
|
|
? store.getState().meshtastic.radio.hardware.myNodeNum
|
|
: packet.to,
|
|
hops: packet.hopLimit,
|
|
}),
|
|
);
|
|
});
|
|
|
|
connection.onDeviceStatus.subscribe((status) => {
|
|
store.dispatch(setDeviceStatus(status));
|
|
|
|
if (status === Types.DeviceStatusEnum.DEVICE_CONFIGURED) {
|
|
store.dispatch(setReady(true));
|
|
}
|
|
if (status === Types.DeviceStatusEnum.DEVICE_DISCONNECTED) {
|
|
store.dispatch(setReady(false));
|
|
store.dispatch(resetState());
|
|
cleanupListeners();
|
|
}
|
|
});
|
|
|
|
connection.onMyNodeInfo.subscribe((nodeInfo) => {
|
|
store.dispatch(setMyNodeInfo(nodeInfo));
|
|
});
|
|
|
|
connection.onUserPacket.subscribe((user) => {
|
|
store.dispatch(addUser(user));
|
|
});
|
|
|
|
connection.onPositionPacket.subscribe((position) => {
|
|
store.dispatch(addPosition(position));
|
|
});
|
|
|
|
connection.onNodeInfoPacket.subscribe(
|
|
(nodeInfoPacket): void | { payload: Protobuf.NodeInfo; type: string } => {
|
|
store.dispatch(addNode(nodeInfoPacket.data));
|
|
store.dispatch(addChat(nodeInfoPacket.data.num));
|
|
},
|
|
);
|
|
|
|
connection.onAdminPacket.subscribe((adminPacket) => {
|
|
switch (adminPacket.data.variant.oneofKind) {
|
|
case 'getChannelResponse':
|
|
store.dispatch(addChannel(adminPacket.data.variant.getChannelResponse));
|
|
store.dispatch(
|
|
addChat(adminPacket.data.variant.getChannelResponse.index),
|
|
);
|
|
break;
|
|
case 'getRadioResponse':
|
|
if (adminPacket.data.variant.getRadioResponse.preferences) {
|
|
store.dispatch(
|
|
setPreferences(
|
|
adminPacket.data.variant.getRadioResponse.preferences,
|
|
),
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
|
|
connection.onMeshHeartbeat.subscribe(
|
|
(date): void | { payload: number; type: string } =>
|
|
store.dispatch(setLastMeshInterraction(date.getTime())),
|
|
);
|
|
|
|
connection.onRoutingPacket.subscribe((routingPacket) => {
|
|
store.dispatch(
|
|
updateLastInteraction({
|
|
id: routingPacket.packet.from,
|
|
time: new Date(routingPacket.packet.rxTime * 1000),
|
|
}),
|
|
);
|
|
});
|
|
|
|
connection.onTextPacket.subscribe((message) => {
|
|
const myNodeNum = store.getState().meshtastic.radio.hardware.myNodeNum;
|
|
|
|
store.dispatch(
|
|
addMessage({
|
|
message: message,
|
|
ack: message.packet.from !== myNodeNum,
|
|
received: message.packet.rxTime
|
|
? new Date(message.packet.rxTime * 1000)
|
|
: new Date(),
|
|
}),
|
|
);
|
|
});
|
|
};
|
|
|