⚠️ WARNING — USE AT YOUR OWN RISK⚠️ This software is experimental and completely unofficial. It was built by reverse-engineering proprietary protocols and could behave in unexpected ways.
This tool could:
- Brick your head unit — corrupted updates may render your MediaNav permanently inoperable
- Void your warranty — using unofficial tools to modify your head unit is not sanctioned by Dacia, Renault, or NNG
- Damage your vehicle — the head unit is connected to vehicle systems; a bad update could have unpredictable consequences
- Violate terms of service — using this tool may breach your naviextras.com account terms
- Produce incorrect map/navigation data — potentially leading to dangerous driving situations
The authors accept no responsibility whatsoever for any damage to your head unit, vehicle, naviextras.com account, or anything else that results from using this software.
You have been warned. Seriously.
A Linux/Python replacement for the Windows-only Dacia MediaNav Evolution Toolbox — the official app for updating maps, POIs, speed cameras, and voice packs on Dacia/Renault MediaNav head units.
This project reverse-engineers the NaviExtras wire protocol and reimplements it as a Python library and CLI tool.
Protocol fully reverse-engineered. All cryptographic parameters derived from credentials — no captured data or hardcoded values needed.
| Component | Status |
|---|---|
| Wire protocol encryption (SnakeOil xorshift128) | ✅ Solved |
Delegated request generation (build_dynamic_request) |
✅ Byte-exact match with captured data |
| Session key derivation | ✅ Solved: creds.secret (toolbox Secret) |
| HMAC-MD5 delegation auth | ✅ Verified against captured logs |
| USB detection + device identity | ✅ Working |
| Device registration | ✅ Working |
| Full authentication flow | ✅ Working (login → fingerprint → delegator → senddevicestatus) |
| senddevicestatus → server | ✅ Returns HTTP 200 |
| Catalog browsing (30 packages, 31 content items) | ✅ Working |
| Content selection + size estimation | ✅ Working |
| License fetch + install (.lyc + .lyc.md5) | ✅ Working |
| Sync command (select → confirm → install) | ✅ Working |
| NNG map format reverse engineering | ✅ Fully decoded |
| OSM → FBL map conversion | ✅ Working (pure Python) |
| Map format documentation | ✅ 1,842 lines |
340 tests passing (57 wire format tests, 32 golden round-trip, 18 USB layout verification, 27 map tool tests).
The NaviExtras catalog shows all map packages compatible with your head unit. Maps are region-based (e.g., "UK + Ireland", "Western Europe") and cost £49–£129 each. The only free content is the Dealership POI pack.
Map data can be downloaded by any registered device, but the head unit requires a valid
.lyc license file (RSA-signed) to accept the update. Purchasing a map through the
NaviExtras store generates the license. The sync command handles the full flow:
select content → confirm with server → download licenses → write to USB.
- Python 3.11+
- A naviextras.com account
- A USB drive previously used with your MediaNav head unit (contains
device.nng)
git clone https://github.com/mretallack/MediaNavToolkit.git
cd MediaNavToolkit
python3 -m venv venv
source venv/bin/activate
pip install -e ".[dev]"Create a .env file with your credentials:
NAVIEXTRAS_USER=your.email@example.com
NAVIEXTRAS_PASS=your_password
NAVIEXTRAS_USB_PATH=/mnt/penWith NAVIEXTRAS_USB_PATH set, you can omit --usb-path:
# Detect your MediaNav USB drive
medianav-toolbox detect
# Show installed maps, licenses, and content versions
medianav-toolbox status
# Authenticate and show session info
medianav-toolbox login
# Browse available content (maps, POIs, safety cameras)
medianav-toolbox catalog
# Show and install available licenses
medianav-toolbox licenses
medianav-toolbox licenses --install
# Quick update check
medianav-toolbox updates
# Sync updates to USB drive (select → download → install)
medianav-toolbox syncNote: You can also pass
--usb-path /mnt/penbefore the command instead of using the env var. If the USB is read-only, credentials are cached in~/.config/medianav-toolbox/.
### Usage Flow
1. **Sync your car** — plug the USB drive into your MediaNav head unit and let it sync
2. **Plug USB into PC** — the drive must contain `NaviSync/license/device.nng`
3. **Run the tool** — `medianav-toolbox catalog` to see available content
4. **Buy content** — `medianav-toolbox buy 61811` to purchase (free items install automatically)
5. **Install licenses** — `medianav-toolbox licenses --install` to write licenses to USB
6. **Sync back to car** — plug the USB drive back into the head unit to apply updates
### Example Output
$ medianav-toolbox detect ✓ MediaNav device detected AppCID: 0x42000B53 Space: 2.3 GB free / 4.4 GB total OS: 6.0.12.2.1166_r2
$ medianav-toolbox status ✓ 6.0.12.2.1166_r2 2.3 GB free / 4.4 GB total Installed Maps ┏━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓ ┃ Map ┃ Size ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩ │ France │ 220.7 MB │ │ Germany │ 174.4 MB │ │ UnitedKingdom │ 104.4 MB │ │ ... │ ... │ └────────────────────────┴──────────┘ Total map data: 1.28 GB Licenses (3) Renault_Dacia_Global_Config_update.lyc 472 B ✓ Other content: speedcam: 9, poi: 28, voice: 67
$ medianav-toolbox catalog Dealership POI 2012 Q1 61811 ✓ purchased Map of Europe 14.4 62038 Map of France 14.4 121256 Map of United Kingdom and Ireland 14.4 62122 Map of Western Europe 14.4 123788 ... (38 items total)
$ medianav-toolbox sync --dry-run Connecting... Fetching content tree... Selecting 31 items... Selected Content ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓ ┃ Content ┃ Size ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩ │ France │ 715.0 MB │ │ Germany │ 529.7 MB │ │ United Kingdom │ 487.8 MB │ │ ... │ ... │ └───────────────────────────┴───────────┘ Total download: 6.10 GB
$ medianav-toolbox sync -c "United Kingdom" Connecting... Selecting 1 items... Total download: 487.8 MB ✓ Selection confirmed
$ medianav-toolbox licenses --install RenaultDealers_Pack.lyc 440 B ✓ installed
## Supported Devices
Currently targets **Dacia MediaNav Evolution** head units (model: `DaciaAutomotiveDeviceCY20_ULC4dot5`). The same NaviExtras API is used by Renault, Opel, Nissan, and other brands with NNG-based navigation.
## Development
```bash
# Run tests
pytest tests/ -v
# Format
black medianav_toolbox/ tests/
isort medianav_toolbox/ tests/
# Integration tests (requires .env credentials + USB drive image)
pytest tests/integration/ -v
medianav_toolbox/
├── api/
│ ├── boot.py # Service URL discovery
│ ├── client.py # HTTP client with retry
│ └── register.py # Device registration + delegator
├── catalog.py # HTML catalog + content tree parsers
├── cli.py # Click CLI (detect, login, catalog, updates, register)
├── config.py # Brand defaults from plugin.dll
├── content.py # Content selection + size estimation
├── crypto.py # SnakeOil xorshift128 cipher
├── device.py # USB drive detection, device.nng parsing
├── download.py # Download manager with cache + MD5 verify
├── fingerprint.py # Device fingerprint encoding
├── igo_parser.py # igo-binary response parser
├── igo_serializer.py # Credential block encoder
├── installer.py # USB content writer (.stm, .lyc, checksums)
├── models.py # Data classes
├── protocol.py # Wire protocol envelope (header + SnakeOil)
├── session.py # Full session flow orchestration
├── swid.py # SWID generation (MD5 + Crockford base32)
├── wire_codec.py # Request body encoder
└── wire_message.py # Structured wire message decode/encode
The NaviExtras API uses a custom binary wire protocol over HTTPS:
Standard requests (login, fingerprint, register):
[16B header] [SnakeOil(query, Code)] [SnakeOil(body, Secret)]
Delegated requests (senddevicestatus):
[16B header] [1B prefix] [SnakeOil(query, Secret)] [SnakeOil(body, Secret)]
Each SnakeOil call resets the PRNG independently. The session key is creds.secret
(toolbox Secret from registration). The body is standard plaintext format.
See docs/chain-encryption.md for the complete payload construction recipe with test vectors.
Full session flow:
1. Boot → service URLs (RANDOM mode)
2. Register → toolbox credentials (RANDOM mode, cached)
3. Login → JSESSIONID (DEVICE mode)
4. Fingerprint → 200 (DEVICE mode)
5. Delegator → head unit credentials (DEVICE mode)
6. DeviceStatus → 200 (delegated, session_key = creds.secret)
7. Web login → authenticated session (HTTP form POST)
8. Catalog → content tree + sizes (HTTP GET/POST)
See docs/reverse-engineering.md for full protocol documentation.
The NNG/iGO proprietary map format has been fully reverse-engineered. This is the first public decode of this format.
Convert OpenStreetMap data directly into NNG .fbl map files:
# Download OSM data for an area
curl -o monaco.osm --data-urlencode \
'data=[out:xml];way["highway"](43.72,7.41,43.75,7.44);out body;>;out skel qt;' \
'https://overpass-api.de/api/interpreter'
# Convert to FBL map file (no template needed)
python tools/maps/osm_to_fbl.py monaco.osm \
--bbox 7.409,43.536,7.631,43.752 --country MON -o Monaco_osm.fblThe generated FBL file is:
- Fully encrypted (XOR with 4096-byte key)
- Valid SET container with correct header, bbox, section table
- Road data split into sections 4/5/8 (main/secondary/tertiary)
- Verified: the DLL's graph builder accepts the output
Dependencies: Python + numpy. No template file, no Unicorn, no DLL needed.
24 standalone tools in tools/maps/ for decrypting, parsing, and analysing NNG map files.
| Tool | Description |
|---|---|
| osm_to_fbl.py | Convert OSM data → FBL map file |
| fbl_builder.py | Build FBL from scratch (no template) |
| nng_decoder.py | Decode FBL sections into records (pure Python) |
| fbl_parse.py | Extract coordinates from FBL files |
| fbl_road_class.py | Extract road classifications |
| fbl_to_geojson.py | Export all coordinates as GeoJSON |
| fbl_info.py | Show metadata (country, version, bbox) |
| fbl_validate.py | Cross-validate against OpenStreetMap |
| fbl_segments.py | Extract road segment boundaries |
| fbl_road_network.py | Complete road network export |
| fbl_replace_section.py | Replace sections in existing FBL |
| decrypt_fbl.py | Remove XOR encryption layer |
| spc_to_csv.py | Speed cameras → CSV (1,404 cameras, 21 countries) |
| poi_to_geojson.py | POI extraction with category names |
| hnr_info.py | HNR routing data analysis |
| hnr_fbl_link.py | Link HNR tiles to countries |
| lyc_decrypt.py | Decrypt license files |
| nng_varint.py | Varint decoder library |
| curves_to_geojson.py | Curve point extraction |
| junctions_to_geojson.py | Junction coordinates |
| segments_to_csv.py | Segment metadata |
| map_overview.py | Multi-country overview |
| nng_emulator.py | Unicorn DLL emulation framework |
| nng_decoder_python.py | Pure Python section decoder (67-74% accuracy) |
Full specification in docs/mapformat.md (1,842 lines):
- XOR encryption (4096-byte repeating key)
- SET container format (magic, version, sections, metadata)
- UTF-8-like varint encoding
- Regex-like pattern language for section data
- Road class system (value 92 + DLL lookup table)
- Packed bitstream coordinate encoding
- HNR routing format (256-byte tiles, A/B classification)
- Speed camera records (12-byte: lon, lat, flags, speed, type)
- POI name encoding (byte×2)
- LYC license decryption (RSA + XOR-CBC)
The 67 voice files on the head unit are not audio recordings — they're Lua script
bundles (Voice_Eng-uk-f3-lua.zip) that drive the iGO TTS engine. They're stored as
plain .zip files with no encryption or license requirement. In theory, custom voices
could be created by writing Lua scripts following the same API. See tools/voice/ for
exploration tools.
The dealership POI files (userdata/POI/*.zip) are plain zipped KML/CSV data with no
encryption. The .lyc license is only needed for the update mechanism. Custom POI
datasets could potentially be packaged in the same format.
Only map updates require purchased licenses (£49–£129 per region). Everything else is either pre-installed with the factory license or free:
| Content | Protection | Format |
|---|---|---|
| Maps (1.3 GB) | RSA-signed .lyc license per region |
.fbl binary |
| POI, speed cameras, TMC | Factory .lyc (pre-installed) |
.poi, .spc, .tmc |
| Voice (191 MB) | None — no license needed | Lua scripts in .zip |
| Language packs (4 MB) | Separate free .lyc |
.zip |
| Global config | Separate free .lyc |
.zip |
| Dealership POI (7 MB) | Free .lyc per SWID |
KML/CSV in .zip |
See docs/license-system.md for RSA key details and the full license format specification.
MIT