重启Usb蓝牙设备(PD虚拟机模拟插拔)

版权声明:本文为博主原创文章,转载请注明出处。

前言

小米pro的Hackintosh方案挺香的,用了也有8个月了,还是挺稳定的。

但是其中有两个很操蛋的问题:

  • 内置蓝牙无法使用
  • 无法驱动内置Wi-Fi

由于不想硬改,作出一些不可逆操作,所以以上问题均采用USB方案解决。

  • Wi-Fi解决方案也比较完美了,使用Comfast的CF-811AC可支持5G网络,搭配GitHub上的驱动使用,效果极佳。

  • 蓝牙,当时随便在淘宝买了个比较mini的USB蓝牙(加搜黑苹果关键字),倒是能用,但睡眠唤醒(设备断电)之后(手动关闭亦是如此),会导致无法使用,但如果重新插拔就又能正常使用了。(可能是驱动问题)

所以为了让蓝牙正常的工作,而又不希望每次都进行物理插拔(一点都不geek),就诞生了现在的想法:

  • 使用虚拟机模拟插拔!

正文

首先是会导致蓝牙翻车的情况有:

  • 长时间的睡眠唤醒
  • 手动关闭蓝牙(无法再打开)

睡眠唤醒的话,直接模拟插拔就OK。

而手动关闭蓝牙,会在重新插上的时候,系统会根据之前关闭的状态再一次把蓝牙设备关闭(关闭就翻车了),形成了死循环。

所以这时需要在系统里,将蓝牙开关打开;

可以使用blueutil(终端下的蓝牙工具)进行打开操作。(拒绝手动操作)

模拟插拔使用PD虚拟机,其SDK极其完善。(在.app/Contents/MacOS内的命令行工具)

代码

shell脚本的语法十分诡异,查了好久才能写出个判断、循环语句。(???)

  • 将以上所有内容结合,最后得出以下结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/bash

# 设置变量
program="/Applications/Parallels Desktop.app/Contents/MacOS/prlctl"
vm="Windows 10"
device="CSR8510 A10"
vm_app="$HOME/Parallels/$vm.pvm/$vm.app"

# 重置蓝牙开关(后台运行以缩短时间)
{
/usr/local/bin/blueutil -p 0 2> /dev/null
/usr/local/bin/blueutil -p 1 2> /dev/null
} &

# 等待PD启动
start=false
while true; do
status_content=$("$program" status "$vm" 2>&1)
if [[ "$status_content" =~ "Unable to connect to Parallels Service" ]]; then
if [ !$start ]; then
start=true
open "$vm_app"
fi
echo "Waiting PD Service Start..."
sleep 0.5
elif [[ "$status_content" =~ "$vm" ]]; then
break
fi
done

# 获取VM状态
echo $status_content
status=$(echo "$status_content"|awk '{print $NF}')

[ "$status" == "suspended" -o "$status" == "stopped" -o "$status" == "paused" ]
need_resume=$?

# 开启VM
if [ $need_resume -eq 0 ]; then
"$program" resume "$vm" 2> /dev/null
fi

while true; do
status_content=$("$program" status "$vm" 2>&1)
if [[ "$status_content" =~ "resuming" ]]; then
echo "Waiting VM Resuming..."
sleep 0.5
elif [[ "$status_content" =~ "running" ]]; then
break
fi
done

# 模拟USB插拔
"$program" set "$vm" --device-connect "$device"
"$program" set "$vm" --device-disconnect "$device"

# 根据操作前状态决定是否暂停VM
if [ $need_resume -eq 0 ]; then
"$program" pause "$vm"
fi
# macos
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×