I am trying to create and use a user channel socket on an hci interface. Here's the code
in main.c:
int devsocket = open_dev(dev_id);
if(devsocket < 0){
perror("Unable to open HCI_CHANNEL_USER socket on interface");
exit(1);
}
printf("HCI_CHANNEL_USER socket open on device %d\n",dev_id);
char name[20];
int ret = hci_read_local_name(devsocket,sizeof(name),name,1000);
if(ret < 0){
perror("Unable to read local name");
exit(1);
}
printf("Local name : %s\n",name);
open_dev:
int open_dev(int dev_id){
struct sockaddr_hci a;
int dd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);
if (dd < 0){
perror("Can't create socket");
return -1;
}
printf("[open_dev][+] HCI socket created\n");
if(ioctl(dd,HCIDEVDOWN,dev_id)){
perror("[open_dev][-] Unable to turn down interface");
close(dd);
return -1;
}
printf("[open_dev][+] Interface turned off\n");
if(wait_hcidev(dev_id)){
perror("[open_dev][-] Interface unavailable\n");
close(dd);
return -1;
}
printf("[open_dev][+] Interface available\n");
memset(&a, 0, sizeof(a));
a.hci_family = AF_BLUETOOTH;
a.hci_dev = dev_id;
a.hci_channel = HCI_CHANNEL_USER;
if (bind(dd,(struct sockaddr *) &a,sizeof(a)) < 0){
close(dd);
perror("[open_dev][-] Unable to bind socket");
return -1;
}
return dd;
}
I posted the relevant parts of the code. When i compile and run it says that the File descriptor is in a bad state when trying to read the local name of the interface (hci0). There is almost no documentation for this type of socket. I tried to understand something from the commit about the introduction of it, one link is this https://marc.info/?l=linux-bluetooth&m=137805746226433&w=2. I copied some code from https://github.com/projectceladon/libbt-vendor-linux/blob/master/bt_vendor_linux.c#L302. When i don't set a.hci_channel=HCI_CHANNEL_USER and i don't turn off the interface i can use the BlueZ API, so what are the uses of a user channel socket? What am i doing wrong? Thank you!