使用 C 代码使蓝牙可发现
Making bluetooth discoverable using c code
我想制作一个可以启动的蓝牙服务器,其他设备可以与之配对。
我可以让代码正常编译,服务器启动,但是当我从 android phone.
扫描蓝牙设备时,我看不到广告
我想我需要打开可发现模式。
我尝试在 hci_lib.h 中搜索使蓝牙可被发现但找不到的功能。
这是我目前的代码。
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>
int main(int argc, char **argv)
{
struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
char buf[1024] = { 0 };
int s, client, bytes_read,dev_id,sock;
socklen_t opt = sizeof(rem_addr);
dev_id = hci_get_route(NULL);
if (dev_id < 0) {
perror("No Bluetooth Adapter Available");
exit(1);
}
if (hci_devinfo(dev_id, &dev_info) < 0) {
perror("Can't get device info");
exit(1);
}
sock = hci_open_dev( dev_id );
if (sock < 0) {
perror("HCI device open failed");
free(info);
exit(1);
}
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
// bind socket to port 1 of the first available
// local bluetooth adapter
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_bdaddr = *BDADDR_ANY;
loc_addr.rc_channel = (uint8_t) 1;
bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
// put socket into listening mode
listen(s, 1);
// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
ba2str( &rem_addr.rc_bdaddr, buf );
fprintf(stderr, "accepted connection from %s\n", buf);
memset(buf, 0, sizeof(buf));
// read data from the client
bytes_read = read(client, buf, sizeof(buf));
if( bytes_read > 0 ) {
printf("received [%s]\n", buf);
}
// close connection
close(client);
close(s);
return 0;
}
打开蓝牙可发现模式需要做什么?
我相信您需要 hci_inquiry() 函数。它在蓝牙适配器上启动设备发现。
int hci_inquiry (int adapter_id, int len, int max_rsp,
const uint8 t *lap, inquiry_info **devs, long flags);
这里有一个很好的教程:
http://people.csail.mit.edu/albert/bluez-intro/c404.html#bzi-choosing
通过BlueZ命令行,通过hciconfig工具实现启用discoverability的命令如下:
hciconfig hciX piscan
其中 hciX 是系统上安装的 HCI 设备,在大多数情况下是 hci0。您可以尝试上面的命令,如果它没有 return 错误,那么您应该能够通过 Android 设备执行查询来查看您的 Linux 机器。如果这对你有用,那么你需要的代码可以在下面 link 的 hciconfig 源代码中找到:-
https://github.com/aguedes/bluez/blob/master/tools/hciconfig.c
然后您的起点将是以下函数:-
static void cmd_scan(int ctl, int hdev, char *opt)
{
struct hci_dev_req dr;
dr.dev_id = hdev;
dr.dev_opt = SCAN_DISABLED;
if (!strcmp(opt, "iscan"))
dr.dev_opt = SCAN_INQUIRY;
else if (!strcmp(opt, "pscan"))
dr.dev_opt = SCAN_PAGE;
else if (!strcmp(opt, "piscan"))
dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) {
fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n",
hdev, strerror(errno), errno);
exit(1);
}
}
希望对您有所帮助
为了让 Youssif 的回答更进一步,这里是您可以使用的代码
#include <bluetooth/hci.h>
#include <sys/ioctl.h>
int ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
// Open HCI socket
if (ctl < 0) {
// Can't open HCI socket
}
struct hci_dev_req dr;
dr.dev_id = 0; // hci0
dr.dev_opt = SCAN_DISABLED;
dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
if (ioctl(ctl, HCISETSCAN, (unsigned long)&dr) < 0) {
// Can't set scan mode
} else {
// "hci0 is now discoverable
}
close(ctl);
// Normal setup of rfcomm
int socket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
// ....
我想制作一个可以启动的蓝牙服务器,其他设备可以与之配对。
我可以让代码正常编译,服务器启动,但是当我从 android phone.
扫描蓝牙设备时,我看不到广告我想我需要打开可发现模式。
我尝试在 hci_lib.h 中搜索使蓝牙可被发现但找不到的功能。
这是我目前的代码。
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>
int main(int argc, char **argv)
{
struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
char buf[1024] = { 0 };
int s, client, bytes_read,dev_id,sock;
socklen_t opt = sizeof(rem_addr);
dev_id = hci_get_route(NULL);
if (dev_id < 0) {
perror("No Bluetooth Adapter Available");
exit(1);
}
if (hci_devinfo(dev_id, &dev_info) < 0) {
perror("Can't get device info");
exit(1);
}
sock = hci_open_dev( dev_id );
if (sock < 0) {
perror("HCI device open failed");
free(info);
exit(1);
}
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
// bind socket to port 1 of the first available
// local bluetooth adapter
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_bdaddr = *BDADDR_ANY;
loc_addr.rc_channel = (uint8_t) 1;
bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
// put socket into listening mode
listen(s, 1);
// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
ba2str( &rem_addr.rc_bdaddr, buf );
fprintf(stderr, "accepted connection from %s\n", buf);
memset(buf, 0, sizeof(buf));
// read data from the client
bytes_read = read(client, buf, sizeof(buf));
if( bytes_read > 0 ) {
printf("received [%s]\n", buf);
}
// close connection
close(client);
close(s);
return 0;
}
打开蓝牙可发现模式需要做什么?
我相信您需要 hci_inquiry() 函数。它在蓝牙适配器上启动设备发现。
int hci_inquiry (int adapter_id, int len, int max_rsp,
const uint8 t *lap, inquiry_info **devs, long flags);
这里有一个很好的教程: http://people.csail.mit.edu/albert/bluez-intro/c404.html#bzi-choosing
通过BlueZ命令行,通过hciconfig工具实现启用discoverability的命令如下:
hciconfig hciX piscan
其中 hciX 是系统上安装的 HCI 设备,在大多数情况下是 hci0。您可以尝试上面的命令,如果它没有 return 错误,那么您应该能够通过 Android 设备执行查询来查看您的 Linux 机器。如果这对你有用,那么你需要的代码可以在下面 link 的 hciconfig 源代码中找到:-
https://github.com/aguedes/bluez/blob/master/tools/hciconfig.c
然后您的起点将是以下函数:-
static void cmd_scan(int ctl, int hdev, char *opt)
{
struct hci_dev_req dr;
dr.dev_id = hdev;
dr.dev_opt = SCAN_DISABLED;
if (!strcmp(opt, "iscan"))
dr.dev_opt = SCAN_INQUIRY;
else if (!strcmp(opt, "pscan"))
dr.dev_opt = SCAN_PAGE;
else if (!strcmp(opt, "piscan"))
dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) {
fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n",
hdev, strerror(errno), errno);
exit(1);
}
}
希望对您有所帮助
为了让 Youssif 的回答更进一步,这里是您可以使用的代码
#include <bluetooth/hci.h>
#include <sys/ioctl.h>
int ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
// Open HCI socket
if (ctl < 0) {
// Can't open HCI socket
}
struct hci_dev_req dr;
dr.dev_id = 0; // hci0
dr.dev_opt = SCAN_DISABLED;
dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
if (ioctl(ctl, HCISETSCAN, (unsigned long)&dr) < 0) {
// Can't set scan mode
} else {
// "hci0 is now discoverable
}
close(ctl);
// Normal setup of rfcomm
int socket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
// ....