From c8473e4bf3d9884f9af68983468eff940d0df7ad Mon Sep 17 00:00:00 2001 From: frankpreel Date: Sun, 2 Oct 2022 20:21:16 +0200 Subject: [PATCH 1/7] README description --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f40483b8..4680afd3 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,12 @@ developer: ## Changelogs -### v0.15.0 (candidate) +### v0.15.1 (candidate) +- 431 optionally lock bootloader after flashing +- 432 Check the path to the files in MSWindows +- 434 Easy Installer detect 2e as not compatible + +### v0.15.0 - No shortcut created when installing from a non-admin account on Windows - e-recovery assets - Update German translation - by F. Wildermuth -- GitLab From e18fea401ad449622a86efa2e9bd6906902871d8 Mon Sep 17 00:00:00 2001 From: frankpreel Date: Sun, 2 Oct 2022 20:21:49 +0200 Subject: [PATCH 2/7] Version number --- src/main/java/ecorp/easy/installer/AppConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ecorp/easy/installer/AppConstants.java b/src/main/java/ecorp/easy/installer/AppConstants.java index 62497b77..c74d633d 100644 --- a/src/main/java/ecorp/easy/installer/AppConstants.java +++ b/src/main/java/ecorp/easy/installer/AppConstants.java @@ -27,7 +27,7 @@ import java.nio.file.Paths; */ public abstract class AppConstants { - public final static String APP_VERSION = "v0.15.0"; + public final static String APP_VERSION = "v0.15.1"; public final static String Separator = FileSystems.getDefault().getSeparator(); public final static String OsName = System.getProperty("os.name"); public final static String JavaHome = System.getProperty("java.home"); -- GitLab From c597c06093b06ac93df3819168631e6bdcf3b4d2 Mon Sep 17 00:00:00 2001 From: frankpreel Date: Sun, 2 Oct 2022 20:22:27 +0200 Subject: [PATCH 3/7] Emerald lock the bootloader --- flash-scripts/linux/emerald-flashingLock.sh | 53 ++++++++++++++++++ .../linux/emerald-install-from-bootloader.sh | 19 ++++--- .../windows/emerald-flashingLock.bat | 47 ++++++++++++++++ .../emerald-install-from-bootloader.bat | 56 +++++++++---------- .../resources/lang/translation.properties | 3 + .../lang/translation_fr_FR.properties | 8 ++- src/main/resources/yaml/emerald_flash.yml | 27 +++++++-- 7 files changed, 170 insertions(+), 43 deletions(-) create mode 100644 flash-scripts/linux/emerald-flashingLock.sh create mode 100644 flash-scripts/windows/emerald-flashingLock.bat diff --git a/flash-scripts/linux/emerald-flashingLock.sh b/flash-scripts/linux/emerald-flashingLock.sh new file mode 100644 index 00000000..4973c8c0 --- /dev/null +++ b/flash-scripts/linux/emerald-flashingLock.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# Copyright (C) 2022 ECORP SAS - Author: Frank Preel +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Parameter +# $1: device id +# $2: fastboot folder path + +# Exit status +# - 0 : bootloader locked +# - 1 : unknown error +# - 2 : Flashing locked failed +# - 101 : $DEVICE_ID missing +# - 102 : $FASTBOOT_FOLDER_PATH is missing + +DEVICE_ID=$1 +FASTBOOT_FOLDER_PATH=$2 + +# check serial number has been provided +if [ -z "$DEVICE_ID" ] +then + exit 101 +fi + +# Check fastboot parent folder path has been provided +if [ -z "$FASTBOOT_FOLDER_PATH" ] +then + exit 102 +fi + +# Build fastboot path +FASTBOOT_PATH=${FASTBOOT_FOLDER_PATH}"fastboot" + +# Lock bootloader +if ! ${FASTBOOT_PATH} flashing lock ; +then + exit 2 +fi + +sleep 1 diff --git a/flash-scripts/linux/emerald-install-from-bootloader.sh b/flash-scripts/linux/emerald-install-from-bootloader.sh index 6fd529b5..6d4ea2df 100755 --- a/flash-scripts/linux/emerald-install-from-bootloader.sh +++ b/flash-scripts/linux/emerald-install-from-bootloader.sh @@ -27,15 +27,16 @@ # - 1 : generic error # - 10: can't unpack system.img # - 11: can't wipe userdata -# - 11: can't wipe metadata +# - 12: can't wipe metadata +# - 13: can't active partition # - 20-30 : see partition_name index below # - 101 : DEVICE_ID missing # - 102 : ARCHIVE_PATH missing # - 103 : fastboot folder path missing -partition_name=(gz_a lk_a md1img_a scp_a spmfw_a sspm_a tee_a boot_a dtbo_a vbmeta_a super) -partition_image=(gz.img lk.img md1img.img scp.img spmfw.img sspm.img tee.img boot.img dtbo.img vbmeta.img super.img) -partition_error=(20 21 22 23 24 25 26 27 28 29 30) +partition_name=(boot_a dtbo_a vbmeta_a vbmeta_system_a vbmeta_vendor_a super lk_a logo preloader_a) +partition_image=(boot.img dtbo.img vbmeta.img vbmeta_system.img vbmeta_vendor.img super.img lk.img logo-verified.bin preloader_yk673v6_lwg62_64.bin) +partition_error=(20 21 22 23 24 25 26 27 28) DEVICE_ID=$1 ARCHIVE_PATH=$2 @@ -87,7 +88,6 @@ echo "unpacked archive" sleep 1 - # Wipe user data if ! "$FASTBOOT_PATH" erase userdata ; then @@ -97,12 +97,12 @@ fi echo "user data wiped" sleep 5 -if ! "$FASTBOOT_PATH" erase metadata ; +if ! "$FASTBOOT_PATH" format md_udc ; then exit 12 fi -echo "meta data wiped" +echo "format md_udc" sleep 5 #Flash partition @@ -116,5 +116,8 @@ for i in ${!partition_name[@]}; do done -"$FASTBOOT_PATH" --set-active=a +if ! "$FASTBOOT_PATH" --set-active=a ; +then + exit 13 +fi diff --git a/flash-scripts/windows/emerald-flashingLock.bat b/flash-scripts/windows/emerald-flashingLock.bat new file mode 100644 index 00000000..a2631220 --- /dev/null +++ b/flash-scripts/windows/emerald-flashingLock.bat @@ -0,0 +1,47 @@ +@echo off + +:: Coyright (C) 2022 ECORP SAS - Author: Frank Preel + +:: This program is free software: you can redistribute it and/or modify +:: it under the terms of the GNU General Public License as published by +:: the Free Software Foundation, either version 3 of the License, or +:: (at your option) any later version. + +:: This program is distributed in the hope that it will be useful, +:: but WITHOUT ANY WARRANTY; without even the implied warranty of +:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +:: GNU General Public License for more details. + +:: You should have received a copy of the GNU General Public License +:: along with this program. If not, see . + +:: Parameter +:: $1: device id +:: $2: fastboot folder path + +:: Exit status +:: - 0 : bootloader locked +:: - 1 : unknown error +:: - 2 : Flashing unlocked failed +:: - 101 : $DEVICE_ID missing +:: - 102 : $FASTBOOT_FOLDER_PATH is missing + + +SET DEVICE_ID=%~1 +SET FASTBOOT_FOLDER_PATH=%~2 + +IF not defined %DEVICE_ID ( + exit /b 101 +) +IF not defined %FASTBOOT_FOLDER_PATH ( + exit /b 102 +) + +SET FASTBOOT_PATH="%FASTBOOT_FOLDER_PATH%fastboot" +%FASTBOOT_PATH% -s %DEVICE_ID% flashing lock +if errorlevel 1 ( + exit /b 2 +) + +timeout 1 >nul 2>&1 +exit /b 0 diff --git a/flash-scripts/windows/emerald-install-from-bootloader.bat b/flash-scripts/windows/emerald-install-from-bootloader.bat index be287ed0..232c4881 100755 --- a/flash-scripts/windows/emerald-install-from-bootloader.bat +++ b/flash-scripts/windows/emerald-install-from-bootloader.bat @@ -27,35 +27,32 @@ :: - 1 : generic error :: - 10: can't unpack system.img :: - 11: can't wipe userdata -:: - 11: can't wipe metadata +:: - 12: can't wipe metadata +:: - 13: can't active partition :: - 20-30 : see partition_name index below :: - 101 : DEVICE_ID missing :: - 102 : ARCHIVE_PATH missing :: - 103 : fastboot folder path missing -SET partition_name[0]=gz_a -SET partition_name[1]=lk_a -SET partition_name[2]=md1img_a -SET partition_name[3]=scp_a -SET partition_name[4]=spmfw_a -SET partition_name[5]=sspm_a -SET partition_name[6]=tee_a -SET partition_name[7]=boot_a -SET partition_name[8]=dtbo_a -SET partition_name[9]=vbmeta_a -SET partition_name[10]=super - -SET partition_image[0]=gz.img -SET partition_image[1]=lk.img -SET partition_image[2]=md1img.img -SET partition_image[3]=scp.img -SET partition_image[4]=spmfw.img -SET partition_image[5]=sspm.img -SET partition_image[6]=tee.img -SET partition_image[7]=boot.img -SET partition_image[8]=dtbo.img -SET partition_image[9]=vbmeta.img -SET partition_image[10]=super.img +SET partition_name[0]=boot_a +SET partition_name[1]=dtbo_a +SET partition_name[2]=vbmeta_a +SET partition_name[3]=vbmeta_system_a +SET partition_name[4]=vbmeta_vendor_a +SET partition_name[5]=super +SET partition_name[6]=lk_a +SET partition_name[7]=logo +SET partition_name[8]=preloader_a + +SET partition_image[0]=boot.img +SET partition_image[1]=dtbo.img +SET partition_image[2]=vbmeta.img +SET partition_image[3]=vbmeta_system.img +SET partition_image[4]=vbmeta_vendor.img +SET partition_image[5]=super.img +SET partition_image[6]=lk.img +SET partition_image[7]=logo-verified.img +SET partition_image[8]=preloader_yk673v6_lwg62_64.img SET partition_error[0]=20 SET partition_error[1]=21 @@ -66,8 +63,6 @@ SET partition_error[5]=25 SET partition_error[6]=26 SET partition_error[7]=27 SET partition_error[8]=28 -SET partition_error[9]=29 -SET partition_error[10]=30 SET DEVICE_ID=%~1 SET ARCHIVE_PATH=%~2 @@ -114,18 +109,21 @@ echo "user data wiped" timeout 5 >nul 2>&1 :: Wipe meta data -%FASTBOOT_PATH% erase userdata +%FASTBOOT_PATH% format md_udc if errorLevel 1 ( exit /b 12 ) echo "meta data wiped" timeout 5 >nul 2>&1 :: Flash partition (for /L %%i in (0,1,10) do ( - %FASTBOOT_PATH% -s %DEVICE_ID% flash %%partition_name[%%i]%% %%partition_image[%%i]%% + call %FASTBOOT_PATH% -s %DEVICE_ID% flash %%partition_name[%%i]%% %%partition_image[%%i]%% if errorLevel 1 ( exit /b %%partition_error[%%i]%% ) timeout 1 >nul 2>&1 call echo "Flashed %%partition_name[%%i]%% " )) +:: Activate %FASTBOOT_PATH% --set-active=a - +if errorLevel 1 ( exit /b 13 ) +echo "set acivated" +timeout 5 >nul 2>&1 \ No newline at end of file diff --git a/src/main/resources/lang/translation.properties b/src/main/resources/lang/translation.properties index e17910e3..6b0a3c4e 100644 --- a/src/main/resources/lang/translation.properties +++ b/src/main/resources/lang/translation.properties @@ -139,6 +139,7 @@ install_instr_startDownload=Keep pressing simultaneously "Power" & "Home" & "Vol install_instr_startFastboot=Keep pressing simultaneously "Power" & "Volume Down" until a screen with green "START" appears to access Fastboot Mode install_instr_startFastbootFromOptions=From options menu use "Volume Up/Down" to select "Fastboot" and "Power" to confirm install_instr_acceptWarning=Accept warning by pressing on "Volume Up" +emerald_install_instr_accept_lock=Accept lock by pressing on "Volume Up" install_instr_verifyHeimdall=Verify Heimdall install_instr_oemUnlock=OEM Unlocking install_instr_recoveryInstall=Recovery installation @@ -248,10 +249,12 @@ script_error_waitRebootFromFastboot_101 = Can't run instruction on the device script_error_serialNumber_missing=No device's serial number provided script_error_fastboot_path_missing= No fastboot tool path provided script_error_fastboot_flashingUnlock_failed=Could not unlock flashing +script_error_fastboot_flashingLock_failed=Could not lock flashing script_error_unknown= The installation encounter an error script_error_cantRebootBootloader= Failed to reboot into bootloader script_error_cantUnpackSources=Failed to unpack /e/ sources script_error_cantWipeData=Failed to wipe data +script_error_cantActivePartition=Failed to active partition script_error_cantFlashBoot=Failed to flash Boot partition script_error_cantFlashDtbo=Failed to flash dtbo partition script_error_cantFlashRecovery=Failed to flash Recovery diff --git a/src/main/resources/lang/translation_fr_FR.properties b/src/main/resources/lang/translation_fr_FR.properties index 0b672a30..9a6ac9bc 100644 --- a/src/main/resources/lang/translation_fr_FR.properties +++ b/src/main/resources/lang/translation_fr_FR.properties @@ -71,7 +71,9 @@ download_lbl_complete=Le téléchargement est terminé, vous êtes maintenant pr install_instr_turnOff=Éteignez le téléphone install_instr_turnOffAgain=Éteignez à nouveau le téléphone install_instr_startDownload=Continuez d'appuyer simultanément sur les boutons « Marche/Arrêt » & « Home » & « Volume moins » jusqu'à ce qu'un écran bleu apparaisse pour accéder au Mode de Téléchargement -install_instr_acceptWarning=Acceptez l'avertissement en appuyant sur « Volume plus » +install_instr_acceptWarning=Acceptez l'avertissement en appuyant sur "Volume plus" +emerald_install_instr_accept_lock=Acceptez le vérouillage en appuyant sur "Volume plus" +install_title_lockBootloader=Vérouillez le bootloader install_instr_oemUnlock=Dévérouillage OEM install_instr_recoveryInstall=Installation du mode de récupération install_instr_leaveDownload=Continuez à appuyer simultanément sur les boutons « Power » & « Home » & « Volume moins » jusqu'à ce que l'appareil s'éteigne @@ -287,7 +289,8 @@ stepTitle_beforeInstallation=Avant l'installation stepTitle_enableOemUnlock=Autorisez le déverouillage OEM stepTitle_checkDeviceUptodate=Verifiez les mises à jour feedback_lbl_sendPrecision=Aucune information qui vous identifie ne sera envoyée -script_error_fastboot_flashingUnlock_failed=Impossible de déverouiller le flashage +script_error_fastboot_flashingUnlock_failed=Impossible de déverrouiller le flashage +script_error_fastboot_flashingLock_failed=Impossible de vérrouiller le flashage script_error_fastboot_path_missing=Aucun chemin vers l'outil fastboot n'a été fourni script_error_serialNumber_missing=Aucun numéro de série fourni install_instr_pressVolUpToAcceptOEMUnlocking=Appuyez sur "volume +" pour accepter le dévérouillage OEM @@ -344,3 +347,4 @@ script_error_cantFlashBoot_a =Erreur de flash boot_a partition script_error_cantFlashDtbo_a =Erreur de flash dtbo_a partition script_error_cantFlashVbmeta_a =Erreur de flash vbmeta_a partition script_error_cantFlashSuper =Erreur de flash super partition + diff --git a/src/main/resources/yaml/emerald_flash.yml b/src/main/resources/yaml/emerald_flash.yml index 48161c36..63d05551 100644 --- a/src/main/resources/yaml/emerald_flash.yml +++ b/src/main/resources/yaml/emerald_flash.yml @@ -14,7 +14,7 @@ ## along with this program. If not, see . ## Author: Frank Preel --- -stepsCount: 6 +stepsCount: 7 steps: f0: type: custom @@ -89,7 +89,8 @@ steps: 1: script_error_unknown 10: script_error_cantUnpackSources 11: script_error_cantWipeData - 12: script_error_cantWipeData + 12: script_error_cantWipeData + 13: script_error_cantActivePartition 20: script_error_cantFlashGz_a 21: script_error_cantFlashLk_a 22: script_error_cantFlashMd1img_a @@ -105,12 +106,30 @@ steps: 102: script_error_installFromFastboot_102 103: script_error_fastboot_path_missing f4: - type: askAccount + type: custom-executable stepNumber: 5 nextStepKey: f5 + titleKey: install_title_lockBootloader + instructions: + - emerald_install_instr_accept_lock + script: emerald-flashingLock + parameters: + device_id: ${DEVICE_ID} + fastboot_folder_path: ${ADB_FOLDER_PATH} + okCodes: + 0: ~ + koCodes: + 1: script_error_unknown + 2: script_error_fastboot_flashingLock_failed + 101: script_error_serialNumber_missing + 102: script_error_fastboot_path_missing f5: - type: custom-executable + type: askAccount stepNumber: 6 + nextStepKey: f6 + f6: + type: custom-executable + stepNumber: 7 nextStepKey: end titleKey: stepTitle_rebootDevice titleIconName: icon-download.png -- GitLab From e21a85d1e3514991055dfe49d1f4aed3a29dda30 Mon Sep 17 00:00:00 2001 From: frankpreel Date: Sun, 2 Oct 2022 20:31:23 +0200 Subject: [PATCH 4/7] 434 Teracube 2e and emerald --- .../subcontrollers/DeviceDetectedController.java | 13 ------------- .../easy/installer/tasks/DeviceDetectionTask.java | 9 ++++++++- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/main/java/ecorp/easy/installer/controllers/subcontrollers/DeviceDetectedController.java b/src/main/java/ecorp/easy/installer/controllers/subcontrollers/DeviceDetectedController.java index bdff37e3..fde8445d 100644 --- a/src/main/java/ecorp/easy/installer/controllers/subcontrollers/DeviceDetectedController.java +++ b/src/main/java/ecorp/easy/installer/controllers/subcontrollers/DeviceDetectedController.java @@ -106,19 +106,6 @@ public class DeviceDetectedController extends AbstractSubController{ return; } - if("2e".equals(phone.getAdbDevice())){ - displayIncompatibleDeviceFound(phone.getAdbModel()); - return; - } - - if("emerald".equals(phone.getAdbDevice()) || - "Teracube_2e".equals(phone.getAdbDevice()) ){ - final String serial = phone.getSerialNo(); - if ( ! serial.startsWith("202111") ) { - displayIncompatibleDeviceFound(phone.getAdbModel()); - return; - } - } //If device is unauthorized if(!phone.isAdbAuthorized()){ displayUnauthorizedDeviceFound(); diff --git a/src/main/java/ecorp/easy/installer/tasks/DeviceDetectionTask.java b/src/main/java/ecorp/easy/installer/tasks/DeviceDetectionTask.java index b5d64f8b..102cb097 100644 --- a/src/main/java/ecorp/easy/installer/tasks/DeviceDetectionTask.java +++ b/src/main/java/ecorp/easy/installer/tasks/DeviceDetectionTask.java @@ -146,7 +146,14 @@ public class DeviceDetectionTask extends Task{ }else if(stringPart.contains("device:")){ logger.debug(" \"device\" keyword has been found"); String device = stringPart.substring("device:".length() ); - if(device.equals("Teracube_2e")) device ="emerald"; + + // Teracube, going to assume that anything that starts with 2020 is "2e", otherwise it's "emerald". + if(device.equals("Teracube_2e")) { + device ="emerald"; + if (datas[0].startsWith("2020")) + device ="Teracube_2e"; + } + //if(device.equals("k63v2_64_bsp")) device="GS290"; //bad idea. Device not really compatible. result.setAdbDevice(device); } -- GitLab From cb87218335a933455b4af6ca71bd2956933f8333 Mon Sep 17 00:00:00 2001 From: frankpreel Date: Sun, 2 Oct 2022 21:04:28 +0200 Subject: [PATCH 5/7] 432 Check the path to the files in MSWindows --- flash-scripts/windows/emerald-wait-reboot-from-fastboot.bat | 2 +- flash-scripts/windows/install-recovery.bat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flash-scripts/windows/emerald-wait-reboot-from-fastboot.bat b/flash-scripts/windows/emerald-wait-reboot-from-fastboot.bat index d7cf1b12..a044c5d7 100755 --- a/flash-scripts/windows/emerald-wait-reboot-from-fastboot.bat +++ b/flash-scripts/windows/emerald-wait-reboot-from-fastboot.bat @@ -26,7 +26,7 @@ :: - 101 : no device found in fastboot SET FASTBOOT_FOLDER_PATH=%~1 -SET FASTBOOT_PATH=%FASTBOOT_FOLDER_PATH%"fastboot" +SET FASTBOOT_PATH="%FASTBOOT_FOLDER_PATH%fastboot" echo "fastboot path: %FASTBOOT_PATH%" diff --git a/flash-scripts/windows/install-recovery.bat b/flash-scripts/windows/install-recovery.bat index e8c78962..c5eca04e 100755 --- a/flash-scripts/windows/install-recovery.bat +++ b/flash-scripts/windows/install-recovery.bat @@ -31,6 +31,6 @@ if not defined %TWRP_IMAGE_PATH ( ping 127.0.0.1 -n 3 -w 10000 >NUL set HEIMDALL_PATH="%HEIMDALL_FOLDER%heimdall" -%HEIMDALL_PATH% flash --RECOVERY %TWRP_IMAGE_PATH% --no-reboot +%HEIMDALL_PATH% flash --RECOVERY "%TWRP_IMAGE_PATH%" --no-reboot exit /b 0 \ No newline at end of file -- GitLab From 305a3848c52c9e6246bc45e58f693859e0609c9f Mon Sep 17 00:00:00 2001 From: Frank PREEL Date: Mon, 3 Oct 2022 10:28:26 +0200 Subject: [PATCH 6/7] Permission Fix --- flash-scripts/linux/emerald-flashingLock.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 flash-scripts/linux/emerald-flashingLock.sh diff --git a/flash-scripts/linux/emerald-flashingLock.sh b/flash-scripts/linux/emerald-flashingLock.sh old mode 100644 new mode 100755 -- GitLab From d80459849b72abaa924e984f4b66066c81321d1c Mon Sep 17 00:00:00 2001 From: Vincent Bourgmayer Date: Wed, 5 Oct 2022 13:51:54 +0000 Subject: [PATCH 7/7] Fine for me --- .../ecorp/easy/installer/tasks/DeviceDetectionTask.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/ecorp/easy/installer/tasks/DeviceDetectionTask.java b/src/main/java/ecorp/easy/installer/tasks/DeviceDetectionTask.java index 102cb097..ba64c635 100644 --- a/src/main/java/ecorp/easy/installer/tasks/DeviceDetectionTask.java +++ b/src/main/java/ecorp/easy/installer/tasks/DeviceDetectionTask.java @@ -148,10 +148,8 @@ public class DeviceDetectionTask extends Task{ String device = stringPart.substring("device:".length() ); // Teracube, going to assume that anything that starts with 2020 is "2e", otherwise it's "emerald". - if(device.equals("Teracube_2e")) { - device ="emerald"; - if (datas[0].startsWith("2020")) - device ="Teracube_2e"; + if (device.equals("Teracube_2e") && !datas[0].startsWith("2020")) { + device ="emerald"; } //if(device.equals("k63v2_64_bsp")) device="GS290"; //bad idea. Device not really compatible. -- GitLab