树莓派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
相关产品推荐
相关产品推荐

