1 /* Copyright (c) 2020 Daniel Widdis, All Rights Reserved 2 * 3 * The contents of this file is dual-licensed under 2 4 * alternative Open Source/Free licenses: LGPL 2.1 or later and 5 * Apache License 2.0. (starting with JNA version 4.0.0). 6 * 7 * You can freely decide which license you want to apply to 8 * the project. 9 * 10 * You may obtain a copy of the LGPL License at: 11 * 12 * http://www.gnu.org/licenses/licenses.html 13 * 14 * A copy is also included in the downloadable source code package 15 * containing JNA, in file "LGPL2.1". 16 * 17 * You may obtain a copy of the Apache License at: 18 * 19 * http://www.apache.org/licenses/ 20 * 21 * A copy is also included in the downloadable source code package 22 * containing JNA, in file "AL2.0". 23 */ 24 package com.sun.jna.platform.linux; 25 26 import com.sun.jna.Library; 27 import com.sun.jna.Native; 28 import com.sun.jna.PointerType; 29 30 /** 31 * libudev.h provides APIs to introspect and enumerate devices on the local 32 * system. Udev objects are opaque and must not be accessed by the caller via 33 * different means than functions provided by libudev. 34 */ 35 public interface Udev extends Library { 36 37 Udev INSTANCE = Native.load("udev", Udev.class); 38 39 /** 40 * All functions require a libudev context to operate. This context can be 41 * created via {@link #udev_new}. It is used to track library state and link 42 * objects together. No global state is used by libudev, everything is always 43 * linked to a udev context. Furthermore, multiple different udev contexts can 44 * be used in parallel by multiple threads. However, a single context must not 45 * be accessed by multiple threads in parallel. The caller is responsible for 46 * providing suitable locking if they intend to use it from multiple threads. 47 */ 48 class UdevContext extends PointerType { 49 /** 50 * Acquire a further reference to this object. 51 * 52 * @return this object, unmodified. 53 */ ref()54 UdevContext ref() { 55 return INSTANCE.udev_ref(this); 56 } 57 58 /** 59 * Drop a reference to this object. Once the reference count hits 0, the context 60 * object is destroyed and freed. 61 */ unref()62 public void unref() { 63 INSTANCE.udev_unref(this); 64 } 65 66 /** 67 * Create a udev enumerate object. Initially, the reference count of the 68 * enumerate object is 1. 69 * 70 * @return On success, returns the allocated enumerator. On failure, NULL is 71 * returned. 72 */ enumerateNew()73 public UdevEnumerate enumerateNew() { 74 return INSTANCE.udev_enumerate_new(this); 75 } 76 77 /** 78 * Creates a udev device object based on information found in {@code /sys}, 79 * annotated with properties from the udev-internal device database. Initially, 80 * the reference count of the device is 1. 81 * 82 * @param syspath 83 * The path of the device in {@code /sys}. 84 * @return the allocated udev device. On failure, NULL is returned, and 85 * {@code errno} is set appropriately. 86 */ deviceNewFromSyspath(String syspath)87 public UdevDevice deviceNewFromSyspath(String syspath) { 88 return INSTANCE.udev_device_new_from_syspath(this, syspath); 89 } 90 } 91 92 /** 93 * To enumerate local devices on the system, an enumeration object can be 94 * created via {@link UdevContext#enumerateNew()}. 95 */ 96 class UdevEnumerate extends PointerType { 97 /** 98 * Acquire a further reference to this object. 99 * 100 * @return this object, unmodified. 101 */ ref()102 public UdevEnumerate ref() { 103 return INSTANCE.udev_enumerate_ref(this); 104 } 105 106 /** 107 * Drop a reference to this object. Once the reference count hits 0, the context 108 * object is destroyed and freed. 109 */ unref()110 public void unref() { 111 INSTANCE.udev_enumerate_unref(this); 112 } 113 114 /** 115 * Modify filters of this object to match a subsystem. 116 * 117 * @param subsystem 118 * The subsystem to match 119 * @return an integer greater than, or equal to, 0 on success. 120 */ addMatchSubsystem(String subsystem)121 public int addMatchSubsystem(String subsystem) { 122 return INSTANCE.udev_enumerate_add_match_subsystem(this, subsystem); 123 } 124 125 /** 126 * Query this object. Scans {@code /sys} for all devices which match the given 127 * filters. No filters will return all currently available devices. 128 * 129 * @return an integer greater than, or equal to, 0 on success. 130 */ scanDevices()131 public int scanDevices() { 132 return INSTANCE.udev_enumerate_scan_devices(this); 133 } 134 135 /** 136 * Get the first list entry from this object. 137 * 138 * @return On success, returns the first entry in the list of found devices. If 139 * the list is empty, or on failure, NULL is returned. 140 */ getListEntry()141 public UdevListEntry getListEntry() { 142 return INSTANCE.udev_enumerate_get_list_entry(this); 143 } 144 } 145 146 /** 147 * Whenever libudev returns a list of objects, the {@code udev_list_entry} API 148 * should be used to iterate, access and modify those lists. 149 */ 150 class UdevListEntry extends PointerType { 151 /** 152 * Gets the next entry in the enumeration. 153 * 154 * @return On success, returns the next list entry. If no such entry can be 155 * found, or on failure, NULL is returned. 156 */ getNext()157 public UdevListEntry getNext() { 158 return INSTANCE.udev_list_entry_get_next(this); 159 } 160 161 /** 162 * Get the name of this entry, which is the path of the device in {@code /sys}. 163 * 164 * @return A string representing the syspath. On failure, NULL is returned. 165 */ getName()166 public String getName() { 167 return INSTANCE.udev_list_entry_get_name(this); 168 } 169 } 170 171 /** 172 * To introspect a local device on a system, a udev device object can be created 173 * via {@link UdevContext#deviceNewFromSyspath(String)} and friends. The device 174 * object allows one to query current state, read and write attributes and 175 * lookup properties of the device in question. 176 */ 177 class UdevDevice extends PointerType { 178 /** 179 * Acquire a further reference to this object. 180 * 181 * @return this object, unmodified. 182 */ ref()183 public UdevDevice ref() { 184 return INSTANCE.udev_device_ref(this); 185 } 186 187 /** 188 * Drop a reference to this object. Once the reference count hits 0, the context 189 * object is destroyed and freed. 190 */ unref()191 public void unref() { 192 INSTANCE.udev_device_unref(this); 193 } 194 195 /** 196 * Gets the parent of this device 197 * 198 * @return the parent device. No additional reference to this device is 199 * acquired, but the child device owns a reference to the parent device. 200 * On failure, NULL is returned. 201 */ getParent()202 public UdevDevice getParent() { 203 return INSTANCE.udev_device_get_parent(this); 204 } 205 206 /** 207 * Gets the parent of this device matching a subsystem and devtype 208 * 209 * @param subsystem 210 * The subsystem to match 211 * @param devtype 212 * The device type to match 213 * @return the parent device. No additional reference to this device is 214 * acquired, but the child device owns a reference to the parent device. 215 * On failure, NULL is returned. 216 */ getParentWithSubsystemDevtype(String subsystem, String devtype)217 public UdevDevice getParentWithSubsystemDevtype(String subsystem, String devtype) { 218 return INSTANCE.udev_device_get_parent_with_subsystem_devtype(this, subsystem, devtype); 219 } 220 221 /** 222 * Gets the syspath of this device 223 * 224 * @return a string that describes the syspath. On failure, may return NULL. 225 */ getSyspath()226 public String getSyspath() { 227 return INSTANCE.udev_device_get_syspath(this); 228 } 229 230 /** 231 * Gets the sysname of this device 232 * 233 * @return a string that describes the sysname. On failure, may return NULL. 234 */ getSysname()235 public String getSysname() { 236 return INSTANCE.udev_device_get_syspath(this); 237 } 238 239 /** 240 * Gets the devnode of this device 241 * 242 * @return a string that describes the devnode. On failure, may return NULL. 243 */ getDevnode()244 public String getDevnode() { 245 return INSTANCE.udev_device_get_devnode(this); 246 } 247 248 /** 249 * Gets the devtype of this device 250 * 251 * @return a string that describes the devtype. On failure, may return NULL. 252 */ getDevtype()253 public String getDevtype() { 254 return INSTANCE.udev_device_get_devtype(this); 255 } 256 257 /** 258 * Gets the subsystem of this device 259 * 260 * @return a string that describes the subsystem. On failure, may return NULL. 261 */ getSubsystem()262 public String getSubsystem() { 263 return INSTANCE.udev_device_get_subsystem(this); 264 } 265 266 /** 267 * Retrieves a device attribute from this device 268 * 269 * @param sysattr 270 * The attribute to retrieve. 271 * @return a string of the requested value. On error, NULL is returned. 272 * Attributes that may contain NUL bytes should not be retrieved with 273 * udev_device_get_sysattr_value(); instead, read them directly from the 274 * files within the device's syspath. 275 */ getSysattrValue(String sysattr)276 public String getSysattrValue(String sysattr) { 277 return INSTANCE.udev_device_get_sysattr_value(this, sysattr); 278 } 279 280 /** 281 * Retrieves a device property from this device 282 * 283 * @param key 284 * The property to retrieve. 285 * @return a string of the requested value. On error, NULL is returned. 286 */ getPropertyValue(String key)287 public String getPropertyValue(String key) { 288 return INSTANCE.udev_device_get_property_value(this, key); 289 } 290 } 291 292 /** 293 * Allocates a new udev context object and returns a pointer to it. This object 294 * is opaque and must not be accessed by the caller via different means than 295 * functions provided by libudev. Initially, the reference count of the context 296 * is 1. 297 * 298 * @return On success, returns a pointer to the allocated udev context. On 299 * failure, NULL is returned. 300 */ udev_new()301 UdevContext udev_new(); 302 303 /** 304 * Acquire further references to a udev context object. 305 * 306 * @param udev 307 * A udev context object. 308 * @return the argument that was passed, unmodified. 309 */ udev_ref(UdevContext udev)310 UdevContext udev_ref(UdevContext udev); 311 312 /** 313 * Drop a reference to a udev context object. Once the reference count hits 0, 314 * the context object is destroyed and freed. 315 * 316 * @param udev 317 * A udev context object. 318 * @return always returns NULL. 319 */ udev_unref(UdevContext udev)320 UdevContext udev_unref(UdevContext udev); 321 322 /** 323 * Allocates a new udev device object and returns a pointer to it. This object 324 * is opaque and must not be accessed by the caller via different means than 325 * functions provided by libudev. Initially, the reference count of the device 326 * is 1. 327 * <p> 328 * Creates the device object based on information found in {@code /sys}, 329 * annotated with properties from the udev-internal device database. A syspath 330 * is any subdirectory of {@code /sys}, with the restriction that a subdirectory 331 * of {@code /sys/devices} (or a symlink to one) represents a real device and as 332 * such must contain a uevent file. 333 * 334 * @param udev 335 * A udev context object. 336 * @param syspath 337 * The path of the device in {@code /sys}. 338 * @return a pointer to the allocated udev device. On failure, NULL is returned, 339 * and {@code errno} is set appropriately. 340 */ udev_device_new_from_syspath(UdevContext udev, String syspath)341 UdevDevice udev_device_new_from_syspath(UdevContext udev, String syspath); 342 343 /** 344 * Create a udev enumerate object. Initially, the reference count of the 345 * enumerate object is 1. 346 * 347 * @param udev 348 * A udev context object. 349 * @return On success, returns a pointer to the allocated udev monitor. On 350 * failure, NULL is returned. 351 */ udev_enumerate_new(UdevContext udev)352 UdevEnumerate udev_enumerate_new(UdevContext udev); 353 354 /** 355 * Acquire further references to a udev enumerate object. 356 * 357 * @param udev_enumerate 358 * A udev enumerate object. 359 * @return the argument that was passed, unmodified. 360 */ udev_enumerate_ref(UdevEnumerate udev_enumerate)361 UdevEnumerate udev_enumerate_ref(UdevEnumerate udev_enumerate); 362 363 /** 364 * Drop a reference to a udev enumerate object. Once the reference count hits 0, 365 * the enumerate object is destroyed and freed. 366 * 367 * @param udev_enumerate 368 * A udev enumerate object. 369 * @return always returns NULL. 370 */ udev_enumerate_unref(UdevEnumerate udev_enumerate)371 UdevEnumerate udev_enumerate_unref(UdevEnumerate udev_enumerate); 372 373 /** 374 * Modify filters of a udev enumerate object to match a subsystem. 375 * 376 * @param udev_enumerate 377 * The udev enumerate object to modify. 378 * @param subsystem 379 * The subsystem to match 380 * @return an integer greater than, or equal to, 0 on success. 381 */ udev_enumerate_add_match_subsystem(UdevEnumerate udev_enumerate, String subsystem)382 int udev_enumerate_add_match_subsystem(UdevEnumerate udev_enumerate, String subsystem); 383 384 /** 385 * Query a udev enumerate object. Scans {@code /sys} for all devices which match 386 * the given filters. No matches will return all currently available devices. 387 * 388 * @param udev_enumerate 389 * The udev enumerate object, with optional filters. 390 * @return an integer greater than, or equal to, 0 on success. 391 */ udev_enumerate_scan_devices(UdevEnumerate udev_enumerate)392 int udev_enumerate_scan_devices(UdevEnumerate udev_enumerate); 393 394 /** 395 * Get the first list entry from a udev enumerate object. 396 * 397 * @param udev_enumerate 398 * The udev enumerate object. 399 * @return On success, returns a pointer to the first entry in the list of found 400 * devices. If the list is empty, or on failure, NULL is returned. 401 */ udev_enumerate_get_list_entry(UdevEnumerate udev_enumerate)402 UdevListEntry udev_enumerate_get_list_entry(UdevEnumerate udev_enumerate); 403 404 /** 405 * Gets the next entry in the enumeration. 406 * 407 * @param list_entry 408 * the current list entry 409 * @return On success, returns a pointer to the next list entry. If no such 410 * entry can be found, or on failure, NULL is returned. 411 */ udev_list_entry_get_next(UdevListEntry list_entry)412 UdevListEntry udev_list_entry_get_next(UdevListEntry list_entry); 413 414 /** 415 * Get the name of the udev list entry 416 * 417 * @param list_entry 418 * A udev list entry 419 * @return a pointer to a constant string representing the requested value. The 420 * string is bound to the lifetime of the list entry itself. On failure, 421 * NULL is returned. 422 */ udev_list_entry_get_name(UdevListEntry list_entry)423 String udev_list_entry_get_name(UdevListEntry list_entry); 424 425 /** 426 * Acquire further references to a udev device object. 427 * 428 * @param udev_device 429 * A udev device object. 430 * @return the argument that was passed, unmodified. 431 */ udev_device_ref(UdevDevice udev_device)432 UdevDevice udev_device_ref(UdevDevice udev_device); 433 434 /** 435 * Drop a reference to a udev device object. Once the reference count hits 0, 436 * the device object is destroyed and freed. 437 * 438 * @param udev_device 439 * A udev device object. 440 * @return always returns NULL. 441 */ udev_device_unref(UdevDevice udev_device)442 UdevDevice udev_device_unref(UdevDevice udev_device); 443 444 /** 445 * Gets the parent of a udev device 446 * 447 * @param udev_device 448 * A udev device object. 449 * @return a pointer to the parent device. No additional reference to this 450 * device is acquired, but the child device owns a reference to such a 451 * parent device. On failure, NULL is returned. 452 */ udev_device_get_parent(UdevDevice udev_device)453 UdevDevice udev_device_get_parent(UdevDevice udev_device); 454 455 /** 456 * Gets the parent of a udev device matching a subsystem and devtype 457 * 458 * @param udev_device 459 * A udev device object. 460 * @param subsystem 461 * The subsystem to match 462 * @param devtype 463 * The device type to match 464 * @return a pointer to the parent device. No additional reference to this 465 * device is acquired, but the child device owns a reference to such a 466 * parent device. On failure, NULL is returned. 467 */ udev_device_get_parent_with_subsystem_devtype(UdevDevice udev_device, String subsystem, String devtype)468 UdevDevice udev_device_get_parent_with_subsystem_devtype(UdevDevice udev_device, String subsystem, String devtype); 469 470 /** 471 * Gets the syspath of a udev device 472 * 473 * @param udev_device 474 * A udev device object. 475 * @return a pointer to a constant string that describes the syspath. The 476 * lifetime of this string is bound to the device it was requested on. 477 * On failure, may return NULL. 478 */ udev_device_get_syspath(UdevDevice udev_device)479 String udev_device_get_syspath(UdevDevice udev_device); 480 481 /** 482 * Gets the sysname of a udev device 483 * 484 * @param udev_device 485 * A udev device object. 486 * @return a pointer to a constant string that describes the sysname. The 487 * lifetime of this string is bound to the device it was requested on. 488 * On failure, may return NULL. 489 */ udev_device_get_sysname(UdevDevice udev_device)490 String udev_device_get_sysname(UdevDevice udev_device); 491 492 /** 493 * Gets the devnode of a udev device 494 * 495 * @param udev_device 496 * A udev device object. 497 * @return a pointer to a constant string that describes the devnode. The 498 * lifetime of this string is bound to the device it was requested on. 499 * On failure, may return NULL. 500 */ udev_device_get_devnode(UdevDevice udev_device)501 String udev_device_get_devnode(UdevDevice udev_device); 502 503 /** 504 * Gets the devtype of a udev device 505 * 506 * @param udev_device 507 * A udev device object. 508 * @return a pointer to a constant string that describes the devtype. The 509 * lifetime of this string is bound to the device it was requested on. 510 * On failure, may return NULL. 511 */ udev_device_get_devtype(UdevDevice udev_device)512 String udev_device_get_devtype(UdevDevice udev_device); 513 514 /** 515 * Gets the subsystem of a udev device 516 * 517 * @param udev_device 518 * A udev device object. 519 * @return a pointer to a constant string that describes the subsystem. The 520 * lifetime of this string is bound to the device it was requested on. 521 * On failure, may return NULL. 522 */ udev_device_get_subsystem(UdevDevice udev_device)523 String udev_device_get_subsystem(UdevDevice udev_device); 524 525 /** 526 * Retrieves a device attributesfrom a udev device. 527 * 528 * @param udev_device 529 * A udev device object. 530 * @param sysattr 531 * The attribute to retrieve. 532 * @return a pointer to a constant string of the requested value. On error, NULL 533 * is returned. Attributes that may contain NUL bytes should not be 534 * retrieved with udev_device_get_sysattr_value(); instead, read them 535 * directly from the files within the device's syspath. 536 */ udev_device_get_sysattr_value(UdevDevice udev_device, String sysattr)537 String udev_device_get_sysattr_value(UdevDevice udev_device, String sysattr); 538 539 /** 540 * Retrieves a device property from a udev device. 541 * 542 * @param udev_device 543 * A udev device object. 544 * @param key 545 * The property to retrieve. 546 * @return a pointer to a constant string of the requested value. On error, NULL 547 * is returned. 548 */ udev_device_get_property_value(UdevDevice udev_device, String key)549 String udev_device_get_property_value(UdevDevice udev_device, String key); 550 }