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

stephendade / Rpanion-server / 19360612817

14 Nov 2025 09:43AM UTC coverage: 34.683% (+0.1%) from 34.547%
19360612817

Pull #343

github

web-flow
Merge ae5d17ea3 into 2164b81a9
Pull Request #343: Add Orange Pi Zero 3 support

328 of 1210 branches covered (27.11%)

Branch coverage included in aggregate %.

23 of 51 new or added lines in 5 files covered. (45.1%)

168 existing lines in 3 files now uncovered.

1008 of 2642 relevant lines covered (38.15%)

2.61 hits per line

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

9.07
/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(':')
12✔
13
        if (device.length === 3 && device[1] !== 'loopback' && device[1] !== 'bridge' && device[1] !== 'wifi-p2p' && device[1] !== 'can0' && device[1] !== 'can1') {
12✔
14
          console.log('Adding Network device ' + device[0])
3✔
15
          // if wifi, check for avail channels
16
          const freqList = []
3✔
17
          freqList.push({ value: 0, freq: 0, label: 'auto', band: 0 })
3✔
18
          if (device[1] === 'wifi') {
3!
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')) })
3!
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
NEW
200
    let cmd = 'sudo nmcli connection add'
×
NEW
201
    cmd += ' type ' + conType
×
NEW
202
    cmd += ' ifname ' + conAdapter
×
NEW
203
    cmd += ' con-name ' + conNameStr
×
NEW
204
    cmd += ' ssid \'' + conSettings.ssid + '\''
×
NEW
205
    cmd += ' 802-11-wireless.mode ' + conSettings.mode
×
206
    
NEW
207
    if (conSettings.band !== undefined && conSettings.band !== null) {
×
NEW
208
      cmd += ' 802-11-wireless.band ' + conSettings.band
×
209
    }
210
    
NEW
211
    if (conSettings.channel !== undefined && conSettings.channel !== null) {
×
NEW
212
      const channelValue = conSettings.channel === '0' ? '\'\'' : conSettings.channel
×
NEW
213
      cmd += ' 802-11-wireless.channel ' + channelValue
×
214
    }
215
    
NEW
216
    cmd += ' ipv4.method ' + conSettings.ipaddresstype
×
NEW
217
    cmd += ' connection.autoconnect no'
×
NEW
218
    cmd += ' && sudo nmcli -g connection.uuid con show ' + conNameStr
×
219
    
NEW
220
    exec(cmd, (error, stdout, stderr) => {
×
221
      if (stderr) {
×
222
        console.error(`exec error: ${error}`)
×
223
        return callback(stderr)
×
224
      } else {
225
        // once the network is created, add in the settings
226
        const conUUID = stdout.split('\n')[stdout.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
          exec('sudo nmcli connection mod ' + conUUID + ' connection.autoconnect yes', (error, stdout, stderr) => {
×
231
            if (!err && !stderr) {
×
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: stderr })
×
237
              return callback(err)
×
238
            }
239
          })
240
        })
241
      }
242
    })
243
  } else {
244
    exec('sudo nmcli connection add type ' + conType + ' ifname ' + conAdapter +
×
245
             ' con-name ' + conNameStr + ' connection.autoconnect no ' + '&&' +
246
             'sudo nmcli -g connection.uuid con show ' + conNameStr, (error, stdout, stderr) => {
UNCOV
247
      if (stderr) {
×
UNCOV
248
        console.error(`exec error: ${error}`)
×
249
        return callback(stderr)
×
250
      } else {
251
        // once the network is created, add in the settings
UNCOV
252
        const conUUID = stdout.split('\n')[stdout.split('\n').length - 2]
×
UNCOV
253
        console.log('Added network Wired: ' + conNameStr + ' - ' + conAdapter + ' - ' + conUUID)
×
254
        this.editConnection(conUUID, conSettings, (err) => {
×
255
          // set autoconnect back to "yes"
256
          exec('sudo nmcli connection mod ' + conUUID + ' connection.autoconnect yes', (error, stdout, stderr) => {
×
UNCOV
257
            if (!err && !stderr) {
×
258
              console.log('addConnection() wired OK')
×
259
              return callback(null, 'AddOK')
×
260
            } else {
261
              console.log('Error in editConnection() wired addcon ', { message: err })
×
UNCOV
262
              console.log('Error in editConnection() wired addcon ', { message: stderr })
×
263
              return callback(err)
×
264
            }
265
          })
266
        })
267
      }
268
    })
269
  }
270
}
271

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

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

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

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

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

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

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

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

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

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

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

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

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

587
module.exports = {
3✔
588
  getAdapters,
589
  getConnections,
590
  getConnectionDetails,
591
  activateConnection,
592
  deleteConnection,
593
  editConnection,
594
  addConnection,
595
  deactivateConnection,
596
  getWirelessStatus,
597
  setWirelessStatus,
598
  getWifiScan
599
}
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