Mobile Station
cdma-ms is a software CDMA2000 1x handset. Point it at an SDR and it scans for a cell, camps, registers, sends SMS and places voice calls the way a phone does. It is built for testing a 1xBTS cell without reaching for a physical handset, and for watching exactly what a cell sends a mobile.
It also runs with no hardware at all. The sim radio starts a complete 1xBTS cell in the same process and connects the two over a simulated air interface, which is the quickest way to try it.
Features
- PRL scan, pilot acquisition, and sync and paging decode
- Registration
- SMS, sending and receiving
- Voice calls, placing and answering, with EVRC-A, EVRC-B, EVRC-WB, TIA-96 and QCELP 13K
- DTMF during a call
- Closed-loop reverse power control
- Live decode of what the cell sends: pilot, sync, overhead, neighbor list and paging
- Console, terminal UI, handset GUI and a gRPC API
Transmit power is digital scaling only, not a calibrated RF level. Keep the antenna setup and gain conservative, and transmit only where you are authorized to.
Build
The mobile station is its own binary. The cli feature includes the console, terminal UI, scan tools, the simulated cell and the network radio. Add gui for the handset window, and one SDR backend for a directly attached radio:
# Simulated cell and network radio onlycargo build --release -p cdma-ms --features cli
# With a UHD (USRP B2xx) radio and the GUIcargo build --release -p cdma-ms --features cli,gui,uhd-backend| Feature | Adds |
|---|---|
cli | Console, TUI, scan/sweep, gRPC API, sim radio, network radio |
gui | Feature-phone window with microphone and speaker audio (needs libasound2-dev on Linux) |
uhd-backend, bladerf-backend, lime-backend, soapy-backend | A directly attached SDR, same packages as the BTS backends |
sdr | All four SDR backends |
To run the mobile on a different machine from its radio, use the network radio and cdma-radiod instead of building an SDR backend into cdma-ms.
Try it without hardware
cargo run --release -p cdma-ms --features cli -- consoleWith the shipped config/ms.json and no --radio, the console starts the simulated cell, powers the mobile on, and registers. Then try:
ms> statusms> mosms 5551234 helloms> sms incoming testGet on the air
- Set the identity. Edit
config/ms.local.json(see Configuration). The cell has to know the IMSI and ESN. On a 1xBTS network, add the subscriber in the dashboard first. - Pick a PRL, or a channel. With
--prl, the mobile scans the channels the PRL lists and only camps on systems it permits, just like a phone. Use your network’s PRL, or one read back from a handset with*228. Without one, it goes straight tochannelin the config. - Point it at the radio. Pass a radio config with
--radio. Any BTS radio profile works.
cdma-ms console --radio config/radio_uhd_b210_native.json --prl my-network.prlTX timing calibration. The reverse link must line up with the forward link to within a fraction of a chip, and every radio model has its own transmit latency. Set
tx_sample_delayin the radio config (shipped profiles include a starting value), and fine-tune it live withpower delay <samples>in the console. A wrong value shows up as access probes the cell never answers.
Configuration
config/ms.json, with an optional config/ms.local.json override:
{ "identity": { "esn": 305419896, "imsi": "310001234567890", "meid": "A1000012345678" }, "channel": { "band_class": "bc1", "cdma_channel": 50 }, "calibration": { "tx_power_control": true, "relative_access_power": true, "access_initial_backoff_db": 12.0, "tx_reference_dbm": -10, "tx_peak_limit": 0.0625 }, "grpc_listen": "[::1]:50052"}| Key | Description |
|---|---|
identity.esn | 32-bit ESN, decimal. Override with --esn (decimal or 0x hex) |
identity.imsi | 15-digit IMSI. The MCC and MIN are taken from it. Override with --imsi |
identity.meid | Optional 14-digit hex MEID |
channel.band_class, channel.cdma_channel | The channel used when no PRL is given, and the channel of the simulated cell |
radio | Radio to use. Defaults to the simulated cell. Usually set with --radio instead (see below) |
acquisition.t57m_power_up_delay_ms | How long to wait after camping before the power-up registration (T57m). Defaults to 20000 on a radio, as the standard specifies, and 0 on the simulated cell. Set 0 to register right away |
acquisition.scan_dwell_ms | How long to wait for a pilot on each channel before moving on (default 500 ms on hardware) |
calibration.tx_power_control | Calibrated power control: set output level from tx_reference_dbm, the received signal and the cell’s power-control commands. Toggle live with power control on|off |
calibration.relative_access_power | Without calibrated power control, start access probes below full scale and step them up with each probe, as the cell’s access parameters ask |
calibration.access_initial_backoff_db | How far below full scale the first access probe starts, for relative_access_power |
calibration.tx_reference_dbm | Output level, in dBm, of a full-scale transmit signal. Adjust live with power tx |
calibration.tx_peak_limit | Digital ceiling on transmit amplitude (0–1), a safety cap on output level |
calibration.rx_reference_dbm | Input level, in dBm, that reads as full scale (default -30). Used for open-loop power |
calibration.tx_delay_samples | Transmit timing compensation, used only when the radio config has no tx_sample_delay |
grpc_listen | Address of the mobile’s control API |
Radios
--radio | What it does |
|---|---|
sim (default) | A complete simulated 1xBTS cell in the same process |
noop | No radio. The mobile hears silence |
| A radio JSON file | Any BTS radio profile (uhd, blade_rf, lime, soapy), or a network profile for cdma-radiod |
An iq_file radio replays a recorded forward-link capture (4.9152 Msps WAV) for offline decoding:
{ "radio": { "kind": "iq_file", "path": "capture.wav", "band_class": "bc1", "cdma_channel": 50 }}Record one from a live radio with dump <seconds> <file.wav> in the console.