xref: /aosp_15_r20/tools/netsim/ui/ts/packet-info.ts (revision cf78ab8cffb8fc9207af348f23af247fb04370a6)
1*cf78ab8cSAndroid Build Coastguard Workerimport {css, html, LitElement} from 'lit';
2*cf78ab8cSAndroid Build Coastguard Workerimport {customElement, property} from 'lit/decorators.js';
3*cf78ab8cSAndroid Build Coastguard Worker
4*cf78ab8cSAndroid Build Coastguard Workerimport {Device, Notifiable, SimulationInfo, simulationState,} from './device-observer.js';
5*cf78ab8cSAndroid Build Coastguard Workerimport {Capture} from './netsim/model.js';
6*cf78ab8cSAndroid Build Coastguard Worker
7*cf78ab8cSAndroid Build Coastguard Worker@customElement('ns-packet-info')
8*cf78ab8cSAndroid Build Coastguard Workerexport class PacketInformation extends LitElement implements Notifiable {
9*cf78ab8cSAndroid Build Coastguard Worker  /**
10*cf78ab8cSAndroid Build Coastguard Worker   * List of captures currently on the netsim.
11*cf78ab8cSAndroid Build Coastguard Worker   */
12*cf78ab8cSAndroid Build Coastguard Worker  @property() captureData: Capture[] = [];
13*cf78ab8cSAndroid Build Coastguard Worker
14*cf78ab8cSAndroid Build Coastguard Worker  /**
15*cf78ab8cSAndroid Build Coastguard Worker   * List of devices currently on the netsim.
16*cf78ab8cSAndroid Build Coastguard Worker   */
17*cf78ab8cSAndroid Build Coastguard Worker  @property() deviceData: Device[] = [];
18*cf78ab8cSAndroid Build Coastguard Worker
19*cf78ab8cSAndroid Build Coastguard Worker  static styles = css`
20*cf78ab8cSAndroid Build Coastguard Worker    :host {
21*cf78ab8cSAndroid Build Coastguard Worker      display: flex;
22*cf78ab8cSAndroid Build Coastguard Worker      justify-content: center;
23*cf78ab8cSAndroid Build Coastguard Worker      align-items: flex-start;
24*cf78ab8cSAndroid Build Coastguard Worker      height: 100vh;
25*cf78ab8cSAndroid Build Coastguard Worker    }
26*cf78ab8cSAndroid Build Coastguard Worker
27*cf78ab8cSAndroid Build Coastguard Worker    .panel {
28*cf78ab8cSAndroid Build Coastguard Worker      cursor: pointer;
29*cf78ab8cSAndroid Build Coastguard Worker      display: grid;
30*cf78ab8cSAndroid Build Coastguard Worker      place-content: center;
31*cf78ab8cSAndroid Build Coastguard Worker      color: black;
32*cf78ab8cSAndroid Build Coastguard Worker      font-size: 25px;
33*cf78ab8cSAndroid Build Coastguard Worker      font-family: 'Lato', sans-serif;
34*cf78ab8cSAndroid Build Coastguard Worker      border: 5px solid black;
35*cf78ab8cSAndroid Build Coastguard Worker      border-radius: 12px;
36*cf78ab8cSAndroid Build Coastguard Worker      margin: 10px;
37*cf78ab8cSAndroid Build Coastguard Worker      padding: 10px;
38*cf78ab8cSAndroid Build Coastguard Worker      background-color: #ffffff;
39*cf78ab8cSAndroid Build Coastguard Worker      max-width: max-content;
40*cf78ab8cSAndroid Build Coastguard Worker      float: left;
41*cf78ab8cSAndroid Build Coastguard Worker    }
42*cf78ab8cSAndroid Build Coastguard Worker
43*cf78ab8cSAndroid Build Coastguard Worker    .title {
44*cf78ab8cSAndroid Build Coastguard Worker      font-weight: bold;
45*cf78ab8cSAndroid Build Coastguard Worker      text-transform: uppercase;
46*cf78ab8cSAndroid Build Coastguard Worker      text-align: center;
47*cf78ab8cSAndroid Build Coastguard Worker      margin-bottom: 10px;
48*cf78ab8cSAndroid Build Coastguard Worker    }
49*cf78ab8cSAndroid Build Coastguard Worker
50*cf78ab8cSAndroid Build Coastguard Worker    .label {
51*cf78ab8cSAndroid Build Coastguard Worker      text-align: left;
52*cf78ab8cSAndroid Build Coastguard Worker    }
53*cf78ab8cSAndroid Build Coastguard Worker
54*cf78ab8cSAndroid Build Coastguard Worker    .styled-table {
55*cf78ab8cSAndroid Build Coastguard Worker      border-collapse: collapse;
56*cf78ab8cSAndroid Build Coastguard Worker      margin: 25px 0;
57*cf78ab8cSAndroid Build Coastguard Worker      font-size: 20px;
58*cf78ab8cSAndroid Build Coastguard Worker      font-family: sans-serif;
59*cf78ab8cSAndroid Build Coastguard Worker      width: 100%;
60*cf78ab8cSAndroid Build Coastguard Worker      box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
61*cf78ab8cSAndroid Build Coastguard Worker    }
62*cf78ab8cSAndroid Build Coastguard Worker
63*cf78ab8cSAndroid Build Coastguard Worker    .styled-table thead tr {
64*cf78ab8cSAndroid Build Coastguard Worker      background-color: #009879;
65*cf78ab8cSAndroid Build Coastguard Worker      color: #ffffff;
66*cf78ab8cSAndroid Build Coastguard Worker      text-align: left;
67*cf78ab8cSAndroid Build Coastguard Worker    }
68*cf78ab8cSAndroid Build Coastguard Worker
69*cf78ab8cSAndroid Build Coastguard Worker    .styled-table th,
70*cf78ab8cSAndroid Build Coastguard Worker    .styled-table td {
71*cf78ab8cSAndroid Build Coastguard Worker      padding: 12px 15px;
72*cf78ab8cSAndroid Build Coastguard Worker      text-align: left;
73*cf78ab8cSAndroid Build Coastguard Worker    }
74*cf78ab8cSAndroid Build Coastguard Worker
75*cf78ab8cSAndroid Build Coastguard Worker    .styled-table tbody tr {
76*cf78ab8cSAndroid Build Coastguard Worker      border-bottom: 1px solid #dddddd;
77*cf78ab8cSAndroid Build Coastguard Worker    }
78*cf78ab8cSAndroid Build Coastguard Worker
79*cf78ab8cSAndroid Build Coastguard Worker    .styled-table tbody tr:nth-of-type(even) {
80*cf78ab8cSAndroid Build Coastguard Worker      background-color: #cac0c0;
81*cf78ab8cSAndroid Build Coastguard Worker    }
82*cf78ab8cSAndroid Build Coastguard Worker
83*cf78ab8cSAndroid Build Coastguard Worker    input[type='button'] {
84*cf78ab8cSAndroid Build Coastguard Worker      height: 2rem;
85*cf78ab8cSAndroid Build Coastguard Worker      font-size: inherit;
86*cf78ab8cSAndroid Build Coastguard Worker    }
87*cf78ab8cSAndroid Build Coastguard Worker
88*cf78ab8cSAndroid Build Coastguard Worker    input[type='checkbox'].switch_1 {
89*cf78ab8cSAndroid Build Coastguard Worker      font-size: 30px;
90*cf78ab8cSAndroid Build Coastguard Worker      -webkit-appearance: none;
91*cf78ab8cSAndroid Build Coastguard Worker      -moz-appearance: none;
92*cf78ab8cSAndroid Build Coastguard Worker      appearance: none;
93*cf78ab8cSAndroid Build Coastguard Worker      width: 3.5em;
94*cf78ab8cSAndroid Build Coastguard Worker      height: 1.5em;
95*cf78ab8cSAndroid Build Coastguard Worker      background: #ddd;
96*cf78ab8cSAndroid Build Coastguard Worker      border-radius: 3em;
97*cf78ab8cSAndroid Build Coastguard Worker      position: relative;
98*cf78ab8cSAndroid Build Coastguard Worker      cursor: pointer;
99*cf78ab8cSAndroid Build Coastguard Worker      outline: none;
100*cf78ab8cSAndroid Build Coastguard Worker      -webkit-transition: all 0.2s ease-in-out;
101*cf78ab8cSAndroid Build Coastguard Worker      transition: all 0.2s ease-in-out;
102*cf78ab8cSAndroid Build Coastguard Worker    }
103*cf78ab8cSAndroid Build Coastguard Worker
104*cf78ab8cSAndroid Build Coastguard Worker    input[type='checkbox'].switch_1:checked {
105*cf78ab8cSAndroid Build Coastguard Worker      background: #0ebeff;
106*cf78ab8cSAndroid Build Coastguard Worker    }
107*cf78ab8cSAndroid Build Coastguard Worker
108*cf78ab8cSAndroid Build Coastguard Worker    input[type='checkbox'].switch_1:after {
109*cf78ab8cSAndroid Build Coastguard Worker      position: absolute;
110*cf78ab8cSAndroid Build Coastguard Worker      content: '';
111*cf78ab8cSAndroid Build Coastguard Worker      width: 1.5em;
112*cf78ab8cSAndroid Build Coastguard Worker      height: 1.5em;
113*cf78ab8cSAndroid Build Coastguard Worker      border-radius: 50%;
114*cf78ab8cSAndroid Build Coastguard Worker      background: #fff;
115*cf78ab8cSAndroid Build Coastguard Worker      -webkit-box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.3);
116*cf78ab8cSAndroid Build Coastguard Worker      box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.3);
117*cf78ab8cSAndroid Build Coastguard Worker      -webkit-transform: scale(0.7);
118*cf78ab8cSAndroid Build Coastguard Worker      transform: scale(0.7);
119*cf78ab8cSAndroid Build Coastguard Worker      left: 0;
120*cf78ab8cSAndroid Build Coastguard Worker      -webkit-transition: all 0.2s ease-in-out;
121*cf78ab8cSAndroid Build Coastguard Worker      transition: all 0.2s ease-in-out;
122*cf78ab8cSAndroid Build Coastguard Worker    }
123*cf78ab8cSAndroid Build Coastguard Worker
124*cf78ab8cSAndroid Build Coastguard Worker    input[type='checkbox'].switch_1:checked:after {
125*cf78ab8cSAndroid Build Coastguard Worker      left: calc(100% - 1.5em);
126*cf78ab8cSAndroid Build Coastguard Worker    }
127*cf78ab8cSAndroid Build Coastguard Worker
128*cf78ab8cSAndroid Build Coastguard Worker    button {
129*cf78ab8cSAndroid Build Coastguard Worker      display: inline-block;
130*cf78ab8cSAndroid Build Coastguard Worker      padding: 12px 24px;
131*cf78ab8cSAndroid Build Coastguard Worker      background-color: #4CAF50;
132*cf78ab8cSAndroid Build Coastguard Worker      color: #FFFFFF;
133*cf78ab8cSAndroid Build Coastguard Worker      font-size: 18px;
134*cf78ab8cSAndroid Build Coastguard Worker      font-weight: bold;
135*cf78ab8cSAndroid Build Coastguard Worker      text-align: center;
136*cf78ab8cSAndroid Build Coastguard Worker      text-decoration: none;
137*cf78ab8cSAndroid Build Coastguard Worker      border: none;
138*cf78ab8cSAndroid Build Coastguard Worker      cursor: pointer;
139*cf78ab8cSAndroid Build Coastguard Worker      transition: background-color 0.3s ease;
140*cf78ab8cSAndroid Build Coastguard Worker    }
141*cf78ab8cSAndroid Build Coastguard Worker
142*cf78ab8cSAndroid Build Coastguard Worker    button:hover {
143*cf78ab8cSAndroid Build Coastguard Worker      background-color: #45a049;
144*cf78ab8cSAndroid Build Coastguard Worker      transition: 0.5s;
145*cf78ab8cSAndroid Build Coastguard Worker    }
146*cf78ab8cSAndroid Build Coastguard Worker  `;
147*cf78ab8cSAndroid Build Coastguard Worker
148*cf78ab8cSAndroid Build Coastguard Worker  connectedCallback() {
149*cf78ab8cSAndroid Build Coastguard Worker    super.connectedCallback();  // eslint-disable-line
150*cf78ab8cSAndroid Build Coastguard Worker    simulationState.registerObserver(this);
151*cf78ab8cSAndroid Build Coastguard Worker  }
152*cf78ab8cSAndroid Build Coastguard Worker
153*cf78ab8cSAndroid Build Coastguard Worker  disconnectedCallback() {
154*cf78ab8cSAndroid Build Coastguard Worker    simulationState.removeObserver(this);
155*cf78ab8cSAndroid Build Coastguard Worker    super.disconnectedCallback();  // eslint-disable-line
156*cf78ab8cSAndroid Build Coastguard Worker  }
157*cf78ab8cSAndroid Build Coastguard Worker
158*cf78ab8cSAndroid Build Coastguard Worker  onNotify(data: SimulationInfo) {
159*cf78ab8cSAndroid Build Coastguard Worker    this.captureData = data.captures;
160*cf78ab8cSAndroid Build Coastguard Worker    this.deviceData = data.devices;
161*cf78ab8cSAndroid Build Coastguard Worker    this.requestUpdate();
162*cf78ab8cSAndroid Build Coastguard Worker  }
163*cf78ab8cSAndroid Build Coastguard Worker
164*cf78ab8cSAndroid Build Coastguard Worker  toggleCapture(capture: Capture) {
165*cf78ab8cSAndroid Build Coastguard Worker    let id = capture.id.toString();
166*cf78ab8cSAndroid Build Coastguard Worker    let state = capture.state ? '0' : '1';
167*cf78ab8cSAndroid Build Coastguard Worker    simulationState.patchCapture(id, state);
168*cf78ab8cSAndroid Build Coastguard Worker  }
169*cf78ab8cSAndroid Build Coastguard Worker
170*cf78ab8cSAndroid Build Coastguard Worker  private handleGetChips(device: Device) {
171*cf78ab8cSAndroid Build Coastguard Worker    let btTable = html``;
172*cf78ab8cSAndroid Build Coastguard Worker    let uwbTable = html``;
173*cf78ab8cSAndroid Build Coastguard Worker    let wifiTable = html``;
174*cf78ab8cSAndroid Build Coastguard Worker    if ('chips' in device && device.chips) {
175*cf78ab8cSAndroid Build Coastguard Worker      for (const chip of device.chips) {
176*cf78ab8cSAndroid Build Coastguard Worker        if ('bt' in chip && chip.bt) {
177*cf78ab8cSAndroid Build Coastguard Worker          let bleTable = html``;
178*cf78ab8cSAndroid Build Coastguard Worker          let bclassicTable = html``;
179*cf78ab8cSAndroid Build Coastguard Worker          if ('lowEnergy' in chip.bt && chip.bt.lowEnergy) {
180*cf78ab8cSAndroid Build Coastguard Worker            bleTable = html`
181*cf78ab8cSAndroid Build Coastguard Worker              <tr>
182*cf78ab8cSAndroid Build Coastguard Worker                <td>BLE</td>
183*cf78ab8cSAndroid Build Coastguard Worker                <td>${chip.bt.lowEnergy.rxCount ?? 0}</td>
184*cf78ab8cSAndroid Build Coastguard Worker                <td>${chip.bt.lowEnergy.txCount ?? 0}</td>
185*cf78ab8cSAndroid Build Coastguard Worker              </tr>
186*cf78ab8cSAndroid Build Coastguard Worker            `;
187*cf78ab8cSAndroid Build Coastguard Worker          }
188*cf78ab8cSAndroid Build Coastguard Worker          if ('classic' in chip.bt && chip.bt.classic) {
189*cf78ab8cSAndroid Build Coastguard Worker            bclassicTable = html`
190*cf78ab8cSAndroid Build Coastguard Worker              <tr>
191*cf78ab8cSAndroid Build Coastguard Worker                <td>Bluetooth Classic</td>
192*cf78ab8cSAndroid Build Coastguard Worker                <td>${chip.bt.classic.rxCount ?? 0}</td>
193*cf78ab8cSAndroid Build Coastguard Worker                <td>${chip.bt.classic.txCount ?? 0}</td>
194*cf78ab8cSAndroid Build Coastguard Worker              </tr>
195*cf78ab8cSAndroid Build Coastguard Worker            `;
196*cf78ab8cSAndroid Build Coastguard Worker          }
197*cf78ab8cSAndroid Build Coastguard Worker          btTable = html`${bleTable} ${bclassicTable}`;
198*cf78ab8cSAndroid Build Coastguard Worker        }
199*cf78ab8cSAndroid Build Coastguard Worker        if ('uwb' in chip && chip.uwb) {
200*cf78ab8cSAndroid Build Coastguard Worker          uwbTable = html`
201*cf78ab8cSAndroid Build Coastguard Worker            <tr>
202*cf78ab8cSAndroid Build Coastguard Worker              <td>UWB</td>
203*cf78ab8cSAndroid Build Coastguard Worker              <td>${chip.uwb.rxCount ?? 0}</td>
204*cf78ab8cSAndroid Build Coastguard Worker              <td>${chip.uwb.txCount ?? 0}</td>
205*cf78ab8cSAndroid Build Coastguard Worker            </tr>
206*cf78ab8cSAndroid Build Coastguard Worker          `;
207*cf78ab8cSAndroid Build Coastguard Worker        }
208*cf78ab8cSAndroid Build Coastguard Worker        if ('wifi' in chip && chip.wifi) {
209*cf78ab8cSAndroid Build Coastguard Worker          wifiTable = html`
210*cf78ab8cSAndroid Build Coastguard Worker            <tr>
211*cf78ab8cSAndroid Build Coastguard Worker              <td>WIFI</td>
212*cf78ab8cSAndroid Build Coastguard Worker              <td>${chip.wifi.rxCount ?? 0}</td>
213*cf78ab8cSAndroid Build Coastguard Worker              <td>${chip.wifi.txCount ?? 0}</td>
214*cf78ab8cSAndroid Build Coastguard Worker            </tr>
215*cf78ab8cSAndroid Build Coastguard Worker          `;
216*cf78ab8cSAndroid Build Coastguard Worker        }
217*cf78ab8cSAndroid Build Coastguard Worker      }
218*cf78ab8cSAndroid Build Coastguard Worker    }
219*cf78ab8cSAndroid Build Coastguard Worker    return html`
220*cf78ab8cSAndroid Build Coastguard Worker      ${btTable}
221*cf78ab8cSAndroid Build Coastguard Worker      ${uwbTable}
222*cf78ab8cSAndroid Build Coastguard Worker      ${wifiTable}
223*cf78ab8cSAndroid Build Coastguard Worker    `;
224*cf78ab8cSAndroid Build Coastguard Worker  }
225*cf78ab8cSAndroid Build Coastguard Worker
226*cf78ab8cSAndroid Build Coastguard Worker  private handleListCaptures(capture: Capture) {
227*cf78ab8cSAndroid Build Coastguard Worker    return html`
228*cf78ab8cSAndroid Build Coastguard Worker      <tr>
229*cf78ab8cSAndroid Build Coastguard Worker        <td>${capture.deviceName}</td>
230*cf78ab8cSAndroid Build Coastguard Worker        <td>${capture.chipKind}</td>
231*cf78ab8cSAndroid Build Coastguard Worker        <td>${capture.size}</td>
232*cf78ab8cSAndroid Build Coastguard Worker        <td>${capture.records}</td>
233*cf78ab8cSAndroid Build Coastguard Worker        <td>
234*cf78ab8cSAndroid Build Coastguard Worker        <input
235*cf78ab8cSAndroid Build Coastguard Worker                type="checkbox"
236*cf78ab8cSAndroid Build Coastguard Worker                class="switch_1"
237*cf78ab8cSAndroid Build Coastguard Worker                .checked=${capture.state}
238*cf78ab8cSAndroid Build Coastguard Worker                @click=${() => {
239*cf78ab8cSAndroid Build Coastguard Worker      this.toggleCapture(capture);
240*cf78ab8cSAndroid Build Coastguard Worker    }}
241*cf78ab8cSAndroid Build Coastguard Worker              />
242*cf78ab8cSAndroid Build Coastguard Worker        </td>
243*cf78ab8cSAndroid Build Coastguard Worker        <td>
244*cf78ab8cSAndroid Build Coastguard Worker          <a
245*cf78ab8cSAndroid Build Coastguard Worker            href="./v1/captures/${capture.id}"
246*cf78ab8cSAndroid Build Coastguard Worker            target="_blank"
247*cf78ab8cSAndroid Build Coastguard Worker            type="application/vnd.tcpdump.pcap"
248*cf78ab8cSAndroid Build Coastguard Worker            ><button>Download</button></a
249*cf78ab8cSAndroid Build Coastguard Worker          >
250*cf78ab8cSAndroid Build Coastguard Worker        </td>
251*cf78ab8cSAndroid Build Coastguard Worker      </tr>
252*cf78ab8cSAndroid Build Coastguard Worker    `
253*cf78ab8cSAndroid Build Coastguard Worker  }
254*cf78ab8cSAndroid Build Coastguard Worker
255*cf78ab8cSAndroid Build Coastguard Worker  render() {
256*cf78ab8cSAndroid Build Coastguard Worker    return html`
257*cf78ab8cSAndroid Build Coastguard Worker      <div class="panel">
258*cf78ab8cSAndroid Build Coastguard Worker        <div class="title">Packet Info</div>
259*cf78ab8cSAndroid Build Coastguard Worker        ${this.deviceData.map(device => html`
260*cf78ab8cSAndroid Build Coastguard Worker              <div class="label">${device.name}</div>
261*cf78ab8cSAndroid Build Coastguard Worker              <table class="styled-table">
262*cf78ab8cSAndroid Build Coastguard Worker                <tr>
263*cf78ab8cSAndroid Build Coastguard Worker                  <th>Radio</th>
264*cf78ab8cSAndroid Build Coastguard Worker                  <th>RX Count</th>
265*cf78ab8cSAndroid Build Coastguard Worker                  <th>TX Count</th>
266*cf78ab8cSAndroid Build Coastguard Worker                </tr>
267*cf78ab8cSAndroid Build Coastguard Worker                ${this.handleGetChips(device)}
268*cf78ab8cSAndroid Build Coastguard Worker              </table>
269*cf78ab8cSAndroid Build Coastguard Worker            `)}
270*cf78ab8cSAndroid Build Coastguard Worker      </div>
271*cf78ab8cSAndroid Build Coastguard Worker      <div class="panel">
272*cf78ab8cSAndroid Build Coastguard Worker        <div class="title">Packet Capture</div>
273*cf78ab8cSAndroid Build Coastguard Worker        <table class="styled-table">
274*cf78ab8cSAndroid Build Coastguard Worker          <tr>
275*cf78ab8cSAndroid Build Coastguard Worker            <th>Device Name</th>
276*cf78ab8cSAndroid Build Coastguard Worker            <th>Chip Kind</th>
277*cf78ab8cSAndroid Build Coastguard Worker            <th>Bytes</th>
278*cf78ab8cSAndroid Build Coastguard Worker            <th>Records</th>
279*cf78ab8cSAndroid Build Coastguard Worker            <th>Capture State</th>
280*cf78ab8cSAndroid Build Coastguard Worker            <th>Download Pcap</th>
281*cf78ab8cSAndroid Build Coastguard Worker          </tr>
282*cf78ab8cSAndroid Build Coastguard Worker          ${this.captureData.map(capture => this.handleListCaptures(capture))}
283*cf78ab8cSAndroid Build Coastguard Worker        </table>
284*cf78ab8cSAndroid Build Coastguard Worker      </div>
285*cf78ab8cSAndroid Build Coastguard Worker    `;
286*cf78ab8cSAndroid Build Coastguard Worker  }
287*cf78ab8cSAndroid Build Coastguard Worker}
288