I'm using libusb-1.0 to pair a BLE dongle to an RCU.
For this, I write a pairing request to the dongle interface succesfully.
To listen to the dongle response I'm using the function libusb_fill_interrupt_transfer
and I pass a callback, which will be executed when receiving the response.
This function accepts a parameter, as mentionned in the documentation (void *user_data
), that can be used in the callback. But when I try to use this parameter, I get a compilation error.
undeclared (first use in this function)
Following the call of the previous function and the declaration of my callback :
libusb_fill_interrupt_transfer(pairing->transfer, dctx->devh, 0x84, pairing->buffer,
sizeof(pairing->buffer), cb_aknowledgement, pairing, 0);
static void cb_aknowledgement(struct libusb_transfer *transfer)
{
if (pairing->transfer->status != LIBUSB_TRANSFER_COMPLETED) {
printf( "img transfer status %d?\n", pairing->transfer->status);
libusb_free_transfer(pairing->transfer);
pairing->transfer = NULL;
return;
}
if(pairing->buffer[0]!=0x05 || pairing->buffer[1]!=0x21)
{
printf( "wrong command recieved\n");
libusb_free_transfer(pairing->transfer);
pairing->transfer = NULL;
return;
}
printf("I've read data \n");
printf("USB Report Id = 0x%x \n",pairing->buffer[0]);
printf("Command = 0x%x \n",pairing->buffer[1]);
printf("Acknowledgement type = 0x%x \n",pairing->buffer[2]);
return ;
}
The question is: How can I use the user_data
I passed as a parameter to the callback?
Use transfer->user_data
. From libusb_transfer structure doc :
Data Fields
void * user_data
User context data to pass to the callback function.
I don't know what is the type of pairing
but it would look like this:
int main() {
...
struct pairing_type_s *pairing = pairing_init();
...
libusb_fill_interrupt_transfer(pairing->transfer, dctx->devh, 0x84, pairing->buffer,
sizeof(pairing->buffer), cb_aknowledgement, pairing, 0);
...
}
// Then later:
static void cb_aknowledgement(struct libusb_transfer *transfer)
{
assert(transfer != NULL);
struct pairing_type_s *pairing = transfer->user_data;
assert(pairing != NULL);
// use pairing like a pro
...
}
But you can also be more pro, if you ensure that you always call libusb_fill_interrupt_transfer
with pairing->transfer
with cb_aknowledgement
and use container_of
macro:
int main() {
...
struct pairing_type_s *pairing = pairing_init();
...
libusb_fill_interrupt_transfer(pairing->transfer, dctx->devh, 0x84, pairing->buffer,
sizeof(pairing->buffer), cb_aknowledgement, NULL, 0);
...
}
// Then later:
static void cb_aknowledgement(struct libusb_transfer *transfer)
{
assert(transfer != NULL);
struct pairing_type_s *pairing = container_of(transfer, struct pairing_type_s, transfer);
assert(pairing != NULL);
// use pairing like a pro
...
}
But I would prefer the first method in this case, as it's more readable and more errorless.