xref: /aosp_15_r20/tools/netsim/ui/ts/device-observer.ts (revision cf78ab8cffb8fc9207af348f23af247fb04370a6)
1*cf78ab8cSAndroid Build Coastguard Workerimport {Capture, Chip, Chip_Radio, Device as ProtoDevice,} from './netsim/model.js';
2*cf78ab8cSAndroid Build Coastguard Worker
3*cf78ab8cSAndroid Build Coastguard Worker// URL for netsim
4*cf78ab8cSAndroid Build Coastguard Workerconst DEVICES_URL = './v1/devices';
5*cf78ab8cSAndroid Build Coastguard Workerconst CAPTURES_URL = './v1/captures';
6*cf78ab8cSAndroid Build Coastguard Worker
7*cf78ab8cSAndroid Build Coastguard Worker/**
8*cf78ab8cSAndroid Build Coastguard Worker * Interface for a method in notifying the subscribed observers.
9*cf78ab8cSAndroid Build Coastguard Worker * Subscribed observers must implement this interface.
10*cf78ab8cSAndroid Build Coastguard Worker */
11*cf78ab8cSAndroid Build Coastguard Workerexport interface Notifiable {
12*cf78ab8cSAndroid Build Coastguard Worker  onNotify(data: {}): void;
13*cf78ab8cSAndroid Build Coastguard Worker}
14*cf78ab8cSAndroid Build Coastguard Worker
15*cf78ab8cSAndroid Build Coastguard Worker/**
16*cf78ab8cSAndroid Build Coastguard Worker * Modularization of Device.
17*cf78ab8cSAndroid Build Coastguard Worker * Contains getters and setters for properties in Device interface.
18*cf78ab8cSAndroid Build Coastguard Worker */
19*cf78ab8cSAndroid Build Coastguard Workerexport class Device {
20*cf78ab8cSAndroid Build Coastguard Worker  device: ProtoDevice;
21*cf78ab8cSAndroid Build Coastguard Worker
22*cf78ab8cSAndroid Build Coastguard Worker  constructor(device: ProtoDevice) {
23*cf78ab8cSAndroid Build Coastguard Worker    this.device = device;
24*cf78ab8cSAndroid Build Coastguard Worker  }
25*cf78ab8cSAndroid Build Coastguard Worker
26*cf78ab8cSAndroid Build Coastguard Worker  get name(): string {
27*cf78ab8cSAndroid Build Coastguard Worker    return this.device.name;
28*cf78ab8cSAndroid Build Coastguard Worker  }
29*cf78ab8cSAndroid Build Coastguard Worker
30*cf78ab8cSAndroid Build Coastguard Worker  set name(value: string) {
31*cf78ab8cSAndroid Build Coastguard Worker    this.device.name = value;
32*cf78ab8cSAndroid Build Coastguard Worker  }
33*cf78ab8cSAndroid Build Coastguard Worker
34*cf78ab8cSAndroid Build Coastguard Worker  get position(): {x: number; y: number; z: number} {
35*cf78ab8cSAndroid Build Coastguard Worker    const result = {x: 0, y: 0, z: 0};
36*cf78ab8cSAndroid Build Coastguard Worker    if ('position' in this.device && this.device.position &&
37*cf78ab8cSAndroid Build Coastguard Worker        typeof this.device.position === 'object') {
38*cf78ab8cSAndroid Build Coastguard Worker      if ('x' in this.device.position &&
39*cf78ab8cSAndroid Build Coastguard Worker          typeof this.device.position.x === 'number') {
40*cf78ab8cSAndroid Build Coastguard Worker        result.x = this.device.position.x;
41*cf78ab8cSAndroid Build Coastguard Worker      }
42*cf78ab8cSAndroid Build Coastguard Worker      if ('y' in this.device.position &&
43*cf78ab8cSAndroid Build Coastguard Worker          typeof this.device.position.y === 'number') {
44*cf78ab8cSAndroid Build Coastguard Worker        result.y = this.device.position.y;
45*cf78ab8cSAndroid Build Coastguard Worker      }
46*cf78ab8cSAndroid Build Coastguard Worker      if ('z' in this.device.position &&
47*cf78ab8cSAndroid Build Coastguard Worker          typeof this.device.position.z === 'number') {
48*cf78ab8cSAndroid Build Coastguard Worker        result.z = this.device.position.z;
49*cf78ab8cSAndroid Build Coastguard Worker      }
50*cf78ab8cSAndroid Build Coastguard Worker    }
51*cf78ab8cSAndroid Build Coastguard Worker    return result;
52*cf78ab8cSAndroid Build Coastguard Worker  }
53*cf78ab8cSAndroid Build Coastguard Worker
54*cf78ab8cSAndroid Build Coastguard Worker  set position(pos: {x: number; y: number; z: number}) {
55*cf78ab8cSAndroid Build Coastguard Worker    this.device.position = pos;
56*cf78ab8cSAndroid Build Coastguard Worker  }
57*cf78ab8cSAndroid Build Coastguard Worker
58*cf78ab8cSAndroid Build Coastguard Worker  get orientation(): {yaw: number; pitch: number; roll: number} {
59*cf78ab8cSAndroid Build Coastguard Worker    const result = {yaw: 0, pitch: 0, roll: 0};
60*cf78ab8cSAndroid Build Coastguard Worker    if ('orientation' in this.device && this.device.orientation &&
61*cf78ab8cSAndroid Build Coastguard Worker        typeof this.device.orientation === 'object') {
62*cf78ab8cSAndroid Build Coastguard Worker      if ('yaw' in this.device.orientation &&
63*cf78ab8cSAndroid Build Coastguard Worker          typeof this.device.orientation.yaw === 'number') {
64*cf78ab8cSAndroid Build Coastguard Worker        result.yaw = this.device.orientation.yaw;
65*cf78ab8cSAndroid Build Coastguard Worker      }
66*cf78ab8cSAndroid Build Coastguard Worker      if ('pitch' in this.device.orientation &&
67*cf78ab8cSAndroid Build Coastguard Worker          typeof this.device.orientation.pitch === 'number') {
68*cf78ab8cSAndroid Build Coastguard Worker        result.pitch = this.device.orientation.pitch;
69*cf78ab8cSAndroid Build Coastguard Worker      }
70*cf78ab8cSAndroid Build Coastguard Worker      if ('roll' in this.device.orientation &&
71*cf78ab8cSAndroid Build Coastguard Worker          typeof this.device.orientation.roll === 'number') {
72*cf78ab8cSAndroid Build Coastguard Worker        result.roll = this.device.orientation.roll;
73*cf78ab8cSAndroid Build Coastguard Worker      }
74*cf78ab8cSAndroid Build Coastguard Worker    }
75*cf78ab8cSAndroid Build Coastguard Worker    return result;
76*cf78ab8cSAndroid Build Coastguard Worker  }
77*cf78ab8cSAndroid Build Coastguard Worker
78*cf78ab8cSAndroid Build Coastguard Worker  set orientation(ori: {yaw: number; pitch: number; roll: number}) {
79*cf78ab8cSAndroid Build Coastguard Worker    this.device.orientation = ori;
80*cf78ab8cSAndroid Build Coastguard Worker  }
81*cf78ab8cSAndroid Build Coastguard Worker
82*cf78ab8cSAndroid Build Coastguard Worker  // TODO modularize getters and setters for Chip Interface
83*cf78ab8cSAndroid Build Coastguard Worker  get chips(): Chip[] {
84*cf78ab8cSAndroid Build Coastguard Worker    return this.device.chips ?? [];
85*cf78ab8cSAndroid Build Coastguard Worker  }
86*cf78ab8cSAndroid Build Coastguard Worker
87*cf78ab8cSAndroid Build Coastguard Worker  // TODO modularize getters and setters for Chip Interface
88*cf78ab8cSAndroid Build Coastguard Worker  set chips(value: Chip[]) {
89*cf78ab8cSAndroid Build Coastguard Worker    this.device.chips = value;
90*cf78ab8cSAndroid Build Coastguard Worker  }
91*cf78ab8cSAndroid Build Coastguard Worker
92*cf78ab8cSAndroid Build Coastguard Worker  get visible(): boolean {
93*cf78ab8cSAndroid Build Coastguard Worker    return Boolean(this.device.visible);
94*cf78ab8cSAndroid Build Coastguard Worker  }
95*cf78ab8cSAndroid Build Coastguard Worker
96*cf78ab8cSAndroid Build Coastguard Worker  set visible(value: boolean) {
97*cf78ab8cSAndroid Build Coastguard Worker    this.device.visible = value;
98*cf78ab8cSAndroid Build Coastguard Worker  }
99*cf78ab8cSAndroid Build Coastguard Worker
100*cf78ab8cSAndroid Build Coastguard Worker  toggleChipState(radio: Chip_Radio) {
101*cf78ab8cSAndroid Build Coastguard Worker    radio.state = !radio.state;
102*cf78ab8cSAndroid Build Coastguard Worker  }
103*cf78ab8cSAndroid Build Coastguard Worker
104*cf78ab8cSAndroid Build Coastguard Worker  toggleCapture(device: Device, chip: Chip) {
105*cf78ab8cSAndroid Build Coastguard Worker    if ('capture' in chip && chip.capture) {
106*cf78ab8cSAndroid Build Coastguard Worker      chip.capture = !chip.capture;
107*cf78ab8cSAndroid Build Coastguard Worker      simulationState.patchDevice({
108*cf78ab8cSAndroid Build Coastguard Worker        device: {
109*cf78ab8cSAndroid Build Coastguard Worker          name: device.name,
110*cf78ab8cSAndroid Build Coastguard Worker          chips: device.chips,
111*cf78ab8cSAndroid Build Coastguard Worker        },
112*cf78ab8cSAndroid Build Coastguard Worker      });
113*cf78ab8cSAndroid Build Coastguard Worker    }
114*cf78ab8cSAndroid Build Coastguard Worker  }
115*cf78ab8cSAndroid Build Coastguard Worker}
116*cf78ab8cSAndroid Build Coastguard Worker
117*cf78ab8cSAndroid Build Coastguard Worker/**
118*cf78ab8cSAndroid Build Coastguard Worker * The most recent state of the simulation.
119*cf78ab8cSAndroid Build Coastguard Worker * Subscribed observers must refer to this info and patch accordingly.
120*cf78ab8cSAndroid Build Coastguard Worker */
121*cf78ab8cSAndroid Build Coastguard Workerexport interface SimulationInfo {
122*cf78ab8cSAndroid Build Coastguard Worker  devices: Device[];
123*cf78ab8cSAndroid Build Coastguard Worker  captures: Capture[];
124*cf78ab8cSAndroid Build Coastguard Worker  selectedId: string;
125*cf78ab8cSAndroid Build Coastguard Worker  dimension: {x: number; y: number; z: number};
126*cf78ab8cSAndroid Build Coastguard Worker  lastModified: string;
127*cf78ab8cSAndroid Build Coastguard Worker}
128*cf78ab8cSAndroid Build Coastguard Worker
129*cf78ab8cSAndroid Build Coastguard Workerinterface Observable {
130*cf78ab8cSAndroid Build Coastguard Worker  registerObserver(elem: Notifiable): void;
131*cf78ab8cSAndroid Build Coastguard Worker  removeObserver(elem: Notifiable): void;
132*cf78ab8cSAndroid Build Coastguard Worker}
133*cf78ab8cSAndroid Build Coastguard Worker
134*cf78ab8cSAndroid Build Coastguard Workerclass SimulationState implements Observable {
135*cf78ab8cSAndroid Build Coastguard Worker  private observers: Notifiable[] = [];
136*cf78ab8cSAndroid Build Coastguard Worker
137*cf78ab8cSAndroid Build Coastguard Worker  private simulationInfo: SimulationInfo = {
138*cf78ab8cSAndroid Build Coastguard Worker    devices: [],
139*cf78ab8cSAndroid Build Coastguard Worker    captures: [],
140*cf78ab8cSAndroid Build Coastguard Worker    selectedId: '',
141*cf78ab8cSAndroid Build Coastguard Worker    dimension: {x: 10, y: 10, z: 0},
142*cf78ab8cSAndroid Build Coastguard Worker    lastModified: '',
143*cf78ab8cSAndroid Build Coastguard Worker  };
144*cf78ab8cSAndroid Build Coastguard Worker
145*cf78ab8cSAndroid Build Coastguard Worker  constructor() {
146*cf78ab8cSAndroid Build Coastguard Worker    // initial GET
147*cf78ab8cSAndroid Build Coastguard Worker    this.invokeGetDevice();
148*cf78ab8cSAndroid Build Coastguard Worker    this.invokeListCaptures();
149*cf78ab8cSAndroid Build Coastguard Worker  }
150*cf78ab8cSAndroid Build Coastguard Worker
151*cf78ab8cSAndroid Build Coastguard Worker  async invokeGetDevice() {
152*cf78ab8cSAndroid Build Coastguard Worker    await fetch(DEVICES_URL, {
153*cf78ab8cSAndroid Build Coastguard Worker      method: 'GET',
154*cf78ab8cSAndroid Build Coastguard Worker    })
155*cf78ab8cSAndroid Build Coastguard Worker        .then(response => response.json())
156*cf78ab8cSAndroid Build Coastguard Worker        .then(data => {
157*cf78ab8cSAndroid Build Coastguard Worker          this.fetchDevice(data.devices);
158*cf78ab8cSAndroid Build Coastguard Worker          this.updateLastModified(data.lastModified);
159*cf78ab8cSAndroid Build Coastguard Worker        })
160*cf78ab8cSAndroid Build Coastguard Worker        .catch(error => {
161*cf78ab8cSAndroid Build Coastguard Worker          // eslint-disable-next-line
162*cf78ab8cSAndroid Build Coastguard Worker          console.log('Cannot connect to netsim web server', error);
163*cf78ab8cSAndroid Build Coastguard Worker        });
164*cf78ab8cSAndroid Build Coastguard Worker  }
165*cf78ab8cSAndroid Build Coastguard Worker
166*cf78ab8cSAndroid Build Coastguard Worker  async invokeListCaptures() {
167*cf78ab8cSAndroid Build Coastguard Worker    await fetch(CAPTURES_URL, {
168*cf78ab8cSAndroid Build Coastguard Worker      method: 'GET',
169*cf78ab8cSAndroid Build Coastguard Worker    })
170*cf78ab8cSAndroid Build Coastguard Worker        .then(response => response.json())
171*cf78ab8cSAndroid Build Coastguard Worker        .then(data => {
172*cf78ab8cSAndroid Build Coastguard Worker          this.simulationInfo.captures = data.captures;
173*cf78ab8cSAndroid Build Coastguard Worker          this.notifyObservers();
174*cf78ab8cSAndroid Build Coastguard Worker        })
175*cf78ab8cSAndroid Build Coastguard Worker        .catch(error => {
176*cf78ab8cSAndroid Build Coastguard Worker          console.log('Cannot connect to netsim web server', error);
177*cf78ab8cSAndroid Build Coastguard Worker        });
178*cf78ab8cSAndroid Build Coastguard Worker  }
179*cf78ab8cSAndroid Build Coastguard Worker
180*cf78ab8cSAndroid Build Coastguard Worker  fetchDevice(devices?: ProtoDevice[]) {
181*cf78ab8cSAndroid Build Coastguard Worker    this.simulationInfo.devices = [];
182*cf78ab8cSAndroid Build Coastguard Worker    if (devices) {
183*cf78ab8cSAndroid Build Coastguard Worker      this.simulationInfo.devices = devices.map(device => new Device(device));
184*cf78ab8cSAndroid Build Coastguard Worker    }
185*cf78ab8cSAndroid Build Coastguard Worker    this.notifyObservers();
186*cf78ab8cSAndroid Build Coastguard Worker  }
187*cf78ab8cSAndroid Build Coastguard Worker
188*cf78ab8cSAndroid Build Coastguard Worker  getLastModified() {
189*cf78ab8cSAndroid Build Coastguard Worker    return this.simulationInfo.lastModified;
190*cf78ab8cSAndroid Build Coastguard Worker  }
191*cf78ab8cSAndroid Build Coastguard Worker
192*cf78ab8cSAndroid Build Coastguard Worker  updateLastModified(timestamp: string) {
193*cf78ab8cSAndroid Build Coastguard Worker    this.simulationInfo.lastModified = timestamp;
194*cf78ab8cSAndroid Build Coastguard Worker  }
195*cf78ab8cSAndroid Build Coastguard Worker
196*cf78ab8cSAndroid Build Coastguard Worker  patchSelected(id: string) {
197*cf78ab8cSAndroid Build Coastguard Worker    this.simulationInfo.selectedId = id;
198*cf78ab8cSAndroid Build Coastguard Worker    this.notifyObservers();
199*cf78ab8cSAndroid Build Coastguard Worker  }
200*cf78ab8cSAndroid Build Coastguard Worker
201*cf78ab8cSAndroid Build Coastguard Worker  handleDrop(id: string, x: number, y: number) {
202*cf78ab8cSAndroid Build Coastguard Worker    this.simulationInfo.selectedId = id;
203*cf78ab8cSAndroid Build Coastguard Worker    for (const device of this.simulationInfo.devices) {
204*cf78ab8cSAndroid Build Coastguard Worker      if (id === device.name) {
205*cf78ab8cSAndroid Build Coastguard Worker        device.position = {x, y, z: device.position.z};
206*cf78ab8cSAndroid Build Coastguard Worker        this.patchDevice({
207*cf78ab8cSAndroid Build Coastguard Worker          device: {
208*cf78ab8cSAndroid Build Coastguard Worker            name: device.name,
209*cf78ab8cSAndroid Build Coastguard Worker            position: device.position,
210*cf78ab8cSAndroid Build Coastguard Worker          },
211*cf78ab8cSAndroid Build Coastguard Worker        });
212*cf78ab8cSAndroid Build Coastguard Worker        break;
213*cf78ab8cSAndroid Build Coastguard Worker      }
214*cf78ab8cSAndroid Build Coastguard Worker    }
215*cf78ab8cSAndroid Build Coastguard Worker  }
216*cf78ab8cSAndroid Build Coastguard Worker
217*cf78ab8cSAndroid Build Coastguard Worker  patchCapture(id: string, state: string) {
218*cf78ab8cSAndroid Build Coastguard Worker    fetch(CAPTURES_URL + '/' + id, {
219*cf78ab8cSAndroid Build Coastguard Worker      method: 'PATCH',
220*cf78ab8cSAndroid Build Coastguard Worker      headers: {
221*cf78ab8cSAndroid Build Coastguard Worker        'Content-Type': 'text/plain',
222*cf78ab8cSAndroid Build Coastguard Worker        'Content-Length': state.length.toString(),
223*cf78ab8cSAndroid Build Coastguard Worker      },
224*cf78ab8cSAndroid Build Coastguard Worker      body: state,
225*cf78ab8cSAndroid Build Coastguard Worker    });
226*cf78ab8cSAndroid Build Coastguard Worker    this.notifyObservers();
227*cf78ab8cSAndroid Build Coastguard Worker  }
228*cf78ab8cSAndroid Build Coastguard Worker
229*cf78ab8cSAndroid Build Coastguard Worker  patchDevice(obj: object) {
230*cf78ab8cSAndroid Build Coastguard Worker    const jsonBody = JSON.stringify(obj);
231*cf78ab8cSAndroid Build Coastguard Worker    fetch(DEVICES_URL, {
232*cf78ab8cSAndroid Build Coastguard Worker      method: 'PATCH',
233*cf78ab8cSAndroid Build Coastguard Worker      headers: {
234*cf78ab8cSAndroid Build Coastguard Worker        'Content-Type': 'application/json',
235*cf78ab8cSAndroid Build Coastguard Worker        'Content-Length': jsonBody.length.toString(),
236*cf78ab8cSAndroid Build Coastguard Worker      },
237*cf78ab8cSAndroid Build Coastguard Worker      body: jsonBody,
238*cf78ab8cSAndroid Build Coastguard Worker    })
239*cf78ab8cSAndroid Build Coastguard Worker        .then(response => response.json())
240*cf78ab8cSAndroid Build Coastguard Worker        .catch(error => {
241*cf78ab8cSAndroid Build Coastguard Worker          // eslint-disable-next-line
242*cf78ab8cSAndroid Build Coastguard Worker          console.error('Error:', error);
243*cf78ab8cSAndroid Build Coastguard Worker        });
244*cf78ab8cSAndroid Build Coastguard Worker    this.notifyObservers();
245*cf78ab8cSAndroid Build Coastguard Worker  }
246*cf78ab8cSAndroid Build Coastguard Worker
247*cf78ab8cSAndroid Build Coastguard Worker  registerObserver(elem: Notifiable) {
248*cf78ab8cSAndroid Build Coastguard Worker    this.observers.push(elem);
249*cf78ab8cSAndroid Build Coastguard Worker    elem.onNotify(this.simulationInfo);
250*cf78ab8cSAndroid Build Coastguard Worker  }
251*cf78ab8cSAndroid Build Coastguard Worker
252*cf78ab8cSAndroid Build Coastguard Worker  removeObserver(elem: Notifiable) {
253*cf78ab8cSAndroid Build Coastguard Worker    const index = this.observers.indexOf(elem);
254*cf78ab8cSAndroid Build Coastguard Worker    this.observers.splice(index, 1);
255*cf78ab8cSAndroid Build Coastguard Worker  }
256*cf78ab8cSAndroid Build Coastguard Worker
257*cf78ab8cSAndroid Build Coastguard Worker  notifyObservers() {
258*cf78ab8cSAndroid Build Coastguard Worker    for (const observer of this.observers) {
259*cf78ab8cSAndroid Build Coastguard Worker      observer.onNotify(this.simulationInfo);
260*cf78ab8cSAndroid Build Coastguard Worker    }
261*cf78ab8cSAndroid Build Coastguard Worker  }
262*cf78ab8cSAndroid Build Coastguard Worker
263*cf78ab8cSAndroid Build Coastguard Worker  getDeviceList() {
264*cf78ab8cSAndroid Build Coastguard Worker    return this.simulationInfo.devices;
265*cf78ab8cSAndroid Build Coastguard Worker  }
266*cf78ab8cSAndroid Build Coastguard Worker}
267*cf78ab8cSAndroid Build Coastguard Worker
268*cf78ab8cSAndroid Build Coastguard Worker/** Subscribed observers must register itself to the simulationState */
269*cf78ab8cSAndroid Build Coastguard Workerexport const simulationState = new SimulationState();
270*cf78ab8cSAndroid Build Coastguard Worker
271*cf78ab8cSAndroid Build Coastguard Workerasync function subscribeCaptures() {
272*cf78ab8cSAndroid Build Coastguard Worker  const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
273*cf78ab8cSAndroid Build Coastguard Worker  while (true) {
274*cf78ab8cSAndroid Build Coastguard Worker    await simulationState.invokeListCaptures();
275*cf78ab8cSAndroid Build Coastguard Worker    await simulationState.invokeGetDevice();
276*cf78ab8cSAndroid Build Coastguard Worker    await delay(1000);
277*cf78ab8cSAndroid Build Coastguard Worker  }
278*cf78ab8cSAndroid Build Coastguard Worker}
279*cf78ab8cSAndroid Build Coastguard Worker
280*cf78ab8cSAndroid Build Coastguard Workerasync function subscribeDevices() {
281*cf78ab8cSAndroid Build Coastguard Worker  await simulationState.invokeGetDevice();
282*cf78ab8cSAndroid Build Coastguard Worker  while (true) {
283*cf78ab8cSAndroid Build Coastguard Worker    const jsonBody = JSON.stringify({
284*cf78ab8cSAndroid Build Coastguard Worker      lastModified: simulationState.getLastModified(),
285*cf78ab8cSAndroid Build Coastguard Worker    });
286*cf78ab8cSAndroid Build Coastguard Worker    await fetch(DEVICES_URL, {
287*cf78ab8cSAndroid Build Coastguard Worker      method: 'SUBSCRIBE',
288*cf78ab8cSAndroid Build Coastguard Worker      headers: {
289*cf78ab8cSAndroid Build Coastguard Worker        'Content-Type': 'application/json',
290*cf78ab8cSAndroid Build Coastguard Worker        'Content-Length': jsonBody.length.toString(),
291*cf78ab8cSAndroid Build Coastguard Worker      },
292*cf78ab8cSAndroid Build Coastguard Worker      body: jsonBody,
293*cf78ab8cSAndroid Build Coastguard Worker    })
294*cf78ab8cSAndroid Build Coastguard Worker        .then(response => response.json())
295*cf78ab8cSAndroid Build Coastguard Worker        .then(data => {
296*cf78ab8cSAndroid Build Coastguard Worker          simulationState.fetchDevice(data.devices);
297*cf78ab8cSAndroid Build Coastguard Worker          simulationState.updateLastModified(data.lastModified);
298*cf78ab8cSAndroid Build Coastguard Worker        })
299*cf78ab8cSAndroid Build Coastguard Worker        .catch(error => {
300*cf78ab8cSAndroid Build Coastguard Worker          // eslint-disable-next-line
301*cf78ab8cSAndroid Build Coastguard Worker          console.log('Cannot connect to netsim web server', error);
302*cf78ab8cSAndroid Build Coastguard Worker        });
303*cf78ab8cSAndroid Build Coastguard Worker  }
304*cf78ab8cSAndroid Build Coastguard Worker}
305*cf78ab8cSAndroid Build Coastguard Worker
306*cf78ab8cSAndroid Build Coastguard WorkersubscribeCaptures();
307*cf78ab8cSAndroid Build Coastguard WorkersubscribeDevices();
308