CSUSBDevice.m 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //
  2. // Copyright © 2021 osy. All rights reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #import "CSUSBDevice.h"
  17. #import <glib.h>
  18. #import <spice-client.h>
  19. #import <libusb.h>
  20. @interface CSUSBDevice ()
  21. @property (nonatomic, readwrite, nonnull) SpiceUsbDevice *device;
  22. @end
  23. @implementation CSUSBDevice
  24. + (instancetype)usbDeviceWithDevice:(SpiceUsbDevice *)device {
  25. return [[CSUSBDevice alloc] initWithDevice:device];
  26. }
  27. - (instancetype)initWithDevice:(SpiceUsbDevice *)device {
  28. if (self = [super init]) {
  29. self.device = g_boxed_copy(spice_usb_device_get_type(), device);
  30. }
  31. return self;
  32. }
  33. - (void)dealloc {
  34. g_boxed_free(spice_usb_device_get_type(), self.device);
  35. }
  36. - (NSString *)name {
  37. libusb_device *dev = (libusb_device *)spice_usb_device_get_libusb_device(self.device);
  38. struct libusb_device_descriptor ddesc;
  39. libusb_device_handle *handle;
  40. if (dev == NULL) {
  41. return nil;
  42. }
  43. if (libusb_get_device_descriptor(dev, &ddesc) != 0) {
  44. return nil;
  45. }
  46. if (libusb_open(dev, &handle) == 0) {
  47. unsigned char name[64] = { 0 };
  48. int bus = libusb_get_bus_number(dev);
  49. int port = libusb_get_port_number(dev);
  50. libusb_get_string_descriptor_ascii(handle,
  51. ddesc.iProduct,
  52. name, sizeof(name));
  53. libusb_close(handle);
  54. if (name[0] == '\0') {
  55. return nil;
  56. } else {
  57. return [NSString stringWithFormat:@"%s (%d:%d)", (const char *)name, bus, port];
  58. }
  59. } else {
  60. return nil;
  61. }
  62. }
  63. - (NSString *)description {
  64. gchar *description = spice_usb_device_get_description(self.device, NULL);
  65. if (!description) {
  66. return @"";
  67. }
  68. NSString *nsdescription = [NSString stringWithUTF8String:description];
  69. g_free(description);
  70. return nsdescription;
  71. }
  72. - (BOOL)isEqualToUSBDevice:(CSUSBDevice *)usbDevice {
  73. NSString *description = self.description;
  74. return description.length > 0 && [description isEqualToString:usbDevice.description];
  75. }
  76. - (BOOL)isEqual:(id)object {
  77. if (self == object) {
  78. return YES;
  79. }
  80. if (![object isKindOfClass:[CSUSBDevice class]]) {
  81. return NO;
  82. }
  83. return [self isEqualToUSBDevice:object];
  84. }
  85. - (NSUInteger)hash {
  86. return self.description.hash;
  87. }
  88. @end