View Javadoc
1   /*
2    * Copyright 2021-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.hardware.platform.unix.openbsd;
6   
7   import java.util.ArrayList;
8   import java.util.Collections;
9   import java.util.List;
10  import java.util.regex.Matcher;
11  import java.util.regex.Pattern;
12  
13  import oshi.annotation.concurrent.Immutable;
14  import oshi.hardware.GraphicsCard;
15  import oshi.hardware.common.AbstractGraphicsCard;
16  import oshi.util.Constants;
17  import oshi.util.ExecutingCommand;
18  
19  /**
20   * Graphics Card info obtained from pciconf
21   */
22  @Immutable
23  final class OpenBsdGraphicsCard extends AbstractGraphicsCard {
24  
25      private static final String PCI_CLASS_DISPLAY = "Class: 03 Display";
26      private static final Pattern PCI_DUMP_HEADER = Pattern.compile(" \\d+:\\d+:\\d+: (.+)");
27  
28      /**
29       * Constructor for OpenBsdGraphicsCard
30       *
31       * @param name        The name
32       * @param deviceId    The device ID
33       * @param vendor      The vendor
34       * @param versionInfo The version info
35       * @param vram        The VRAM
36       */
37      OpenBsdGraphicsCard(String name, String deviceId, String vendor, String versionInfo, long vram) {
38          super(name, deviceId, vendor, versionInfo, vram);
39      }
40  
41      /**
42       * public method used by {@link oshi.hardware.common.AbstractHardwareAbstractionLayer} to access the graphics cards.
43       *
44       * @return List of {@link oshi.hardware.platform.unix.freebsd.OpenBsdGraphicsCard} objects.
45       */
46      public static List<GraphicsCard> getGraphicsCards() {
47          List<GraphicsCard> cardList = new ArrayList<>();
48          // Enumerate all devices and add if required
49          List<String> devices = ExecutingCommand.runNative("pcidump -v");
50          if (devices.isEmpty()) {
51              return Collections.emptyList();
52          }
53          String name = "";
54          String vendorId = "";
55          String productId = "";
56          boolean classCodeFound = false;
57          String versionInfo = "";
58          for (String line : devices) {
59              Matcher m = PCI_DUMP_HEADER.matcher(line);
60              if (m.matches()) {
61                  // Identifies start of a new device. Save previous if it's a graphics card
62                  if (classCodeFound) {
63                      cardList.add(new OpenBsdGraphicsCard(name.isEmpty() ? Constants.UNKNOWN : name,
64                              productId.isEmpty() ? "0x0000" : productId, vendorId.isEmpty() ? "0x0000" : vendorId,
65                              versionInfo.isEmpty() ? Constants.UNKNOWN : versionInfo, 0L));
66                  }
67                  // Device name is the captured pattern
68                  name = m.group(1);
69                  // Reset values
70                  vendorId = "";
71                  productId = "";
72                  classCodeFound = false;
73                  versionInfo = "";
74              } else {
75                  int idx;
76                  // Look for:
77                  // 0x0000: Vendor ID: 1ab8, Product ID: 4005
78                  // 0x0008: Class: 03 Display, Subclass: 00 VGA
79                  // ....... Interface: 00, Revision: 00
80                  if (!classCodeFound) {
81                      idx = line.indexOf("Vendor ID: ");
82                      if (idx >= 0 && line.length() >= idx + 15) {
83                          vendorId = "0x" + line.substring(idx + 11, idx + 15);
84                      }
85                      idx = line.indexOf("Product ID: ");
86                      if (idx >= 0 && line.length() >= idx + 16) {
87                          productId = "0x" + line.substring(idx + 12, idx + 16);
88                      }
89                      if (line.contains(PCI_CLASS_DISPLAY)) {
90                          classCodeFound = true;
91                      }
92                  } else if (versionInfo.isEmpty()) {
93                      idx = line.indexOf("Revision: ");
94                      if (idx >= 0) {
95                          versionInfo = line.substring(idx);
96                      }
97                  }
98              }
99          }
100         // In case we reached end before saving
101         if (classCodeFound) {
102             cardList.add(new OpenBsdGraphicsCard(name.isEmpty() ? Constants.UNKNOWN : name,
103                     productId.isEmpty() ? "0x0000" : productId, vendorId.isEmpty() ? "0x0000" : vendorId,
104                     versionInfo.isEmpty() ? Constants.UNKNOWN : versionInfo, 0L));
105         }
106         return cardList;
107     }
108 }