1
2
3
4
5 package oshi.hardware.platform.unix.freebsd;
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.Locale;
12 import java.util.Map;
13
14 import oshi.annotation.concurrent.Immutable;
15 import oshi.hardware.UsbDevice;
16 import oshi.hardware.common.AbstractUsbDevice;
17 import oshi.util.ExecutingCommand;
18 import oshi.util.ParseUtil;
19
20
21
22
23 @Immutable
24 public class FreeBsdUsbDevice extends AbstractUsbDevice {
25
26 public FreeBsdUsbDevice(String name, String vendor, String vendorId, String productId, String serialNumber,
27 String uniqueDeviceId, List<UsbDevice> connectedDevices) {
28 super(name, vendor, vendorId, productId, serialNumber, uniqueDeviceId, connectedDevices);
29 }
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public static List<UsbDevice> getUsbDevices(boolean tree) {
44 List<UsbDevice> devices = getUsbDevices();
45 if (tree) {
46 return devices;
47 }
48 List<UsbDevice> deviceList = new ArrayList<>();
49
50
51 for (UsbDevice device : devices) {
52 deviceList.add(new FreeBsdUsbDevice(device.getName(), device.getVendor(), device.getVendorId(),
53 device.getProductId(), device.getSerialNumber(), device.getUniqueDeviceId(),
54 Collections.emptyList()));
55 addDevicesToList(deviceList, device.getConnectedDevices());
56 }
57 return deviceList;
58 }
59
60 private static List<UsbDevice> getUsbDevices() {
61
62 Map<String, String> nameMap = new HashMap<>();
63 Map<String, String> vendorMap = new HashMap<>();
64 Map<String, String> vendorIdMap = new HashMap<>();
65 Map<String, String> productIdMap = new HashMap<>();
66 Map<String, String> serialMap = new HashMap<>();
67 Map<String, String> parentMap = new HashMap<>();
68 Map<String, List<String>> hubMap = new HashMap<>();
69
70
71
72
73
74 List<String> devices = ExecutingCommand.runNative("lshal");
75 if (devices.isEmpty()) {
76 return Collections.emptyList();
77 }
78
79 String key = "";
80 List<String> usBuses = new ArrayList<>();
81 for (String line : devices) {
82
83 if (line.startsWith("udi =")) {
84
85 key = ParseUtil.getSingleQuoteStringValue(line);
86 } else if (!key.isEmpty()) {
87
88
89 line = line.trim();
90 if (!line.isEmpty()) {
91 if (line.startsWith("freebsd.driver =")
92 && "usbus".equals(ParseUtil.getSingleQuoteStringValue(line))) {
93 usBuses.add(key);
94 } else if (line.contains(".parent =")) {
95 String parent = ParseUtil.getSingleQuoteStringValue(line);
96
97 if (key.replace(parent, "").startsWith("_if")) {
98 continue;
99 }
100
101 parentMap.put(key, parent);
102
103 hubMap.computeIfAbsent(parent, x -> new ArrayList<>()).add(key);
104 } else if (line.contains(".product =")) {
105 nameMap.put(key, ParseUtil.getSingleQuoteStringValue(line));
106 } else if (line.contains(".vendor =")) {
107 vendorMap.put(key, ParseUtil.getSingleQuoteStringValue(line));
108 } else if (line.contains(".serial =")) {
109 String serial = ParseUtil.getSingleQuoteStringValue(line);
110 serialMap.put(key,
111 serial.startsWith("0x") ? ParseUtil.hexStringToString(serial.replace("0x", ""))
112 : serial);
113 } else if (line.contains(".vendor_id =")) {
114 vendorIdMap.put(key, String.format(Locale.ROOT, "%04x", ParseUtil.getFirstIntValue(line)));
115 } else if (line.contains(".product_id =")) {
116 productIdMap.put(key, String.format(Locale.ROOT, "%04x", ParseUtil.getFirstIntValue(line)));
117 }
118 }
119 }
120 }
121
122
123 List<UsbDevice> controllerDevices = new ArrayList<>();
124 for (String usbus : usBuses) {
125
126
127 String parent = parentMap.get(usbus);
128 hubMap.put(parent, hubMap.get(usbus));
129 controllerDevices.add(getDeviceAndChildren(parent, "0000", "0000", nameMap, vendorMap, vendorIdMap,
130 productIdMap, serialMap, hubMap));
131 }
132 return controllerDevices;
133 }
134
135 private static void addDevicesToList(List<UsbDevice> deviceList, List<UsbDevice> list) {
136 for (UsbDevice device : list) {
137 deviceList.add(device);
138 addDevicesToList(deviceList, device.getConnectedDevices());
139 }
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156 private static FreeBsdUsbDevice getDeviceAndChildren(String devPath, String vid, String pid,
157 Map<String, String> nameMap, Map<String, String> vendorMap, Map<String, String> vendorIdMap,
158 Map<String, String> productIdMap, Map<String, String> serialMap, Map<String, List<String>> hubMap) {
159 String vendorId = vendorIdMap.getOrDefault(devPath, vid);
160 String productId = productIdMap.getOrDefault(devPath, pid);
161 List<String> childPaths = hubMap.getOrDefault(devPath, new ArrayList<>());
162 List<UsbDevice> usbDevices = new ArrayList<>();
163 for (String path : childPaths) {
164 usbDevices.add(getDeviceAndChildren(path, vendorId, productId, nameMap, vendorMap, vendorIdMap,
165 productIdMap, serialMap, hubMap));
166 }
167 Collections.sort(usbDevices);
168 return new FreeBsdUsbDevice(nameMap.getOrDefault(devPath, vendorId + ":" + productId),
169 vendorMap.getOrDefault(devPath, ""), vendorId, productId, serialMap.getOrDefault(devPath, ""), devPath,
170 usbDevices);
171 }
172 }