You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派RFCOMM蓝牙服务器GUI配对失败问题求助

问题:无桌面Ubuntu树莓派BlueZ RFCOMM服务器无法通过GUI配对连接

当前现象

  • 树莓派在手机/PC的设备列表中可见,但通过GUI尝试配对时失败
  • 仅能通过PC手动指定MAC地址执行rfcomm命令成功连接,操作示例:
# Pi端运行服务器
$ ./bluetooth_server
Waiting for Bluetooth connections on RFCOMM channel 1...

# PC端手动连接
➜  ~ sudo rfcomm connect 0 B2:25:EB:16:BC:09 1
Connected /dev/rfcomm0 to B2:25:EB:16:BC:09 on channel 1

核心需求

如何启用基于GUI的配对与连接,让手机/PC无需手动指定MAC地址即可无缝连接到Serial Port服务?

服务器代码

int main() 
{
    struct sockaddr_rc loc_addr = { 0 }; // 树莓派服务器地址
    struct sockaddr_rc rem_addr = { 0 }; // 客户端地址
    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("Failed to create socket");
        exit(1);
    }

    loc_addr.rc_family = AF_BLUETOOTH;
    loc_addr.rc_bdaddr = *BDADDR_ANY; // 绑定所有蓝牙地址
    loc_addr.rc_channel = (uint8_t) 1;  // 使用RFCOMM通道1

    if (bind(socket_descriptor, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0) {
        perror("Failed to bind socket");
        close(socket_descriptor);
        exit(1);
    }

    listen(socket_descriptor, 1);
    printf("Waiting for Bluetooth connections on RFCOMM channel 1...\n");

    client_descriptor = accept(socket_descriptor, (struct sockaddr *)&rem_addr, &opt);
    if (client_descriptor < 0) {
        perror("Failed to accept connection");
        close(socket_descriptor);
        exit(1);
    }

    char client_addr[18] = { 0 };
    ba2str(&rem_addr.rc_bdaddr, client_addr);
    printf("Accepted connection from %s\n", client_addr);

    const char *welcome_message = "Welcome to Raspberry Pi Bluetooth Server!\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("Received: %s\n", buf);

            write(client_descriptor, buf, (size_t)bytes_read);
        } else if (bytes_read < 0) {
            perror("Failed to read from client");
            break;
        }
    }

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

当前配置信息

hciconfig输出

$ hciconfig
hci0:   Type: Primary  Bus: UART
    BD Address: B8:27:EB:16:BC:06  ACL MTU: 1021:8  SCO MTU: 64:1
    UP RUNNING PSCAN ISCAN
    RX bytes:83994 acl:4189 sco:0 events:2388 errors:0
    TX bytes:61466 acl:4071 sco:0 commands:279 errors:0

bluetoothctl操作记录

$ bluetoothctl
Agent registered
[CHG] Controller B8:27:EB:16:BC:06 Pairable: yes
[bluetooth]# agent on
Agent is already registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# discoverable on
Changing discoverable on succeeded
[bluetooth]# pairable on
[bluetooth]# quit

Bluetooth服务状态

$ sudo systemctl status bluetooth
● bluetooth.service - Bluetooth service
     Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2024-12-22 22:30:04 UTC; 9s ago
       Docs: man:bluetoothd(8)
   Main PID: 2639 (bluetoothd)
     Status: "Running"
      Tasks: 1 (limit: 961)
     Memory: 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]: Ignoring (cli) avrcp
Dec 22 22:30:04 matan bluetoothd[2639]: Ignoring (cli) network
Dec 22 22:30:04 matan bluetoothd[2639]: Ignoring (cli) input
Dec 22 22:30:04 matan bluetoothd[2639]: Ignoring (cli) hog
Dec 22 22:30:04 matan bluetoothd[2639]: Ignoring (cli) gap
Dec 22 22:30:04 matan bluetoothd[2639]: Ignoring (cli) scanparam
Dec 22 22:30:04 matan bluetoothd[2639]: Ignoring (cli) deviceinfo
Dec 22 22:30:04 matan bluetoothd[2639]: Ignoring (cli) battery
Dec 22 22:30:04 matan bluetoothd[2639]: Ignoring (cli) sixaxis
Dec 22 22:30:04 matan bluetoothd[2639]: Bluetooth management interface 1.21 initialized

已尝试操作

  • 使用sdptool add SP添加Serial Port(SP)服务
  • 设置树莓派为可发现、可配对状态
  • 验证RFCOMM服务器正在运行并监听Channel 1

解决方案

1. 持久化注册SDP服务

sdptool add SP是临时注册,重启后会失效,需配置持久化服务:

  • 创建SDP配置文件/etc/bluetooth/sdp.conf,添加内容:
service SerialPort
{
    name "Serial Port";
    description "Raspberry Pi RFCOMM Serial Port Service";
    provider "BlueZ";
    rfcomm channel 1;
    protocol RFCOMM;
}
  • 重启蓝牙服务:sudo systemctl restart bluetooth
  • 验证注册:sdptool browse local,确认能看到Serial Port服务

2. 调整bluetoothd启动参数

当前--plugin=simple-agent --compat参数存在兼容性问题,修改服务配置:

  • 编辑/lib/systemd/system/bluetooth.service,将ExecStart行改为:
ExecStart=/usr/lib/bluetooth/bluetoothd -C --noplugin=avrcp,network,input,hog,gap,scanparam,deviceinfo,battery,sixaxis
  • 重新加载配置并重启:
sudo systemctl daemon-reload
sudo systemctl restart bluetooth

3. 配置无桌面环境的配对代理

在bluetoothctl中设置适配无桌面的代理:

bluetoothctl
agent NoInputNoOutput  # 无需输入输出的代理模式
default-agent
discoverable on
pairable on
save  # 保存配置
quit

4. 给服务器程序添加权限

无桌面环境下普通用户可能缺少蓝牙权限,可执行以下操作:

sudo setcap cap_net_raw,cap_net_admin+eip ./bluetooth_server

5. 测试GUI配对

完成以上配置后:

  • 重启树莓派
  • 启动RFCOMM服务器
  • 在手机/PC的蓝牙设置中找到树莓派,尝试配对连接,此时应能自动识别并连接到Serial Port服务

内容的提问来源于stack exchange,提问作者MatanCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 10:59:59