import {css, html, LitElement} from 'lit'; import {customElement, property} from 'lit/decorators.js'; import {Device, Notifiable, SimulationInfo, simulationState,} from './device-observer.js'; import {Capture} from './netsim/model.js'; @customElement('ns-packet-info') export class PacketInformation extends LitElement implements Notifiable { /** * List of captures currently on the netsim. */ @property() captureData: Capture[] = []; /** * List of devices currently on the netsim. */ @property() deviceData: Device[] = []; static styles = css` :host { display: flex; justify-content: center; align-items: flex-start; height: 100vh; } .panel { cursor: pointer; display: grid; place-content: center; color: black; font-size: 25px; font-family: 'Lato', sans-serif; border: 5px solid black; border-radius: 12px; margin: 10px; padding: 10px; background-color: #ffffff; max-width: max-content; float: left; } .title { font-weight: bold; text-transform: uppercase; text-align: center; margin-bottom: 10px; } .label { text-align: left; } .styled-table { border-collapse: collapse; margin: 25px 0; font-size: 20px; font-family: sans-serif; width: 100%; box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); } .styled-table thead tr { background-color: #009879; color: #ffffff; text-align: left; } .styled-table th, .styled-table td { padding: 12px 15px; text-align: left; } .styled-table tbody tr { border-bottom: 1px solid #dddddd; } .styled-table tbody tr:nth-of-type(even) { background-color: #cac0c0; } input[type='button'] { height: 2rem; font-size: inherit; } input[type='checkbox'].switch_1 { font-size: 30px; -webkit-appearance: none; -moz-appearance: none; appearance: none; width: 3.5em; height: 1.5em; background: #ddd; border-radius: 3em; position: relative; cursor: pointer; outline: none; -webkit-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; } input[type='checkbox'].switch_1:checked { background: #0ebeff; } input[type='checkbox'].switch_1:after { position: absolute; content: ''; width: 1.5em; height: 1.5em; border-radius: 50%; background: #fff; -webkit-box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.3); box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.3); -webkit-transform: scale(0.7); transform: scale(0.7); left: 0; -webkit-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; } input[type='checkbox'].switch_1:checked:after { left: calc(100% - 1.5em); } button { display: inline-block; padding: 12px 24px; background-color: #4CAF50; color: #FFFFFF; font-size: 18px; font-weight: bold; text-align: center; text-decoration: none; border: none; cursor: pointer; transition: background-color 0.3s ease; } button:hover { background-color: #45a049; transition: 0.5s; } `; connectedCallback() { super.connectedCallback(); // eslint-disable-line simulationState.registerObserver(this); } disconnectedCallback() { simulationState.removeObserver(this); super.disconnectedCallback(); // eslint-disable-line } onNotify(data: SimulationInfo) { this.captureData = data.captures; this.deviceData = data.devices; this.requestUpdate(); } toggleCapture(capture: Capture) { let id = capture.id.toString(); let state = capture.state ? '0' : '1'; simulationState.patchCapture(id, state); } private handleGetChips(device: Device) { let btTable = html``; let uwbTable = html``; let wifiTable = html``; if ('chips' in device && device.chips) { for (const chip of device.chips) { if ('bt' in chip && chip.bt) { let bleTable = html``; let bclassicTable = html``; if ('lowEnergy' in chip.bt && chip.bt.lowEnergy) { bleTable = html` BLE ${chip.bt.lowEnergy.rxCount ?? 0} ${chip.bt.lowEnergy.txCount ?? 0} `; } if ('classic' in chip.bt && chip.bt.classic) { bclassicTable = html` Bluetooth Classic ${chip.bt.classic.rxCount ?? 0} ${chip.bt.classic.txCount ?? 0} `; } btTable = html`${bleTable} ${bclassicTable}`; } if ('uwb' in chip && chip.uwb) { uwbTable = html` UWB ${chip.uwb.rxCount ?? 0} ${chip.uwb.txCount ?? 0} `; } if ('wifi' in chip && chip.wifi) { wifiTable = html` WIFI ${chip.wifi.rxCount ?? 0} ${chip.wifi.txCount ?? 0} `; } } } return html` ${btTable} ${uwbTable} ${wifiTable} `; } private handleListCaptures(capture: Capture) { return html` ${capture.deviceName} ${capture.chipKind} ${capture.size} ${capture.records} { this.toggleCapture(capture); }} /> ` } render() { return html`
Packet Info
${this.deviceData.map(device => html`
${device.name}
${this.handleGetChips(device)}
Radio RX Count TX Count
`)}
Packet Capture
${this.captureData.map(capture => this.handleListCaptures(capture))}
Device Name Chip Kind Bytes Records Capture State Download Pcap
`; } }