1
2
3
4
5 package oshi.hardware.platform.unix.openbsd;
6
7 import java.util.ArrayList;
8 import java.util.Collections;
9 import java.util.HashMap;
10 import java.util.List;
11 import java.util.Map;
12
13 import oshi.annotation.concurrent.Immutable;
14 import oshi.hardware.UsbDevice;
15 import oshi.hardware.common.AbstractUsbDevice;
16 import oshi.util.ExecutingCommand;
17
18
19
20
21 @Immutable
22 public class OpenBsdUsbDevice extends AbstractUsbDevice {
23
24 public OpenBsdUsbDevice(String name, String vendor, String vendorId, String productId, String serialNumber,
25 String uniqueDeviceId, List<UsbDevice> connectedDevices) {
26 super(name, vendor, vendorId, productId, serialNumber, uniqueDeviceId, connectedDevices);
27 }
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public static List<UsbDevice> getUsbDevices(boolean tree) {
42 List<UsbDevice> devices = getUsbDevices();
43 if (tree) {
44 return devices;
45 }
46 List<UsbDevice> deviceList = new ArrayList<>();
47
48
49 for (UsbDevice device : devices) {
50 deviceList.add(new OpenBsdUsbDevice(device.getName(), device.getVendor(), device.getVendorId(),
51 device.getProductId(), device.getSerialNumber(), device.getUniqueDeviceId(),
52 Collections.emptyList()));
53 addDevicesToList(deviceList, device.getConnectedDevices());
54 }
55 return deviceList;
56 }
57
58 private static List<UsbDevice> getUsbDevices() {
59
60
61 Map<String, String> nameMap = new HashMap<>();
62 Map<String, String> vendorMap = new HashMap<>();
63 Map<String, String> vendorIdMap = new HashMap<>();
64 Map<String, String> productIdMap = new HashMap<>();
65 Map<String, String> serialMap = new HashMap<>();
66 Map<String, List<String>> hubMap = new HashMap<>();
67
68 List<String> rootHubs = new ArrayList<>();
69
70 String key = "";
71
72
73 String parent = "";
74
75
76 for (String line : ExecutingCommand.runNative("usbdevs -v")) {
77 if (line.startsWith("Controller ")) {
78 parent = line.substring(11);
79 } else if (line.startsWith("addr ")) {
80
81 if (line.indexOf(':') == 7 && line.indexOf(',') >= 18) {
82 key = parent + line.substring(0, 7);
83 String[] split = line.substring(8).trim().split(",");
84 if (split.length > 1) {
85
86 String vendorStr = split[0].trim();
87 int idx1 = vendorStr.indexOf(':');
88 int idx2 = vendorStr.indexOf(' ');
89 if (idx1 >= 0 && idx2 >= 0) {
90 vendorIdMap.put(key, vendorStr.substring(0, idx1));
91 productIdMap.put(key, vendorStr.substring(idx1 + 1, idx2));
92 vendorMap.put(key, vendorStr.substring(idx2 + 1));
93 }
94
95 nameMap.put(key, split[1].trim());
96
97 hubMap.computeIfAbsent(parent, x -> new ArrayList<>()).add(key);
98
99 if (!parent.contains("addr")) {
100 parent = key;
101 rootHubs.add(parent);
102 }
103 }
104 }
105 } else if (!key.isEmpty()) {
106
107
108
109 int idx = line.indexOf("iSerial ");
110 if (idx >= 0) {
111 serialMap.put(key, line.substring(idx + 8).trim());
112 }
113 key = "";
114 }
115 }
116
117
118 List<UsbDevice> controllerDevices = new ArrayList<>();
119 for (String devusb : rootHubs) {
120 controllerDevices.add(getDeviceAndChildren(devusb, "0000", "0000", nameMap, vendorMap, vendorIdMap,
121 productIdMap, serialMap, hubMap));
122 }
123 return controllerDevices;
124 }
125
126 private static void addDevicesToList(List<UsbDevice> deviceList, List<UsbDevice> list) {
127 for (UsbDevice device : list) {
128 deviceList.add(device);
129 addDevicesToList(deviceList, device.getConnectedDevices());
130 }
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 private static OpenBsdUsbDevice getDeviceAndChildren(String devPath, String vid, String pid,
148 Map<String, String> nameMap, Map<String, String> vendorMap, Map<String, String> vendorIdMap,
149 Map<String, String> productIdMap, Map<String, String> serialMap, Map<String, List<String>> hubMap) {
150 String vendorId = vendorIdMap.getOrDefault(devPath, vid);
151 String productId = productIdMap.getOrDefault(devPath, pid);
152 List<String> childPaths = hubMap.getOrDefault(devPath, new ArrayList<>());
153 List<UsbDevice> usbDevices = new ArrayList<>();
154 for (String path : childPaths) {
155 usbDevices.add(getDeviceAndChildren(path, vendorId, productId, nameMap, vendorMap, vendorIdMap,
156 productIdMap, serialMap, hubMap));
157 }
158 Collections.sort(usbDevices);
159 return new OpenBsdUsbDevice(nameMap.getOrDefault(devPath, vendorId + ":" + productId),
160 vendorMap.getOrDefault(devPath, ""), vendorId, productId, serialMap.getOrDefault(devPath, ""), devPath,
161 usbDevices);
162 }
163 }