ubuntu+windows双系统切换后蓝牙设备无法连接

最近在安装ubuntu+Windows双系统后,电脑连接蓝牙出现了问题,每次切换系统之后都要把原来储存的蓝牙信息删除才能再次连接。

这是因为蓝牙设备的配对信息存储在操作系统中。当从一个系统(如 Windows)切换到另一个系统( Ubuntu)时,设备识别到配对信息不一致,导致连接失败。

想要解决这个问题有两种方法,一种是在ubuntu系统中把蓝牙设备的信息改成和Windows中的一样,第二种是在Windows中把信息改成和ubuntu的一样。

由于懒得改Windows的注册表,所以选择第一种方法。

提前准备

  1. 进入你的ubuntu系统,将蓝牙设备与 Linux 系统进行配对, 留下设备信息, 完成后重启系统引导至 Windows
  2. 将蓝牙设备与 Windows 系统进行配对, 留下设备信息。

获取 Windows 下蓝牙设备信息

  1. 微软官方文档网站下载 PsExec. 我们可以使用这个工具来获得Windows注册表内的蓝牙设备信息
  2. 解压 PSTools.zip 压缩包至合适目录下
  3. 以管理员身份打开终端并进入这个目录。比如你解压到了C:\Program Files\PSTools
bash 复制代码
c:
cd C:\Program Files\PSTools
  1. 输入如下命令,将注册表内有关信息导出保存到 C:\BTKeys.reg 中
    因为Windows终端默认不会从当前位置加载命令,所以加上.\表示信任此命令。
bash 复制代码
.\psexec -s -i regedit /e C:\BTKeys.reg HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys
  1. 复制 C:\BTKeys.reg 到 ubuntu分区 或 U盘 内,当然也能在ubuntu中挂载C盘,反正确保你在ubuntu系统中能够读取到这个文件即可

在ubuntu中修改蓝牙配置

Windows的BTKeys.reg格式

用任意文本编辑器打开BTKeys.reg 文件,会看到里面的格式类似这样,具体参数会不一样。

bash 复制代码
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys]


[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\ffffffffffff]

"MasterIRK"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\ffffffffffff\00000000000]

"LTK"=hex:f3,13,02,86,20,9d,04,12,c0,1e,8e,cb,fb,e9,04,1b

"KeyLength"=dword:00000010

"ERand"=hex(b):18,57,93,eb,5f,b2,15,2e

"EDIV"=dword:0000ecb0

"IRK"=hex:a0,8d,5a,98,34,41,31,3f,00,72,c9,f8,95,5f,fa,d5

"Address"=hex(b):27,d5,bb,fc,5a,eb,00,00

"AddressType"=dword:00000001

"CSRK"=hex:bc,70,a8,79,7c,35,9e,9a,3f,0d,d7,f7,70,64,44,a4

"OutboundSignCounter"=dword:00000000

"MasterIRKStatus"=dword:00000001

"AuthReq"=dword:0000002d



[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\ffffffffffff\1111111111111]

"LTK"=hex:88,0f,f4,8d,11,db,33,28,36,54,06,cd,a6,27,a2,64

"KeyLength"=dword:00000010

"ERand"=hex(b):38,bb,05,08,11,91,f1,8b

"EDIV"=dword:0000882b

"MasterIRKStatus"=dword:00000001

"AuthReq"=dword:0000002d

从含有中括号 [ ] 的行至下一个含有中括号 [ ] 的行前是一个蓝牙设备的配置信息

如:

第 9 行 [ ...\Keys\ffffffffffff] 的 ffffffffffff 就是该主机蓝牙控制器的十六位地址

第 15 行 [ ...\Keys\ffffffffffff\000000000000] 的 000000000000 就是一个蓝牙设备的十六位地址,至第 40 行是该设备的配置信息

第 41 行 [ ...\Keys\ffffffffffff\1111111111111] 的 1111111111111 就是另一个蓝牙设备的十六位地址,至第 53 行是该设备的配置信息

Linux 下设备蓝牙信息

在任意位置打开 ubuntu 的终端,进入管理员权限

bash 复制代码
sudo su

键入命令(以 root 用户身份),进入蓝牙信息的目录,并查看里面的文件夹。

bash 复制代码
cd /var/lib/bluetooth/
ls

会看到一个地址

FF:FF:FF:FF:FF:FF // 该文件夹名称对应之前获取的该主机蓝牙控制器的十六位地址

进入这个目录(小技巧,在cd后面按Tab键会自动帮你填好),再输入ls查看

bash 复制代码
cd FF:FF:FF:FF:FF:FF

假如这两个蓝牙设备都在你的ubuntu上连接过的话,会出现这样的信息,

00:00:00:00:00:01 11:11:11:11:11:12是两个蓝牙设备的信息,具体数字因人而异,如果你只连过一个设备的话,就只有一个地址。

00:00:00:00:00:01 11:11:11:11:11:12 cache settings

文件夹 00:00:00:00:00:01 和 11:11:11:11:11:12 则是 Linux 下两个蓝牙设备的十六位地址(和Windows的数有一位数字的偏差)

修改蓝牙配置文件夹名称

我们需要将两个文件夹的名称改为 Windows 下同一设备的地址,比如同一个设备在Windows上是00:00:00:00:00:00,在ubuntu上是00:00:00:00:00:01,则把ubuntu上的文件夹名更改。

再ls查看是否更改成功。

bash 复制代码
mv 00:00:00:00:00:01 00:00:00:00:00:00
ls

进入这个改好的目录,并使用任意文本编辑器打开里面的info文件

bash 复制代码
cd 00:00:00:00:00:00
ls 

这里列举了几个常用的文本编辑器。

  1. 使用 vim
    vim info
  2. 使用 gedit
    gedit info
  3. 使用 code(VS Code)
    code info
  4. 使用 subl(Sublime Text)
    subl info

打开后能看到这样格式的代码(比Windows的好看很多(bushi))

bash 复制代码
[General]
Name=Ergonomic Keyboard
Appearance=0x03c1
AddressType=static
SupportedTechnologies=LE;
Trusted=true
Blocked=false
WakeAllowed=true
Services=00001800-0000-1000-8000-00805f9b34fb;00001801-0000-1000-8000-00805f9b34fb;0000180a-0000-1000-8000-00805f9b34fb;0000180f-0000-1000-8000-00805f9b34fb;00001812-0000-1000-8000-00805f9b34fb;
Alias=Ergonomic Keyboard

[ConnectionParameters]
MinInterval=12
MaxInterval=12
Latency=20
Timeout=200

[DeviceID]
Source=2
Vendor=1118
Product=2071
Version=308

[IdentityResolvingKey]
Key=A08D5A983441313F0072C9F8955FFAD5

[LocalSignatureKey]
Key=BC70A8707C359E9A3F0DD7F770444A04
Counter=0
Authenticated=true

[LongTermKey]
Key=F3130286209D0412C01E8ECBFBE9041B
Authenticated=1
EncSize=16
EDiv=60592
Rand=3320756425299547928

配置项中, Linux 下名称和 Windows 下名称对应为

[IdentityResolvingKey] <=> "IRK"

[LocalSignatureKey] <=> "CSRK"

[LongTermKey] <=> "LTK"

EncSize ([LongTermKey]下) <=> "KeyLength"

EDiv ([LongTermKey]下) <=> "EDIV"

Rand ([LongTermKey]下) <=> "ERand"

但是由于二者的进制编码不同,所以需要进行进制转换后才能更改info的信息。

对应数值转换

用终端把 BTKeys.reg 内的数值转换后修改对应 info 文件下的数值

"IRK"项 只保留字母数字,且字母小写转大写

bash 复制代码
echo "a0,8d,5a,98,34,41,31,3f,00,72,c9,f8,95,5f,fa,d5" | tr a-z A-Z | sed "s/[[:punct:]]//g"

"CSRK"项 只保留字母数字,且字母小写转大写

bash 复制代码
echo "bc,70,a8,79,7c,35,9e,9a,3f,0d,d7,f7,70,64,44,a4" | tr a-z A-Z | sed "s/[[:punct:]]//g"

"LTK"项 只保留字母数字,且字母小写转大写

bash 复制代码
echo "f3,13,02,86,20,9d,04,12,c0,1e,8e,cb,fb,e9,04,1b" | tr a-z A-Z | sed "s/[[:punct:]]//g"

"KeyLength"项 只保留数字,且十六进制转十进制

bash 复制代码
echo $((16#00000010))

"EDIV"项 只保留字母数字,且十六进制转十进制

bash 复制代码
echo $((16#0000ecb0))

"ERand"项 只保留字母数字,且以逗号相隔为一组,各组逆序排列后所得十六进制转十进制

bash 复制代码
echo $((16#2e15b25feb935718))

"IRK"的数值需修改 [IdentityResolvingKey] 下一行的 key

同理修改 [LocalSignatureKey] 和 [LongTermKey]

EncSize ,EDIV 和 Rand 找到其对应名称修改即可

若未在 BTKeys.reg 的某一设备中发现某一配置,不用着急,找出其存在的配置即可。因为 Linux 下 info 文件里也不需要该未出现的配置

修改完一个蓝牙设备后记得保存info文件的更改。

如果需要更改多个蓝牙设备的话,进入另外一个目录修改另一个蓝牙设备的 info 文件。

重启蓝牙服务

修改完毕后,重启蓝牙服务,此时蓝牙设备应该能够正常在 Linux 系统下使用且不用重新配对也能够在重启后引导至 Windows 系统下使用

bash 复制代码
sudo systemctl restart bluetooth

参考链接

相关推荐
九鼎科技-Leo9 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
Yang.9911 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
我不瘦但很逗11 小时前
Windows下使用DBeaver连接云数据库(MySQL)
数据库·windows
ashane131412 小时前
Java list
java·windows·list
万里沧海寄云帆12 小时前
Word 插入分节符页码更新问题
windows·microsoft·word
dot.Net安全矩阵13 小时前
.NET 通过模块和驱动收集本地EDR的工具
windows·安全·web安全·.net·交互
编程修仙15 小时前
Collections工具类
linux·windows·python
写点什么啦15 小时前
[debug]不同的window连接ubuntu的vscode后无法正常加载kernel
linux·vscode·ubuntu·debug
wellnw15 小时前
[ubuntu]编译共享内存读取出现read.c:(.text+0x1a): undefined reference to `shm_open‘问题解决方案
linux·ubuntu