• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stephendade / Rpanion-server / 19425374606

17 Nov 2025 09:51AM UTC coverage: 34.54% (-0.007%) from 34.547%
19425374606

push

github

stephendade
Video server: RTSP server has seperate pipline for each client

330 of 1234 branches covered (26.74%)

Branch coverage included in aggregate %.

1006 of 2634 relevant lines covered (38.19%)

2.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

8.8
/server/networkManager.js
1
const { exec, execSync, execFile } = require('child_process')
3✔
2

3
function getAdapters (callback) {
4
  // Get all network adapter name, type and states
5
  exec('sudo nmcli -t -f device,type,state dev', (error, stdout, stderr) => {
3✔
6
    const netStatusList = []
3✔
7
    if (stderr) {
3!
8
      console.error(`exec error: ${error}`)
×
9
      return callback(stderr)
×
10
    } else {
11
      stdout.split('\n').forEach(function (item) {
3✔
12
        const device = item.split(':')
13✔
13
        if (device.length === 3 && device[1] !== 'loopback' && device[1] !== 'bridge' && device[1] !== 'wifi-p2p' && device[1] !== 'can0' && device[1] !== 'can1') {
13✔
14
          console.log('Adding Network device ' + device[0])
4✔
15
          // if wifi, check for avail channels
16
          const freqList = []
4✔
17
          freqList.push({ value: 0, freq: 0, label: 'auto', band: 0 })
4✔
18
          if (device[1] === 'wifi') {
4!
19
            try {
×
20
              const output = execSync('iwlist ' + device[0] + ' channel')
×
21
              const allFreqs = output.toString().split('\n')
×
22
              for (let i = 0, len = allFreqs.length; i < len; i++) {
×
23
                if (allFreqs[i].includes('Channel ') && !allFreqs[i].includes('Current')) {
×
24
                  const ln = allFreqs[i].split(' ').filter(i => i)
×
25
                  if (ln.length > 4) {
×
26
                    freqList.push({ value: parseInt(ln[1]), freq: ln[3], label: '' + ln[1] + ' (' + ln[3] + ' GHz)', band: ((parseFloat(ln[3]) < 3) ? 'bg' : 'a') })
×
27
                  }
28
                }
29
              }
30
            } catch (e) {
31
              console.error('exec error: ' + e)
×
32
              return callback(e)
×
33
            }
34
          }
35
          netStatusList.push({ value: device[0], label: device[0] + ' (' + device[1] + ')', type: device[1], state: device[2], channels: freqList, isDisabled: !!((device[2] === 'unavailable' && device[1] === 'wifi')) })
4!
36
        }
37
      })
38
    }
39
    return callback(null, netStatusList)
3✔
40
  })
41
}
42

43
function getWirelessStatus (callback) {
44
  // get the "flight mode" status of the wireless (wifi) adapters
45
  exec('sudo nmcli -t radio wifi', (error, stdout, stderr) => {
×
46
    if (stderr) {
×
47
      console.error(`exec error: ${error}`)
×
48
      return callback(stderr)
×
49
    } else {
50
      console.log('Wifi is ' + stdout)
×
51
      if (stdout === 'enabled\n') {
×
52
        return callback(null, true)
×
53
      } else {
54
        return callback(null, false)
×
55
      }
56
    }
57
  })
58
}
59

60
function setWirelessStatus (status, callback) {
61
  exec('sudo nmcli radio wifi ' + ((status === true) ? 'on' : 'off') + ' && sudo nmcli -t radio wifi', (error, stdout, stderr) => {
×
62
    if (stderr) {
×
63
      console.error(`exec error: ${error}`)
×
64
      return callback(stderr)
×
65
    } else {
66
      if (stdout === 'enabled\n') {
×
67
        return callback(null, true)
×
68
      } else {
69
        return callback(null, false)
×
70
      }
71
    }
72
  })
73
}
74

75
function activateConnection (conName, callback) {
76
  // activate the connection (by id)
77
  // assumed that conName is a valid UUID
78
  execFile('sudo', ['nmcli', 'connection', 'mod', conName, 'connection.autoconnect', 'yes'], (error, stdout, stderr) => {
×
79
    if (stderr) {
×
80
      console.error(`exec error: ${error}`)
×
81
      return callback(stderr)
×
82
    } else {
83
      execFile('sudo', ['nmcli', 'connection', 'up', conName], (error, stdout, stderr) => {
×
84
        if (stderr) {
×
85
          console.error(`exec error: ${error}`)
×
86
          return callback(stderr)
×
87
        } else {
88
          console.log('Activated network: ' + conName)
×
89
          return callback(null, 'OK')
×
90
        }
91
      })
92
    }
93
  })
94
}
95

96
function deactivateConnection (conName, callback) {
97
  // deactivate the connection (by id)
98
  // assumed that conName is a valid UUID
99
  // need to disable auto-connect too
100
  execFile('sudo', ['nmcli', 'connection', 'mod', conName, 'connection.autoconnect', 'no'], (error, stdout, stderr) => {
×
101
    if (stderr) {
×
102
      console.error(`exec error: ${error}`)
×
103
      return callback(stderr)
×
104
    } else {
105
      execFile('sudo', ['nmcli', 'connection', 'down', conName], (error, stdout, stderr) => {
×
106
        if (stderr) {
×
107
          console.error(`exec error: ${error}`)
×
108
          return callback(stderr)
×
109
        } else {
110
          console.log('Dectivated network: ' + conName)
×
111
          return callback(null, 'OK')
×
112
        }
113
      })
114
    }
115
  })
116
}
117

118
function getPrimaryWifiDevice(callback) {
119
  exec('iw dev | grep Interface | awk \'{print $2}\'', (error, stdout, stderr) => {
×
120
      if (error) {
×
121
          console.error(`exec error: ${error}`)
×
122
          return callback(error)
×
123
      }
124
      if (stderr) {
×
125
          console.error(`stderr: ${stderr}`)
×
126
          return callback(new Error(stderr))
×
127
      }
128
      const device = stdout.trim().split('\n')[0]
×
129
      callback(null, device)
×
130
  });
131
}
132

133
function getWifiScan(callback) {
134
  getPrimaryWifiDevice((error, device) => {
×
135
    if (error) {
×
136
      return callback(error)
×
137
    }
138

139
    exec(`sudo iw dev ${device} scan ap-force`, (error, stdout, stderr) => {
×
140
      if (error) {
×
141
        console.error(`exec error: ${error}`)
×
142
        return callback(error)
×
143
      }
144
      if (stderr) {
×
145
        console.error(`stderr: ${stderr}`)
×
146
        return callback(new Error(stderr))
×
147
      }
148

149
      const networks = [];
×
150
      let current = null;
×
151

152
      stdout.split("\n").forEach(line => {
×
153
        line = line.trim();
×
154

155
        if (line.startsWith("BSS ")) {
×
156
          if (current) networks.push(current);
×
157
          current = { ssid: null, signal: null, security: "Open" };
×
158
          return;
×
159
        }
160

161
        if (!current) return;
×
162

163
        if (line.startsWith("SSID:")) {
×
164
          current.ssid = line.slice(5).trim();
×
165
          // if not ascii, return
166
          if (!/^[\x00-\x7F]*$/.test(current.ssid)) {
×
167
            return;
×
168
          }
169
        }
170

171
        if (line.startsWith("signal:")) {
×
172
          const dBm = parseFloat(line.split(" ")[1]);
×
173
          current.signal = dBm;
×
174
        }
175

176
        if (line.includes("RSN:")) {
×
177
          current.security = "WPA2";
×
178
        } else if (line.includes("WPA:")) {
×
179
          current.security = "WPA";
×
180
        } else if (line.includes("WEP:")) {
×
181
          current.security = "WEP";
×
182
        }
183
      });
184
      if (current) networks.push(current);
×
185
      callback(null, networks
×
186
        .filter(net => net.ssid) // Filter out entries without SSID
×
187
        .sort((a, b) => b.signal - a.signal) // Sort by signal strength descending
×
188
      );
189
    });
190
  })
191
}
192

193
function addConnection (conNameStr, conType, conAdapter, conSettings, callback) {
194
  // add a new connection with name conNameStr and settings
195
  // conSettings
196
  // nmcli connection add type wifi ifname $IFNAME con-name $APNAME ssid $SSID
197
  // due to the multiple edits, we need to set autoconnect to "no"
198
  if (conType === 'wifi') {
×
199
    // Build nmcli command gradually for readability
200
    // Build argument array for nmcli command
201
    let nmcliArgs = ['connection', 'add', 'type', conType, 'ifname', conAdapter, 'con-name', conNameStr, 'ssid', conSettings.ssid, '802-11-wireless.mode', conSettings.mode];
×
202

203
    if (conSettings.band !== undefined && conSettings.band !== null) {
×
204
      nmcliArgs.push('802-11-wireless.band', conSettings.band);
×
205
    }
206

207
    if (conSettings.channel !== undefined && conSettings.channel !== null) {
×
208
      const channelValue = conSettings.channel === '0' ? '' : conSettings.channel;
×
209
      nmcliArgs.push('802-11-wireless.channel', channelValue);
×
210
    }
211

212
    nmcliArgs.push('ipv4.method', conSettings.ipaddresstype, 'connection.autoconnect', 'no');
×
213

214
    // run nmcli connection add safely
215
    execFile('sudo', ['nmcli', ...nmcliArgs], (error, stdout, stderr) => {
×
216
      if (error || stderr) {
×
217
        console.error(`execFile error: ${error || stderr}`);
×
218
        return callback(error || stderr);
×
219
      } else {
220
        // After connection added, get the connection UUID.
221
        execFile('sudo', ['nmcli', '-g', 'connection.uuid', 'con', 'show', conNameStr], (error2, stdout2, stderr2) => {
×
222
          if (error2 || stderr2) {
×
223
            console.error(`execFile error (uuid): ${error2 || stderr2}`);
×
224
            return callback(error2 || stderr2);
×
225
          } else {
226
            const conUUID = stdout2.split('\n')[stdout2.split('\n').length - 2];
×
227
            console.log('Added network Wifi: ' + conNameStr + ' - ' + conAdapter + ' - ' + conUUID);
×
228
            this.editConnection(conUUID, conSettings, (err) => {
×
229
              // set autoconnect back to "yes"
230
              execFile('sudo', ['nmcli', 'connection', 'mod', conUUID, 'connection.autoconnect', 'yes'], (error3, stdout3, stderr3) => {
×
231
                if (!err && !error3 && !stderr3) {
×
232
                  console.log('addConnection() wifi OK');
×
233
                  return callback(null, 'AddOK');
×
234
                } else {
235
                  console.log('Error in editConnection() wifi addcon ', { message: err });
×
236
                  console.log('Error in editConnection() wifi addcon ', { message: error3 || stderr3 });
×
237
                  return callback(err || error3 || stderr3);
×
238
                }
239
              });
240
            });
241
          }
242
        });
243
      }
244
    });
245
  } else {
246
    exec('sudo nmcli connection add type ' + conType + ' ifname ' + conAdapter +
×
247
             ' con-name ' + conNameStr + ' connection.autoconnect no ' + '&&' +
248
             'sudo nmcli -g connection.uuid con show ' + conNameStr, (error, stdout, stderr) => {
249
      if (stderr) {
×
250
        console.error(`exec error: ${error}`)
×
251
        return callback(stderr)
×
252
      } else {
253
        // once the network is created, add in the settings
254
        const conUUID = stdout.split('\n')[stdout.split('\n').length - 2]
×
255
        console.log('Added network Wired: ' + conNameStr + ' - ' + conAdapter + ' - ' + conUUID)
×
256
        this.editConnection(conUUID, conSettings, (err) => {
×
257
          // set autoconnect back to "yes"
258
          exec('sudo nmcli connection mod ' + conUUID + ' connection.autoconnect yes', (error, stdout, stderr) => {
×
259
            if (!err && !stderr) {
×
260
              console.log('addConnection() wired OK')
×
261
              return callback(null, 'AddOK')
×
262
            } else {
263
              console.log('Error in editConnection() wired addcon ', { message: err })
×
264
              console.log('Error in editConnection() wired addcon ', { message: stderr })
×
265
              return callback(err)
×
266
            }
267
          })
268
        })
269
      }
270
    })
271
  }
272
}
273

274
function editConnection (conName, conSettings, callback) {
275
  // edit an existing connection
276
  // assumed that conName is a valid UUID
277
  // there are 4 types of edits - AttachedInterface, IP, Wifi security, Wifi AP
278
  // small amount of callback hell here :(
279
  console.log(conSettings)
×
280
  editConnectionAttached(conName, conSettings, (errAttach) => {
×
281
    console.log('Attach')
×
282
    if (!errAttach) {
×
283
      editConnectionIP(conName, conSettings, (errIP) => {
×
284
        console.log('IP')
×
285
        if (!errIP) {
×
286
          editConnectionPSK(conName, conSettings, (errPSK) => {
×
287
            console.log('PSK')
×
288
            if (!errPSK) {
×
289
              editConnectionAPClient(conName, conSettings, (errAP) => {
×
290
                console.log('AP')
×
291
                if (!errAP) {
×
292
                  return callback(null, 'EditOK')
×
293
                } else {
294
                  return callback(errAP)
×
295
                }
296
              })
297
            } else {
298
              console.log('Error in editConnection() errPSK ', { message: errPSK })
×
299
              return callback(errPSK)
×
300
            }
301
          })
302
        } else {
303
          console.log('Error in editConnection() errIP ', { message: errIP })
×
304
          return callback(errIP)
×
305
        }
306
      })
307
    } else {
308
      console.log('Error in editConnection() errAttach ', { message: errAttach })
×
309
      return callback(errAttach)
×
310
    }
311
  })
312
}
313

314
function editConnectionAttached (conName, conSettings, callback) {
315
  // edit the attached interface for a connection
316
  if (conSettings.attachedIface === '&quot;&quot;' || conSettings.attachedIface === 'undefined') {
×
317
    conSettings.attachedIface = '""'
×
318
  }
319

320
  execFile('sudo', ['nmcli', 'connection', 'mod', conName, 'connection.interface-name', conSettings.attachedIface], (error, stdout, stderr) => {
×
321
    if (stderr) {
×
322
      console.error(`exec error: ${error}`)
×
323
      return callback(stderr)
×
324
    } else {
325
      console.log('Edited network Attachment: ' + conName + ' to ' + conSettings.attachedIface)
×
326
      return callback(null, 'EditAttachOK')
×
327
    }
328
  })
329
}
330

331
function editConnectionIP (conName, conSettings, callback) {
332
  // first sort out the IP Addressing (DHCP/static) for LAN and Wifi Client
333
  if (Object.keys(conSettings.ssid).length === 0 || conSettings.mode === 'infrastructure') {
×
334
    if (conSettings.ipaddresstype === 'auto') {
×
335
      execFile('sudo', ['nmcli', 'connection', 'mod', conName, 'ipv4.method', 'auto', 'ipv4.addresses', ''], (error, stdout, stderr) => {
×
336
        if (stderr) {
×
337
          console.error(`exec error: ${error}`)
×
338
          return callback(stderr)
×
339
        } else {
340
          console.log('Edited network IP Auto: ' + conName)
×
341
          return callback(null, 'EditOK')
×
342
        }
343
      })
344
    } else if (Object.keys(conSettings.ipaddress).length !== 0 && Object.keys(conSettings.subnet).length !== 0) {
×
345
      execFile('sudo', ['nmcli', 'connection', 'mod', conName, 'ipv4.addresses', conSettings.ipaddress + '/' +
×
346
        netmask2CIDR(conSettings.subnet), 'ipv4.method', conSettings.ipaddresstype], (error, stdout, stderr) => {
347
        if (stderr) {
×
348
          console.error(`exec error: ${error}`)
×
349
          return callback(stderr)
×
350
        } else {
351
          console.log('Edited network IP manual: ' + conName)
×
352
          return callback(null, 'EditOK')
×
353
        }
354
      })
355
    }
356
  } else {
357
    console.log('editConnectionIP() not required')
×
358
    return callback(null, 'EditNotRequired')
×
359
  }
360
}
361

362
function editConnectionPSK (conName, conSettings, callback) {
363
  // now sort out Wifi client/ap settings - password and security type
364
  if (Object.keys(conSettings.mode).length === 0) {
×
365
    return callback(null, 'EditNotRequired')
×
366
  }
367
  if (conSettings.mode === 'infrastructure' || conSettings.mode === 'ap') {
×
368
    // psk network
369
    if (conSettings.wpaType !== 'none' &&
×
370
            Object.keys(conSettings.ssid).length !== 0 &&
371
            Object.keys(conSettings.password).length !== 0) {
372
            execFile('sudo', ['nmcli', 'connection', 'mod', conName, '802-11-wireless-security.key-mgmt', conSettings.wpaType], (error, stdout, stderr) => {
×
373
        if (stderr) {
×
374
          console.error(`exec error: ${error}`)
×
375
          return callback(stderr)
×
376
        } else {
377
          execFile('sudo', ['nmcli', '-s', 'connection', 'mod', conName, '802-11-wireless-security.pairwise', 'ccmp', '802-11-wireless-security.psk', conSettings.password], (error, stdout, stderr) => {
×
378
            if (stderr) {
×
379
              console.error(`exec error: ${error}`)
×
380
              return callback(stderr)
×
381
            } else {
382
              console.log('Edited Wifi psk: ' + conName)
×
383
              return callback(null, 'OK')
×
384
            }
385
          })
386
        }
387
      })
388
    }
389
    else if (conSettings.wpaType === 'none' &&
×
390
                 Object.keys(conSettings.ssid).length !== 0) {
391
      execFile('sudo', ['nmcli', 'connection', 'mod', conName, 'remove', '802-11-wireless-security'], (error, stdout, stderr) => {
×
392
        if (stderr) {
×
393
          console.error(`exec error: ${error}`)
×
394
          return callback(stderr)
×
395
        } else {
396
          console.log('Edited Wifi no-psk: ' + conName)
×
397
          return callback(null, 'OK')
×
398
        }
399
      })
400
    }
401
  } else {
402
    console.log('editConnectionPSK() not required')
×
403
    return callback(null, 'EditNotRequired')
×
404
  }
405
}
406

407
function editConnectionAPClient (conName, conSettings, callback) {
408
  // now sort out Wifi ap or client settings - ssid, band, starting ip
409
  if (Object.keys(conSettings.mode).length === 0) {
×
410
    return callback(null, 'EditNotRequired')
×
411
  }
412
  if (conSettings.mode === 'ap') {
×
413
    if (Object.keys(conSettings.ssid).length !== 0 &&
×
414
            Object.keys(conSettings.band).length !== 0 &&
415
            Object.keys(conSettings.channel).length !== 0 &&
416
            Object.keys(conSettings.ipaddress).length !== 0) {
417
      const cmds = ['nmcli', 'connection', 'mod', conName, '802-11-wireless.ssid', conSettings.ssid,
×
418
        '802-11-wireless.band', conSettings.band, 'ipv4.addresses', conSettings.ipaddress + '/24']
419
      if (conSettings.channel !== '0') {
×
420
        cmds.push('802-11-wireless.channel', conSettings.channel)
×
421
      }
422
      if (conSettings.wpaType !== 'none') {
×
423
        cmds.push('802-11-wireless-security.group', 'ccmp', '802-11-wireless-security.wps-method', '1')
×
424
      }
425
      execFile('sudo', cmds, (error, stdout, stderr) => {
×
426
        if (stderr) {
×
427
          console.error(`exec error: ${error}`)
×
428
          return callback(stderr)
×
429
        } else {
430
          console.log('Edited Wifi ap ssid/band: ' + conName)
×
431
          return callback(null, 'OK')
×
432
        }
433
      })
434
    } else {
435
      console.log('Badsettings in editConnectionAPClient')
×
436
      console.log(conSettings)
×
437
      return callback(null, 'BADARGS')
×
438
    }
439
  } else {
440
    // client connection - edit ssid if required
441
    if (Object.keys(conSettings.ssid).length !== 0) {
×
442
      execFile('sudo', ['nmcli', 'connection', 'mod', conName, '802-11-wireless.ssid', conSettings.ssid], (error, stdout, stderr) => {
×
443
        if (stderr) {
×
444
          console.error(`exec error: ${error}`)
×
445
          return callback(stderr)
×
446
        } else {
447
          console.log('Edited Wifi client ssid: ' + conName)
×
448
          return callback(null, 'OK')
×
449
        }
450
      })
451
    } else {
452
      console.log('Badsettings in editConnectionAPClient')
×
453
      console.log(conSettings)
×
454
      return callback(null, 'BADARGS')
×
455
    }
456
  }
457
}
458

459
function deleteConnection (conName, callback) {
460
  // delete the connection (by id)
461
  // assumed that conName is a valid UUID
462
  execFile('sudo', ['nmcli', 'connection', 'delete', conName], (error, stdout, stderr) => {
×
463
    if (stderr) {
×
464
      console.error(`exec error: ${error}`)
×
465
      return callback(stderr)
×
466
    } else {
467
      console.log('Deleted network: ' + conName)
×
468
      return callback(null, 'OK')
×
469
    }
470
  })
471
}
472

473
function getConnections (callback) {
474
  let output = ''
3✔
475
  const conStatusList = []
3✔
476
  try {
3✔
477
    output = execSync('sudo nmcli -t -f NAME,UUID,TYPE,DEVICE connection show')
3✔
478
  } catch (e) {
479
    console.error('exec error: ' + e)
×
480
    return callback(e)
×
481
  }
482

483
  const allConns = output.toString().split('\n')
3✔
484
  for (let i = 0, len = allConns.length; i < len; i++) {
3✔
485
    const item = allConns[i]
3✔
486
    const connection = item.split(':')
3✔
487
    let curConn = {}
3✔
488
    let subout = ''
3✔
489
    if (connection.length == 4 || connection.length == 3) {
3!
490
      try {
×
491
        subout = execSync('sudo nmcli -s -t -f connection.interface-name connection show ' + connection[1])
×
492
        subout = subout.toString().split(':')[1].trim()
×
493
      } catch (e) {
494
        console.error('exec error: ' + e)
×
495
        // return callback("");
496
      }
497
    }
498
    if (connection[3] === '' || connection[3] === '--') {
3!
499
      curConn = { value: connection[1], label: '', labelPre: connection[0], type: connection[2], state: '', attachedIface: subout }
×
500
      conStatusList.push(curConn)
×
501
    } else if (connection.length === 4) {
3!
502
      // active connection
503
      curConn = { value: connection[1], label: '', labelPre: connection[0], type: connection[2], state: connection[3], attachedIface: subout }
×
504
      conStatusList.push(curConn)
×
505
    }
506
    // if we're at the end, return callback
507
    if (i === allConns.length - 1) {
3!
508
      console.log('getConnections() got: ' + allConns.length)
3✔
509
      return callback(null, conStatusList)
3✔
510
    }
511
  }
512
}
513

514
function getConnectionDetails (conName, callback) {
515
  execFile('sudo', ['nmcli', '-s', '-t', '-f', 'ipv4.addresses,802-11-wireless.band,ipv4.method,IP4.ADDRESS,802-11-wireless.ssid,802-11-wireless.mode,802-11-wireless-security.key-mgmt,802-11-wireless-security.psk,connection.interface-name,802-11-wireless.channel', 'connection', 'show', conName], (error, stdout, stderr) => {
×
516
    if (stderr) {
×
517
      // no connection with that name
518
      console.error(`exec error: ${error}`)
×
519
      return callback(stderr)
×
520
    } else {
521
      const ret = { DHCP: 'auto', IP: '', subnet: '', mode: '', wpaType: 'none', password: '' }
×
522
      stdout.split('\n').forEach(function (item) {
×
523
        if (item.split(':')[0] === '802-11-wireless.ssid') {
×
524
          ret.ssid = item.split(':')[1]
×
525
        } else if (item.split(':')[0] === '802-11-wireless.band') {
×
526
          if (item.split(':')[1] === '') {
×
527
            ret.band = 'bg'
×
528
          } else {
529
            ret.band = item.split(':')[1]
×
530
          }
531
        } else if (item.split(':')[0] === 'ipv4.method') {
×
532
          ret.DHCP = item.split(':')[1]
×
533
        }
534
        // DHCP IP, if using DHCP
535
        else if (item.split(':')[0] === 'IP4.ADDRESS[1]' && item.split(':').length > 1 && item.split(':')[1] !== '') {
×
536
          ret.IP = item.split(':')[1].split('/')[0]
×
537
          ret.subnet = CIDR2netmask(item.split(':')[1].split('/')[1])
×
538
        }
539
        // static IP
540
        else if (item.split(':')[0] === 'ipv4.addresses' && item.split(':').length > 1 && item.split(':')[1] !== '') {
×
541
          ret.IP = item.split(':')[1].split('/')[0]
×
542
          ret.subnet = CIDR2netmask(item.split(':')[1].split('/')[1])
×
543
        } else if (item.split(':')[0] === '802-11-wireless.mode') {
×
544
          ret.mode = item.split(':')[1]
×
545
        } else if (item.split(':')[0] === '802-11-wireless-security.key-mgmt') {
×
546
          ret.wpaType = item.split(':')[1]
×
547
        } else if (item.split(':')[0] === '802-11-wireless-security.psk') {
×
548
          ret.password = item.split(':')[1]
×
549
        } else if (item.split(':')[0] === 'connection.interface-name') {
×
550
          ret.attachedIface = item.split(':')[1]
×
551
        } else if (item.split(':')[0] === '802-11-wireless.channel') {
×
552
          ret.channel = item.split(':')[1]
×
553
        }
554
      })
555
      return callback(null, ret)
×
556
    }
557
  })
558
}
559

560
function CIDR2netmask (bitCountstr) {
561
  const mask = []
×
562
  let bitCount = parseInt(bitCountstr)
×
563
  // console.log(bitCountstr);
564
  for (let i = 0; i < 4; i++) {
×
565
    const n = Math.min(bitCount, 8)
×
566
    // console.log(bitCount);
567
    mask.push(256 - Math.pow(2, 8 - n))
×
568
    bitCount -= n
×
569
  }
570
  return mask.join('.')
×
571
}
572

573
function netmask2CIDR (mask) {
574
  let cidr = ''
×
575
  for (const m of mask.split('.')) {
×
576
    if (parseInt(m) > 255) { throw 'ERROR: Invalid Netmask' } // Check each group is 0-255
×
577
    if (parseInt(m) > 0 && parseInt(m) < 128) { throw 'ERROR: Invalid Netmask' }
×
578

579
    cidr += (m >>> 0).toString(2)
×
580
  }
581
  // Condition to check for validity of the netmask
582
  if (cidr.substring(cidr.search('0'), 32).search('1') !== -1) {
×
583
    console.log('Error in netmask2CIDR() ', { message: mask })
×
584
    throw 'ERROR: Invalid Netmask ' + mask
×
585
  }
586
  return cidr.split('1').length - 1
×
587
}
588

589
module.exports = {
3✔
590
  getAdapters,
591
  getConnections,
592
  getConnectionDetails,
593
  activateConnection,
594
  deleteConnection,
595
  editConnection,
596
  addConnection,
597
  deactivateConnection,
598
  getWirelessStatus,
599
  setWirelessStatus,
600
  getWifiScan
601
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc