The desktop side of the CrownOS phone bridge. A daemon that holds a persistent connection to a paired phone and carries clipboard, media, notification, call and OTP traffic.
Comparable to KDE Connect or Windows Phone Link.
Status: Early. It compiles and runs, but three of seven actions are
implemented, there is no authentication, and the D-Bus service crownotify
expects does not exist. See Other known gaps.
Transport: TCP on 0.0.0.0:5252, one thread per connected device, held open
for the life of the connection — "similar to websockets". UDP :5253 is bound
for LAN discovery, though the discovery function is a stub.
Encoding: CBOR, streamed.
pub struct Message {
pub client: Ipv4Addr,
pub method: Actions,
pub body: HashMap<String, String>,
}
#[repr(u8)]
pub enum Actions {
CLIPBOARD, MEDIA, OPEN, OTPSYNC, MONITOR, VOLUME, SHUTDOWN,
}
src/communication/README.mdsays "one line json". That is out of date — the code uses CBOR, andserde_jsonis a declared but unused dependency.
Implemented actions:
| Action | Implementation |
|---|---|
SHUTDOWN |
sh -c "shutdown now" |
VOLUME |
pactl set-sink-volume 0 {value}% |
CLIPBOARD |
prints the "type" field and nothing more |
There is no pairing, no authentication, and no encryption. Any peer that can
reach port 5252 can send a SHUTDOWN message and power the machine off.
It was worse than that until recently: ActionManager::notify fanned every
message out to every registered action, and ShutdownAction ignored
message.method entirely — so any decodable frame, whatever its method, shut
the machine down. notify now dispatches on the method, using the key the
action table always had.
The crate builds and runs, so the remaining exposure is live. Do not run it on an untrusted network, and fix the missing pairing before anyone ships it.
See SECURITY.md.
crownotify calls into this daemon for
call handling:
pub const CROWNCRATE_SERVICE: &str = "io.crownos.crowncrate";
pub const CROWNCRATE_PATH: &str = "/io/crownos/crowncrate";
pub const CROWNCRATE_INTERFACE: &str = "io.crownos.crowncrate";
// methods: PickupCall, DeclineCallThis crate has no zbus dependency and no D-Bus code at all — the service
does not exist. crownotify has a mock-based integration test for it, plus an
ignored test that runs against a real daemon. Implementing it is well-scoped
work.
A Rust toolchain and nothing else. This is a headless daemon with no UI, and
gtk4 — which it declared but never used, and which was by far the heaviest
thing in its dependency graph — has been removed. The crate went from about 148
packages to 43.
If you re-add a UI later, the GTK4 4.10+ stack is:
sudo pacman -S --needed base-devel pkgconf gtk4 glib2 pango gdk-pixbuf2 grapheneDebian/Ubuntu equivalents: Prerequisites.
Ports 5252/tcp and 5253/udp must be reachable for the bridge to work.
cargo build
cargo run # binds TCP :5252Rust 1.88+, pinned in rust-toolchain.toml. No CrownOS dependencies, so no
dev overlay is needed.
Do not copy this repository's
rustfmt.toml. It is the only one in the organization and it is a liability — an ~80-key dump of defaults containingedition = "2015"(the crate is edition 2024),required_version = "1.5.1"(rustfmt refuses to run on a mismatch), the deprecatedfn_args_layout, and several nightly-only keys alongsideunstable_features = false. Every other repo uses rustfmt defaults. Deleting it is a reasonable patch.
There are none — no unit tests, no integration tests, no examples. cargo test
compiles the crate and reports zero tests. The CBOR Message round-trip and
ActionManager::subscribe/unsubscribe are the obvious first targets.
There is none. src/config/mod.rs holds a single constant —
DEFAULT_LOGGING_FILE_PATH = "/var/log/crowncrate.log". The listen addresses,
the ports and the pairing state are all hardcoded, and the crate does not depend
on crownos-config.
- The empty
src/ui/mod.rs,src/lib.rs,src/predule.rsandsrc/config/mod.rshave been deleted, along with the unusedgtk4,serde_json,bytesandanyhowdependencies. What remains of the dependency set is still older than the rest of the organization. src/discovery/mod.rsbinds a socket and returns; it is never called.src/logging.rsmixesfn log(&mut self, ..)with receiver-lesswarn/debug/errorin one trait;FileLoggeris imported and unused;writeln!results are ignored.
| Repo | Role | State |
|---|---|---|
crowncrate-android |
Client | Android Studio template; no network permission |
crowncrate-chrome |
Browser client | No commits |
The two halves have never communicated.
See the organization-wide
contribution guide.
Default branch here is main.
Licensed under the MIT License.