From d054fa1a9574257625134d9bba516fe572154cee Mon Sep 17 00:00:00 2001 From: unclehowell Date: Tue, 2 Dec 2025 17:05:40 -0300 Subject: [PATCH] Revert "[Auto-PR] Auto-commit: 2025-12-02 16:57:53 - Automated PR update." --- .gitignore | 1 - .pr_trigger | 2 +- CHANGELOG.md | 1 - pr_automation.sh | 10 +- static/ew/index.html | 696 ------------------ static/gui/404.html | 32 - static/gui/CHANGELOG.md | 1 - static/gui/GEMINI.md | 35 - static/gui/app-error.html | 123 ---- static/gui/app-store/000-new.html | 22 +- static/gui/app-store/000.html | 21 +- static/gui/app-store/0000.html | 91 +-- static/gui/app-store/002.html | 70 +- static/gui/app-store/002b.html | 22 +- static/gui/app-store/003.html | 67 +- static/gui/app-store/004.html | 72 +- static/gui/app-store/005.html | 82 +-- static/gui/app-store/006.html | 82 +-- static/gui/app-store/00x.html | 71 +- .../app-store/app-description-002-001.html | 184 ----- .../app-store/app-description-002-002.html | 184 ----- .../app-store/app-description-003-001.html | 184 ----- .../app-store/app-description-004-001.html | 184 ----- .../app-store/app-description-004-002.html | 184 ----- .../app-store/app-description-004-003.html | 176 ----- .../app-store/app-description-004-004.html | 176 ----- .../app-store/app-description-005-001.html | 176 ----- .../app-store/app-description-005-002.html | 176 ----- .../app-store/app-description-006-001.html | 176 ----- .../app-store/app-description-006-002.html | 176 ----- .../app-store/app-description-TEMPLATE.html | 156 ---- static/gui/app-store/apps/002-001/fetch.html | 28 +- static/gui/app-store/apps/002-002/fetch.html | 44 +- static/gui/app-store/apps/003-001/fetch.html | 83 ++- static/gui/app-store/apps/004-001/fetch.html | 29 +- static/gui/app-store/apps/004-002/fetch.html | 54 +- static/gui/app-store/apps/004-003/fetch.html | 83 ++- static/gui/app-store/apps/004-004/fetch.html | 34 - static/gui/app-store/apps/005-001/fetch.html | 83 ++- static/gui/app-store/apps/005-002/fetch.html | 87 ++- static/gui/app-store/apps/006-001/fetch.html | 54 +- static/gui/app-store/apps/006-002/fetch.html | 44 +- static/gui/app-store/css/breadcrumb.css | 29 +- static/gui/app-store/doc-001.html | 113 +-- static/gui/app-store/doc-002.html | 30 +- static/gui/app-store/doc-003.html | 30 +- static/gui/app-store/js/dynamic-breadcrumb.js | 128 ---- static/gui/app-store/sitemap.json | 9 - static/gui/dashboard/000.html | 248 +++---- static/gui/dashboard/001-a.html | 5 +- static/gui/dashboard/js/appLauncher.js | 137 ---- static/gui/dashboard/media/css/appstore.css | 345 +-------- static/gui/dashboard/media/css/breadcrumb.css | 35 +- static/gui/sw.js | 17 - static/puck | 2 +- 55 files changed, 807 insertions(+), 4577 deletions(-) delete mode 100644 static/ew/index.html delete mode 100644 static/gui/404.html delete mode 100644 static/gui/GEMINI.md delete mode 100644 static/gui/app-error.html delete mode 100644 static/gui/app-store/app-description-002-001.html delete mode 100644 static/gui/app-store/app-description-002-002.html delete mode 100644 static/gui/app-store/app-description-003-001.html delete mode 100644 static/gui/app-store/app-description-004-001.html delete mode 100644 static/gui/app-store/app-description-004-002.html delete mode 100644 static/gui/app-store/app-description-004-003.html delete mode 100644 static/gui/app-store/app-description-004-004.html delete mode 100644 static/gui/app-store/app-description-005-001.html delete mode 100644 static/gui/app-store/app-description-005-002.html delete mode 100644 static/gui/app-store/app-description-006-001.html delete mode 100644 static/gui/app-store/app-description-006-002.html delete mode 100644 static/gui/app-store/app-description-TEMPLATE.html delete mode 100644 static/gui/app-store/apps/004-004/fetch.html delete mode 100644 static/gui/app-store/js/dynamic-breadcrumb.js delete mode 100644 static/gui/app-store/sitemap.json delete mode 100644 static/gui/dashboard/js/appLauncher.js delete mode 100644 static/gui/sw.js diff --git a/.gitignore b/.gitignore index f03a2ccd3..380188e90 100755 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,3 @@ yarn-error.log* # Local Netlify folder .netlify /static/library/**/*.log -.aider* diff --git a/.pr_trigger b/.pr_trigger index 0bfe8c4a8..e65cf5217 100644 --- a/.pr_trigger +++ b/.pr_trigger @@ -1 +1 @@ -Last run: 2025-12-02 16:57:53 +Last run: 2025-11-28 18:53:03 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b40a7294..1a417fd41 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ## [0.0.1-rtw.17] - Q4/2025 -Dec-02 - Added static/ew Nov-13 - TEST 24/7 Nov-13 - Trying something/ Trying something else / Trying something else else Nov-12 - Added `cloudflare-conditional-deploy.yml` to new top level directory .github/workflow `so preview links can be generated on pull requests' diff --git a/pr_automation.sh b/pr_automation.sh index ca2ffdb67..816eec855 100755 --- a/pr_automation.sh +++ b/pr_automation.sh @@ -61,13 +61,10 @@ do esac done -# 4. Push the changes to the remote repository -echo "πŸš€ Pushing changes to remote branch 'origin/$BRANCH_TO_USE'..." -# The redirection to /dev/null has been removed to allow the SSH passphrase prompt to be visible. -if ! git push -u origin "$BRANCH_TO_USE"; then +# 4. Push the changes to the remote repository (Silent, but allows errors/passphrase prompt) +if ! git push -u origin "$BRANCH_TO_USE" > /dev/null 2>&1; then echo "----------------------------------------------" - echo "❌ **FATAL ERROR: Git push failed.**" - echo "Please ensure your SSH key is loaded (try 'ssh-add' if prompted for a passphrase)." + echo "❌ **FATAL ERROR: Git push failed.** Please fix your SSH/access rights (use ssh-add)." echo "----------------------------------------------" exit 1 fi @@ -98,4 +95,3 @@ else echo "❌ **Action Failed.** Could not determine or create the Pull Request URL." fi echo "----------------------------------------------" - diff --git a/static/ew/index.html b/static/ew/index.html deleted file mode 100644 index 3dc54f4b0..000000000 --- a/static/ew/index.html +++ /dev/null @@ -1,696 +0,0 @@ - - - - - - The WSPR C2 Mesh - Research Paper - - - -
-
-

The WSPR C2 Mesh:
A Civilian Discovery of a Global Baseband Exfiltration and Tracking Network

-
- - -
- πŸ“„ Download Current Version PDF -
- -
-
Version 0.1 (Original)
- - -
-
- Gareth [REDACTED]
- Classification: UNCLASSIFIED // FOR OFFICIAL USE ONLY
- Delivery: Hand-carried to NCSC Cheltenham / MI5 Thames House / NCA Cyber
- Date: 17 November 2025 -
- -
- Abstract: Between 14–17 November 2025, a civilian investigation uncovered a previously undocumented command-and-control (C2) infrastructure leveraging Weak Signal Propagation Reporter (WSPR) transmissions to covertly exfiltrate data and track commodity smartphones. The exploit uses rogue Mobile Device Management (MDM) provisioning to obtain privileged access to a phone's Qualcomm baseband, which is then temporarily reconfigured in RAM to transmit legitimate-looking WSPR beacons on HF and VHF amateur bands. Two independent victims across two countries have been confirmed. The exploit requires brief physical access, leaves minimal persistent artefacts, and is mitigated primarily via power-off and Faraday isolation. -
- -
- Keywords: WSPR, baseband exploit, MDM, C2 mesh, mobile device security, SDR, forensic analysis -
- -

1. Introduction

-

Between 14–17 November 2025, a British civilian independently discovered and documented an operational C2 mesh that converts ordinary iPhones into covert radio beacons. The mesh uses Weak Signal Propagation Reporter (WSPR) as an exfiltration and tracking channel and operates under legitimate amateur callsigns across at least six countries. The attack chain is concise: a silent rogue MDM profile installed with under 60 seconds of physical access grants a hidden application the ability to reconfigure the Qualcomm baseband in RAM, causing periodic WSPR transmissions (β‰ˆ110 s every few minutes) at approximately 0.2 W EIRP.

-

Two victims have been cross-confirmed: the original discoverer in the UK and an independent victim in Switzerland, both sharing exposure to the same individual at a professional conference in Milan 2024. The stalker's callsign (IW3RMR) appears consistently in receiver logs for both victims.

- -

2. Background: WSPR & Baseband Interfaces

-

WSPR is a low-data, weak-signal propagation reporting protocol introduced by K1JT (Joe Taylor). It is intended for automated propagation experiments and uses highly-structured, time-synchronised transmissions that are readily decoded by distributed receivers. Modern Qualcomm basebands (X65/X70) support a broad frequency range from 600 kHz to 7.125 GHz, covering amateur bands including 160m (1.838 MHz) and 6m (50.294 MHz). Vendor diagnostic interfaces, if exposed by privileged software, allow radio configuration commands to be issued directly to the radio DSP and RF front end.

- -

3. Threat Model and Attack Summary

-

3.1 Threat model

-

An attacker capable of obtaining brief, unsupervised physical access to a target device (conference environment, brief handshake or pocket access) and the ability to install a silent configuration profile (MDM) is sufficient. The attacker does not require root/jailbreak access, external hardware, nor persistent baseband flash modification. The threat actor operates under legitimate amateur radio callsigns, providing operational cover.

- -

3.2 Attack summary

-
    -
  • Install a silent/hidden MDM configuration profile via physical access (under 60 seconds required).
  • -
  • Deploy a hidden application that uses enterprise-level entitlements (com.apple.private.mobilegestalt.allow-baseband-override) to access private vendor IPC, invoking raw baseband commands (e.g., AT+QCFG or QDSP6 hex sequences) to place the baseband into test/diagnostic state and inject a RAM-resident patch.
  • -
  • Schedule periodic WSPR transmissions (162 symbols every 110 s, ~0.2 W EIRP) broadcasting a callsign and a 6-character Maidenhead locator that identifies the target's street-level location.
  • -
  • Coordinate a distributed receive mesh of legitimate amateur callsigns across multiple countries to log spots synchronously, providing real-time tracking capability.
  • -
- -

4. Methods

-

4.1 Forensic setup

-

Instrumentation included:

-
    -
  • RTL-SDR Blog V3 receiver and a 160 m dipole (fixed QTH, IO81ti grid).
  • -
  • GQRX and WSPR-X for continuous decode and spot logging.
  • -
  • EMF meters and decibel meters for power measurement and source localization.
  • -
  • WSPRnet.org public logs for cross-correlation and receiver mesh identification.
  • -
  • Time synchronisation via public NTP to correlate transmission windows.
  • -
- -

4.2 Validation tests

-
    -
  1. Initial discovery: Unexplained 1.07 GB mobile data exfiltration triggered investigation (14 Nov 2025).
  2. -
  3. Power-state correlation: Phone ON = strong WSPR bursts on 1.838143 MHz; Phone OFF = instant silence and EMF drop from 2.9 to 0.0 Β΅W/cmΒ².
  4. -
  5. Two-phone isolation: Identical model "clean" phone vs infected phone on same tableβ€”only infected phone transmits.
  6. -
  7. Neighbour elimination: Mobile SDR scans of entire street with infected phone in Faraday pouch confirmed no external transmitter (noise floor –95 to –110 dBm).
  8. -
  9. Faraday containment: Single and double-layer Faraday pouches immediately halt all worldwide WSPR spots.
  10. -
  11. Band hopping: Detected transmissions on both 160 m (1.838 MHz) and 6 m (50.294 MHz) without external antenna, confirming baseband reprogramming capability.
  12. -
  13. Cross-validation: Independent victim in Switzerland exhibited identical behaviour; stalker callsign IW3RMR appeared in both victims' logs.
  14. -
  15. Stress test: 168 spots logged across 42 unique reporters in 4 minutes (16 Nov 23:34–23:38), demonstrating coordinated mesh response.
  16. -
- -

5. Results

-

5.1 Observed WSPR signatures

-

The infected phone produced discrete WSPR spots at 1.838143 MHz and 50.294439 MHz. Decoded payloads contained an amateur callsign (G0KTN for the UK victim) and a 6-character Maidenhead locator (example: IO81ti, identifying the victim's street). Emission profile matched low-power, short-duration bursts (β‰ˆ0.2 W EIRP, 110 s duration) occurring every 2–10 minutes. First spot appeared within 110 seconds of phone power-on; average 30–40 spots per hour during active transmission periods.

- -

5.2 Containment

-

Placing the phone in a Faraday pouch or powering it off halted all WSPR spots worldwide within 5 seconds. Re-powering the phone outside Faraday isolation resulted in immediate resumption of transmissions (first spot within 102 seconds). Factory reset (Settings β†’ General β†’ Transfer or Reset β†’ Erase All Content and Settings) permanently stopped transmissions by removing the rogue MDM profile and hidden application.

- -

5.3 Receiver mesh behaviour

-

A minimum six-country receive mesh (UK, Switzerland, Italy, Netherlands, USA, Russia) reported synchronous spots during tests. Key receiver callsigns identified: IW3RMR (Italy, suspected controller), PA2W (Netherlands), WB6CXC (USA), G0SJP (UK), UA3VNM (Russia), DL1FX (Germany). During a coordinated stress test on 16 November 23:34–23:38 GMT, 168 spots were logged across 42 unique reporters spanning 6 continents, suggesting deliberate mesh activation in response to victim countermeasures. Each receive node appears as a legitimate amateur station in public databases (QRZ.com), providing operational cover.

- -

5.4 Cross-victim validation

-

A second victim in Switzerland (grid JN37**), who met the same individual at a Milan conference in 2024, independently tested his iPhone and immediately triggered identical WSPR behaviour. The stalker's callsign IW3RMR appeared as the primary reporter for both victims. QRZ.com lookup identified IW3RMR as Alessandro [REDACTED], QTH Pradamano, Udine, Italy, with photo matching the individual met at the conference.

- -

6. Analysis

-

6.1 Baseband reprogramming mechanism

-

Forensic observations are consistent with the following hypothesis:

-
    -
  1. A rogue MDM configuration profile grants a hidden app elevated entitlements, specifically com.apple.private.mobilegestalt.allow-baseband-override (normally restricted to Apple and certified carriers).
  2. -
  3. App issues raw diagnostic/configuration commands to the Qualcomm interface via private IPC APIs, using AT+QCFG or QDSP6 hex command sequences.
  4. -
  5. Baseband enters diagnostic/test mode and accepts a RAM-resident patch to transmit single-tone FSK/WSPR payloads on specified frequencies.
  6. -
  7. The patch configures 162-symbol WSPR transmissions every 110 seconds at approximately 200 mW EIRP using the phone's internal antenna array.
  8. -
  9. Baseband reports "transmit complete" and app schedules next cycle (2–10 minute intervals).
  10. -
-

This approach leaves minimal persistent artifacts (RAM-only patch that does not survive reboot), requires no jailbreak, and uses the stock internal antenna. The Qualcomm X65/X70 modem's frequency range (600 kHz – 7.125 GHz) enables transmission on multiple amateur bands without hardware modification.

- -

6.2 Geolocation capabilities

-

The 6-character Maidenhead locator provides resolution of approximately 70Γ—100 km at the equator, narrowing to street-level precision in practice due to grid square conventions. Example: IO81ti identifies a specific street in the UK. The receiver mesh logs these transmissions across multiple international stations, providing distributed observation and confirmation of the target device's location. Spots appear on the public WSPRnet.org database in near-real-time, enabling continuous tracking of any infected device that remains powered and unshielded.

- -

6.3 Infection vector

-

Both confirmed victims attended the same professional conference in Milan (2024) and had brief physical interaction with the same individual (subsequently identified as IW3RMR). The MDM profile installation requires under 60 seconds of physical access and can be accomplished during handshakes, device demonstrations, or similar social engineering scenarios common at conferences. The profile installs silently with no user notification and does not appear in standard Settings β†’ General β†’ VPN & Device Management unless specifically searched.

- -

7. Recommendations

-

7.1 Immediate actions (0–72 hours)

-
    -
  • Device forensics & containment: Seize affected devices in Faraday isolation under appropriate legal authority (e.g., RIPA Section 8); dump baseband RAM (Qualcomm QDSP6) while in test mode to capture injected patch; extract MDM configuration profiles and identify signing authority; avoid powering devices outside Faraday until forensic imaging complete.
  • -
  • Spectrum coordination: Temporarily monitor 1.8381–1.8382 MHz and 50.294 MHz; liaise with national spectrum authorities (RSGB/Ofcom for UK) to place watch notices on identified callsigns: IW3RMR, PA2W, WB6CXC, G0SJP, UA3VNM, DL1FX.
  • -
  • Vendor engagement: Request emergency audit from Apple and Qualcomm on MDM entitlements and exposed baseband command paths; identify all enterprise certificates with baseband override privileges; request full MDM command logs tied to rogue profiles.
  • -
  • Public guidance: Issue advisory (non-alarmist) for conference attendees not to accept unknown configuration profiles; recommend immediate power-off and Faraday storage if suspicious data usage or device heating occurs; publish simple containment guide (power off + Β£15 Faraday pouch).
  • -
  • Victim identification: Cross-reference Milan 2024 conference attendee lists with WSPRnet spot patterns for callsigns matching conference attendee locations.
  • -
- -

7.2 Medium-term (0–30 days)

-

Coordinate international investigative bodies (NCA/NCSC/ENISA/Interpol/FCC/BNetzA) for cross-border analysis and legal action. Open Interpol Yellow Notice for identified threat actor (Alessandro [REDACTED], Pradamano, Italy). Notify EU Cyber Rapid Response Team regarding potential supply-chain attack vector via professional conferences. Develop detection signatures for anomalous WSPR patterns (excessive self-spots, street-level locator precision, correlation with known conference attendee movements).

- -

7.3 Long-term mitigation

-

Apple to implement MDM policy restrictions preventing baseband radio override without explicit user consent. Qualcomm to audit diagnostic mode access paths in consumer device firmware. Amateur radio community (ARRL/RSGB/IARU) to establish anomalous WSPR pattern monitoring. Conference security guidelines to include MDM profile inspection recommendations.

- -

8. Technical Appendix (selected excerpts)

-
    -
  • WSPR protocol: 162-symbol FSK transmission over 110.6 seconds, 6 Hz bandwidth, designed for weak-signal propagation experiments. Highly structured and time-synchronised, making it ideal for covert C2 due to legitimacy and public receiver infrastructure.
  • -
  • Observed frequencies: 1.838143 MHz (160m band) and 50.294439 MHz (6m band). Both fall within Qualcomm X65/X70 modem frequency range.
  • -
  • Hypothesised reprogramming flow: silent MDM profile β†’ com.apple.private.mobilegestalt.allow-baseband-override entitlement β†’ raw vendor IPC (AT+QCFG/QDSP6 commands) β†’ baseband test mode β†’ RAM-resident patch β†’ scheduled WSPR bursts.
  • -
  • Power characteristics: Approximately 0.2 W EIRP (+23 dBm), 110-second duration, 2–10 minute intervals. Low enough to blend with legitimate amateur WSPR stations, high enough for continental-scale reception.
  • -
  • Containment: Power off + Faraday bag provides immediate, complete isolation (5-second response time globally). Factory reset (Erase All Content and Settings) provides permanent eradication. Airplane mode and SIM removal do NOT stop transmissionsβ€”baseband operates independently of user-facing radio controls.
  • -
- -

9. Conclusion

-

This discovery reveals a novel and dangerous class of C2 that combines mobile device management, baseband command interfaces, and a global amateur receiver mesh to perform covert exfiltration and street-level geolocation. The attack is low-cost, difficult to detect at scale, and operates under the cover of legitimate amateur radio activity. Two confirmed victims across two countries demonstrate this is not an isolated incident but a coordinated operation. The only reason this network was discovered is because a civilian victim refused to accept coincidence and conducted systematic forensic analysis. Rapid coordination between law enforcement, spectrum regulators, device vendors, and the amateur radio community is required to investigate, contain, and mitigate the threat before the next conference season begins.

- -
- Acknowledgments: The author thanks the independent Swiss victim who provided cross-validation data, and volunteer SDR operators who contributed WSPR observations used in this study. Special acknowledgment to the amateur radio community whose public receiver infrastructure inadvertently enabled discovery of this exploit. -
- -

References

-
    -
  1. J. Taylor (K1JT), "WSPR: Weak Signal Propagation Reporter," 2008.
  2. -
  3. RTL-SDR Blog V3 technical documentation and calibration procedures.
  4. -
  5. Qualcomm QDSP6 and baseband diagnostic interface vendor documentation.
  6. -
  7. WSPRnet.org public spot database (archived logs 14–17 November 2025).
  8. -
  9. QRZ.com amateur radio callsign database (IW3RMR, PA2W, WB6CXC, G0SJP, UA3VNM lookups).
  10. -
-
- - - -
-
- Gareth [REDACTED] (version 0.1)
- Classification: UNCLASSIFIED // FOR OFFICIAL USE ONLY
- Date: 17 November 2025
-
- Revised by: Sion Buckler (version 0.2)
- Cyber & Electronic Warfare Professional
- Life Member of the Royal Corps of Signals (2017+
- Oath of Allegiance 2002 - 2024
- Formerly Developed Vetted (DV) Security & Official Secrets Act Cleared
- Added MLAT/TDOA precision geolocation analysis
- Revision Date: 2 December 2025 -
- -
- Abstract: Between 14–17 November 2025, a civilian investigation uncovered a previously undocumented command-and-control (C2) infrastructure leveraging Weak Signal Propagation Reporter (WSPR) transmissions to covertly exfiltrate data and perform precision geolocation on commodity smartphones. The exploit uses rogue Mobile Device Management (MDM) provisioning to obtain privileged access to a phone's Qualcomm baseband, which is then temporarily reconfigured in RAM to transmit legitimate-looking WSPR beacons on HF and VHF amateur bands. We describe forensic evidence from multiple independent tests, cross-validation with international receive nodes, hypothesised multilateration (MLAT) for street-level accuracy, and recommended containment and investigation procedures. The exploit requires brief physical access, leaves minimal persistent artefacts, and is mitigated primarily via power-off and Faraday isolation. -
- -
- Keywords: WSPR, baseband exploit, MDM, multilateration, MLAT, TDOA, mobile device security, SDR, forensic analysis -
- -

1. Introduction

-

Between 14–17 November 2025 a British civilian documented an operational C2 mesh that converts ordinary iPhones into covert radio beacons. The mesh uses Weak Signal Propagation Reporter (WSPR) as an exfiltration and tracking channel and operates under legitimate amateur callsigns across at least six countries. The attack chain is concise: a silent rogue MDM profile installed with under 60 seconds of physical access grants a hidden application the ability to reconfigure the Qualcomm baseband in RAM, causing periodic WSPR transmissions (β‰ˆ110 s every few minutes) at approximately 0.2 W EIRP.

-

This paper synthesises the discovery, forensic validation, and analysis into a format suitable for technical review and submission to engineering and security venues.

- -

2. Background: WSPR & Baseband Interfaces

-

WSPR is a low-data, weak-signal propagation reporting protocol introduced by K1JT (Joe Taylor). It is intended for automated propagation experiments and uses highly-structured, time-synchronised transmissions that are readily decoded by distributed receivers. Modern Qualcomm basebands support a broad frequency range and vendor interfaces (e.g., diagnostic/test APIs) that, if exposed by privileged software, could allow radio configuration commands to be issued directly to the radio DSP and RF front end.

- -

3. Threat Model and Attack Summary

-

3.1 Threat model

-

An attacker capable of obtaining brief, unsupervised physical access to a target device (conference environment, brief handshake pocket access) and the ability to install a silent configuration profile (MDM) is sufficient. The attacker does not require root/jailbreak access, external hardware, nor persistent baseband flash.

- -

3.2 Attack summary

-
    -
  • Install a silent/hidden MDM configuration profile via physical access.
  • -
  • Deploy a hidden application that uses enterprise-level entitlements to access private mobilegestalt or vendor IPC, invoking raw baseband commands (e.g., QCFG/QDSP-like sequences) to place the baseband into a test/diagnostic state and inject a RAM-resident patch.
  • -
  • Schedule periodic WSPR transmissions (example: 162 symbols every 110 s, ~0.2 W EIRP) broadcasting a callsign and a 6-character Maidenhead locator.
  • -
  • Coordinate a distributed receive mesh of legitimate amateur callsigns to log spots synchronously and compute TDOA/MLAT for higher-precision localisation.
  • -
- -

4. Methods

-

4.1 Forensic setup

-

Instrumentation included:

-
    -
  • RTL-SDR Blog V3 receiver and a 160 m dipole (fixed QTH).
  • -
  • GQRX and WSPR-X for continuous decode.
  • -
  • EMF and decibel meters.
  • -
  • WSPRnet logs from public reporters for cross-correlation.
  • -
  • Time synchronisation via public NTP for receive machines where possible.
  • -
- -

4.2 Validation tests

-
    -
  1. Two-phone isolation: identical model "clean" phone vs infected phone on same table.
  2. -
  3. Faraday containment: single and double-layer Faraday pouches.
  4. -
  5. Neighbour sweep: mobile SDR scans of the immediate street with the phone inside Faraday.
  6. -
  7. Band hopping: attempt to detect transmissions on 160 m (1.838 MHz) and 6 m (50.294 MHz) without external antenna.
  8. -
  9. Cross-validation: independence checks via an infected second device in Switzerland and public WSPRnet reporters.
  10. -
- -

5. Results

-

5.1 Observed WSPR signatures

-

The infected phone produced discrete WSPR spots at 1.838143 MHz and at 50.294439 MHz. Decoded payloads contained an amateur callsign and a 6-character Maidenhead locator (example: IO81ti). Emission profile matched low-power, short-duration bursts (β‰ˆ0.2 W, 110 s bursts).

- -

5.2 Containment

-

Placing the phone in a Faraday pouch or powering it off halted all WSPR spots worldwide within seconds. Factory reset (removal of MDM profile and application) permanently stopped transmissions.

- -

5.3 Receiver mesh behaviour

-

A minimum six-country receive mesh (UK, Switzerland, Italy, Netherlands, USA, Russia) reported synchronous spots during tests, producing 168 spots in a 4-minute stress test. Each receive node registered as a legitimate amateur station in public databases.

- -

6. Analysis

-

6.1 Baseband reprogramming

-

Forensic observations are consistent with the following hypothesis:

-
    -
  1. A profile gives a hidden app elevated entitlements (private mobilegestalt / vendor IPC).
  2. -
  3. App issues raw diagnostic/configuration commands to the Qualcomm interface.
  4. -
  5. Baseband enters diagnostic/test mode and accepts a RAM-resident patch to transmit single-tone FSK/WSPR payloads.
  6. -
-

This approach leaves minimal persistent artifacts (RAM-only patch), requires no jailbreak, and uses the phone's internal antenna array.

- -
-

6.2 Precision geolocation: MLAT/TDOA (NEW IN v0.2)

-

Revision Note: This section introduces advanced geolocation analysis not present in the original discovery documentation.

- -

While a 6-character Maidenhead locator provides coarse resolution (~400 m), the receiver mesh can plausibly produce street-level accuracy via multilateration (MLAT) and Time Difference of Arrival (TDOA) techniques.

- -

6.2.1 MLAT/TDOA Fundamentals

-

Multilateration is a positioning technique that determines location by measuring the time difference of arrival (TDOA) of a signal at multiple receivers. Unlike traditional triangulation which requires distance measurements, MLAT uses the relative time delays between receivers to construct hyperbolic curves. The intersection of multiple hyperbolas yields the transmitter's position.

- -

6.2.2 Implementation in WSPR C2 Context

-

The WSPR protocol's highly structured 110-second transmission window provides an ideal timing reference for TDOA calculations. Key implementation factors include:

-
    -
  • Time Synchronization: Receivers synchronized via GPS or NTP to within microseconds enable precise TDOA measurements.
  • -
  • Receiver Geometry: The six-country mesh (UK, Switzerland, Italy, Netherlands, USA, Russia) provides favorable geometric dilution of precision (GDOP) for European targets.
  • -
  • Signal Characteristics: The 0.2 W EIRP transmission at 1.838 MHz and 50.294 MHz allows consistent detection across continental distances during favorable propagation conditions.
  • -
- -

6.2.3 Accuracy Estimates

-

Under favorable conditions, MLAT/TDOA systems can achieve positioning accuracy described by:

-

Οƒ_position β‰ˆ (c Γ— Οƒ_time) / √(N-1)

-

Where c is the speed of light, Οƒ_time is timing uncertainty, and N is the number of receivers. With:

-
    -
  • 6 receivers (N=6)
  • -
  • GPS-synchronized timing (Οƒ_time β‰ˆ 10 ΞΌs)
  • -
  • Favorable GDOP (< 3)
  • -
-

Theoretical positioning accuracy approaches 1-3 kilometers for HF propagation. However, ionospheric effects and multipath propagation introduce significant uncertainty in HF bands. The 6m VHF transmission (50.294 MHz) offers superior precision within line-of-sight ranges, potentially achieving metre-scale accuracy with proper receiver deployment.

- -

6.2.4 Practical Constraints

-

Several factors limit operational MLAT/TDOA effectiveness:

-
    -
  • Ionospheric Variability: HF propagation paths vary with solar activity, time of day, and season, introducing timing errors of 100s of microseconds.
  • -
  • Multipath Propagation: Multiple signal paths to a single receiver create ambiguous arrival times.
  • -
  • Receiver Density: Continental-scale deployment provides coarse positioning; urban-scale precision requires local receiver infrastructure.
  • -
  • Processing Requirements: Real-time hyperbolic intersection computation requires coordinated data fusion and sophisticated signal processing.
  • -
- -

6.2.5 Dual-Band Exploitation Strategy

-

The observed dual-band operation (1.838 MHz HF and 50.294 MHz VHF) suggests a tiered tracking strategy:

-
    -
  1. HF (160m band): Continental-scale tracking with 1-10 km accuracy via long-distance receivers.
  2. -
  3. VHF (6m band): Regional-scale precision (10-100 m) using line-of-sight receivers for final approach tracking.
  4. -
-

This dual-band approach compensates for HF ionospheric limitations while leveraging VHF line-of-sight precision, creating a hierarchical tracking capability from continental to street-level resolution.

-
- -

7. Recommendations

-

7.1 Immediate actions (0–72 hours)

-
    -
  • Device forensics & containment: Seize affected devices in Faraday isolation; dump baseband RAM where possible; avoid powering devices outside Faraday.
  • -
  • Spectrum coordination: Temporarily monitor 1.8381–1.8382 MHz and 50.294 MHz; liaise with RSGB/Ofcom for watch notices on relevant callsigns.
  • -
  • Vendor engagement: Request emergency audit from Apple and Qualcomm on MDM entitlements and exposed baseband command paths.
  • -
  • Public guidance: Advise conference attendees not to accept unknown configuration profiles; recommend immediate power-off and Faraday storage if suspicious behaviour occurs.
  • -
  • MLAT countermeasures: Consider directed RF noise generation at 1.838 MHz and 50.294 MHz in sensitive locations to degrade TDOA positioning accuracy.
  • -
- -

7.2 Medium-term

-

Coordinate international investigative bodies (NCA/NCSC/ENISA/Interpol/FCC) for cross-border analysis and legal action where appropriate. Develop MLAT detection capabilities to identify suspicious time-synchronized receiver networks.

- -

8. Technical Appendix (selected excerpts)

-
    -
  • WSPR protocol: structured, synchronised transmissions suited to weak-signal propagation experiments.
  • -
  • Observed frequencies: 1.838143 MHz and 50.294439 MHz (experimentally observed in this investigation).
  • -
  • Hypothesised reprogramming flow: silent MDM profile β†’ elevated entitlements β†’ raw vendor IPC β†’ RAM patch β†’ scheduled WSPR bursts.
  • -
  • MLAT equations: Hyperbolic positioning via TDOA measurements across N receivers with geometric dilution of precision (GDOP) considerations.
  • -
  • Containment: Power off + Faraday bag or factory reset (Erase All Content and Settings) removes the attack surface.
  • -
- -

9. Conclusion

-

This discovery reveals a novel and dangerous class of C2 that combines mobile device management, baseband command interfaces, and a global amateur receiver mesh to perform covert exfiltration and highly-precise geolocation. The addition of MLAT/TDOA analysis demonstrates that the threat extends beyond simple location reporting to potential metre-scale tracking capability when properly implemented with coordinated receiver infrastructure. The attack is low-cost and difficult to detect at scale. Rapid coordination between law enforcement, spectrum regulators, and device vendors is required to investigate, contain, and mitigate the threat.

- -
- Acknowledgments: The author thanks independent reporters and volunteer SDR operators who contributed WSPR observations used in this study. v0.2 revision adds technical analysis of multilateration capabilities. -
- -

References

-
    -
  1. J. Taylor, "WSPR: Weak Signal Propagation Reporter," 2008.
  2. -
  3. RTL-SDR Blog V3 documentation.
  4. -
  5. Qualcomm QDSP6 and baseband interface vendor documentation.
  6. -
  7. B. Hofmann-Wellenhof et al., "GNSS – Global Navigation Satellite Systems: GPS, GLONASS, Galileo, and more," Springer, 2008.
  8. -
  9. S. Stein, "Algorithms for ambiguity function processing," IEEE Trans. Acoustics, Speech, and Signal Processing, vol. 29, no. 3, 1981.
  10. -
-
- -
- - -
- - - - - - diff --git a/static/gui/404.html b/static/gui/404.html deleted file mode 100644 index 8f039f1cf..000000000 --- a/static/gui/404.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - 404 – Not Found - - - - -
-

404

-

Oops! This page doesn’t exist.

-

← Go home

-
- - - - - \ No newline at end of file diff --git a/static/gui/CHANGELOG.md b/static/gui/CHANGELOG.md index bd2f32dfb..6b476e3f7 100755 --- a/static/gui/CHANGELOG.md +++ b/static/gui/CHANGELOG.md @@ -11,7 +11,6 @@ and a combination of [Prince2 Project Management](https://prince2.com). ## [gui-0.9] - Q4/2025 ### Changes -Nov-29 - Some of the webapps weren't staying installed - fixed it Nov-13 - Test A - TEST B - TEST C - TEST D - CLAUD YML 1 - CLAUD 2 ## [gui-0.8] - Q3/2024 diff --git a/static/gui/GEMINI.md b/static/gui/GEMINI.md deleted file mode 100644 index 1fa376e26..000000000 --- a/static/gui/GEMINI.md +++ /dev/null @@ -1,35 +0,0 @@ -# Gemini CLI Configuration - -This file stores configuration and context for the Gemini CLI. - -## Project Information - -- **Project Name:** static-gui -- **Current Directory:** /home/unclehowell/datro/static/gui -- **Operating System:** linux -- **Today's Date:** 2025-11-29 - -## Key Files and Directories - -- **Main HTML:** index.html -- **Configuration:** tailwind.config.js, package.json, manifest.json -- **Source Code/App Logic:** app-store/, dashboard/ -- **Assets:** app-store/css/, app-store/fonts/, app-store/img/, app-store/js/, dashboard/css/, dashboard/fonts/, dashboard/img/, dashboard/js/, dashboard/media/, dashboard/scss/ - -## Notes - -- The project appears to be a static website with a focus on an "app store" and "dashboard" interface. -- It utilizes Tailwind CSS for styling. -- Several JavaScript libraries are included (jQuery, Bootstrap, Featherlight, etc.). -- There are multiple versions or demo HTML files, suggesting a development or staging process. - -## Breadcrumb Navigation - -- **Order:** Breadcrumb items in the `app-store/` directory appear visually inverted to their order in the HTML code. The first visible item (last in code) should be blank. - -## TODO - -- [ ] Review `app-store/apps/` for application-specific details. -- [ ] Analyze `dashboard/apps.json` for dashboard data structure. -- [ ] Investigate the purpose of the numerous demo HTML files. -- [ ] Check `package.json` for build scripts or dependencies. \ No newline at end of file diff --git a/static/gui/app-error.html b/static/gui/app-error.html deleted file mode 100644 index 367eda824..000000000 --- a/static/gui/app-error.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - App Not Available - - - -
-

!

-

App not available

-

This app doesn't appear to be installed or running on your localhost.

- ← Go Back - -
- - - - \ No newline at end of file diff --git a/static/gui/app-store/000-new.html b/static/gui/app-store/000-new.html index 8e7f979c5..cae61911e 100755 --- a/static/gui/app-store/000-new.html +++ b/static/gui/app-store/000-new.html @@ -45,12 +45,20 @@
- - - - - - +
@@ -130,4 +138,4 @@ .then(response => console.log('Success:', response)); - \ No newline at end of file + diff --git a/static/gui/app-store/000.html b/static/gui/app-store/000.html index 8b948be9e..789aa8b1c 100755 --- a/static/gui/app-store/000.html +++ b/static/gui/app-store/000.html @@ -1,3 +1,4 @@ + @@ -162,12 +163,17 @@
- - - - - - +
@@ -249,4 +255,5 @@ - \ No newline at end of file + + diff --git a/static/gui/app-store/0000.html b/static/gui/app-store/0000.html index 023c8d73d..00b5a4176 100755 --- a/static/gui/app-store/0000.html +++ b/static/gui/app-store/0000.html @@ -26,80 +26,31 @@
- - - - - - +
+

App Store locked for the Woodhaven Release !!
Our next Over-the-Air Update will auto-unlock access to the App Store - stay tuned, visit datro.world !!

+ -
- - - - \ No newline at end of file + + + + + diff --git a/static/gui/app-store/002.html b/static/gui/app-store/002.html index 385bf0a61..408a4aa18 100755 --- a/static/gui/app-store/002.html +++ b/static/gui/app-store/002.html @@ -4,37 +4,36 @@ App Store - - + + - - +
- - - - - - +
- +
HΞ²nΞ² entertainment app icon 002-001 @@ -46,7 +45,7 @@
- +
HΞ²nΞ² entertainment app icon 002-002 @@ -72,34 +71,5 @@
- - \ No newline at end of file + diff --git a/static/gui/app-store/002b.html b/static/gui/app-store/002b.html index 481cbbc23..ee62a7934 100755 --- a/static/gui/app-store/002b.html +++ b/static/gui/app-store/002b.html @@ -19,12 +19,20 @@
@@ -146,4 +154,4 @@ window.addEventListener('storage', updateHomeScreen); // Listen for changes in localStorage - \ No newline at end of file + diff --git a/static/gui/app-store/003.html b/static/gui/app-store/003.html index 4dc9bb53f..ddb0533cf 100755 --- a/static/gui/app-store/003.html +++ b/static/gui/app-store/003.html @@ -4,18 +4,9 @@ HΞ²nΞ² Controller Apps - - + + - +
  • + Categories +
  • +
  • + App Store +
  • +
  • + +
  • +
    - +
    - -
    -
    - Smart home app icon 004-001 -
    -
    - - -
    -
    -
    - - -
    -
    - Smart home app icon 004-002 -
    -
    - - -
    -
    -
    - - -
    -
    - Smart home app icon 004-003 -
    -
    - - -
    -
    -
    - - -
    -
    - Smart home app icon 004-004 -
    -
    - - -
    -
    -
    -
    - + - \ No newline at end of file + diff --git a/static/gui/app-store/005.html b/static/gui/app-store/005.html index 1cf81180a..d8e428678 100755 --- a/static/gui/app-store/005.html +++ b/static/gui/app-store/005.html @@ -4,36 +4,35 @@ App Store - - + + - - +
    - - - - - - +
    - +
    Safety and security app icon 005-001 @@ -45,7 +44,7 @@
    - +
    Safety and security app icon 005-002 @@ -71,46 +70,5 @@
    - - \ No newline at end of file + diff --git a/static/gui/app-store/006.html b/static/gui/app-store/006.html index 806920bc5..e7607ca20 100755 --- a/static/gui/app-store/006.html +++ b/static/gui/app-store/006.html @@ -4,37 +4,35 @@ App Store - - + + - - +
    -
    - +
    Other app icon 006-001 @@ -46,7 +44,7 @@
    - +
    Other app icon 006-002 @@ -72,46 +70,6 @@
    - + diff --git a/static/gui/app-store/00x.html b/static/gui/app-store/00x.html index 49a33aea1..388d59228 100755 --- a/static/gui/app-store/00x.html +++ b/static/gui/app-store/00x.html @@ -26,17 +26,72 @@
    -

    App Store locked for the Woodhaven Release !!
    Our next Over-the-Air Update will auto-unlock access to the App Store - stay tuned, visit datro.world !!

    + +
    + +
    + +
    + +
    + + +
    + +
    + +
    +
    @@ -45,4 +100,4 @@ - \ No newline at end of file + diff --git a/static/gui/app-store/app-description-002-001.html b/static/gui/app-store/app-description-002-001.html deleted file mode 100644 index e570c26f7..000000000 --- a/static/gui/app-store/app-description-002-001.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - HΞ²nΞ² entertainment app 002-001 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - HΞ²nΞ² entertainment app 002-001 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Entertainment

    -
    -
    -
    -

    This is a placeholder description for the HΞ²nΞ² entertainment app 002-001. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - diff --git a/static/gui/app-store/app-description-002-002.html b/static/gui/app-store/app-description-002-002.html deleted file mode 100644 index b8b913f1f..000000000 --- a/static/gui/app-store/app-description-002-002.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - HΞ²nΞ² entertainment app 002-002 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - HΞ²nΞ² entertainment app 002-002 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Entertainment

    -
    -
    -
    -

    This is a placeholder description for the HΞ²nΞ² entertainment app 002-002. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - \ No newline at end of file diff --git a/static/gui/app-store/app-description-003-001.html b/static/gui/app-store/app-description-003-001.html deleted file mode 100644 index 950788bbd..000000000 --- a/static/gui/app-store/app-description-003-001.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - JeHervy controller app - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - JeHervy controller app icon -
    -

    [APP_REAL_NAME]

    -

    Category: Controllers

    -
    -
    -
    -

    This is a placeholder description for the JeHervy controller app. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - \ No newline at end of file diff --git a/static/gui/app-store/app-description-004-001.html b/static/gui/app-store/app-description-004-001.html deleted file mode 100644 index 3757f81e3..000000000 --- a/static/gui/app-store/app-description-004-001.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - App 004-001 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - App 004-001 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Smart Home

    -
    -
    -
    -

    This is a placeholder description for App 004-001. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - diff --git a/static/gui/app-store/app-description-004-002.html b/static/gui/app-store/app-description-004-002.html deleted file mode 100644 index 200a0a51c..000000000 --- a/static/gui/app-store/app-description-004-002.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - App 004-002 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - App 004-002 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Smart Home

    -
    -
    -
    -

    This is a placeholder description for App 004-002. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - diff --git a/static/gui/app-store/app-description-004-003.html b/static/gui/app-store/app-description-004-003.html deleted file mode 100644 index 1b7f6fb20..000000000 --- a/static/gui/app-store/app-description-004-003.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - App 004-003 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - App 004-003 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Smart Home

    -
    -
    -
    -

    This is a placeholder description for App 004-003. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - diff --git a/static/gui/app-store/app-description-004-004.html b/static/gui/app-store/app-description-004-004.html deleted file mode 100644 index 5fe79cf89..000000000 --- a/static/gui/app-store/app-description-004-004.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - App 004-004 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - App 004-004 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Smart Home

    -
    -
    -
    -

    This is a placeholder description for App 004-004. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - \ No newline at end of file diff --git a/static/gui/app-store/app-description-005-001.html b/static/gui/app-store/app-description-005-001.html deleted file mode 100644 index b5049984f..000000000 --- a/static/gui/app-store/app-description-005-001.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - App 005-001 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - App 005-001 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Safety & Security

    -
    -
    -
    -

    This is a placeholder description for App 005-001. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - \ No newline at end of file diff --git a/static/gui/app-store/app-description-005-002.html b/static/gui/app-store/app-description-005-002.html deleted file mode 100644 index c122cb36a..000000000 --- a/static/gui/app-store/app-description-005-002.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - App 005-002 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - App 005-002 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Safety & Security

    -
    -
    -
    -

    This is a placeholder description for App 005-002. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - \ No newline at end of file diff --git a/static/gui/app-store/app-description-006-001.html b/static/gui/app-store/app-description-006-001.html deleted file mode 100644 index b7869e1f5..000000000 --- a/static/gui/app-store/app-description-006-001.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - App 006-001 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - App 006-001 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Other

    -
    -
    -
    -

    This is a placeholder description for App 006-001. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - \ No newline at end of file diff --git a/static/gui/app-store/app-description-006-002.html b/static/gui/app-store/app-description-006-002.html deleted file mode 100644 index 44aae73c7..000000000 --- a/static/gui/app-store/app-description-006-002.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - App 006-002 - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - App 006-002 icon -
    -

    [APP_REAL_NAME]

    -

    Category: Other

    -
    -
    -
    -

    This is a placeholder description for App 006-002. More details about its features and functionality would go here.

    -
    - -
    -
    -
    - - - -
    -
    - - - - - \ No newline at end of file diff --git a/static/gui/app-store/app-description-TEMPLATE.html b/static/gui/app-store/app-description-TEMPLATE.html deleted file mode 100644 index 6721df09c..000000000 --- a/static/gui/app-store/app-description-TEMPLATE.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - [APP_NAME] - App Store - - - - - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - -
    -
    - [APP_NAME] icon -
    -

    [APP_REAL_NAME]

    -

    Category: [CATEGORY_NAME]

    -
    -
    -
    -

    [APP_DESCRIPTION]

    - -
    -
    - - - -
    -
    - - - - - diff --git a/static/gui/app-store/apps/002-001/fetch.html b/static/gui/app-store/apps/002-001/fetch.html index b213ecf96..b3be0b37c 100755 --- a/static/gui/app-store/apps/002-001/fetch.html +++ b/static/gui/app-store/apps/002-001/fetch.html @@ -4,26 +4,20 @@ Redirect Page - @@ -31,4 +25,4 @@ - \ No newline at end of file + diff --git a/static/gui/app-store/apps/002-002/fetch.html b/static/gui/app-store/apps/002-002/fetch.html index 39a0c8f1d..51e31bab0 100755 --- a/static/gui/app-store/apps/002-002/fetch.html +++ b/static/gui/app-store/apps/002-002/fetch.html @@ -2,33 +2,29 @@ - Redirect Page + + - - - - + - \ No newline at end of file + diff --git a/static/gui/app-store/apps/003-001/fetch.html b/static/gui/app-store/apps/003-001/fetch.html index 37e0b8911..472d289da 100755 --- a/static/gui/app-store/apps/003-001/fetch.html +++ b/static/gui/app-store/apps/003-001/fetch.html @@ -1,34 +1,55 @@ - - - - - Redirect Page - - - + + + + + + + + + +======= + + + + + - // Ensure handleAppLaunch is available (it should be loaded from appLauncher.js) - if (typeof handleAppLaunch === 'function') { - handleAppLaunch(appId, localBaseUrl, onlineDemoUrl); - } else { - // Fallback if appLauncher.js is not loaded or function is not available - console.error('appLauncher.js or handleAppLaunch function not found.'); - // Optionally, you could try the old redirect logic here as a fallback - var hostname = window.location.hostname; - if (hostname.indexOf("datro") !== -1) { - window.location.replace(onlineDemoUrl); - } else { - window.location.replace(localBaseUrl); - } - } - }; - + + + + + + - - + - \ No newline at end of file + +>>>>>>> 741d0a0ca1ee372699f08f24b26ce103144db70c diff --git a/static/gui/app-store/apps/004-001/fetch.html b/static/gui/app-store/apps/004-001/fetch.html index 742a3462c..7133985cd 100755 --- a/static/gui/app-store/apps/004-001/fetch.html +++ b/static/gui/app-store/apps/004-001/fetch.html @@ -4,26 +4,20 @@ Redirect Page - @@ -31,4 +25,5 @@ - \ No newline at end of file + + diff --git a/static/gui/app-store/apps/004-002/fetch.html b/static/gui/app-store/apps/004-002/fetch.html index 5f29db874..c7a6117ef 100755 --- a/static/gui/app-store/apps/004-002/fetch.html +++ b/static/gui/app-store/apps/004-002/fetch.html @@ -1,34 +1,26 @@ - - - - - Redirect Page - - - + + + + + + - - + - \ No newline at end of file + diff --git a/static/gui/app-store/apps/004-003/fetch.html b/static/gui/app-store/apps/004-003/fetch.html index fa074213f..25b159cc2 100755 --- a/static/gui/app-store/apps/004-003/fetch.html +++ b/static/gui/app-store/apps/004-003/fetch.html @@ -1,34 +1,55 @@ - - - - - Redirect Page - - - + + + + + + + + + +======= + + + + + - // Ensure handleAppLaunch is available (it should be loaded from appLauncher.js) - if (typeof handleAppLaunch === 'function') { - handleAppLaunch(appId, localBaseUrl, onlineDemoUrl); - } else { - // Fallback if appLauncher.js is not loaded or function is not available - console.error('appLauncher.js or handleAppLaunch function not found.'); - // Optionally, you could try the old redirect logic here as a fallback - var hostname = window.location.hostname; - if (hostname.indexOf("datro") !== -1) { - window.location.replace(onlineDemoUrl); - } else { - window.location.replace(localBaseUrl); - } - } - }; - + + + + + + - - + - \ No newline at end of file + +>>>>>>> 741d0a0ca1ee372699f08f24b26ce103144db70c diff --git a/static/gui/app-store/apps/004-004/fetch.html b/static/gui/app-store/apps/004-004/fetch.html deleted file mode 100644 index a9b5fec30..000000000 --- a/static/gui/app-store/apps/004-004/fetch.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Redirect Page - - - - - - - - \ No newline at end of file diff --git a/static/gui/app-store/apps/005-001/fetch.html b/static/gui/app-store/apps/005-001/fetch.html index e98a77144..3e72f231d 100755 --- a/static/gui/app-store/apps/005-001/fetch.html +++ b/static/gui/app-store/apps/005-001/fetch.html @@ -1,34 +1,55 @@ - - - - - Redirect Page - - - + + + + + + + + + + +======= + + + + + - // Ensure handleAppLaunch is available (it should be loaded from appLauncher.js) - if (typeof handleAppLaunch === 'function') { - handleAppLaunch(appId, localBaseUrl, onlineDemoUrl); - } else { - // Fallback if appLauncher.js is not loaded or function is not available - console.error('appLauncher.js or handleAppLaunch function not found.'); - // Optionally, you could try the old redirect logic here as a fallback - var hostname = window.location.hostname; - if (hostname.indexOf("datro") !== -1) { - window.location.replace(onlineDemoUrl); - } else { - window.location.replace(localBaseUrl); - } - } - }; - + + + + + + + - - + - \ No newline at end of file + +>>>>>>> 741d0a0ca1ee372699f08f24b26ce103144db70c diff --git a/static/gui/app-store/apps/005-002/fetch.html b/static/gui/app-store/apps/005-002/fetch.html index 2d5cda9cd..20facf58c 100755 --- a/static/gui/app-store/apps/005-002/fetch.html +++ b/static/gui/app-store/apps/005-002/fetch.html @@ -1,34 +1,59 @@ - - - - - Redirect Page - - - + + + + + + + + + + +======= + + + + + - // Ensure handleAppLaunch is available (it should be loaded from appLauncher.js) - if (typeof handleAppLaunch === 'function') { - handleAppLaunch(appId, localBaseUrl, onlineDemoUrl); - } else { - // Fallback if appLauncher.js is not loaded or function is not available - console.error('appLauncher.js or handleAppLaunch function not found.'); - // Optionally, you could try the old redirect logic here as a fallback - var hostname = window.location.hostname; - if (hostname.indexOf("datro") !== -1) { - window.location.replace(onlineDemoUrl); - } else { - window.location.replace(localBaseUrl); - } - } - }; - + + + + + + + - - + - \ No newline at end of file + +>>>>>>> 741d0a0ca1ee372699f08f24b26ce103144db70c diff --git a/static/gui/app-store/apps/006-001/fetch.html b/static/gui/app-store/apps/006-001/fetch.html index e0efb8d68..c7a6117ef 100755 --- a/static/gui/app-store/apps/006-001/fetch.html +++ b/static/gui/app-store/apps/006-001/fetch.html @@ -1,34 +1,26 @@ - - - - - Redirect Page - - - + + + + + + - - + - \ No newline at end of file + diff --git a/static/gui/app-store/apps/006-002/fetch.html b/static/gui/app-store/apps/006-002/fetch.html index 80acb90d5..51e31bab0 100755 --- a/static/gui/app-store/apps/006-002/fetch.html +++ b/static/gui/app-store/apps/006-002/fetch.html @@ -2,33 +2,29 @@ - Redirect Page + + - - - - + - \ No newline at end of file + diff --git a/static/gui/app-store/css/breadcrumb.css b/static/gui/app-store/css/breadcrumb.css index f962ab395..5dd584df6 100755 --- a/static/gui/app-store/css/breadcrumb.css +++ b/static/gui/app-store/css/breadcrumb.css @@ -43,22 +43,25 @@ ul.breadcrumb li { } ul.breadcrumb li a { - overflow: visible; + overflow: hidden; -moz-border-radius: 50px; -webkit-border-radius: 50px; border-radius: 50px; text-decoration: none; - height: auto; + height: 50px; color: white; text-align: center; - width: auto; - display: inline-block; + width: 50px; + display: block; line-height: 50px; - padding: 0 1.5vw; + padding-left: 52px; + padding-right: 33.33333px; + width: 50px; border: 1px solid grey; + --breadcrumb-link-size: 3.8vw; + font-size: 3.8vw; font-size: var(--breadcrumb-link-size, 3.8vw); word-spacing:0.4vw; - white-space: nowrap; } @media screen and (min-width: 900px) { ul.breadcrumb li a { @@ -91,8 +94,8 @@ ul.breadcrumb li a .icon { line-height: unset; /* stops a conflict with fontawesomecss */ } ul.breadcrumb li a .text { - display: inline-block; - opacity: 1; + display: none; + opacity: 0; } ul.breadcrumb li a:hover, @@ -100,14 +103,16 @@ ul.breadcrumb li a:focus, ul.breadcrumb li a:active { background-color: inherit; color: inherit!important; - padding: 0 1.5vw; + padding-left: 52px; + padding-right: 33.33333px; border-color: grey; + font-size: 3.8vw; font-size: var(--breadcrumb-link-size, 3.8vw); line-height: 50px; } ul.breadcrumb li a:hover .text { - display: inline-block; - opacity: 1; + display: none; + opacity: 0; } ul.breadcrumb li:last-child a { @@ -122,7 +127,7 @@ ul.breadcrumb li:last-child:hover a { color: inherit; line-height: 50px; float: right; - padding: 0 1.5vw; + padding: 0 1.2px; background-color: rgb(44, 12, 33); border-radius: 50px; margin-left: -25px; diff --git a/static/gui/app-store/doc-001.html b/static/gui/app-store/doc-001.html index 79bd3e265..a136c742c 100755 --- a/static/gui/app-store/doc-001.html +++ b/static/gui/app-store/doc-001.html @@ -1,21 +1,22 @@ - + + - + App Store - - - - - - - - - + + + + + + + + + @@ -28,74 +29,36 @@ - - - - - - -
    - - + + + + + diff --git a/static/gui/app-store/doc-002.html b/static/gui/app-store/doc-002.html index 13b0f3e4a..7a2dfc739 100755 --- a/static/gui/app-store/doc-002.html +++ b/static/gui/app-store/doc-002.html @@ -29,12 +29,28 @@ - - - - - -
    +
    +
    +
    +
    + +
    +
    +
    +
    - \ No newline at end of file + diff --git a/static/gui/app-store/doc-003.html b/static/gui/app-store/doc-003.html index ab932408a..182d00ea7 100755 --- a/static/gui/app-store/doc-003.html +++ b/static/gui/app-store/doc-003.html @@ -1,5 +1,3 @@ - - @@ -32,12 +30,26 @@
    - - - - - - +
    +
    +
    + +
    +
    +
    @@ -106,4 +118,4 @@ window.addEventListener('storage', updateHomeScreen); // Listen for changes in localStorage - \ No newline at end of file + diff --git a/static/gui/app-store/js/dynamic-breadcrumb.js b/static/gui/app-store/js/dynamic-breadcrumb.js deleted file mode 100644 index edd8a7860..000000000 --- a/static/gui/app-store/js/dynamic-breadcrumb.js +++ /dev/null @@ -1,128 +0,0 @@ -// app-store/js/dynamic-breadcrumb.js - -document.addEventListener('DOMContentLoaded', function() { - // Function to fetch JSON data from a URL - async function fetchJson(url) { - try { - const response = await fetch(url); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - return await response.json(); - } catch (error) { - console.error('Error fetching JSON:', error); - return null; - } - } - - // Function to get the current page identifier - function getCurrentPageIdentifier() { - const path = window.location.pathname; - const segments = path.split('/').filter(segment => segment !== ''); - - // If it's the root of app-store (e.g., /app-store/) - if (segments.length === 1 && segments[0] === 'app-store') { - return '000'; // Assuming '000' represents the main app store page - } - - // If it's a specific app page (e.g., /app-store/apps/004-001/fetch.html) - // We need to extract the app ID. This might need adjustment based on actual URL structure. - // For now, let's assume the last segment before .html is the identifier. - if (segments.length > 1 && segments[segments.length - 1].endsWith('.html')) { - const filename = segments[segments.length - 1]; - return filename.split('.')[0]; - } - - // Fallback for other cases, might need more specific logic - return segments.pop()?.split('.')[0] || '000'; - } - - // Function to generate breadcrumb HTML - function generateBreadcrumbs(sitemapData, currentPageId) { - const breadcrumbContainer = document.querySelector('.breadcrumb'); - if (!breadcrumbContainer) { - console.error('Breadcrumb container not found.'); - return; - } - - let breadcrumbHtml = ''; - let listItemNumber = 1; - - // Start JSON-LD BreadcrumbList - breadcrumbHtml += ` - - `; - - // Inject the generated HTML into the container - breadcrumbContainer.innerHTML = breadcrumbHtml; - } - - // Main execution - async function initializeBreadcrumbs() { - const sitemapData = await fetchJson('/app-store/sitemap.json'); - if (!sitemapData) { - console.error('Failed to load sitemap.json'); - return; - } - - const currentPageId = getCurrentPageIdentifier(); - generateBreadcrumbs(sitemapData, currentPageId); - } - - initializeBreadcrumbs(); -}); \ No newline at end of file diff --git a/static/gui/app-store/sitemap.json b/static/gui/app-store/sitemap.json deleted file mode 100644 index a893fffd7..000000000 --- a/static/gui/app-store/sitemap.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "breadcrumbs": [ - {"text": "", "url": "#"}, - {"text": "App Store", "url": "/app-store/"}, - {"text": "Categories", "url": "#"}, - {"text": "Subcategory", "url": "#"}, - {"text": "App Name", "url": "#"} - ] -} \ No newline at end of file diff --git a/static/gui/dashboard/000.html b/static/gui/dashboard/000.html index ae922fef8..3dea1952d 100755 --- a/static/gui/dashboard/000.html +++ b/static/gui/dashboard/000.html @@ -4,90 +4,120 @@ Site Selector Categories - - - - - - - - + + + + + + + @@ -95,12 +125,13 @@ window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); + gtag('config', 'G-6BTNPTMXBF'); - +