Repository files navigation

Firmware - by GulfCoastMesh Mobile

Custom firmware for MeshCore running on ESP32 boards.

🔗 "Give me the sales pitch, why do I need this?"

This project layers its changes onto a fresh copy of the upstream MeshCore source instead of maintaining a separate long-term fork. Each build starts with the latest upstream release: each mod's own source files are copied in, then a small set of patches edits the upstream files that need to call them. That keeps the project current without slowly drifting out of sync with MeshCore.

The MeshCore source code itself is not stored in this repository. Instead, this repo contains the patches, board-specific configuration, and the GitHub Actions workflow that puts everything together and publishes the builds.

Available Mods

Mods add features or changes to the standard MeshCore firmware. Each mod can ship owned source, integration declarations, upstream patches, board configuration, and documentation.

ModDescriptionMain Features
hotspot-otaAdds remote firmware updates over WiFi ( or cellular hotspot) and automatic rollback protection. A device can connect to an existing WiFi network, download a firmware image, verify it, and install it without needing to be onsite with the node.Remote OTA updates, power control of external cell modems, firmware SHA-256 verification, firmware authenticity checks, OTA slot management, automatic rollback / recovery after failed updates, automatic clock sync via NTP whenever WiFi is joined, remote updates through MeshCore CLI commands, downloads that run in the background so the node keeps repeating, and an update in progress that can be cancelled
timing-safetySmall fixes for how the firmware tracks time. Keeps timers working correctly on devices that run for many weeks, and stops "time since last heard from" numbers from showing garbage right after a reboot.Long-uptime timer fix, safer elapsed-time math across reboots
power-guardKeeps a bad situation from becoming an unrecoverable one, and puts the battery under its own management. Brownouts happen -- a flat pack, a cold morning, a cloudy week. Left alone, a node that browns out reboots straight into a loop that burns whatever charge is left and ends in a trip up the tower. This hibernates before it gets there, retries on a widening schedule, and comes back by itself once the battery does. Beyond the standard powersaving on / off it adds powersaving auto, which saves power only when the battery says to, and powersaving safe, the brownout failsafe. It also stops a mistyped poweroff from ending a node permanently.Hibernation before the bootloop threshold, automatic recovery, power saving that engages only when it's needed, thresholds set over serial or the mesh and kept across reboots, poweroff requires a wake time and is refused over the mesh

More information about each mod can be found in its own README under mods/<name>/.

Web-Based Flasher

You can use the ⚡️web-based flasher to flash a supported devices directly from your browser over USB.

The flasher requires Chrome, Edge, or Opera because it uses Web Serial. No additional software is needed.

It automatically uses the most recently built firmware for the board and variant you select.

This is not the official MeshCore flasher. It was built specifically for the custom firmware releases in this project.

Some mods may add extra options or requirements for a traditional flasher. Check the README for the specific mod if you need more information. For example, hotspot-ota changes how images are assigned to a device's OTA slots to support auto-recovery — see that mod's README for details.

Supported Boards

* more boards are on the way - " lookin' at you Grumpy "

VariantBoardUpstream TagRelease Asset
RepeaterHeltec V4repeater-v*heltec_v4_rep_mobmesh-vX.Y.Z.bin
Room ServerHeltec V4room-server-v*heltec_v4_room_mobmesh-vX.Y.Z.bin
RepeaterXiao ESP32-C3repeater-v*xiao_c3_rep_mobmesh-vX.Y.Z.bin
Room ServerXiao ESP32-C3room-server-v*xiao_c3_room_mobmesh-vX.Y.Z.bin

Each also ships a -merged.bin alongside it: the same firmware plus the bootloader, partition table and otadata in one file, written at offset 0 to a blank board. The plain .bin is the app alone, for an OTA slot or an update over an existing install.

Each Variant/Board pair uses its own release tag, so they are all built and released independently even when they share an upstream tag sequence (e.g. both boards' Repeater builds track repeater-v*).

build-targets.yaml at the repo root is the single source of truth for roles, release channels, and which (board, role) combinations get built with which mods. The CI matrix is generated from it, not hand-maintained. Adding support for another board is normally just adding entries there plus a variants/<board>/overrides.yaml file; the resolver rejects a mod when the board does not satisfy its required capabilities.

How It Works

Every morning a GitHub Actions run checks upstream MeshCore for new release tags, one per variant.

When it finds one:

  1. Clone upstream at that tag.
  2. Check the plan — every patch's dependencies come first, and every board can actually do what its mods ask of it.
  3. Copy in each mod's own source files.
  4. Generate the glue that wires those mods into upstream.
  5. Apply the patches, testing each one against the source before it goes in.
  6. Build.
  7. Stamp each build so the modifications it includes are identifiable in the binary itself.
  8. Boot it under emulation and confirm it comes up, on the boards set up for that.

It is pass or fail, with no middle. Every patch has to apply cleanly, the stamped image has to verify, and it has to boot. Miss any one of those and that build is dead and an issue is opened naming what broke. There is no partial build and no "close enough."

Usually the news arrives earlier than that. patch-drift-canary runs the same applicability check every day against upstream's development branches, so drift tends to show up before there is a release to break.

The flasher configures itself. After a successful build, pages/flasher/auto_boards.json is regenerated from the board overrides, upstream's board information, and the actual partitions.bin the build produced. Nothing about it is hand-maintained.

The flasher waits for all of them. It updates only after every board and variant has succeeded, so a half-finished matrix never puts a broken option in front of someone flashing a device.

The published .bin carries its own SHA-256 and its build identity inside the image, so there is no separate checksum file to keep in step with it.

Builds can also be started by hand from the Actions tab, against a specific upstream ref or a single variant instead of the whole matrix.

Releases

Releases are named using the variant and the upstream tag they were built from.

For example:

Repeater v1.16.0 - mobmesh

Each release includes:

  • <asset-basename>-vX.Y.Z.bin — the app image, for an OTA slot or an update over an existing install
  • <asset-basename>-vX.Y.Z-merged.bin — the same firmware plus bootloader, partition table and otadata, written at offset 0 to a blank board

The release notes come directly from the upstream MeshCore release for that tag.

You can flash the .bin file the same way you would flash an official MeshCore release. You can also use the web-based flasher provided by this project.

Requirements

You need an ESP32 board that is already supported by MeshCore and has a matching variants/<board>/overrides.yaml file in this repository.

Some mods may also require additional hardware -or- manual configuration overrides due to RAM and storage limitations.

For example, hotspot-ota requires an external power switch to control an external cellular hotspot. Check the README for the mod you are using for the wiring and hardware requirements.

About

Custom firmware for MeshCore by Mobmesh a member of GulfCoastMesh

About

custom firmware for MeshCore by GulfCoastMesh - Mobile, AL

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Firmware - by GulfCoastMesh Mobile

Custom firmware for MeshCore running on ESP32 boards.

🔗 "Give me the sales pitch, why do I need this?"

This project layers its changes onto a fresh copy of the upstream MeshCore source instead of maintaining a separate long-term fork. Each build starts with the latest upstream release: each mod's own source files are copied in, then a small set of patches edits the upstream files that need to call them. That keeps the project current without slowly drifting out of sync with MeshCore.

The MeshCore source code itself is not stored in this repository. Instead, this repo contains the patches, board-specific configuration, and the GitHub Actions workflow that puts everything together and publishes the builds.

Available Mods

Mods add features or changes to the standard MeshCore firmware. Each mod can ship owned source, integration declarations, upstream patches, board configuration, and documentation.

ModDescriptionMain Features
hotspot-otaAdds remote firmware updates over WiFi ( or cellular hotspot) and automatic rollback protection. A device can connect to an existing WiFi network, download a firmware image, verify it, and install it without needing to be onsite with the node.Remote OTA updates, power control of external cell modems, firmware SHA-256 verification, firmware authenticity checks, OTA slot management, automatic rollback / recovery after failed updates, automatic clock sync via NTP whenever WiFi is joined, remote updates through MeshCore CLI commands, downloads that run in the background so the node keeps repeating, and an update in progress that can be cancelled
timing-safetySmall fixes for how the firmware tracks time. Keeps timers working correctly on devices that run for many weeks, and stops "time since last heard from" numbers from showing garbage right after a reboot.Long-uptime timer fix, safer elapsed-time math across reboots
power-guardKeeps a bad situation from becoming an unrecoverable one, and puts the battery under its own management. Brownouts happen -- a flat pack, a cold morning, a cloudy week. Left alone, a node that browns out reboots straight into a loop that burns whatever charge is left and ends in a trip up the tower. This hibernates before it gets there, retries on a widening schedule, and comes back by itself once the battery does. Beyond the standard powersaving on / off it adds powersaving auto, which saves power only when the battery says to, and powersaving safe, the brownout failsafe. It also stops a mistyped poweroff from ending a node permanently.Hibernation before the bootloop threshold, automatic recovery, power saving that engages only when it's needed, thresholds set over serial or the mesh and kept across reboots, poweroff requires a wake time and is refused over the mesh

More information about each mod can be found in its own README under mods/<name>/.

Web-Based Flasher

You can use the ⚡️web-based flasher to flash a supported devices directly from your browser over USB.

The flasher requires Chrome, Edge, or Opera because it uses Web Serial. No additional software is needed.

It automatically uses the most recently built firmware for the board and variant you select.

This is not the official MeshCore flasher. It was built specifically for the custom firmware releases in this project.

Some mods may add extra options or requirements for a traditional flasher. Check the README for the specific mod if you need more information. For example, hotspot-ota changes how images are assigned to a device's OTA slots to support auto-recovery — see that mod's README for details.

Supported Boards

* more boards are on the way - " lookin' at you Grumpy "

VariantBoardUpstream TagRelease Asset
RepeaterHeltec V4repeater-v*heltec_v4_rep_mobmesh-vX.Y.Z.bin
Room ServerHeltec V4room-server-v*heltec_v4_room_mobmesh-vX.Y.Z.bin
RepeaterXiao ESP32-C3repeater-v*xiao_c3_rep_mobmesh-vX.Y.Z.bin
Room ServerXiao ESP32-C3room-server-v*xiao_c3_room_mobmesh-vX.Y.Z.bin

Each also ships a -merged.bin alongside it: the same firmware plus the bootloader, partition table and otadata in one file, written at offset 0 to a blank board. The plain .bin is the app alone, for an OTA slot or an update over an existing install.

Each Variant/Board pair uses its own release tag, so they are all built and released independently even when they share an upstream tag sequence (e.g. both boards' Repeater builds track repeater-v*).

build-targets.yaml at the repo root is the single source of truth for roles, release channels, and which (board, role) combinations get built with which mods. The CI matrix is generated from it, not hand-maintained. Adding support for another board is normally just adding entries there plus a variants/<board>/overrides.yaml file; the resolver rejects a mod when the board does not satisfy its required capabilities.

How It Works

Every morning a GitHub Actions run checks upstream MeshCore for new release tags, one per variant.

When it finds one:

  1. Clone upstream at that tag.
  2. Check the plan — every patch's dependencies come first, and every board can actually do what its mods ask of it.
  3. Copy in each mod's own source files.
  4. Generate the glue that wires those mods into upstream.
  5. Apply the patches, testing each one against the source before it goes in.
  6. Build.
  7. Stamp each build so the modifications it includes are identifiable in the binary itself.
  8. Boot it under emulation and confirm it comes up, on the boards set up for that.

It is pass or fail, with no middle. Every patch has to apply cleanly, the stamped image has to verify, and it has to boot. Miss any one of those and that build is dead and an issue is opened naming what broke. There is no partial build and no "close enough."

Usually the news arrives earlier than that. patch-drift-canary runs the same applicability check every day against upstream's development branches, so drift tends to show up before there is a release to break.

The flasher configures itself. After a successful build, pages/flasher/auto_boards.json is regenerated from the board overrides, upstream's board information, and the actual partitions.bin the build produced. Nothing about it is hand-maintained.

The flasher waits for all of them. It updates only after every board and variant has succeeded, so a half-finished matrix never puts a broken option in front of someone flashing a device.

The published .bin carries its own SHA-256 and its build identity inside the image, so there is no separate checksum file to keep in step with it.

Builds can also be started by hand from the Actions tab, against a specific upstream ref or a single variant instead of the whole matrix.

Releases

Releases are named using the variant and the upstream tag they were built from.

For example:

Repeater v1.16.0 - mobmesh

Each release includes:

  • <asset-basename>-vX.Y.Z.bin — the app image, for an OTA slot or an update over an existing install
  • <asset-basename>-vX.Y.Z-merged.bin — the same firmware plus bootloader, partition table and otadata, written at offset 0 to a blank board

The release notes come directly from the upstream MeshCore release for that tag.

You can flash the .bin file the same way you would flash an official MeshCore release. You can also use the web-based flasher provided by this project.

Requirements

You need an ESP32 board that is already supported by MeshCore and has a matching variants/<board>/overrides.yaml file in this repository.

Some mods may also require additional hardware -or- manual configuration overrides due to RAM and storage limitations.

For example, hotspot-ota requires an external power switch to control an external cellular hotspot. Check the README for the mod you are using for the wiring and hardware requirements.

About

Custom firmware for MeshCore by Mobmesh a member of GulfCoastMesh

About

custom firmware for MeshCore by GulfCoastMesh - Mobile, AL

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Firmware - by GulfCoastMesh Mobile

Custom firmware for MeshCore running on ESP32 boards.

🔗 "Give me the sales pitch, why do I need this?"

This project layers its changes onto a fresh copy of the upstream MeshCore source instead of maintaining a separate long-term fork. Each build starts with the latest upstream release: each mod's own source files are copied in, then a small set of patches edits the upstream files that need to call them. That keeps the project current without slowly drifting out of sync with MeshCore.

The MeshCore source code itself is not stored in this repository. Instead, this repo contains the patches, board-specific configuration, and the GitHub Actions workflow that puts everything together and publishes the builds.

Available Mods

Mods add features or changes to the standard MeshCore firmware. Each mod can ship owned source, integration declarations, upstream patches, board configuration, and documentation.

ModDescriptionMain Features
hotspot-otaAdds remote firmware updates over WiFi ( or cellular hotspot) and automatic rollback protection. A device can connect to an existing WiFi network, download a firmware image, verify it, and install it without needing to be onsite with the node.Remote OTA updates, power control of external cell modems, firmware SHA-256 verification, firmware authenticity checks, OTA slot management, automatic rollback / recovery after failed updates, automatic clock sync via NTP whenever WiFi is joined, remote updates through MeshCore CLI commands, downloads that run in the background so the node keeps repeating, and an update in progress that can be cancelled
timing-safetySmall fixes for how the firmware tracks time. Keeps timers working correctly on devices that run for many weeks, and stops "time since last heard from" numbers from showing garbage right after a reboot.Long-uptime timer fix, safer elapsed-time math across reboots
power-guardKeeps a bad situation from becoming an unrecoverable one, and puts the battery under its own management. Brownouts happen -- a flat pack, a cold morning, a cloudy week. Left alone, a node that browns out reboots straight into a loop that burns whatever charge is left and ends in a trip up the tower. This hibernates before it gets there, retries on a widening schedule, and comes back by itself once the battery does. Beyond the standard powersaving on / off it adds powersaving auto, which saves power only when the battery says to, and powersaving safe, the brownout failsafe. It also stops a mistyped poweroff from ending a node permanently.Hibernation before the bootloop threshold, automatic recovery, power saving that engages only when it's needed, thresholds set over serial or the mesh and kept across reboots, poweroff requires a wake time and is refused over the mesh

More information about each mod can be found in its own README under mods/<name>/.

Web-Based Flasher

You can use the ⚡️web-based flasher to flash a supported devices directly from your browser over USB.

The flasher requires Chrome, Edge, or Opera because it uses Web Serial. No additional software is needed.

It automatically uses the most recently built firmware for the board and variant you select.

This is not the official MeshCore flasher. It was built specifically for the custom firmware releases in this project.

Some mods may add extra options or requirements for a traditional flasher. Check the README for the specific mod if you need more information. For example, hotspot-ota changes how images are assigned to a device's OTA slots to support auto-recovery — see that mod's README for details.

Supported Boards

* more boards are on the way - " lookin' at you Grumpy "

VariantBoardUpstream TagRelease Asset
RepeaterHeltec V4repeater-v*heltec_v4_rep_mobmesh-vX.Y.Z.bin
Room ServerHeltec V4room-server-v*heltec_v4_room_mobmesh-vX.Y.Z.bin
RepeaterXiao ESP32-C3repeater-v*xiao_c3_rep_mobmesh-vX.Y.Z.bin
Room ServerXiao ESP32-C3room-server-v*xiao_c3_room_mobmesh-vX.Y.Z.bin

Each also ships a -merged.bin alongside it: the same firmware plus the bootloader, partition table and otadata in one file, written at offset 0 to a blank board. The plain .bin is the app alone, for an OTA slot or an update over an existing install.

Each Variant/Board pair uses its own release tag, so they are all built and released independently even when they share an upstream tag sequence (e.g. both boards' Repeater builds track repeater-v*).

build-targets.yaml at the repo root is the single source of truth for roles, release channels, and which (board, role) combinations get built with which mods. The CI matrix is generated from it, not hand-maintained. Adding support for another board is normally just adding entries there plus a variants/<board>/overrides.yaml file; the resolver rejects a mod when the board does not satisfy its required capabilities.

How It Works

Every morning a GitHub Actions run checks upstream MeshCore for new release tags, one per variant.

When it finds one:

  1. Clone upstream at that tag.
  2. Check the plan — every patch's dependencies come first, and every board can actually do what its mods ask of it.
  3. Copy in each mod's own source files.
  4. Generate the glue that wires those mods into upstream.
  5. Apply the patches, testing each one against the source before it goes in.
  6. Build.
  7. Stamp each build so the modifications it includes are identifiable in the binary itself.
  8. Boot it under emulation and confirm it comes up, on the boards set up for that.

It is pass or fail, with no middle. Every patch has to apply cleanly, the stamped image has to verify, and it has to boot. Miss any one of those and that build is dead and an issue is opened naming what broke. There is no partial build and no "close enough."

Usually the news arrives earlier than that. patch-drift-canary runs the same applicability check every day against upstream's development branches, so drift tends to show up before there is a release to break.

The flasher configures itself. After a successful build, pages/flasher/auto_boards.json is regenerated from the board overrides, upstream's board information, and the actual partitions.bin the build produced. Nothing about it is hand-maintained.

The flasher waits for all of them. It updates only after every board and variant has succeeded, so a half-finished matrix never puts a broken option in front of someone flashing a device.

The published .bin carries its own SHA-256 and its build identity inside the image, so there is no separate checksum file to keep in step with it.

Builds can also be started by hand from the Actions tab, against a specific upstream ref or a single variant instead of the whole matrix.

Releases

Releases are named using the variant and the upstream tag they were built from.

For example:

Repeater v1.16.0 - mobmesh

Each release includes:

  • <asset-basename>-vX.Y.Z.bin — the app image, for an OTA slot or an update over an existing install
  • <asset-basename>-vX.Y.Z-merged.bin — the same firmware plus bootloader, partition table and otadata, written at offset 0 to a blank board

The release notes come directly from the upstream MeshCore release for that tag.

You can flash the .bin file the same way you would flash an official MeshCore release. You can also use the web-based flasher provided by this project.

Requirements

You need an ESP32 board that is already supported by MeshCore and has a matching variants/<board>/overrides.yaml file in this repository.

Some mods may also require additional hardware -or- manual configuration overrides due to RAM and storage limitations.

For example, hotspot-ota requires an external power switch to control an external cellular hotspot. Check the README for the mod you are using for the wiring and hardware requirements.

About

Custom firmware for MeshCore by Mobmesh a member of GulfCoastMesh

About

custom firmware for MeshCore by GulfCoastMesh - Mobile, AL

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Firmware - by GulfCoastMesh Mobile

Custom firmware for MeshCore running on ESP32 boards.

🔗 "Give me the sales pitch, why do I need this?"

This project layers its changes onto a fresh copy of the upstream MeshCore source instead of maintaining a separate long-term fork. Each build starts with the latest upstream release: each mod's own source files are copied in, then a small set of patches edits the upstream files that need to call them. That keeps the project current without slowly drifting out of sync with MeshCore.

The MeshCore source code itself is not stored in this repository. Instead, this repo contains the patches, board-specific configuration, and the GitHub Actions workflow that puts everything together and publishes the builds.

Available Mods

Mods add features or changes to the standard MeshCore firmware. Each mod can ship owned source, integration declarations, upstream patches, board configuration, and documentation.

ModDescriptionMain Features
hotspot-otaAdds remote firmware updates over WiFi ( or cellular hotspot) and automatic rollback protection. A device can connect to an existing WiFi network, download a firmware image, verify it, and install it without needing to be onsite with the node.Remote OTA updates, power control of external cell modems, firmware SHA-256 verification, firmware authenticity checks, OTA slot management, automatic rollback / recovery after failed updates, automatic clock sync via NTP whenever WiFi is joined, remote updates through MeshCore CLI commands, downloads that run in the background so the node keeps repeating, and an update in progress that can be cancelled
timing-safetySmall fixes for how the firmware tracks time. Keeps timers working correctly on devices that run for many weeks, and stops "time since last heard from" numbers from showing garbage right after a reboot.Long-uptime timer fix, safer elapsed-time math across reboots
power-guardKeeps a bad situation from becoming an unrecoverable one, and puts the battery under its own management. Brownouts happen -- a flat pack, a cold morning, a cloudy week. Left alone, a node that browns out reboots straight into a loop that burns whatever charge is left and ends in a trip up the tower. This hibernates before it gets there, retries on a widening schedule, and comes back by itself once the battery does. Beyond the standard powersaving on / off it adds powersaving auto, which saves power only when the battery says to, and powersaving safe, the brownout failsafe. It also stops a mistyped poweroff from ending a node permanently.Hibernation before the bootloop threshold, automatic recovery, power saving that engages only when it's needed, thresholds set over serial or the mesh and kept across reboots, poweroff requires a wake time and is refused over the mesh

More information about each mod can be found in its own README under mods/<name>/.

Web-Based Flasher

You can use the ⚡️web-based flasher to flash a supported devices directly from your browser over USB.

The flasher requires Chrome, Edge, or Opera because it uses Web Serial. No additional software is needed.

It automatically uses the most recently built firmware for the board and variant you select.

This is not the official MeshCore flasher. It was built specifically for the custom firmware releases in this project.

Some mods may add extra options or requirements for a traditional flasher. Check the README for the specific mod if you need more information. For example, hotspot-ota changes how images are assigned to a device's OTA slots to support auto-recovery — see that mod's README for details.

Supported Boards

* more boards are on the way - " lookin' at you Grumpy "

VariantBoardUpstream TagRelease Asset
RepeaterHeltec V4repeater-v*heltec_v4_rep_mobmesh-vX.Y.Z.bin
Room ServerHeltec V4room-server-v*heltec_v4_room_mobmesh-vX.Y.Z.bin
RepeaterXiao ESP32-C3repeater-v*xiao_c3_rep_mobmesh-vX.Y.Z.bin
Room ServerXiao ESP32-C3room-server-v*xiao_c3_room_mobmesh-vX.Y.Z.bin

Each also ships a -merged.bin alongside it: the same firmware plus the bootloader, partition table and otadata in one file, written at offset 0 to a blank board. The plain .bin is the app alone, for an OTA slot or an update over an existing install.

Each Variant/Board pair uses its own release tag, so they are all built and released independently even when they share an upstream tag sequence (e.g. both boards' Repeater builds track repeater-v*).

build-targets.yaml at the repo root is the single source of truth for roles, release channels, and which (board, role) combinations get built with which mods. The CI matrix is generated from it, not hand-maintained. Adding support for another board is normally just adding entries there plus a variants/<board>/overrides.yaml file; the resolver rejects a mod when the board does not satisfy its required capabilities.

How It Works

Every morning a GitHub Actions run checks upstream MeshCore for new release tags, one per variant.

When it finds one:

  1. Clone upstream at that tag.
  2. Check the plan — every patch's dependencies come first, and every board can actually do what its mods ask of it.
  3. Copy in each mod's own source files.
  4. Generate the glue that wires those mods into upstream.
  5. Apply the patches, testing each one against the source before it goes in.
  6. Build.
  7. Stamp each build so the modifications it includes are identifiable in the binary itself.
  8. Boot it under emulation and confirm it comes up, on the boards set up for that.

It is pass or fail, with no middle. Every patch has to apply cleanly, the stamped image has to verify, and it has to boot. Miss any one of those and that build is dead and an issue is opened naming what broke. There is no partial build and no "close enough."

Usually the news arrives earlier than that. patch-drift-canary runs the same applicability check every day against upstream's development branches, so drift tends to show up before there is a release to break.

The flasher configures itself. After a successful build, pages/flasher/auto_boards.json is regenerated from the board overrides, upstream's board information, and the actual partitions.bin the build produced. Nothing about it is hand-maintained.

The flasher waits for all of them. It updates only after every board and variant has succeeded, so a half-finished matrix never puts a broken option in front of someone flashing a device.

The published .bin carries its own SHA-256 and its build identity inside the image, so there is no separate checksum file to keep in step with it.

Builds can also be started by hand from the Actions tab, against a specific upstream ref or a single variant instead of the whole matrix.

Releases

Releases are named using the variant and the upstream tag they were built from.

For example:

Repeater v1.16.0 - mobmesh

Each release includes:

  • <asset-basename>-vX.Y.Z.bin — the app image, for an OTA slot or an update over an existing install
  • <asset-basename>-vX.Y.Z-merged.bin — the same firmware plus bootloader, partition table and otadata, written at offset 0 to a blank board

The release notes come directly from the upstream MeshCore release for that tag.

You can flash the .bin file the same way you would flash an official MeshCore release. You can also use the web-based flasher provided by this project.

Requirements

You need an ESP32 board that is already supported by MeshCore and has a matching variants/<board>/overrides.yaml file in this repository.

Some mods may also require additional hardware -or- manual configuration overrides due to RAM and storage limitations.

For example, hotspot-ota requires an external power switch to control an external cellular hotspot. Check the README for the mod you are using for the wiring and hardware requirements.

About

Custom firmware for MeshCore by Mobmesh a member of GulfCoastMesh

About

custom firmware for MeshCore by GulfCoastMesh - Mobile, AL

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Firmware - by GulfCoastMesh Mobile

Custom firmware for MeshCore running on ESP32 boards.

🔗 "Give me the sales pitch, why do I need this?"

This project layers its changes onto a fresh copy of the upstream MeshCore source instead of maintaining a separate long-term fork. Each build starts with the latest upstream release: each mod's own source files are copied in, then a small set of patches edits the upstream files that need to call them. That keeps the project current without slowly drifting out of sync with MeshCore.

The MeshCore source code itself is not stored in this repository. Instead, this repo contains the patches, board-specific configuration, and the GitHub Actions workflow that puts everything together and publishes the builds.

Available Mods

Mods add features or changes to the standard MeshCore firmware. Each mod can ship owned source, integration declarations, upstream patches, board configuration, and documentation.

ModDescriptionMain Features
hotspot-otaAdds remote firmware updates over WiFi ( or cellular hotspot) and automatic rollback protection. A device can connect to an existing WiFi network, download a firmware image, verify it, and install it without needing to be onsite with the node.Remote OTA updates, power control of external cell modems, firmware SHA-256 verification, firmware authenticity checks, OTA slot management, automatic rollback / recovery after failed updates, automatic clock sync via NTP whenever WiFi is joined, remote updates through MeshCore CLI commands, downloads that run in the background so the node keeps repeating, and an update in progress that can be cancelled
timing-safetySmall fixes for how the firmware tracks time. Keeps timers working correctly on devices that run for many weeks, and stops "time since last heard from" numbers from showing garbage right after a reboot.Long-uptime timer fix, safer elapsed-time math across reboots
power-guardKeeps a bad situation from becoming an unrecoverable one, and puts the battery under its own management. Brownouts happen -- a flat pack, a cold morning, a cloudy week. Left alone, a node that browns out reboots straight into a loop that burns whatever charge is left and ends in a trip up the tower. This hibernates before it gets there, retries on a widening schedule, and comes back by itself once the battery does. Beyond the standard powersaving on / off it adds powersaving auto, which saves power only when the battery says to, and powersaving safe, the brownout failsafe. It also stops a mistyped poweroff from ending a node permanently.Hibernation before the bootloop threshold, automatic recovery, power saving that engages only when it's needed, thresholds set over serial or the mesh and kept across reboots, poweroff requires a wake time and is refused over the mesh

More information about each mod can be found in its own README under mods/<name>/.

Web-Based Flasher

You can use the ⚡️web-based flasher to flash a supported devices directly from your browser over USB.

The flasher requires Chrome, Edge, or Opera because it uses Web Serial. No additional software is needed.

It automatically uses the most recently built firmware for the board and variant you select.

This is not the official MeshCore flasher. It was built specifically for the custom firmware releases in this project.

Some mods may add extra options or requirements for a traditional flasher. Check the README for the specific mod if you need more information. For example, hotspot-ota changes how images are assigned to a device's OTA slots to support auto-recovery — see that mod's README for details.

Supported Boards

* more boards are on the way - " lookin' at you Grumpy "

VariantBoardUpstream TagRelease Asset
RepeaterHeltec V4repeater-v*heltec_v4_rep_mobmesh-vX.Y.Z.bin
Room ServerHeltec V4room-server-v*heltec_v4_room_mobmesh-vX.Y.Z.bin
RepeaterXiao ESP32-C3repeater-v*xiao_c3_rep_mobmesh-vX.Y.Z.bin
Room ServerXiao ESP32-C3room-server-v*xiao_c3_room_mobmesh-vX.Y.Z.bin

Each also ships a -merged.bin alongside it: the same firmware plus the bootloader, partition table and otadata in one file, written at offset 0 to a blank board. The plain .bin is the app alone, for an OTA slot or an update over an existing install.

Each Variant/Board pair uses its own release tag, so they are all built and released independently even when they share an upstream tag sequence (e.g. both boards' Repeater builds track repeater-v*).

build-targets.yaml at the repo root is the single source of truth for roles, release channels, and which (board, role) combinations get built with which mods. The CI matrix is generated from it, not hand-maintained. Adding support for another board is normally just adding entries there plus a variants/<board>/overrides.yaml file; the resolver rejects a mod when the board does not satisfy its required capabilities.

How It Works

Every morning a GitHub Actions run checks upstream MeshCore for new release tags, one per variant.

When it finds one:

  1. Clone upstream at that tag.
  2. Check the plan — every patch's dependencies come first, and every board can actually do what its mods ask of it.
  3. Copy in each mod's own source files.
  4. Generate the glue that wires those mods into upstream.
  5. Apply the patches, testing each one against the source before it goes in.
  6. Build.
  7. Stamp each build so the modifications it includes are identifiable in the binary itself.
  8. Boot it under emulation and confirm it comes up, on the boards set up for that.

It is pass or fail, with no middle. Every patch has to apply cleanly, the stamped image has to verify, and it has to boot. Miss any one of those and that build is dead and an issue is opened naming what broke. There is no partial build and no "close enough."

Usually the news arrives earlier than that. patch-drift-canary runs the same applicability check every day against upstream's development branches, so drift tends to show up before there is a release to break.

The flasher configures itself. After a successful build, pages/flasher/auto_boards.json is regenerated from the board overrides, upstream's board information, and the actual partitions.bin the build produced. Nothing about it is hand-maintained.

The flasher waits for all of them. It updates only after every board and variant has succeeded, so a half-finished matrix never puts a broken option in front of someone flashing a device.

The published .bin carries its own SHA-256 and its build identity inside the image, so there is no separate checksum file to keep in step with it.

Builds can also be started by hand from the Actions tab, against a specific upstream ref or a single variant instead of the whole matrix.

Releases

Releases are named using the variant and the upstream tag they were built from.

For example:

Repeater v1.16.0 - mobmesh

Each release includes:

  • <asset-basename>-vX.Y.Z.bin — the app image, for an OTA slot or an update over an existing install
  • <asset-basename>-vX.Y.Z-merged.bin — the same firmware plus bootloader, partition table and otadata, written at offset 0 to a blank board

The release notes come directly from the upstream MeshCore release for that tag.

You can flash the .bin file the same way you would flash an official MeshCore release. You can also use the web-based flasher provided by this project.

Requirements

You need an ESP32 board that is already supported by MeshCore and has a matching variants/<board>/overrides.yaml file in this repository.

Some mods may also require additional hardware -or- manual configuration overrides due to RAM and storage limitations.

For example, hotspot-ota requires an external power switch to control an external cellular hotspot. Check the README for the mod you are using for the wiring and hardware requirements.

About

Custom firmware for MeshCore by Mobmesh a member of GulfCoastMesh

About

custom firmware for MeshCore by GulfCoastMesh - Mobile, AL

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Firmware - by GulfCoastMesh Mobile

Custom firmware for MeshCore running on ESP32 boards.

🔗 "Give me the sales pitch, why do I need this?"

This project layers its changes onto a fresh copy of the upstream MeshCore source instead of maintaining a separate long-term fork. Each build starts with the latest upstream release: each mod's own source files are copied in, then a small set of patches edits the upstream files that need to call them. That keeps the project current without slowly drifting out of sync with MeshCore.

The MeshCore source code itself is not stored in this repository. Instead, this repo contains the patches, board-specific configuration, and the GitHub Actions workflow that puts everything together and publishes the builds.

Available Mods

Mods add features or changes to the standard MeshCore firmware. Each mod can ship owned source, integration declarations, upstream patches, board configuration, and documentation.

ModDescriptionMain Features
hotspot-otaAdds remote firmware updates over WiFi ( or cellular hotspot) and automatic rollback protection. A device can connect to an existing WiFi network, download a firmware image, verify it, and install it without needing to be onsite with the node.Remote OTA updates, power control of external cell modems, firmware SHA-256 verification, firmware authenticity checks, OTA slot management, automatic rollback / recovery after failed updates, automatic clock sync via NTP whenever WiFi is joined, remote updates through MeshCore CLI commands, downloads that run in the background so the node keeps repeating, and an update in progress that can be cancelled
timing-safetySmall fixes for how the firmware tracks time. Keeps timers working correctly on devices that run for many weeks, and stops "time since last heard from" numbers from showing garbage right after a reboot.Long-uptime timer fix, safer elapsed-time math across reboots
power-guardKeeps a bad situation from becoming an unrecoverable one, and puts the battery under its own management. Brownouts happen -- a flat pack, a cold morning, a cloudy week. Left alone, a node that browns out reboots straight into a loop that burns whatever charge is left and ends in a trip up the tower. This hibernates before it gets there, retries on a widening schedule, and comes back by itself once the battery does. Beyond the standard powersaving on / off it adds powersaving auto, which saves power only when the battery says to, and powersaving safe, the brownout failsafe. It also stops a mistyped poweroff from ending a node permanently.Hibernation before the bootloop threshold, automatic recovery, power saving that engages only when it's needed, thresholds set over serial or the mesh and kept across reboots, poweroff requires a wake time and is refused over the mesh

More information about each mod can be found in its own README under mods/<name>/.

Web-Based Flasher

You can use the ⚡️web-based flasher to flash a supported devices directly from your browser over USB.

The flasher requires Chrome, Edge, or Opera because it uses Web Serial. No additional software is needed.

It automatically uses the most recently built firmware for the board and variant you select.

This is not the official MeshCore flasher. It was built specifically for the custom firmware releases in this project.

Some mods may add extra options or requirements for a traditional flasher. Check the README for the specific mod if you need more information. For example, hotspot-ota changes how images are assigned to a device's OTA slots to support auto-recovery — see that mod's README for details.

Supported Boards

* more boards are on the way - " lookin' at you Grumpy "

VariantBoardUpstream TagRelease Asset
RepeaterHeltec V4repeater-v*heltec_v4_rep_mobmesh-vX.Y.Z.bin
Room ServerHeltec V4room-server-v*heltec_v4_room_mobmesh-vX.Y.Z.bin
RepeaterXiao ESP32-C3repeater-v*xiao_c3_rep_mobmesh-vX.Y.Z.bin
Room ServerXiao ESP32-C3room-server-v*xiao_c3_room_mobmesh-vX.Y.Z.bin

Each also ships a -merged.bin alongside it: the same firmware plus the bootloader, partition table and otadata in one file, written at offset 0 to a blank board. The plain .bin is the app alone, for an OTA slot or an update over an existing install.

Each Variant/Board pair uses its own release tag, so they are all built and released independently even when they share an upstream tag sequence (e.g. both boards' Repeater builds track repeater-v*).

build-targets.yaml at the repo root is the single source of truth for roles, release channels, and which (board, role) combinations get built with which mods. The CI matrix is generated from it, not hand-maintained. Adding support for another board is normally just adding entries there plus a variants/<board>/overrides.yaml file; the resolver rejects a mod when the board does not satisfy its required capabilities.

How It Works

Every morning a GitHub Actions run checks upstream MeshCore for new release tags, one per variant.

When it finds one:

  1. Clone upstream at that tag.
  2. Check the plan — every patch's dependencies come first, and every board can actually do what its mods ask of it.
  3. Copy in each mod's own source files.
  4. Generate the glue that wires those mods into upstream.
  5. Apply the patches, testing each one against the source before it goes in.
  6. Build.
  7. Stamp each build so the modifications it includes are identifiable in the binary itself.
  8. Boot it under emulation and confirm it comes up, on the boards set up for that.

It is pass or fail, with no middle. Every patch has to apply cleanly, the stamped image has to verify, and it has to boot. Miss any one of those and that build is dead and an issue is opened naming what broke. There is no partial build and no "close enough."

Usually the news arrives earlier than that. patch-drift-canary runs the same applicability check every day against upstream's development branches, so drift tends to show up before there is a release to break.

The flasher configures itself. After a successful build, pages/flasher/auto_boards.json is regenerated from the board overrides, upstream's board information, and the actual partitions.bin the build produced. Nothing about it is hand-maintained.

The flasher waits for all of them. It updates only after every board and variant has succeeded, so a half-finished matrix never puts a broken option in front of someone flashing a device.

The published .bin carries its own SHA-256 and its build identity inside the image, so there is no separate checksum file to keep in step with it.

Builds can also be started by hand from the Actions tab, against a specific upstream ref or a single variant instead of the whole matrix.

Releases

Releases are named using the variant and the upstream tag they were built from.

For example:

Repeater v1.16.0 - mobmesh

Each release includes:

  • <asset-basename>-vX.Y.Z.bin — the app image, for an OTA slot or an update over an existing install
  • <asset-basename>-vX.Y.Z-merged.bin — the same firmware plus bootloader, partition table and otadata, written at offset 0 to a blank board

The release notes come directly from the upstream MeshCore release for that tag.

You can flash the .bin file the same way you would flash an official MeshCore release. You can also use the web-based flasher provided by this project.

Requirements

You need an ESP32 board that is already supported by MeshCore and has a matching variants/<board>/overrides.yaml file in this repository.

Some mods may also require additional hardware -or- manual configuration overrides due to RAM and storage limitations.

For example, hotspot-ota requires an external power switch to control an external cellular hotspot. Check the README for the mod you are using for the wiring and hardware requirements.

About

Custom firmware for MeshCore by Mobmesh a member of GulfCoastMesh

About

custom firmware for MeshCore by GulfCoastMesh - Mobile, AL

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Firmware - by GulfCoastMesh Mobile

Custom firmware for MeshCore running on ESP32 boards.

🔗 "Give me the sales pitch, why do I need this?"

This project layers its changes onto a fresh copy of the upstream MeshCore source instead of maintaining a separate long-term fork. Each build starts with the latest upstream release: each mod's own source files are copied in, then a small set of patches edits the upstream files that need to call them. That keeps the project current without slowly drifting out of sync with MeshCore.

The MeshCore source code itself is not stored in this repository. Instead, this repo contains the patches, board-specific configuration, and the GitHub Actions workflow that puts everything together and publishes the builds.

Available Mods

Mods add features or changes to the standard MeshCore firmware. Each mod can ship owned source, integration declarations, upstream patches, board configuration, and documentation.

ModDescriptionMain Features
hotspot-otaAdds remote firmware updates over WiFi ( or cellular hotspot) and automatic rollback protection. A device can connect to an existing WiFi network, download a firmware image, verify it, and install it without needing to be onsite with the node.Remote OTA updates, power control of external cell modems, firmware SHA-256 verification, firmware authenticity checks, OTA slot management, automatic rollback / recovery after failed updates, automatic clock sync via NTP whenever WiFi is joined, remote updates through MeshCore CLI commands, downloads that run in the background so the node keeps repeating, and an update in progress that can be cancelled
timing-safetySmall fixes for how the firmware tracks time. Keeps timers working correctly on devices that run for many weeks, and stops "time since last heard from" numbers from showing garbage right after a reboot.Long-uptime timer fix, safer elapsed-time math across reboots
power-guardKeeps a bad situation from becoming an unrecoverable one, and puts the battery under its own management. Brownouts happen -- a flat pack, a cold morning, a cloudy week. Left alone, a node that browns out reboots straight into a loop that burns whatever charge is left and ends in a trip up the tower. This hibernates before it gets there, retries on a widening schedule, and comes back by itself once the battery does. Beyond the standard powersaving on / off it adds powersaving auto, which saves power only when the battery says to, and powersaving safe, the brownout failsafe. It also stops a mistyped poweroff from ending a node permanently.Hibernation before the bootloop threshold, automatic recovery, power saving that engages only when it's needed, thresholds set over serial or the mesh and kept across reboots, poweroff requires a wake time and is refused over the mesh

More information about each mod can be found in its own README under mods/<name>/.

Web-Based Flasher

You can use the ⚡️web-based flasher to flash a supported devices directly from your browser over USB.

The flasher requires Chrome, Edge, or Opera because it uses Web Serial. No additional software is needed.

It automatically uses the most recently built firmware for the board and variant you select.

This is not the official MeshCore flasher. It was built specifically for the custom firmware releases in this project.

Some mods may add extra options or requirements for a traditional flasher. Check the README for the specific mod if you need more information. For example, hotspot-ota changes how images are assigned to a device's OTA slots to support auto-recovery — see that mod's README for details.

Supported Boards

* more boards are on the way - " lookin' at you Grumpy "

VariantBoardUpstream TagRelease Asset
RepeaterHeltec V4repeater-v*heltec_v4_rep_mobmesh-vX.Y.Z.bin
Room ServerHeltec V4room-server-v*heltec_v4_room_mobmesh-vX.Y.Z.bin
RepeaterXiao ESP32-C3repeater-v*xiao_c3_rep_mobmesh-vX.Y.Z.bin
Room ServerXiao ESP32-C3room-server-v*xiao_c3_room_mobmesh-vX.Y.Z.bin

Each also ships a -merged.bin alongside it: the same firmware plus the bootloader, partition table and otadata in one file, written at offset 0 to a blank board. The plain .bin is the app alone, for an OTA slot or an update over an existing install.

Each Variant/Board pair uses its own release tag, so they are all built and released independently even when they share an upstream tag sequence (e.g. both boards' Repeater builds track repeater-v*).

build-targets.yaml at the repo root is the single source of truth for roles, release channels, and which (board, role) combinations get built with which mods. The CI matrix is generated from it, not hand-maintained. Adding support for another board is normally just adding entries there plus a variants/<board>/overrides.yaml file; the resolver rejects a mod when the board does not satisfy its required capabilities.

How It Works

Every morning a GitHub Actions run checks upstream MeshCore for new release tags, one per variant.

When it finds one:

  1. Clone upstream at that tag.
  2. Check the plan — every patch's dependencies come first, and every board can actually do what its mods ask of it.
  3. Copy in each mod's own source files.
  4. Generate the glue that wires those mods into upstream.
  5. Apply the patches, testing each one against the source before it goes in.
  6. Build.
  7. Stamp each build so the modifications it includes are identifiable in the binary itself.
  8. Boot it under emulation and confirm it comes up, on the boards set up for that.

It is pass or fail, with no middle. Every patch has to apply cleanly, the stamped image has to verify, and it has to boot. Miss any one of those and that build is dead and an issue is opened naming what broke. There is no partial build and no "close enough."

Usually the news arrives earlier than that. patch-drift-canary runs the same applicability check every day against upstream's development branches, so drift tends to show up before there is a release to break.

The flasher configures itself. After a successful build, pages/flasher/auto_boards.json is regenerated from the board overrides, upstream's board information, and the actual partitions.bin the build produced. Nothing about it is hand-maintained.

The flasher waits for all of them. It updates only after every board and variant has succeeded, so a half-finished matrix never puts a broken option in front of someone flashing a device.

The published .bin carries its own SHA-256 and its build identity inside the image, so there is no separate checksum file to keep in step with it.

Builds can also be started by hand from the Actions tab, against a specific upstream ref or a single variant instead of the whole matrix.

Releases

Releases are named using the variant and the upstream tag they were built from.

For example:

Repeater v1.16.0 - mobmesh

Each release includes:

  • <asset-basename>-vX.Y.Z.bin — the app image, for an OTA slot or an update over an existing install
  • <asset-basename>-vX.Y.Z-merged.bin — the same firmware plus bootloader, partition table and otadata, written at offset 0 to a blank board

The release notes come directly from the upstream MeshCore release for that tag.

You can flash the .bin file the same way you would flash an official MeshCore release. You can also use the web-based flasher provided by this project.

Requirements

You need an ESP32 board that is already supported by MeshCore and has a matching variants/<board>/overrides.yaml file in this repository.

Some mods may also require additional hardware -or- manual configuration overrides due to RAM and storage limitations.

For example, hotspot-ota requires an external power switch to control an external cellular hotspot. Check the README for the mod you are using for the wiring and hardware requirements.

About

Custom firmware for MeshCore by Mobmesh a member of GulfCoastMesh

About

custom firmware for MeshCore by GulfCoastMesh - Mobile, AL

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Firmware - by GulfCoastMesh Mobile

Custom firmware for MeshCore running on ESP32 boards.

🔗 "Give me the sales pitch, why do I need this?"

This project layers its changes onto a fresh copy of the upstream MeshCore source instead of maintaining a separate long-term fork. Each build starts with the latest upstream release: each mod's own source files are copied in, then a small set of patches edits the upstream files that need to call them. That keeps the project current without slowly drifting out of sync with MeshCore.

The MeshCore source code itself is not stored in this repository. Instead, this repo contains the patches, board-specific configuration, and the GitHub Actions workflow that puts everything together and publishes the builds.

Available Mods

Mods add features or changes to the standard MeshCore firmware. Each mod can ship owned source, integration declarations, upstream patches, board configuration, and documentation.

ModDescriptionMain Features
hotspot-otaAdds remote firmware updates over WiFi ( or cellular hotspot) and automatic rollback protection. A device can connect to an existing WiFi network, download a firmware image, verify it, and install it without needing to be onsite with the node.Remote OTA updates, power control of external cell modems, firmware SHA-256 verification, firmware authenticity checks, OTA slot management, automatic rollback / recovery after failed updates, automatic clock sync via NTP whenever WiFi is joined, remote updates through MeshCore CLI commands, downloads that run in the background so the node keeps repeating, and an update in progress that can be cancelled
timing-safetySmall fixes for how the firmware tracks time. Keeps timers working correctly on devices that run for many weeks, and stops "time since last heard from" numbers from showing garbage right after a reboot.Long-uptime timer fix, safer elapsed-time math across reboots
power-guardKeeps a bad situation from becoming an unrecoverable one, and puts the battery under its own management. Brownouts happen -- a flat pack, a cold morning, a cloudy week. Left alone, a node that browns out reboots straight into a loop that burns whatever charge is left and ends in a trip up the tower. This hibernates before it gets there, retries on a widening schedule, and comes back by itself once the battery does. Beyond the standard powersaving on / off it adds powersaving auto, which saves power only when the battery says to, and powersaving safe, the brownout failsafe. It also stops a mistyped poweroff from ending a node permanently.Hibernation before the bootloop threshold, automatic recovery, power saving that engages only when it's needed, thresholds set over serial or the mesh and kept across reboots, poweroff requires a wake time and is refused over the mesh

More information about each mod can be found in its own README under mods/<name>/.

Web-Based Flasher

You can use the ⚡️web-based flasher to flash a supported devices directly from your browser over USB.

The flasher requires Chrome, Edge, or Opera because it uses Web Serial. No additional software is needed.

It automatically uses the most recently built firmware for the board and variant you select.

This is not the official MeshCore flasher. It was built specifically for the custom firmware releases in this project.

Some mods may add extra options or requirements for a traditional flasher. Check the README for the specific mod if you need more information. For example, hotspot-ota changes how images are assigned to a device's OTA slots to support auto-recovery — see that mod's README for details.

Supported Boards

* more boards are on the way - " lookin' at you Grumpy "

VariantBoardUpstream TagRelease Asset
RepeaterHeltec V4repeater-v*heltec_v4_rep_mobmesh-vX.Y.Z.bin
Room ServerHeltec V4room-server-v*heltec_v4_room_mobmesh-vX.Y.Z.bin
RepeaterXiao ESP32-C3repeater-v*xiao_c3_rep_mobmesh-vX.Y.Z.bin
Room ServerXiao ESP32-C3room-server-v*xiao_c3_room_mobmesh-vX.Y.Z.bin

Each also ships a -merged.bin alongside it: the same firmware plus the bootloader, partition table and otadata in one file, written at offset 0 to a blank board. The plain .bin is the app alone, for an OTA slot or an update over an existing install.

Each Variant/Board pair uses its own release tag, so they are all built and released independently even when they share an upstream tag sequence (e.g. both boards' Repeater builds track repeater-v*).

build-targets.yaml at the repo root is the single source of truth for roles, release channels, and which (board, role) combinations get built with which mods. The CI matrix is generated from it, not hand-maintained. Adding support for another board is normally just adding entries there plus a variants/<board>/overrides.yaml file; the resolver rejects a mod when the board does not satisfy its required capabilities.

How It Works

Every morning a GitHub Actions run checks upstream MeshCore for new release tags, one per variant.

When it finds one:

  1. Clone upstream at that tag.
  2. Check the plan — every patch's dependencies come first, and every board can actually do what its mods ask of it.
  3. Copy in each mod's own source files.
  4. Generate the glue that wires those mods into upstream.
  5. Apply the patches, testing each one against the source before it goes in.
  6. Build.
  7. Stamp each build so the modifications it includes are identifiable in the binary itself.
  8. Boot it under emulation and confirm it comes up, on the boards set up for that.

It is pass or fail, with no middle. Every patch has to apply cleanly, the stamped image has to verify, and it has to boot. Miss any one of those and that build is dead and an issue is opened naming what broke. There is no partial build and no "close enough."

Usually the news arrives earlier than that. patch-drift-canary runs the same applicability check every day against upstream's development branches, so drift tends to show up before there is a release to break.

The flasher configures itself. After a successful build, pages/flasher/auto_boards.json is regenerated from the board overrides, upstream's board information, and the actual partitions.bin the build produced. Nothing about it is hand-maintained.

The flasher waits for all of them. It updates only after every board and variant has succeeded, so a half-finished matrix never puts a broken option in front of someone flashing a device.

The published .bin carries its own SHA-256 and its build identity inside the image, so there is no separate checksum file to keep in step with it.

Builds can also be started by hand from the Actions tab, against a specific upstream ref or a single variant instead of the whole matrix.

Releases

Releases are named using the variant and the upstream tag they were built from.

For example:

Repeater v1.16.0 - mobmesh

Each release includes:

  • <asset-basename>-vX.Y.Z.bin — the app image, for an OTA slot or an update over an existing install
  • <asset-basename>-vX.Y.Z-merged.bin — the same firmware plus bootloader, partition table and otadata, written at offset 0 to a blank board

The release notes come directly from the upstream MeshCore release for that tag.

You can flash the .bin file the same way you would flash an official MeshCore release. You can also use the web-based flasher provided by this project.

Requirements

You need an ESP32 board that is already supported by MeshCore and has a matching variants/<board>/overrides.yaml file in this repository.

Some mods may also require additional hardware -or- manual configuration overrides due to RAM and storage limitations.

For example, hotspot-ota requires an external power switch to control an external cellular hotspot. Check the README for the mod you are using for the wiring and hardware requirements.

About

Custom firmware for MeshCore by Mobmesh a member of GulfCoastMesh

About

custom firmware for MeshCore by GulfCoastMesh - Mobile, AL

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages