From 0931bdfecb0c11fc731800539f22ebe29899cd79 Mon Sep 17 00:00:00 2001 From: AmyangXYZ Date: Thu, 28 Dec 2023 21:47:58 -0500 Subject: [PATCH] adding flows --- src/components/PacketSniffer.vue | 13 +++- src/hooks/useDrawTopology.ts | 57 ++++++++++---- src/hooks/useStates.ts | 8 +- src/networks/5G/network.ts | 13 ++-- src/networks/5G/typedefs.ts | 5 ++ src/networks/TSCH/network.ts | 32 ++++---- src/networks/TSCH/node.ts | 51 ++++++------ src/networks/TSCH/typedefs.ts | 28 +------ src/networks/TSN/network.ts | 11 +-- src/networks/TSN/node.ts | 43 ++++++++-- src/networks/TSN/typedefs.ts | 18 +---- src/networks/common.ts | 130 ++++++------------------------- src/networks/es.ts | 52 +++++++++++++ src/networks/{TSN => }/kdtree.ts | 0 src/networks/network.ts | 129 ++++++++++++++++++++++++++++++ 15 files changed, 367 insertions(+), 223 deletions(-) create mode 100644 src/networks/es.ts rename src/networks/{TSN => }/kdtree.ts (100%) create mode 100644 src/networks/network.ts diff --git a/src/components/PacketSniffer.vue b/src/components/PacketSniffer.vue index 7b13541..5362799 100644 --- a/src/components/PacketSniffer.vue +++ b/src/components/PacketSniffer.vue @@ -3,10 +3,13 @@ import ChannelChart from '@/components/ChannelChart.vue' import { ref, watch, nextTick } from 'vue' import { Network } from '@/hooks/useStates' -import type { Packet } from '@/networks/common' -import { PKT_TYPES } from '@/networks/TSCH/typedefs' +import { NETWORK_TYPE, type Packet } from '@/networks/common' +import { TSCH_PKT_TYPE } from '@/networks/TSCH/typedefs' +import { TSN_PKT_TYPE } from '@/networks/TSN/typedefs' +import { FIVE_G_PKT_TYPE } from '@/networks/5G/typedefs' import { Filter } from '@element-plus/icons-vue' + const filterRules = ref() function filterFunc(pkt: Packet) { @@ -65,7 +68,11 @@ const columns: any = [ dataKey: 'type', width: 80, align: 'center', - cellRenderer: ({ cellData: type }: any) => PKT_TYPES[type] + cellRenderer: ({ cellData: type }: any) => { + if (Network.Type == NETWORK_TYPE.TSCH) return TSCH_PKT_TYPE[type] + if (Network.Type == NETWORK_TYPE.TSN) return TSN_PKT_TYPE[type] + if (Network.Type == NETWORK_TYPE.FIVE_G) return FIVE_G_PKT_TYPE[type] + } }, // { // key: 'seq', diff --git a/src/hooks/useDrawTopology.ts b/src/hooks/useDrawTopology.ts index 1d1e38d..95633c0 100644 --- a/src/hooks/useDrawTopology.ts +++ b/src/hooks/useDrawTopology.ts @@ -1,6 +1,6 @@ import { watch } from 'vue' import { Network, SelectedNode, SignalEditTopology, SignalResetCamera } from './useStates' -import { ADDR, PKT_TYPES } from '@/networks/TSCH/typedefs' +import { TSCH_PKT_TYPE } from '@/networks/TSCH/typedefs' import * as THREE from 'three' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' @@ -11,6 +11,7 @@ import * as TWEEN from '@tweenjs/tween.js' import { NODE_TYPE, NETWORK_TYPE, + ADDR, type Packet, type LinkMeta, LINK_TYPE, @@ -124,7 +125,7 @@ export function useDrawTopology(dom: HTMLElement) { case NETWORK_TYPE.TSN: drawTSNNodes() break - case NETWORK_TYPE.FiveG: + case NETWORK_TYPE.FIVE_G: drawFiveGBS() drawFiveGUE() break @@ -404,7 +405,7 @@ export function useDrawTopology(dom: HTMLElement) { } // Load and place models - loadAndPlaceModel('/models/server/scene.gltf', [.08, .08, .08], -Math.PI / 2, 1.9, 7, 0) + loadAndPlaceModel('/models/server/scene.gltf', [0.08, 0.08, 0.08], -Math.PI / 2, 1.9, 7, 0) loadAndPlaceModel( '/models/robotic_arm/scene.gltf', [0.004, 0.004, 0.004], @@ -449,7 +450,7 @@ export function useDrawTopology(dom: HTMLElement) { } } const drawLink = (l: LinkMeta) => { - let p1: THREE.Vector3 + let p1: THREE.Vector3, p3: THREE.Vector3 if (l.v1 <= Network.TopoConfig.value.num_nodes) { p1 = new THREE.Vector3( Network.Nodes.value[l.v1].pos[0], @@ -465,7 +466,6 @@ export function useDrawTopology(dom: HTMLElement) { ) } - let p3: THREE.Vector3 if (l.v2 <= Network.TopoConfig.value.num_nodes) { p3 = new THREE.Vector3( Network.Nodes.value[l.v2].pos[0], @@ -531,9 +531,10 @@ export function useDrawTopology(dom: HTMLElement) { const drawPackets = () => { time = 0 // reset animation timer for (const pkt of Network.PacketsCurrent.value) { - if (pkt.type != PKT_TYPES.ACK && pkt.dst != ADDR.BROADCAST) { + if (Network.Type == NETWORK_TYPE.TSCH && pkt.type == TSCH_PKT_TYPE.ACK) continue + if (pkt.dst != ADDR.BROADCAST) { drawUnicastPacket(pkt) - } else if (pkt.type == PKT_TYPES.BEACON) { + } else if (Network.Type == NETWORK_TYPE.TSCH && pkt.type == TSCH_PKT_TYPE.BEACON) { drawBeaconPacket(pkt) } } @@ -571,16 +572,38 @@ export function useDrawTopology(dom: HTMLElement) { const mesh = new THREE.Points(geometry, material) scene.add(mesh) - const p1 = new THREE.Vector3( - Network.Nodes.value[pkt.src].pos[0], - 1.6, - Network.Nodes.value[pkt.src].pos[1] - ) - const p3 = new THREE.Vector3( - Network.Nodes.value[pkt.dst].pos[0], - 1.6, - Network.Nodes.value[pkt.dst].pos[1] - ) + let p1: THREE.Vector3, p3: THREE.Vector3 + + if (pkt.src <= Network.TopoConfig.value.num_nodes) { + p1 = new THREE.Vector3( + Network.Nodes.value[pkt.src].pos[0], + 1.6, + Network.Nodes.value[pkt.src].pos[1] + ) + } else { + // is an end system + p1 = new THREE.Vector3( + Network.EndSystems.value[pkt.src - Network.TopoConfig.value.num_nodes - 1].pos[0], + 1.6, + Network.EndSystems.value[pkt.src - Network.TopoConfig.value.num_nodes - 1].pos[1] + ) + } + + if (pkt.dst <= Network.TopoConfig.value.num_nodes) { + p3 = new THREE.Vector3( + Network.Nodes.value[pkt.dst].pos[0], + 1.6, + Network.Nodes.value[pkt.dst].pos[1] + ) + } else { + // is an end system + p3 = new THREE.Vector3( + Network.EndSystems.value[pkt.dst - Network.TopoConfig.value.num_nodes - 1].pos[0], + 1.6, + Network.EndSystems.value[pkt.dst - Network.TopoConfig.value.num_nodes - 1].pos[1] + ) + } + const x2 = (p1.x + p3.x) / 2 const z2 = (p1.z + p3.z) / 2 const h = 5 diff --git a/src/hooks/useStates.ts b/src/hooks/useStates.ts index e2969c8..63fd629 100644 --- a/src/hooks/useStates.ts +++ b/src/hooks/useStates.ts @@ -2,11 +2,11 @@ import { ref } from 'vue' -import { TSCHNetwork } from '@/networks/TSCH/network' -export const Network = new TSCHNetwork() +// import { TSCHNetwork } from '@/networks/TSCH/network' +// export const Network = new TSCHNetwork() -// import { TSNNetwork } from '@/networks/TSN/network' -// export const Network = new TSNNetwork() +import { TSNNetwork } from '@/networks/TSN/network' +export const Network = new TSNNetwork() // import { FiveGNetwork } from '@/networks/5G/network' // export const Network = new FiveGNetwork() diff --git a/src/networks/5G/network.ts b/src/networks/5G/network.ts index 9b9984e..6c47f3e 100644 --- a/src/networks/5G/network.ts +++ b/src/networks/5G/network.ts @@ -1,12 +1,13 @@ import { ref } from 'vue' -import { LINK_TYPE, Network, NETWORK_TYPE, NODE_TYPE } from '../common' +import { LINK_TYPE, NETWORK_TYPE, NODE_TYPE } from '../common' import type { ScheduleConfig, FiveGNodeMeta } from './typedefs' -import { KDNode } from '../TSN/kdtree' +import { KDNode } from '../kdtree' +import { Network } from '../network' export class FiveGNetwork extends Network { constructor() { super() - this.Type = NETWORK_TYPE.FiveG + this.Type = NETWORK_TYPE.FIVE_G // this.Schedule = ref([]) this.SchConfig = ref({ num_slots: 40 @@ -59,7 +60,7 @@ export class FiveGNetwork extends Network { // send init msg // n.w!.postMessage({ - // type: MSG_TYPES.INIT, + // type: MSG_TYPE.INIT, // payload: { // id: n.id, // pos: toRaw(n.pos), @@ -68,7 +69,7 @@ export class FiveGNetwork extends Network { // }) // handle msg/pkt from nodes // n.w!.onmessage = (e: any) => { - // if ('ch' in e.data == false) { + // if ('uid' in e.data == false) { // const msg: Message = e.data // if (this.msgHandlers[msg.type] != undefined) { // this.msgHandlers[msg.type](msg) @@ -80,7 +81,7 @@ export class FiveGNetwork extends Network { // // check channel interference, only one packet can be transmitted on each channel in a slot // if ( // this.PacketsCurrent.value.filter((p) => p.ch == pkt.ch).length == 0 || - // pkt.type == PKT_TYPES.ACK + // pkt.type == PKT_TYPE.ACK // ) { // // must use this format for the detailedView function of el-table-v2 // pkt.id = this.Packets.value.length diff --git a/src/networks/5G/typedefs.ts b/src/networks/5G/typedefs.ts index 9e7462d..ba4bc4e 100644 --- a/src/networks/5G/typedefs.ts +++ b/src/networks/5G/typedefs.ts @@ -5,3 +5,8 @@ export interface ScheduleConfig { } export interface FiveGNodeMeta extends NodeMeta {} + +export enum FIVE_G_PKT_TYPE { + ACK, + DATA +} diff --git a/src/networks/TSCH/network.ts b/src/networks/TSCH/network.ts index d257c51..e9d05bb 100644 --- a/src/networks/TSCH/network.ts +++ b/src/networks/TSCH/network.ts @@ -3,14 +3,14 @@ import type { Cell, TSCHNodeMeta, ScheduleConfig, - INIT_MSG_PAYLOAD, - ASN_MSG_PAYLOAD, + TSCH_INIT_MSG_PAYLOAD, ASSOC_RSP_PKT_PAYLOAD } from './typedefs' -import { ADDR, MSG_TYPES, PKT_TYPES, CELL_TYPES } from './typedefs' -import { LINK_TYPE, Network, NETWORK_TYPE, NODE_TYPE } from '../common' -import type { Packet, Message, MsgHandler } from '../common' -import { KDNode } from '../TSN/kdtree' +import { TSCH_PKT_TYPE, CELL_TYPES } from './typedefs' +import { ADDR, MSG_TYPE, LINK_TYPE, NETWORK_TYPE, NODE_TYPE } from '../common' +import type { Packet, Message, ASN_MSG_PAYLOAD, MsgHandler } from '../common' +import { KDNode } from '../kdtree' +import { Network } from '../network' export class TSCHNetwork extends Network { doneCnt = 0 @@ -30,9 +30,9 @@ export class TSCHNetwork extends Network { num_shared_slots: 8 }) - this.registerMsgHandler(MSG_TYPES.DONE, this.doneMsgHandler) - this.registerMsgHandler(MSG_TYPES.STAT, this.statMsgHandler) - this.registerMsgHandler(MSG_TYPES.ASSOC_REQ, this.assocReqMsgHandler) + this.registerMsgHandler(MSG_TYPE.DONE, this.doneMsgHandler) + this.registerMsgHandler(MSG_TYPE.STAT, this.statMsgHandler) + this.registerMsgHandler(MSG_TYPE.ASSOC_REQ, this.assocReqMsgHandler) this.createNodes() super.createEndSystems() @@ -45,7 +45,7 @@ export class TSCHNetwork extends Network { for (const n of this.Nodes.value) { if (n.w != undefined) { n.w.postMessage({ - type: MSG_TYPES.ASN, + type: MSG_TYPE.ASN, dst: n.id, payload: { asn: this.ASN.value } }) @@ -98,7 +98,7 @@ export class TSCHNetwork extends Network { if (topo_check) { const p = { - type: PKT_TYPES.ASSOC_RSP, + type: TSCH_PKT_TYPE.ASSOC_RSP, uid: Math.floor(Math.random() * 0xffff), ch: 2, src: 0, @@ -147,7 +147,7 @@ export class TSCHNetwork extends Network { const n = { id: i, type: NODE_TYPE.TSCH, - pos: [ + pos: <[number, number]>[ Math.floor(this.Rand.next() * this.TopoConfig.value.grid_size) - this.TopoConfig.value.grid_size / 2, Math.floor(this.Rand.next() * this.TopoConfig.value.grid_size) - @@ -166,8 +166,8 @@ export class TSCHNetwork extends Network { // send init msg n.w!.postMessage({ - type: MSG_TYPES.INIT, - payload: { + type: MSG_TYPE.INIT, + payload: { id: n.id, pos: toRaw(n.pos), sch_config: toRaw(this.SchConfig.value) @@ -175,7 +175,7 @@ export class TSCHNetwork extends Network { }) // handle msg/pkt from nodes n.w!.onmessage = (e: any) => { - if ('ch' in e.data == false) { + if ('uid' in e.data == false) { const msg: Message = e.data if (this.msgHandlers[msg.type] != undefined) { this.msgHandlers[msg.type](msg) @@ -187,7 +187,7 @@ export class TSCHNetwork extends Network { // check channel interference, only one packet can be transmitted on each channel in a slot if ( this.PacketsCurrent.value.filter((p) => p.ch == pkt.ch).length == 0 || - pkt.type == PKT_TYPES.ACK + pkt.type == TSCH_PKT_TYPE.ACK ) { // must use this format for the detailedView function of el-table-v2 pkt.id = this.Packets.value.length diff --git a/src/networks/TSCH/node.ts b/src/networks/TSCH/node.ts index 9f85407..7d50f6f 100644 --- a/src/networks/TSCH/node.ts +++ b/src/networks/TSCH/node.ts @@ -2,14 +2,21 @@ import type { ScheduleConfig, Cell, - INIT_MSG_PAYLOAD, + TSCH_INIT_MSG_PAYLOAD, BEACON_PKT_PAYLOAD, ASSOC_REQ_PKT_PAYLOAD, - ASN_MSG_PAYLOAD, ASSOC_RSP_PKT_PAYLOAD } from './typedefs' -import { MSG_TYPES, ADDR, CELL_TYPES, PKT_TYPES } from './typedefs' -import type { Packet, Message, MsgHandler, PktHandler } from '../common' +import { CELL_TYPES, TSCH_PKT_TYPE } from './typedefs' +import { + type Packet, + type Message, + type MsgHandler, + type PktHandler, + ADDR, + MSG_TYPE, + type ASN_MSG_PAYLOAD +} from '../common' class TSCHNode { id: number = 0 @@ -33,13 +40,13 @@ class TSCHNode { constructor() { this.joinedNeighbors[ADDR.BROADCAST] = true - this.registerMsgHandler(MSG_TYPES.ASN, this.asnMsgHandler) - this.registerMsgHandler(MSG_TYPES.INIT, this.initMsgHandler) + this.registerMsgHandler(MSG_TYPE.ASN, this.asnMsgHandler) + this.registerMsgHandler(MSG_TYPE.INIT, this.initMsgHandler) - this.registerPktHandler(PKT_TYPES.ACK, this.ackPktHandler) - this.registerPktHandler(PKT_TYPES.BEACON, this.beaconPktHandler) - this.registerPktHandler(PKT_TYPES.ASSOC_REQ, this.assocReqPktHandler) - this.registerPktHandler(PKT_TYPES.ASSOC_RSP, this.assocRspPktHandler) + this.registerPktHandler(TSCH_PKT_TYPE.ACK, this.ackPktHandler) + this.registerPktHandler(TSCH_PKT_TYPE.BEACON, this.beaconPktHandler) + this.registerPktHandler(TSCH_PKT_TYPE.ASSOC_REQ, this.assocReqPktHandler) + this.registerPktHandler(TSCH_PKT_TYPE.ASSOC_RSP, this.assocRspPktHandler) } registerMsgHandler(type: number, handler: MsgHandler) { @@ -77,9 +84,9 @@ class TSCHNode { } respondAck(pkt: Packet) { - if (pkt.dst != ADDR.BROADCAST && pkt.src != ADDR.CONTROLLER && pkt.type != PKT_TYPES.ACK) { + if (pkt.dst != ADDR.BROADCAST && pkt.src != ADDR.CONTROLLER && pkt.type != TSCH_PKT_TYPE.ACK) { const ack: Packet = { ...pkt } - ack.type = PKT_TYPES.ACK + ack.type = TSCH_PKT_TYPE.ACK ack.src = this.id ack.dst = pkt.src ack.len = 0 @@ -124,7 +131,7 @@ class TSCHNode { } } checkSchRx(pkt: Packet): boolean { - if (!this.joined || pkt.type == PKT_TYPES.ACK || pkt.src == ADDR.CONTROLLER) { + if (!this.joined || pkt.type == TSCH_PKT_TYPE.ACK || pkt.src == ADDR.CONTROLLER) { return true } const slot = this.ASN % this.sch_config.num_slots || this.sch_config.num_slots @@ -149,7 +156,7 @@ class TSCHNode { ) { this.queue.push({ uid: Math.floor(Math.random() * 0xffff), - type: PKT_TYPES.BEACON, + type: TSCH_PKT_TYPE.BEACON, src: this.id, dst: -1, seq: ++this.pkt_seq, @@ -161,17 +168,17 @@ class TSCHNode { // done postMessage({ - type: MSG_TYPES.DONE + type: MSG_TYPE.DONE }) postMessage({ - type: MSG_TYPES.STAT, + type: MSG_TYPE.STAT, src: this.id, dst: ADDR.CONTROLLER, payload: JSON.parse(JSON.stringify(this)) }) } initMsgHandler = (msg: Message) => { - const payload: INIT_MSG_PAYLOAD = msg.payload + const payload: TSCH_INIT_MSG_PAYLOAD = msg.payload this.id = payload.id this.joined = this.id == ADDR.ROOT this.sch_config = payload.sch_config @@ -203,7 +210,7 @@ class TSCHNode { ackPktHandler = (ack: Packet) => { if (this.queue[0] != undefined && this.queue[0].uid == ack.uid) { if ( - this.queue[0].type == PKT_TYPES.ASSOC_RSP && + this.queue[0].type == TSCH_PKT_TYPE.ASSOC_RSP && this.queue[0].payload.parent == this.id && this.queue[0].payload.permit ) { @@ -219,7 +226,7 @@ class TSCHNode { this.rank = payload.rank + 1 const assoc_req = { uid: Math.floor(Math.random() * 0xffff), - type: PKT_TYPES.ASSOC_REQ, + type: TSCH_PKT_TYPE.ASSOC_REQ, src: this.id, dst: pkt.src, seq: ++this.pkt_seq, @@ -243,7 +250,7 @@ class TSCHNode { } else { // send to controller postMessage({ - type: MSG_TYPES.ASSOC_REQ, + type: MSG_TYPE.ASSOC_REQ, src: this.id, dst: ADDR.CONTROLLER, payload: pkt.payload @@ -265,7 +272,7 @@ class TSCHNode { } postMessage({ - type: MSG_TYPES.STAT, + type: MSG_TYPE.STAT, src: this.id, dst: ADDR.CONTROLLER, payload: JSON.parse(JSON.stringify(this)) @@ -273,7 +280,7 @@ class TSCHNode { this.queue.push({ uid: Math.floor(Math.random() * 0xffff), - type: PKT_TYPES.BEACON, + type: TSCH_PKT_TYPE.BEACON, src: this.id, dst: -1, seq: ++this.pkt_seq, diff --git a/src/networks/TSCH/typedefs.ts b/src/networks/TSCH/typedefs.ts index 9ba83a5..9926638 100644 --- a/src/networks/TSCH/typedefs.ts +++ b/src/networks/TSCH/typedefs.ts @@ -1,6 +1,6 @@ // all types and enums here -import type { NodeMeta } from '../common' +import type { INIT_MSG_PAYLOAD, NodeMeta } from '../common' export interface TSCHNodeMeta extends NodeMeta { joined: boolean @@ -33,33 +33,11 @@ export enum CELL_TYPES { DATA } -export enum MSG_TYPES { - INIT, - ASN, - DONE, // finished all activities of the current slot - SEND, - STAT, - ASSOC_REQ -} - -export interface ASN_MSG_PAYLOAD { - asn: number -} - -export interface INIT_MSG_PAYLOAD { - id: number - pos: number[] +export interface TSCH_INIT_MSG_PAYLOAD extends INIT_MSG_PAYLOAD { sch_config: ScheduleConfig } -export enum ADDR { - CONTROLLER = 0, - ROOT = 1, - BROADCAST = -1, - ANY = -2 -} - -export enum PKT_TYPES { +export enum TSCH_PKT_TYPE { ACK, BEACON, ASSOC_REQ, diff --git a/src/networks/TSN/network.ts b/src/networks/TSN/network.ts index af4c96c..40382b3 100644 --- a/src/networks/TSN/network.ts +++ b/src/networks/TSN/network.ts @@ -1,7 +1,8 @@ import { ref, toRaw } from 'vue' -import { Network, NETWORK_TYPE, NODE_TYPE, type Message, LINK_TYPE } from '../common' -import { MSG_TYPES, type INIT_MSG_PAYLOAD, type ScheduleConfig, type TSNNodeMeta } from './typedefs' -import { KDNode } from './kdtree' +import { NETWORK_TYPE, NODE_TYPE, type Message, LINK_TYPE, MSG_TYPE } from '../common' +import { type ScheduleConfig, type TSNNodeMeta, type TSN_INIT_MSG_PAYLOAD } from './typedefs' +import { KDNode } from '../kdtree' +import { Network } from '../network' export class TSNNetwork extends Network { InPorts: any @@ -58,8 +59,8 @@ export class TSNNetwork extends Network { } // send init msg n.w!.postMessage({ - type: MSG_TYPES.INIT, - payload: { + type: MSG_TYPE.INIT, + payload: { id: n.id, pos: toRaw(n.pos), neighbors: [], diff --git a/src/networks/TSN/node.ts b/src/networks/TSN/node.ts index c865dc9..50b5e97 100644 --- a/src/networks/TSN/node.ts +++ b/src/networks/TSN/node.ts @@ -1,12 +1,27 @@ -import type { INIT_MSG_PAYLOAD } from '../TSCH/typedefs' -import type { Packet, Message, MsgHandler, PktHandler } from '../common' +import { + type Packet, + type Message, + type MsgHandler, + type PktHandler, + ADDR, + MSG_TYPE, + type ASN_MSG_PAYLOAD +} from '../common' +import { TSN_PKT_TYPE, type TSN_INIT_MSG_PAYLOAD } from './typedefs' class TSNNode { id: number = 0 + ASN: number = 0 ports: { [p: number]: number } = {} msgHandlers: { [type: number]: MsgHandler } = {} pktHandlers: { [type: number]: PktHandler } = {} - constructor() {} + + constructor() { + this.registerMsgHandler(MSG_TYPE.ASN, this.asnMsgHandler) + this.registerMsgHandler(MSG_TYPE.INIT, this.initMsgHandler) + + this.registerPktHandler(TSN_PKT_TYPE.DATA, this.dataPktHandler) + } registerMsgHandler(type: number, handler: MsgHandler) { this.msgHandlers[type] = handler } @@ -36,12 +51,28 @@ class TSNNode { } initMsgHandler = (msg: Message) => { - const payload: INIT_MSG_PAYLOAD = msg.payload + const payload: TSN_INIT_MSG_PAYLOAD = msg.payload this.id = payload.id - console.log(this.id) + } + asnMsgHandler = (msg: Message) => { + const payload: ASN_MSG_PAYLOAD = msg.payload + this.ASN = payload.asn + + // this.checkSchTx() + + // done + postMessage({ + type: MSG_TYPE.DONE + }) + postMessage({ + type: MSG_TYPE.STAT, + src: this.id, + dst: ADDR.CONTROLLER, + payload: JSON.parse(JSON.stringify(this)) + }) } dataPktHandler = (pkt: Packet) => { - console.log(pkt) + console.log('tsn', pkt) } } diff --git a/src/networks/TSN/typedefs.ts b/src/networks/TSN/typedefs.ts index cce1c44..62631c9 100644 --- a/src/networks/TSN/typedefs.ts +++ b/src/networks/TSN/typedefs.ts @@ -1,4 +1,4 @@ -import type { NodeMeta } from '../common' +import type { INIT_MSG_PAYLOAD, NodeMeta } from '../common' export interface ScheduleConfig { num_slots: number @@ -6,20 +6,10 @@ export interface ScheduleConfig { export interface TSNNodeMeta extends NodeMeta {} -export enum MSG_TYPES { - INIT, - ASN, - DONE, // finished all activities of the current slot - STAT +export enum TSN_PKT_TYPE { + DATA } -export interface INIT_MSG_PAYLOAD { - id: number - pos: number[] - neighbors: [] +export interface TSN_INIT_MSG_PAYLOAD extends INIT_MSG_PAYLOAD { sch_config: ScheduleConfig } - -export enum PKT_TYPES { - DATA -} diff --git a/src/networks/common.ts b/src/networks/common.ts index a2c673f..a92bb1e 100644 --- a/src/networks/common.ts +++ b/src/networks/common.ts @@ -1,11 +1,7 @@ -import { ref, type Ref } from 'vue' -import { SeededRandom } from '@/hooks/useSeed' -import { KDTree } from './TSN/kdtree' - export enum NETWORK_TYPE { TSCH, TSN, - FiveG + FIVE_G } export enum NODE_TYPE { @@ -70,6 +66,30 @@ export interface Message { payload: any } +export enum MSG_TYPE { + INIT, + ASN, + DONE, // finished all activities of the current slot + FLOW, // install periodic flow + STAT, + ASSOC_REQ +} + +export interface INIT_MSG_PAYLOAD { + id: number +} + +export interface ASN_MSG_PAYLOAD { + asn: number +} + +export enum ADDR { + CONTROLLER = 0, + ROOT = 1, + BROADCAST = -1, + ANY = -2 +} + export type MsgHandler = (msg: Message) => void export type PktHandler = (pkt: Packet) => void @@ -80,103 +100,3 @@ export interface TopologyConfig { grid_size: number tx_range: number } - -export class Network { - ID: number - Type: number - Nodes: any // tsn bridges, tsch node or 5g ue/bs - EndSystems: any - Links = ref<{ [uid: number]: LinkMeta }>([]) - TopoConfig: Ref - KDTree: KDTree - SchConfig: any - Schedule: any - Packets = ref([]) - ASN = ref(0) - asnTimer: any - PacketsCurrent = ref([]) - - SignalReset = ref(0) - SlotDone = ref(true) - Running = ref(false) - SlotDuration = ref(750) - - Rand: SeededRandom - - constructor() { - this.ID = 1 - this.Type = -1 - this.TopoConfig = ref({ - seed: 1, - num_nodes: 10, - num_es: 4, - grid_size: 80, - tx_range: 25 - }) - this.Rand = new SeededRandom(this.TopoConfig.value.seed) - this.KDTree = new KDTree() - } - // call after create nodes - createEndSystems() { - // initialize ref array if it does not already exist - this.EndSystems = ref([]) - - this.EndSystems.value = [] // clear any old end systems - - for (let i = 1; i <= this.TopoConfig.value.num_es; i++) { - const es = { - id: i + this.TopoConfig.value.num_nodes, - type: Math.floor( - this.Rand.next() * Object.keys(END_SYSTEM_TYPE).filter((key) => isNaN(Number(key))).length - ), // Object.keys(...).filter(...) is used to count # of elements in enum - pos: [ - Math.floor(this.Rand.next() * this.TopoConfig.value.grid_size) - - this.TopoConfig.value.grid_size / 2, - Math.floor(this.Rand.next() * this.TopoConfig.value.grid_size) - - this.TopoConfig.value.grid_size / 2 - ], - tx_cnt: 0, - rx_cnt: 0, - neighbors: [], - w: undefined - } - es.neighbors = this.KDTree.FindKNearest(es.pos, 1, this.TopoConfig.value.grid_size) - if (es.neighbors.length > 0) { - this.addLink(es.id, es.neighbors[0], LINK_TYPE.WIRED) - } - this.EndSystems.value.push(es) - } - } - addLink(v1: number, v2: number, type: number) { - if (v1 > v2) { - ;[v1, v2] = [v2, v1] - } - // Cantor pairing - const uid = 0.5 * (v1 + v2) * (v1 + v2 + 1) + v2 - if (this.Links.value[uid] == undefined) { - this.Links.value[uid] = { uid, v1, v2, type } - } - } - - Run = () => { - this.Step() - this.Running.value = true - this.asnTimer = setInterval(() => { - this.ASN.value++ - this.SlotDone.value = false - }, this.SlotDuration.value) - } - Step = () => { - this.ASN.value++ - this.SlotDone.value = false - } - Pause = () => { - this.Running.value = false - clearInterval(this.asnTimer) - } - Reset = () => { - this.Running.value = false - clearInterval(this.asnTimer) - this.SignalReset.value++ - } -} diff --git a/src/networks/es.ts b/src/networks/es.ts new file mode 100644 index 0000000..b3b854b --- /dev/null +++ b/src/networks/es.ts @@ -0,0 +1,52 @@ +import { MSG_TYPE, type Message, type MsgHandler, type Packet, type PktHandler } from './common' + +// end system, run as a webworker +class EndSystem { + id: number = 0 + neighbor: number = -1 + + msgHandlers: { [type: number]: MsgHandler } = {} + pktHandlers: { [type: number]: PktHandler } = {} + + constructor() { + this.registerMsgHandler(MSG_TYPE.INIT, this.initMsgHandler) + } + + registerMsgHandler(type: number, handler: MsgHandler) { + this.msgHandlers[type] = handler + } + registerPktHandler(type: number, handler: PktHandler) { + this.pktHandlers[type] = handler + } + run() { + onmessage = (e: any) => { + if ('uid' in e.data == false) { + const msg: Message = e.data + if (this.msgHandlers[msg.type] != undefined) { + this.msgHandlers[msg.type](msg) + // test + postMessage({ + uid: 11, + type: 0, + src: 11, + dst: 3 + }) + } else { + // console.log('!! undefined message type:', msg.type) + } + } else { + const pkt: Packet = e.data + + if (this.pktHandlers[pkt.type] != undefined) { + this.pktHandlers[pkt.type](pkt) + } else { + // console.log('!! undefined packet type:', pkt.type) + } + } + } + } + initMsgHandler = () => {} + dataMsgHandler = () => {} +} + +new EndSystem().run() diff --git a/src/networks/TSN/kdtree.ts b/src/networks/kdtree.ts similarity index 100% rename from src/networks/TSN/kdtree.ts rename to src/networks/kdtree.ts diff --git a/src/networks/network.ts b/src/networks/network.ts new file mode 100644 index 0000000..29aeb5b --- /dev/null +++ b/src/networks/network.ts @@ -0,0 +1,129 @@ +import { ref, toRaw, type Ref } from 'vue' +import { SeededRandom } from '@/hooks/useSeed' +import { KDTree } from './kdtree' +import { END_SYSTEM_TYPE, LINK_TYPE, MSG_TYPE, type LinkMeta, type Message, type NodeMeta, type Packet, type TopologyConfig, type INIT_MSG_PAYLOAD } from './common' + +export class Network { + ID: number + Type: number + Nodes: any // tsn bridges, tsch node or 5g ue/bs + EndSystems: any + Links = ref<{ [uid: number]: LinkMeta }>([]) + TopoConfig: Ref + KDTree: KDTree + SchConfig: any + Schedule: any + Packets = ref([]) + ASN = ref(0) + asnTimer: any + PacketsCurrent = ref([]) + + SignalReset = ref(0) + SlotDone = ref(false) + Running = ref(false) + SlotDuration = ref(750) + + Rand: SeededRandom + + constructor() { + this.ID = 1 + this.Type = -1 + this.TopoConfig = ref({ + seed: 1, + num_nodes: 10, + num_es: 1, + grid_size: 80, + tx_range: 25 + }) + this.Rand = new SeededRandom(this.TopoConfig.value.seed) + this.KDTree = new KDTree() + } + // call after createNodes + createEndSystems() { + // initialize ref array if it does not already exist + this.EndSystems = ref([]) + + this.EndSystems.value = [] // clear any old end systems + + for ( + let i = 1 + this.TopoConfig.value.num_nodes; + i <= this.TopoConfig.value.num_es + this.TopoConfig.value.num_nodes; + i++ + ) { + const es = { + id: i, + type: Math.floor( + this.Rand.next() * Object.keys(END_SYSTEM_TYPE).filter((key) => isNaN(Number(key))).length + ), // Object.keys(...).filter(...) is used to count # of elements in enum + pos: [ + Math.floor(this.Rand.next() * this.TopoConfig.value.grid_size) - + this.TopoConfig.value.grid_size / 2, + Math.floor(this.Rand.next() * this.TopoConfig.value.grid_size) - + this.TopoConfig.value.grid_size / 2 + ], + tx_cnt: 0, + rx_cnt: 0, + neighbors: [], + w: new Worker(new URL('@/networks/es.ts', import.meta.url), { type: 'module' }) + } + es.neighbors = this.KDTree.FindKNearest(es.pos, 1, this.TopoConfig.value.grid_size) + if (es.neighbors.length > 0) { + this.addLink(es.id, es.neighbors[0], LINK_TYPE.WIRED) + } + this.EndSystems.value.push(es) + + es.w!.postMessage({ + type: MSG_TYPE.INIT, + payload: { + id: es.id, + pos: toRaw(es.pos) + } + }) + // handle msg/pkt from end systems + es.w!.onmessage = (e: any) => { + if ('uid' in e.data == false) { + const msg: Message = e.data + console.log(msg) + } else { + const pkt: Packet = e.data + this.Nodes.value[pkt.dst].w!.postMessage(pkt) + this.Packets.value.push(pkt) + this.PacketsCurrent.value.push(pkt) + this.SlotDone.value = true + } + } + } + } + addLink(v1: number, v2: number, type: number) { + if (v1 > v2) { + ;[v1, v2] = [v2, v1] + } + // Cantor pairing + const uid = 0.5 * (v1 + v2) * (v1 + v2 + 1) + v2 + if (this.Links.value[uid] == undefined) { + this.Links.value[uid] = { uid, v1, v2, type } + } + } + + Run = () => { + this.Step() + this.Running.value = true + this.asnTimer = setInterval(() => { + this.ASN.value++ + this.SlotDone.value = false + }, this.SlotDuration.value) + } + Step = () => { + this.ASN.value++ + this.SlotDone.value = false + } + Pause = () => { + this.Running.value = false + clearInterval(this.asnTimer) + } + Reset = () => { + this.Running.value = false + clearInterval(this.asnTimer) + this.SignalReset.value++ + } +}