HarmonyOS 鸿蒙Next上libusb是否可以获取设备列表

HarmonyOS 鸿蒙Next上libusb是否可以获取设备列表

ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER

允许应用使用外接设备增强功能。

权限级别:normal

授权方式:系统授权(system_grant)

起始版本:11

今天查文档,看到这个权限。 想知道如果加了这个权限后,libusb 集成到我的工程里,可以正常获取device列表吗?

因为,我前几天尝试了修改libusb源码,就是先通过 USBManager 获取到 device 数据,然后在 libusb 内加个方法,直接连接到设备。 相当于不使用 libusb 来获取设备列表了,因为想获取也获取不到嘛。

虽然说这样是可行的,但是是修改了源码才做到的。 这样的话很多三方库 如 : libuvc 他是依赖 libusb 的,那也要修改 libuvc 的源码了,这就太麻烦了。

所以,刚刚逛文档,发现这个 ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER 权限 。

想知道,如果加了这个权限 , 是不是就不需要我上面写的那样修改 libusb 源码来实现外设连接呢?


更多关于HarmonyOS 鸿蒙Next上libusb是否可以获取设备列表的实战教程也可以访问 https://www.itying.com/category-93-b0.html

12 回复

开发者您好,可以采取以下方式解决:

通过应用层的usbManager获取到usb的句柄传到native层去使用,示例代码如下:

import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';
import { usbManager } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  showToast(msg: string) {
    promptAction.showToast({
      message: msg,
      duration: 1500,
    });
  }

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            let deviceList: Array<usbManager.USBDevice> = usbManager.getDevices();
            if (deviceList.length <= 0) {
              this.showToast('未发现龙脉Ukey! ');
              return;
            }
            console.log(`devicesList = ${JSON.stringify(deviceList)}`);

            let find = false;
            let index = 0;
            for (let dev of deviceList) {
              if (dev.vendorId == 1372) {
                if (!usbManager.hasRight(dev.name)) {
                  usbManager.requestRight(dev.name);
                }
                find = true;
                break;
              }
              index++;
            }

            let devicepipe: usbManager.USBDevicePipe = usbManager.connectDevice(deviceList[index]);
            let fd: number = usbManager.getFileDescriptor(devicepipe);
            testNapi.skf_TestLed(fd);
            this.showToast(index + "  :  " + fd + "  " + deviceList[0].vendorId + "  " + deviceList[index].vendorId);
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
static napi_value NAPI_Global_skf_TestLed(napi_env env, napi_callback_info info) {
    napi_value result;
    size_t argc = 1;
    napi_value argv;
    napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
    int32_t fd = 0;
    napi_get_value_int32(env, argv, &fd);
    OH_LOG_INFO(LOG_APP, "fd: %d", fd);
    static libusb_context *ctx = NULL;
    if (NULL == ctx) {
        struct libusb_init_option options[] = {
            {
                .option = LIBUSB_OPTION_NO_DEVICE_DISCOVERY,
                .value = {.ival = NULL},
            },
        };
        OH_LOG_INFO(LOG_APP, "%s %s", "libusb_init1", "start");
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "Failed to libusb_init1");
        int r = libusb_init_context(&ctx, options, 1);
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "Failed to libusb_init1");

        if (r < 0) {
            OH_LOG_INFO(LOG_APP, "%s %d", "libusb_initfail", libusb_error_name(r));
        }
        OH_LOG_INFO(LOG_APP, "%s %d", "libusb_init2", r);
    }
    libusb_device_handle *handle = NULL;
    int r = libusb_wrap_sys_device(ctx, (intptr_t)fd, &handle);
    OH_LOG_INFO(LOG_APP, "%s %d", "libusb_wrap_sys_device", r);
    if (0 == r) {
        OH_LOG_INFO(LOG_APP, "%s", "libusb_wrap_sys_device ok");
    }
    napi_get_undefined(env, &result);
    // 获取设备列表
    libusb_device **devices;
    ssize_t cnt = libusb_get_device_list(ctx, &devices);
    if (cnt < 0) {
        std::cerr << "Failed to get device list: " << libusb_error_name(cnt) << std::endl;
        libusb_exit(ctx);
    }
    // 遍历设备列表并获取第一个设备的文件描述符
    for (ssize_t i = 0; i < cnt; i++) {
        libusb_device *device = devices[i];
        libusb_device_descriptor desc;
        // 获取设备描述符
        r = libusb_get_device_descriptor(device, &desc);
        if (r < 0) {
            std::cerr << "Failed to get device descriptor: " << libusb_error_name(r) << std::endl;
            continue;
        }
        // 打印设备信息
        std::cout << "Device " << i << ": ID " << std::hex << desc.idVendor << ":" << desc.idProduct << std::dec
                  << std::endl;
        // 打开设备
        libusb_device_handle *handle;
        r = libusb_open(device, &handle);
        if (r != 0) {
            std::cerr << "Failed to open device: " << libusb_error_name(r) << std::endl;
            continue;
        }
        // 关闭设备
        libusb_close(handle);
        break; // 只处理第一个设备
    }
    // 释放设备列表
    libusb_free_device_list(devices, 1);
    // 退出libusb
    libusb_exit(ctx);
    return result;
}

权限配置:

"requestPermissions":
[
  {
    "name": "ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER"
  }
]

更多关于HarmonyOS 鸿蒙Next上libusb是否可以获取设备列表的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


这样写,相当于 libusb 库不需要修改的对吧,把 fd 传进去,使用 libusb_wrap_sys_device 来获取设备。

是的。

ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVE允许应用访问外接设备增强功能(USB设备管理),它属于系统授权,安装时自动授权,不需要用户动态申请。

添加ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVE权限后,可通过鸿蒙提供的标准接口deviceManager.queryDevices()获取设备列表,无需依赖libusb原生方式。但是如果要保持libusb原生调用方式,还得确认鸿蒙是否提供兼容的驱动层支持

推荐楼主通过系统API获取设备信息后注入到libusb,可避免大规模修改三方库。

我已经尝试了实现了 libuvc,需要从 libuvc 开始修改,传入设备信息,然后 libuvc 调用 libusb 也要改。才做到了。

所以,要源码集成,这样太复杂了。遇到复杂的依赖 libusb 的库,就很麻烦。

我要必须使用 libusb 来获取,因为我想使用的第三方库依赖 libusb,所以本来是想问能不能用 libusb 来获取。 目前来看,答案是不能。所以,就需要修改 libusb 的源码了,想想都头大。

是的,你的的理解是对的。鸿蒙提供了“开发无UI界面基础驱动”,

官方解释是:

无UI界面的基础驱动,适用于不需要通过UI界面设置驱动能力的简单设备,例如鼠标,键盘等,保证设备的即插即用功能即可。开发者可以通过DriverExtensionAbility实现此类应用的开发

而该权限意思是“允许应用使用外接设备增强功能。”允许使用,那肯定是可以获取到外设列表的,具体给你找了文档,你可以参考下:Driver Development Kit简介-Driver Development Kit(驱动开发服务)-硬件-系统 - 华为HarmonyOS开发者

通过鸿蒙原生USB管理接口可直接获取设备列表:

//使用usbManager.getDevices()方法

import { usbManager } from '@kit.BasicServicesKit';

let deviceList = usbManager.getDevices();
console.info(`deviceList: ${JSON.stringify(deviceList)}`);

汉字我不懂,

在HarmonyOS鸿蒙Next上,libusb目前无法直接获取USB设备列表。鸿蒙Next采用了全新的硬件抽象层(HDF)架构,USB设备管理通过HDF框架实现,与传统的libusb实现机制不同。开发者需要使用鸿蒙提供的HDI接口(如usb_manager.h)来枚举USB设备,这些接口在//drivers/peripheral/usb目录下定义。鸿蒙Next的USB设备访问权限需要通过ohos.permission.USB权限声明,并在config.json中配置。

在HarmonyOS Next上,仅添加ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER权限并不能让libusb直接获取USB设备列表。该权限主要用于允许应用使用外接设备增强功能,但HarmonyOS的USB访问机制与标准Linux不同。

目前HarmonyOS的USB设备访问需要通过系统提供的USBManager API来实现,libusb这类原生库无法直接访问底层USB设备。您之前通过修改libusb源码,结合USBManager获取设备数据的方式是正确的解决方案。

对于依赖libusb的三方库(如libuvc),确实需要做相应适配。建议继续使用您当前的方案,或者考虑封装HarmonyOS USBManager接口来替代libusb的功能。

回到顶部