BlueZ Bluetooth ライブラリを使用して C で記述されたプログラムで、Linux で Bluetooth デバイスをペアリングする方法に関する参照が見つかりません。HCI レベルのクエリを実行して、(デバイスの検出中に) RSSI レベルと共にデバイスを取得することはできましたが、現在はこれに固執しています。blueZ-simple-agent に DBUS API を使用するという提案を見ましたが、これを回避して BlueZ の C レベル メソッドを使用する方法はありますか?
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);
}
C/C++ で Bluez をいじっていました。私が理解できる限り、BlueZ では C/C++ インターフェイスはユーザーにとってあまり歓迎されていません。Python の方が好まれます。
したがって、主なアイデアは、C で必要な機能の一部を実装しているディレクトリ /tools にある BlueZ リポジトリを確認することです。
また、プレーン 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 関数の可能な実装の小さな例:
// 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 )
また、ここにあなたが答えることができる私の古い質問があります:BlueZ上のLinuxでのC ++ Bluetoothヘッドフォン
注: すべての API (これらの内部関数を「API」と名付けることができる場合) は、他のバージョンの BlueZ と同じであるとは限りません。少なくとも、そのような動作の保証はありません。
この 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 は bluetooth ペアリング エージェントです。bluez/test の agent.c として提供される bluezagent をこの目的で使用できます。