libusb_claim_interface


API_EXPORTED int

libusb_claim_interface(libusb_device_handle *dev,
 int interface_number)
{
 int r = 0;

 usbi_dbg("interface %d", interface_number);

 

 


 if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
  return LIBUSB_ERROR_INVALID_PARAM;

 

 

// 看来这个interface_number 还是跟dev 有关,难道是dev中有许多interface? 然后我们启用其中一个?

//将设备进行加锁 通过修改dev_lock实现

 pthread_mutex_lock(&dev->lock);


 if (dev->claimed_interfaces & (1 << interface_number))
  goto out;

 

//实际上通过该函数实现底层声明借口

 r = usbi_backend->claim_interface(dev, interface_number);


 if (r == 0)
  dev->claimed_interfaces |= 1 << interface_number;

out:
 pthread_mutex_unlock(&dev->lock);
 return r;
}

 

现在来查看下struct  libusb_dev_handle 

struct libusb_device_handle {
 /* lock protects claimed_interfaces */
 pthread_mutex_t lock;
 unsigned long claimed_interfaces;

struct list_head list;
 struct libusb_device *dev;
 unsigned char os_priv[0];
};

 

 

当我们打开一个libusb_device的时候会返回给一个设备处理指针

 

 

libusb_device_handle  * libusb_open_device_with_vid_pid(libusb_context *ctx , uint vid  , uint pid);

 

/** /ingroup dev
 * Convenience function for finding a device with a particular
 * <tt>idVendor</tt>/<tt>idProduct</tt> combination. This function is intended
 * for those scenarios where you are using libusb to knock up a quick test
 * application - it allows you to avoid calling libusb_get_device_list() and
 * worrying about traversing/freeing the list.
 *
 * This function has limitations and is hence not intended for use in real
 * applications: if multiple devices have the same IDs it will only
 * give you the first one, etc.
 *
 * /param ctx the context to operate on, or NULL for the default context
 * /param vendor_id the idVendor value to search for
 * /param product_id the idProduct value to search for
 * /returns a handle for the first found device, or NULL on error or if the
 * device could not be found. */
 
 
API_EXPORTED libusb_device_handle *libusb_open_device_with_vid_pid(
 libusb_context *ctx, uint16_t vendor_id, uint16_t product_id)
{
 struct libusb_device **devs;
 struct libusb_device *found = NULL;
 struct libusb_device *dev;
 struct libusb_device_handle *handle = NULL;
 size_t i = 0;
 int r;

 if (libusb_get_device_list(ctx, &devs) < 0)
  return NULL;

 while ((dev = devs[i++]) != NULL) {
  struct libusb_device_descriptor desc;
  r = libusb_get_device_descriptor(dev, &desc);
  if (r < 0)
   goto out;

//看来vid和pid还是存放在libusb_descriptor中的
  if (desc.idVendor == vendor_id && desc.idProduct == product_id) {
   found = dev;
   break;
  }
 }

 if (found) {
  r = libusb_open(found, &handle);
  if (r < 0)
   handle = NULL;
 }

out:
 libusb_free_device_list(devs, 1);
 return handle;
}

 

  他其实调用的还是int  libusb_open(libusb_device , libusb_device_handle &);

现在分析下如何 通过libusb_open将 libusb_device_handle 中的unsigned long claimed_interface修改下。

API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)

{

struct libusb_context *ctx = DEVICE_CTX(dev);

struct libusb_device_handle *_handle;

size_t priv_size = usbi_backend->device_handle_priv_size;

unsigned char dummy = 1;

int r;

usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);

 

_handle = malloc(sizeof(*_handle) + priv_size);

if (!_handle)

return LIBUSB_ERROR_NO_MEM;

 

//对于每一个handle创建一个lock

r = pthread_mutex_init(&_handle->lock, NULL);

if (r)

return LIBUSB_ERROR_OTHER;

 

_handle->dev = libusb_ref_device(dev);

 

//将claimedInterface设置默认为0

_handle->claimed_interfaces = 0;

memset(&_handle->os_priv, 0, priv_size); 

 

r = usbi_backend->open(_handle);

if (r < 0) {

libusb_unref_device(dev);

free(_handle);

return r;

}

 

pthread_mutex_lock(&ctx->open_devs_lock);

list_add(&_handle->list, &ctx->open_devs);

pthread_mutex_unlock(&ctx->open_devs_lock);

*handle = _handle;

 

 

/* At this point, we want to interrupt any existing event handlers so

* that they realise the addition of the new device's poll fd. One

* example when this is desirable is if the user is running a separate

* dedicated libusb events handling thread, which is running with a long

* or infinite timeout. We want to interrupt that iteration of the loop,

* so that it picks up the new fd, and then continues. */

 

/* record that we are messing with poll fds */

pthread_mutex_lock(&ctx->pollfd_modify_lock);

ctx->pollfd_modify++;

pthread_mutex_unlock(&ctx->pollfd_modify_lock);

 

/* write some data on control pipe to interrupt event handlers */

r = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));

if (r <= 0) {

usbi_warn(ctx, "internal signalling write failed");

pthread_mutex_lock(&ctx->pollfd_modify_lock);

ctx->pollfd_modify--;

 

 

//可见每一个ctx中也有一个lock

pthread_mutex_unlock(&ctx->pollfd_modify_lock);

return 0;

}

 

/* take event handling lock */

libusb_lock_events(ctx);

 

/* read the dummy data */

r = read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));

if (r <= 0)

usbi_warn(ctx, "internal signalling read failed");

 

/* we're done with modifying poll fds */

pthread_mutex_lock(&ctx->pollfd_modify_lock);

ctx->pollfd_modify--;

pthread_mutex_unlock(&ctx->pollfd_modify_lock);

 

/* Release event handling lock and wake up event waiters */

libusb_unlock_events(ctx);

 

return 0;

}

 

 

 

 

总结: claim_interface是libusb_device_handle的成员变量在libusb_open(libusb_device *dev, libusb_context **handle)将其默认为0

  他具体有什么作用的,求高手指教?

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值