1
2
3
4
5 package oshi.hardware.platform.unix.solaris;
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 import oshi.util.ParseUtil;
18
19
20
21
22 @Immutable
23 public class SolarisUsbDevice extends AbstractUsbDevice {
24
25 private static final String PCI_TYPE_USB = "000c";
26
27 public SolarisUsbDevice(String name, String vendor, String vendorId, String productId, String serialNumber,
28 String uniqueDeviceId, List<UsbDevice> connectedDevices) {
29 super(name, vendor, vendorId, productId, serialNumber, uniqueDeviceId, connectedDevices);
30 }
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public static List<UsbDevice> getUsbDevices(boolean tree) {
45 List<UsbDevice> devices = getUsbDevices();
46 if (tree) {
47 return devices;
48 }
49 List<UsbDevice> deviceList = new ArrayList<>();
50
51
52 for (UsbDevice device : devices) {
53 deviceList.add(new SolarisUsbDevice(device.getName(), device.getVendor(), device.getVendorId(),
54 device.getProductId(), device.getSerialNumber(), device.getUniqueDeviceId(),
55 Collections.emptyList()));
56 addDevicesToList(deviceList, device.getConnectedDevices());
57 }
58 return deviceList;
59 }
60
61 private static List<UsbDevice> getUsbDevices() {
62 Map<String, String> nameMap = new HashMap<>();
63 Map<String, String> vendorIdMap = new HashMap<>();
64 Map<String, String> productIdMap = new HashMap<>();
65 Map<String, List<String>> hubMap = new HashMap<>();
66 Map<String, String> deviceTypeMap = new HashMap<>();
67
68
69 List<String> devices = ExecutingCommand.runNative("prtconf -pv");
70 if (devices.isEmpty()) {
71 return Collections.emptyList();
72 }
73
74 Map<Integer, String> lastParent = new HashMap<>();
75 String key = "";
76 int indent = 0;
77 List<String> usbControllers = new ArrayList<>();
78 for (String line : devices) {
79
80 if (line.contains("Node 0x")) {
81
82 key = line.replaceFirst("^\\s*", "");
83
84 int depth = line.length() - key.length();
85
86 if (indent == 0) {
87 indent = depth;
88 }
89
90 lastParent.put(depth, key);
91
92 if (depth > indent) {
93
94 hubMap.computeIfAbsent(lastParent.get(depth - indent), x -> new ArrayList<>()).add(key);
95 } else {
96
97 usbControllers.add(key);
98 }
99 } else if (!key.isEmpty()) {
100
101
102 line = line.trim();
103 if (line.startsWith("model:")) {
104 nameMap.put(key, ParseUtil.getSingleQuoteStringValue(line));
105 } else if (line.startsWith("name:")) {
106
107
108 nameMap.putIfAbsent(key, ParseUtil.getSingleQuoteStringValue(line));
109 } else if (line.startsWith("vendor-id:")) {
110
111 vendorIdMap.put(key, line.substring(line.length() - 4));
112 } else if (line.startsWith("device-id:")) {
113
114 productIdMap.put(key, line.substring(line.length() - 4));
115 } else if (line.startsWith("class-code:")) {
116
117 deviceTypeMap.putIfAbsent(key, line.substring(line.length() - 8, line.length() - 4));
118 } else if (line.startsWith("device_type:")) {
119
120 deviceTypeMap.putIfAbsent(key, ParseUtil.getSingleQuoteStringValue(line));
121 }
122 }
123 }
124
125
126 List<UsbDevice> controllerDevices = new ArrayList<>();
127 for (String controller : usbControllers) {
128
129 if (PCI_TYPE_USB.equals(deviceTypeMap.getOrDefault(controller, ""))
130 || "usb".equals(deviceTypeMap.getOrDefault(controller, ""))) {
131 controllerDevices.add(
132 getDeviceAndChildren(controller, "0000", "0000", nameMap, vendorIdMap, productIdMap, hubMap));
133 }
134 }
135 return controllerDevices;
136 }
137
138 private static void addDevicesToList(List<UsbDevice> deviceList, List<UsbDevice> list) {
139 for (UsbDevice device : list) {
140 deviceList.add(device);
141 addDevicesToList(deviceList, device.getConnectedDevices());
142 }
143 }
144
145
146
147
148
149
150
151
152
153
154
155
156
157 private static SolarisUsbDevice getDeviceAndChildren(String devPath, String vid, String pid,
158 Map<String, String> nameMap, Map<String, String> vendorIdMap, Map<String, String> productIdMap,
159 Map<String, List<String>> hubMap) {
160 String vendorId = vendorIdMap.getOrDefault(devPath, vid);
161 String productId = productIdMap.getOrDefault(devPath, pid);
162 List<String> childPaths = hubMap.getOrDefault(devPath, new ArrayList<>());
163 List<UsbDevice> usbDevices = new ArrayList<>();
164 for (String path : childPaths) {
165 usbDevices.add(getDeviceAndChildren(path, vendorId, productId, nameMap, vendorIdMap, productIdMap, hubMap));
166 }
167 Collections.sort(usbDevices);
168 return new SolarisUsbDevice(nameMap.getOrDefault(devPath, vendorId + ":" + productId), "", vendorId, productId,
169 "", devPath, usbDevices);
170 }
171 }