BlueZ Bluetoothライブラリを使用してCで記述されたプログラムで、Linux上のBluetoothデバイスをペアリングする方法に関するリファレンスが見つかりません。私はすでにHCIレベルのクエリを実行して、RSSIレベルと一緒にデバイスを取得しました(デバイスの検出中)が、現在はこれで立ち往生しています。 blueZ-simple-agentにDBUSAPIを使用するという提案を見ましたが、これを回避してBlueZのいくつかの経営幹部レベルのメソッドを使用する方法はありますか?
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フォルダーに)。たぶん、あなたはあなたの欲望のためにこれらのツールの1つのコードを使うことができます、あるいはそれはあなたがペアリングを理解するのを助けるかもしれません。
そもそも2台のデバイスをbluezbluetoothライブラリとペアリングしたいのですが、bluez-toolsのソースで役立つコードを見つけました。ファイル「btmgmt.c」とそれに含まれるペアリングを実装するいくつかのファイルがあります。
残念ながら、それは機能しておらず、その理由がわかりません。しかし、多分あなたはそれでより多くの成功を収めています。これがあなたがそれをテストする方法です。
まだダウンロードしていない場合は、ここから最新バージョンのソースコードをダウンロードします。 http://www.bluez.org/ 解凍して、bluezフォルダーでターミナルを開きます。
次に、ターミナルで以下を実行します。
./configure --prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--enable-tools \
--disable-test \
--disable-systemd
インストールする必要のあるすべてのパッケージを覚えているわけではありませんが、このコマンドを実行して失敗する理由を確認してから、パッケージをインストールして、機能するまで再実行できます。インストールする必要のあるパッケージがわからない場合は、Googleに問い合わせてください。その後:
make
これで、ターミナルからツールフォルダーに切り替えて、。/ btmgmtと入力し、使用方法を確認できます。また、場所に関係なく「btmgmt」と入力するだけで使用できるようにインストールすることもできます。
Sudo /usr/bin/install -c tools/btmgmt /usr/bin/btmgmt
使用するにはSudoの権限が必要です。
私はC/C++でBluezをいじっていました。私が理解できる限り、C/C++インターフェースは、BlueZではユーザーにとって実際には歓迎されていません。Pythonを好みます。
したがって、主なアイデアは、Cで必要な機能のいくつかを実装するディレクトリ/ toolsにあるBlueZリポジトリを確認することです。
また、プレーンCからのBlueZの使用のいくつかの可能性を示すこの記事を見ることができます: https://people.csail.mit.edu/albert/bluez-intro/c404.html
これが私が思いついたものです(hcidumpに基づいて): https://github.com/IGR2014/Alsa-BlueZ-Example (inspired by 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 overBlueZでの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は、この目的に使用できます。