最近在安装ubuntu+Windows双系统后,电脑连接蓝牙出现了问题,每次切换系统之后都要把原来储存的蓝牙信息删除才能再次连接。
这是因为蓝牙设备的配对信息存储在操作系统中。当从一个系统(如 Windows)切换到另一个系统( Ubuntu)时,设备识别到配对信息不一致,导致连接失败。
想要解决这个问题有两种方法,一种是在ubuntu系统中把蓝牙设备的信息改成和Windows中的一样,第二种是在Windows中把信息改成和ubuntu的一样。
由于懒得改Windows的注册表,所以选择第一种方法。
提前准备
- 进入你的ubuntu系统,将蓝牙设备与 Linux 系统进行配对, 留下设备信息, 完成后重启系统引导至 Windows
- 将蓝牙设备与 Windows 系统进行配对, 留下设备信息。
获取 Windows 下蓝牙设备信息
- 在微软官方文档网站下载 PsExec. 我们可以使用这个工具来获得Windows注册表内的蓝牙设备信息
- 解压 PSTools.zip 压缩包至合适目录下
- 以管理员身份打开终端并进入这个目录。比如你解压到了
C:\Program Files\PSTools
bash
c:
cd C:\Program Files\PSTools
- 输入如下命令,将注册表内有关信息导出保存到 C:\BTKeys.reg 中
因为Windows终端默认不会从当前位置加载命令,所以加上.\
表示信任此命令。
bash
.\psexec -s -i regedit /e C:\BTKeys.reg HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys
- 复制 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
这里列举了几个常用的文本编辑器。
- 使用 vim
vim info- 使用 gedit
gedit info- 使用 code(VS Code)
code info- 使用 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