-
Notifications
You must be signed in to change notification settings - Fork 3
Dual-backend 1/3 — RNS core + protocol seam #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
2e49820
RNS core + protocol seam (dual-backend, PR 1/3)
torlando-agent[bot] 7be8fb4
address greptile review feedback (greploop iteration 1)
torlando-agent[bot] 19bde2f
fix(rns): clear RNS.Reticulum singleton in reset_identity (greploop i…
torlando-agent[bot] 59ed162
fix(rns): full teardown in reset_identity + identify after link is ac…
torlando-agent[bot] 3814427
fix(rns): register link in _links before wiring callbacks (greploop i…
torlando-agent[bot] 026dc78
fix(rns): real propagationSync received count on Swift backend
torlando-agent[bot] 42f6822
fix(bridge): run propagationSync off the shared serial queue
torlando-agent[bot] 63bfa96
fix: three correctness defects from greptile review (#79 iter)
torlando-agent[bot] 71bb911
fix: bound propagationSync by timeout, pin ble-reticulum, fetch wheel…
torlando-agent[bot] b7db7fe
fix: backend restart path — drain loop + leaked per-link state tasks
torlando-agent[bot] 4b365fd
fix: reset_identity must drain RNS.Transport class state (mirror stop())
torlando-agent[bot] cc2c28f
fix: don't hold _lock across link.teardown() in stop()/reset_identity
torlando-agent[bot] ef9cd89
fix: clear RNode callbacks on teardown + canonical LXMF announce app_…
torlando-agent[bot] 422227d
fix: pr1 teardown/lifecycle correctness (greptile #79 round 2)
torlando-agent[bot] 99e04e6
fix: serialize SwiftRNSBackend link registry against openLink races
torlando-agent[bot] 4e56d93
fix: register link + stateTask atomically in openLink
torlando-agent[bot] 8ced444
fix: guard interfaceIds with linkLock + cancel stale announcePoller
torlando-agent[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # Columba-iOS Architecture | ||
|
|
||
| Target / module dependency graph for the iOS app. Mirrors the role of `docs/architecture.md` in the sibling Android repo (`columba/`). | ||
|
|
||
| Regenerate this file from the current `Package.swift` + `Columba.xcodeproj/project.pbxproj`: | ||
|
|
||
| ```sh | ||
| ruby support/generate-module-graph.rb | ||
| ``` | ||
|
|
||
| The script reads: | ||
| - pbxproj targets (e.g. `ColumbaApp`, `ColumbaNetworkExtension`, `PythonBridge`, `RNSBackendPy`) via the `xcodeproj` Ruby gem (already a dependency for `support/configure-xcodeproj.rb`). | ||
| - SPM targets (e.g. `RNSAPI`, `LXSTSwift`, `COpus`, `CCodec2`, `SwiftBLEBridge`) via `swift package dump-package`. | ||
|
|
||
| It overwrites the Mermaid block between the start/end marker comments below the `## Target Graph` heading. Do not edit between the markers by hand — changes will be lost on next regen. | ||
|
|
||
| ## Target Graph | ||
|
|
||
| <!-- module-graph-start --> | ||
| ```mermaid | ||
| flowchart TD | ||
| CCodec2["CCodec2"] | ||
| COpus["COpus"] | ||
| ColumbaApp["ColumbaApp"] | ||
| ColumbaNetworkExtension["ColumbaNetworkExtension"] | ||
| LXSTSwift["LXSTSwift"] | ||
| MapLibre["MapLibre"] | ||
| RNSAPI["RNSAPI"] | ||
| SwiftBLEBridge["SwiftBLEBridge"] | ||
| ColumbaApp --> LXSTSwift | ||
| ColumbaApp --> MapLibre | ||
| ColumbaApp --> RNSAPI | ||
| ColumbaApp --> SwiftBLEBridge | ||
| LXSTSwift --> CCodec2 | ||
| LXSTSwift --> COpus | ||
| LXSTSwift --> RNSAPI | ||
| SwiftBLEBridge --> RNSAPI | ||
| classDef app fill:#1f6feb,stroke:#0d419d,color:#fff | ||
| classDef extension fill:#8957e5,stroke:#553098,color:#fff | ||
| classDef bridge fill:#f0883e,stroke:#9e4c0f,color:#fff | ||
| classDef spm_lib fill:#3fb950,stroke:#0f7a2e,color:#fff | ||
| classDef c_lib fill:#6e7681,stroke:#30363d,color:#fff | ||
| class ColumbaApp app | ||
| class LXSTSwift,MapLibre,RNSAPI,SwiftBLEBridge spm_lib | ||
| class ColumbaNetworkExtension extension | ||
| class CCodec2,COpus c_lib | ||
| ``` | ||
| <!-- module-graph-end --> |
Large diffs are not rendered by default.
Oops, something went wrong.
14 changes: 7 additions & 7 deletions
14
Columba.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
89 changes: 89 additions & 0 deletions
89
Columba.xcodeproj/xcshareddata/xcschemes/Columba-Swift.xcscheme
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <Scheme | ||
| LastUpgradeVersion = "1500" | ||
| version = "1.7"> | ||
| <BuildAction | ||
| parallelizeBuildables = "YES" | ||
| buildImplicitDependencies = "YES"> | ||
| <BuildActionEntries> | ||
| <BuildActionEntry | ||
| buildForTesting = "YES" | ||
| buildForRunning = "YES" | ||
| buildForProfiling = "YES" | ||
| buildForArchiving = "YES" | ||
| buildForAnalyzing = "YES"> | ||
| <BuildableReference | ||
| BuildableIdentifier = "primary" | ||
| BlueprintIdentifier = "TARG" | ||
| BuildableName = "ColumbaApp.app" | ||
| BlueprintName = "ColumbaApp" | ||
| ReferencedContainer = "container:Columba.xcodeproj"> | ||
| </BuildableReference> | ||
| </BuildActionEntry> | ||
| </BuildActionEntries> | ||
| </BuildAction> | ||
| <TestAction | ||
| buildConfiguration = "Debug-Swift" | ||
| selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
| selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
| shouldUseLaunchSchemeArgsEnv = "YES" | ||
| shouldAutocreateTestPlan = "YES"> | ||
| <Testables> | ||
| <TestableReference | ||
| skipped = "NO"> | ||
| <BuildableReference | ||
| BuildableIdentifier = "primary" | ||
| BlueprintIdentifier = "TTARG" | ||
| BuildableName = "ColumbaAppTests.xctest" | ||
| BlueprintName = "ColumbaAppTests" | ||
| ReferencedContainer = "container:Columba.xcodeproj"> | ||
| </BuildableReference> | ||
| </TestableReference> | ||
| </Testables> | ||
| </TestAction> | ||
| <LaunchAction | ||
| buildConfiguration = "Debug-Swift" | ||
| selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
| selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
| launchStyle = "0" | ||
| useCustomWorkingDirectory = "NO" | ||
| ignoresPersistentStateOnLaunch = "NO" | ||
| debugDocumentVersioning = "YES" | ||
| debugServiceExtension = "internal" | ||
| allowLocationSimulation = "YES"> | ||
| <BuildableProductRunnable | ||
| runnableDebuggingMode = "0"> | ||
| <BuildableReference | ||
| BuildableIdentifier = "primary" | ||
| BlueprintIdentifier = "TARG" | ||
| BuildableName = "ColumbaApp.app" | ||
| BlueprintName = "ColumbaApp" | ||
| ReferencedContainer = "container:Columba.xcodeproj"> | ||
| </BuildableReference> | ||
| </BuildableProductRunnable> | ||
| </LaunchAction> | ||
| <ProfileAction | ||
| buildConfiguration = "Release-Swift" | ||
| shouldUseLaunchSchemeArgsEnv = "YES" | ||
| savedToolIdentifier = "" | ||
| useCustomWorkingDirectory = "NO" | ||
| debugDocumentVersioning = "YES"> | ||
| <BuildableProductRunnable | ||
| runnableDebuggingMode = "0"> | ||
| <BuildableReference | ||
| BuildableIdentifier = "primary" | ||
| BlueprintIdentifier = "TARG" | ||
| BuildableName = "ColumbaApp.app" | ||
| BlueprintName = "ColumbaApp" | ||
| ReferencedContainer = "container:Columba.xcodeproj"> | ||
| </BuildableReference> | ||
| </BuildableProductRunnable> | ||
| </ProfileAction> | ||
| <AnalyzeAction | ||
| buildConfiguration = "Debug-Swift"> | ||
| </AnalyzeAction> | ||
| <ArchiveAction | ||
| buildConfiguration = "Release-Swift" | ||
| revealArchiveInOrganizer = "YES"> | ||
| </ArchiveAction> | ||
| </Scheme> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Python.xcframework lives in this directory. Fetch it with `support/fetch-python.sh`. | ||
| The xcframework, the VERSIONS marker, and the upstream tarball are all gitignored | ||
| because the xcframework is ~110 MB. The fetch script pins a specific release tag | ||
| for reproducibility — see support/fetch-python.sh. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,45 +1,68 @@ | ||
| // swift-tools-version: 5.9 | ||
| import PackageDescription | ||
|
|
||
| // Module layout — the iOS app is Xcode-built (Columba.xcodeproj), with | ||
| // configure-xcodeproj.rb pulling files in by path. This SwiftPM manifest | ||
| // exists for two reasons: | ||
| // | ||
| // 1. The Xcode project references this manifest as a LOCAL package | ||
| // (XCLocalSwiftPackageReference) so RNSAPI / SwiftBLEBridge get built by | ||
| // SwiftPM rather than hand-written pbxproj entries. | ||
| // 2. `swift build` (used by tooling + CI) can still typecheck the pure-Swift | ||
| // libraries without the Python.xcframework bridging header. | ||
| // | ||
| // The LXST voice stack (LXSTSwift + the Opus/Codec2 codec C trees) is no longer | ||
| // vendored here — it lives in the standalone, transport-agnostic LXST-swift | ||
| // package (consumed via SwiftPM, wired to RNS through Columba's | ||
| // PythonNetworkTransport). See `dependencies` below. | ||
| // | ||
| // Targets that DO require the bridging header (PythonBridge, RNSBackendPy, | ||
| // ColumbaApp) live ONLY in the pbxproj — they're not declared here. | ||
| let package = Package( | ||
| name: "ColumbaApp", | ||
| platforms: [ | ||
| .iOS(.v17), | ||
| .macOS(.v14) | ||
| ], | ||
| products: [ | ||
| .executable( | ||
| name: "ColumbaApp", | ||
| targets: ["ColumbaApp"] | ||
| ) | ||
| .library(name: "RNSAPI", targets: ["RNSAPI"]), | ||
| .library(name: "SwiftBLEBridge", targets: ["SwiftBLEBridge"]), | ||
| ], | ||
| dependencies: [ | ||
| // SPM resolves these from GitHub on every fresh checkout. To work | ||
| // against an in-progress local clone of any of these libraries | ||
| // without committing a path-override, drop a per-machine | ||
| // `.swiftpm/configuration/mirrors.json` mapping the URL to a local | ||
| // directory — see README "Local development against unreleased | ||
| // library changes" for the exact recipe. | ||
| .package(url: "https://github.com/torlando-tech/LXMF-swift.git", from: "0.4.0"), | ||
| .package(url: "https://github.com/torlando-tech/LXST-swift.git", from: "0.2.0"), | ||
| .package(url: "https://github.com/torlando-tech/reticulum-swift.git", from: "0.3.0"), | ||
| .package(url: "https://github.com/maplibre/maplibre-gl-native-distribution", from: "6.9.0"), | ||
| // Transport-agnostic LXST voice library (owns the Opus/Codec2 codecs | ||
| // and the NetworkTransport seam; no Reticulum dependency). Columba | ||
| // provides the implementation via PythonNetworkTransport. Tracking the | ||
| // branch until a release is tagged — same model as the RNS fork. | ||
| .package(url: "https://github.com/torlando-tech/LXST-swift.git", branch: "feat/transport-agnostic"), | ||
| ], | ||
| targets: [ | ||
| .executableTarget( | ||
| name: "ColumbaApp", | ||
| dependencies: [ | ||
| .product(name: "LXMFSwift", package: "LXMF-swift"), | ||
| .product(name: "LXSTSwift", package: "LXST-swift"), | ||
| // ReticulumSwift is imported directly by several view | ||
| // models (e.g. NomadNetBrowserViewModel, | ||
| // MessagingViewModel) — listed here as a direct product | ||
| // dep so the version constraint on the package above is | ||
| // actually exercised by SPM at resolution time. | ||
| .product(name: "ReticulumSwift", package: "reticulum-swift"), | ||
| .product(name: "MapLibre", package: "maplibre-gl-native-distribution"), | ||
| ], | ||
| path: "Sources/ColumbaApp" | ||
| ) | ||
| // ──────── RNSAPI: pure-interface protocol surface ──────── | ||
| .target( | ||
| name: "RNSAPI", | ||
| path: "Sources/RNSAPI", | ||
| // libsqlite3 (system) backs LXMFDatabase's on-disk persistence. | ||
| linkerSettings: [.linkedLibrary("sqlite3")] | ||
| ), | ||
|
|
||
| // ──────── SwiftBLEBridge: CoreBluetooth wrapper for ble-reticulum ── | ||
| // Mirror of Columba Android's reticulum/ble module. Holds CBCentralManager | ||
| // + CBPeripheralManager state and exposes a Swift API that the iOS BLE | ||
| // driver (app/ble/ios_ble_driver.py) calls into. The Python ↔ Swift | ||
| // callback invocation path lives separately in the pbxproj-only | ||
| // `PythonBLECallbackBridge.swift` (which needs Python.h); SwiftBLEBridge | ||
| // itself is pure CoreBluetooth so `swift build` compiles it cleanly. | ||
| .target( | ||
| name: "SwiftBLEBridge", | ||
| dependencies: ["RNSAPI"], | ||
| path: "Sources/SwiftBLEBridge" | ||
| ), | ||
| // Pure-Swift unit tests for RNSAPI (msgpack, AppDataParser, | ||
| // PropagationNodeInfo). Runs natively via `swift test` on macOS — no | ||
| // simulator / Xcode test target needed (RNSAPI has no UIKit/Python deps). | ||
| .testTarget( | ||
| name: "RNSAPITests", | ||
| dependencies: ["RNSAPI"], | ||
| path: "Tests/RNSAPITests" | ||
| ), | ||
| ] | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| #ifndef ColumbaPython_Bridging_Header_h | ||
| #define ColumbaPython_Bridging_Header_h | ||
|
|
||
| #import <Python/Python.h> | ||
|
|
||
| // Swift cannot express `PyConfig_SetString(&config, &config.home, ...)` because of | ||
| // overlapping-access exclusivity rules — both arguments alias into `config`. | ||
| // These tiny inline shims pull the dual-mutation pattern down into C, which | ||
| // has no such restriction. One shim per `PyConfig` field we touch. | ||
|
|
||
| static inline PyStatus ColumbaPy_PyConfig_SetHome(PyConfig *config, const wchar_t *home) { | ||
| return PyConfig_SetString(config, &config->home, home); | ||
| } | ||
|
|
||
| // Py_None is a macro in CPython's headers, which Swift cannot import. This | ||
| // shim returns a fresh reference so the caller can pass it where a "new" | ||
| // reference is expected (e.g. PyTuple_SetItem, which steals refs). | ||
| static inline PyObject *ColumbaPy_None(void) { | ||
| Py_INCREF(Py_None); | ||
| return Py_None; | ||
| } | ||
|
|
||
| // Py_True / Py_False are likewise macros. New refs so they can be packed into | ||
| // tuples + lists where slot setters steal the ref. | ||
| static inline PyObject *ColumbaPy_True(void) { | ||
| Py_INCREF(Py_True); | ||
| return Py_True; | ||
| } | ||
|
|
||
| static inline PyObject *ColumbaPy_False(void) { | ||
| Py_INCREF(Py_False); | ||
| return Py_False; | ||
| } | ||
|
|
||
| #endif |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.