我找不到任何关于如何在Linux上使用BlueZ蓝牙库在用C编写的程序中配对蓝牙设备的参考。我已经设法进行HCI级别查询以获取设备及其RSSI级别(在设备发现期间),但目前我仍然坚持这一点。我看到了使用DBUS api for blueZ-simple-agent的建议 - 但是有什么方法可以避免这种情况并且只使用BlueZ的一些C级方法吗?
答案 0 :(得分:4)
来自hcitool
的身份验证代码(原始源代码可在http://git.kernel.org/cgit/bluetooth/bluez.git/tree/tools/hcitool.c查看)
/* Request authentication */
static void cmd_auth(int dev_id, int argc, char **argv)
{
struct hci_conn_info_req *cr;
bdaddr_t bdaddr;
int opt, dd;
for_each_opt(opt, auth_options, NULL) {
switch (opt) {
default:
printf("%s", auth_help);
return;
}
}
helper_arg(1, 1, &argc, &argv, auth_help);
str2ba(argv[0], &bdaddr);
if (dev_id < 0) {
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
if (dev_id < 0) {
fprintf(stderr, "Not connected.\n");
exit(1);
}
}
dd = hci_open_dev(dev_id);
if (dd < 0) {
perror("HCI device open failed");
exit(1);
}
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
if (!cr) {
perror("Can't allocate memory");
exit(1);
}
bacpy(&cr->bdaddr, &bdaddr);
cr->type = ACL_LINK;
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
perror("Get connection info failed");
exit(1);
}
if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000) < 0) {
perror("HCI authentication request failed");
exit(1);
}
free(cr);
hci_close_dev(dd);
}
并设置PIN
/* Activate encryption */
static void cmd_enc(int dev_id, int argc, char **argv)
{
struct hci_conn_info_req *cr;
bdaddr_t bdaddr;
uint8_t encrypt;
int opt, dd;
for_each_opt(opt, enc_options, NULL) {
switch (opt) {
default:
printf("%s", enc_help);
return;
}
}
helper_arg(1, 2, &argc, &argv, enc_help);
str2ba(argv[0], &bdaddr);
if (dev_id < 0) {
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
if (dev_id < 0) {
fprintf(stderr, "Not connected.\n");
exit(1);
}
}
dd = hci_open_dev(dev_id);
if (dd < 0) {
perror("HCI device open failed");
exit(1);
}
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
if (!cr) {
perror("Can't allocate memory");
exit(1);
}
bacpy(&cr->bdaddr, &bdaddr);
cr->type = ACL_LINK;
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
perror("Get connection info failed");
exit(1);
}
encrypt = (argc > 1) ? atoi(argv[1]) : 1;
if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), encrypt, 25000) < 0) {
perror("HCI set encryption request failed");
exit(1);
}
free(cr);
hci_close_dev(dd);
}
答案 1 :(得分:3)
您可以在此处下载最新版本的源代码:http://www.bluez.org/ 有工具“btmgmt”以及可用于配对的bluez-simple-agent。代码全部在源代码中,还有一些文档(在docs文件夹中)。也许您可以根据自己的需要使用其中一种工具的代码,或者它可以帮助您理解配对。
我想首先将2个设备与bluez蓝牙库配对,但我发现在bluez-tools的源代码中找到有用的代码。 文件“btmgmt.c”和包含在其中的一些文件实现了配对。
对我来说不幸的是它不起作用,我无法理解为什么。但也许你有更多的成功。以下是测试方法。
如果您还没有,请在此处下载最新版本的源代码:http://www.bluez.org/ 解压缩并打开bluez文件夹中的终端。
然后在终端中运行以下命令:
./configure --prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--enable-tools \
--disable-test \
--disable-systemd
我不记得您需要安装的所有软件包但是您可以运行此命令并检查它失败的原因,然后安装软件包并重新运行它直到它工作。如果您不知道需要安装哪个软件包,请询问谷歌。 算账:
make
现在您可以从终端切换到tools文件夹并输入./btmgmt以查看如何使用它。 您也可以通过输入“btmgmt”来使用它,无论您的位置如何。
sudo /usr/bin/install -c tools/btmgmt /usr/bin/btmgmt
您需要sudo权限才能使用它。
答案 2 :(得分:0)
此dbus命令可用于启动配对
dbus-send --system --print-reply --dest=org.bluez /org/bluez/1301/hci0 org.bluez.Adapter.CreatePairedDevice string:"XX:XX:XX:XX:XX:XX" objpath:/org/bluez/agent_1317 string:"NoInputNoOutput"
这里1301是bluetoothd的进程ID
/ org / bluez / agent_1317是蓝牙配对代理。在bluez / test中作为agent.c提供的bluezagent可以用于此目的。
答案 3 :(得分:0)
我曾经在C / C ++中玩过Bluez。据我了解,BlueZ并不真正欢迎用户使用C / C ++接口,它确实更喜欢python。
因此,主要思想是查看目录/ tools中的BlueZ存储库,该目录在C中实现了一些必需的功能。
此外,您还可以看一下这篇文章,该文章显示了从纯C语言使用BlueZ的一些可能性:https://people.csail.mit.edu/albert/bluez-intro/c404.html
这是我想出的(基于hcidump): https://github.com/IGR2014/Alsa-BlueZ-Example(受https://github.com/pauloborges/bluez,https://git.kernel.org/pub/scm/bluetooth/bluez.git启发)
连接功能可能实现的小示例:
// Connect to device
bool btCore::connect(const char* address) {
std::cout << "Connecting to device\t" << address << " ..." << std::endl;
std::cout << std::endl;
uint16_t handle;
unsigned int ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5;
char addr[19] = {0};
bdaddr_t bdaddr;
str2ba(address, &bdaddr);
// Open local HCI device
int sk = hci_open_dev(dev_id);
if (sk < 0) {
std::cerr << "HCI open device:\t\t" << strerror(errno) << std::endl;
return false;
}
// Establish HCI connection with device
if (hci_create_connection(sk, &bdaddr, htobs(ptype), 0, 0, &handle, 0) < 0) {
std::cerr << "HCI create connection:\t" << strerror(errno) << std::endl;
close(sk);
return false;
} else {
std::cout << "Connection:\t\tOK" << std::endl;
}
// Authenticate HCI link (without pin)
if (hci_authenticate_link(sk, handle, 0) < 0) {
std::cerr << "HCI authenticate connection:\t" << strerror(errno) << std::endl;
close(sk);
return false;
} else {
std::cout << "Authentication:\t\tOK" << std::endl;
}
// Encrypt HCI link
if (hci_encrypt_link(sk, handle, 1, 0) < 0) {
std::cerr << "HCI encrypt connection:\t" << strerror(errno) << std::endl;
close(sk);
return false;
} else {
std::cout << "Encryption:\t\tOK" << std::endl;
}
close(sk);
return true;
}
接下来要做的就是发现服务(https://www.bluetooth.com/specifications/assigned-numbers/service-discovery)
这也是我的老问题,可以使您回答:C++ Bluetooth headphones under Linux over BlueZ
请注意:不能保证所有API(如果我们可以将这些内部函数命名为“ API”)都与其他版本的BlueZ相同。至少,对这种行为没有任何保证。