[英]Bluetooth pairing in C blueZ on Linux
在使用BlueZ藍牙庫以C語言編寫的程序中,我找不到如何在Linux上配對藍牙設備的任何參考。 我已經設法進行了HCI級別查詢,以使設備與RSSI級別一起(在設備發現過程中),但是目前我對此感到困惑。 我看到了將DBUS api用於blueZ-simple-agent的建議-但是有什么方法可以避免這種情況,而只是使用BlueZ中的一些C級方法?
來自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);
}
您可以在此處下載源代碼的最新版本: 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
我不記得您需要安裝所有軟件包,但是您可以運行此命令並檢查其失敗原因,然后安裝該軟件包並重新運行,直到它起作用為止。 向Google詢問是否不知道需要安裝哪個軟件包。 然后:
make
現在,您可以從終端切換到tools文件夾,然后鍵入./btmgmt來查看如何使用它。 您也可以通過鍵入“ btmgmt”來安裝它以使用它,而無論您身在何處。
sudo /usr/bin/install -c tools/btmgmt /usr/bin/btmgmt
您需要使用sudo權限才能使用它。
此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是藍牙的進程ID
/ org / bluez / agent_1317是藍牙配對代理。bluez/ test中作為agent.c出現的bluezagent可以用於此目的。
我曾經在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 )
這也是我的老問題,可能會導致您回答: Linux over BlueZ下的C ++藍牙耳機
請注意:不能保證所有API(如果可以將這些內部函數命名為“ API”)都與其他版本的BlueZ相同。 至少,對於這種行為沒有任何保證。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.