2.0 KiB
2.0 KiB
callpipe control protocol (Pi ⇄ phone)
The phone app hosts a WebSocket server on the LAN (default port 8090). The Pi
(or any client, e.g. wscat) connects in and drives the cellular call. No audio
crosses this channel — audio is Bluetooth HFP between the phone and the Pi. This is
purely call control + state.
Endpoint: ws://<phone-ip>:8090/ (any path is accepted)
Commands (client → phone)
| JSON | Action |
|---|---|
{"cmd":"dial","number":"+9607…","sim":0} |
Place outgoing call. sim optional (0-based index from the sims event); omit for default SIM. |
{"cmd":"answer"} |
Answer the ringing call. |
{"cmd":"hangup"} |
End the active call (or reject if still ringing). |
{"cmd":"reject"} |
Reject the ringing call. |
{"cmd":"state"} |
Ask for the current call snapshot. |
{"cmd":"sims"} |
Ask for the SIM list. |
{"cmd":"ping"} |
Liveness check → pong. |
Events (phone → client)
| JSON | Meaning |
|---|---|
{"event":"hello","app":"callpipe","proto":1} |
Sent on connect. |
{"event":"sims","sims":[{"index":0,"label":"Ooredoo"},{"index":1,"label":"Dhiraagu"}]} |
SIM list (sent on connect + on request). |
{"event":"state","state":"ACTIVE","number":"+9607…","direction":"OUT"} |
Call state. Pushed on every change + on connect. |
{"event":"ack","cmd":"dial"} |
Command accepted. |
{"event":"error","cmd":"dial","msg":"…"} |
Command failed. |
{"event":"pong"} |
Reply to ping. |
state values: IDLE, CONNECTING, DIALING, RINGING, ACTIVE, HOLDING,
DISCONNECTING, DISCONNECTED. direction: IN, OUT, or null.
Quick test (before the Pi is ready)
# phone IP is 10.0.1.239 (adb wireless). Install app, open it once so the
# foreground service + default-dialer role are granted.
npm i -g wscat # or: nix-shell -p nodePackages.wscat
wscat -c ws://10.0.1.239:8090/
> {"cmd":"sims"}
> {"cmd":"dial","number":"+9607xxxxxx"}
> {"cmd":"hangup"}
You should see hello, sims, and live state events stream back.