Przeglądaj źródła

Merge pull request #11 from derskythe/master

Sync working tree
Der Skythe 2 lat temu
rodzic
commit
a89ba3ccf4

+ 218 - 0
.github/workflows/build-with-firmwware.yml

@@ -0,0 +1,218 @@
+name: "Build for Firmware"
+run-name: "Build ${{ inputs.DEPLOY_TARGET }} by @${{ github.ACTOR }}"
+
+on:
+  workflow_dispatch:
+    inputs:
+      version:
+        description: "Enter version to build or left empty for current version"
+        required: false
+        type: string
+  release:
+    types: [unpublished]
+  push:
+    paths:
+      - .github/workflows/build-with-firmware.yml
+
+permissions:
+  contents: write
+  packages: write
+
+jobs:
+  build-and-upload:
+    # runs-on: [self-hosted, linux]
+    runs-on: ubuntu-latest
+    concurrency:
+      group: firmware-build-${{ vars.FIRMWARE_VERSION }}-${{ vars.RELEASE_VERSION }}
+      cancel-in-progress: false
+    env:
+      REPO_SELF: ${{ vars.REPO_SELF }}
+      IGNORED_PATH: "applications_user/subbrute"
+      RELATIVE_PATH: "applications/external/subbrute"
+      CURRENT_VERSION: ${{ vars.RELEASE_VERSION }}
+    strategy:
+      fail-fast: false
+      matrix:
+        firmware: [unlshd]
+        include:
+          - firmware: unlshd
+            url: ${{ vars.REPO_UNLEASHED }}
+            version: ${{ vars.FIRMWARE_VERSION }}
+            src-included: 1
+          #- firmware: official
+          #  url: ${{ vars.REPO_OFFICIAL }}
+          #  version: "official"
+    steps:
+      - name: Set version
+        env:
+          INPUT_VERSION: ${{ inputs.version }}
+          CURRENT_VERSION: ${{ env.CURRENT_VERSION }}
+        shell: pwsh
+        run: |
+          $ReleaseVersion = ([string]::IsNullOrWhitespace($env:INPUT_VERSION) ? $env:CURRENT_VERSION : $env:INPUT_VERSION)
+          Write-Output ('RELEASE_VERSION={0}' -f $ReleaseVersion) >> $env:GITHUB_ENV
+
+      - name: Copy Repo Files
+        uses: actions/checkout@v3
+        with:
+          repository: "${{ matrix.url }}"
+          clean: "true"
+          submodules: "true"
+          ref: "dev"
+
+      - name: Copy Repo Files
+        if: ${{ matrix.src-included == 0 }}
+        uses: actions/checkout@v3
+        with:
+          repository: "${{ vars.REPO_SELF }}"
+          clean: "true"
+          submodules: "true"
+          path: "${{ env.IGNORED_PATH }}"
+
+      - name: Print vars about state or repo if Unleashed
+        if: ${{ matrix.src-included == 1 }}
+        shell: pwsh
+        run: |
+          git log --pretty=format:'%s by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local --abbrev-commit --max-count=1
+          git submodule set-branch --branch master '${{ env.RELATIVE_PATH }}'
+          git submodule sync '${{ env.RELATIVE_PATH }}'
+          cd '${{ env.RELATIVE_PATH }}'
+          if ( '${{ env.CURRENT_VERSION }}' -ne '${{ env.RELEASE_VERSION }}' ) {
+            Write-Output '::warning title=Different version::Current version is ${{ env.CURRENT_VERSION }} but we trying to build ${{ env.RELEASE_VERSION }}'
+            git checkout tags/v${{ env.RELEASE_VERSION }} -b tmp-build
+
+            if ( $LASTEXITCODE -ne 0 ) {
+              Write-Error '::error title=Cannot checkout to this version::Error during execution checkout to this tag ${{ env.RELEASE_VERSION }}'
+              exit 1
+            }
+          }
+
+          $Output = (git log --pretty=format:'%s by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local --abbrev-commit --max-count=1)
+
+          if ( $LASTEXITCODE -ne 0 ) {
+            Write-Error '::error title=Invalid checkout::Invalid checkout'
+            exit 1
+          }
+          Write-Output ('::notice title=Git output::{0}' -f $Output)
+
+      - name: Print vars about state or repo if Official
+        if: ${{ matrix.src-included == 0 }}
+        shell: pwsh
+        run: |
+          git log --pretty=format:'%s by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local --abbrev-commit --max-count=1
+          cd '${{ env.IGNORED_PATH }}'
+
+          if ( '${{ env.CURRENT_VERSION }}' -ne '${{ env.RELEASE_VERSION }}' ) {
+            Write-Output '::warning title=Different version::Current version is ${{ env.CURRENT_VERSION }} but we trying to build ${{ env.RELEASE_VERSION }}'
+            git checkout tags/v${{ env.RELEASE_VERSION }} -b tmp-build
+
+            if ( $LASTEXITCODE -ne 0 ) {
+              Write-Error '::error title=Cannot checkout to this version::Error during execution checkout to this tag ${{ env.RELEASE_VERSION }}'
+              exit 1
+            }
+          } else {
+            $Output = (git log --pretty=format:'%s by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local --abbrev-commit --max-count=1)
+
+            if ( $LASTEXITCODE -ne 0 ) {
+              Write-Error '::error title=Invalid checkout::Invalid checkout'
+              exit 1
+            }
+            Write-Output ('::notice title=Git output::{0}' -f $Output)
+          }
+
+      #    - name: Restore FBT
+      #      id: cache-restore
+      #      if: ${{ success() }}
+      #      uses: actions/cache/restore@v3
+      #      with:
+      #        path: |
+      #          build/**
+      #          debug/**
+      #        # An explicit key for restoring and saving the cache
+      #        key: 'fbt=${{ env.FIRMWARE_VERSION }}'
+      #
+      - name: Build Firmware
+        shell: bash
+        if: ${{ success() }}
+        env:
+          FBT_NO_SYNC: 0
+          DIST_SUFFIX: ${{ matrix.version }}
+          WORKFLOW_BRANCH_OR_TAG: release-cfw
+        run: |
+          ./fbt COMPACT=1 DEBUG=0 fap_dist
+
+      #    - name: Save FBT
+      #      id: cache-save
+      #      if: ${{ success() }}
+      #      uses: actions/cache/save@v3
+      #      with:
+      #        path: |
+      #          build/**
+      #          debug/**
+      #        # An explicit key for restoring and saving the cache
+      #        key: ${{ steps.cache-restore.outputs.cache-primary-key }}
+
+      - name: Create assets
+        if: ${{ success() }}
+        shell: pwsh
+        env:
+          ZIP_NAME: "SubGHz_Bruteforcer_${{ env.RELEASE_VERSION }}_${{ matrix.firmware }}.zip"
+          TGZ_NAME: "SubGHz_Bruteforcer_${{ env.RELEASE_VERSION }}_${{ matrix.firmware }}.tgz"
+        run: |
+          function Format-Bytes {
+            param(
+                  [int]$number
+              )
+              $sizes = 'KB', 'MB', 'GB', 'TB', 'PB'
+              for ($x = 0; $x -lt $sizes.count; $x++) {
+                  if ($number -lt [int64]"1$($sizes[$x])") {
+                      if ($x -eq 0) {
+                          return "$number B"
+                      }
+                      else {
+                          $num = $number / [int64]"1$($sizes[$x-1])"
+                          $num = "{0:N2}" -f $num
+                          return "$num $($sizes[$x-1])"
+                      }
+                  }
+              }
+          }
+          $ZipName = $env:ZIP_NAME
+          $TgzName = $env:TGZ_NAME
+          $FapNamme = 'SubGHz_Bruteforcer.fap'
+          $DstFap = "./$FapNamme"
+
+          if (!(Test-Path -Path "dist/f7-C/apps/Sub-GHz/$FapNamme" -PathType Leaf)) {
+              Write-Error '::error title=Files not found::Cannot find files in location'
+              exit 1
+          }
+
+          $Size = (Get-Item -Path "dist/f7-C/apps/Sub-GHz/$FapNamme" | Get-ItemPropertyValue -Name Length)
+          Write-Output ('Filesize: {0}' -f (Format-Bytes $Size))
+          Copy-Item -Force -Path "dist/f7-C/apps/Sub-GHz/$FapNamme" -Destination $DstFap
+
+          zip -r -qq $ZipName $DstFap
+          tar zcf $TgzName  $DstFap
+
+          if ( !(Test-Path -Path $ZipName -PathType Leaf) -or !(Test-Path -Path $TgzName -PathType Leaf) ) {
+              Write-Error '::error title=Files not found::Cannot find files in location'
+              exit 1
+          }
+
+          $ZipSize = Format-Bytes (Get-Item -Path $ZipName).Length
+          $TgzSize = Format-Bytes (Get-Item -Path $TgzName ).Length
+
+          Write-Output ('ZIP_NAME={0}' -f $ZipName) >> $env:GITHUB_ENV
+          Write-Output ('TGZ_NAME={0}' -f $TgzName ) >> $env:GITHUB_ENV
+          Write-Output ('ZIP_TAG={0} ({1})' -f $ZipName, $ZipSize) >> $env:GITHUB_ENV
+          Write-Output ('TGZ_TAG={0} ({1})' -f $TgzName , $TgzSize) >> $env:GITHUB_ENV
+      - name: Create assets
+        if: ${{ success() && env.ZIP_NAME != '' }}
+        env:
+          GITHUB_TOKEN: ${{ secrets.FLIPPER_TOKEN }}
+        run: |
+          gh release upload 'v${{ env.RELEASE_VERSION }}' --clobber \
+            '${{ env.ZIP_NAME }}#${{ env.ZIP_TAG }}' '${{ env.TGZ_NAME }}#${{ env.TGZ_TAG }}' -R ${{ env.REPO_SELF }}
+          gh release edit 'v${{ env.RELEASE_VERSION }}' --draft=false -R ${{ env.REPO_SELF }}
+
+#EOF

+ 169 - 0
.github/workflows/version-check.yml

@@ -0,0 +1,169 @@
+name: "Version check for NEW release"
+run-name: " Version check for NEW release ${{ inputs.DEPLOY_TARGET }} by @${{ github.ACTOR }}"
+
+on:
+  workflow_dispatch:
+  push:
+    branches:
+      - master
+  schedule:
+    - cron: "*/30 * * * *"
+
+permissions:
+  contents: write
+
+jobs:
+  pull-request:
+    concurrency:
+      group: check-for-new-versions
+      cancel-in-progress: false
+    runs-on: ubuntu-latest
+    env:
+      REPO_UNLEASHED: ${{ vars.REPO_UNLEASHED }}
+      RELEASE_VERSION: ${{ vars.RELEASE_VERSION }}
+      FIRMWARE_VERSION: ${{ vars.FIRMWARE_VERSION }}
+      REPO_SELF: ${{ vars.REPO_SELF }}
+      CHECKOUT_DIR: "firmware"
+    steps:
+      - name: Copy Repo Files
+        uses: actions/checkout@v3
+        with:
+          repository: "${{ env.REPO_SELF }}"
+          path: "${{ env.CHECKOUT_DIR }}"
+          clean: "true"
+          submodules: "true"
+          token: ${{ secrets.FLIPPER_TOKEN }}
+      - name: Check firmware release
+        shell: pwsh
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        run: |
+          function CleanInput
+          {
+              param(
+                  [string]
+                  $DurtyString
+              )
+              return $DurtyString -replace ('[^a-zA-Z\d_\-\,\.\t\n\r\:\;]', '')
+          }
+
+          $Release = @(`
+                      (CleanInput `
+                            (gh release list -L 1 --repo '${{ env.REPO_UNLEASHED }}')`
+                      ) -split "`t")
+
+          $FirmwareVersionNumber = 0
+          $StoredFirmwareVersionNumber = 0
+          if ($Release[2] -match '\-(\d+)$')
+          {
+              $FirmwareVersionNumber = [int]($Matches[1])
+          }
+          else
+          {
+              Write-Error ('::error title=Invalid firmware number::Error during execution this tags {0}' -f $FirmwareVersionNumber)
+              exit 1
+          }
+          if ('${{ env.FIRMWARE_VERSION }}' -match '\-(\d+)$')
+          {
+              $StoredFirmwareVersionNumber = [int]($Matches[1])
+          }
+          else
+          {
+              Write-Error ('::error title=Invalid STORED firmware number::Error during execution this version {0}' -f '${{ env.FIRMWARE_VERSION }}')
+              exit 1
+          }
+
+          $LatestFirmware = CleanInput ((CleanInput (gh release list -L 1 --repo '${{ env.REPO_SELF }}') -replace '\t', ';') | `
+              ConvertFrom-Csv -Delimiter ';' -Header name, flag, tag).tag
+
+          $Delta = ( [DateTime]::Now - [DateTime]::Parse($Release[3]) )
+          $NewVersionFw = $false
+          Write-Host ('Latest firmware {0}' -f $LatestFirmware) -ForegroundColor Gray -BackgroundColor Magenta
+          Write-Debug ('::debug LatestFirmware {0}' -f $LatestFirmware)
+
+          Write-Output ('REMOTE_TAG_INFO=[{0}]({1}/releases/tag/{2})' -f $LatestFirmware, '${{ env.REPO_UNLEASHED }}', $LatestFirmware) >> $env:GITHUB_ENV
+          if (($FirmwareVersionNumber -gt $StoredFirmwareVersionNumber) -and ( $Delta -gt [TimeSpan]::FromMinutes(10)))
+          {
+              Write-Debug ('::debug LatestFirmware {0}' -f $LatestFirmware)
+              Write-Output ('FIRMWARE_VERSION={0}' -f $LatestFirmware) >> $env:GITHUB_ENV
+              $NewVersionFw = $true
+          }
+          elseif ($FirmwareVersionNumber -lt $StoredFirmwareVersionNumber)
+          {
+              Write-Error ('::error title=Invalid check of stored::Version in repo: {0}, but we think it is {1}' -f  $FirmwareVersionNumber, $StoredFirmwareVersionNumber)
+              exit 1
+          }
+
+          $LastPublished = (gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" '/repos/${{ vars.REPO_SELF }}/releases?per_page=1' | ConvertFrom-Json).published_at
+          $Delta = ([DateTime]::Now - $LastPublished)
+
+          $Release = (gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" '/repos/${{ vars.REPO_SELF }}/tags?per_page=1' | ConvertFrom-Json).name
+          Write-Host ('Release {0}' -f $Release) -ForegroundColor Gray -BackgroundColor Magenta
+          $LatestTag = $Release.Substring(1)
+
+          $CurrentVersion = [version]::Parse('${{ env.RELEASE_VERSION }}')
+          $ParsedRepoVersion = [version]::Parse($LatestTag)
+          Write-Host ('Current tag:Repos tag {0}, {1}' -f $CurrentVersion, $ParsedRepoVersion) -ForegroundColor Gray -BackgroundColor Magenta
+          Write-Debug ('::debug Current tag:Repos tag {0}, {1}' -f $CurrentVersion, $ParsedRepoVersion)
+          if (($CurrentVersion -lt $ParsedRepoVersion) -and ( $Delta -gt [TimeSpan]::FromMinutes(10)))
+          {
+              $Tag = ('{0}.{1}.{2}' -f $ParsedRepoVersion.Major, $ParsedRepoVersion.Minor, $ParsedRepoVersion.Build)
+
+              Write-Output ('RELEASE_VERSION={0}' -f $Tag) >> $env:GITHUB_ENV
+              Write-Output ('RELEASE_TYPE=2' -f $Tag) >> $env:GITHUB_ENV
+
+              Write-Output ('::warning title=New release!::Release {0}' -f $Tag)
+          }
+          elseif ( $NewVersionFw )
+          {
+              $Tag = ('{0}.{1}.{2}' -f $CurrentVersion.Major, $CurrentVersion.Minor, ($CurrentVersion.Build + 1))
+
+              Write-Output ('RELEASE_VERSION={0}' -f $Tag) >> $env:GITHUB_ENV
+              Write-Output ('RELEASE_TYPE=1' -f $Tag) >> $env:GITHUB_ENV
+
+              Write-Output ('::warning title=Firmware was changed!::New version is {0}, creating release {1}' -f $LatestFirmware, $Tag)
+          }
+          elseif ( ($Delta -gt [TimeSpan]::FromMinutes(10)) -and ($CurrentVersion -gt $ParsedRepoVersion)) 
+          {
+              Write-Output ('::warning title=Invalid version!::Version in settings: {0}, but repo version is {1}. Going to change variable' -f $CurrentVersion, $ParsedRepoVersion)
+              Write-Output ('RELEASE_VERSION={0}' -f $ParsedRepoVersion) >> $env:GITHUB_ENV
+              Write-Output ('RELEASE_TYPE=3' -f $Tag) >> $env:GITHUB_ENV
+          }
+          else
+          {
+              # none to release
+              Write-Host 'No new versions, sorry'
+          }
+          Write-Output ('CURRENT_TAG={0}' -f $LatestTag) >> $env:GITHUB_ENV
+
+      - name: Update Firmware variable and create UPDATE release if necessary
+        if: ${{ success() && env.RELEASE_TYPE == 1 }}
+        env:
+          GITHUB_TOKEN: ${{ secrets.FLIPPER_TOKEN }}
+          OWNER: ${{ github.repository_owner }}
+        run: |
+          gh release create 'v${{ env.RELEASE_VERSION }}' --latest --draft \
+            --notes 'Rebuild with new version of firmware.\n\nSee: [CHANGELOG](${{ env.FIRMWARE_VERSION }}/blob/dev/CHANGELOG.md)\n${{ env.REMOTE_TAG_INFO}}' \
+            --title 'Minor update v${{ env.RELEASE_VERSION }}' --verify-tag -R '${{ env.REPO_SELF }}'
+          gh variable set FIRMWARE_VERSION -b '${{ env.FIRMWARE_VERSION }}' -R '${{ env.REPO_SELF }}'
+          gh variable set RELEASE_VERSION -b '${{ env.RELEASE_VERSION }}' -R '${{ env.REPO_SELF }}'
+      - name: Update release variable and create NEW release if necessary
+        if: ${{ success() && env.RELEASE_TYPE == 2 }}
+        env:
+          GITHUB_TOKEN: ${{ secrets.FLIPPER_TOKEN }}
+          OWNER: ${{ github.repository_owner }}
+        run: |
+          gh release create 'v${{ env.RELEASE_VERSION }}' --notes-start-tag 'v${{ env.CURRENT_TAG }}' --generate-notes --draft --latest \
+            --notes 'New version is rolling out!' --verify-tag --title 'Release v${{ env.RELEASE_VERSION }}'  -R '${{ env.REPO_SELF }}'
+
+          gh variable set FIRMWARE_VERSION -b '${{ env.FIRMWARE_VERSION }}' -R '${{ env.REPO_SELF }}'
+          gh variable set RELEASE_VERSION -b '${{ env.RELEASE_VERSION }}' -R '${{ env.REPO_SELF }}'
+      - name: Current settings in repo invalid. Changing
+        if: ${{ success() && env.RELEASE_TYPE > 2 }}
+        env:
+          GITHUB_TOKEN: ${{ secrets.FLIPPER_TOKEN }}
+          OWNER: ${{ github.repository_owner }}
+        run: |
+          gh variable set RELEASE_VERSION -b ${{ env.RELEASE_VERSION }} -R ${{ env.REPO_SELF }}
+
+# EOF

+ 13 - 10
README.md

@@ -30,8 +30,11 @@ We do not condone illegal activity and strongly encourage keeping transmissions
 
 #### Holtek
 
-- Holtek HT12X 12bit 433.920MHz
-
+- Holtek HT12X 12bit FM 433.920MHz (TE: 204us)
+- Holtek HT12X 12bit AM 433.920MHz (TE: 433us)
+- Holtek HT12X 12bit AM 315MHz (TE: 433us)
+- Holtek HT12X 12bit AM 868MHz (TE: 433us)
+- Holtek HT12X 12bit AM 915MHz (TE: 433us)
 #### Chamberlain
 
 - Chamberlain 9bit 300MHz
@@ -53,20 +56,20 @@ We do not condone illegal activity and strongly encourage keeping transmissions
 
 #### UNILARM
 
-- UNILARM 25bit 330MHz
-- UNILARM 25bit 433MHz
+- UNILARM 25bit 330MHz (TE: 209us) (only dip switch combinations, not full 25bit bruteforce)
+- UNILARM 25bit 433MHz (TE: 209us) (only dip switch combinations, not full 25bit bruteforce)
 
 #### SMC5326
 
-- SMC5326 25bit 330MHz
-- SMC5326 25bit 433MHz
+- SMC5326 25bit 330MHz (TE: 320us) (only dip switch combinations, not full 25bit bruteforce)
+- SMC5326 25bit 433MHz (TE: 320us) (only dip switch combinations, not full 25bit bruteforce)
 
 #### PT2260
 
-- PT2260 24bit 315MHz
-- PT2260 24bit 330MHz
-- PT2260 24bit 390MHz
-- PT2260 24bit 433MHz
+- PT2260 24bit 315MHz (TE: 286us) (only for 8 dip switch remote, not full 24bit bruteforce)
+- PT2260 24bit 330MHz (TE: 286us) (only for 8 dip switch remote, not full 24bit bruteforce)
+- PT2260 24bit 390MHz (TE: 286us) (only for 8 dip switch remote, not full 24bit bruteforce)
+- PT2260 24bit 433MHz (TE: 286us) (only for 8 dip switch remote, not full 24bit bruteforce)
 
 #### Additional
 

+ 1 - 2
application.fam

@@ -3,11 +3,10 @@ App(
     name="Sub-GHz Bruteforcer",
     apptype=FlipperAppType.EXTERNAL,
     entry_point="subbrute_app",
-    cdefines=["APP_SUB_BRUTE"],
     requires=["gui","dialogs"],
     stack_size=2 * 1024,
     order=11,
     fap_icon="images/subbrute_10px.png",
-    fap_category="Tools",
+    fap_category="Sub-GHz",
     fap_icon_assets="images",
 )

+ 12 - 0
subbrute.c

@@ -178,10 +178,22 @@ int32_t subbrute_app(void* p) {
         instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen);
     scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
 
+    // Enable power for External CC1101 if it is connected
+    furi_hal_subghz_enable_ext_power();
+    // Auto switch to internal radio if external radio is not available
+    furi_delay_ms(15);
+    if(!furi_hal_subghz_check_radio()) {
+        furi_hal_subghz_set_radio_type(SubGhzRadioInternal);
+    }
+
     furi_hal_power_suppress_charge_enter();
+
     notification_message(instance->notifications, &sequence_display_backlight_on);
     view_dispatcher_run(instance->view_dispatcher);
     furi_hal_power_suppress_charge_exit();
+    // Disable power for External CC1101 if it was enabled and module is connected
+    furi_hal_subghz_disable_ext_power();
+
     subbrute_free(instance);
 
     return 0;

+ 1 - 1
subbrute_i.h

@@ -29,7 +29,7 @@
 #include "views/subbrute_attack_view.h"
 #include "views/subbrute_main_view.h"
 
-#define SUBBRUTEFORCER_VER "Sub-GHz BruteForcer 3.4"
+#define SUBBRUTEFORCER_VER "Sub-GHz BruteForcer 3.5"
 
 #ifdef FURI_DEBUG
 //#define SUBBRUTE_FAST_TRACK false

+ 62 - 10
subbrute_protocols.c

@@ -264,7 +264,7 @@ const SubBruteProtocol subbrute_protocol_unilarm_24bit_330 = {
     .frequency = 330000000,
     .bits = 25,
     .te = 209,
-    .repeat = 5,
+    .repeat = 4,
     .preset = FuriHalSubGhzPresetOok650Async,
     .file = UNILARMFileProtocol};
 
@@ -275,7 +275,7 @@ const SubBruteProtocol subbrute_protocol_unilarm_24bit_433 = {
     .frequency = 433920000,
     .bits = 25,
     .te = 209,
-    .repeat = 5,
+    .repeat = 4,
     .preset = FuriHalSubGhzPresetOok650Async,
     .file = UNILARMFileProtocol};
 
@@ -286,7 +286,7 @@ const SubBruteProtocol subbrute_protocol_smc5326_24bit_330 = {
     .frequency = 330000000,
     .bits = 25,
     .te = 320,
-    .repeat = 5,
+    .repeat = 4,
     .preset = FuriHalSubGhzPresetOok650Async,
     .file = SMC5326FileProtocol};
 
@@ -297,7 +297,7 @@ const SubBruteProtocol subbrute_protocol_smc5326_24bit_433 = {
     .frequency = 433920000,
     .bits = 25,
     .te = 320,
-    .repeat = 5,
+    .repeat = 4,
     .preset = FuriHalSubGhzPresetOok650Async,
     .file = SMC5326FileProtocol};
 
@@ -308,7 +308,7 @@ const SubBruteProtocol subbrute_protocol_pt2260_24bit_315 = {
     .frequency = 315000000,
     .bits = 24,
     .te = 286,
-    .repeat = 5,
+    .repeat = 4,
     .preset = FuriHalSubGhzPresetOok650Async,
     .file = PT2260FileProtocol};
 
@@ -319,7 +319,7 @@ const SubBruteProtocol subbrute_protocol_pt2260_24bit_330 = {
     .frequency = 330000000,
     .bits = 24,
     .te = 286,
-    .repeat = 5,
+    .repeat = 4,
     .preset = FuriHalSubGhzPresetOok650Async,
     .file = PT2260FileProtocol};
 
@@ -330,7 +330,7 @@ const SubBruteProtocol subbrute_protocol_pt2260_24bit_390 = {
     .frequency = 390000000,
     .bits = 24,
     .te = 286,
-    .repeat = 5,
+    .repeat = 4,
     .preset = FuriHalSubGhzPresetOok650Async,
     .file = PT2260FileProtocol};
 
@@ -341,7 +341,7 @@ const SubBruteProtocol subbrute_protocol_pt2260_24bit_433 = {
     .frequency = 433920000,
     .bits = 24,
     .te = 286,
-    .repeat = 5,
+    .repeat = 4,
     .preset = FuriHalSubGhzPresetOok650Async,
     .file = PT2260FileProtocol};
 
@@ -356,6 +356,50 @@ const SubBruteProtocol subbrute_protocol_holtek_12bit_433 = {
     .preset = FuriHalSubGhzPreset2FSKDev476Async,
     .file = HoltekFileProtocol};
 
+/**
+ * Holtek AM 12bit 433MHz
+ */
+const SubBruteProtocol subbrute_protocol_holtek_12bit_am_433 = {
+    .frequency = 433920000,
+    .bits = 12,
+    .te = 433,
+    .repeat = 3,
+    .preset = FuriHalSubGhzPresetOok650Async,
+    .file = HoltekFileProtocol};
+
+/**
+ * Holtek AM 12bit 315MHz
+ */
+const SubBruteProtocol subbrute_protocol_holtek_12bit_am_315 = {
+    .frequency = 315000000,
+    .bits = 12,
+    .te = 433,
+    .repeat = 3,
+    .preset = FuriHalSubGhzPresetOok650Async,
+    .file = HoltekFileProtocol};
+
+/**
+ * Holtek AM 12bit 868MHz
+ */
+const SubBruteProtocol subbrute_protocol_holtek_12bit_am_868 = {
+    .frequency = 868350000,
+    .bits = 12,
+    .te = 433,
+    .repeat = 3,
+    .preset = FuriHalSubGhzPresetOok650Async,
+    .file = HoltekFileProtocol};
+
+/**
+ * Holtek AM 12bit 915MHz
+ */
+const SubBruteProtocol subbrute_protocol_holtek_12bit_am_915 = {
+    .frequency = 915000000,
+    .bits = 12,
+    .te = 433,
+    .repeat = 3,
+    .preset = FuriHalSubGhzPresetOok650Async,
+    .file = HoltekFileProtocol};
+
 /**
  * BF existing dump
  */
@@ -373,7 +417,11 @@ static const char* subbrute_protocol_names[] = {
     [SubBruteAttackAnsonic12bit433075] = "Ansonic 12bit 433.07MHz",
     [SubBruteAttackAnsonic12bit433] = "Ansonic 12bit 433.92MHz",
     [SubBruteAttackAnsonic12bit434] = "Ansonic 12bit 434.07MHz",
-    [SubBruteAttackHoltek12bit433] = "Holtek FM 12bit 433MHz",
+    [SubBruteAttackHoltek12bitFM433] = "Holtek FM 12bit 433MHz",
+    [SubBruteAttackHoltek12bitAM433] = "Holtek AM 12bit 433MHz",
+    [SubBruteAttackHoltek12bitAM315] = "Holtek AM 12bit 315MHz",
+    [SubBruteAttackHoltek12bitAM868] = "Holtek AM 12bit 868MHz",
+    [SubBruteAttackHoltek12bitAM915] = "Holtek AM 12bit 915MHz",
     [SubBruteAttackChamberlain9bit300] = "Chamberlain 9bit 300MHz",
     [SubBruteAttackChamberlain9bit315] = "Chamberlain 9bit 315MHz",
     [SubBruteAttackChamberlain9bit390] = "Chamberlain 9bit 390MHz",
@@ -420,7 +468,11 @@ const SubBruteProtocol* subbrute_protocol_registry[] = {
     [SubBruteAttackAnsonic12bit433075] = &subbrute_protocol_ansonic_12bit_433075,
     [SubBruteAttackAnsonic12bit433] = &subbrute_protocol_ansonic_12bit_433,
     [SubBruteAttackAnsonic12bit434] = &subbrute_protocol_ansonic_12bit_434,
-    [SubBruteAttackHoltek12bit433] = &subbrute_protocol_holtek_12bit_433,
+    [SubBruteAttackHoltek12bitFM433] = &subbrute_protocol_holtek_12bit_433,
+    [SubBruteAttackHoltek12bitAM433] = &subbrute_protocol_holtek_12bit_am_433,
+    [SubBruteAttackHoltek12bitAM315] = &subbrute_protocol_holtek_12bit_am_315,
+    [SubBruteAttackHoltek12bitAM868] = &subbrute_protocol_holtek_12bit_am_868,
+    [SubBruteAttackHoltek12bitAM915] = &subbrute_protocol_holtek_12bit_am_915,
     [SubBruteAttackChamberlain9bit300] = &subbrute_protocol_chamberlain_9bit_300,
     [SubBruteAttackChamberlain9bit315] = &subbrute_protocol_chamberlain_9bit_315,
     [SubBruteAttackChamberlain9bit390] = &subbrute_protocol_chamberlain_9bit_390,

+ 5 - 1
subbrute_protocols.h

@@ -40,7 +40,11 @@ typedef enum {
     SubBruteAttackAnsonic12bit433075,
     SubBruteAttackAnsonic12bit433,
     SubBruteAttackAnsonic12bit434,
-    SubBruteAttackHoltek12bit433,
+    SubBruteAttackHoltek12bitFM433,
+    SubBruteAttackHoltek12bitAM433,
+    SubBruteAttackHoltek12bitAM315,
+    SubBruteAttackHoltek12bitAM868,
+    SubBruteAttackHoltek12bitAM915,
     SubBruteAttackChamberlain9bit300,
     SubBruteAttackChamberlain9bit315,
     SubBruteAttackChamberlain9bit390,