-
Notifications
You must be signed in to change notification settings - Fork 0
RE SD Card
Where this fits: the FAT32 layout the BCDx36HP family writes to the microSD, and how its file shapes are the actual API our app (and Sentinel) uses for persistent edits. For the consolidated narrative start at Reverse Engineering.
The SDS100, BT885, BCD436HP, BCD536HP, SDS200, and SDS150 all write the same on-disk layout. We've imaged BT885 and SDS100 cards directly; the deltas are documented inline.
| Property | BT885 | SDS100 | Notes |
|---|---|---|---|
| Filesystem | FAT32 | FAT32 | Always |
| Total size | 3.6 GiB | 7.5 GiB | Card-dependent |
| Volume label | (none) | (none) | Both |
| Sector size | 512 B | 512 B | Standard |
The volume's content fingerprint is not a model differentiator
in our app's sdcard.py:_content_fingerprint because BT885 and
SDS100 ship bit-identical CityTable*.dat and ZipTable*.dat
files (same SHA-256). Use volume serial + scanner.inf for
identity instead. See AI/Dev/RE/docs/SD_CARD_COMPARISON.md.
Both BT885 and SDS100 have the identical folder skeleton. The SDS100 just populates more of it.
<DRIVE>:\
└── BCDx36HP\ <-- canonical scanner-data root
├── activity_log\ (empty on stock card)
├── alert\ (empty on stock card)
├── audio\
│ ├── inner_rec\ (empty on stock; populated when scanner records)
│ └── user_rec\ (empty on stock; populated by user record button)
├── discovery\
│ ├── Conventional\ (empty until Discovery sessions run)
│ └── Trunk\ (empty until Discovery sessions run)
├── favorites_lists\
│ ├── f_list.cfg SDS100 populated; BT885 empty 42-B stub
│ └── f_NNNNNN.hpd SDS100 only (per-favorite payload)
├── firmware\
│ ├── CityTable_V1_00_00.dat 566,492 B (bit-identical BT885 = SDS100)
│ └── ZipTable_V1_00_00.dat 693,758 B (bit-identical BT885 = SDS100)
├── HPDB\
│ ├── hpdb.cfg state/county/agency master index
│ └── s_NNNNNN.hpd per-state HPD payloads
├── scanner.inf identity / firmware versions
├── profile.cfg SDS100 only (giant settings file)
├── app_data.cfg SDS100 only (last-active state)
└── discvery.cfg SDS100 only (discovery stub - sic, typo in firmware)
The folder name
BCDx36HPis the firmware family, not the scanner model. Treat it as fixed; never localise it. Likewisediscvery.cfgis missing ano- this is a Uniden typo and we must preserve it verbatim.
3 records, tab-separated. Sample lines from each scanner:
# BT885
TargetModel BCDx36HP
FormatVersion 1.00
Scanner BT885-SCN <SERIAL> 1.01.02 01 1.00.00 1.00.00 0
# SDS100
TargetModel BCDx36HP
FormatVersion 1.00
Scanner SDS100 <SERIAL> 1.23.07 01 1.00.00 1.00.00 0 1.03.05
The Scanner line is the canonical model fingerprint. Field 1
is the literal model string (BT885-SCN vs SDS100); field 9
is only present on SDS100 and carries the SUB MCU firmware
version (BT885 has no SUB MCU).
| Idx | BT885 | SDS100 | Likely meaning |
|---|---|---|---|
| 1 | BT885-SCN |
SDS100 |
Model fingerprint |
| 2 | 41626-... |
38326-... |
Serial / part number |
| 3 | 1.01.02 |
1.23.07 |
MAIN firmware version |
| 4 | 01 |
01 |
Hardware revision |
| 5 | (blank) | (blank) | Reserved |
| 6 | 1.00.00 |
1.00.00 |
DSP firmware? |
| 7 | 1.00.00 |
1.00.00 |
DSP firmware? |
| 8 | 0 |
0 |
Reserved flag |
| 9 | (absent) | 1.03.15 |
SUB firmware (SDS100-only) |
Codebase note:
Bt885Profile.target_model_aliases = ("Beartracker885", "BearTracker885", "BT885")is stale. Real BT885 firmware writesTargetModel\tBCDx36HP. Detect onscanner.inffield 1, notTargetModel.
The same shape on both cards; sizes differ:
- BT885: 178 KB - state-only index. The BT885 is happy with just-the-states.
- SDS100: 1.6 MB - state + county + agency index. The SDS100 needs the deeper hierarchy for its bigger UI.
Sample lines:
TargetModel BCDx36HP
FormatVersion 1.00
DateModified 04/07/2024 17:00:01
StateInfo StateId=0 CountryId=0 _MultipleStates
StateInfo StateId=1 CountryId=1 Alabama AL
...
Round-trip rule: preserve every record verbatim, including trailing tabs.
Tab-separated record-oriented format. The same record types appear on both BT885 and SDS100 - the SDS100 record set is a strict superset. Every record type the BT885 writes is also written by the SDS100, just with extra trailing fields.
| Record | Purpose | BT885 fields | SDS100 fields |
|---|---|---|---|
Conventional |
Conventional system | 7 | 14 |
Trunk |
Trunked system | varies | varies |
Site |
Trunked site | ~10 | 13 |
T-Group |
Talkgroup category | varies | varies |
T-Freq |
Trunked control/voice | varies | varies |
TGID |
Talkgroup ID | varies | varies |
C-Group |
Conventional group | 8 | 10 |
C-Freq |
Conventional frequency | 7 | 17 |
AreaState |
State binding | 2 | 2 |
AreaCounty |
County binding | 2 | 2 |
BandPlan_Mot |
Motorola band plan | not used | observed |
FleetMap |
Motorola fleet map | not observed | observed |
DateModified |
Header | yes | no (BT885-only) |
The trailing tab fields on SDS100 are real and round-trip-significant
- preserve them. Our parser does. The empty trailing slots are "feature slots" (lockout count, recording hold, per-channel volume, etc.) that the firmware allocates but the user doesn't always populate.
BT885 has the empty 42-byte stub f_list.cfg; that's the only
indication on disk that the family format includes favourites.
The BT885 firmware lacks the UI to populate it. SDS100 fills it
in:
One F-List row per favourite list. 116 columns:
- Idx 1: display name
- Idx 2: per-list payload filename (
f_NNNNNN.hpd) - Idx 3-118: 116 enable/disable slots (Quick Key + per-favorite-bit mask; exact slot semantics TBD)
Sample:
F-List Alachua f_000001.hpd Off Off ... (116 columns)
F-List Home f_000002.hpd Off On ...
Same record alphabet as s_*.hpd (Trunk / Site / T-Freq / T-Group
/ TGID / Conventional / C-Group / C-Freq) plus:
-
DQKs_Statusat the top of each system: 100-slot Department Quick Key on/off mask. - Site rows have 13 fields (vs ~10 on BT885 state HPDs).
- No
Idfields on records (favourites are name-keyed, not ID-keyed).
This is one of the things our app already reads/writes for the SDS100 even though Sentinel is doing the same job - we have the parser, we have the schema.
15.6 KB, 184 lines. Every SDS100-specific feature lives here. Header lines:
TargetModel BCDx36HP
FormatVersion 1.00
ProductName SDS100
GlobalSetting Off Off Off Off Off 2 100 Custom1 Custom2 Custom3 Off Auto 0 2 Off Off Ignore Normal 0
Major record types (~30):
| Record | Slots | Purpose |
|---|---|---|
ProductName |
- | Model name |
GlobalSetting |
20 | Global toggles (key beep, opening msg, charge time, contrast, attenuator) |
SearchCommon |
12 | Search-mode global params |
PresetBroadcastScreen |
5 | Pre-defined skip bands (FM, weather, ...) |
CustomBroadcastScreen |
30 | 10 user-defined skip-bands |
CurrentLocation |
3 | Last GPS fix (lat, lon, accuracy radius) |
GpsOption |
2 | GPS coordinate display + serial baud |
ServiceType |
36 | 36-slot service-type mask (vs BT885's 14) |
CustomServiceType |
10 | 10 user-defined service-type slots |
Weather / WxSameList
|
several | Weather priority + SAME alerts |
DisplayOption, DispOptItems, DispColors
|
many | Layout/colour customization |
Backlight, Battery, OwnerInfo, ClockOption
|
- | Hardware settings |
RecordingOption, StandbyOption
|
several | Recording + standby |
LimitSearch |
10 rows × ~16 | User-defined limit-search ranges |
CloseCall |
~16 | Close Call (RF nearest-frequency capture) |
ToneOut |
32 rows | Paging tone-out slots |
Waterfall, CustomWfBand × 10 |
many | SDS100 waterfall display (not on BT885) |
WfColors |
6 | Waterfall colour palette (hex) |
IfxFreqs |
- | Intermod frequencies |
BandDefault |
31 | Per-band default mod + step |
QuickKeys |
100 | Quick-key enable mask (not on BT885) |
Round-trip rule: capture every record verbatim. Don't rebuild from a minimal field set or the firmware silently reverts to defaults. Our parser already does this via opaque preservation of unrecognised records.
386-486 bytes. Sample:
TargetModel BCDx36HP
FormatVersion 1.00
ModeInfo IDscan
ScanListType FavoritesList Home
ScanTrunkSystem Off Trunk ... (per-trunk state)
ScanT-Group Off T-Group ... (per-group state)
ScanSite Off Site ... (per-site state)
ScanT-Freq T-Freq ... (per-freq state)
Treat as ephemeral. Don't merge or version. On a push, copy verbatim.
42 bytes; just the standard header. Discovery records will be appended after a Discovery session - we have not yet RE'd the populated state.
firmware/
├── CityTable_V1_00_00.dat 566,492 B (bit-identical BT885 = SDS100)
└── ZipTable_V1_00_00.dat 693,758 B (bit-identical BT885 = SDS100)
Already RE'd in our scanner_manager.py:FirmwareCityTable and
FirmwareZipTable parsers. 47,204 city records and 41,771 ZIPs
respectively. Same SHA-256 across the family.
Never delete or modify these files - the scanner refuses to boot without them. They're also where firmware updates are dropped (see RE-Firmware and RE-Sentinel).
| Need | File(s) | Already supported in our parser? |
|---|---|---|
| Identify which scanner is mounted |
BCDx36HP/scanner.inf field 1 |
Detection refactor pending; raw read works today |
| Read/write per-state channel data | BCDx36HP/HPDB/s_*.hpd |
Yes |
| Read/write favourites |
BCDx36HP/favorites_lists/f_*.hpd + f_list.cfg
|
Yes (round-trip preservation; UI for edit pending) |
| Read/write SDS100 settings | BCDx36HP/profile.cfg |
Round-trip yes; record-level UI for edit pending |
| Drop a firmware update |
BCDx36HP/firmware/*.bin (MAIN) or *.firm (SUB) |
Yes - just copy the file in; reboot the scanner |
| Backup everything | walk BCDx36HP/
|
Yes |
| Restore everything | walk BCDx36HP/ in reverse |
Yes |
This is the same set of operations Sentinel does (see RE-Sentinel). Our app does them with the additional benefit of the MetaStore audit trail, virtual SD workspaces, and RadioReference import - all features Sentinel doesn't have.
-
AI/Dev/RE/docs/SD_CARD_COMPARISON.md- exhaustive BT885 vs SDS100 diff with raw bytes. -
AI/Dev/RE/docs/BT885.md- per-scanner SD-card RE notes. -
AI/Dev/RE/docs/SDS100.md- same for SDS100. -
AI/Dev/RE/tools/sentinel/compare_cards.py- read-only side-by-side script.
Scanner Manager
Getting started
Features
- ZIP & GPS Simulation
- Coverage Tools
- RadioReference Import
- Workspaces & Sync
- Uniden Tools
- Channel List Management
- CityTable & Custom Locations
- Service Types
- Alerts
Reference
RE / Development