@depup/systeminformation 5.31.4-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,311 @@
1
+ 'use strict';
2
+ // @ts-check
3
+ // ==================================================================================
4
+ // audio.js
5
+ // ----------------------------------------------------------------------------------
6
+ // Description: System Information - library
7
+ // for Node.js
8
+ // Copyright: (c) 2014 - 2026
9
+ // Author: Sebastian Hildebrandt
10
+ // ----------------------------------------------------------------------------------
11
+ // License: MIT
12
+ // ==================================================================================
13
+ // 17. bluetooth
14
+ // ----------------------------------------------------------------------------------
15
+
16
+ const exec = require('child_process').exec;
17
+ const execSync = require('child_process').execSync;
18
+ const path = require('path');
19
+ const util = require('./util');
20
+ const bluetoothVendors = require('./bluetoothVendors');
21
+ const fs = require('fs');
22
+
23
+ const _platform = process.platform;
24
+
25
+ const _linux = _platform === 'linux' || _platform === 'android';
26
+ const _darwin = _platform === 'darwin';
27
+ const _windows = _platform === 'win32';
28
+ const _freebsd = _platform === 'freebsd';
29
+ const _openbsd = _platform === 'openbsd';
30
+ const _netbsd = _platform === 'netbsd';
31
+ const _sunos = _platform === 'sunos';
32
+
33
+ function parseBluetoothType(str) {
34
+ let result = '';
35
+
36
+ if (str.indexOf('keyboard') >= 0) {
37
+ result = 'Keyboard';
38
+ }
39
+ if (str.indexOf('mouse') >= 0) {
40
+ result = 'Mouse';
41
+ }
42
+ if (str.indexOf('trackpad') >= 0) {
43
+ result = 'Trackpad';
44
+ }
45
+ if (str.indexOf('audio') >= 0) {
46
+ result = 'Audio';
47
+ }
48
+ if (str.indexOf('sound') >= 0) {
49
+ result = 'Audio';
50
+ }
51
+ if (str.indexOf('microph') >= 0) {
52
+ result = 'Microphone';
53
+ }
54
+ if (str.indexOf('speaker') >= 0) {
55
+ result = 'Speaker';
56
+ }
57
+ if (str.indexOf('headset') >= 0) {
58
+ result = 'Headset';
59
+ }
60
+ if (str.indexOf('phone') >= 0) {
61
+ result = 'Phone';
62
+ }
63
+ if (str.indexOf('macbook') >= 0) {
64
+ result = 'Computer';
65
+ }
66
+ if (str.indexOf('imac') >= 0) {
67
+ result = 'Computer';
68
+ }
69
+ if (str.indexOf('ipad') >= 0) {
70
+ result = 'Tablet';
71
+ }
72
+ if (str.indexOf('watch') >= 0) {
73
+ result = 'Watch';
74
+ }
75
+ if (str.indexOf('headphone') >= 0) {
76
+ result = 'Headset';
77
+ }
78
+ // to be continued ...
79
+
80
+ return result;
81
+ }
82
+
83
+ function parseBluetoothManufacturer(str) {
84
+ let result = str.split(' ')[0];
85
+ str = str.toLowerCase();
86
+ if (str.indexOf('apple') >= 0) {
87
+ result = 'Apple';
88
+ }
89
+ if (str.indexOf('ipad') >= 0) {
90
+ result = 'Apple';
91
+ }
92
+ if (str.indexOf('imac') >= 0) {
93
+ result = 'Apple';
94
+ }
95
+ if (str.indexOf('iphone') >= 0) {
96
+ result = 'Apple';
97
+ }
98
+ if (str.indexOf('magic mouse') >= 0) {
99
+ result = 'Apple';
100
+ }
101
+ if (str.indexOf('magic track') >= 0) {
102
+ result = 'Apple';
103
+ }
104
+ if (str.indexOf('macbook') >= 0) {
105
+ result = 'Apple';
106
+ }
107
+ // to be continued ...
108
+
109
+ return result;
110
+ }
111
+
112
+ function parseBluetoothVendor(str) {
113
+ const id = parseInt(str);
114
+ if (!isNaN(id)) return bluetoothVendors[id];
115
+ }
116
+
117
+ function parseLinuxBluetoothInfo(lines, macAddr1, macAddr2) {
118
+ const result = {};
119
+
120
+ result.device = null;
121
+ result.name = util.getValue(lines, 'name', '=');
122
+ result.manufacturer = null;
123
+ result.macDevice = macAddr1;
124
+ result.macHost = macAddr2;
125
+ result.batteryPercent = null;
126
+ result.type = parseBluetoothType(result.name.toLowerCase());
127
+ result.connected = false;
128
+
129
+ return result;
130
+ }
131
+
132
+ function parseDarwinBluetoothDevices(bluetoothObject, macAddr2) {
133
+ const result = {};
134
+ const typeStr = (
135
+ (bluetoothObject.device_minorClassOfDevice_string || bluetoothObject.device_majorClassOfDevice_string || bluetoothObject.device_minorType || '') + (bluetoothObject.device_name || '')
136
+ ).toLowerCase();
137
+
138
+ result.device = bluetoothObject.device_services || '';
139
+ result.name = bluetoothObject.device_name || '';
140
+ result.manufacturer = bluetoothObject.device_manufacturer || parseBluetoothVendor(bluetoothObject.device_vendorID) || parseBluetoothManufacturer(bluetoothObject.device_name || '') || '';
141
+ result.macDevice = (bluetoothObject.device_addr || bluetoothObject.device_address || '').toLowerCase().replace(/-/g, ':');
142
+ result.macHost = macAddr2;
143
+ result.batteryPercent = bluetoothObject.device_batteryPercent || null;
144
+ result.type = parseBluetoothType(typeStr);
145
+ result.connected = bluetoothObject.device_isconnected === 'attrib_Yes' || false;
146
+
147
+ return result;
148
+ }
149
+
150
+ function parseWindowsBluetooth(lines) {
151
+ const result = {};
152
+
153
+ result.device = null;
154
+ result.name = util.getValue(lines, 'name', ':');
155
+ result.manufacturer = util.getValue(lines, 'manufacturer', ':');
156
+ result.macDevice = null;
157
+ result.macHost = null;
158
+ result.batteryPercent = null;
159
+ result.type = parseBluetoothType(result.name.toLowerCase());
160
+ result.connected = null;
161
+
162
+ return result;
163
+ }
164
+
165
+ function bluetoothDevices(callback) {
166
+ return new Promise((resolve) => {
167
+ process.nextTick(() => {
168
+ let result = [];
169
+ if (_linux) {
170
+ // get files in /var/lib/bluetooth/ recursive
171
+ const btFiles = util.getFilesInPath('/var/lib/bluetooth/');
172
+ btFiles.forEach((element) => {
173
+ const filename = path.basename(element);
174
+ const pathParts = element.split('/');
175
+ const macAddr1 = pathParts.length >= 6 ? pathParts[pathParts.length - 2] : null;
176
+ const macAddr2 = pathParts.length >= 7 ? pathParts[pathParts.length - 3] : null;
177
+ if (filename === 'info') {
178
+ const infoFile = fs.readFileSync(element, { encoding: 'utf8' }).split('\n');
179
+ result.push(parseLinuxBluetoothInfo(infoFile, macAddr1, macAddr2));
180
+ }
181
+ });
182
+ // determine "connected" with hcitool con
183
+ try {
184
+ const hdicon = execSync('hcitool con', util.execOptsLinux).toString().toLowerCase();
185
+ for (let i = 0; i < result.length; i++) {
186
+ if (result[i].macDevice && result[i].macDevice.length > 10 && hdicon.indexOf(result[i].macDevice.toLowerCase()) >= 0) {
187
+ result[i].connected = true;
188
+ }
189
+ }
190
+ } catch {
191
+ util.noop();
192
+ }
193
+
194
+ if (callback) {
195
+ callback(result);
196
+ }
197
+ resolve(result);
198
+ }
199
+ if (_darwin) {
200
+ let cmd = 'system_profiler SPBluetoothDataType -json';
201
+ exec(cmd, (error, stdout) => {
202
+ if (!error) {
203
+ try {
204
+ const outObj = JSON.parse(stdout.toString());
205
+ if (
206
+ outObj.SPBluetoothDataType &&
207
+ outObj.SPBluetoothDataType.length &&
208
+ outObj.SPBluetoothDataType[0] &&
209
+ outObj.SPBluetoothDataType[0]['device_title'] &&
210
+ outObj.SPBluetoothDataType[0]['device_title'].length
211
+ ) {
212
+ // missing: host BT Adapter macAddr ()
213
+ let macAddr2 = null;
214
+ if (outObj.SPBluetoothDataType[0]['local_device_title'] && outObj.SPBluetoothDataType[0].local_device_title.general_address) {
215
+ macAddr2 = outObj.SPBluetoothDataType[0].local_device_title.general_address.toLowerCase().replace(/-/g, ':');
216
+ }
217
+ outObj.SPBluetoothDataType[0]['device_title'].forEach((element) => {
218
+ const obj = element;
219
+ const objKey = Object.keys(obj);
220
+ if (objKey && objKey.length === 1) {
221
+ const innerObject = obj[objKey[0]];
222
+ innerObject.device_name = objKey[0];
223
+ const bluetoothDevice = parseDarwinBluetoothDevices(innerObject, macAddr2);
224
+ result.push(bluetoothDevice);
225
+ }
226
+ });
227
+ }
228
+ if (
229
+ outObj.SPBluetoothDataType &&
230
+ outObj.SPBluetoothDataType.length &&
231
+ outObj.SPBluetoothDataType[0] &&
232
+ outObj.SPBluetoothDataType[0]['device_connected'] &&
233
+ outObj.SPBluetoothDataType[0]['device_connected'].length
234
+ ) {
235
+ const macAddr2 =
236
+ outObj.SPBluetoothDataType[0].controller_properties && outObj.SPBluetoothDataType[0].controller_properties.controller_address
237
+ ? outObj.SPBluetoothDataType[0].controller_properties.controller_address.toLowerCase().replace(/-/g, ':')
238
+ : null;
239
+ outObj.SPBluetoothDataType[0]['device_connected'].forEach((element) => {
240
+ const obj = element;
241
+ const objKey = Object.keys(obj);
242
+ if (objKey && objKey.length === 1) {
243
+ const innerObject = obj[objKey[0]];
244
+ innerObject.device_name = objKey[0];
245
+ innerObject.device_isconnected = 'attrib_Yes';
246
+ const bluetoothDevice = parseDarwinBluetoothDevices(innerObject, macAddr2);
247
+ result.push(bluetoothDevice);
248
+ }
249
+ });
250
+ }
251
+ if (
252
+ outObj.SPBluetoothDataType &&
253
+ outObj.SPBluetoothDataType.length &&
254
+ outObj.SPBluetoothDataType[0] &&
255
+ outObj.SPBluetoothDataType[0]['device_not_connected'] &&
256
+ outObj.SPBluetoothDataType[0]['device_not_connected'].length
257
+ ) {
258
+ const macAddr2 =
259
+ outObj.SPBluetoothDataType[0].controller_properties && outObj.SPBluetoothDataType[0].controller_properties.controller_address
260
+ ? outObj.SPBluetoothDataType[0].controller_properties.controller_address.toLowerCase().replace(/-/g, ':')
261
+ : null;
262
+ outObj.SPBluetoothDataType[0]['device_not_connected'].forEach((element) => {
263
+ const obj = element;
264
+ const objKey = Object.keys(obj);
265
+ if (objKey && objKey.length === 1) {
266
+ const innerObject = obj[objKey[0]];
267
+ innerObject.device_name = objKey[0];
268
+ innerObject.device_isconnected = 'attrib_No';
269
+ const bluetoothDevice = parseDarwinBluetoothDevices(innerObject, macAddr2);
270
+ result.push(bluetoothDevice);
271
+ }
272
+ });
273
+ }
274
+ } catch {
275
+ util.noop();
276
+ }
277
+ }
278
+ if (callback) {
279
+ callback(result);
280
+ }
281
+ resolve(result);
282
+ });
283
+ }
284
+ if (_windows) {
285
+ util.powerShell('Get-CimInstance Win32_PNPEntity | select PNPClass, Name, Manufacturer, Status, Service, ConfigManagerErrorCode, Present | fl').then((stdout, error) => {
286
+ if (!error) {
287
+ const parts = stdout.toString().split(/\n\s*\n/);
288
+ parts.forEach((part) => {
289
+ const lines = part.split('\n');
290
+ const service = util.getValue(lines, 'Service', ':');
291
+ const errorCode = util.getValue(lines, 'ConfigManagerErrorCode', ':');
292
+ const pnpClass = util.getValue(lines, 'PNPClass', ':').toLowerCase();
293
+ if (pnpClass === 'bluetooth' && errorCode === '0' && service === '') {
294
+ result.push(parseWindowsBluetooth(lines));
295
+ }
296
+ });
297
+ }
298
+ if (callback) {
299
+ callback(result);
300
+ }
301
+ resolve(result);
302
+ });
303
+ }
304
+ if (_freebsd || _netbsd || _openbsd || _sunos) {
305
+ resolve(null);
306
+ }
307
+ });
308
+ });
309
+ }
310
+
311
+ exports.bluetoothDevices = bluetoothDevices;