├── .github └── workflows │ └── main.yml ├── .gitignore ├── BrcmBluetoothInjector.kext └── Contents │ └── Info.plist ├── BrcmBluetoothInjectorLegacy.kext └── Contents │ └── Info.plist ├── BrcmNonPatchRAM-Info.plist ├── BrcmNonPatchRAM2-Info.plist ├── BrcmPatchRAM.xcodeproj └── project.pbxproj ├── BrcmPatchRAM ├── BlueToolFixup-Info.plist ├── BlueToolFixup.cpp ├── BrcmFirmwareData-Info.plist ├── BrcmFirmwareRepo-Info.plist ├── BrcmFirmwareStore.cpp ├── BrcmFirmwareStore.h ├── BrcmPatchRAM-Info.plist ├── BrcmPatchRAM.cpp ├── BrcmPatchRAM.h ├── BrcmPatchRAM2-Info.plist ├── BrcmPatchRAM3-Info.plist ├── BrcmPatchRAM3.cpp ├── Common.h ├── FirmwareData.cpp ├── FirmwareData.h ├── USBDeviceShim.cpp ├── USBDeviceShim.h ├── USBHostDeviceShim.cpp ├── hci.h └── package.tool ├── Changelog.md ├── LICENSE ├── README-Mac.md ├── README.md ├── README_CN.md ├── extra_firmwares ├── 0a5c_22be │ ├── BrcmFirmwareInjector2_0a5c_22be.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_22be.kext │ │ └── Contents │ │ └── Info.plist └── 0a5c_6412 │ ├── BCM4350C5_003.006.007.0222.4689_v8785.zhx │ ├── BrcmFirmwareInjector2_0a5c_6412.kext │ └── Contents │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_6412.kext │ └── Contents │ └── Info.plist ├── firmware.rb ├── firmware_update.tool ├── firmwares ├── 0489_e032 │ ├── BCM20702A1_001.002.014.1443.1485_v5581.zhx │ ├── BrcmFirmwareInjector2_0489_e032.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e032.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e042 │ ├── BCM20702A1_001.002.014.1443.1484_v5580.zhx │ ├── BrcmFirmwareInjector2_0489_e042.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e042.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e046 │ ├── BCM20702A1_001.002.014.1443.1465_v5561.zhx │ ├── BrcmFirmwareInjector2_0489_e046.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e046.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e047 │ ├── BCM20702A1_001.002.014.1055.1061_v5157.zhx │ ├── BrcmFirmwareInjector2_0489_e047.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e047.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e04f │ ├── BCM20702A1_001.002.014.1443.1486_v5582.zhx │ ├── BrcmFirmwareInjector2_0489_e04f.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e04f.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e052 │ ├── BCM20702A1_001.002.014.1502.1758_v5854.zhx │ ├── BrcmFirmwareInjector2_0489_e052.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e052.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e055 │ ├── BCM43142A0_001.001.011.0311.0331_v4427.zhx │ ├── BrcmFirmwareInjector2_0489_e055.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e055.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e059 │ ├── BCM20702A1_001.002.014.1443.1466_v5562.zhx │ ├── BrcmFirmwareInjector2_0489_e059.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e059.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e062 │ ├── BCM43142A0_001.001.011.0277.0280_v4376.zhx │ ├── BrcmFirmwareInjector2_0489_e062.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e062.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e079 │ ├── BCM4335C0_003.001.009.0066.0115_v4211.zhx │ ├── BrcmFirmwareInjector2_0489_e079.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e079.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e07a │ ├── BCM20702A1_001.002.014.1483.1651_v5747.zhx │ ├── BrcmFirmwareInjector2_0489_e07a.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e07a.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e087 │ ├── BCM20702A1_001.002.014.1443.1532_v5628.zhx │ ├── BrcmFirmwareInjector2_0489_e087.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e087.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e096 │ ├── BCM43142A0_001.001.011.0311.0340_v4436.zhx │ ├── BrcmFirmwareInjector2_0489_e096.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e096.kext │ │ └── Contents │ │ └── Info.plist ├── 0489_e0a1 │ ├── BCM20703A1_001.001.005.0214.0414_v4510.zhx │ ├── BrcmFirmwareInjector2_0489_e0a1.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0489_e0a1.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_2003 │ ├── BCM20702A1_001.002.014.1443.1488_v5584.zhx │ ├── BrcmFirmwareInjector2_04ca_2003.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_2003.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_2004 │ ├── BCM20702A1_001.002.014.1443.1489_v5585.zhx │ ├── BrcmFirmwareInjector2_04ca_2004.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_2004.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_2005 │ ├── BCM20702A1_001.002.014.1443.1490_v5586.zhx │ ├── BrcmFirmwareInjector2_04ca_2005.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_2005.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_2006 │ ├── BCM43142A0_001.001.011.0311.0327_v4423.zhx │ ├── BrcmFirmwareInjector2_04ca_2006.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_2006.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_2007 │ ├── BCM43142A0_001.001.011.0277.0279_v4375.zhx │ ├── BrcmFirmwareInjector2_04ca_2007.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_2007.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_2009 │ ├── BCM43142A0_001.001.011.0311.0330_v4426.zhx │ ├── BrcmFirmwareInjector2_04ca_2009.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_2009.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_200a │ ├── BCM20702A1_001.002.014.1443.1492_v5588.zhx │ ├── BrcmFirmwareInjector2_04ca_200a.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_200a.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_200b │ ├── BCM20702A1_001.002.014.1443.1493_v5589.zhx │ ├── BrcmFirmwareInjector2_04ca_200b.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_200b.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_200c │ ├── BCM20702A1_001.002.014.1443.1494_v5590.zhx │ ├── BrcmFirmwareInjector2_04ca_200c.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_200c.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_200e │ ├── BCM20702A1_001.002.014.1443.1499_v5595.zhx │ ├── BrcmFirmwareInjector2_04ca_200e.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_200e.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_200f │ ├── BCM20702A1_001.002.014.1443.1521_v5617.zhx │ ├── BrcmFirmwareInjector2_04ca_200f.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_200f.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_2012 │ ├── BCM43142A0_001.001.011.0311.0339_v4435.zhx │ ├── BrcmFirmwareInjector2_04ca_2012.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_2012.kext │ │ └── Contents │ │ └── Info.plist ├── 04ca_2016 │ ├── BCM4335C0_003.001.009.0066.0121_v4217.zhx │ ├── BrcmFirmwareInjector2_04ca_2016.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04ca_2016.kext │ │ └── Contents │ │ └── Info.plist ├── 04f2_b49d │ ├── BCM43142A0_001.001.011.0277.0308_v4404.zhx │ ├── BrcmFirmwareInjector2_04f2_b49d.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04f2_b49d.kext │ │ └── Contents │ │ └── Info.plist ├── 04f2_b4a1 │ ├── BCM43142A0_001.001.011.0311.0316_v4412.zhx │ ├── BrcmFirmwareInjector2_04f2_b4a1.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_04f2_b4a1.kext │ │ └── Contents │ │ └── Info.plist ├── 050d_065a │ ├── BCM20702A1_001.002.014.1443.1482_v5578.zhx │ ├── BrcmFirmwareInjector2_050d_065a.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_050d_065a.kext │ │ └── Contents │ │ └── Info.plist ├── 0930_021e │ ├── BCM20702A1_001.002.014.1502.1759_v5855.zhx │ ├── BrcmFirmwareInjector2_0930_021e.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0930_021e.kext │ │ └── Contents │ │ └── Info.plist ├── 0930_021f │ ├── BCM43142A0_001.001.011.0311.0335_v4431.zhx │ ├── BrcmFirmwareInjector2_0930_021f.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0930_021f.kext │ │ └── Contents │ │ └── Info.plist ├── 0930_0221 │ ├── BCM20702A1_001.002.014.1502.1762_v5858.zhx │ ├── BrcmFirmwareInjector2_0930_0221.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0930_0221.kext │ │ └── Contents │ │ └── Info.plist ├── 0930_0223 │ ├── BCM20702A1_001.002.014.1502.1763_v5859.zhx │ ├── BrcmFirmwareInjector2_0930_0223.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0930_0223.kext │ │ └── Contents │ │ └── Info.plist ├── 0930_0225 │ ├── BCM43142A0_001.001.011.0311.0334_v4430.zhx │ ├── BrcmFirmwareInjector2_0930_0225.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0930_0225.kext │ │ └── Contents │ │ └── Info.plist ├── 0930_0229 │ ├── BCM4335C0_003.001.009.0066.0104_v4200.zhx │ ├── BrcmFirmwareInjector2_0930_0229.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0930_0229.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_2167 │ ├── BCM43142A0_001.001.011.0249.0265_v4361.zhx │ ├── BrcmFirmwareInjector2_0a5c_2167.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_2167.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_2168 │ ├── BCM4335C0_003.001.009.0066.0108_v4204.zhx │ ├── BrcmFirmwareInjector2_0a5c_2168.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_2168.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_2169 │ ├── BCM20702A1_001.002.014.1443.1462_v5558.zhx │ ├── BrcmFirmwareInjector2_0a5c_2169.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_2169.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_216a │ ├── BCM43142A0_001.001.011.0311.0336_v4432.zhx │ ├── BrcmFirmwareInjector2_0a5c_216a.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_216a.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_216b │ ├── BCM20702A1_001.002.014.1502.1768_v5864.zhx │ ├── BrcmFirmwareInjector2_0a5c_216b.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_216b.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_216c │ ├── BCM43142A0_001.001.011.0311.0328_v4424.zhx │ ├── BrcmFirmwareInjector2_0a5c_216c.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_216c.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_216d │ ├── BCM43142A0_001.001.011.0311.0329_v4425.zhx │ ├── BrcmFirmwareInjector2_0a5c_216d.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_216d.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_216e │ ├── BCM4335C0_003.001.009.0066.0105_v4201.zhx │ ├── BrcmFirmwareInjector2_0a5c_216e.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_216e.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_216f │ ├── BCM20702A1_001.002.014.1443.1572_v5668.zhx │ ├── BrcmFirmwareInjector2_0a5c_216f.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_216f.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21d3 │ ├── BCM43142A0_001.001.011.0197.0218_v4314.zhx │ ├── BrcmFirmwareInjector2_0a5c_21d3.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21d3.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21d6 │ ├── BCM43142A0_001.001.011.0197.0220_v4316.zhx │ ├── BrcmFirmwareInjector2_0a5c_21d6.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21d6.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21d7 │ ├── BCM43142A0_001.001.011.0311.0341_v4437.zhx │ ├── BrcmFirmwareInjector2_0a5c_21d7.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21d7.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21d8 │ ├── BCM43142A0_001.001.011.0197.0222_v4318.zhx │ ├── BrcmFirmwareInjector2_0a5c_21d8.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21d8.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21dc │ ├── BCM43142A0_001.001.011.0161.0187_v4283.zhx │ ├── BrcmFirmwareInjector2_0a5c_21dc.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21dc.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21de │ ├── BCM20702A1_001.002.014.1443.1461_v5557.zhx │ ├── BrcmFirmwareInjector2_0a5c_21de.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21de.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21e1 │ ├── BCM20702A1_001.002.014.1502.1770_v5866.zhx │ ├── BrcmFirmwareInjector2_0a5c_21e1.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21e1.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21e3 │ ├── BCM20702A1_001.002.014.1502.1767_v5863.zhx │ ├── BrcmFirmwareInjector2_0a5c_21e3.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21e3.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21e6 │ ├── BCM20702A1_001.002.014.1502.1757_v5853.zhx │ ├── BrcmFirmwareInjector2_0a5c_21e6.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21e6.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21e8 │ ├── BCM20702A1_001.002.014.1502.1764_v5860.zhx │ ├── BrcmFirmwareInjector2_0a5c_21e8.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21e8.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21ec │ ├── BCM20702A1_001.002.014.1443.1460_v5556.zhx │ ├── BrcmFirmwareInjector2_0a5c_21ec.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21ec.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21f1 │ ├── BCM20702A1_001.002.014.1502.1765_v5861.zhx │ ├── BrcmFirmwareInjector2_0a5c_21f1.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21f1.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21f3 │ ├── BCM20702A1_001.002.014.1502.1761_v5857.zhx │ ├── BrcmFirmwareInjector2_0a5c_21f3.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21f3.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21f4 │ ├── BCM20702A1_001.002.014.1502.1760_v5856.zhx │ ├── BrcmFirmwareInjector2_0a5c_21f4.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21f4.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21fb │ ├── BCM20702A1_001.002.014.1502.1766_v5862.zhx │ ├── BrcmFirmwareInjector2_0a5c_21fb.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21fb.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21fd │ ├── BCM20702A1_001.002.014.1443.1463_v5559.zhx │ ├── BrcmFirmwareInjector2_0a5c_21fd.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21fd.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_21fe │ ├── BCM43142A0_001.001.011.0161.0186_v4282.zhx │ ├── BrcmFirmwareInjector2_0a5c_21fe.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_21fe.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_640b │ ├── BCM20702A1_001.002.014.1502.1769_v5865.zhx │ ├── BrcmFirmwareInjector2_0a5c_640b.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_640b.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_6410 │ ├── BCM20703A1_001.001.005.0214.0422_v4518.zhx │ ├── BrcmFirmwareInjector2_0a5c_6410.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_6410.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_6412 │ ├── BCM4350C5_003.006.007.0222.4689_v4689.zhx │ ├── BrcmFirmwareInjector2_0a5c_6412.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_6412.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_6413 │ ├── BCM4350C5_003.006.007.0120.2118_v6214.zhx │ ├── BrcmFirmwareInjector2_0a5c_6413.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_6413.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_6414 │ ├── BCM4350C5_003.006.007.0145.2724_v6820.zhx │ ├── BrcmFirmwareInjector2_0a5c_6414.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_6414.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_6417 │ ├── BCM20702A1_001.002.014.1502.1780_v5876.zhx │ ├── BrcmFirmwareInjector2_0a5c_6417.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_6417.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_6418 │ ├── BCM4371C2_001.003.015.0093.0116_v4212.zhx │ ├── BrcmFirmwareInjector2_0a5c_6418.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_6418.kext │ │ └── Contents │ │ └── Info.plist ├── 0a5c_7460 │ ├── BCM20703A1_001.001.005.0214.0473_v4569.zhx │ ├── BrcmFirmwareInjector2_0a5c_7460.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0a5c_7460.kext │ │ └── Contents │ │ └── Info.plist ├── 0b05_17b5 │ ├── BCM20702A1_001.002.014.1443.1468_v5564.zhx │ ├── BrcmFirmwareInjector2_0b05_17b5.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0b05_17b5.kext │ │ └── Contents │ │ └── Info.plist ├── 0b05_17cb │ ├── BCM20702A1_001.002.014.1443.1467_v5563.zhx │ ├── BrcmFirmwareInjector2_0b05_17cb.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0b05_17cb.kext │ │ └── Contents │ │ └── Info.plist ├── 0b05_17cf │ ├── BCM20702A1_001.002.014.1443.1469_v5565.zhx │ ├── BrcmFirmwareInjector2_0b05_17cf.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0b05_17cf.kext │ │ └── Contents │ │ └── Info.plist ├── 0b05_180a │ ├── BCM20702A1_001.002.014.1443.1714_v5810.zhx │ ├── BrcmFirmwareInjector2_0b05_180a.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0b05_180a.kext │ │ └── Contents │ │ └── Info.plist ├── 0bb4_0306 │ ├── BCM20703A1_001.001.005.0214.0481_v4577.zhx │ ├── BrcmFirmwareInjector2_0bb4_0306.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_0bb4_0306.kext │ │ └── Contents │ │ └── Info.plist ├── 105b_e065 │ ├── BCM43142A0_001.001.011.0311.0312_v4408.zhx │ ├── BrcmFirmwareInjector2_105b_e065.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_105b_e065.kext │ │ └── Contents │ │ └── Info.plist ├── 105b_e066 │ ├── BCM20702A1_001.002.014.1443.1487_v5583.zhx │ ├── BrcmFirmwareInjector2_105b_e066.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_105b_e066.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3384 │ ├── BCM20702A1_001.002.014.1443.1477_v5573.zhx │ ├── BrcmFirmwareInjector2_13d3_3384.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3384.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3388 │ ├── BCM43142A0_001.001.011.0311.0332_v4428.zhx │ ├── BrcmFirmwareInjector2_13d3_3388.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3388.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3389 │ ├── BCM43142A0_001.001.011.0311.0333_v4429.zhx │ ├── BrcmFirmwareInjector2_13d3_3389.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3389.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3392 │ ├── BCM20702A1_001.002.014.1443.1478_v5574.zhx │ ├── BrcmFirmwareInjector2_13d3_3392.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3392.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3404 │ ├── BCM20702A1_001.002.014.1443.1479_v5575.zhx │ ├── BrcmFirmwareInjector2_13d3_3404.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3404.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3411 │ ├── BCM20702A1_001.002.014.1443.1450_v5546.zhx │ ├── BrcmFirmwareInjector2_13d3_3411.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3411.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3413 │ ├── BCM20702A1_001.002.014.1443.1481_v5577.zhx │ ├── BrcmFirmwareInjector2_13d3_3413.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3413.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3418 │ ├── BCM20702A1_001.002.014.1443.1480_v5576.zhx │ ├── BrcmFirmwareInjector2_13d3_3418.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3418.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3435 │ ├── BCM20702A1_001.002.014.1443.1501_v5597.zhx │ ├── BrcmFirmwareInjector2_13d3_3435.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3435.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3456 │ ├── BCM20702A1_001.002.014.1443.1502_v5598.zhx │ ├── BrcmFirmwareInjector2_13d3_3456.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3456.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3482 │ ├── BCM43142A0_001.001.011.0311.0346_v4442.zhx │ ├── BrcmFirmwareInjector2_13d3_3482.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3482.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3484 │ ├── BCM43142A0_001.001.011.0311.0347_v4443.zhx │ ├── BrcmFirmwareInjector2_13d3_3484.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3484.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3504 │ ├── BCM4371C2_001.003.015.0093.0118_v4214.zhx │ ├── BrcmFirmwareInjector2_13d3_3504.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3504.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3508 │ ├── BCM4371C2_001.003.015.0093.0117_v4213.zhx │ ├── BrcmFirmwareInjector2_13d3_3508.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3508.kext │ │ └── Contents │ │ └── Info.plist ├── 13d3_3517 │ ├── BCM20702A1_001.002.014.1502.1786_v5882.zhx │ ├── BrcmFirmwareInjector2_13d3_3517.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_13d3_3517.kext │ │ └── Contents │ │ └── Info.plist ├── 145f_01a3 │ ├── BCM20702A1_001.002.014.1443.1483_v5579.zhx │ ├── BrcmFirmwareInjector2_145f_01a3.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_145f_01a3.kext │ │ └── Contents │ │ └── Info.plist ├── 185f_2167 │ ├── BCM43142A0_001.001.011.0277.0292_v4388.zhx │ ├── BrcmFirmwareInjector2_185f_2167.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_185f_2167.kext │ │ └── Contents │ │ └── Info.plist ├── 19ff_0239 │ ├── BCM20702B0_002.001.014.0527.0557_v4653.zhx │ ├── BrcmFirmwareInjector2_19ff_0239.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_19ff_0239.kext │ │ └── Contents │ │ └── Info.plist ├── 413c_8143 │ ├── BCM20702A1_001.002.014.1443.1449_v5545.zhx │ ├── BrcmFirmwareInjector2_413c_8143.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_413c_8143.kext │ │ └── Contents │ │ └── Info.plist ├── 413c_8197 │ ├── BCM20702A1_001.002.014.1443.1447_v5543.zhx │ ├── BrcmFirmwareInjector2_413c_8197.kext │ │ └── Contents │ │ │ └── Info.plist │ └── BrcmFirmwareInjector_413c_8197.kext │ │ └── Contents │ │ └── Info.plist ├── BCM20702A1_001.002.014.1055.1061_v5157.zhx ├── BCM20702A1_001.002.014.1443.1447_v5543.zhx ├── BCM20702A1_001.002.014.1443.1449_v5545.zhx ├── BCM20702A1_001.002.014.1443.1450_v5546.zhx ├── BCM20702A1_001.002.014.1443.1460_v5556.zhx ├── BCM20702A1_001.002.014.1443.1461_v5557.zhx ├── BCM20702A1_001.002.014.1443.1462_v5558.zhx ├── BCM20702A1_001.002.014.1443.1463_v5559.zhx ├── BCM20702A1_001.002.014.1443.1465_v5561.zhx ├── BCM20702A1_001.002.014.1443.1466_v5562.zhx ├── BCM20702A1_001.002.014.1443.1467_v5563.zhx ├── BCM20702A1_001.002.014.1443.1468_v5564.zhx ├── BCM20702A1_001.002.014.1443.1469_v5565.zhx ├── BCM20702A1_001.002.014.1443.1477_v5573.zhx ├── BCM20702A1_001.002.014.1443.1478_v5574.zhx ├── BCM20702A1_001.002.014.1443.1479_v5575.zhx ├── BCM20702A1_001.002.014.1443.1480_v5576.zhx ├── BCM20702A1_001.002.014.1443.1481_v5577.zhx ├── BCM20702A1_001.002.014.1443.1482_v5578.zhx ├── BCM20702A1_001.002.014.1443.1483_v5579.zhx ├── BCM20702A1_001.002.014.1443.1484_v5580.zhx ├── BCM20702A1_001.002.014.1443.1485_v5581.zhx ├── BCM20702A1_001.002.014.1443.1486_v5582.zhx ├── BCM20702A1_001.002.014.1443.1487_v5583.zhx ├── BCM20702A1_001.002.014.1443.1488_v5584.zhx ├── BCM20702A1_001.002.014.1443.1489_v5585.zhx ├── BCM20702A1_001.002.014.1443.1490_v5586.zhx ├── BCM20702A1_001.002.014.1443.1492_v5588.zhx ├── BCM20702A1_001.002.014.1443.1493_v5589.zhx ├── BCM20702A1_001.002.014.1443.1494_v5590.zhx ├── BCM20702A1_001.002.014.1443.1499_v5595.zhx ├── BCM20702A1_001.002.014.1443.1501_v5597.zhx ├── BCM20702A1_001.002.014.1443.1502_v5598.zhx ├── BCM20702A1_001.002.014.1443.1521_v5617.zhx ├── BCM20702A1_001.002.014.1443.1532_v5628.zhx ├── BCM20702A1_001.002.014.1443.1572_v5668.zhx ├── BCM20702A1_001.002.014.1443.1714_v5810.zhx ├── BCM20702A1_001.002.014.1483.1651_v5747.zhx ├── BCM20702A1_001.002.014.1502.1757_v5853.zhx ├── BCM20702A1_001.002.014.1502.1758_v5854.zhx ├── BCM20702A1_001.002.014.1502.1759_v5855.zhx ├── BCM20702A1_001.002.014.1502.1760_v5856.zhx ├── BCM20702A1_001.002.014.1502.1761_v5857.zhx ├── BCM20702A1_001.002.014.1502.1762_v5858.zhx ├── BCM20702A1_001.002.014.1502.1763_v5859.zhx ├── BCM20702A1_001.002.014.1502.1764_v5860.zhx ├── BCM20702A1_001.002.014.1502.1765_v5861.zhx ├── BCM20702A1_001.002.014.1502.1766_v5862.zhx ├── BCM20702A1_001.002.014.1502.1767_v5863.zhx ├── BCM20702A1_001.002.014.1502.1768_v5864.zhx ├── BCM20702A1_001.002.014.1502.1769_v5865.zhx ├── BCM20702A1_001.002.014.1502.1770_v5866.zhx ├── BCM20702A1_001.002.014.1502.1780_v5876.zhx ├── BCM20702A1_001.002.014.1502.1786_v5882.zhx ├── BCM20702B0_002.001.014.0527.0557_v4653.zhx ├── BCM20703A1_001.001.005.0214.0414_v4510.zhx ├── BCM20703A1_001.001.005.0214.0422_v4518.zhx ├── BCM20703A1_001.001.005.0214.0473_v4569.zhx ├── BCM20703A1_001.001.005.0214.0481_v4577.zhx ├── BCM43142A0_001.001.011.0161.0186_v4282.zhx ├── BCM43142A0_001.001.011.0161.0187_v4283.zhx ├── BCM43142A0_001.001.011.0197.0218_v4314.zhx ├── BCM43142A0_001.001.011.0197.0220_v4316.zhx ├── BCM43142A0_001.001.011.0197.0222_v4318.zhx ├── BCM43142A0_001.001.011.0249.0265_v4361.zhx ├── BCM43142A0_001.001.011.0277.0279_v4375.zhx ├── BCM43142A0_001.001.011.0277.0280_v4376.zhx ├── BCM43142A0_001.001.011.0277.0292_v4388.zhx ├── BCM43142A0_001.001.011.0277.0308_v4404.zhx ├── BCM43142A0_001.001.011.0311.0312_v4408.zhx ├── BCM43142A0_001.001.011.0311.0316_v4412.zhx ├── BCM43142A0_001.001.011.0311.0327_v4423.zhx ├── BCM43142A0_001.001.011.0311.0328_v4424.zhx ├── BCM43142A0_001.001.011.0311.0329_v4425.zhx ├── BCM43142A0_001.001.011.0311.0330_v4426.zhx ├── BCM43142A0_001.001.011.0311.0331_v4427.zhx ├── BCM43142A0_001.001.011.0311.0332_v4428.zhx ├── BCM43142A0_001.001.011.0311.0333_v4429.zhx ├── BCM43142A0_001.001.011.0311.0334_v4430.zhx ├── BCM43142A0_001.001.011.0311.0335_v4431.zhx ├── BCM43142A0_001.001.011.0311.0336_v4432.zhx ├── BCM43142A0_001.001.011.0311.0339_v4435.zhx ├── BCM43142A0_001.001.011.0311.0340_v4436.zhx ├── BCM43142A0_001.001.011.0311.0341_v4437.zhx ├── BCM43142A0_001.001.011.0311.0346_v4442.zhx ├── BCM43142A0_001.001.011.0311.0347_v4443.zhx ├── BCM4335C0_003.001.009.0066.0104_v4200.zhx ├── BCM4335C0_003.001.009.0066.0105_v4201.zhx ├── BCM4335C0_003.001.009.0066.0108_v4204.zhx ├── BCM4335C0_003.001.009.0066.0115_v4211.zhx ├── BCM4335C0_003.001.009.0066.0121_v4217.zhx ├── BCM4350C5_003.006.007.0120.2118_v6214.zhx ├── BCM4350C5_003.006.007.0145.2724_v6820.zhx ├── BCM4350C5_003.006.007.0222.4689_v4689.zhx ├── BCM4371C2_001.003.015.0093.0116_v4212.zhx ├── BCM4371C2_001.003.015.0093.0117_v4213.zhx ├── BCM4371C2_001.003.015.0093.0118_v4214.zhx ├── firmwares.md ├── firmwares.plist ├── firmwares2.plist └── firmwares3.plist └── generate_firmware_data.sh /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | release: 8 | types: [published] 9 | 10 | env: 11 | PROJECT_TYPE: KEXT 12 | 13 | jobs: 14 | build: 15 | name: Build 16 | runs-on: macos-latest 17 | env: 18 | JOB_TYPE: BUILD 19 | steps: 20 | - uses: actions/checkout@v3 21 | - uses: actions/checkout@v3 22 | with: 23 | repository: acidanthera/MacKernelSDK 24 | path: MacKernelSDK 25 | - name: CI Bootstrap 26 | run: | 27 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 28 | - name: Lilu Bootstrap 29 | run: | 30 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/Lilu/master/Lilu/Scripts/bootstrap.sh) && eval "$src" || exit 1 31 | 32 | - run: xcodebuild -jobs 1 -target Package -configuration Debug 33 | - run: xcodebuild -jobs 1 -target Package -configuration Release 34 | 35 | - name: Upload to Artifacts 36 | uses: actions/upload-artifact@v3 37 | with: 38 | name: Artifacts 39 | path: build/*/*/*.zip 40 | - name: Upload to Release 41 | if: github.event_name == 'release' 42 | uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d 43 | with: 44 | repo_token: ${{ secrets.GITHUB_TOKEN }} 45 | file: build/*/*/*.zip 46 | tag: ${{ github.ref }} 47 | file_glob: true 48 | 49 | analyze-clang: 50 | name: Analyze Clang 51 | runs-on: macos-latest 52 | env: 53 | JOB_TYPE: ANALYZE 54 | steps: 55 | - uses: actions/checkout@v3 56 | - uses: actions/checkout@v3 57 | with: 58 | repository: acidanthera/MacKernelSDK 59 | path: MacKernelSDK 60 | - name: CI Bootstrap 61 | run: | 62 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 63 | - name: Lilu Bootstrap 64 | run: | 65 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/Lilu/master/Lilu/Scripts/bootstrap.sh) && eval "$src" || exit 1 66 | 67 | - run: xcodebuild analyze -quiet -scheme Package -target Package -configuration Debug CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR="$(pwd)/clang-analyze" && [ "$(find clang-analyze -name "*.html")" = "" ] 68 | - run: xcodebuild clean -quiet -scheme Package 69 | - run: xcodebuild analyze -quiet -scheme Package -target Package -configuration Release CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR="$(pwd)/clang-analyze" && [ "$(find clang-analyze -name "*.html")" = "" ] 70 | 71 | analyze-coverity: 72 | name: Analyze Coverity 73 | runs-on: macos-latest 74 | env: 75 | JOB_TYPE: COVERITY 76 | if: github.repository_owner == 'acidanthera' && github.event_name != 'pull_request' 77 | steps: 78 | - uses: actions/checkout@v3 79 | - uses: actions/checkout@v3 80 | with: 81 | repository: acidanthera/MacKernelSDK 82 | path: MacKernelSDK 83 | - name: CI Bootstrap 84 | run: | 85 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 86 | - name: Lilu Bootstrap 87 | run: | 88 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/Lilu/master/Lilu/Scripts/bootstrap.sh) && eval "$src" || exit 1 89 | 90 | - name: Run Coverity 91 | run: | 92 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/coverity/covstrap.sh) && eval "$src" || exit 1 93 | env: 94 | COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} 95 | COVERITY_SCAN_EMAIL: ${{ secrets.COVERITY_SCAN_EMAIL }} 96 | COVERITY_BUILD_COMMAND: xcodebuild -target Package -configuration Release 97 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Build 2 | build 3 | DerivedData 4 | Distribute 5 | Index 6 | Logs 7 | TextIndex 8 | xcuserdata 9 | xcshareddata 10 | project.xcworkspace 11 | scm.plist 12 | *.xccheckout 13 | .DS_Store 14 | ModuleCache 15 | GeneratedFirmwares.cpp 16 | GeneratedFirmwaresMD5.txt 17 | /MacKernelSDK 18 | /Lilu.kext 19 | -------------------------------------------------------------------------------- /BrcmNonPatchRAM-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | $(PRODUCT_BUNDLE_IDENTIFIER) 7 | CFBundleInfoDictionaryVersion 8 | 6.0 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundlePackageType 12 | KEXT 13 | CFBundleShortVersionString 14 | ${CURRENT_PROJECT_VERSION} 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | ${CURRENT_PROJECT_VERSION} 19 | IOKitPersonalities 20 | 21 | 03f0_231d no firmware legacy 22 | 23 | #FirmwareKey 24 | only load and unload native bluetooth 25 | CFBundleIdentifier 26 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 27 | DisplayName 28 | HP 231d (ProBook BT built-in firmware) 29 | IOClass 30 | BrcmPatchRAM 31 | IOMatchCategory 32 | BrcmPatchRAM 33 | IOProviderClass 34 | IOUSBDevice 35 | idProduct 36 | 8989 37 | idVendor 38 | 1008 39 | 40 | 0489_e030 no firmware legacy - 2 41 | 42 | #FirmwareKey 43 | only load and unload native bluetooth 44 | CFBundleIdentifier 45 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 46 | DisplayName 47 | Foxconn AW-NB290 48 | IOClass 49 | BrcmPatchRAM 50 | IOMatchCategory 51 | BrcmPatchRAM 52 | IOProviderClass 53 | IOUSBDevice 54 | idProduct 55 | 57392 56 | idVendor 57 | 1161 58 | 59 | 0a5c_219a no firmware legacy 60 | 61 | #FirmwareKey 62 | only load and unload native bluetooth 63 | CFBundleIdentifier 64 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 65 | DisplayName 66 | Broadcom BCM2070 0a5c_219a (BT on BCM43225HMB) 67 | IOClass 68 | BrcmPatchRAM 69 | IOMatchCategory 70 | BrcmPatchRAM 71 | IOProviderClass 72 | IOUSBDevice 73 | idProduct 74 | 2652 75 | idVendor 76 | 8602 77 | 78 | 0b05_1788 no firmware legacy 79 | 80 | #FirmwareKey 81 | only load and unload native bluetooth 82 | CFBundleIdentifier 83 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 84 | DisplayName 85 | Asus BT-270(20702A built-in firmware) 86 | IOClass 87 | BrcmPatchRAM 88 | IOMatchCategory 89 | BrcmPatchRAM 90 | IOProviderClass 91 | IOUSBDevice 92 | idProduct 93 | 6024 94 | idVendor 95 | 2821 96 | 97 | 0b05_178a no firmware legacy 98 | 99 | #FirmwareKey 100 | only load and unload native bluetooth 101 | CFBundleIdentifier 102 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 103 | DisplayName 104 | HP EliteBook NB-290 (built-in firmware) 105 | IOClass 106 | BrcmPatchRAM 107 | IOMatchCategory 108 | BrcmPatchRAM 109 | IOProviderClass 110 | IOUSBDevice 111 | idProduct 112 | 6026 113 | idVendor 114 | 2821 115 | 116 | 13d3_3295 no firmware legacy 117 | 118 | #FirmwareKey 119 | only load and unload native bluetooth 120 | CFBundleIdentifier 121 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 122 | DisplayName 123 | Azurewave BCM943225 (20702A built-in firmware) 124 | IOClass 125 | BrcmPatchRAM 126 | IOMatchCategory 127 | BrcmPatchRAM 128 | IOProviderClass 129 | IOUSBDevice 130 | idProduct 131 | 12949 132 | idVendor 133 | 5075 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /BrcmNonPatchRAM2-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | $(PRODUCT_BUNDLE_IDENTIFIER) 7 | CFBundleInfoDictionaryVersion 8 | 6.0 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundlePackageType 12 | KEXT 13 | CFBundleShortVersionString 14 | ${CURRENT_PROJECT_VERSION} 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | ${CURRENT_PROJECT_VERSION} 19 | IOKitPersonalities 20 | 21 | 03f0_231d native 22 | 23 | CFBundleIdentifier 24 | com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport 25 | IOClass 26 | BroadcomBluetoothHostControllerUSBTransport 27 | IOProviderClass 28 | IOUSBHostDevice 29 | idProduct 30 | 8989 31 | idVendor 32 | 1008 33 | 34 | 0489_e030 no firmware 35 | 36 | CFBundleIdentifier 37 | com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport 38 | IOClass 39 | BroadcomBluetoothHostControllerUSBTransport 40 | IOProviderClass 41 | IOUSBHostDevice 42 | idProduct 43 | 57392 44 | idVendor 45 | 1161 46 | 47 | 03f0_231d no firmware 48 | 49 | #FirmwareKey 50 | only load and unload native bluetooth 51 | CFBundleIdentifier 52 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 53 | DisplayName 54 | HP 231d (ProBook BT built-in firmware) 55 | IOClass 56 | BrcmPatchRAM2 57 | IOMatchCategory 58 | BrcmPatchRAM2 59 | IOProviderClass 60 | IOUSBHostDevice 61 | idProduct 62 | 8989 63 | idVendor 64 | 1008 65 | 66 | 0489_e030 native 67 | 68 | CFBundleIdentifier 69 | com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport 70 | IOClass 71 | BroadcomBluetoothHostControllerUSBTransport 72 | IOProviderClass 73 | IOUSBHostDevice 74 | idProduct 75 | 57392 76 | idVendor 77 | 1161 78 | 79 | 0489_e030 no firmware 80 | 81 | #FirmwareKey 82 | only load and unload native bluetooth 83 | CFBundleIdentifier 84 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 85 | DisplayName 86 | Foxconn AW-NB290 87 | IOClass 88 | BrcmPatchRAM2 89 | IOMatchCategory 90 | BrcmPatchRAM2 91 | IOProviderClass 92 | IOUSBHostDevice 93 | idProduct 94 | 57392 95 | idVendor 96 | 1161 97 | 98 | 0a5c_219a native 99 | 100 | CFBundleIdentifier 101 | com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport 102 | IOClass 103 | BroadcomBluetoothHostControllerUSBTransport 104 | IOProviderClass 105 | IOUSBHostDevice 106 | idProduct 107 | 2652 108 | idVendor 109 | 8602 110 | 111 | 0a5c_219a no firmware 112 | 113 | #FirmwareKey 114 | only load and unload native bluetooth 115 | CFBundleIdentifier 116 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 117 | DisplayName 118 | Broadcom BCM2070 0a5c_219a (BT on BCM43225HMB) 119 | IOClass 120 | BrcmPatchRAM2 121 | IOMatchCategory 122 | BrcmPatchRAM2 123 | IOProviderClass 124 | IOUSBHostDevice 125 | idProduct 126 | 2652 127 | idVendor 128 | 8602 129 | 130 | 0b05_1788 native 131 | 132 | CFBundleIdentifier 133 | com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport 134 | IOClass 135 | BroadcomBluetoothHostControllerUSBTransport 136 | IOProviderClass 137 | IOUSBHostDevice 138 | idProduct 139 | 6024 140 | idVendor 141 | 2821 142 | 143 | 0b05_1788 no firmware 144 | 145 | #FirmwareKey 146 | only load and unload native bluetooth 147 | CFBundleIdentifier 148 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 149 | DisplayName 150 | Asus BT-270(20702A built-in firmware) 151 | IOClass 152 | BrcmPatchRAM2 153 | IOMatchCategory 154 | BrcmPatchRAM2 155 | IOProviderClass 156 | IOUSBHostDevice 157 | idProduct 158 | 6024 159 | idVendor 160 | 2821 161 | 162 | 0b05_178a native 163 | 164 | CFBundleIdentifier 165 | com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport 166 | IOClass 167 | BroadcomBluetoothHostControllerUSBTransport 168 | IOProviderClass 169 | IOUSBHostDevice 170 | idProduct 171 | 6026 172 | idVendor 173 | 2821 174 | 175 | 0b05_178a no firmware 176 | 177 | #FirmwareKey 178 | only load and unload native bluetooth 179 | CFBundleIdentifier 180 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 181 | DisplayName 182 | HP EliteBook NB-290 (built-in firmware) 183 | IOClass 184 | BrcmPatchRAM2 185 | IOMatchCategory 186 | BrcmPatchRAM2 187 | IOProviderClass 188 | IOUSBHostDevice 189 | idProduct 190 | 6026 191 | idVendor 192 | 2821 193 | 194 | 13d3_3295 native 195 | 196 | CFBundleIdentifier 197 | com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport 198 | IOClass 199 | BroadcomBluetoothHostControllerUSBTransport 200 | IOProviderClass 201 | IOUSBHostDevice 202 | idProduct 203 | 12949 204 | idVendor 205 | 5075 206 | 207 | 13d3_3295 no firmware 208 | 209 | #FirmwareKey 210 | only load and unload native bluetooth 211 | CFBundleIdentifier 212 | as.acidanthera.$(PRODUCT_NAME:rfc1034identifier) 213 | DisplayName 214 | Azurewave BCM943225 (20702A built-in firmware) 215 | IOClass 216 | BrcmPatchRAM2 217 | IOMatchCategory 218 | BrcmPatchRAM2 219 | IOProviderClass 220 | IOUSBHostDevice 221 | idProduct 222 | 12949 223 | idVendor 224 | 5075 225 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /BrcmPatchRAM/BlueToolFixup-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | KEXT 17 | CFBundleShortVersionString 18 | $(MODULE_VERSION) 19 | CFBundleVersion 20 | $(MODULE_VERSION) 21 | IOKitPersonalities 22 | 23 | BlueToolFixup 24 | 25 | CFBundleIdentifier 26 | $(PRODUCT_BUNDLE_IDENTIFIER) 27 | IOClass 28 | $(PRODUCT_NAME:rfc1034identifier) 29 | IOMatchCategory 30 | $(PRODUCT_NAME:rfc1034identifier) 31 | IOProviderClass 32 | IOResources 33 | IOResourceMatch 34 | IOKit 35 | 36 | 37 | OSBundleLibraries 38 | 39 | as.vit9696.Lilu 40 | 1.4.7 41 | com.apple.kpi.bsd 42 | 12.0.0 43 | com.apple.kpi.dsep 44 | 12.0.0 45 | com.apple.kpi.iokit 46 | 12.0.0 47 | com.apple.kpi.libkern 48 | 12.0.0 49 | com.apple.kpi.mach 50 | 12.0.0 51 | com.apple.kpi.unsupported 52 | 12.0.0 53 | 54 | OSBundleRequired 55 | Root 56 | 57 | 58 | -------------------------------------------------------------------------------- /BrcmPatchRAM/BlueToolFixup.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // BlueToolFixup.cpp 3 | // BrcmPatchRAM 4 | // 5 | // Created by Dhinak G on 6/11/21. 6 | // 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | #define MODULE_SHORT "btlfx" 18 | 19 | 20 | class EXPORT BlueToolFixup : public IOService { 21 | OSDeclareDefaultStructors(BlueToolFixup) 22 | public: 23 | IOService *probe(IOService *provider, SInt32 *score) override; 24 | bool start(IOService *provider) override; 25 | }; 26 | 27 | OSDefineMetaClassAndStructors(BlueToolFixup, IOService) 28 | 29 | 30 | IOService *BlueToolFixup::probe(IOService *provider, SInt32 *score) { 31 | return ADDPR(startSuccess) ? IOService::probe(provider, score) : nullptr; 32 | } 33 | 34 | bool BlueToolFixup::start(IOService *provider) { 35 | if (!IOService::start(provider)) { 36 | SYSLOG("init", "failed to start the parent"); 37 | return false; 38 | } 39 | setProperty("VersionInfo", kextVersion); 40 | registerService(); 41 | 42 | return true; 43 | } 44 | 45 | 46 | #pragma mark - Patches 47 | 48 | static const uint8_t kSkipUpdateFilePathOriginal[] = "/etc/bluetool/SkipBluetoothAutomaticFirmwareUpdate"; 49 | static const uint8_t kSkipUpdateFilePathPatched[] = "/System/Library/CoreServices/boot.efi"; 50 | 51 | 52 | // Workaround 12.4 Beta 3+ bug where macOS may detect the Bluetooth chipset twice 53 | // Once as internal, and second as an external dongle: 54 | // 'ERROR -- Third Party Dongle has the same address as the internal module' 55 | // Mainly applicable for BCM2046 and BCM2070 chipsets (BT2.1) 56 | static const uint8_t kSkipAddressCheckOriginal[] = 57 | { 58 | 0x48, 0x89, 0xF3, // mov rbx, rsi 59 | 0xE8, 0x00, 0x00, 0x00, 0x00, // call 60 | 0x85, 0xC0, // test eax, eax 61 | 0x74, 0x1D, // je 62 | }; 63 | 64 | static const uint8_t kSkipAddressCheckPatched[] = 65 | { 66 | 0x48, 0x89, 0xF3, // mov rbx, rsi 67 | 0xE8, 0x00, 0x00, 0x00, 0x00, // call 68 | 0x85, 0xC0, // test eax, eax 69 | 0x72, 0x1D, // jb short 70 | }; 71 | 72 | static const uint8_t kSkipAddressCheckMask[] = 73 | { 74 | 0xFF, 0xFF, 0xFF, 75 | 0xFF, 0x00, 0x00, 0x00, 0x00, 76 | 0xFF, 0xFF, 77 | 0xFF, 0xFF, 78 | }; 79 | 80 | static const uint8_t kVendorCheckOriginal[] = 81 | { 82 | 0x81, 0xFA, // cmp edx 83 | 0x5C, 0x0A, 0x00, 0x00, // Vendor BRCM, 84 | 0x74 // jnz short 85 | }; 86 | 87 | static const uint8_t kVendorCheckPatched[] = 88 | { 89 | 0x81, 0xFA, // cmp edx 90 | 0x5C, 0x0A, 0x00, 0x00, // Vendor BRCM, 91 | 0xEB // jmp short 92 | }; 93 | 94 | // Workaround for bugged chipset range check that 95 | // doesn't consider 0 "THIRD_PARTY_DONGLE" as valid. 96 | // This patch allows bluetooth to turn back on after the first power cycle. 97 | // See https://github.com/acidanthera/BrcmPatchRAM/pull/18 for more details. 98 | static const uint8_t kBadChipsetCheckOriginal[] = 99 | { 100 | 0x81, 0xF9, // cmp ecx 101 | 0xCF, 0x07, 0x00, 0x00, // int 1999 102 | 0x72 // jb short 103 | }; 104 | 105 | static const uint8_t kBadChipsetCheckPatched[] = 106 | { 107 | 0x81, 0xF9, // cmp ecx 108 | 0xCF, 0x07, 0x00, 0x00, // int 1999 109 | 0xEB // jmp short 110 | }; 111 | 112 | static const uint8_t kBadChipsetCheckOriginal13_3[] = 113 | { 114 | 0x81, 0xF9, // cmp ecx 115 | 0x9E, 0x0F, 0x00, 0x00, // int 3998 116 | 0x77, 0x1A // ja short 117 | }; 118 | 119 | static const uint8_t kBadChipsetCheckPatched13_3[] = 120 | { 121 | 0x90, 0x90, 122 | 0x90, 0x90, 0x90, 0x90, 123 | 0x90, 0x90 124 | }; 125 | 126 | static const uint8_t kSkipInternalControllerNVRAMCheck13_3[] = 127 | { 128 | 0x41, 0x80, 0x00, 0x01, // xor r15b, 1 129 | 0x75, 0x00, // jnz short 130 | 0x84, 0xDB, // test bl, bl 131 | 0x75, 0x00 // jnz short 132 | }; 133 | 134 | static const uint8_t kSkipInternalControllerNVRAMCheckMask13_3[] = 135 | { 136 | 0xFF, 0xFF, 0x00, 0xFF, 137 | 0xFF, 0x00, 138 | 0xFF, 0xFF, 139 | 0xFF, 0x00 140 | }; 141 | 142 | static const uint8_t kSkipInternalControllerNVRAMCheckPatched13_3[] = 143 | { 144 | 0x90, 0x90, 0x90, 0x90, 145 | 0x90, 0x90, 146 | 0x90, 0x90, 147 | 0x90, 0x90 148 | }; 149 | 150 | static bool shouldPatchBoardId = false; 151 | static bool shouldPatchAddress = false; 152 | 153 | static constexpr size_t kBoardIdSize = sizeof("Mac-F60DEB81FF30ACF6"); 154 | static constexpr size_t kBoardIdSizeLegacy = sizeof("Mac-F22586C8"); 155 | 156 | static const char boardIdsWithUSBBluetooth[][kBoardIdSize] = { 157 | "Mac-F60DEB81FF30ACF6", 158 | "Mac-9F18E312C5C2BF0B", 159 | "Mac-937CB26E2E02BB01", 160 | "Mac-E43C1C25D4880AD6", 161 | "Mac-06F11FD93F0323C5", 162 | "Mac-06F11F11946D27C5", 163 | "Mac-A369DDC4E67F1C45", 164 | "Mac-FFE5EF870D7BA81A", 165 | "Mac-DB15BD556843C820", 166 | "Mac-B809C3757DA9BB8D", 167 | "Mac-65CE76090165799A", 168 | "Mac-4B682C642B45593E", 169 | "Mac-77F17D7DA9285301", 170 | "Mac-BE088AF8C5EB4FA2" 171 | }; 172 | 173 | static mach_vm_address_t orig_cs_validate {}; 174 | 175 | #pragma mark - Kernel patching code 176 | 177 | static inline void searchAndPatch(const void *haystack, size_t haystackSize, const char *path, const void *needle, size_t findSize, const void *patch, size_t replaceSize) { 178 | if (KernelPatcher::findAndReplace(const_cast(haystack), haystackSize, needle, findSize, patch, replaceSize)) 179 | DBGLOG(MODULE_SHORT, "found string to patch at %s!", path); 180 | } 181 | 182 | template 183 | static inline void searchAndPatch(const void *haystack, size_t haystackSize, const char *path, const T (&needle)[findSize], const T (&patch)[replaceSize]) { 184 | searchAndPatch(haystack, haystackSize, path, needle, findSize * sizeof(T), patch, replaceSize * sizeof(T)); 185 | } 186 | 187 | static inline void searchAndPatchWithMask(const void *haystack, size_t haystackSize, const char *path, const void *needle, size_t findSize, const void *findMask, size_t findMaskSize, const void *patch, size_t replaceSize, const void *patchMask, size_t replaceMaskSize) { 188 | if (KernelPatcher::findAndReplaceWithMask(const_cast(haystack), haystackSize, needle, findSize, findMask, findMaskSize, patch, replaceSize, patchMask, replaceMaskSize)) 189 | DBGLOG(MODULE_SHORT, "found string to patch at %s!", path); 190 | } 191 | 192 | template 193 | static inline void searchAndPatchWithMask(const void *haystack, size_t haystackSize, const char *path, const T (&needle)[findSize], const T (&findMask)[findMaskSize], const T (&patch)[replaceSize], const T (&patchMask)[replaceMaskSize]) { 194 | searchAndPatchWithMask(haystack, haystackSize, path, needle, findSize * sizeof(T), findMask, findMaskSize * sizeof(T), patch, replaceSize * sizeof(T), patchMask, replaceSize * sizeof(T)); 195 | } 196 | 197 | 198 | #pragma mark - Patched functions 199 | 200 | static void patched_cs_validate_page(vnode_t vp, memory_object_t pager, memory_object_offset_t page_offset, const void *data, int *validated_p, int *tainted_p, int *nx_p) { 201 | char path[PATH_MAX]; 202 | int pathlen = PATH_MAX; 203 | FunctionCast(patched_cs_validate_page, orig_cs_validate)(vp, pager, page_offset, data, validated_p, tainted_p, nx_p); 204 | static constexpr size_t dirLength = sizeof("/usr/sbin/")-1; 205 | if (vn_getpath(vp, path, &pathlen) == 0 && UNLIKELY(strncmp(path, "/usr/sbin/", dirLength) == 0)) { 206 | if (strcmp(path + dirLength, "BlueTool") == 0) { 207 | searchAndPatch(data, PAGE_SIZE, path, kSkipUpdateFilePathOriginal, kSkipUpdateFilePathPatched); 208 | if (shouldPatchBoardId) 209 | searchAndPatch(data, PAGE_SIZE, path, boardIdsWithUSBBluetooth[0], kBoardIdSize, BaseDeviceInfo::get().boardIdentifier, kBoardIdSize); 210 | } 211 | else if (strcmp(path + dirLength, "bluetoothd") == 0) { 212 | searchAndPatch(data, PAGE_SIZE, path, kVendorCheckOriginal, kVendorCheckPatched); 213 | searchAndPatch(data, PAGE_SIZE, path, kBadChipsetCheckOriginal, kBadChipsetCheckPatched); 214 | searchAndPatch(data, PAGE_SIZE, path, kBadChipsetCheckOriginal13_3, kBadChipsetCheckPatched13_3); 215 | searchAndPatchWithMask(data, PAGE_SIZE, path, kSkipInternalControllerNVRAMCheck13_3, sizeof(kSkipInternalControllerNVRAMCheck13_3), kSkipInternalControllerNVRAMCheckMask13_3, sizeof(kSkipInternalControllerNVRAMCheckMask13_3), kSkipInternalControllerNVRAMCheckPatched13_3, sizeof(kSkipInternalControllerNVRAMCheckPatched13_3), nullptr, 0); 216 | if (shouldPatchBoardId) 217 | searchAndPatch(data, PAGE_SIZE, path, boardIdsWithUSBBluetooth[0], kBoardIdSize, BaseDeviceInfo::get().boardIdentifier, kBoardIdSize); 218 | if (shouldPatchAddress) 219 | searchAndPatchWithMask(data, PAGE_SIZE, path, kSkipAddressCheckOriginal, kSkipAddressCheckMask, kSkipAddressCheckPatched, kSkipAddressCheckMask); 220 | } 221 | } 222 | } 223 | 224 | 225 | #pragma mark - Patches on start/stop 226 | 227 | static void pluginStart() { 228 | SYSLOG(MODULE_SHORT, "start"); 229 | // There is no point in routing cs_validate_range, because this kext should only be running on Monterey+ 230 | if (getKernelVersion() >= KernelVersion::Monterey) { 231 | lilu.onPatcherLoadForce([](void *user, KernelPatcher &patcher) { 232 | auto boardId = BaseDeviceInfo::get().boardIdentifier; 233 | auto boardIdSize = strlen(boardId) + 1; 234 | shouldPatchBoardId = boardIdSize == kBoardIdSize || boardIdSize == kBoardIdSizeLegacy; 235 | if (shouldPatchBoardId) 236 | for (size_t i = 0; i < arrsize(boardIdsWithUSBBluetooth); i++) 237 | if (strcmp(boardIdsWithUSBBluetooth[i], boardId) == 0) { 238 | shouldPatchBoardId = false; 239 | break; 240 | } 241 | if ((getKernelVersion() == KernelVersion::Monterey && getKernelMinorVersion() >= 5) || getKernelVersion() > KernelVersion::Monterey) 242 | // 12.4 Beta 3+, XNU 21.5 243 | shouldPatchAddress = checkKernelArgument("-btlfxallowanyaddr"); 244 | KernelPatcher::RouteRequest csRoute = KernelPatcher::RouteRequest("_cs_validate_page", patched_cs_validate_page, orig_cs_validate); 245 | if (!patcher.routeMultipleLong(KernelPatcher::KernelID, &csRoute, 1)) 246 | SYSLOG(MODULE_SHORT, "failed to route cs validation pages"); 247 | }); 248 | } 249 | } 250 | 251 | // Boot args. 252 | static const char *bootargOff[] { 253 | "-btlfxoff" 254 | }; 255 | static const char *bootargDebug[] { 256 | "-btlfxdbg" 257 | }; 258 | static const char *bootargBeta[] { 259 | "-btlfxbeta" 260 | }; 261 | 262 | // Plugin configuration. 263 | PluginConfiguration ADDPR(config) { 264 | xStringify(PRODUCT_NAME), 265 | parseModuleVersion(xStringify(MODULE_VERSION)), 266 | LiluAPI::AllowNormal | LiluAPI::AllowInstallerRecovery | LiluAPI::AllowSafeMode, 267 | bootargOff, 268 | arrsize(bootargOff), 269 | bootargDebug, 270 | arrsize(bootargDebug), 271 | bootargBeta, 272 | arrsize(bootargBeta), 273 | KernelVersion::Monterey, 274 | KernelVersion::Sonoma, 275 | pluginStart 276 | }; 277 | -------------------------------------------------------------------------------- /BrcmPatchRAM/BrcmFirmwareData-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleExecutable 6 | $(EXECUTABLE_NAME) 7 | CFBundleIdentifier 8 | $(PRODUCT_BUNDLE_IDENTIFIER) 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | $(PRODUCT_NAME) 13 | CFBundlePackageType 14 | KEXT 15 | CFBundleShortVersionString 16 | ${CURRENT_PROJECT_VERSION} 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | ${CURRENT_PROJECT_VERSION} 21 | IOKitPersonalities 22 | 23 | BrcmFirmwareStore 24 | 25 | CFBundleIdentifier 26 | as.acidanthera.BrcmFirmwareStore 27 | IOClass 28 | BrcmFirmwareStore 29 | IOMatchCategory 30 | BrcmFirmwareStore 31 | IOProviderClass 32 | IOResources 33 | 34 | 35 | OSBundleCompatibleVersion 36 | ${CURRENT_PROJECT_VERSION} 37 | OSBundleLibraries 38 | 39 | com.apple.kpi.iokit 40 | 9.0 41 | com.apple.kpi.libkern 42 | 9.0 43 | com.apple.kpi.mach 44 | 9.0 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /BrcmPatchRAM/BrcmFirmwareRepo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleExecutable 6 | $(EXECUTABLE_NAME) 7 | CFBundleIdentifier 8 | $(PRODUCT_BUNDLE_IDENTIFIER) 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | $(PRODUCT_NAME) 13 | CFBundlePackageType 14 | KEXT 15 | CFBundleShortVersionString 16 | ${CURRENT_PROJECT_VERSION} 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | ${CURRENT_PROJECT_VERSION} 21 | IOKitPersonalities 22 | 23 | BrcmFirmwareStore 24 | 25 | CFBundleIdentifier 26 | as.acidanthera.BrcmFirmwareStore 27 | IOClass 28 | BrcmFirmwareStore 29 | IOMatchCategory 30 | BrcmFirmwareStore 31 | IOProviderClass 32 | IOResources 33 | 34 | 35 | OSBundleCompatibleVersion 36 | ${CURRENT_PROJECT_VERSION} 37 | OSBundleLibraries 38 | 39 | com.apple.kpi.iokit 40 | 9.0 41 | com.apple.kpi.libkern 42 | 9.0 43 | com.apple.kpi.mach 44 | 9.0 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /BrcmPatchRAM/BrcmFirmwareStore.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | * Zlib implementation based on /apple/xnu/libkern/c++/OSKext.cpp 19 | */ 20 | 21 | #include "Common.h" 22 | #include "BrcmFirmwareStore.h" 23 | #ifdef FIRMWAREDATA 24 | #include "FirmwareData.h" 25 | #endif 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | /*************************************** 32 | * Zlib Decompression 33 | ***************************************/ 34 | #include 35 | #include 36 | 37 | extern "C" 38 | { 39 | static void* z_alloc(void*, u_int items, u_int size); 40 | static void z_free(void*, void *ptr); 41 | 42 | typedef struct z_mem 43 | { 44 | UInt32 alloc_size; 45 | UInt8 data[0]; 46 | } z_mem; 47 | 48 | /* 49 | * Space allocation and freeing routines for use by zlib routines. 50 | */ 51 | void* z_alloc(void* notused __unused, u_int num_items, u_int size) 52 | { 53 | void* result = NULL; 54 | z_mem* zmem = NULL; 55 | UInt32 total = num_items * size; 56 | UInt32 allocSize = total + sizeof(zmem); 57 | 58 | zmem = (z_mem*)IOMalloc(allocSize); 59 | 60 | if (zmem) 61 | { 62 | zmem->alloc_size = allocSize; 63 | result = (void*)&(zmem->data); 64 | } 65 | 66 | return result; 67 | } 68 | 69 | void z_free(void* notused __unused, void* ptr) 70 | { 71 | UInt32* skipper = (UInt32 *)ptr - 1; 72 | z_mem* zmem = (z_mem*)skipper; 73 | IOFree((void*)zmem, zmem->alloc_size); 74 | } 75 | }; 76 | 77 | /* 78 | * Decompress the firmware using zlib inflate (If not compressed, return data normally) 79 | */ 80 | OSData* BrcmFirmwareStore::decompressFirmware(OSData* firmware) 81 | { 82 | z_stream zstream; 83 | int zlib_result; 84 | int bufferSize = 0; 85 | void* buffer = NULL; 86 | OSData* result = NULL; 87 | 88 | // Verify if the data is compressed 89 | UInt16* magic = (UInt16*)firmware->getBytesNoCopy(); 90 | 91 | if (*magic != 0x0178 // Zlib no compression 92 | && *magic != 0x9c78 // Zlib default compression 93 | && *magic != 0xda78) // Zlib maximum compression 94 | { 95 | // Return the data as-is 96 | firmware->retain(); 97 | return firmware; 98 | } 99 | 100 | bufferSize = firmware->getLength() * 4; 101 | 102 | buffer = IOMalloc(bufferSize); 103 | 104 | bzero(&zstream, sizeof(zstream)); 105 | 106 | zstream.next_in = (unsigned char*)firmware->getBytesNoCopy(); 107 | zstream.avail_in = firmware->getLength(); 108 | 109 | zstream.next_out = (unsigned char*)buffer; 110 | zstream.avail_out = bufferSize; 111 | 112 | zstream.zalloc = z_alloc; 113 | zstream.zfree = z_free; 114 | 115 | zlib_result = inflateInit(&zstream); 116 | 117 | if (zlib_result != Z_OK) 118 | { 119 | IOFree(buffer, bufferSize); 120 | return NULL; 121 | } 122 | 123 | zlib_result = inflate(&zstream, Z_FINISH); 124 | 125 | if (zlib_result == Z_STREAM_END || zlib_result == Z_OK) 126 | // Allocate final result 127 | result = OSData::withBytes(buffer, (unsigned int)zstream.total_out); 128 | 129 | inflateEnd(&zstream); 130 | IOFree(buffer, bufferSize); 131 | 132 | return result; 133 | } 134 | 135 | /********************************************** 136 | * IntelHex firmware parsing 137 | **********************************************/ 138 | #define HEX_LINE_PREFIX ':' 139 | #define HEX_HEADER_SIZE 4 140 | 141 | #define REC_TYPE_DATA 0 // Data 142 | #define REC_TYPE_EOF 1 // End of File 143 | #define REC_TYPE_ESA 2 // Extended Segment Address 144 | #define REC_TYPE_SSA 3 // Start Segment Address 145 | #define REC_TYPE_ELA 4 // Extended Linear Address 146 | #define REC_TYPE_SLA 5 // Start Linear Address 147 | 148 | /* 149 | * Validate if the current character is a valid hexadecimal character 150 | */ 151 | static inline bool validHexChar(UInt8 hex) 152 | { 153 | return (hex >= 'a' && hex <= 'f') || (hex >= 'A' && hex <= 'F') || (hex >= '0' && hex <= '9'); 154 | } 155 | 156 | /* 157 | * Convert char '0-9,A-F' to hexadecimal values 158 | */ 159 | static inline void hex_nibble(UInt8 hex, UInt8 &output) 160 | { 161 | output <<= 4; 162 | 163 | if (hex >= 'a') 164 | output |= (0x0A + (hex - 'a')) & 0x0F; 165 | if (hex >= 'A') 166 | output |= (0x0A + (hex - 'A')) & 0x0F; 167 | else 168 | output |= (hex - '0') & 0x0F; 169 | } 170 | 171 | /* 172 | * Two's complement checksum 173 | */ 174 | static char check_sum(const UInt8* data, UInt16 len) 175 | { 176 | UInt32 crc = 0; 177 | 178 | for (int i = 0; i < len; i++) 179 | crc += *(data + i); 180 | 181 | return (~crc + 1) & 0xFF; 182 | } 183 | 184 | OSArray* BrcmFirmwareStore::parseFirmware(OSData* firmwareData) 185 | { 186 | // Vendor Specific: Launch RAM 187 | UInt8 HCI_VSC_LAUNCH_RAM[] = { 0x4c, 0xfc }; 188 | 189 | OSArray* instructions = OSArray::withCapacity(1); 190 | if (!instructions) 191 | return NULL; 192 | 193 | UInt8* data = (UInt8*)firmwareData->getBytesNoCopy(); 194 | UInt32 address = 0; 195 | UInt8 binary[0x110]; 196 | 197 | if (*data != HEX_LINE_PREFIX) 198 | { 199 | DebugLog("parseFirmware - Invalid firmware data.\n"); 200 | goto exit_error; 201 | } 202 | 203 | while (*data == HEX_LINE_PREFIX) 204 | { 205 | bzero(binary, sizeof(binary)); 206 | data++; 207 | 208 | int offset = 0; 209 | 210 | // Read all hex characters for this line 211 | while (validHexChar(*data)) 212 | { 213 | hex_nibble(*data++, binary[offset]); 214 | hex_nibble(*data++, binary[offset++]); 215 | } 216 | 217 | // Parse line data 218 | UInt8 length = binary[0]; 219 | UInt16 addr = binary[1] << 8 | binary[2]; 220 | UInt8 record_type = binary[3]; 221 | UInt8 checksum = binary[HEX_HEADER_SIZE + length]; 222 | 223 | UInt8 calc_checksum = check_sum(binary, HEX_HEADER_SIZE + length); 224 | 225 | if (checksum != calc_checksum) 226 | { 227 | DebugLog("parseFirmware - Invalid firmware, checksum mismatch.\n"); 228 | goto exit_error; 229 | } 230 | 231 | // ParseFirmware class only supports I32HEX format 232 | switch (record_type) 233 | { 234 | // Data 235 | case REC_TYPE_DATA: 236 | { 237 | address = (address & 0xFFFF0000) | addr; 238 | 239 | // Reserved 4 bytes for the address 240 | length += 4; 241 | 242 | // Allocate instruction (Opcode - 2 bytes, length - 1 byte) 243 | OSData* instruction = OSData::withCapacity(3 + length); 244 | if (!instruction) 245 | goto exit_error; 246 | 247 | instruction->appendBytes(HCI_VSC_LAUNCH_RAM, sizeof(HCI_VSC_LAUNCH_RAM)); 248 | instruction->appendBytes(&length, sizeof(length)); 249 | instruction->appendBytes(&address, sizeof(address)); 250 | instruction->appendBytes(&binary[4], length - 4); 251 | 252 | instructions->setObject(instruction); 253 | instruction->release(); 254 | break; 255 | } 256 | // End of File 257 | case REC_TYPE_EOF: 258 | return instructions; 259 | // Extended Segment Address 260 | case REC_TYPE_ESA: 261 | // Segment address multiplied by 16 262 | address = binary[4] << 8 | binary[5]; 263 | address <<= 4; 264 | break; 265 | // Start Segment Address 266 | case REC_TYPE_SSA: 267 | // Set CS:IP register for 80x86 268 | DebugLog("parseFirmware - Invalid firmware, unsupported start segment address instruction.\n"); 269 | goto exit_error; 270 | // Extended Linear Address 271 | case REC_TYPE_ELA: 272 | // Set new higher 16 bits of the current address 273 | address = binary[4] << 24 | binary[5] << 16; 274 | break; 275 | // Start Linear Address 276 | case REC_TYPE_SLA: 277 | // Set EIP of 80386 and higher 278 | DebugLog("parseFirmware - Invalid firmware, unsupported start linear address instruction.\n"); 279 | goto exit_error; 280 | default: 281 | DebugLog("parseFirmware - Invalid firmware, unknown record type encountered: 0x%02x.\n", record_type); 282 | goto exit_error; 283 | } 284 | 285 | // Skip over any trailing newlines / whitespace 286 | while (!validHexChar(*data) && !(*data == HEX_LINE_PREFIX)) 287 | data++; 288 | } 289 | 290 | DebugLog("parseFirmware - Invalid firmware.\n"); 291 | 292 | exit_error: 293 | OSSafeReleaseNULL(instructions); 294 | return NULL; 295 | } 296 | 297 | OSDefineMetaClassAndStructors(BrcmFirmwareStore, IOService) 298 | 299 | bool BrcmFirmwareStore::start(IOService *provider) 300 | { 301 | DebugLog("Firmware store start\n"); 302 | 303 | if (!super::start(provider)) 304 | return false; 305 | 306 | mFirmwares = OSDictionary::withCapacity(1); 307 | if (!mFirmwares) 308 | return false; 309 | 310 | mCompletionLock = IOLockAlloc(); 311 | if (!mCompletionLock) 312 | return false; 313 | 314 | mDataLock = IOLockAlloc(); 315 | if (!mDataLock) 316 | return false; 317 | 318 | registerService(); 319 | 320 | return true; 321 | } 322 | 323 | void BrcmFirmwareStore::stop(IOService *provider) 324 | { 325 | DebugLog("Firmware store stop\n"); 326 | 327 | OSSafeReleaseNULL(mFirmwares); 328 | 329 | if (mCompletionLock) 330 | { 331 | IOLockFree(mCompletionLock); 332 | mCompletionLock = NULL; 333 | } 334 | 335 | if (mDataLock) 336 | { 337 | IOLockFree(mDataLock); 338 | mDataLock = NULL; 339 | } 340 | 341 | super::stop(provider); 342 | } 343 | 344 | void BrcmFirmwareStore::requestResourceCallback(OSKextRequestTag requestTag, OSReturn result, const void * resourceData, uint32_t resourceDataLength, void* context1) 345 | { 346 | ResourceCallbackContext *context = (ResourceCallbackContext*)context1; 347 | 348 | IOLockLock(context->me->mCompletionLock); 349 | 350 | if (kOSReturnSuccess == result) 351 | { 352 | DebugLog("OSKextRequestResource Callback: %d bytes of data.\n", resourceDataLength); 353 | 354 | context->firmware = OSData::withBytes(resourceData, resourceDataLength); 355 | } 356 | else 357 | DebugLog("OSKextRequestResource Callback: %08x.\n", result); 358 | 359 | IOLockUnlock(context->me->mCompletionLock); 360 | 361 | // wake waiting task in performUpgrade (in IOLockSleep)... 362 | IOLockWakeup(context->me->mCompletionLock, context->me, true); 363 | } 364 | 365 | OSData* BrcmFirmwareStore::loadFirmwareFile(const char* filename, const char* suffix) 366 | { 367 | IOLockLock(mCompletionLock); 368 | 369 | ResourceCallbackContext context = { .me = this, .firmware = NULL }; 370 | 371 | char path[PATH_MAX]; 372 | snprintf(path, PATH_MAX, "%s.%s", filename, suffix); 373 | 374 | OSReturn ret = OSKextRequestResource(OSKextGetCurrentIdentifier(), 375 | path, 376 | requestResourceCallback, 377 | &context, 378 | NULL); 379 | (void) ret; 380 | DebugLog("OSKextRequestResource: %08x\n", ret); 381 | 382 | // wait for completion of the async read 383 | IOLockSleep(mCompletionLock, this, 0); 384 | 385 | IOLockUnlock(mCompletionLock); 386 | 387 | if (context.firmware) 388 | { 389 | AlwaysLog("Loaded firmware \"%s\" from resources.\n", path); 390 | return context.firmware; 391 | } 392 | 393 | return NULL; 394 | } 395 | 396 | OSData* BrcmFirmwareStore::loadFirmwareFiles(UInt16 vendorId, UInt16 productId, OSString* firmwareKey) 397 | { 398 | char filename[PATH_MAX]; 399 | snprintf(filename, PATH_MAX, "%04x_%04x", vendorId, productId); 400 | 401 | OSData* result = loadFirmwareFile(filename, kBrcmFirmwareCompressed); 402 | 403 | if (!result) 404 | result = loadFirmwareFile(filename, kBrmcmFirwareUncompressed); 405 | 406 | if (!result) 407 | result = loadFirmwareFile(firmwareKey->getCStringNoCopy(), kBrcmFirmwareCompressed); 408 | 409 | if (!result) 410 | result = loadFirmwareFile(firmwareKey->getCStringNoCopy(), kBrmcmFirwareUncompressed); 411 | 412 | return result; 413 | } 414 | 415 | OSArray* BrcmFirmwareStore::loadFirmware(UInt16 vendorId, UInt16 productId, OSString* firmwareKey) 416 | { 417 | #ifdef FIRMWAREDATA 418 | char filename[PATH_MAX]; 419 | // Try to load from internal binary data 420 | DebugLog("loadFirmware from internal binary data %s\n", firmwareKey->getCStringNoCopy()); 421 | snprintf(filename, PATH_MAX, "%s.%s", firmwareKey->getCStringNoCopy(), kBrcmFirmwareCompressed); 422 | OSData* configuredData = lookupFirmware(filename); 423 | if (configuredData) 424 | AlwaysLog("Loaded compressed embedded firmware for key \"%s\".\n", firmwareKey->getCStringNoCopy()); 425 | if (!configuredData) 426 | { 427 | snprintf(filename, PATH_MAX, "%s.%s", firmwareKey->getCStringNoCopy(), kBrmcmFirwareUncompressed); 428 | configuredData = lookupFirmware(filename); 429 | if (configuredData) 430 | AlwaysLog("Loaded compressed embedded firmware for key \"%s\".\n", firmwareKey->getCStringNoCopy()); 431 | } 432 | #else 433 | // Try to load firmware from disk 434 | DebugLog("loadFirmware from disk data %s\n", firmwareKey->getCStringNoCopy()); 435 | OSData* configuredData = loadFirmwareFiles(vendorId, productId, firmwareKey); 436 | #endif 437 | 438 | // Next try to load firmware from configuration 439 | if (!configuredData) 440 | { 441 | OSDictionary* firmwares = OSDynamicCast(OSDictionary, this->getProperty("Firmwares")); 442 | 443 | if (!firmwares) 444 | { 445 | AlwaysLog("Unable to locate BrcmFirmwareStore configured firmwares.\n"); 446 | return NULL; 447 | } 448 | 449 | configuredData = OSDynamicCast(OSData, firmwares->getObject(firmwareKey)); 450 | 451 | if (configuredData) 452 | { 453 | configuredData->retain(); 454 | AlwaysLog("Retrieved firmware \"%s\" from internal configuration.\n", firmwareKey->getCStringNoCopy()); 455 | } 456 | } 457 | 458 | if (!configuredData) 459 | { 460 | AlwaysLog("No firmware available for firmware key \"%s\".\n", firmwareKey->getCStringNoCopy()); 461 | return NULL; 462 | } 463 | 464 | OSData* firmwareData = decompressFirmware(configuredData); 465 | 466 | if (!firmwareData) 467 | { 468 | configuredData->release(); 469 | AlwaysLog("Failed to decompress firmware.\n"); 470 | return NULL; 471 | } 472 | 473 | if (configuredData->getLength() < firmwareData->getLength()) 474 | AlwaysLog("Decompressed firmware (%d bytes --> %d bytes).\n", configuredData->getLength(), firmwareData->getLength()); 475 | else 476 | AlwaysLog("Non-compressed firmware.\n"); 477 | 478 | configuredData->release(); 479 | 480 | #ifdef DEBUG 481 | SHA1_CTX ctx; 482 | uint8_t hash[SHA1_RESULTLEN]; 483 | SHA1Init(&ctx); 484 | SHA1Update(&ctx, firmwareData->getBytesNoCopy(), firmwareData->getLength()); 485 | SHA1Final(hash, &ctx); 486 | DebugLog("Firmware SHA1: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", 487 | hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], 488 | hash[10], hash[11], hash[12], hash[13], hash[14], hash[15], hash[16], hash[17], hash[18], hash[19]); 489 | #endif 490 | 491 | OSArray* instructions = parseFirmware(firmwareData); 492 | firmwareData->release(); 493 | 494 | if (!instructions) 495 | { 496 | AlwaysLog("Firmware is not valid IntelHex firmware.\n"); 497 | return NULL; 498 | } 499 | 500 | AlwaysLog("Firmware is valid IntelHex firmware.\n"); 501 | 502 | return instructions; 503 | } 504 | 505 | OSArray* BrcmFirmwareStore::getFirmware(UInt16 vendorId, UInt16 productId, OSString* firmwareKey) 506 | { 507 | DebugLog("getFirmware\n"); 508 | 509 | if (!firmwareKey || firmwareKey->getLength() == 0) 510 | { 511 | AlwaysLog("Current device has no FirmwareKey configured.\n"); 512 | return NULL; 513 | } 514 | 515 | IOLockLock(mDataLock); 516 | OSArray* instructions = OSDynamicCast(OSArray, mFirmwares->getObject(firmwareKey)); 517 | 518 | // Cached instructions found for firmwareKey? 519 | if (!instructions) 520 | { 521 | // Load instructions for firmwareKey 522 | instructions = loadFirmware(vendorId, productId, firmwareKey); 523 | 524 | // Add instructions to the firmwares cache 525 | if (instructions) 526 | { 527 | mFirmwares->setObject(firmwareKey, instructions); 528 | instructions->release(); 529 | } 530 | } 531 | else 532 | DebugLog("Retrieved cached firmware for \"%s\".\n", firmwareKey->getCStringNoCopy()); 533 | 534 | IOLockUnlock(mDataLock); 535 | 536 | return instructions; 537 | } 538 | 539 | 540 | -------------------------------------------------------------------------------- /BrcmPatchRAM/BrcmFirmwareStore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | */ 19 | 20 | #ifndef __BrcmPatchRAM__BrcmFirmwareStore__ 21 | #define __BrcmPatchRAM__BrcmFirmwareStore__ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #define kBrcmFirmwareCompressed "zhx" 28 | #define kBrmcmFirwareUncompressed "hex" 29 | 30 | #define kBrcmFirmwareStoreService "BrcmFirmwareStore" 31 | 32 | class BrcmFirmwareStore : public IOService 33 | { 34 | private: 35 | typedef IOService super; 36 | OSDeclareDefaultStructors(BrcmFirmwareStore); 37 | 38 | struct ResourceCallbackContext 39 | { 40 | BrcmFirmwareStore* me; 41 | OSData* firmware; 42 | }; 43 | 44 | IOLock* mDataLock; 45 | OSDictionary* mFirmwares; 46 | IOLock* mCompletionLock = NULL; 47 | 48 | OSData* decompressFirmware(OSData* firmware); 49 | OSArray* parseFirmware(OSData* firmwareData); 50 | static void requestResourceCallback(OSKextRequestTag requestTag, OSReturn result, const void * resourceData, uint32_t resourceDataLength, void* context); 51 | OSData* loadFirmwareFile(const char* filename, const char* suffix); 52 | OSData* loadFirmwareFiles(UInt16 vendorId, UInt16 productId, OSString* firmwareIdentifier); 53 | OSArray* loadFirmware(UInt16 vendorId, UInt16 productId, OSString* firmwareIdentifier); 54 | 55 | public: 56 | bool start(IOService *provider) override; 57 | void stop(IOService *provider) override; 58 | 59 | virtual OSArray* getFirmware(UInt16 vendorId, UInt16 productId, OSString* firmwareIdentifier); 60 | }; 61 | 62 | #endif /* defined(__BrcmPatchRAM__BrcmFirmwareStore__) */ 63 | -------------------------------------------------------------------------------- /BrcmPatchRAM/BrcmPatchRAM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | */ 19 | #ifndef __BrcmPatchRAM__ 20 | #define __BrcmPatchRAM__ 21 | 22 | #if defined(TARGET_ELCAPITAN) || defined(TARGET_CATALINA) 23 | // 10.11 works better if probe simply exits after updating firmware 24 | #define NON_RESIDENT 1 25 | #endif 26 | 27 | #include 28 | #include 29 | 30 | #include "BrcmFirmwareStore.h" 31 | #include "USBDeviceShim.h" 32 | 33 | #define kDisplayName "DisplayName" 34 | #define kBundleIdentifier "CFBundleIdentifier" 35 | #define kIOUSBDeviceClassName "IOUSBDevice" 36 | #ifndef kIOUSBHostDeviceClassName 37 | #define kIOUSBHostDeviceClassName "IOUSBHostDevice" 38 | #endif 39 | #define kAppleBundlePrefix "com.apple." 40 | #define kFirmwareKey "FirmwareKey" 41 | #define kFirmwareLoaded "FirmwareLoaded" 42 | 43 | enum DeviceState 44 | { 45 | kUnknown, 46 | kPreInitialize, 47 | kInitialize, 48 | kFirmwareVersion, 49 | kMiniDriverComplete, 50 | kInstructionWrite, 51 | kInstructionWritten, 52 | kFirmwareWritten, 53 | kResetWrite, 54 | kResetComplete, 55 | kUpdateComplete, 56 | kUpdateNotNeeded, 57 | kUpdateAborted, 58 | }; 59 | 60 | typedef struct DeviceHskSupport 61 | { 62 | UInt16 vid; 63 | UInt16 did; 64 | } DeviceHskSupport; 65 | 66 | #if defined(TARGET_CATALINA) 67 | #define BrcmPatchRAM BrcmPatchRAM3 68 | #elif defined(TARGET_ELCAPITAN) 69 | #define BrcmPatchRAM BrcmPatchRAM2 70 | #endif 71 | 72 | extern "C" 73 | { 74 | kern_return_t BrcmPatchRAM_Start(kmod_info_t*, void*); 75 | kern_return_t BrcmPatchRAM_Stop(kmod_info_t*, void*); 76 | } 77 | 78 | class BrcmPatchRAM : public IOService 79 | { 80 | private: 81 | typedef IOService super; 82 | #if defined(TARGET_CATALINA) 83 | OSDeclareDefaultStructors(BrcmPatchRAM3); 84 | #elif defined(TARGET_ELCAPITAN) 85 | OSDeclareDefaultStructors(BrcmPatchRAM2); 86 | #else 87 | OSDeclareDefaultStructors(BrcmPatchRAM); 88 | #endif 89 | 90 | UInt16 mVendorId = 0xFFFF; 91 | UInt16 mProductId = 0xFFFF; 92 | #ifndef TARGET_CATALINA 93 | UInt32 mProbeDelay = 0; 94 | #endif 95 | UInt32 mPreResetDelay = 0; 96 | UInt32 mPostResetDelay = 0; 97 | UInt32 mInitialDelay = 0; 98 | 99 | USBDeviceShim mDevice; 100 | USBInterfaceShim mInterface; 101 | USBPipeShim mInterruptPipe; 102 | USBPipeShim mBulkPipe; 103 | BrcmFirmwareStore* mFirmwareStore = NULL; 104 | #ifndef NON_RESIDENT 105 | bool mStopping = false; 106 | #endif 107 | bool mSupportsHandshake = false; 108 | 109 | USBCOMPLETION mInterruptCompletion {}; 110 | IOBufferMemoryDescriptor* mReadBuffer = NULL; 111 | 112 | volatile DeviceState mDeviceState = kInitialize; 113 | volatile uint16_t mFirmwareVersion = 0xFFFF; 114 | IOLock* mCompletionLock = NULL; 115 | 116 | #ifdef DEBUG 117 | static const char* getState(DeviceState deviceState); 118 | #endif 119 | 120 | #ifndef TARGET_CATALINA 121 | static OSString* brcmBundleIdentifier; 122 | static OSString* brcmIOClass; 123 | static OSString* brcmProviderClass; 124 | static void initBrcmStrings(); 125 | #endif 126 | 127 | #ifdef DEBUG 128 | void printPersonalities(); 129 | #endif 130 | 131 | #ifndef NON_RESIDENT 132 | UInt32 mBlurpWait = 0; 133 | IOTimerEventSource* mTimer = NULL; 134 | IOReturn onTimerEvent(void); 135 | 136 | static void uploadFirmwareThread(void* arg, wait_result_t wait); 137 | thread_t mWorker = 0; 138 | 139 | IOInterruptEventSource* mWorkSource = NULL; 140 | IOLock* mWorkLock = NULL; 141 | static IOLock* mLoadFirmwareLock; 142 | friend kern_return_t BrcmPatchRAM_Start(kmod_info_t*, void*); 143 | friend kern_return_t BrcmPatchRAM_Stop(kmod_info_t*, void*); 144 | 145 | enum WorkPending 146 | { 147 | kWorkLoadFirmware = 0x01, 148 | kWorkFinished = 0x02, 149 | }; 150 | unsigned mWorkPending = 0; 151 | void scheduleWork(unsigned newWork); 152 | void processWorkQueue(IOInterruptEventSource*, int); 153 | #endif // #ifndef NON_RESIDENT 154 | 155 | #ifndef TARGET_CATALINA 156 | void publishPersonality(); 157 | #endif 158 | 159 | #ifndef NON_RESIDENT 160 | #if (!defined(TARGET_ELCAPITAN)) && (!defined(TARGET_CATALINA)) 161 | void removePersonality(); 162 | #endif 163 | #endif 164 | #ifndef TARGET_CATALINA 165 | bool publishResourcePersonality(const char* classname); 166 | #endif 167 | BrcmFirmwareStore* getFirmwareStore(); 168 | void uploadFirmware(); 169 | 170 | void printDeviceInfo(); 171 | int getDeviceStatus(); 172 | 173 | bool setConfiguration(int configurationIndex); 174 | 175 | bool findInterface(USBInterfaceShim* interface); 176 | bool findPipe(USBPipeShim* pipe, uint8_t type, uint8_t direction); 177 | 178 | bool continuousRead(); 179 | #if defined(TARGET_ELCAPITAN) || defined(TARGET_CATALINA) 180 | static void readCompletion(void* target, void* parameter, IOReturn status, uint32_t bytesTransferred); 181 | #else 182 | static void readCompletion(void* target, void* parameter, IOReturn status, UInt32 bufferSizeRemaining); 183 | #endif 184 | 185 | IOReturn hciCommand(void * command, uint16_t length); 186 | IOReturn hciParseResponse(void* response, uint16_t length, void* output, uint8_t* outputLength); 187 | 188 | IOReturn bulkWrite(const void* data, uint16_t length); 189 | 190 | uint16_t getFirmwareVersion(); 191 | 192 | bool performUpgrade(); 193 | bool supportsHandshake(UInt16 vid, UInt16 did); 194 | public: 195 | IOService* probe(IOService *provider, SInt32 *probeScore) override; 196 | #if defined(TARGET_CATALINA) || (!defined(NON_RESIDENT)) 197 | bool start(IOService* provider) override; 198 | void stop(IOService* provider) override; 199 | IOReturn setPowerState(unsigned long which, IOService *whom) override; 200 | #endif 201 | 202 | const char* stringFromReturn(IOReturn rtn) override; 203 | 204 | #ifdef TARGET_CATALINA 205 | bool init(OSDictionary *properties) override; 206 | void free() override; 207 | #endif 208 | }; 209 | 210 | #if defined(NON_RESIDENT) && (!defined(TARGET_CATALINA)) 211 | 212 | #define kBrcmPatchRAMResidency "BrcmPatchRAMResidency" 213 | class BrcmPatchRAMResidency : public IOService 214 | { 215 | private: 216 | typedef IOService super; 217 | OSDeclareDefaultStructors(BrcmPatchRAMResidency); 218 | 219 | public: 220 | bool start(IOService *provider) override; 221 | }; 222 | 223 | #endif //defined(NON_RESIDENT) && (!defined(TARGET_CATALINA)) 224 | 225 | #endif //__BrcmPatchRAM__ 226 | -------------------------------------------------------------------------------- /BrcmPatchRAM/Common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | */ 19 | 20 | #ifndef BRCMPatchRAM_Common_h 21 | #define BRCMPatchRAM_Common_h 22 | 23 | #ifndef TARGET_ELCAPITAN 24 | #define BRCMPATCHRAM_NAME "BrcmPatchRAM" 25 | #else 26 | #define BRCMPATCHRAM_NAME "BrcmPatchRAM2" 27 | #endif 28 | 29 | #ifdef DEBUG 30 | #define DebugLog(args...) do { IOLog(BRCMPATCHRAM_NAME ": " args); } while (0) 31 | #else 32 | #define DebugLog(args...) do { } while (0) 33 | #endif 34 | #define AlwaysLog(args...) do { IOLog(BRCMPATCHRAM_NAME ": " args); } while (0) 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /BrcmPatchRAM/FirmwareData.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | */ 19 | 20 | #include "Common.h" 21 | #include "FirmwareData.h" 22 | #include "../GeneratedFirmwares.cpp" 23 | 24 | #include 25 | 26 | OSData* lookupFirmware(const char* filename) 27 | { 28 | OSData* result = NULL; 29 | for (const FirmwareEntry* entry = firmwares; entry->filename != NULL; entry++) 30 | { 31 | if (0 == strcmp(filename, entry->filename)) 32 | { 33 | result = OSData::withBytes(entry->firmwareData, (unsigned int)entry->firmwareSize); 34 | break; 35 | } 36 | } 37 | return result; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /BrcmPatchRAM/FirmwareData.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | */ 19 | 20 | #ifndef _FIRMWAREDATA_H 21 | #define _FIRMWAREDATA_H 22 | 23 | #include 24 | 25 | struct FirmwareEntry 26 | { 27 | const char* filename; 28 | const unsigned char* firmwareData; 29 | size_t firmwareSize; 30 | }; 31 | 32 | OSData* lookupFirmware(const char* filename); 33 | 34 | #endif//_FIRMWAREDATA_H 35 | -------------------------------------------------------------------------------- /BrcmPatchRAM/USBDeviceShim.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | */ 19 | 20 | #include "USBDeviceShim.h" 21 | #include "Common.h" 22 | 23 | #include 24 | 25 | USBDeviceShim::USBDeviceShim() 26 | { 27 | m_pDevice = NULL; 28 | } 29 | 30 | void USBDeviceShim::setDevice(IOService* provider) 31 | { 32 | OSObject* prev = m_pDevice; 33 | 34 | m_pDevice = OSDynamicCast(IOUSBDevice, provider); 35 | 36 | if (m_pDevice) 37 | m_pDevice->retain(); 38 | 39 | if (prev) 40 | prev->release(); 41 | } 42 | 43 | UInt16 USBDeviceShim::getVendorID() 44 | { 45 | return m_pDevice->GetVendorID(); 46 | } 47 | 48 | UInt16 USBDeviceShim::getProductID() 49 | { 50 | return m_pDevice->GetProductID(); 51 | } 52 | 53 | OSObject* USBDeviceShim::getProperty(const char* name) 54 | { 55 | return m_pDevice->getProperty(name); 56 | } 57 | 58 | void USBDeviceShim::setProperty(const char* name, bool value) 59 | { 60 | m_pDevice->setProperty(name, value); 61 | } 62 | 63 | void USBDeviceShim::removeProperty(const char* name) 64 | { 65 | m_pDevice->removeProperty(name); 66 | } 67 | 68 | IOReturn USBDeviceShim::getStringDescriptor(UInt8 index, char *buf, int maxLen, UInt16 lang) 69 | { 70 | return m_pDevice->GetStringDescriptor(index, buf, maxLen, lang); 71 | } 72 | 73 | UInt16 USBDeviceShim::getDeviceRelease() 74 | { 75 | return m_pDevice->GetDeviceRelease(); 76 | } 77 | 78 | IOReturn USBDeviceShim::getDeviceStatus(IOService* forClient, USBStatus *status) 79 | { 80 | return m_pDevice->GetDeviceStatus(status); 81 | } 82 | 83 | IOReturn USBDeviceShim::resetDevice() 84 | { 85 | return m_pDevice->ResetDevice(); 86 | } 87 | 88 | UInt8 USBDeviceShim::getNumConfigurations() 89 | { 90 | return m_pDevice->GetNumConfigurations(); 91 | } 92 | 93 | const USBCONFIGURATIONDESCRIPTOR* USBDeviceShim::getFullConfigurationDescriptor(UInt8 configIndex) 94 | { 95 | return m_pDevice->GetFullConfigurationDescriptor(configIndex); 96 | } 97 | 98 | IOReturn USBDeviceShim::getConfiguration(IOService* forClient, UInt8 *configNumber) 99 | { 100 | return m_pDevice->GetConfiguration(configNumber); 101 | } 102 | 103 | IOReturn USBDeviceShim::setConfiguration(IOService *forClient, UInt8 configValue, bool startInterfaceMatching) 104 | { 105 | return m_pDevice->SetConfiguration(forClient, configValue, startInterfaceMatching); 106 | } 107 | 108 | bool USBDeviceShim::findFirstInterface(USBInterfaceShim* shim) 109 | { 110 | DebugLog("USBDeviceShim::findFirstInterface\n"); 111 | 112 | IOUSBFindInterfaceRequest request; 113 | request.bAlternateSetting = kIOUSBFindInterfaceDontCare; 114 | request.bInterfaceClass = kIOUSBFindInterfaceDontCare; 115 | request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; 116 | request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; 117 | IOUSBInterface* interface = m_pDevice->FindNextInterface(NULL, &request); 118 | DebugLog("FindNextInterface returns %p\n", interface); 119 | shim->setInterface(interface); 120 | 121 | DebugLog("getValidatedInterface returns %p\n", shim->getValidatedInterface()); 122 | return shim->getValidatedInterface() != NULL; 123 | } 124 | 125 | bool USBDeviceShim::open(IOService *forClient, IOOptionBits options, void *arg) 126 | { 127 | return m_pDevice->open(forClient, options, arg); 128 | } 129 | 130 | void USBDeviceShim::close(IOService *forClient, IOOptionBits options) 131 | { 132 | return m_pDevice->close(forClient, options); 133 | } 134 | 135 | UInt8 USBDeviceShim::getManufacturerStringIndex() 136 | { 137 | return m_pDevice->GetManufacturerStringIndex(); 138 | } 139 | 140 | UInt8 USBDeviceShim::getProductStringIndex() 141 | { 142 | return m_pDevice->GetProductStringIndex(); 143 | } 144 | UInt8 USBDeviceShim::getSerialNumberStringIndex() 145 | { 146 | return m_pDevice->GetSerialNumberStringIndex(); 147 | } 148 | 149 | USBInterfaceShim::USBInterfaceShim() 150 | { 151 | m_pInterface = NULL; 152 | } 153 | 154 | void USBInterfaceShim::setInterface(IOService* interface) 155 | { 156 | OSObject* prev = m_pInterface; 157 | 158 | m_pInterface = OSDynamicCast(IOUSBInterface, interface); 159 | 160 | if (m_pInterface) 161 | m_pInterface->retain(); 162 | if (prev) 163 | prev->release(); 164 | } 165 | 166 | bool USBInterfaceShim::open(IOService *forClient, IOOptionBits options, void *arg) 167 | { 168 | bool result = m_pInterface->open(forClient, options, arg); 169 | if (!result) 170 | AlwaysLog("USBInterfaceShim:open failed\n"); 171 | return result; 172 | } 173 | 174 | void USBInterfaceShim::close(IOService *forClient, IOOptionBits options) 175 | { 176 | m_pInterface->close(forClient, options); 177 | } 178 | 179 | #ifdef DEBUG 180 | UInt8 USBInterfaceShim::getInterfaceNumber() 181 | { 182 | return m_pInterface->GetInterfaceNumber(); 183 | } 184 | 185 | UInt8 USBInterfaceShim::getInterfaceClass() 186 | { 187 | return m_pInterface->GetInterfaceClass(); 188 | } 189 | 190 | UInt8 USBInterfaceShim::getInterfaceSubClass() 191 | { 192 | return m_pInterface->GetInterfaceSubClass(); 193 | } 194 | 195 | UInt8 USBInterfaceShim::getInterfaceProtocol() 196 | { 197 | return m_pInterface->GetInterfaceProtocol(); 198 | } 199 | #endif 200 | 201 | bool USBInterfaceShim::findPipe(USBPipeShim* shim, UInt8 type, UInt8 direction) 202 | { 203 | IOUSBFindEndpointRequest findEndpointRequest; 204 | findEndpointRequest.type = type; 205 | findEndpointRequest.direction = direction; 206 | if (IOUSBPipe* pipe = m_pInterface->FindNextPipe(NULL, &findEndpointRequest)) 207 | { 208 | shim->setPipe(pipe); 209 | return true; 210 | } 211 | return false; 212 | } 213 | 214 | IOReturn USBInterfaceShim::hciCommand(void* command, UInt16 length) 215 | { 216 | IOUSBDevRequest request = 217 | { 218 | .bmRequestType = USBmakebmRequestType(kUSBOut, kUSBClass, kUSBDevice), 219 | .bRequest = 0, 220 | .wValue = 0, 221 | .wIndex = 0, 222 | .wLength = length, 223 | .pData = command 224 | }; 225 | return m_pInterface->DeviceRequest(&request); 226 | } 227 | 228 | USBPipeShim::USBPipeShim() 229 | { 230 | m_pPipe = NULL; 231 | } 232 | 233 | void USBPipeShim::setPipe(OSObject* pipe) 234 | { 235 | OSObject* prev = m_pPipe; 236 | m_pPipe = OSDynamicCast(IOUSBPipe, pipe); 237 | 238 | if (m_pPipe) 239 | m_pPipe->retain(); 240 | if (prev) 241 | prev->release(); 242 | } 243 | 244 | IOReturn USBPipeShim::abort(void) 245 | { 246 | return m_pPipe->Abort(); 247 | } 248 | 249 | /*! 250 | * @brief Issue an asynchronous I/O request 251 | * 252 | * @discussion See IOUSBHostIOSource::io for documentation 253 | * 254 | * @param completionTimeoutMs Must be 0 for interrupt endpoints. 255 | */ 256 | //virtual IOReturn io(IOMemoryDescriptor* dataBuffer, uint32_t dataBufferLength, IOUSBHostCompletion* completion, uint32_t completionTimeoutMs = 0); 257 | 258 | /*! 259 | * @brief Issue a synchronous I/O request 260 | * 261 | * @discussion See IOUSBHostIOSource::io for documentation 262 | * 263 | * @param completionTimeoutMs Must be 0 for interrupt endpoints. 264 | */ 265 | //virtual IOReturn io(IOMemoryDescriptor* dataBuffer, uint32_t dataBufferLength, uint32_t& bytesTransferred, uint32_t completionTimeoutMs = 0); 266 | 267 | IOReturn USBPipeShim::read(IOMemoryDescriptor * buffer, 268 | UInt32 noDataTimeout, 269 | UInt32 completionTimeout, 270 | IOByteCount reqCount, 271 | USBCOMPLETION * completion, 272 | IOByteCount * bytesRead) 273 | { 274 | return m_pPipe->Read(buffer, noDataTimeout, completionTimeout, reqCount, completion, bytesRead); 275 | } 276 | 277 | IOReturn USBPipeShim::write(IOMemoryDescriptor * buffer, 278 | UInt32 noDataTimeout, 279 | UInt32 completionTimeout, 280 | IOByteCount reqCount, 281 | USBCOMPLETION * completion) 282 | { 283 | return m_pPipe->Write(buffer, noDataTimeout, completionTimeout, reqCount, completion); 284 | } 285 | 286 | const USBENDPOINTDESCRIPTOR* USBPipeShim::getEndpointDescriptor() 287 | { 288 | return m_pPipe->GetEndpointDescriptor(); 289 | } 290 | 291 | IOReturn USBPipeShim::clearStall() 292 | { 293 | return m_pPipe->Reset(); 294 | } 295 | -------------------------------------------------------------------------------- /BrcmPatchRAM/USBDeviceShim.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | */ 19 | 20 | #ifndef __USBDeviceShim__ 21 | #define __USBDeviceShim__ 22 | 23 | #if defined(TARGET_ELCAPITAN) || defined(TARGET_CATALINA) 24 | #include 25 | #else 26 | #include 27 | #endif 28 | 29 | #if defined(TARGET_ELCAPITAN) || defined(TARGET_CATALINA) 30 | #define USBCOMPLETION IOUSBHostCompletion 31 | #define USBCONFIGURATIONDESCRIPTOR StandardUSB::ConfigurationDescriptor 32 | #define USBENDPOINTDESCRIPTOR StandardUSB::EndpointDescriptor 33 | #define USBStatus uint16_t 34 | #else 35 | #define USBCOMPLETION IOUSBCompletion 36 | #define USBCONFIGURATIONDESCRIPTOR IOUSBConfigurationDescriptor 37 | #define USBENDPOINTDESCRIPTOR IOUSBEndpointDescriptor 38 | #endif 39 | 40 | class USBPipeShim; 41 | class USBInterfaceShim; 42 | 43 | class USBDeviceShim 44 | { 45 | private: 46 | #if defined(TARGET_ELCAPITAN) || defined(TARGET_CATALINA) 47 | IOUSBHostDevice* m_pDevice; // 10.11+ 48 | #else 49 | IOUSBDevice* m_pDevice; 50 | #endif 51 | 52 | public: 53 | USBDeviceShim(); 54 | void setDevice(IOService* provider); 55 | inline IOService* getValidatedDevice() { return m_pDevice; } 56 | 57 | UInt16 getVendorID(); 58 | UInt16 getProductID(); 59 | OSObject* getProperty(const char* name); 60 | void setProperty(const char* name, bool value); 61 | void removeProperty(const char* name); 62 | IOReturn getStringDescriptor(UInt8 index, char *buf, int maxLen, UInt16 lang=0x409); 63 | UInt16 getDeviceRelease(); 64 | IOReturn getDeviceStatus(IOService* forClient, USBStatus *status); 65 | IOReturn resetDevice(); 66 | UInt8 getNumConfigurations(); 67 | const USBCONFIGURATIONDESCRIPTOR* getFullConfigurationDescriptor(UInt8 configIndex); 68 | IOReturn getConfiguration(IOService* forClient, UInt8 *configNumber); 69 | IOReturn setConfiguration(IOService *forClient, UInt8 configValue, bool startInterfaceMatching=true); 70 | bool findFirstInterface(USBInterfaceShim* shim); 71 | bool open(IOService *forClient, IOOptionBits options = 0, void *arg = 0 ); 72 | void close(IOService *forClient, IOOptionBits options = 0); 73 | UInt8 getManufacturerStringIndex(); 74 | UInt8 getProductStringIndex(); 75 | UInt8 getSerialNumberStringIndex(); 76 | }; 77 | 78 | class USBInterfaceShim 79 | { 80 | private: 81 | #if defined(TARGET_ELCAPITAN) || defined(TARGET_CATALINA) 82 | IOUSBHostInterface* m_pInterface; // 10.11+ 83 | #else 84 | IOUSBInterface* m_pInterface; 85 | #endif 86 | 87 | public: 88 | USBInterfaceShim(); 89 | void setInterface(IOService* interface); 90 | inline IOService* getValidatedInterface() { return (IOService*)m_pInterface; } 91 | 92 | bool open(IOService *forClient, IOOptionBits options = 0, void *arg = 0 ); 93 | void close(IOService *forClient, IOOptionBits options = 0); 94 | 95 | #ifdef DEBUG 96 | UInt8 getInterfaceNumber(); 97 | UInt8 getInterfaceClass(); 98 | UInt8 getInterfaceSubClass(); 99 | UInt8 getInterfaceProtocol(); 100 | #endif 101 | 102 | bool findPipe(USBPipeShim* shim, uint8_t type, uint8_t direction); 103 | 104 | IOReturn hciCommand(void * command, UInt16 length); 105 | }; 106 | 107 | class USBPipeShim 108 | { 109 | private: 110 | #if defined(TARGET_ELCAPITAN) || defined(TARGET_CATALINA) 111 | IOUSBHostPipe* m_pPipe; // 10.11+ 112 | #else 113 | IOUSBPipe* m_pPipe; 114 | #endif 115 | 116 | public: 117 | USBPipeShim(); 118 | void setPipe(OSObject* pipe); 119 | inline OSObject* getValidatedPipe() { return m_pPipe; } 120 | 121 | IOReturn abort(void); 122 | 123 | IOReturn read(IOMemoryDescriptor * buffer, 124 | UInt32 noDataTimeout, 125 | UInt32 completionTimeout, 126 | IOByteCount reqCount, 127 | USBCOMPLETION * completion = 0, 128 | IOByteCount * bytesRead = 0); 129 | IOReturn write(IOMemoryDescriptor * buffer, 130 | UInt32 noDataTimeout, 131 | UInt32 completionTimeout, 132 | IOByteCount reqCount, 133 | USBCOMPLETION * completion = 0); 134 | const USBENDPOINTDESCRIPTOR* getEndpointDescriptor(); 135 | IOReturn clearStall(void); 136 | }; 137 | 138 | #endif /* __USBDeviceShim__ */ 139 | -------------------------------------------------------------------------------- /BrcmPatchRAM/USBHostDeviceShim.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | */ 19 | 20 | #include "USBDeviceShim.h" 21 | #include "Common.h" 22 | 23 | #include 24 | 25 | #include 26 | 27 | USBDeviceShim::USBDeviceShim() 28 | { 29 | m_pDevice = NULL; 30 | } 31 | 32 | void USBDeviceShim::setDevice(IOService* provider) 33 | { 34 | OSObject* prev = m_pDevice; 35 | 36 | m_pDevice = OSDynamicCast(IOUSBHostDevice, provider); 37 | 38 | if (m_pDevice) 39 | m_pDevice->retain(); 40 | 41 | if (prev) 42 | prev->release(); 43 | } 44 | 45 | UInt16 USBDeviceShim::getVendorID() 46 | { 47 | return USBToHost16(m_pDevice->getDeviceDescriptor()->idVendor); 48 | } 49 | 50 | UInt16 USBDeviceShim::getProductID() 51 | { 52 | return USBToHost16(m_pDevice->getDeviceDescriptor()->idProduct); 53 | } 54 | 55 | OSObject* USBDeviceShim::getProperty(const char* name) 56 | { 57 | return m_pDevice->getProperty(name); 58 | } 59 | 60 | void USBDeviceShim::setProperty(const char* name, bool value) 61 | { 62 | m_pDevice->setProperty(name, value); 63 | } 64 | 65 | void USBDeviceShim::removeProperty(const char* name) 66 | { 67 | m_pDevice->removeProperty(name); 68 | } 69 | 70 | IOReturn USBDeviceShim::getStringDescriptor(UInt8 index, char *buf, int maxLen, UInt16 lang) 71 | { 72 | memset(buf, 0, maxLen); 73 | 74 | const StringDescriptor* desc = m_pDevice->getStringDescriptor(index); 75 | 76 | if (!desc) 77 | return kIOReturnBadArgument; 78 | 79 | if (desc->bLength <= StandardUSB::kDescriptorSize) 80 | return kIOReturnBadArgument; 81 | 82 | size_t utf8len = 0; 83 | utf8_encodestr(reinterpret_cast(desc->bString), desc->bLength - StandardUSB::kDescriptorSize, reinterpret_cast(buf), &utf8len, maxLen, '/', UTF_LITTLE_ENDIAN); 84 | 85 | return kIOReturnSuccess; 86 | } 87 | 88 | UInt16 USBDeviceShim::getDeviceRelease() 89 | { 90 | return USBToHost16(m_pDevice->getDeviceDescriptor()->bcdDevice); 91 | } 92 | 93 | IOReturn USBDeviceShim::getDeviceStatus(IOService* forClient, USBStatus *status) 94 | { 95 | uint16_t stat = 0; 96 | StandardUSB::DeviceRequest request; 97 | request.bmRequestType = makeDeviceRequestbmRequestType(kRequestDirectionIn, kRequestTypeStandard, kRequestRecipientDevice); 98 | request.bRequest = kDeviceRequestGetStatus; 99 | request.wValue = 0; 100 | request.wIndex = 0; 101 | request.wLength = sizeof(stat); 102 | uint32_t bytesTransferred = 0; 103 | IOReturn result = m_pDevice->deviceRequest(forClient, request, &stat, bytesTransferred, kUSBHostStandardRequestCompletionTimeout); 104 | *status = stat; 105 | return result; 106 | } 107 | 108 | IOReturn USBDeviceShim::resetDevice() 109 | { 110 | // Setting configuration value 0 (unconfigured) releases all opened interfaces / pipes 111 | m_pDevice->setConfiguration(0); 112 | //m_pDevice->reset(); 113 | return kIOReturnSuccess; 114 | } 115 | 116 | UInt8 USBDeviceShim::getNumConfigurations() 117 | { 118 | return m_pDevice->getDeviceDescriptor()->bNumConfigurations; 119 | } 120 | 121 | const USBCONFIGURATIONDESCRIPTOR* USBDeviceShim::getFullConfigurationDescriptor(UInt8 configIndex) 122 | { 123 | return m_pDevice->getConfigurationDescriptor(configIndex); 124 | } 125 | 126 | IOReturn USBDeviceShim::getConfiguration(IOService* forClient, UInt8 *configNumber) 127 | { 128 | uint8_t config = 0; 129 | StandardUSB::DeviceRequest request; 130 | request.bmRequestType = makeDeviceRequestbmRequestType(kRequestDirectionIn, kRequestTypeStandard, kRequestRecipientDevice); 131 | request.bRequest = kDeviceRequestGetConfiguration; 132 | request.wValue = 0; 133 | request.wIndex = 0; 134 | request.wLength = sizeof(config); 135 | uint32_t bytesTransferred = 0; 136 | IOReturn result = m_pDevice->deviceRequest(forClient, request, &config, bytesTransferred, kUSBHostStandardRequestCompletionTimeout); 137 | *configNumber = config; 138 | return result; 139 | } 140 | 141 | IOReturn USBDeviceShim::setConfiguration(IOService *forClient, UInt8 configValue, bool startInterfaceMatching) 142 | { 143 | return m_pDevice->setConfiguration(configValue, startInterfaceMatching); 144 | } 145 | 146 | bool USBDeviceShim::findFirstInterface(USBInterfaceShim* shim) 147 | { 148 | DebugLog("USBDeviceShim::findFirstInterface\n"); 149 | 150 | OSIterator* iterator = m_pDevice->getChildIterator(gIOServicePlane); 151 | 152 | if (!iterator) 153 | return false; 154 | 155 | while (OSObject* candidate = iterator->getNextObject()) 156 | { 157 | if (IOUSBHostInterface* interface = OSDynamicCast(IOUSBHostInterface, candidate)) 158 | { 159 | //if (interface->getInterfaceDescriptor()->bInterfaceClass != kUSBHubClass) 160 | { 161 | shim->setInterface(interface); 162 | break; 163 | } 164 | } 165 | } 166 | 167 | iterator->release(); 168 | 169 | DebugLog("getValidatedInterface returns %p\n", shim->getValidatedInterface()); 170 | return shim->getValidatedInterface() != NULL; 171 | } 172 | 173 | bool USBDeviceShim::open(IOService *forClient, IOOptionBits options, void *arg) 174 | { 175 | return m_pDevice->open(forClient, options, arg); 176 | } 177 | 178 | void USBDeviceShim::close(IOService *forClient, IOOptionBits options) 179 | { 180 | return m_pDevice->close(forClient, options); 181 | } 182 | 183 | UInt8 USBDeviceShim::getManufacturerStringIndex() 184 | { 185 | return m_pDevice->getDeviceDescriptor()->iManufacturer; 186 | } 187 | 188 | UInt8 USBDeviceShim::getProductStringIndex() 189 | { 190 | return m_pDevice->getDeviceDescriptor()->iProduct; 191 | } 192 | 193 | UInt8 USBDeviceShim::getSerialNumberStringIndex() 194 | { 195 | return m_pDevice->getDeviceDescriptor()->iSerialNumber; 196 | } 197 | 198 | USBInterfaceShim::USBInterfaceShim() 199 | { 200 | m_pInterface = NULL; 201 | } 202 | 203 | void USBInterfaceShim::setInterface(IOService* interface) 204 | { 205 | OSObject* prev = m_pInterface; 206 | 207 | m_pInterface = OSDynamicCast(IOUSBHostInterface, interface); 208 | 209 | if (m_pInterface) 210 | m_pInterface->retain(); 211 | if (prev) 212 | prev->release(); 213 | } 214 | 215 | bool USBInterfaceShim::open(IOService *forClient, IOOptionBits options, void *arg) 216 | { 217 | bool result = m_pInterface->open(forClient, options, arg); 218 | if (!result) 219 | AlwaysLog("USBInterfaceShim:open failed\n"); 220 | return result; 221 | } 222 | 223 | void USBInterfaceShim::close(IOService *forClient, IOOptionBits options) 224 | { 225 | m_pInterface->close(forClient, options); 226 | } 227 | 228 | #ifdef DEBUG 229 | UInt8 USBInterfaceShim::getInterfaceNumber() 230 | { 231 | return m_pInterface->getInterfaceDescriptor()->bInterfaceNumber; 232 | } 233 | 234 | UInt8 USBInterfaceShim::getInterfaceClass() 235 | { 236 | return m_pInterface->getInterfaceDescriptor()->bInterfaceClass; 237 | } 238 | 239 | UInt8 USBInterfaceShim::getInterfaceSubClass() 240 | { 241 | return m_pInterface->getInterfaceDescriptor()->bInterfaceSubClass; 242 | } 243 | 244 | UInt8 USBInterfaceShim::getInterfaceProtocol() 245 | { 246 | return m_pInterface->getInterfaceDescriptor()->bInterfaceProtocol; 247 | } 248 | #endif 249 | 250 | bool USBInterfaceShim::findPipe(USBPipeShim* shim, UInt8 type, UInt8 direction) 251 | { 252 | // virtual IOUSBHostPipe* FindNextPipe(IOUSBHostPipe* current, IOUSBFindEndpointRequest* request) __attribute__((deprecated)); 253 | // virtual IOUSBHostPipe* FindNextPipe(IOUSBHostPipe* current, IOUSBFindEndpointRequest* request, bool withRetain) __attribute__((deprecated)); 254 | // Replacement: getInterfaceDescriptor and StandardUSB::getNextAssociatedDescriptorWithType to find an endpoint descriptor, 255 | // then use copyPipe to retrieve the pipe object 256 | // virtual const StandardUSB::InterfaceDescriptor* getInterfaceDescriptor(); 257 | // const Descriptor* getNextAssociatedDescriptorWithType(const ConfigurationDescriptor* configurationDescriptor, const Descriptor* parentDescriptor, const Descriptor* currentDescriptor, const uint8_t type); 258 | 259 | // 260 | /*! 261 | * @brief Return the configuration descriptor in which this interface is defined 262 | * 263 | * @return Pointer to the configuration descriptor 264 | */ 265 | //virtual const StandardUSB::ConfigurationDescriptor* getConfigurationDescriptor(); 266 | 267 | /*! 268 | * @brief Return the pipe whose bEndpointAddress matches address 269 | * 270 | * @discussion This method will return the pipe whose bEndpointAddress matches address. If 271 | * the pipe doesn't exist yet, but is part of the interface, it will first be created. This method returns a 272 | * retain()ed object that must be release()ed by the caller. 273 | * 274 | * @param address Address of the pipe 275 | * 276 | * @return Pointer to a retain()ed IOUSBHostPipe object or NULL 277 | */ 278 | //virtual IOUSBHostPipe* copyPipe(uint8_t address); 279 | 280 | // USB 2.0 9.5: Descriptors 281 | //struct Descriptor 282 | //{ 283 | // uint8_t bLength; 284 | // uint8_t bDescriptorType; 285 | //} __attribute__((packed)); 286 | // 287 | //typedef struct Descriptor Descriptor; 288 | 289 | // USB 2.0 9.6.5: Interface 290 | //struct InterfaceDescriptor : public Descriptor 291 | //{ 292 | // uint8_t bInterfaceNumber; 293 | // uint8_t bAlternateSetting; 294 | // uint8_t bNumEndpoints; 295 | // uint8_t bInterfaceClass; 296 | // uint8_t bInterfaceSubClass; 297 | // uint8_t bInterfaceProtocol; 298 | // uint8_t iInterface; 299 | //} __attribute__((packed)); 300 | //typedef struct InterfaceDescriptor InterfaceDescriptor; 301 | 302 | // USB 2.0 9.6.6: Endpoint 303 | //struct EndpointDescriptor : public Descriptor 304 | //{ 305 | // uint8_t bEndpointAddress; 306 | // uint8_t bmAttributes; 307 | // uint16_t wMaxPacketSize; 308 | // uint8_t bInterval; 309 | //} __attribute__((packed)); 310 | //typedef struct EndpointDescriptor EndpointDescriptor; 311 | 312 | //const EndpointDescriptor* getNextEndpointDescriptor(const ConfigurationDescriptor* configurationDescriptor, const InterfaceDescriptor* interfaceDescriptor, const Descriptor* currentDescriptor); 313 | 314 | DebugLog("findPipe: direction = %d, type = %d\n", direction, type); 315 | const StandardUSB::ConfigurationDescriptor* configDesc = m_pInterface->getConfigurationDescriptor(); 316 | const StandardUSB::InterfaceDescriptor* ifaceDesc = m_pInterface->getInterfaceDescriptor(); 317 | if (!configDesc || !ifaceDesc) 318 | { 319 | DebugLog("configDesc = %p, ifaceDesc = %p\n", configDesc, ifaceDesc); 320 | return false; 321 | } 322 | const EndpointDescriptor* ep = NULL; 323 | while ((ep = StandardUSB::getNextEndpointDescriptor(configDesc, ifaceDesc, ep))) 324 | { 325 | // check if endpoint matches type and direction 326 | uint8_t epDirection = StandardUSB::getEndpointDirection(ep); 327 | uint8_t epType = StandardUSB::getEndpointType(ep); 328 | DebugLog("endpoint found: epDirection = %d, epType = %d\n", epDirection, epType); 329 | if (direction == epDirection && type == epType) 330 | { 331 | DebugLog("found matching endpoint\n"); 332 | 333 | // matches... try to make a pipe from the endpoint address 334 | IOUSBHostPipe* pipe = m_pInterface->copyPipe(StandardUSB::getEndpointAddress(ep)); 335 | if (pipe == NULL) 336 | { 337 | DebugLog("copyPipe failed\n"); 338 | return false; 339 | } 340 | 341 | // set it in the shim 342 | shim->setPipe(pipe); 343 | pipe->release(); 344 | return true; 345 | } 346 | } 347 | DebugLog("findPipe: no matching endpoint found"); 348 | return false; 349 | } 350 | 351 | IOReturn USBInterfaceShim::hciCommand(void* command, UInt16 length) 352 | { 353 | StandardUSB::DeviceRequest request = 354 | { 355 | .bmRequestType = makeDeviceRequestbmRequestType(kRequestDirectionOut, kRequestTypeClass, kRequestRecipientDevice), 356 | .bRequest = 0, 357 | .wValue = 0, 358 | .wIndex = 0, 359 | .wLength = length 360 | }; 361 | 362 | uint32_t bytesTransfered; 363 | return m_pInterface->deviceRequest(request, command, bytesTransfered, 0); 364 | } 365 | 366 | USBPipeShim::USBPipeShim() 367 | { 368 | m_pPipe = NULL; 369 | } 370 | 371 | void USBPipeShim::setPipe(OSObject* pipe) 372 | { 373 | OSObject* prev = m_pPipe; 374 | m_pPipe = OSDynamicCast(IOUSBHostPipe, pipe); 375 | 376 | if (m_pPipe) 377 | m_pPipe->retain(); 378 | if (prev) 379 | prev->release(); 380 | } 381 | 382 | IOReturn USBPipeShim::abort(void) 383 | { 384 | return m_pPipe->abort(); 385 | } 386 | 387 | /*! 388 | * @brief Issue an asynchronous I/O request 389 | * 390 | * @discussion See IOUSBHostIOSource::io for documentation 391 | * 392 | * @param completionTimeoutMs Must be 0 for interrupt endpoints. 393 | */ 394 | //virtual IOReturn io(IOMemoryDescriptor* dataBuffer, uint32_t dataBufferLength, IOUSBHostCompletion* completion, uint32_t completionTimeoutMs = 0); 395 | 396 | /*! 397 | * @brief Issue a synchronous I/O request 398 | * 399 | * @discussion See IOUSBHostIOSource::io for documentation 400 | * 401 | * @param completionTimeoutMs Must be 0 for interrupt endpoints. 402 | */ 403 | //virtual IOReturn io(IOMemoryDescriptor* dataBuffer, uint32_t dataBufferLength, uint32_t& bytesTransferred, uint32_t completionTimeoutMs = 0); 404 | 405 | IOReturn USBPipeShim::read(IOMemoryDescriptor * buffer, 406 | UInt32 noDataTimeout, 407 | UInt32 completionTimeout, 408 | IOByteCount reqCount, 409 | USBCOMPLETION * completion, 410 | IOByteCount * bytesRead) 411 | { 412 | IOReturn result; 413 | if (completion) 414 | result = m_pPipe->io(buffer, (uint32_t)reqCount, completion, completionTimeout); 415 | else 416 | { 417 | uint32_t bytesTransfered; 418 | result = m_pPipe->io(buffer, (uint32_t)reqCount, bytesTransfered, completionTimeout); 419 | if (bytesRead) *bytesRead = bytesTransfered; 420 | } 421 | return result; 422 | } 423 | 424 | IOReturn USBPipeShim::write(IOMemoryDescriptor * buffer, 425 | UInt32 noDataTimeout, 426 | UInt32 completionTimeout, 427 | IOByteCount reqCount, 428 | USBCOMPLETION * completion) 429 | { 430 | IOReturn result; 431 | if (completion) 432 | result = m_pPipe->io(buffer, (uint32_t)reqCount, completion, completionTimeout); 433 | else 434 | { 435 | uint32_t bytesTransfered; 436 | result = m_pPipe->io(buffer, (uint32_t)reqCount, bytesTransfered, completionTimeout); 437 | } 438 | return result; 439 | } 440 | 441 | const USBENDPOINTDESCRIPTOR* USBPipeShim::getEndpointDescriptor() 442 | { 443 | return m_pPipe->getEndpointDescriptor(); 444 | } 445 | 446 | IOReturn USBPipeShim::clearStall() 447 | { 448 | return m_pPipe->clearStall(false); 449 | } 450 | -------------------------------------------------------------------------------- /BrcmPatchRAM/hci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Released under "The GNU General Public License (GPL-2.0)" 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | * 18 | */ 19 | 20 | #ifndef BRCMPatchRAM_hci_h 21 | #define BRCMPatchRAM_hci_h 22 | 23 | typedef enum 24 | { 25 | HCI_COMMAND = 0x01, 26 | HCI_ACL = 0x02, 27 | HCI_SCL = 0x03, 28 | HCI_EVENT = 0x04 29 | } HCI_PACKET_TYPE; 30 | 31 | typedef enum 32 | { 33 | HCI_EVENT_CONN_COMPLETE = 0x03, 34 | HCI_EVENT_DISCONN_COMPLETE = 0x05, 35 | HCI_EVENT_COMMAND_COMPLETE = 0x0e, 36 | HCI_EVENT_HARDWARE_ERROR = 0x10, 37 | HCI_EVENT_NUM_COMPLETED_PACKETS = 0x13, 38 | HCI_EVENT_MODE_CHANGE = 0x14, 39 | HCI_EVENT_LE_META = 0x3e, 40 | HCI_EVENT_VENDOR = 0xff 41 | } HCI_EVENT_TYPE; 42 | 43 | typedef struct __attribute__((packed)) 44 | { 45 | union 46 | { 47 | uint16_t opcode; 48 | struct 49 | { 50 | uint16_t ocf: 10; 51 | uint16_t ogf: 6; 52 | } op; 53 | }; 54 | unsigned char length; 55 | } HCI_PACKET; 56 | 57 | typedef struct __attribute__((packed)) 58 | { 59 | unsigned char eventCode; 60 | unsigned char length; 61 | } HCI_RESPONSE; 62 | 63 | struct __attribute__((packed)) HCI_COMMAND_COMPLETE: HCI_RESPONSE 64 | { 65 | unsigned char numCommands; 66 | union 67 | { 68 | uint16_t opcode; 69 | struct 70 | { 71 | uint16_t ocf: 10; 72 | uint16_t ogf: 6; 73 | } op; 74 | }; 75 | unsigned char status; 76 | }; 77 | 78 | #define HCI_OPCODE_RESET 0x0c03 79 | #define HCI_OPCODE_READ_VERBOSE_CONFIG 0xfc79 80 | #define HCI_OPCODE_DOWNLOAD_MINIDRIVER 0xfc2e 81 | #define HCI_OPCODE_LAUNCH_RAM 0xfc4c 82 | #define HCI_OPCODE_END_OF_RECORD 0xfc4e 83 | #define HCI_OPCODE_WAKEUP 0xfc53 84 | 85 | // Standard HCI commands 86 | uint8_t HCI_LOCAL_VERSION[] = { 0x01, 0x10, 0x00 }; 87 | uint8_t HCI_READ_LOCAL_COMMANDS[] = { 0x02, 0x10, 0x00 }; 88 | uint8_t HCI_READ_FEATURES[] = { 0x03, 0x10, 0x00 }; 89 | uint8_t HCI_READ_LOCAL_FEATURES[] = { 0x04, 0x10, 0x00 }; 90 | uint8_t HCI_RESET[] = { 0x03, 0x0c, 0x00 }; 91 | 92 | // Broadcom vendor specific commands 93 | 94 | // Vendor Specific: Read chip-id and other Broadcom specific configuration variables 95 | uint8_t HCI_VSC_READ_VERBOSE_CONFIG[] = { 0x79, 0xfc, 0x00 }; 96 | 97 | // Vendor Specific: Download mini driver 98 | uint8_t HCI_VSC_DOWNLOAD_MINIDRIVER[] = { 0x2e, 0xfc, 0x00 }; 99 | 100 | // Vendor Specific: End of Record 101 | uint8_t HCI_VSC_END_OF_RECORD[] = { 0x4e, 0xfc, 0x04, 0xff, 0xff, 0xff, 0xff }; 102 | 103 | // Vendor Specific: Wake up 104 | uint8_t HCI_VSC_WAKEUP[] = { 0x53, 0xfc, 0x01, 0x13 }; 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /BrcmPatchRAM/package.tool: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "${TARGET_BUILD_DIR}" = "" ]; then 4 | echo "This must not be run outside of Xcode" 5 | exit 1 6 | fi 7 | 8 | cd "${TARGET_BUILD_DIR}" 9 | 10 | # clean / build 11 | if [ "$1" != "analyze" ]; then 12 | rm -rf *.zip || exit 1 13 | fi 14 | 15 | if [ "$1" != "" ]; then 16 | echo "Got action $1, skipping!" 17 | exit 0 18 | fi 19 | 20 | for kext in BrcmBluetoothInjector.kext BrcmBluetoothInjectorLegacy.kext; do 21 | rm -rf "$kext" 22 | cp -a "$PROJECT_DIR/$kext" "$kext" || exit 1 23 | done 24 | 25 | dist=() 26 | if [ -d "$DWARF_DSYM_FILE_NAME" ]; then dist+=("$DWARF_DSYM_FILE_NAME"); fi 27 | 28 | for kext in *.kext; do 29 | dist+=("$kext") 30 | done 31 | 32 | archive="BrcmPatchRAM-${CURRENT_PROJECT_VERSION}-$(echo $CONFIGURATION | tr /a-z/ /A-Z/).zip" 33 | rm -rf *.zip 34 | zip -qry -FS "${archive}" "${dist[@]}" 35 | -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | BrcmPatchRAM Changelog 2 | ====================== 3 | #### v2.6.8 4 | - Added vendor callback patch for Bluetooth power status toggling on macOS 13.3+ (thx @zxystd) 5 | - Added patch that skips Internal Bluetooth Controller NVRAM checking (thx @zxystd) 6 | 7 | #### v2.6.7 8 | - Added constants for macOS 14 support 9 | 10 | #### v2.6.6 11 | - Added firmware for legacy BCM20702A1 (thx @chapuza) 12 | 13 | #### v2.6.5 14 | - Fixed legacy Mac compatibility (thx @AsdMonio) 15 | 16 | #### v2.6.4 17 | - Improve compatibility with BCM43142A0 on macOS Big Sur (thx lalithkota) 18 | 19 | #### v2.6.3 20 | - Added constants for macOS 13 support 21 | - Fixed Skip Address Check patch for 13.0 Beta 1 and newer 22 | 23 | #### v2.6.2 24 | - Added Skip Address Check patch for 12.4 Beta 3 and newer (thx @khronokernel) 25 | 26 | #### v2.6.1 27 | - Improved BlueToolFixup compatibility with macOS 12b10 (thx @dhinakg, @williambj1) 28 | - Fixed bluetooth support on MBP15,4 and other similar boards (thx @dhinakg, @usr-sse2) 29 | - Fixed bluetooth not working on macOS 12 after the first power cycle (thx @williambj1, @zxystd) 30 | 31 | #### v2.6.0 32 | - Added BlueToolFixup for macOS 12 compatibility 33 | 34 | #### v2.5.9 35 | - Added BCM94352Z identifiers for injection 36 | 37 | #### v2.5.8 38 | - Added BCM94360Z3 identifiers for injection 39 | 40 | #### v2.5.7 41 | - Added BCM94360Z4 identifiers for injection 42 | 43 | #### v2.5.6 44 | - Added inject Laird BT851 Bluetooth 5.0 USB dongle 45 | - Added legacy Bluetooth injection kext 46 | 47 | #### v2.5.5 48 | - Initial MacKernelSDK and Xcode 12 compatibility 49 | - Added bundled BrcmPatchRAM.kext to the binaries 50 | 51 | #### v2.5.4 52 | - Added inject BCM2070 - BCM943224HMB, BCM943225HMB Combo 53 | 54 | #### v2.5.3 55 | - Fix parsing firmware versions (e.g. 8785 is 4689) 56 | - Use 4689 firmware for DW1820A [0a5c:6412] 57 | - Log uncompressed firmware SHA-1 in DEBUG builds 58 | - Reworked device reset to improve compatibility (thx @mishurov) 59 | 60 | #### v2.5.2 61 | - Revert DW1820A from 8785 to 8784 [0a5c:6412] 62 | - Add older firmwares from 12.0.1.1012 63 | - Add `bpr_handshake` boot argument to override handshake support mode 64 | - Change `bpr_preresetdelay=0` behaviour to no longer imply `bpr_handshake=1` 65 | 66 | #### v2.5.1 67 | - Add Lenovo 00JT494 [0a5c:6414] 68 | 69 | #### v2.5.0 70 | - Initial import based on @headkaze [2.2.12](https://github.com/headkaze/OS-X-BrcmPatchRAM/releases) 71 | - Merged BrcmPatchRAM3 improvements authored by @Mieze 72 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README-Mac.md: -------------------------------------------------------------------------------- 1 | ##### BrcmPatchRAM on Apple Mac 2 | 3 | The instructions in the readme are for a [Hackintosh](http://en.wikipedia.org/wiki/OSx86), a normal PC modified to run macOS. 4 | 5 | You should __not__ follow the original instructions on a real Mac as it might inadvertently break things. 6 | 7 | BrcmPatchRAM.kext, BrcmPatchRAM2.kext, BrcmFirmwareRepo.kext, and BrcmFirmwareData.kext are all unsigned kernel extensions. 8 | 9 | In order to use them, unsigned kernel extensions need to be enabled. Refer to [this page](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html) for more details. Hint: you need to disable System Integrity Protection. 10 | 11 | For macOS older than 10.11, install the required kexts inside /System/Library/Extensions. 12 | ``` 13 | sudo cp -R ~/Downloads/BrcmPatchRAM.kext /System/Library/Extensions 14 | sudo cp -R ~/Downloads/BrcmFirmwareRepo.kext /System/Library/Extensions 15 | sudo touch /System/Library/Extensions 16 | ``` 17 | 18 | Or for 10.11 and later, to /Library/Extensions: 19 | ``` 20 | sudo cp -R ~/Downloads/BrcmPatchRAM2.kext /Library/Extensions 21 | sudo cp -R ~/Downloads/BrcmFirmwareRepo.kext /Library/Extensions 22 | sudo touch /Library/Extensions 23 | ``` 24 | 25 | Wait about a minute before rebooting the Mac again. 26 | 27 | If all works properly the firmware version in the Bluetooth profiler will now show a higher version than v4096 (4096 means its non-upgraded). 28 | 29 | Additionally its possible to confirm BrcmPatchRAM did its job by executing the following in the terminal: 30 | ``` 31 | sudo cat /var/log/system.log | grep -i brcm[fp] 32 | ``` 33 | 34 | This will show a log excerpt of BrcmPatchRAM output during startup. 35 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | BrcmPatchRAM 2 | ============ 3 | 4 | [![Build Status](https://github.com/acidanthera/BrcmPatchRAM/workflows/CI/badge.svg?branch=master)](https://github.com/acidanthera/BrcmPatchRAM/actions) [![Scan Status](https://scan.coverity.com/projects/22191/badge.svg?flat=1)](https://scan.coverity.com/projects/22191) 5 | 6 | #### 翻译语言 7 | 8 | - 简体中文 9 | - [English](./README.md) 10 | 11 | 大多数Broadcom USB蓝牙设备都使用称为RAMUSB的系统。 RAMUSB允许动态更新设备的固件,但是在关闭计算机时,先前应用的任何更新都会丢失。 12 | 13 | Broadcom Windows驱动程序将在每次启动时将固件上载到Broadcom蓝牙设备中,但是,对于macOS,此功能不可用。 `BrcmPatchRAM` kext是一个macOS驱动程序,适用于基于Broadcom RAMUSB的设备的PatchRAM更新。 每次启动/唤醒时,它将固件更新应用于Broadcom蓝牙设备,与Windows驱动程序相同。 应用的固件是从Windows驱动程序中提取的,并且功能应与Windows相同。 14 | 15 | 请注意,原始的Apple Broadcom蓝牙设备不是RAMUSB设备,因此没有相同的固件机制。 16 | 17 | ### 安装 18 | 19 | __请注意,如果您有Apple MacBook / iMac / Mac Pro等,请按照 [Mac instructions](https://github.com/acidanthera/BrcmPatchRAM/blob/master/README-Mac.md)__ 20 | 21 | 根据macOS版本安装`BrcmPatchRAM.kext`或`BrcmPatchRAM2.kext`或`BrcmPatchRAM3.kext`其中之一,决不要三者都安装。 22 | 23 | * `BrcmPatchRAM.kext`: 适用于 10.10 或更早版本. 24 | 25 | * `BrcmPatchRAM2.kext`: 适用于 10.11-10.14. 26 | 27 | * `BrcmPatchRAM3.kext`: 适用于 10.15 或更高版本 28 | 29 | 另外,根据安装位置安装一个固件kext BrcmFirmwareData.kext或BrcmFirmwareRepo.kext,决不要同时安装。 30 | 31 | * `BrcmFirmwareData.kext`: 最适合引导加载程序注入。 这是首选配置。 32 | 33 | * `BrcmFirmwareRepo.kext`: 安装到`/System/Library/Extensions`(在10.11及更高版本上为`/Library/Extensions`)。 该kext的内存效率比`BrcmFirmwareData.kext`略高,但是不能由引导加载程序注入。 34 | 35 | * 高级用户:对于自定义固件注入器,请安装注入器以及`BrcmFirmwareRepo.kext`。 这可以从`/System/Library/Extensions`或通过引导加载程序注入工作。 (可选)您可以从`BrcmFirmwareRepo.kext/Contents/Resources`中删除所有固件。 如果通过引导加载程序使用注入器,则必须将`BrcmFirmwareRepo.kext`的`Info.plist`中的`IOProviderClass`从`disabled_IOResources`更改为`IOResources`。 36 | 37 | 另外,如果您有非PatchRAM设备(或者不确定),请安装macOS版本的`BrcmNonPatchRAM.kext`或`BrcmNonPatchRAM2.kext`之一,请不要同时安装两者。尽管这些kext不安装任何固件(这些设备内置固件),但它们仍依赖`BrcmPatchRAM.kext` / `BrcmPatchRAM2.kext`。 38 | 39 | * `BrcmNonPatchRAM.kext`: 适用于 10.10 或更早版本. 40 | 41 | * `BrcmNonPatchRAM2.kext`: 适用于 10.11 或更高版本. 42 | 43 | ### BrcmBluetoothInjector.kext 44 | 45 | 用于macOS 10.11或更高版本,对于较旧的系统,请使用`BrcmBluetoothInjectorLetacy.kext`;使用`BrcmPatchRAM3.kext`还需要`BrcmBluetoothInjector.kext`,因为macOS Catalina(10.15)中的更改要求使用单独的注射器注入到kext。 这是由于删除了以下IOCatalogue方法: 46 | 47 | ```bash 48 | IOCatalogue::addDrivers, IOCatalogue::removeDrivers and IOCatalogue::startMatching 49 | ``` 50 | 51 | 因此,为了使设备(`BroadcomBluetoothHostControllerUSBTransport`)加载本机BT驱动程序,我们使用IOProbeScore稍低于BrcmPatchRAM3的plist进行注入,因此它不会在固件上传之前进行探测。 52 | 53 | `BrcmBluetoothInjector.kext`是[无代码内核扩展](https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptAnatomy/kext_anatomy.html),它使用plist注入BT硬件数据; 它不包含固件上载器。 如果希望查看您的设备在没有固件上传器的情况下是否可以运行,则可能还需要尝试此kext。 54 | 55 | 请勿在此kext上使用`BrcmPatchRAM`或`BrcmPatchRAM2`。 56 | 57 | `BrcmBluetoothInjector` 支持的设备: 58 | 59 | * ``[0489:e032]`` 20702 E032 Combo 60 | * ``[0489:e042]`` 20702A1 Lenovo China standalone 61 | * ``[0489:e046]`` 20702A1 Acer 43228+20702 combo card 62 | * ``[0489:e04f]`` 20702A1 Lenovo China 43227 WLAN + 20702A1 Combo card 63 | * ``[0489:e052]`` 20702 non-UHE Generic 64 | * ``[0489:e055]`` 43142A0 Acer combo 65 | * ``[0489:e059]`` Acer 43228 + 20702A1 combo 66 | * ``[0489:e079]`` Lenovo China 43162 NGFF 67 | * ``[0489:e07a]`` Lenovo China 4352+20702 NGFF 68 | * ``[0489:e087]`` Acer 43228 NGFF combo module 69 | * ``[0489:e096]`` BCM43142A0 70 | * ``[0489:e097]`` Acer Foxconn BCM4356A2 NGFF 71 | * ``[0489:e0a1]`` 20703A1 Lenovo 43602 NGFF combo 72 | * ``[04ca:2003]`` 20702A1 Lenovo China standalone 73 | * ``[04ca:2004]`` LiteOn 43228+20702 combo 74 | * ``[04ca:2005]`` LiteOn 43228+20702 combo 75 | * ``[04ca:2006]`` LiteOn 43142 combo 76 | * ``[04ca:2009]`` LiteOn 43142 combo 77 | * ``[04ca:200a]`` LiteOn 4352 combo 78 | * ``[04ca:200b]`` LiteOn 4352 combo 79 | * ``[04ca:200c]`` LiteOn 4352 combo 80 | * ``[04ca:200e]`` Liteon 43228 NGFF combo 81 | * ``[04ca:200f]`` Acer_LiteOn BCM20702A1_4352 82 | * ``[04ca:2012]`` Acer BCM943142Y NGFF 83 | * ``[04ca:2013]`` Acer LiteOn BCM4356A2 NGFF 84 | * ``[04ca:2014]`` Asus LiteOn BCM4356A2 NGFF 85 | * ``[04ca:2016]`` Lenovo 43162 NGFF combo module 86 | * ``[04f2:b4a1]`` ASUS Chicony BCM43142A0 NGFF 87 | * ``[04f2:b4a2]`` BCM4356A2 88 | * ``[050d:065a]`` 20702 standalone 89 | * ``[0930:021e]`` 20702A1 Toshiba standalone 90 | * ``[0930:021f]`` Toshiba 43142 91 | * ``[0930:0221]`` 20702A1 Toshiba 4352 92 | * ``[0930:0223]`` 20702A1 Toshiba 4352 93 | * ``[0930:0225]`` Toshiba 43142 combo NGFF 94 | * ``[0930:0226]`` Toshiba 43142 combo NGFF 95 | * ``[0930:0229]`` 43162 combo NGFF 96 | * ``[0a5c:2168]`` BRCM Generic 43162Z 97 | * ``[0a5c:2169]`` BRCM Generic 43228z 98 | * ``[0a5c:216a]`` Dell DW1708 43142Y combo 99 | * ``[0a5c:216b]`` HP Rapture 4352z ngff combo 100 | * ``[0a5c:216c]`` HP Harrier 43142 101 | * ``[0a5c:216d]`` HP Hornet 43142Y ngff combo 102 | * ``[0a5c:216e]`` HP Blackbird 43162 NGFF 103 | * ``[0a5c:216f]`` Dell DW1560 4352+20702 M.2 104 | * ``[0a5c:217d]`` BCM2070 - BCM943224HMB, BCM943225HMB Combo 105 | * ``[0a5c:21d7]`` BRCM Generic 43142A0 RAMUSB 106 | * ``[0a5c:21de]`` 4352+20702A1 combo 107 | * ``[0a5c:21e1]`` 20702A1 non-UHE HP SoftSailing 108 | * ``[0a5c:21e3]`` 20702A1 non-UHE 4313 combo HP Valentine 109 | * ``[0a5c:21e6]`` 20702 non-UHE Lenovo Japan 110 | * ``[0a5c:21e8]`` 20702A1 dongles 111 | * ``[0a5c:21ec]`` 20702A1 REF6 OTP module standalone 112 | * ``[0a5c:21f1]`` 43228 combo 113 | * ``[0a5c:21f3]`` Lenovo Edge 43228 + 20702A1 combo 114 | * ``[0a5c:21f4]`` Lenovo Edge 4313 + 20702A1 combo 115 | * ``[0a5c:21fb]`` HP Supra 4352 20702A1 combo 116 | * ``[0a5c:21fd]`` BRCM Generic 4352z RAMUSB 117 | * ``[0a5c:640a]`` BRCM Generic Reference 4356 118 | * ``[0a5c:640b]`` HP Luffy 43228 + 20702 M.2 119 | * ``[0a5c:640e]`` Lenovo 4356 NGFF combo 120 | * ``[0a5c:6410]`` 20703A1 RAM download - DW1830 43602 121 | * ``[0a5c:6412]`` Dell 4350C5 122 | * ``[0a5c:6413]`` Broadcom Generic 4350C5 123 | * ``[0a5c:6414]`` Lenovo 4350C5 124 | * ``[0a5c:6417]`` Zebra 4352 125 | * ``[0a5c:6418]`` HP Brook 2x2ac 126 | * ``[0a5c:7460]`` 20703A1 RAM download 127 | * ``[0a5c:828d]`` Fenvi BCM94352Z 128 | * ``[0b05:17b5]`` Asus 43228+20702A1 combo 129 | * ``[0b05:17cb]`` 20702 standalone 130 | * ``[0b05:17cf]`` Asus 4352_20702A1 combo 131 | * ``[0b05:180a]`` Azurewave 4360+20702 combo 132 | * ``[0b05:181d]`` Asus AZUREWAVE MB BCM4356A2 133 | * ``[0bb4:0306]`` 20703A1 HTC runtime RAM dongle 134 | * ``[105b:e065]`` LenovoChina 43142A0 combo 135 | * ``[105b:e066]`` LenovoChina 43228+20702 combo 136 | * ``[13d3:3384]`` 20702A1 Azurewave standalone 137 | * ``[13d3:3388]`` BRCM Generic 43142A0 RAMUSB 138 | * ``[13d3:3389]`` BRCM Generic 43142A0 RAMUSB 139 | * ``[13d3:3392]`` Azurewave 43228+20702 140 | * ``[13d3:3404]`` 4352HMB Azurewave Module 141 | * ``[13d3:3411]`` Dell Alienware 4352 20702A1 combo 142 | * ``[13d3:3413]`` Azurewave 4360+20702 combo 143 | * ``[13d3:3418]`` Azurewave 4352+20702 combo module 144 | * ``[13d3:3427]`` Toshiba 43142 combo NGFF 145 | * ``[13d3:3435]`` AZUREWAVE BCM20702A1_4352 146 | * ``[13d3:3456]`` AZUREWAVE BCM20702A1_4352 147 | * ``[13d3:3473]`` Asus AZUREWAVE BCM4356A2 NGFF 148 | * ``[13d3:3482]`` AZUREWAVE BCM43142A0 NGFF 149 | * ``[13d3:3484]`` Acer AZUREWAVE BCM43142A0 NGFF 150 | * ``[13d3:3485]`` Asus AZUREWAVE BCM4356A2 NB 2217NF 151 | * ``[13d3:3488]`` Asus AZUREWAVE BCM4356A2 NB 2210 152 | * ``[13d3:3492]`` Asus AZUREWAVE BCM4356A2 NGFF 153 | * ``[13d3:3504]`` AW CM217NF BCM4371C2 154 | * ``[13d3:3508]`` AW ASUS CM217NF BCM4371C2 155 | * ``[13d3:3517]`` AW CE160H BCM20702 156 | * ``[145f:01a3]`` 20702A1 Asus Trust standalone 157 | * ``[2b54:5600]`` Emdoor AP6356SD BCM4356A2 158 | * ``[2b54:5601]`` Asus AP6356SDP1A BCM4356A2 159 | * ``[2b54:5602]`` AMPAK AP6356SDP2A BCM4356A2 160 | * ``[33ba:03e8]`` TOULINEUA BCM94360Z4 4360+20702 combo 161 | * ``[33ba:03e9]`` TOULINEUA BCM94360Z3 4360+20702 combo 162 | * ``[413c:8143]`` DW1550 4352+20702 combo 163 | * ``[413c:8197]`` Dell DW380 Nancy Blakes standalone 164 | 165 | 如果你的设备不在支持设备中,请根据需要修改 Info.plist 。 166 | 167 | ### BlueToolFixup.kext 168 | 169 | 需要 macOS 12 或者更新的版本,在 macOS 12 中,Apple 已经将部分蓝牙堆栈从内核空间改为用户空间,更多详情请看 [acidanthera/bugtracker#1669](https://github.com/acidanthera/bugtracker/issues/1669)。 170 | 171 | 请不要在 macOS 12 或者更新的版本上将它和 `BrcmBluetoothInjector` 一起使用。 172 | 173 | ### 支持的设备 174 | 175 | `BrcmPatchRAM`支持任何基于BCM20702芯片组的Broadcom USB蓝牙设备(可能也支持其他芯片组,但是尚未经过测试)。 176 | 177 | 目前支持以下设备: 178 | 179 | * 标有 ***** 的设备已成功测试 180 | 181 | 非PatchRAM设备(BrcmPatchRAM用于加速睡眠后的恢复): 182 | 183 | * ``[03f0:231d]`` HP 231d (ProBook BT built-in firmware) 184 | * ``[13d3:3295]`` Azurewave BCM943225 (20702A bult-in firmware) 185 | 186 | 经过测试的PatchRAM设备: 187 | * ``[0489:e032]`` 20702 Combo USB 188 | * ``[0489:e042]`` 20702A1 Lenovo China * 189 | * ``[0489:e079]`` Lenovo China 43162 NGFF 190 | * ``[0489:e07a]`` Lenovo NGFF (4352 / 20702) 191 | * ``[04ca:2003]`` 20702A1 Lenovo China 192 | * ``[04ca:200a]`` LiteOn (4352 Combo) 193 | * ``[04ca:200b]`` LiteOn (4352 Combo) * 194 | * ``[04ca:200c]`` LiteOn (4352 Combo) 195 | * ``[04ca:200f]`` Acer / LiteOn (4352 Combo) 196 | * ``[050d:065a]`` Belkin (20702) 197 | * ``[0930:0221]`` Toshiba (4352 / 20702) 198 | * ``[0930:0223]`` Toshiba NGFF (4352 / 20702) * 199 | * ``[0a5c:216b]`` HP Rapture 4352Z NGFF Combo 200 | * ``[0a5c:216e]`` HP Blackbird 43162 NGFF 201 | * ``[0a5c:216f]`` Dell DW1560 (4352/20702) 202 | * ``[0a5c:21de]`` 4352/20702A1 combo 203 | * ``[0a5c:21e1]`` HP Softsailing (20702A1) 204 | * ``[0a5c:21e6]`` non-UHE Lenovo Bluetooth (20702) 205 | * ``[0a5c:21e8]`` Bluetooth USB Dongle (20702A1) * 206 | * ``[0a5c:21ec]`` Inateck Bluetooth (20702A1) 207 | * ``[0a5c:21fb]`` HP Supra 4352 (20702A1 Combo) 208 | * ``[0a5c:21fd]`` Broadcom 4352Z 209 | * ``[0a5c:22be]`` Broadcom BCM20702 Bluetooth 4.0 USB Device 210 | * ``[0a5c:6410]`` Dell Wireless 1830 Bluetooth 4.1 LE 211 | * ``[0a5c:6412]`` Dell Wireless 1820 Bluetooth 4.1 LE 212 | * ``[0a5c:828d]`` Fenvi BCM94352Z 213 | * ``[0b05:17cb]`` Asus BT-400 (20702 stand-alone) * 214 | * ``[0b05:17cf]`` Asus (4352/20702A1 combo) * 215 | * ``[0b05:180a]`` Azurewave (4360/20702 combo) 216 | * ``[13d3:3404]`` Azurewave (4352HMB) * 217 | * ``[13d3:3411]`` Dell Alienware (4352/20702A1 combo) * 218 | * ``[13d3:3413]`` Azurewave (4360/20702 combo) 219 | * ``[13d3:3418]`` Azurewave (4352/20702 combo) 220 | * ``[13d3:3435]`` Azurewave (4352/20702 combo) 221 | * ``[13d3:3456]`` Azurewave (4352/20702 combo) 222 | * ``[413c:8143]`` Dell DW1550 (4352/20702 combo) 223 | 224 | Windows软件包中的所有固件都存在于kext中,并自动与其供应商/设备ID关联。 它们有望工作,但尚未得到确认。 如果您可以确认上面未列出的工作设备,请通过github上的issues数据库进行通知。固件已更新到版本12.0.1.1105。 225 | 226 | ### 更多安装细节 227 | 228 | `BrcmPatchRAM.kext`或`BrcmPatchRAM2.kext`或`BrcmPatchRAM3.kext`可以通过引导加载程序kext注入安装,也可以放置在`/System/Library/Extensions`(在10.11及更高版本中为`/Library/Extensions`)中。 229 | 根据系统版本,仅安装一个,而不是安装三个。 230 | 231 | `BrcmFirmwareRepo.kext`不适用于bootloader kext注入,除非使用特定于设备的固件注入器。 232 | `BrcmFirmwareData.kext`可以与bootloader kext注入一起使用。 233 | 234 | 您还可以使用特定于设备的固件注入器(与`BrcmFirmwareRepo.kext`结合使用)。 在这种情况下,`BrcmFirmwareRepo.kext`确实可以从引导加载程序kexts中工作。 235 | 236 | 您可以在git存储库的`firmwares`目录中找到设备专用注射器。 它们不包含在发行版ZIP中。 237 | 238 | ### 配置 239 | 240 | 使用以下内核引导参数可以更改许多延迟。 如果发现在固件加载期间`BrcmPatchRAM`挂起,则可以更改这些值。 有关这些延迟的更多详细信息,请参阅源。 241 | 242 | - `bpr_initialdelay`:更改`mInitialDelay`,即与设备进行任何通信之前的延迟(以毫秒为单位)。预设值为`100` 243 | - `bpr_handshake`:覆盖`mSupportsHandshake`,固件上传的握手支持状态。` 0`表示在上传固件后等待`bpr_preresetdelay` 毫秒,然后重置设备。 `1`表示等待来自设备的特定响应,然后重置设备。默认值取决于设备标识符。 244 | - `bpr_preresetdelay`:更改`mPreResetDelay`,即设备接受固件所需的延迟(以毫秒为单位)。当`bpr_handshake`为`1`(根据设备标识符手动传递或自动应用)时,该值未使用。默认值为`250` 245 | - `bpr_postresetdelay`:更改`mPostResetDelay`,即固件上传后重置设备后,固件初始化所需的延迟(以毫秒为单位)。预设值为`100` 246 | - `bpr_probedelay`:更改`mProbeDelay`(已在BrcmPatchRAM3中删除),即探测设备之前的延迟(以毫秒为单位)。预设值为`0` 247 | 248 | 例如,要将`mPostResetDelay`更改为400ms,请使用内核标志:`bpr_postresetdelay=400`。 249 | 250 | 注意:一些典型的“从睡眠中唤醒”问题报告成功:`bpr_probedelay=100 bpr_initialdelay=300 bpr_postresetdelay=300`。 或稍长的延迟:`bpr_probedelay=200 bpr_initialdelay=400 bpr_postresetdelay=400`。 251 | 252 | ### 细节 253 | 254 | `BrcmPatchRAM`包含2个部分: 255 | 256 | * `BrcmPatchRAM`本身与受支持的Broadcom蓝牙USB设备(在`Info.plist`中配置)进行通信,并检测它们是否需要固件更新。 257 | 258 | 如果需要固件更新,则匹配的固件数据将被上载到设备并重置设备。 259 | 260 | 261 | * `BrcmFirmwareStore`(由`BrcmFirmwareData.kext`或`BrcmFirmwareRepo.kext`实现)是共享资源,其中包含用于不同Broadcom蓝牙USB设备的所有已配置固件。 262 | 263 | 某些设备需要特定于设备的固件,而其他设备可以使用Windows驱动程序中可用的最新版本。 264 | 265 | 会定期添加/配置新固件以支持设备,因此请确保遵循发行更新,或者如果发现不支持设备,请记录问题。 266 | 267 | 可以使用zlib压缩存储固件,以使配置大小易于管理。 268 | 269 | 上传设备固件后,设备控件将移交给Apple的`BroadcomBluetoothHostControllerUSBTransport`。 270 | 这意味着,出于所有意图和目的,您的设备将是macOS上的本地设备,并且完全支持所有功能。 271 | 272 | 可以通过引导加载程序或通过BrcmPatchRAM与Continuity Activation Patch结合使用 [BT4LEContinuityFixup](https://github.com/acidanthera/BT4LEContinuityFixup), 或通过dokterdok的脚本 [Continuity-Activation-Tool](https://github.com/dokterdok/Continuity-Activation-Tool) 273 | 274 | [OpenCore](https://github.com/acidanthera/OpenCorePkg) 用户可以使用`config.plist`中的quirk参数 `ExtendBTFeatureFlags`进行修补。 275 | 276 | ### 故障排除 277 | 278 | 安装`BrcmPatchRAM`之后,即使您的蓝牙图标可能出现,也可能是固件未正确更新。 279 | 280 | 通过转到系统信息并在蓝牙信息面板下检查蓝牙固件版本号来验证固件是否已更新。 281 | 282 | 如果版本号为` 4096`,则意味着您的设备没有更新固件,并且将无法正常工作。 283 | 284 | 通过在终端中运行以下命令来验证系统日志中的任何错误: 285 | 286 | ```bash 287 | # 10.12或者更新的系统: 288 | log show --last boot | grep -i brcm[fp] 289 | # 对于旧的macOS版本: 290 | cat /var/log/system.log | grep -i brcm[fp] 291 | ``` 292 | 确保只检查最新的引导消息,因为`system.log`可能会追溯几天。 293 | 294 | 如果固件上传失败并显示错误,请尝试安装`BrcmPatchRAM`的`debug`版本,以便在日志中获取更多详细信息。 295 | 296 | 为了报告错误,请在github上用以下信息记录问题: 297 | 298 | * Device product ID 299 | * Device vendor ID 300 | * 使用的`BrcmPatchRAM`版本 301 | * `/var/log/system.log`中的`BrcmPatchRAM`调试输出转储,显示固件上传失败 302 | 303 | ### 固件兼容性 304 | 305 | 某些USB设备专用于固件,尝试将同一芯片组的任何其他固件上载到它们中都会失败。 306 | 307 | 通常在系统日志中显示为: 308 | ```bash 309 | BrcmPatchRAM: Version 0.5 starting. 310 | BrcmPatchRAM: USB [0a5c:21e8 5CF3706267E9 v274] "BCM20702A0" by "Broadcom Corp" 311 | BrcmPatchRAM: Retrieved firmware for firmware key "BCM20702A1_001.002.014.1443.1612_v5708". 312 | BrcmPatchRAM: Decompressed firmware (29714 bytes --> 70016 bytes). 313 | BrcmPatchRAM: device request failed (0xe000404f). 314 | BrcmPatchRAM: Failed to reset the device (0xe00002d5). 315 | BrcmPatchRAM: Unable to get device status (0xe000404f). 316 | BrcmPatchRAM: Firmware upgrade completed successfully. 317 | ``` 318 | 319 | 两次之间的错误表示固件未成功上传,并且设备很可能需要配置特定的固件。 320 | 321 | 对于其他设备,可用的最新固件(即使未在Windows驱动程序中专门指定)也可以正常工作。 322 | 323 | ### 新设备 324 | 325 | 为了支持新设备,需要从现有Windows驱动程序中提取该设备的固件。 326 | 327 | 可在以下位置找到最新(最新)的Broadcom USB蓝牙驱动程序的副本: 328 | http://drivers.softpedia.com/get/BLUETOOTH/Broadcom/ASUS-X99-DELUXE-Broadcom-Bluetooth-Driver-6515800-12009860.shtml#download 329 | 330 | *如果您遇到的驱动程序比12.0.0.9860更新,请告诉我。* 331 | 332 | 为了获取设备专用的设备固件,请执行以下步骤: 333 | 334 | * 查找您的USB设备供应商和产品ID,在此示例中,我们将使用BCM94352Z PCI NGFF WiFi/BT组合卡,其供应商为0930,产品ID为0233。 335 | * 解压缩Windows蓝牙驱动程序包并打开bcbtums-win8x64-brcm.inf文件 336 | * 在.inf文件中找到您的供应商/设备ID组合 337 | ```dosini 338 | %BRCM20702.DeviceDesc%=BlueRAMUSB0223, USB\VID_0930&PID_0223 ; 20702A1 Toshiba 4352 339 | ``` 340 | * 在.inf文件中找到提到的`RAMUSB0223`设备: 341 | ```dosini 342 | ;;;;;;;;;;;;;RAMUSB0223;;;;;;;;;;;;;;;;; 343 | [RAMUSB0223.CopyList] 344 | bcbtums.sys 345 | btwampfl.sys 346 | BCM20702A1_001.002.014.1443.1457.hex 347 | ``` 348 | 349 | * 在这种情况下,请从Windows软件包中复制与设备匹配的固件十六进制文件。`BCM20702A1_001.002.014.1443.1457.hex` 350 | 351 | * 现在可以选择使用随附的zlib.pl脚本压缩固件文件: 352 | ```bash 353 | zlib.pl deflate BCM20702A1_001.002.014.1443.1457.hex > BCM20702A1_001.002.014.1443.1457.zhx 354 | ``` 355 | * 之后,可以创建一个十六进制转储,以粘贴到plist编辑器中: 356 | ```bash 357 | xxd -ps BCM20702A1_001.002.014.1443.1457.zhx|tr '\n' ' ' > BCM20702A1_001.002.014.1443.1457.dmp 358 | ``` 359 | * *使用plist编辑器在* *`BcmFirmwareStore/Firmwares`*词典下创建一个新的固件密钥。 360 | 361 | 请注意,macOS中显示的版本号是文件名中的最后一个数字(在我们的示例中为1457)+ 4096。 362 | 363 | 因此,在这种情况下,macOS中的固件版本为:*`c14 v5553`*。 364 | 365 | * 在*`BcmFirmwareStore/Firmwares`*下配置密钥后,将设备ID添加为`BrcmPatchRAM`的新设备。 366 | 367 | 固件也可以直接通过`BrcmFirmwareRepo.kext/Contents/Resources`加载,可以通过固件密钥名称(请参见上文),也可以仅使用供应商和设备ID命名文件。 例如,`0930_0223.hex`(未压缩)或`0930_0223.zhx`(压缩)。 368 | 369 | 复制现有的IOKit个性化并修改其属性是最简单的方法。 370 | 使用其唯一的固件密钥配置较早的固件。 371 | 372 | ### 支持和讨论 373 | 374 | [InsanelyMac topic](https://www.insanelymac.com/forum/topic/339175-brcmpatchram2-for-1015-catalina-broadcom-bluetooth-firmware-upload/) in English 375 | [AppleLife topic](https://applelife.ru/threads/bluetooth.2944352/) in Russian 376 | 377 | -------------------------------------------------------------------------------- /extra_firmwares/0a5c_6412/BCM4350C5_003.006.007.0222.4689_v8785.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/extra_firmwares/0a5c_6412/BCM4350C5_003.006.007.0222.4689_v8785.zhx -------------------------------------------------------------------------------- /firmware.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | require 'base64' 4 | require 'fileutils' 5 | require 'optparse' 6 | require 'ostruct' 7 | require 'zlib' 8 | require 'rexml/document' 9 | include REXML 10 | 11 | def add_element(parent, name, text) 12 | element = Element.new(name, parent) 13 | element.text = text 14 | end 15 | 16 | def add_key_value(dict, key, type, value) 17 | add_element(dict, "key", key) 18 | add_element(dict, type, value) 19 | end 20 | 21 | def parse_inf(inf_path) 22 | devices = Array.new 23 | in_device_block = 0 24 | device = nil 25 | 26 | if !File.exist?(inf_path) 27 | puts "Error: bcbtums.inf not found in firmware input folder." 28 | exit 29 | end 30 | 31 | File.open(inf_path).each do |line| 32 | 33 | # When in the device block, parse all devices 34 | if in_device_block == 1 and line =~ /^%([\w\.]*)%=.*(RAMUSB\w*),\s*USB\\VID_([0-9A-F]{4})\&PID_([0-9A-F]{4})\s*;\s(.*?)\r\n$/ 35 | # Example match: %BRCM20702.DeviceDesc%=BlueRAMUSB21E8, USB\VID_0A5C&PID_21E8 ; 20702A1 dongles 36 | # new Example: %BRCM20702.DeviceDesc%=RAMUSB21E8, USB\VID_0A5C&PID_21E8 ; 20702A1 dongles 37 | device = OpenStruct.new 38 | 39 | device.stringKey = $1 40 | device.deviceKey = $2 41 | device.vendorId = $3.hex 42 | device.productId = $4.hex 43 | device.comment = $5 44 | 45 | new_device = devices.find { |f| f.deviceKey.casecmp(device.deviceKey) == 0 } 46 | 47 | # Skip drivers from Windows 8 when we have drivers from Windows 10. 48 | if new_device == nil 49 | devices << device 50 | end 51 | 52 | device = nil 53 | end 54 | 55 | # Extract the firmware file name from the current device block 56 | if device and line =~ /^(BCM.*\.hex)/ 57 | device.firmware = $1 58 | device.firmwareVersion = $1[-8..-1].chomp(".hex").to_i 59 | 60 | if device.firmwareVersion < 4096 61 | device.firmwareVersion += 4096 62 | end 63 | 64 | if device.firmware.start_with?("BCM4356A2") 65 | devices.delete(device) 66 | end 67 | 68 | device = nil 69 | end 70 | 71 | # Determine the firmware filename for each device 72 | if line =~ /^\[(RAMUSB[0-9A-F_]{4,})\.CopyList\]/ 73 | # Example matches: 74 | # [RAMUSB21E8.CopyList] 75 | # [RAMUSB185F_2167.CopyList] 76 | 77 | # Locate the device information for this RAMUSB device in the firmware array 78 | device = devices.find { |f| f.deviceKey.casecmp($1) == 0 } 79 | end 80 | 81 | # Extract device descriptions 82 | if line =~ /^(\w*\.DeviceDesc)\=\s*"(.*)"/ 83 | matches = devices.each.select { |f| f.stringKey.casecmp($1) == 0 } 84 | 85 | matches.each do |match| 86 | match.description = $2 87 | end 88 | end 89 | 90 | # Found start of Windows 10 drivers block 91 | if line =~ /^\[Broadcom\.NT\w*\.10\.0\]/ 92 | in_device_block = 1 93 | end 94 | 95 | # Found end of all drivers blocks 96 | if line =~ /^\[DestinationDirs\]/ 97 | in_device_block = 0 98 | end 99 | end 100 | 101 | return devices 102 | end 103 | 104 | def create_firmwares(devices, input_path, output_path) 105 | # Create output folder 106 | FileUtils::makedirs output_path 107 | FileUtils::chdir output_path 108 | 109 | # Wipe any existing symbolic links - Ignore exceptions 110 | begin 111 | FileUtils::remove(Dir.glob(File.join(output_path, "*.zhx"))) 112 | rescue 113 | end 114 | 115 | # Prune and rename existing firmwares 116 | Dir.glob(File.join(input_path, "*.hex")).each do |firmware| 117 | basename = File.basename(firmware) 118 | 119 | # Validate if we have a matching firmware definition 120 | device = devices.find { |d| d.firmware != nil && d.firmware.casecmp(basename) == 0 } 121 | 122 | if device 123 | output_file = "#{File.basename(firmware, File.extname(firmware))}_v#{device.firmwareVersion}.zhx" 124 | data_to_compress = File.read(firmware) 125 | data_compressed = Zlib::Deflate.deflate(data_to_compress, Zlib::BEST_COMPRESSION) 126 | 127 | puts "Compressed firmware #{output_file} (#{data_to_compress.size} --> #{data_compressed.size})" 128 | 129 | device_folder = "%04x_%04x" % [ device.vendorId, device.productId ] 130 | device_path = File.join(output_path, device_folder) 131 | 132 | FileUtils::makedirs(device_path) 133 | File.write(File.join(device_path, output_file), data_compressed) 134 | 135 | # Determine latest firmware for the current device and symlink 136 | latest_firmware = Dir.glob(File.join(device_path, "*.zhx")).sort_by{ |f| f[-8..1] }.reverse.each.first 137 | 138 | if File.exist?(File.basename(latest_firmware)) 139 | puts "Firmware symlink #{File.basename(latestfirmware)} already created for another device." 140 | else 141 | FileUtils::symlink("./" + File.join(device_folder, File.basename(latest_firmware)), File.basename(latest_firmware)) 142 | end 143 | 144 | create_injector(device, false, data_compressed, device_path) 145 | create_injector(device, true, data_compressed, device_path) 146 | else 147 | puts "Firmware file %s is not matched against devices in INF file... skipping." % basename 148 | end 149 | end 150 | end 151 | 152 | def create_injector(device, for_usbhost, compressed_data, output_path) 153 | xml = Document.new(''); 154 | 155 | root_dict = Element.new("dict", xml.root) 156 | add_key_value(root_dict, "CFBundleIdentifier", "string", "as.acidanthera.BrcmInjector.%04x.%04x" % [ device.vendorId, device.productId ]) 157 | add_key_value(root_dict, "CFBundleInfoDictionaryVersion", "string", "6.0") 158 | add_key_value(root_dict, "CFBundleName", "string", "BrcmInjector.%04x.%04x" % [ device.vendorId, device.productId ]) 159 | add_key_value(root_dict, "CFBundlePackageType", "string", "KEXT") 160 | add_key_value(root_dict, "CFBundleShortVersionString", "string", "2.1.0") 161 | add_key_value(root_dict, "CFBundleSignature", "string", "????") 162 | add_key_value(root_dict, "CFBundleVersion", "string", "2.1.0") 163 | 164 | add_element(root_dict, "key", "IOKitPersonalities") 165 | iokit_dict = Element.new("dict", root_dict) 166 | 167 | add_element(iokit_dict, "key", "%04x_%04x" % [ device.vendorId, device.productId ]) 168 | 169 | device_dict = Element.new("dict", iokit_dict); 170 | add_key_value(device_dict, "CFBundleIdentifier", "string", for_usbhost ? "as.acidanthera.BrcmPatchRAM2" : "as.acidanthera.BrcmPatchRAM") 171 | add_key_value(device_dict, "DisplayName", "string", device.description) 172 | add_key_value(device_dict, "FirmwareKey", "string", "%04x_%04x_v%4d" % [ device.vendorId, device.productId, device.firmwareVersion ]) 173 | add_key_value(device_dict, "IOClass", "string", for_usbhost ? "BrcmPatchRAM2" : "BrcmPatchRAM" ) 174 | add_key_value(device_dict, "IOMatchCategory", "string", for_usbhost ? "BrcmPatchRAM2" : "BrcmPatchRAM") 175 | add_key_value(device_dict, "IOProbeScore", "integer", "2000") 176 | add_key_value(device_dict, "IOProviderClass", "string", for_usbhost ? "IOUSBHostDevice" : "IOUSBDevice") 177 | add_key_value(device_dict, "idProduct", "integer", device.productId.to_i()) 178 | add_key_value(device_dict, "idVendor", "integer", device.vendorId.to_i()) 179 | 180 | add_element(iokit_dict, "key", "BrcmFirmwareStore") 181 | 182 | firmware_dict = Element.new("dict", iokit_dict) 183 | add_key_value(firmware_dict, "CFBundleIdentifier", "string", "as.acidanthera.BrcmFirmwareStore") 184 | add_element(firmware_dict, "key", "Firmwares") 185 | 186 | firmwares_dict = Element.new("dict", firmware_dict) 187 | add_key_value(firmwares_dict, "%04x_%04x_v%4d" % [ device.vendorId, device.productId, device.firmwareVersion ], "data", Base64.encode64(compressed_data)) 188 | 189 | add_key_value(firmware_dict, "IOClass", "string", "BrcmFirmwareStore") 190 | add_key_value(firmware_dict, "IOMatchCategory", "string", "BrcmFirmwareStore") 191 | add_key_value(firmware_dict, "IOProbeScore", "integer", "2000") 192 | add_key_value(firmware_dict, "IOProviderClass", "string", "IOResources") 193 | 194 | injector_path = File.join(output_path, "BrcmFirmwareInjector%s_%04x_%04x.kext/Contents" % [ for_usbhost ? "2" : "", device.vendorId, device.productId, device.version ]) 195 | 196 | FileUtils::makedirs(injector_path) 197 | 198 | formatter = REXML::Formatters::Pretty.new 199 | formatter.compact = true 200 | File.open(File.join(injector_path, "Info.plist"), "w") { |file| file.puts formatter.write(xml.root, "") } 201 | end 202 | 203 | def create_plist(devices, output_path, version) 204 | # Generate plist XML snippet 205 | xml = Document.new "" 206 | 207 | Element.new("key", xml.root).text = "IOKitPersonalities" 208 | fws_xml = Element.new("dict", xml.root) 209 | 210 | devices.sort_by{|d| [d.vendorId, d.productId]}.each do |device| 211 | if device.firmware == nil 212 | puts "Failed to parse firmware path for %s, skipping..." % device 213 | next 214 | end 215 | 216 | Element.new("key", fws_xml).text = "%04x_%04x" % [ device.vendorId, device.productId ] 217 | 218 | device_xml = Element.new("dict", fws_xml) 219 | 220 | add_key_value(device_xml, "CFBundleIdentifier", "string", "as.acidanthera.$(PRODUCT_NAME:rfc1034identifier)") 221 | add_key_value(device_xml, "DisplayName", "string", device.description) 222 | add_key_value(device_xml, "FirmwareKey", "string", "#{device.firmware.chomp(".hex")}_v#{device.firmwareVersion}") 223 | if version >= 2 224 | add_key_value(device_xml, "IOClass", "string", "BrcmPatchRAM%d" % version) 225 | add_key_value(device_xml, "IOMatchCategory", "string", "BrcmPatchRAM%d" % version) 226 | add_key_value(device_xml, "IOProbeScore", "integer", 4000) 227 | add_key_value(device_xml, "IOProviderClass", "string", "IOUSBHostDevice") 228 | else 229 | add_key_value(device_xml, "IOClass", "string", "BrcmPatchRAM") 230 | add_key_value(device_xml, "IOMatchCategory", "string", "BrcmPatchRAM") 231 | add_key_value(device_xml, "IOProbeScore", "integer", 4000) 232 | add_key_value(device_xml, "IOProviderClass", "string", "IOUSBDevice") 233 | end 234 | add_key_value(device_xml, "idProduct", "integer", device.productId) 235 | add_key_value(device_xml, "idVendor", "integer", device.vendorId) 236 | end 237 | 238 | if version >= 2 239 | Element.new("key", fws_xml).text = "BrcmPatchRAMResidency" 240 | residency_xml = Element.new("dict", fws_xml) 241 | add_key_value(residency_xml, "CFBundleIdentifier", "string", "as.acidanthera.$(PRODUCT_NAME:rfc1034identifier)") 242 | add_key_value(residency_xml, "IOClass", "string", "BrcmPatchRAMResidency") 243 | add_key_value(residency_xml, "IOMatchCategory", "string", "BrcmPatchRAMResidency") 244 | add_key_value(residency_xml, "IOProviderClass", "string", "disabled_IOResources") 245 | end 246 | 247 | formatter = REXML::Formatters::Pretty.new 248 | formatter.compact = true 249 | if version >= 2 250 | firmwares = "firmwares%d.plist" % version 251 | else 252 | firmwares = "firmwares.plist" 253 | end 254 | File.open(File.join(output_path, firmwares), "w") { |file| file.puts formatter.write(xml.root, "") } 255 | end 256 | 257 | def create_readme(devices, output_path) 258 | File.open(File.join(output_path, "firmwares.md"), "w") do |file| 259 | 260 | devices.sort_by{|d| [d.vendorId, d.productId]}.each do |device| 261 | device_folder = "%04x_%04x" % [ device.vendorId, device.productId ] 262 | device_path = File.join(output_path, device_folder) 263 | 264 | if Dir.exists?(device_path) 265 | file.puts "* [`%04x:%04x`] %s (%s)" % [ device.vendorId, device.productId, device.comment, device.description ] 266 | 267 | 268 | Dir.glob(File.join(device_path, "*.zhx")).each do |firmware| 269 | firmware = File.basename(firmware).chomp(".zhx") 270 | file.puts(" * %s (v%s)" % [ firmware[0..-7], firmware[-4..-1] ]) 271 | end 272 | end 273 | end 274 | end 275 | end 276 | 277 | if ARGV.length != 2 278 | puts "Usage: firmware.rb " 279 | exit 280 | end 281 | 282 | input = File.expand_path(ARGV.shift) 283 | output = File.expand_path(ARGV.shift) 284 | 285 | # Parse Windows INF file into device objects 286 | devices = parse_inf(File.join(input, "bcbtums.inf")) 287 | 288 | # Extract and compress all device firmwares 289 | create_firmwares(devices, input, output) 290 | 291 | # Generate plist extract 292 | create_plist(devices, output, 1) 293 | create_plist(devices, output, 2) 294 | create_plist(devices, output, 3) 295 | 296 | # Generate markdown readme with device / firmware information 297 | create_readme(devices, output) 298 | -------------------------------------------------------------------------------- /firmware_update.tool: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SRC_DIR=$(dirname "$0") 4 | pushd "$SRC_DIR" &>/dev/null 5 | SRC_DIR="$(pwd)" 6 | popd &>/dev/null 7 | 8 | abort() { 9 | echo "ERROR: $1" 10 | exit 1 11 | } 12 | 13 | if [ "$#" -le 1 ]; then 14 | echo -n "Drag and drop Broadcom firmware directory and press [ENTER]: " 15 | read FWDIR 16 | else 17 | FWDIR="$1" 18 | shift 19 | fi 20 | 21 | if [ ! -f "${FWDIR}/bcbtums.inf" ]; then 22 | abort "Broadcom firmware directory should contain bcbtums.inf file, but it is missing!" 23 | fi 24 | 25 | rm -rf "${SRC_DIR}/firmwares" 26 | 27 | "${SRC_DIR}/firmware.rb" "${FWDIR}" "${SRC_DIR}/firmwares" || abort "Cannot process Broadcom firmware directory" 28 | 29 | /usr/libexec/PlistBuddy -c "Delete :IOKitPersonalities" "${SRC_DIR}/BrcmPatchRAM/BrcmPatchRAM-Info.plist" 2>/dev/null 30 | /usr/libexec/PlistBuddy -c "Merge ${SRC_DIR}/firmwares/firmwares.plist" "${SRC_DIR}/BrcmPatchRAM/BrcmPatchRAM-Info.plist" || abort "Cannot update BrcmPatchRAM.kext" 31 | 32 | /usr/libexec/PlistBuddy -c "Delete :IOKitPersonalities" "${SRC_DIR}/BrcmPatchRAM/BrcmPatchRAM2-Info.plist" 2>/dev/null 33 | /usr/libexec/PlistBuddy -c "Merge ${SRC_DIR}/firmwares/firmwares2.plist" "${SRC_DIR}/BrcmPatchRAM/BrcmPatchRAM2-Info.plist" || abort "Cannot update BrcmPatchRAM.kext" 34 | 35 | /usr/libexec/PlistBuddy -c "Delete :IOKitPersonalities" "${SRC_DIR}/BrcmPatchRAM/BrcmPatchRAM3-Info.plist" 2>/dev/null 36 | /usr/libexec/PlistBuddy -c "Merge ${SRC_DIR}/firmwares/firmwares3.plist" "${SRC_DIR}/BrcmPatchRAM/BrcmPatchRAM3-Info.plist" || abort "Cannot update BrcmPatchRAM.kext" 37 | 38 | echo "All good, please rebuilt the KEXTs!" 39 | -------------------------------------------------------------------------------- /firmwares/0489_e032/BCM20702A1_001.002.014.1443.1485_v5581.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e032/BCM20702A1_001.002.014.1443.1485_v5581.zhx -------------------------------------------------------------------------------- /firmwares/0489_e042/BCM20702A1_001.002.014.1443.1484_v5580.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e042/BCM20702A1_001.002.014.1443.1484_v5580.zhx -------------------------------------------------------------------------------- /firmwares/0489_e046/BCM20702A1_001.002.014.1443.1465_v5561.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e046/BCM20702A1_001.002.014.1443.1465_v5561.zhx -------------------------------------------------------------------------------- /firmwares/0489_e047/BCM20702A1_001.002.014.1055.1061_v5157.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e047/BCM20702A1_001.002.014.1055.1061_v5157.zhx -------------------------------------------------------------------------------- /firmwares/0489_e04f/BCM20702A1_001.002.014.1443.1486_v5582.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e04f/BCM20702A1_001.002.014.1443.1486_v5582.zhx -------------------------------------------------------------------------------- /firmwares/0489_e052/BCM20702A1_001.002.014.1502.1758_v5854.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e052/BCM20702A1_001.002.014.1502.1758_v5854.zhx -------------------------------------------------------------------------------- /firmwares/0489_e055/BCM43142A0_001.001.011.0311.0331_v4427.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e055/BCM43142A0_001.001.011.0311.0331_v4427.zhx -------------------------------------------------------------------------------- /firmwares/0489_e059/BCM20702A1_001.002.014.1443.1466_v5562.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e059/BCM20702A1_001.002.014.1443.1466_v5562.zhx -------------------------------------------------------------------------------- /firmwares/0489_e062/BCM43142A0_001.001.011.0277.0280_v4376.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e062/BCM43142A0_001.001.011.0277.0280_v4376.zhx -------------------------------------------------------------------------------- /firmwares/0489_e079/BCM4335C0_003.001.009.0066.0115_v4211.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e079/BCM4335C0_003.001.009.0066.0115_v4211.zhx -------------------------------------------------------------------------------- /firmwares/0489_e07a/BCM20702A1_001.002.014.1483.1651_v5747.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e07a/BCM20702A1_001.002.014.1483.1651_v5747.zhx -------------------------------------------------------------------------------- /firmwares/0489_e087/BCM20702A1_001.002.014.1443.1532_v5628.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e087/BCM20702A1_001.002.014.1443.1532_v5628.zhx -------------------------------------------------------------------------------- /firmwares/0489_e096/BCM43142A0_001.001.011.0311.0340_v4436.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e096/BCM43142A0_001.001.011.0311.0340_v4436.zhx -------------------------------------------------------------------------------- /firmwares/0489_e0a1/BCM20703A1_001.001.005.0214.0414_v4510.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0489_e0a1/BCM20703A1_001.001.005.0214.0414_v4510.zhx -------------------------------------------------------------------------------- /firmwares/04ca_2003/BCM20702A1_001.002.014.1443.1488_v5584.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_2003/BCM20702A1_001.002.014.1443.1488_v5584.zhx -------------------------------------------------------------------------------- /firmwares/04ca_2004/BCM20702A1_001.002.014.1443.1489_v5585.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_2004/BCM20702A1_001.002.014.1443.1489_v5585.zhx -------------------------------------------------------------------------------- /firmwares/04ca_2005/BCM20702A1_001.002.014.1443.1490_v5586.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_2005/BCM20702A1_001.002.014.1443.1490_v5586.zhx -------------------------------------------------------------------------------- /firmwares/04ca_2006/BCM43142A0_001.001.011.0311.0327_v4423.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_2006/BCM43142A0_001.001.011.0311.0327_v4423.zhx -------------------------------------------------------------------------------- /firmwares/04ca_2007/BCM43142A0_001.001.011.0277.0279_v4375.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_2007/BCM43142A0_001.001.011.0277.0279_v4375.zhx -------------------------------------------------------------------------------- /firmwares/04ca_2009/BCM43142A0_001.001.011.0311.0330_v4426.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_2009/BCM43142A0_001.001.011.0311.0330_v4426.zhx -------------------------------------------------------------------------------- /firmwares/04ca_200a/BCM20702A1_001.002.014.1443.1492_v5588.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_200a/BCM20702A1_001.002.014.1443.1492_v5588.zhx -------------------------------------------------------------------------------- /firmwares/04ca_200b/BCM20702A1_001.002.014.1443.1493_v5589.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_200b/BCM20702A1_001.002.014.1443.1493_v5589.zhx -------------------------------------------------------------------------------- /firmwares/04ca_200c/BCM20702A1_001.002.014.1443.1494_v5590.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_200c/BCM20702A1_001.002.014.1443.1494_v5590.zhx -------------------------------------------------------------------------------- /firmwares/04ca_200e/BCM20702A1_001.002.014.1443.1499_v5595.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_200e/BCM20702A1_001.002.014.1443.1499_v5595.zhx -------------------------------------------------------------------------------- /firmwares/04ca_200f/BCM20702A1_001.002.014.1443.1521_v5617.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_200f/BCM20702A1_001.002.014.1443.1521_v5617.zhx -------------------------------------------------------------------------------- /firmwares/04ca_2012/BCM43142A0_001.001.011.0311.0339_v4435.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_2012/BCM43142A0_001.001.011.0311.0339_v4435.zhx -------------------------------------------------------------------------------- /firmwares/04ca_2016/BCM4335C0_003.001.009.0066.0121_v4217.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04ca_2016/BCM4335C0_003.001.009.0066.0121_v4217.zhx -------------------------------------------------------------------------------- /firmwares/04f2_b49d/BCM43142A0_001.001.011.0277.0308_v4404.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04f2_b49d/BCM43142A0_001.001.011.0277.0308_v4404.zhx -------------------------------------------------------------------------------- /firmwares/04f2_b4a1/BCM43142A0_001.001.011.0311.0316_v4412.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/04f2_b4a1/BCM43142A0_001.001.011.0311.0316_v4412.zhx -------------------------------------------------------------------------------- /firmwares/050d_065a/BCM20702A1_001.002.014.1443.1482_v5578.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/050d_065a/BCM20702A1_001.002.014.1443.1482_v5578.zhx -------------------------------------------------------------------------------- /firmwares/0930_021e/BCM20702A1_001.002.014.1502.1759_v5855.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0930_021e/BCM20702A1_001.002.014.1502.1759_v5855.zhx -------------------------------------------------------------------------------- /firmwares/0930_021f/BCM43142A0_001.001.011.0311.0335_v4431.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0930_021f/BCM43142A0_001.001.011.0311.0335_v4431.zhx -------------------------------------------------------------------------------- /firmwares/0930_0221/BCM20702A1_001.002.014.1502.1762_v5858.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0930_0221/BCM20702A1_001.002.014.1502.1762_v5858.zhx -------------------------------------------------------------------------------- /firmwares/0930_0223/BCM20702A1_001.002.014.1502.1763_v5859.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0930_0223/BCM20702A1_001.002.014.1502.1763_v5859.zhx -------------------------------------------------------------------------------- /firmwares/0930_0225/BCM43142A0_001.001.011.0311.0334_v4430.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0930_0225/BCM43142A0_001.001.011.0311.0334_v4430.zhx -------------------------------------------------------------------------------- /firmwares/0930_0229/BCM4335C0_003.001.009.0066.0104_v4200.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0930_0229/BCM4335C0_003.001.009.0066.0104_v4200.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_2167/BCM43142A0_001.001.011.0249.0265_v4361.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_2167/BCM43142A0_001.001.011.0249.0265_v4361.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_2168/BCM4335C0_003.001.009.0066.0108_v4204.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_2168/BCM4335C0_003.001.009.0066.0108_v4204.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_2169/BCM20702A1_001.002.014.1443.1462_v5558.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_2169/BCM20702A1_001.002.014.1443.1462_v5558.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_216a/BCM43142A0_001.001.011.0311.0336_v4432.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_216a/BCM43142A0_001.001.011.0311.0336_v4432.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_216b/BCM20702A1_001.002.014.1502.1768_v5864.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_216b/BCM20702A1_001.002.014.1502.1768_v5864.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_216c/BCM43142A0_001.001.011.0311.0328_v4424.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_216c/BCM43142A0_001.001.011.0311.0328_v4424.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_216d/BCM43142A0_001.001.011.0311.0329_v4425.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_216d/BCM43142A0_001.001.011.0311.0329_v4425.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_216e/BCM4335C0_003.001.009.0066.0105_v4201.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_216e/BCM4335C0_003.001.009.0066.0105_v4201.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_216f/BCM20702A1_001.002.014.1443.1572_v5668.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_216f/BCM20702A1_001.002.014.1443.1572_v5668.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21d3/BCM43142A0_001.001.011.0197.0218_v4314.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21d3/BCM43142A0_001.001.011.0197.0218_v4314.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21d6/BCM43142A0_001.001.011.0197.0220_v4316.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21d6/BCM43142A0_001.001.011.0197.0220_v4316.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21d7/BCM43142A0_001.001.011.0311.0341_v4437.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21d7/BCM43142A0_001.001.011.0311.0341_v4437.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21d8/BCM43142A0_001.001.011.0197.0222_v4318.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21d8/BCM43142A0_001.001.011.0197.0222_v4318.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21dc/BCM43142A0_001.001.011.0161.0187_v4283.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21dc/BCM43142A0_001.001.011.0161.0187_v4283.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21de/BCM20702A1_001.002.014.1443.1461_v5557.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21de/BCM20702A1_001.002.014.1443.1461_v5557.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21e1/BCM20702A1_001.002.014.1502.1770_v5866.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21e1/BCM20702A1_001.002.014.1502.1770_v5866.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21e3/BCM20702A1_001.002.014.1502.1767_v5863.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21e3/BCM20702A1_001.002.014.1502.1767_v5863.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21e6/BCM20702A1_001.002.014.1502.1757_v5853.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21e6/BCM20702A1_001.002.014.1502.1757_v5853.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21e8/BCM20702A1_001.002.014.1502.1764_v5860.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21e8/BCM20702A1_001.002.014.1502.1764_v5860.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21ec/BCM20702A1_001.002.014.1443.1460_v5556.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21ec/BCM20702A1_001.002.014.1443.1460_v5556.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21f1/BCM20702A1_001.002.014.1502.1765_v5861.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21f1/BCM20702A1_001.002.014.1502.1765_v5861.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21f3/BCM20702A1_001.002.014.1502.1761_v5857.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21f3/BCM20702A1_001.002.014.1502.1761_v5857.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21f4/BCM20702A1_001.002.014.1502.1760_v5856.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21f4/BCM20702A1_001.002.014.1502.1760_v5856.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21fb/BCM20702A1_001.002.014.1502.1766_v5862.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21fb/BCM20702A1_001.002.014.1502.1766_v5862.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21fd/BCM20702A1_001.002.014.1443.1463_v5559.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21fd/BCM20702A1_001.002.014.1443.1463_v5559.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_21fe/BCM43142A0_001.001.011.0161.0186_v4282.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_21fe/BCM43142A0_001.001.011.0161.0186_v4282.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_640b/BCM20702A1_001.002.014.1502.1769_v5865.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_640b/BCM20702A1_001.002.014.1502.1769_v5865.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_6410/BCM20703A1_001.001.005.0214.0422_v4518.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_6410/BCM20703A1_001.001.005.0214.0422_v4518.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_6412/BCM4350C5_003.006.007.0222.4689_v4689.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_6412/BCM4350C5_003.006.007.0222.4689_v4689.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_6413/BCM4350C5_003.006.007.0120.2118_v6214.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_6413/BCM4350C5_003.006.007.0120.2118_v6214.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_6414/BCM4350C5_003.006.007.0145.2724_v6820.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_6414/BCM4350C5_003.006.007.0145.2724_v6820.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_6417/BCM20702A1_001.002.014.1502.1780_v5876.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_6417/BCM20702A1_001.002.014.1502.1780_v5876.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_6418/BCM4371C2_001.003.015.0093.0116_v4212.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_6418/BCM4371C2_001.003.015.0093.0116_v4212.zhx -------------------------------------------------------------------------------- /firmwares/0a5c_7460/BCM20703A1_001.001.005.0214.0473_v4569.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0a5c_7460/BCM20703A1_001.001.005.0214.0473_v4569.zhx -------------------------------------------------------------------------------- /firmwares/0b05_17b5/BCM20702A1_001.002.014.1443.1468_v5564.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0b05_17b5/BCM20702A1_001.002.014.1443.1468_v5564.zhx -------------------------------------------------------------------------------- /firmwares/0b05_17cb/BCM20702A1_001.002.014.1443.1467_v5563.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0b05_17cb/BCM20702A1_001.002.014.1443.1467_v5563.zhx -------------------------------------------------------------------------------- /firmwares/0b05_17cf/BCM20702A1_001.002.014.1443.1469_v5565.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0b05_17cf/BCM20702A1_001.002.014.1443.1469_v5565.zhx -------------------------------------------------------------------------------- /firmwares/0b05_180a/BCM20702A1_001.002.014.1443.1714_v5810.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0b05_180a/BCM20702A1_001.002.014.1443.1714_v5810.zhx -------------------------------------------------------------------------------- /firmwares/0bb4_0306/BCM20703A1_001.001.005.0214.0481_v4577.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/0bb4_0306/BCM20703A1_001.001.005.0214.0481_v4577.zhx -------------------------------------------------------------------------------- /firmwares/105b_e065/BCM43142A0_001.001.011.0311.0312_v4408.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/105b_e065/BCM43142A0_001.001.011.0311.0312_v4408.zhx -------------------------------------------------------------------------------- /firmwares/105b_e066/BCM20702A1_001.002.014.1443.1487_v5583.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/105b_e066/BCM20702A1_001.002.014.1443.1487_v5583.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3384/BCM20702A1_001.002.014.1443.1477_v5573.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3384/BCM20702A1_001.002.014.1443.1477_v5573.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3388/BCM43142A0_001.001.011.0311.0332_v4428.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3388/BCM43142A0_001.001.011.0311.0332_v4428.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3389/BCM43142A0_001.001.011.0311.0333_v4429.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3389/BCM43142A0_001.001.011.0311.0333_v4429.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3392/BCM20702A1_001.002.014.1443.1478_v5574.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3392/BCM20702A1_001.002.014.1443.1478_v5574.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3404/BCM20702A1_001.002.014.1443.1479_v5575.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3404/BCM20702A1_001.002.014.1443.1479_v5575.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3411/BCM20702A1_001.002.014.1443.1450_v5546.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3411/BCM20702A1_001.002.014.1443.1450_v5546.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3413/BCM20702A1_001.002.014.1443.1481_v5577.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3413/BCM20702A1_001.002.014.1443.1481_v5577.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3418/BCM20702A1_001.002.014.1443.1480_v5576.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3418/BCM20702A1_001.002.014.1443.1480_v5576.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3435/BCM20702A1_001.002.014.1443.1501_v5597.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3435/BCM20702A1_001.002.014.1443.1501_v5597.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3456/BCM20702A1_001.002.014.1443.1502_v5598.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3456/BCM20702A1_001.002.014.1443.1502_v5598.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3482/BCM43142A0_001.001.011.0311.0346_v4442.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3482/BCM43142A0_001.001.011.0311.0346_v4442.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3484/BCM43142A0_001.001.011.0311.0347_v4443.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3484/BCM43142A0_001.001.011.0311.0347_v4443.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3504/BCM4371C2_001.003.015.0093.0118_v4214.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3504/BCM4371C2_001.003.015.0093.0118_v4214.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3508/BCM4371C2_001.003.015.0093.0117_v4213.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3508/BCM4371C2_001.003.015.0093.0117_v4213.zhx -------------------------------------------------------------------------------- /firmwares/13d3_3517/BCM20702A1_001.002.014.1502.1786_v5882.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/13d3_3517/BCM20702A1_001.002.014.1502.1786_v5882.zhx -------------------------------------------------------------------------------- /firmwares/145f_01a3/BCM20702A1_001.002.014.1443.1483_v5579.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/145f_01a3/BCM20702A1_001.002.014.1443.1483_v5579.zhx -------------------------------------------------------------------------------- /firmwares/185f_2167/BCM43142A0_001.001.011.0277.0292_v4388.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/185f_2167/BCM43142A0_001.001.011.0277.0292_v4388.zhx -------------------------------------------------------------------------------- /firmwares/19ff_0239/BCM20702B0_002.001.014.0527.0557_v4653.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/19ff_0239/BCM20702B0_002.001.014.0527.0557_v4653.zhx -------------------------------------------------------------------------------- /firmwares/413c_8143/BCM20702A1_001.002.014.1443.1449_v5545.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/413c_8143/BCM20702A1_001.002.014.1443.1449_v5545.zhx -------------------------------------------------------------------------------- /firmwares/413c_8197/BCM20702A1_001.002.014.1443.1447_v5543.zhx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zxystd/BrcmPatchRAM/9abe4f74ae2d5e57b91326513955511424c64873/firmwares/413c_8197/BCM20702A1_001.002.014.1443.1447_v5543.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1055.1061_v5157.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e047/BCM20702A1_001.002.014.1055.1061_v5157.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1447_v5543.zhx: -------------------------------------------------------------------------------- 1 | ./413c_8197/BCM20702A1_001.002.014.1443.1447_v5543.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1449_v5545.zhx: -------------------------------------------------------------------------------- 1 | ./413c_8143/BCM20702A1_001.002.014.1443.1449_v5545.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1450_v5546.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3411/BCM20702A1_001.002.014.1443.1450_v5546.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1460_v5556.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21ec/BCM20702A1_001.002.014.1443.1460_v5556.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1461_v5557.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21de/BCM20702A1_001.002.014.1443.1461_v5557.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1462_v5558.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_2169/BCM20702A1_001.002.014.1443.1462_v5558.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1463_v5559.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21fd/BCM20702A1_001.002.014.1443.1463_v5559.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1465_v5561.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e046/BCM20702A1_001.002.014.1443.1465_v5561.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1466_v5562.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e059/BCM20702A1_001.002.014.1443.1466_v5562.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1467_v5563.zhx: -------------------------------------------------------------------------------- 1 | ./0b05_17cb/BCM20702A1_001.002.014.1443.1467_v5563.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1468_v5564.zhx: -------------------------------------------------------------------------------- 1 | ./0b05_17b5/BCM20702A1_001.002.014.1443.1468_v5564.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1469_v5565.zhx: -------------------------------------------------------------------------------- 1 | ./0b05_17cf/BCM20702A1_001.002.014.1443.1469_v5565.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1477_v5573.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3384/BCM20702A1_001.002.014.1443.1477_v5573.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1478_v5574.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3392/BCM20702A1_001.002.014.1443.1478_v5574.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1479_v5575.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3404/BCM20702A1_001.002.014.1443.1479_v5575.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1480_v5576.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3418/BCM20702A1_001.002.014.1443.1480_v5576.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1481_v5577.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3413/BCM20702A1_001.002.014.1443.1481_v5577.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1482_v5578.zhx: -------------------------------------------------------------------------------- 1 | ./050d_065a/BCM20702A1_001.002.014.1443.1482_v5578.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1483_v5579.zhx: -------------------------------------------------------------------------------- 1 | ./145f_01a3/BCM20702A1_001.002.014.1443.1483_v5579.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1484_v5580.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e042/BCM20702A1_001.002.014.1443.1484_v5580.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1485_v5581.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e032/BCM20702A1_001.002.014.1443.1485_v5581.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1486_v5582.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e04f/BCM20702A1_001.002.014.1443.1486_v5582.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1487_v5583.zhx: -------------------------------------------------------------------------------- 1 | ./105b_e066/BCM20702A1_001.002.014.1443.1487_v5583.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1488_v5584.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_2003/BCM20702A1_001.002.014.1443.1488_v5584.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1489_v5585.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_2004/BCM20702A1_001.002.014.1443.1489_v5585.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1490_v5586.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_2005/BCM20702A1_001.002.014.1443.1490_v5586.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1492_v5588.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_200a/BCM20702A1_001.002.014.1443.1492_v5588.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1493_v5589.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_200b/BCM20702A1_001.002.014.1443.1493_v5589.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1494_v5590.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_200c/BCM20702A1_001.002.014.1443.1494_v5590.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1499_v5595.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_200e/BCM20702A1_001.002.014.1443.1499_v5595.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1501_v5597.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3435/BCM20702A1_001.002.014.1443.1501_v5597.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1502_v5598.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3456/BCM20702A1_001.002.014.1443.1502_v5598.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1521_v5617.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_200f/BCM20702A1_001.002.014.1443.1521_v5617.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1532_v5628.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e087/BCM20702A1_001.002.014.1443.1532_v5628.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1572_v5668.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_216f/BCM20702A1_001.002.014.1443.1572_v5668.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1443.1714_v5810.zhx: -------------------------------------------------------------------------------- 1 | ./0b05_180a/BCM20702A1_001.002.014.1443.1714_v5810.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1483.1651_v5747.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e07a/BCM20702A1_001.002.014.1483.1651_v5747.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1757_v5853.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21e6/BCM20702A1_001.002.014.1502.1757_v5853.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1758_v5854.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e052/BCM20702A1_001.002.014.1502.1758_v5854.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1759_v5855.zhx: -------------------------------------------------------------------------------- 1 | ./0930_021e/BCM20702A1_001.002.014.1502.1759_v5855.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1760_v5856.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21f4/BCM20702A1_001.002.014.1502.1760_v5856.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1761_v5857.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21f3/BCM20702A1_001.002.014.1502.1761_v5857.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1762_v5858.zhx: -------------------------------------------------------------------------------- 1 | ./0930_0221/BCM20702A1_001.002.014.1502.1762_v5858.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1763_v5859.zhx: -------------------------------------------------------------------------------- 1 | ./0930_0223/BCM20702A1_001.002.014.1502.1763_v5859.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1764_v5860.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21e8/BCM20702A1_001.002.014.1502.1764_v5860.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1765_v5861.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21f1/BCM20702A1_001.002.014.1502.1765_v5861.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1766_v5862.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21fb/BCM20702A1_001.002.014.1502.1766_v5862.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1767_v5863.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21e3/BCM20702A1_001.002.014.1502.1767_v5863.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1768_v5864.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_216b/BCM20702A1_001.002.014.1502.1768_v5864.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1769_v5865.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_640b/BCM20702A1_001.002.014.1502.1769_v5865.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1770_v5866.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21e1/BCM20702A1_001.002.014.1502.1770_v5866.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1780_v5876.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_6417/BCM20702A1_001.002.014.1502.1780_v5876.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702A1_001.002.014.1502.1786_v5882.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3517/BCM20702A1_001.002.014.1502.1786_v5882.zhx -------------------------------------------------------------------------------- /firmwares/BCM20702B0_002.001.014.0527.0557_v4653.zhx: -------------------------------------------------------------------------------- 1 | ./19ff_0239/BCM20702B0_002.001.014.0527.0557_v4653.zhx -------------------------------------------------------------------------------- /firmwares/BCM20703A1_001.001.005.0214.0414_v4510.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e0a1/BCM20703A1_001.001.005.0214.0414_v4510.zhx -------------------------------------------------------------------------------- /firmwares/BCM20703A1_001.001.005.0214.0422_v4518.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_6410/BCM20703A1_001.001.005.0214.0422_v4518.zhx -------------------------------------------------------------------------------- /firmwares/BCM20703A1_001.001.005.0214.0473_v4569.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_7460/BCM20703A1_001.001.005.0214.0473_v4569.zhx -------------------------------------------------------------------------------- /firmwares/BCM20703A1_001.001.005.0214.0481_v4577.zhx: -------------------------------------------------------------------------------- 1 | ./0bb4_0306/BCM20703A1_001.001.005.0214.0481_v4577.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0161.0186_v4282.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21fe/BCM43142A0_001.001.011.0161.0186_v4282.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0161.0187_v4283.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21dc/BCM43142A0_001.001.011.0161.0187_v4283.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0197.0218_v4314.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21d3/BCM43142A0_001.001.011.0197.0218_v4314.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0197.0220_v4316.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21d6/BCM43142A0_001.001.011.0197.0220_v4316.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0197.0222_v4318.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21d8/BCM43142A0_001.001.011.0197.0222_v4318.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0249.0265_v4361.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_2167/BCM43142A0_001.001.011.0249.0265_v4361.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0277.0279_v4375.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_2007/BCM43142A0_001.001.011.0277.0279_v4375.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0277.0280_v4376.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e062/BCM43142A0_001.001.011.0277.0280_v4376.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0277.0292_v4388.zhx: -------------------------------------------------------------------------------- 1 | ./185f_2167/BCM43142A0_001.001.011.0277.0292_v4388.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0277.0308_v4404.zhx: -------------------------------------------------------------------------------- 1 | ./04f2_b49d/BCM43142A0_001.001.011.0277.0308_v4404.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0312_v4408.zhx: -------------------------------------------------------------------------------- 1 | ./105b_e065/BCM43142A0_001.001.011.0311.0312_v4408.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0316_v4412.zhx: -------------------------------------------------------------------------------- 1 | ./04f2_b4a1/BCM43142A0_001.001.011.0311.0316_v4412.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0327_v4423.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_2006/BCM43142A0_001.001.011.0311.0327_v4423.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0328_v4424.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_216c/BCM43142A0_001.001.011.0311.0328_v4424.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0329_v4425.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_216d/BCM43142A0_001.001.011.0311.0329_v4425.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0330_v4426.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_2009/BCM43142A0_001.001.011.0311.0330_v4426.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0331_v4427.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e055/BCM43142A0_001.001.011.0311.0331_v4427.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0332_v4428.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3388/BCM43142A0_001.001.011.0311.0332_v4428.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0333_v4429.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3389/BCM43142A0_001.001.011.0311.0333_v4429.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0334_v4430.zhx: -------------------------------------------------------------------------------- 1 | ./0930_0225/BCM43142A0_001.001.011.0311.0334_v4430.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0335_v4431.zhx: -------------------------------------------------------------------------------- 1 | ./0930_021f/BCM43142A0_001.001.011.0311.0335_v4431.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0336_v4432.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_216a/BCM43142A0_001.001.011.0311.0336_v4432.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0339_v4435.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_2012/BCM43142A0_001.001.011.0311.0339_v4435.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0340_v4436.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e096/BCM43142A0_001.001.011.0311.0340_v4436.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0341_v4437.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_21d7/BCM43142A0_001.001.011.0311.0341_v4437.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0346_v4442.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3482/BCM43142A0_001.001.011.0311.0346_v4442.zhx -------------------------------------------------------------------------------- /firmwares/BCM43142A0_001.001.011.0311.0347_v4443.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3484/BCM43142A0_001.001.011.0311.0347_v4443.zhx -------------------------------------------------------------------------------- /firmwares/BCM4335C0_003.001.009.0066.0104_v4200.zhx: -------------------------------------------------------------------------------- 1 | ./0930_0229/BCM4335C0_003.001.009.0066.0104_v4200.zhx -------------------------------------------------------------------------------- /firmwares/BCM4335C0_003.001.009.0066.0105_v4201.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_216e/BCM4335C0_003.001.009.0066.0105_v4201.zhx -------------------------------------------------------------------------------- /firmwares/BCM4335C0_003.001.009.0066.0108_v4204.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_2168/BCM4335C0_003.001.009.0066.0108_v4204.zhx -------------------------------------------------------------------------------- /firmwares/BCM4335C0_003.001.009.0066.0115_v4211.zhx: -------------------------------------------------------------------------------- 1 | ./0489_e079/BCM4335C0_003.001.009.0066.0115_v4211.zhx -------------------------------------------------------------------------------- /firmwares/BCM4335C0_003.001.009.0066.0121_v4217.zhx: -------------------------------------------------------------------------------- 1 | ./04ca_2016/BCM4335C0_003.001.009.0066.0121_v4217.zhx -------------------------------------------------------------------------------- /firmwares/BCM4350C5_003.006.007.0120.2118_v6214.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_6413/BCM4350C5_003.006.007.0120.2118_v6214.zhx -------------------------------------------------------------------------------- /firmwares/BCM4350C5_003.006.007.0145.2724_v6820.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_6414/BCM4350C5_003.006.007.0145.2724_v6820.zhx -------------------------------------------------------------------------------- /firmwares/BCM4350C5_003.006.007.0222.4689_v4689.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_6412/BCM4350C5_003.006.007.0222.4689_v4689.zhx -------------------------------------------------------------------------------- /firmwares/BCM4371C2_001.003.015.0093.0116_v4212.zhx: -------------------------------------------------------------------------------- 1 | ./0a5c_6418/BCM4371C2_001.003.015.0093.0116_v4212.zhx -------------------------------------------------------------------------------- /firmwares/BCM4371C2_001.003.015.0093.0117_v4213.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3508/BCM4371C2_001.003.015.0093.0117_v4213.zhx -------------------------------------------------------------------------------- /firmwares/BCM4371C2_001.003.015.0093.0118_v4214.zhx: -------------------------------------------------------------------------------- 1 | ./13d3_3504/BCM4371C2_001.003.015.0093.0118_v4214.zhx -------------------------------------------------------------------------------- /firmwares/firmwares.md: -------------------------------------------------------------------------------- 1 | * [`0489:e032`] 20702 E032 Combo (Broadcom Bluetooth 4.0 USB) 2 | * BCM20702A1_001.002.014.1443.1485 (v5581) 3 | * [`0489:e042`] 20702A1 Lenovo China standalone (Broadcom Bluetooth 4.0 USB) 4 | * BCM20702A1_001.002.014.1443.1484 (v5580) 5 | * [`0489:e046`] 20702A1 Acer 43228+20702 combo card (Bluetooth USB module) 6 | * BCM20702A1_001.002.014.1443.1465 (v5561) 7 | * [`0489:e047`] 20702A1 4313 (Bluetooth USB module) 8 | * BCM20702A1_001.002.014.1055.1061 (v5157) 9 | * [`0489:e04f`] 20702A1 Lenovo China 43227 WLAN + 20702A1 Combo card (Broadcom Bluetooth 4.0 USB) 10 | * BCM20702A1_001.002.014.1443.1486 (v5582) 11 | * [`0489:e052`] 20702 non-UHE Generic (Broadcom BCM20702 Bluetooth USB Device) 12 | * BCM20702A1_001.002.014.1502.1758 (v5854) 13 | * [`0489:e055`] 43142A0 Acer combo (Bluetooth USB module) 14 | * BCM43142A0_001.001.011.0311.0331 (v4427) 15 | * [`0489:e059`] Acer 43228 + 20702A1 combo (Bluetooth USB module) 16 | * BCM20702A1_001.002.014.1443.1466 (v5562) 17 | * [`0489:e062`] Sony 43142A0 combo (BCM43142 Bluetooth Adapter) 18 | * BCM43142A0_001.001.011.0277.0280 (v4376) 19 | * [`0489:e079`] Lenovo China 43162 NGFF (Broadcom Bluetooth 4.0 USB) 20 | * BCM4335C0_003.001.009.0066.0115 (v4211) 21 | * [`0489:e07a`] Lenovo China 4352+20702 NGFF (Broadcom Bluetooth 4.0 USB) 22 | * BCM20702A1_001.002.014.1483.1651 (v5747) 23 | * [`0489:e087`] Acer 43228 NGFF combo module (Bluetooth USB module) 24 | * BCM20702A1_001.002.014.1443.1532 (v5628) 25 | * [`0489:e096`] BCM43142A0 (Broadcom Bluetooth 4.0 USB) 26 | * BCM43142A0_001.001.011.0311.0340 (v4436) 27 | * [`0489:e0a1`] 20703A1 Lenovo 43602 NGFF combo (Broadcom Bluetooth 4.1 USB) 28 | * BCM20703A1_001.001.005.0214.0414 (v4510) 29 | * [`04ca:2003`] 20702A1 Lenovo China standalone (Broadcom Bluetooth 4.0 USB) 30 | * BCM20702A1_001.002.014.1443.1488 (v5584) 31 | * [`04ca:2004`] LiteOn 43228+20702 combo (Bluetooth USB module) 32 | * BCM20702A1_001.002.014.1443.1489 (v5585) 33 | * [`04ca:2005`] LiteOn 43228+20702 combo (Bluetooth Module) 34 | * BCM20702A1_001.002.014.1443.1490 (v5586) 35 | * [`04ca:2006`] LiteOn 43142 combo (Bluetooth Module) 36 | * BCM43142A0_001.001.011.0311.0327 (v4423) 37 | * [`04ca:2007`] LiteOn 43142 (Broadcom Bluetooth 4.0) 38 | * BCM43142A0_001.001.011.0277.0279 (v4375) 39 | * [`04ca:2009`] LiteOn 43142 combo (Bluetooth USB module) 40 | * BCM43142A0_001.001.011.0311.0330 (v4426) 41 | * [`04ca:200a`] LiteOn 4352 combo (Bluetooth USB module) 42 | * BCM20702A1_001.002.014.1443.1492 (v5588) 43 | * [`04ca:200b`] LiteOn 4352 combo (Broadcom Bluetooth 4.0 USB) 44 | * BCM20702A1_001.002.014.1443.1493 (v5589) 45 | * [`04ca:200c`] LiteOn 4352 combo (Broadcom Bluetooth 4.0 USB) 46 | * BCM20702A1_001.002.014.1443.1494 (v5590) 47 | * [`04ca:200e`] Liteon 43228 NGFF combo (Bluetooth USB module) 48 | * BCM20702A1_001.002.014.1443.1499 (v5595) 49 | * [`04ca:200f`] Acer_LiteOn BCM20702A1_4352 (Broadcom Bluetooth 4.0 USB) 50 | * BCM20702A1_001.002.014.1443.1521 (v5617) 51 | * [`04ca:2012`] Acer BCM943142Y NGFF (Broadcom Bluetooth 4.0 USB) 52 | * BCM43142A0_001.001.011.0311.0339 (v4435) 53 | * [`04ca:2016`] Lenovo 43162 NGFF combo module (Broadcom Bluetooth 4.0 USB) 54 | * BCM4335C0_003.001.009.0066.0121 (v4217) 55 | * [`04f2:b49d`] ASUS Chicony BCM43142A0 HM (Bluetooth USB module) 56 | * BCM43142A0_001.001.011.0277.0308 (v4404) 57 | * [`04f2:b4a1`] ASUS Chicony BCM43142A0 NGFF (Bluetooth USB module) 58 | * BCM43142A0_001.001.011.0311.0316 (v4412) 59 | * [`050d:065a`] 20702 standalone (Belkin Bluetooth 4.0 USB Adapter) 60 | * BCM20702A1_001.002.014.1443.1482 (v5578) 61 | * [`0930:021e`] 20702A1 Toshiba standalone (Broadcom BCM20702 Bluetooth USB Device) 62 | * BCM20702A1_001.002.014.1502.1759 (v5855) 63 | * [`0930:021f`] Toshiba 43142 (Bluetooth USB module) 64 | * BCM43142A0_001.001.011.0311.0335 (v4431) 65 | * [`0930:0221`] 20702A1 Toshiba 4352 (Broadcom BCM20702 Bluetooth 4.0 USB Device) 66 | * BCM20702A1_001.002.014.1502.1762 (v5858) 67 | * [`0930:0223`] 20702A1 Toshiba 4352 (Broadcom BCM20702 Bluetooth 4.0 USB Device) 68 | * BCM20702A1_001.002.014.1502.1763 (v5859) 69 | * [`0930:0225`] Toshiba 43142 combo NGFF (Broadcom Bluetooth 4.0 USB Device) 70 | * BCM43142A0_001.001.011.0311.0334 (v4430) 71 | * [`0930:0229`] 43162 combo NGFF (Broadcom Bluetooth 4.0 USB Device) 72 | * BCM4335C0_003.001.009.0066.0104 (v4200) 73 | * [`0a5c:2167`] BRCM Generic 43142Y (NGFF) (BCM43142 Bluetooth 4.0 +HS USB Device) 74 | * BCM43142A0_001.001.011.0249.0265 (v4361) 75 | * [`0a5c:2168`] BRCM Generic 43162Z (BCM43162 Bluetooth 4.0 +HS USB Device) 76 | * BCM4335C0_003.001.009.0066.0108 (v4204) 77 | * [`0a5c:2169`] BRCM Generic 43228z (Broadcom BCM20702 Bluetooth USB Device) 78 | * BCM20702A1_001.002.014.1443.1462 (v5558) 79 | * [`0a5c:216a`] Dell DW1708 43142Y combo (Dell Wireless 1708 Bluetooth 4.0 LE Device) 80 | * BCM43142A0_001.001.011.0311.0336 (v4432) 81 | * [`0a5c:216b`] HP Rapture 4352z ngff combo (Broadcom 20702 Bluetooth 4.0 Adapter) 82 | * BCM20702A1_001.002.014.1502.1768 (v5864) 83 | * [`0a5c:216c`] HP Harrier 43142 (Broadcom 43142 Bluetooth 4.0 Adapter) 84 | * BCM43142A0_001.001.011.0311.0328 (v4424) 85 | * [`0a5c:216d`] HP Hornet 43142Y ngff combo (Broadcom 43142 Bluetooth 4.0 Adapter) 86 | * BCM43142A0_001.001.011.0311.0329 (v4425) 87 | * [`0a5c:216e`] HP Blackbird 43162 NGFF (Broadcom 43162 Bluetooth 4.0 Adapter) 88 | * BCM4335C0_003.001.009.0066.0105 (v4201) 89 | * [`0a5c:216f`] Dell DW1560 4352+20702 M.2 (DW1560 Bluetooth 4.0 LE) 90 | * BCM20702A1_001.002.014.1443.1572 (v5668) 91 | * [`0a5c:21d3`] BRCM Generic 43142A0 RAMUSB (BCM43142 Bluetooth 4.0 +HS USB Device) 92 | * BCM43142A0_001.001.011.0197.0218 (v4314) 93 | * [`0a5c:21d6`] BRCM Generic 43142A0 RAMUSB (Radio Control Disabled) (BCM43142 Bluetooth 4.0 +HS USB Device) 94 | * BCM43142A0_001.001.011.0197.0220 (v4316) 95 | * [`0a5c:21d7`] BRCM Generic 43142A0 RAMUSB (Dell Wireless 1704 Bluetooth v4.0+HS) 96 | * BCM43142A0_001.001.011.0311.0341 (v4437) 97 | * [`0a5c:21d8`] BRCM Generic 43142A0 RAMUSB (BCM43142 Bluetooth 4.0 +HS USB Device) 98 | * BCM43142A0_001.001.011.0197.0222 (v4318) 99 | * [`0a5c:21dc`] HP 43142A0 RAMUSB (Broadcom 43142 Bluetooth 4.0 Adapter) 100 | * BCM43142A0_001.001.011.0161.0187 (v4283) 101 | * [`0a5c:21de`] 4352+20702A1 combo (Broadcom BCM20702 Bluetooth 4.0 +HS USB Device) 102 | * BCM20702A1_001.002.014.1443.1461 (v5557) 103 | * [`0a5c:21e1`] 20702A1 non-UHE HP SoftSailing (Broadcom 20702 Bluetooth 4.0 Adapter) 104 | * BCM20702A1_001.002.014.1502.1770 (v5866) 105 | * [`0a5c:21e3`] 20702A1 non-UHE 4313 combo HP Valentine (Broadcom 20702 Bluetooth 4.0 Adapter) 106 | * BCM20702A1_001.002.014.1502.1767 (v5863) 107 | * [`0a5c:21e6`] 20702 non-UHE Lenovo Japan (ThinkPad Bluetooth 4.0) 108 | * BCM20702A1_001.002.014.1502.1757 (v5853) 109 | * [`0a5c:21e8`] 20702A1 dongles (Broadcom BCM20702 Bluetooth 4.0 USB Device) 110 | * BCM20702A1_001.002.014.1502.1764 (v5860) 111 | * [`0a5c:21ec`] 20702A1 REF6 OTP module standalone (Broadcom BCM20702 Bluetooth 4.0 USB Device) 112 | * BCM20702A1_001.002.014.1443.1460 (v5556) 113 | * [`0a5c:21f1`] 43228 combo (Broadcom Bluetooth 4.0 Adapter) 114 | * BCM20702A1_001.002.014.1502.1765 (v5861) 115 | * [`0a5c:21f3`] Lenovo Edge 43228 + 20702A1 combo (Broadcom Bluetooth 4.0) 116 | * BCM20702A1_001.002.014.1502.1761 (v5857) 117 | * [`0a5c:21f4`] Lenovo Edge 4313 + 20702A1 combo (Broadcom Bluetooth 4.0) 118 | * BCM20702A1_001.002.014.1502.1760 (v5856) 119 | * [`0a5c:21fb`] HP Supra 4352 20702A1 combo (Broadcom 20702 Bluetooth 4.0 Adapter) 120 | * BCM20702A1_001.002.014.1502.1766 (v5862) 121 | * [`0a5c:21fd`] BRCM Generic 4352z RAMUSB (Broadcom BCM20702 Bluetooth 4.0 +HS USB Device) 122 | * BCM20702A1_001.002.014.1443.1463 (v5559) 123 | * [`0a5c:21fe`] HP Vegas 43142 combo (Broadcom 43142 Bluetooth 4.0 Adapter) 124 | * BCM43142A0_001.001.011.0161.0186 (v4282) 125 | * [`0a5c:640b`] HP Luffy 43228 + 20702 M.2 (Broadcom Bluetooth 4.0 Adapter) 126 | * BCM20702A1_001.002.014.1502.1769 (v5865) 127 | * [`0a5c:6410`] 20703A1 RAM download - DW1830 43602 (Dell Wireless 1830 Bluetooth 4.1 LE) 128 | * BCM20703A1_001.001.005.0214.0422 (v4518) 129 | * [`0a5c:6412`] Dell 4350C5 (Dell Wireless 1820A Bluetooth 4.1 LE) 130 | * BCM4350C5_003.006.007.0222.4689 (v4689) 131 | * [`0a5c:6413`] Broadcom Generic 4350C5 (Broadcom Bluetooth 4.0 USB Device) 132 | * BCM4350C5_003.006.007.0120.2118 (v6214) 133 | * [`0a5c:6414`] Lenovo 4350C5 (Broadcom Bluetooth 4.1 USB) 134 | * BCM4350C5_003.006.007.0145.2724 (v6820) 135 | * [`0a5c:6417`] Zebra 4352 (Broadcom 20702 Bluetooth 4.0) 136 | * BCM20702A1_001.002.014.1502.1780 (v5876) 137 | * [`0a5c:6418`] HP Brook 2x2ac (Broadcom 4371 Bluetooth 4.1 Adapter) 138 | * BCM4371C2_001.003.015.0093.0116 (v4212) 139 | * [`0a5c:7460`] 20703A1 RAM download (Broadcom BCM20703 Bluetooth USB Device) 140 | * BCM20703A1_001.001.005.0214.0473 (v4569) 141 | * [`0b05:17b5`] Asus 43228+20702A1 combo (Bluetooth Module) 142 | * BCM20702A1_001.002.014.1443.1468 (v5564) 143 | * [`0b05:17cb`] 20702 standalone (ASUS USB-BT400) 144 | * BCM20702A1_001.002.014.1443.1467 (v5563) 145 | * [`0b05:17cf`] Asus 4352_20702A1 combo (Bluetooth USB module) 146 | * BCM20702A1_001.002.014.1443.1469 (v5565) 147 | * [`0b05:180a`] Azurewave 4360+20702 combo (Bluetooth USB module) 148 | * BCM20702A1_001.002.014.1443.1714 (v5810) 149 | * [`0bb4:0306`] 20703A1 HTC runtime RAM dongle (Broadcom BCM20703 Bluetooth USB Device) 150 | * BCM20703A1_001.001.005.0214.0481 (v4577) 151 | * [`105b:e065`] LenovoChina 43142A0 combo (Broadcom Bluetooth 4.0) 152 | * BCM43142A0_001.001.011.0311.0312 (v4408) 153 | * [`105b:e066`] LenovoChina 43228+20702 combo (Broadcom Bluetooth 4.0 USB) 154 | * BCM20702A1_001.002.014.1443.1487 (v5583) 155 | * [`13d3:3384`] 20702A1 Azurewave standalone (Bluetooth USB module) 156 | * BCM20702A1_001.002.014.1443.1477 (v5573) 157 | * [`13d3:3388`] BRCM Generic 43142A0 RAMUSB (BCM43142 Bluetooth 4.0 +HS USB Device) 158 | * BCM43142A0_001.001.011.0311.0332 (v4428) 159 | * [`13d3:3389`] BRCM Generic 43142A0 RAMUSB (BCM43142 Bluetooth 4.0 +HS USB Device) 160 | * BCM43142A0_001.001.011.0311.0333 (v4429) 161 | * [`13d3:3392`] Azurewave 43228+20702 (Bluetooth Module) 162 | * BCM20702A1_001.002.014.1443.1478 (v5574) 163 | * [`13d3:3404`] 4352HMB Azurewave Module (Bluetooth Module) 164 | * BCM20702A1_001.002.014.1443.1479 (v5575) 165 | * [`13d3:3411`] Dell Alienware 4352 20702A1 combo (Broadcom BCM20702 Bluetooth 4.0 +HS USB Device) 166 | * BCM20702A1_001.002.014.1443.1450 (v5546) 167 | * [`13d3:3413`] Azurewave 4360+20702 combo (Bluetooth USB module) 168 | * BCM20702A1_001.002.014.1443.1481 (v5577) 169 | * [`13d3:3418`] Azurewave 4352+20702 combo module (Bluetooth USB module) 170 | * BCM20702A1_001.002.014.1443.1480 (v5576) 171 | * [`13d3:3435`] AZUREWAVE BCM20702A1_4352 (Bluetooth USB module) 172 | * BCM20702A1_001.002.014.1443.1501 (v5597) 173 | * [`13d3:3456`] AZUREWAVE BCM20702A1_4352 (Bluetooth USB module) 174 | * BCM20702A1_001.002.014.1443.1502 (v5598) 175 | * [`13d3:3482`] AZUREWAVE BCM43142A0 NGFF (Bluetooth USB module) 176 | * BCM43142A0_001.001.011.0311.0346 (v4442) 177 | * [`13d3:3484`] Acer AZUREWAVE BCM43142A0 NGFF (Bluetooth USB module) 178 | * BCM43142A0_001.001.011.0311.0347 (v4443) 179 | * [`13d3:3504`] AW CM217NF BCM4371C2 (Bluetooth USB module) 180 | * BCM4371C2_001.003.015.0093.0118 (v4214) 181 | * [`13d3:3508`] AW ASUS CM217NF BCM4371C2 (Bluetooth USB module) 182 | * BCM4371C2_001.003.015.0093.0117 (v4213) 183 | * [`13d3:3517`] AW CE160H BCM20702 (Bluetooth USB module) 184 | * BCM20702A1_001.002.014.1502.1786 (v5882) 185 | * [`145f:01a3`] 20702A1 Asus Trust standalone (Trust Bluetooth 4.0 Adapter) 186 | * BCM20702A1_001.002.014.1443.1483 (v5579) 187 | * [`185f:2167`] LenovoChina_BCM43142A0_1.1.11.197_NGFF (Broadcom Bluetooth 4.0 USB) 188 | * BCM43142A0_001.001.011.0277.0292 (v4388) 189 | * [`19ff:0239`] Bestbuy 20702B0 micro (Micro size USB to Bluetooth Dongle) 190 | * BCM20702B0_002.001.014.0527.0557 (v4653) 191 | * [`413c:8143`] DW1550 4352+20702 combo (DW1550 Bluetooth 4.0 LE) 192 | * BCM20702A1_001.002.014.1443.1449 (v5545) 193 | * [`413c:8197`] Dell DW380 Nancy Blakes standalone (Dell Wireless 380 Bluetooth 4.0 Module) 194 | * BCM20702A1_001.002.014.1443.1447 (v5543) 195 | -------------------------------------------------------------------------------- /generate_firmware_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | out="GeneratedFirmwares.cpp" 4 | cksum="GeneratedFirmwaresMD5.txt" 5 | cksum_temp="/tmp/$(uuidgen)_GeneratedFirmwareMD5.txt" 6 | 7 | firmwaredir=./firmwares 8 | firmwares=$firmwaredir/*.zhx 9 | 10 | if [[ "$1" == "clean" ]]; then 11 | if [ -e $out ]; then rm $out; fi 12 | if [ -e $cksum ]; then rm $cksum; fi 13 | exit 0 14 | fi 15 | 16 | if [ -e $cksum_temp ]; then rm $cksum_temp; fi 17 | for firmware in $firmwares; do 18 | echo "`basename $firmware` `md5 -q $firmware`" >>$cksum_temp 19 | done 20 | 21 | cksum_old="unknown" 22 | if [[ -e $cksum ]]; then 23 | cksum_old=`md5 -q $cksum` 24 | fi 25 | 26 | cksum_new=`md5 -q $cksum_temp` 27 | if [[ $cksum_new == $cksum_old ]]; then 28 | echo "Firmwares unchanged, no need to update GeneratedFirmwares.cpp" 29 | exit 0 30 | fi 31 | 32 | echo "// GeneratedFirmwares.cpp">$out 33 | echo "//">>$out 34 | echo "// generated from generate_firmware_data.sh">>$out 35 | echo "//">>$out 36 | 37 | for firmware in $firmwares; do 38 | fname=`basename $firmware` 39 | cname=${fname//./_} 40 | 41 | echo "static const unsigned char $cname[] = ">>$out 42 | echo "{">>$out 43 | xxd -i <$firmware >>$out 44 | echo "};">>$out 45 | echo "">>$out 46 | done 47 | 48 | echo "static const FirmwareEntry firmwares[] = ">>$out 49 | echo "{">>$out 50 | for firmware in $firmwares; do 51 | fname=`basename $firmware` 52 | cname=${fname//./_} 53 | echo " { \"${fname}\", ${cname}, sizeof(${cname}), },">>$out 54 | done 55 | echo " { NULL, NULL, 0, },">>$out 56 | echo "};">>$out 57 | 58 | cp $cksum_temp $cksum 59 | --------------------------------------------------------------------------------