Не удается подключиться к серверу Bluetooth RFCOMM на Raspberry Pi

Вопрос или проблема

Я запускаю сервер Bluetooth RFCOMM на своем Raspberry Pi (безголовый Ubuntu) с использованием стека BlueZ. Моя цель — позволить смартфону или ПК подключаться к Raspberry Pi через GUI (например, из настроек Bluetooth) и обеспечить последовательную связь с использованием виртуального последовательного порта.

Текущая проблема:
Raspberry Pi виден в списке устройств на смартфоне/ПК.
Парирование не удается при попытке подключиться через GUI.
Единственный способ, которым я могу успешно подключиться, — это вручную указать MAC-адрес и использовать rfcomm с ПК:

    Pi:
    $ ./bluetooth_server
    Ожидание Bluetooth-соединений на канале RFCOMM 1...

    ПК:
    ➜  ~ sudo rfcomm connect 0 B2:25:EB:16:BC:09 1
    Подключено /dev/rfcomm0 к B2:25:EB:16:BC:09 на канале 1

Вопрос:
Как я могу включить парирование и подключение на основе GUI, позволяя смартфону или ПК бесшовно подключаться к службе последовательного порта без ручного указания MAC-адреса?

Код:

int main() 
{
    struct sockaddr_rc loc_addr = { 0 }; // сервер (rpi)
    struct sockaddr_rc rem_addr = { 0 }; // клиент (pc)
    socklen_t opt = sizeof(rem_addr);
    char buf[1024] = { 0 };
    int socket_descriptor = 0; 
    int client_descriptor = 0; 
    int bytes_read = 0;

    socket_descriptor = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
    if (socket_descriptor < 0) {
        perror("Не удалось создать сокет");
        exit(1);
    }

    loc_addr.rc_family = AF_BLUETOOTH;
    loc_addr.rc_bdaddr = *BDADDR_ANY; // без специфического mac_add
    loc_addr.rc_channel = (uint8_t) 1;  // канал 1

    if (bind(socket_descriptor, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0) {
        perror("Не удалось привязать сокет");
        close(socket_descriptor);
        exit(1);
    }

    listen(socket_descriptor, 1);
    printf("Ожидание Bluetooth-соединений на канале RFCOMM 1...\n");

    client_descriptor = accept(socket_descriptor, (struct sockaddr *)&rem_addr, &opt);
    if (client_descriptor < 0) {
        perror("Не удалось принять соединение");
        close(socket_descriptor);
        exit(1);
    }

    char client_addr[18] = { 0 };
    ba2str(&rem_addr.rc_bdaddr, client_addr);
    printf("Принимаем соединение от %s\n", client_addr);

    const char *welcome_message = "Добро пожаловать на сервер Bluetooth Raspberry Pi!\r\n";
    write(client_descriptor, welcome_message, strlen(welcome_message));

    while (1) {
        memset(buf, 0, sizeof(buf));
        bytes_read = (int)read(client_descriptor, buf, sizeof(buf) - 1);
        if (bytes_read > 0) {
            buf[bytes_read] = '\0'; 
            printf("Получено: %s\n", buf);

            write(client_descriptor, buf, (size_t)bytes_read);
        } else if (bytes_read < 0) {
            perror("Не удалось прочитать от клиента");
            break;
        }
    }

    close(client_descriptor);
    close(socket_descriptor);
    return 0;
}

Кроме того, у меня есть следующая конфигурация:

$ hciconfig
hci0:   Тип: Первичный  Шина: UART
    BD Адрес: B8:27:EB:16:BC:06  ACL MTU: 1021:8  SCO MTU: 64:1
    **Включен работающий PSCAN ISCAN**
    RX байты:83994 acl:4189 sco:0 события:2388 ошибки:0
    TX байты:61466 acl:4071 sco:0 команды:279 ошибки:0

$ bluetoothctl
Агент зарегистрирован
[CHG] Контроллер B8:27:EB:16:BC:06 Парируемый: да
[bluetooth]# агент включен
Агент уже зарегистрирован
[bluetooth]# агент по умолчанию
Запрос агента по умолчанию выполнен
[bluetooth]# обнаружимый включен
Успех изменения обнаружимости
[bluetooth]# парируемый включен
[bluetooth]# выйти

$ sudo systemctl status bluetooth
● bluetooth.service - Служба Bluetooth
     Загружен: загружен (/lib/systemd/system/bluetooth.service; включено; предустановка поставщика: включено)
     Активен: активен (работает) с вс 2024-12-22 22:30:04 UTC; 9с назад
       Документы: man:bluetoothd(8)
   Главный PID: 2639 (bluetoothd)
     **Статус: "Работает"**
      Задачи: 1 (лимит: 961)
     Память: 624.0K
        CPU: 276ms
     CGroup: /system.slice/bluetooth.service
             **└─2639 /usr/lib/bluetooth/bluetoothd --plugin=simple-agent --compat**

Dec 22 22:30:04 matan bluetoothd[2639]: Игнорирование (cli) avrcp
Dec 22 22:30:04 matan bluetoothd[2639]: Игнорирование (cli) network
Dec 22 22:30:04 matan bluetoothd[2639]: Игнорирование (cli) input
Dec 22 22:30:04 matan bluetoothd[2639]: Игнорирование (cli) hog
Dec 22 22:30:04 matan bluetoothd[2639]: Игнорирование (cli) gap
Dec 22 22:30:04 matan bluetoothd[2639]: Игнорирование (cli) scanparam
Dec 22 22:30:04 matan bluetoothd[2639]: Игнорирование (cli) deviceinfo
Dec 22 22:30:04 matan bluetoothd[2639]: Игнорирование (cli) battery
Dec 22 22:30:04 matan bluetoothd[2639]: Игнорирование (cli) sixaxis
Dec 22 22:30:04 matan bluetoothd[2639]: Bluetooth интерфейс управления 1.21 инициализирован

Что я пробовал:
Добавил службу последовательного порта (SP) с помощью sdptool add SP.
Сделал Raspberry Pi обнаружимым и парируемым.
Проверил, что сервер RFCOMM работает и слушает на канале 1.
Любая помощь по включению автоматического парирования и подключения для взаимодействия на основе GUI будет очень признательна! Спасибо!

Ответ или решение

Решение проблемы с подключением к Bluetooth RFCOMM-серверу на Raspberry Pi

Введение

Ваша цель - настроить Bluetooth-сервер на Raspberry Pi, чтобы устройства, такие как смартфоны и ПК, могли легко подключаться к нему через графический интерфейс. Основная проблема заключается в том, что хотя устройство видно в списке Bluetooth, попытки подключения через GUI завершаются неудачно, и требуется ручной ввод MAC-адреса для успешного подключения. В данном руководстве мы обсудим ключевые шаги и рекомендации для решения этой проблемы.

Шаг 1: Подготовка окружения

Для начала необходимо убедиться, что ваше окружение настроено корректно. Вы уже проверили, что служба Bluetooth активна и работает:

$ sudo systemctl status bluetooth

Это подтверждает, что Bluetooth-демон (bluetoothd) активен и выполняется без ошибок. Также стоит убедиться, что Raspberry Pi обнаружим и может принимать соединения:

$ bluetoothctl
[bluetooth]# discoverable on
[bluetooth]# pairable on

Шаг 2: Настройка SDP (Service Discovery Protocol)

Чтобы устройства могли автоматически находить ваш сервер Bluetooth, необходимо убедиться, что служба, предоставляющая виртуальный последовательный порт (Serial Port Profile, SPP), правильно настроена. Вы уже использовали команду sdptool для добавления профиля SP:

$ sdptool add SP

Шаг 3: Параметры безопасности

Один из наиболее распространенных сценариев, по которому могут возникать проблемы с парой Bluetooth, касается параметров безопасности. Убедитесь, что на вашем Raspberry Pi нет настроек, блокирующих автоматическое соединение. Проверьте файл конфигурации main.conf, который обычно находится по пути /etc/bluetooth/main.conf. В этом файле установите следующие параметры:

[General]
Class = 0x000000
Discoverable = true
Pairable = true

Обратите внимание на то, что опции Discoverable и Pairable должны быть выставлены на true.

Шаг 4: Повторная настройка Bluetooth-агента

Стоит убедиться, что установленный Bluetooth-агент правильно обрабатывает запросы на подключение. Запустите bluetoothd с плагином агента, если это еще не сделано:

sudo bluetoothd --plugin=simple-agent --compat

Затем вернитесь в bluetoothctl и проверьте, зарегистрирован ли агент:

$ bluetoothctl
[bluetooth]# agent on
[bluetooth]# default-agent

Эти команды позволяют вашему устройству автоматически обрабатывать запросы на соединение и учетные данные для пары.

Шаг 5: Тестирование подключения

После настройки всех ранее указанных параметров попробуйте выполнить подключение с устройства (смартфона или ПК) снова через графический интерфейс. Сначала удалите предыдущие пары, чтобы избежать конфликтов:

На Android: Настройки → Bluetooth → Удалить устройства.
На Windows: Настройки → Устройства → Удалить.

После этого снова выполните поиск устройства на вашем смартфоне или ПК, он должен отображаться правильно, и возможность подключения через графический интерфейс должна сработать.

Заключение

В успешной настройке Bluetooth RFCOMM-сервера для Raspberry Pi важно следовать всем упомянутым шагам и внимательно проверять параметры конфигурации. Параметры безопасности, корректная регистрация сервиса и активные плагины играют ключевую роль в обеспечении неполадки подключения. Если вы следовали всем шагам, ваше устройство должно успешно подключаться без необходимости вручную вводить MAC-адрес.

Если проблема все еще сохраняется, возможно, стоит рассмотреть обновление стека BlueZ до последней версии или дальнейшую диагностику с использованием инструментов отладки Bluetooth, таких как hcitool и hcidump, чтобы увидеть, какие пакеты отправляются и принимаются.

Оцените материал
Добавить комментарий

Капча загружается...