├── META-INF └── com │ └── google │ └── android │ ├── updater-script │ └── update-binary ├── bash.tar.xz ├── module.prop ├── service.sh ├── SUPPORT.md ├── hexpatch.sh ├── customize.sh └── README.md /META-INF/com/google/android/updater-script: -------------------------------------------------------------------------------- 1 | #MAGISK 2 | -------------------------------------------------------------------------------- /bash.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Magisk-Modules-Repo/BluetoothLibraryPatcher/HEAD/bash.tar.xz -------------------------------------------------------------------------------- /module.prop: -------------------------------------------------------------------------------- 1 | id=BluetoothLibraryPatcher 2 | name=Bluetooth Library Patcher 3 | version=v2.3.2 4 | versionCode=232 5 | author=3arthur6 6 | description=Magisk module avoiding loss of bluetooth pairings after reboot or airplane mode switch on rooted samsung devices. 7 | updateJson=https://raw.githubusercontent.com/3arthur6/BluetoothLibraryPatcher/master/update.json 8 | -------------------------------------------------------------------------------- /service.sh: -------------------------------------------------------------------------------- 1 | # BluetoothLibraryPatcher 2 | # ota survival script 3 | # by 3arthur6 4 | 5 | MODDIR=${0%/*} 6 | previouslibmd5sum_tmp 7 | 8 | if [[ $previouslibmd5sum != `md5sum $(find $(magisk --path)/.magisk/mirror/system/lib*|grep -E "\/(libbluetooth|bluetooth\.default)\.so$"|tail -n 1)|cut -d " " -f1` ]] ; then 9 | magisk --install-module $MODDIR/module.zip 10 | else 11 | exit 12 | fi 13 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | ## Library not supported 2 | 3 | If you are here so your bluetooth library isn't supported by the module yet. 4 | 5 | Open an issue here in [github](https://github.com/Magisk-Modules-Repo/BluetoothLibraryPatcher/issues/new) or at the [XDA thread](https://forum.xda-developers.com/galaxy-note-9/development/zip-libbluetooth-patcher-fix-losing-t4017735). 6 | 7 | A file called BluetoothLibPatcher-files.tar has been created on the main folder of your phone storage. 8 | Please attach it (or a link to it) with your report! 9 | -------------------------------------------------------------------------------- /hexpatch.sh: -------------------------------------------------------------------------------- 1 | # BluetoothLibraryPatcher 2 | # hexpatch script 3 | # by 3arthur6 4 | 5 | bb=/data/adb/magisk/busybox 6 | qcom=`$bb grep -qw androidboot.hardware=qcom /proc/cmdline && echo 'true' || echo 'false'` 7 | 8 | # default(mostly arm64 exynos)=1 arm=2 qcom=3 9 | var=`if ! $IS64BIT || [[ $API -le 25 ]]; then echo 2; elif $qcom && [[ $API -le 30 ]]; then echo 3; else echo 1; fi` 10 | 11 | hex=( \ 12 | # default 13 | [131]=........f9031f2af3031f2a41000014 [1131]=1f2003d5f9031f2af3031f2a48000014 \ 14 | [130]=........f3031f2af4031f2a3e000014 [1130]=1f2003d5f3031f2af4031f2a3e000014 \ 15 | [129]=........f4031f2af3031f2ae8030032 [1129]=1f2003d5f4031f2af3031f2ae8031f2a \ 16 | [128]=88000034e803003248070035 [1128]=1f2003d5e8031f2a48070035 \ 17 | [127]=${hex[126]} [1127]=${hex[1126]} \ 18 | [126]=88000034e803003228050035 [1126]=1f2003d5e8031f2a28050035 \ 19 | # arm 20 | [230]=18b14ff0000b00254ae0 [1230]=00204ff0000b002554e0 \ 21 | [229]=..b100250120 [1229]=00bf00250020 \ 22 | [228]=..b101200028 [1228]=00bf00200028 \ 23 | [227]=09b1012032e0 [1227]=00bf002032e0 \ 24 | [226]=08b1012031e0 [1226]=00bf002031e0 \ 25 | [225]=087850bbb548 [1225]=08785ae1b548 \ 26 | [224]=007840bb6a48 [1224]=0078c4e06a48 \ 27 | # qcom 28 | [330]=${hex[329]} [1330]=${hex[3129]} \ 29 | [329]=88000054691180522925c81a69000037........ [1329]=04000014691180522925c81a69000037e0031f2a \ 30 | [328]=7f1d0071e91700f9e83c0054 [1328]=e0031f2ae91700f9e8010014 \ 31 | # what is happening samsung 32 | [429]=....0034f3031f2af4031f2a....0014 [1429]=1f2003d5f3031f2af4031f2a47000014 \ 33 | # what again (T510) 34 | [529]=44387810b1002400254ae0 [1529]=44387800200024002556e0 \ 35 | [530]=18b100244ff0000b4de0 [1530]=002000244ff0000b57e0 \ 36 | # ... (T595) 37 | [629]=90387810b1002400254ae0 [1629]=90387800200024002558e0 ) 38 | 39 | if [[ $var == 3 ]] && ! `$bb xxd -p $lib|$bb tr -d '\n'|$bb grep -qm1 ${hex[$var$API]}` ; then 40 | if `$bb xxd -p $lib|$bb tr -d '\n'|$bb grep -qm1 ${hex[1$var$API]}` ; then 41 | hex[$var$API]=already 42 | else 43 | var=1 44 | fi 45 | fi 46 | if ( [[ $var == 1 ]] && [[ $API -ge 29 ]] ) || ( [[ $var == 2 ]] && [[ $API -ge 28 ]] ) ; then 47 | hex[$var$API]=`$bb xxd -p $lib|$bb tr -d '\n'|$bb grep -om1 ${hex[$var$API]}` 48 | fi 49 | if [[ -z `$bb xxd -p $lib|$bb tr -d '\n'|$bb grep -om1 ${hex[$var$API]}` ]] ; then 50 | if `$bb xxd -p $lib|$bb tr -d '\n'|$bb grep -qm1 ${hex[1$var$API]}` ; then 51 | hex[$var$API]=already 52 | elif [[ $var == 1 ]] && [[ $API == 29 ]] && hex[4$API]=`$bb xxd -p $lib|$bb tr -d '\n'|$bb grep -om1 ${hex[4$API]}` && [[ ! -z ${hex[4$API]} ]] ; then 53 | var=4 54 | elif [[ $var == 2 ]] && [[ $API -ge 29 ]] ; then 55 | if `$bb xxd -p $lib|$bb tr -d '\n'|$bb grep -qm1 ${hex[5$API]}` ; then 56 | var=5 57 | elif `$bb xxd -p $lib|$bb tr -d '\n'|$bb grep -qm1 ${hex[6$API]}` ; then 58 | var=6 59 | fi 60 | fi 61 | fi 62 | echo -e "${hex[$var$API]}\n${hex[1$var$API]}\nvar=$var\nbl=$($bb grep -o androidboot.bootloader=.* /proc/cmdline|$bb cut -d ' ' -f1|$bb cut -d '=' -f2)" > $TMPDIR/patch 63 | -------------------------------------------------------------------------------- /customize.sh: -------------------------------------------------------------------------------- 1 | # BluetoothLibraryPatcher 2 | # by 3arthur6 3 | 4 | check() { 5 | samsung=`grep -Eqw "androidboot.odin_download|androidboot.warranty_bit|sec_debug" /proc/cmdline && echo 'true' || echo 'false'` 6 | if $BOOTMODE ; then 7 | ui_print "- Magisk Manager installation" 8 | sys="`magisk --path`/.magisk/mirror/system" 9 | else 10 | ui_print "- Recovery installation" 11 | sys=`dirname $(find / -mindepth 2 -maxdepth 3 -path "*system/build.prop"|head -1)` 12 | fi 13 | if ! $samsung ; then 14 | ui_print "- Only for Samsung devices!" 15 | abort 16 | elif ! `grep -qw ro.build.type=user $sys/build.prop` ; then 17 | ui_print "- Only for Samsung stock based roms!" 18 | ui_print "- Not relevant for aosp roms!" 19 | abort 20 | elif [[ $API -lt 24 ]] ; then 21 | ui_print "- Only for Android 7.0 (Nougat) and above" 22 | abort 23 | fi 24 | } 25 | 26 | search() { 27 | ui_print "- Searching for relevant hex byte sequence" 28 | lib=`find $sys/lib*|grep -E "\/(libbluetooth|bluetooth\.default)\.so$"|tail -n 1` 29 | unzip -q $ZIPFILE hexpatch.sh -d $TMPDIR 30 | chmod 755 $TMPDIR/hexpatch.sh 31 | # Executed through bash for array handling 32 | unzip -p $ZIPFILE bash.tar.xz|tar x -J -C $TMPDIR bash 33 | chmod 755 $TMPDIR/bash 34 | export TMPDIR API IS64BIT lib 35 | $TMPDIR/bash $TMPDIR/hexpatch.sh 36 | } 37 | 38 | extract() { 39 | if [ ! -f $lib ] ; then 40 | ui_print "- Library not found!" 41 | abort 42 | else 43 | ui_print "- Copying library from system to module" 44 | mod_path="$MODPATH/`echo $lib|grep -o system.*`" 45 | mkdir -p `dirname $mod_path` 46 | cp -af $lib $mod_path 47 | fi 48 | } 49 | 50 | patchlib() { 51 | ui_print "- Applying patch" 52 | pre=`cat $TMPDIR/patch|sed -n '1 p'` 53 | post=`cat $TMPDIR/patch|sed -n '2 p'` 54 | if [[ $pre == already ]] ; then 55 | ui_print "- Library already (system-ly) patched!" 56 | abort 57 | elif [[ ! -z $pre ]] && `/data/adb/magisk/magiskboot hexpatch $mod_path $pre $post` ; then 58 | ui_print "- Successfully patched!" 59 | else 60 | ui_print "- Library not supported!" 61 | echo -e "BOOTMODE=$BOOTMODE\nAPI=$API\nIS64BIT=$IS64BIT\nlib=$lib" > $TMPDIR/debug 62 | cp -f $lib $TMPDIR 63 | tar c -f /sdcard/BluetoothLibPatcher-files.tar -C $TMPDIR `ls $TMPDIR|sed -E '/bash|hexpatch\.sh/d'` 64 | ui_print " " 65 | ui_print "- To get support upload BluetoothLibPatcher-files.tar" 66 | ui_print " created in your internal storage to github issue or XDA thread" 67 | ui_print " " 68 | ui_print "- Opening support webpage in 5 seconds" 69 | (sleep 5 && am start -a android.intent.action.VIEW -d https://github.com/Magisk-Modules-Repo/BluetoothLibraryPatcher/blob/master/SUPPORT.md >/dev/null) & 70 | rm -rf $MODPATH 71 | abort 72 | fi 73 | } 74 | 75 | otasurvival() { 76 | ui_print "- Creating OTA survival service" 77 | cp -f $ZIPFILE $MODPATH/module.zip 78 | sed -i "s|previouslibmd5sum_tmp|previouslibmd5sum=`md5sum $lib|cut -d ' ' -f1`|" $MODPATH/service.sh 79 | } 80 | 81 | check 82 | search 83 | extract 84 | patchlib 85 | otasurvival 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bluetooth Library Patcher 2 | 3 | ## EOL of Magisk modules repo 4 | 5 | For support and latest updates, go to [my personnal gitub repo](https://github.com/3arthur6/BluetoothLibraryPatcher) 6 | 7 | ## Description 8 | 9 | This module attends to avoid losing bluetooth pairings after reboot or airplane mode switch on rooted samsung devices. 10 | 11 | It patches on the fly the bluetooth library and should support most of samsung devices on android Nougat, Oreo, Pie, 10, 11 and 12. 12 | 13 | This patch is NOT applicable with an aosp rom, only samsung stock/based. 14 | 15 | ## Galaxy Watch devices support 16 | 17 | Due to limitations in Magisk, a manual step is required to fix pairing issues with Galaxy Watch devices. After installing the Magisk module, use a command line (like Terminal Emulator or Termux) to run the following commands, then reboot: 18 | 19 | *Beware! /!\ Owners of the S21 series cannot use these commands (or you have to be SURE your vendor partition isn't read only or full) and must instead use the zip bellow to flash using TWRP. The commands below could brick your device /!\* 20 | 21 | ```bash 22 | $ su 23 | $ mount -o remount,rw /vendor 24 | $ i=`grep -lr 'security.wsm' /vendor/etc/vintf` && [ ! -z $i ] && [ $i != *.bak ] && cp --preserve=all $i $i.bak && sed -i "$((`awk '/security.wsm/ {print FNR}' $i`-1)),/<\/hal>/d" $i 25 | $ mount -o remount,ro /vendor 26 | ``` 27 | 28 | Alternatively, instead of installing the Magisk module and running the commands, flash the zip file (BluetoothLibraryPatcher_twrp_X.X.X.zip​) meant for TWRP recovery found on [XDA](https://forum.xda-developers.com/galaxy-note-9/development/zip-libbluetooth-patcher-fix-losing-t4017735) under 'Links'. 29 | 30 | ## Credits 31 | 32 | - @topjohnwu for magisk 33 | - @afaneh92 for the partition resizing script 34 | 35 | ## Source code 36 | 37 | [Github](https://github.com/Magisk-Modules-Repo/BluetoothLibraryPatcher) 38 | 39 | ## Support 40 | 41 | [XDA](https://forum.xda-developers.com/galaxy-note-9/development/zip-libbluetooth-patcher-fix-losing-t4017735) 42 | 43 | ## Changelog 44 | 45 | ### v1.0 46 | 47 | - Initial release 48 | 49 | ### v1.1 50 | 51 | - Add verification point, to know if we successfully hexpatch 52 | 53 | ### v1.2 54 | 55 | - Add recovery installation support 56 | 57 | ### v1.3 58 | 59 | - Modify hexpatch (more safer patch) 60 | 61 | ### v1.4 62 | 63 | - Add support for chinese variants 64 | 65 | ### v1.5 66 | 67 | - Check we try to apply the patch on a Samsung device & add missing chinese Note10+ 5G variant 68 | 69 | ### v1.6 70 | 71 | - Fix brand and model detection for magisk manager and recovery installation 72 | 73 | ### v1.7 74 | 75 | - Add support for chinese/global snapdragon on Pie 76 | - Add support for chinese/global S/N9 snapdragon on Q & simplify the hexpatch 77 | 78 | ### v1.8 79 | 80 | - Add support for A6, A10, A80, some S10e and N10 variants 81 | - Apply the only known qcom fix to all of them 82 | - Add some checks to avoid false negatives 83 | 84 | ### v1.9 85 | 86 | - Support more arm devices 87 | - Auto create tar with needed files in internal storage to fix unsupported devices 88 | 89 | ### v2.0 90 | 91 | - Support more devices 92 | - Misc optimizations 93 | 94 | ### v2.1 95 | 96 | - Android 11 support 97 | - Android Nougat support 98 | - Misc optimizations 99 | 100 | ### v2.1.1 101 | 102 | - Divers Android 11 fixes 103 | 104 | ### v2.2 105 | 106 | - Large rewrite 107 | - Detect now OTAs and reapply the patch if needed 108 | 109 | ### v2.2.1 110 | 111 | - Misc fixes 112 | 113 | ### v2.2.2 114 | 115 | - Fix OTA survival script 116 | 117 | ### v2.2.3 118 | 119 | - Handle library changes from latest A505FN firmware and possibly others devices 120 | 121 | ### v2.3 122 | 123 | - Android 12 support 124 | - Handle few specific devices 125 | 126 | ### v2.3.1 127 | 128 | - Fix qcoms on Android 12 129 | - Add A105F on Android 11 130 | 131 | ### v2.3.2 132 | 133 | - Final release on Magisk modules repo 134 | - Update for Magisk v24.0 135 | - Misc updates 136 | -------------------------------------------------------------------------------- /META-INF/com/google/android/update-binary: -------------------------------------------------------------------------------- 1 | #!/sbin/sh 2 | 3 | ################# 4 | # Initialization 5 | ################# 6 | 7 | umask 022 8 | 9 | # echo before loading util_functions 10 | ui_print() { echo "$1"; } 11 | 12 | require_new_magisk() { 13 | ui_print "*******************************" 14 | ui_print " Please install Magisk v20.0+! " 15 | ui_print "*******************************" 16 | exit 1 17 | } 18 | 19 | ######################### 20 | # Load util_functions.sh 21 | ######################### 22 | 23 | OUTFD=$2 24 | ZIPFILE=$3 25 | 26 | mount /data 2>/dev/null 27 | 28 | [ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk 29 | . /data/adb/magisk/util_functions.sh 30 | [ $MAGISK_VER_CODE -lt 20000 ] && require_new_magisk 31 | 32 | if [ $MAGISK_VER_CODE -ge 20400 ]; then 33 | # New Magisk have complete installation logic within util_functions.sh 34 | install_module 35 | exit 0 36 | fi 37 | 38 | ################# 39 | # Legacy Support 40 | ################# 41 | 42 | TMPDIR=/dev/tmp 43 | PERSISTDIR=/sbin/.magisk/mirror/persist 44 | 45 | is_legacy_script() { 46 | unzip -l "$ZIPFILE" install.sh | grep -q install.sh 47 | return $? 48 | } 49 | 50 | print_modname() { 51 | local authlen len namelen pounds 52 | namelen=`echo -n $MODNAME | wc -c` 53 | authlen=$((`echo -n $MODAUTH | wc -c` + 3)) 54 | [ $namelen -gt $authlen ] && len=$namelen || len=$authlen 55 | len=$((len + 2)) 56 | pounds=$(printf "%${len}s" | tr ' ' '*') 57 | ui_print "$pounds" 58 | ui_print " $MODNAME " 59 | ui_print " by $MODAUTH " 60 | ui_print "$pounds" 61 | ui_print "*******************" 62 | ui_print " Powered by Magisk " 63 | ui_print "*******************" 64 | } 65 | 66 | # Override abort as old scripts have some issues 67 | abort() { 68 | ui_print "$1" 69 | $BOOTMODE || recovery_cleanup 70 | [ -n $MODPATH ] && rm -rf $MODPATH 71 | rm -rf $TMPDIR 72 | exit 1 73 | } 74 | 75 | rm -rf $TMPDIR 2>/dev/null 76 | mkdir -p $TMPDIR 77 | 78 | # Preperation for flashable zips 79 | setup_flashable 80 | 81 | # Mount partitions 82 | mount_partitions 83 | 84 | # Detect version and architecture 85 | api_level_arch_detect 86 | 87 | # Setup busybox and binaries 88 | $BOOTMODE && boot_actions || recovery_actions 89 | 90 | ############## 91 | # Preparation 92 | ############## 93 | 94 | # Extract prop file 95 | unzip -o "$ZIPFILE" module.prop -d $TMPDIR >&2 96 | [ ! -f $TMPDIR/module.prop ] && abort "! Unable to extract zip file!" 97 | 98 | $BOOTMODE && MODDIRNAME=modules_update || MODDIRNAME=modules 99 | MODULEROOT=$NVBASE/$MODDIRNAME 100 | MODID=`grep_prop id $TMPDIR/module.prop` 101 | MODNAME=`grep_prop name $TMPDIR/module.prop` 102 | MODAUTH=`grep_prop author $TMPDIR/module.prop` 103 | MODPATH=$MODULEROOT/$MODID 104 | 105 | # Create mod paths 106 | rm -rf $MODPATH 2>/dev/null 107 | mkdir -p $MODPATH 108 | 109 | ########## 110 | # Install 111 | ########## 112 | 113 | if is_legacy_script; then 114 | unzip -oj "$ZIPFILE" module.prop install.sh uninstall.sh 'common/*' -d $TMPDIR >&2 115 | 116 | # Load install script 117 | . $TMPDIR/install.sh 118 | 119 | # Callbacks 120 | print_modname 121 | on_install 122 | 123 | # Custom uninstaller 124 | [ -f $TMPDIR/uninstall.sh ] && cp -af $TMPDIR/uninstall.sh $MODPATH/uninstall.sh 125 | 126 | # Skip mount 127 | $SKIPMOUNT && touch $MODPATH/skip_mount 128 | 129 | # prop file 130 | $PROPFILE && cp -af $TMPDIR/system.prop $MODPATH/system.prop 131 | 132 | # Module info 133 | cp -af $TMPDIR/module.prop $MODPATH/module.prop 134 | 135 | # post-fs-data scripts 136 | $POSTFSDATA && cp -af $TMPDIR/post-fs-data.sh $MODPATH/post-fs-data.sh 137 | 138 | # service scripts 139 | $LATESTARTSERVICE && cp -af $TMPDIR/service.sh $MODPATH/service.sh 140 | 141 | ui_print "- Setting permissions" 142 | set_permissions 143 | else 144 | print_modname 145 | 146 | unzip -o "$ZIPFILE" customize.sh -d $MODPATH >&2 147 | 148 | if ! grep -q '^SKIPUNZIP=1$' $MODPATH/customize.sh 2>/dev/null; then 149 | ui_print "- Extracting module files" 150 | unzip -o "$ZIPFILE" -x 'META-INF/*' -d $MODPATH >&2 151 | 152 | # Default permissions 153 | set_perm_recursive $MODPATH 0 0 0755 0644 154 | fi 155 | 156 | # Load customization script 157 | [ -f $MODPATH/customize.sh ] && . $MODPATH/customize.sh 158 | fi 159 | 160 | # Handle replace folders 161 | for TARGET in $REPLACE; do 162 | ui_print "- Replace target: $TARGET" 163 | mktouch $MODPATH$TARGET/.replace 164 | done 165 | 166 | if $BOOTMODE; then 167 | # Update info for Magisk Manager 168 | mktouch $NVBASE/modules/$MODID/update 169 | cp -af $MODPATH/module.prop $NVBASE/modules/$MODID/module.prop 170 | fi 171 | 172 | # Copy over custom sepolicy rules 173 | if [ -f $MODPATH/sepolicy.rule -a -e $PERSISTDIR ]; then 174 | ui_print "- Installing custom sepolicy patch" 175 | # Remove old recovery logs (which may be filling partition) to make room 176 | rm -f $PERSISTDIR/cache/recovery/* 177 | PERSISTMOD=$PERSISTDIR/magisk/$MODID 178 | mkdir -p $PERSISTMOD 179 | cp -af $MODPATH/sepolicy.rule $PERSISTMOD/sepolicy.rule || abort "! Insufficient partition size" 180 | fi 181 | 182 | # Remove stuffs that don't belong to modules 183 | rm -rf \ 184 | $MODPATH/system/placeholder $MODPATH/customize.sh \ 185 | $MODPATH/README.md $MODPATH/.git* 2>/dev/null 186 | 187 | ############# 188 | # Finalizing 189 | ############# 190 | 191 | cd / 192 | $BOOTMODE || recovery_cleanup 193 | rm -rf $TMPDIR 194 | 195 | ui_print "- Done" 196 | exit 0 197 | --------------------------------------------------------------------------------