Configuration Reference
Run the integrated runtime with a config directory:
cargo run --release -p cdma-nib -- --config-dir configRuntime Flags
| Flag | Purpose |
|---|---|
--config-dir <DIR> | Directory containing per-node JSON config files (CDMA_CONFIG_DIR can also be used) |
--bts-config <FILE> | Replace bts.json with a complete custom BTS configuration |
--bts-profile <PROFILE> | Apply bts.<profile>.json from the config directory. sprint selects the included Sprint settings. |
--radio-config <FILE> | Override the radio config embedded in bts.json |
--null-radio | Run without SDR hardware (TX drops, no RX) |
--a1-addr <ADDR> | MSC A1 signaling listen address (default 127.0.0.1:17013) |
--msc-mgmt-addr <ADDR> | MSC management gRPC listen address (default 127.0.0.1:17017) |
Local Overrides
Every per-node config in config/ supports a sibling <name>.local.json file that is merged on top of the base file at load time:
config/bts.json # shared default (checked into git)config/bts.local.json # your overrides (gitignored)The runtime reads the base file, deep-merges the local file on top, and validates the result. The local file only needs the fields you are changing.
Applies to: bts.json, bsc.json, msc.json, pcf.json, pdsn.json, hlr.json, smsc.json, management.json, voice-gw.json, and standalone radio profile files (e.g. radio_bladerf_micro2.local.json).
Merge behavior:
- Nested objects merge field by field; omitted fields keep the base value.
- Arrays in the local file replace the base array (no append).
- Setting a field to
nullremoves it, falling back to the struct default.
Example config/bts.local.json retuning to a different CDMA channel and raising TX gain:
{ "channel": { "band_class": "bc0", "cdma_channel": 283 }, "radio": { "tx_gain_db": 60 }}See Configuration → Local Overrides for the introductory walkthrough.
See Carrier Profiles for the Verizon and
Sprint startup commands, local override order, and Sprint-specific tuning.
Profile names may contain lowercase letters, digits, and hyphens. A profile
also supports a sibling bts.<profile>.local.json override.
bts.json
BTS radio and PHY configuration.
Top-level
| Field | Type | Default | Description |
|---|---|---|---|
pilot_offset | integer | 0 | Pilot PN offset in chips (0–511) |
channel | object | { "band_class": "bc0", "cdma_channel": 384 } | CDMA band class + channel number. Drives TX/RX frequencies and the broadcast CDMA_FREQ / BAND_CLASS overhead fields. |
evdo | object | disabled by default unless set in the shipped config | Optional EV-DO / HRPD Rev 0/Rev A carrier and overhead configuration. |
channel
Single source of truth for the BTS’s RF tuning, per C.S0057-F. The BTS
derives TX/RX center frequencies and the broadcast CDMA_FREQ /
BAND_CLASS fields from this triple.
| Field | Type | Default | Description |
|---|---|---|---|
band_class | string | "bc0" | One of "bc0" through "bc22" |
band_subclass | integer | (required) | 5-bit BAND_SUBCLASS; selects the channel-validity profile within the band |
cdma_channel | integer | 384 | CDMA channel number N |
See Channel Planning for the full
band-class table, valid channel ranges, and recommended channels, or use
the CDMA Channel Calculator to look up
the TX/RX frequencies for any (band, subclass, N).
Overrides for loopback or development work:
runtime.tx_freq_hz_override(integer, optional) — force the TX center frequency.
evdo
Optional EV-DO / HRPD Rev 0/Rev A carrier configuration. When enabled in the
integrated runtime, cdma-nib starts the HRPD AN service, PCF A9 signaling, and
PDSN A11 signaling, then bridges decoded HRPD air events between the BTS PHY and
AN session layers.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Turn on the EV-DO carrier and HRPD packet-data path. |
channel | integer | required when enabled | HRPD band-class channel number. Startup fails if EV-DO is enabled without an explicit channel. For EV-DO-only deployments, channels 589, 630, and 770 are good starting points. |
mode | string | "composite" | Carrier mode: "composite" for 1x + HRPD on one tuned RF span, or "hrpd_only" for an EV-DO-only deployment. |
advertise_on_1x | boolean | false | Advertise the HRPD carrier on the 1x paging channel for hybrid devices. |
gain | float | 1.0 | HRPD forward-carrier amplitude relative to the 1x carrier in composite mode. In HRPD-only mode the carrier level comes from tx_digital_backoff and this value has no effect. |
overhead.sector_id | string | required when enabled | 16-byte HRPD sector ID, encoded as 32 hex characters. |
overhead.subnet_mask | integer | 26 | UATI subnet mask advertised by the HRPD sector. |
overhead.color_code | integer | 26 | HRPD color code used by devices to distinguish the sector. |
overhead.sector_signature | integer | 1 | HRPD sector signature advertised in overhead. |
overhead.access_signature | integer | 1 | HRPD access signature advertised in overhead. |
Use a normal SDR radio profile with this section. The old HRPD-specific radio
profiles and dual-RF evdo_rf settings have been removed.
Derived RF profile
The BTS derives TX/RX SDR sample rates and RF bandwidths at startup from
channel and evdo.
| Carrier mode | Derived sample rate | Derived RF bandwidth |
|---|---|---|
1x only (evdo.enabled: false) | 4x chip rate (4915200 Hz for SR1) | 1500000 Hz |
1x + HRPD (evdo.enabled: true, mode: "composite") | Smallest 4x, 8x, or 16x chip-rate span that fits the 1x and HRPD carriers | Carrier separation plus occupied bandwidth |
HRPD only (mode: "hrpd_only") | 4x chip rate (4915200 Hz for SR1) | 1500000 Hz |
HRPD-only mode also selects the HRPD reverse carrier automatically and omits all 1x receiver correlator and traffic chains.
Composite mode validates both forward and reverse carrier spacing. If the configured 1x and HRPD channels do not fit within the 16x cap, startup fails with a configuration error.
overhead
Cell identity and system parameters broadcast on the paging channel.
| Field | Type | Default | Description |
|---|---|---|---|
sid | integer | 1 | System ID |
nid | integer | 1 | Network ID |
base_id | integer | 1 | Base station ID |
reg_zone | integer | 0 | Registration zone |
total_zones | integer | 1 | Total number of registration zones |
zone_timer | integer | 0 | Zone timer index |
max_slot_cycle_index | integer | 0 | Maximum slot cycle index |
page_chan | integer | 1 | Paging channel number (1–7) |
config_seq | integer | 23 | Configuration sequence number |
acc_config_seq | integer | 1 | Access configuration sequence number |
power_up_reg | boolean | true | Require power-up registration |
parameter_reg | boolean | false | Require parameter-change registration |
auth_mode | integer | 0 | Authentication mode (0–3) |
p_rev | integer | 6 | Protocol revision |
min_p_rev | integer | 3 | Minimum protocol revision accepted |
lp_sec | integer | 18 | Leap seconds offset between UTC and CDMA System Time (GPS-UTC) |
ltm_off | integer | 0 | Local time offset from UTC, half-hour units, 6-bit signed (-32..=+31, i.e. -16h..+15.5h) |
daylt | integer | 0 | Daylight saving time indicator (0 or 1) |
prat | integer | 0 | Paging rate |
cdma_freq | integer | null | null | Broadcast CDMA_FREQ (11-bit). When null, derived from channel.cdma_channel. Set explicitly only to advertise a different channel than the BTS is operating on. |
ext_cdma_freq | integer | null | null | Broadcast EXT_CDMA_FREQ. When null, derived from channel.cdma_channel. |
band_class | integer | null | null | Broadcast BAND_CLASS (5-bit) emitted in ECAMs. When null, derived from channel.band_class. |
timezone
Optional. Controls the local time broadcast on both 1x and EV-DO. Use
source = "system" for the host timezone, source = "user" for a named IANA
timezone, or source = "overhead" for the static overhead values. System and
user timezones pick up DST changes without a restart.
| Field | Type | Default | Description |
|---|---|---|---|
source | string | "overhead" | One of "overhead", "system", "user" |
tz | string | (none) | IANA zone name; required when source = "user" |
source = "system" reads the host’s IANA zone via the iana-time-zone
crate. The BTS refuses to start if the host has no IANA zone configured
and source = "system" is selected.
source = "user" requires a parseable IANA name (e.g.
"America/Los_Angeles"). Invalid names are rejected at config load.
DAYLT tells a 1x phone that daylight saving time is active. It does not tell
the phone to add or subtract another hour. The UTC offset already includes the
DST adjustment.
LP_SEC is not driven by this section. It lives on overhead.lp_sec and is
broadcast as the leap-second value on both 1x and HRPD regardless of source.
Examples:
"timezone": { "source": "overhead" }"timezone": { "source": "system" }"timezone": { "source": "user", "tz": "America/Los_Angeles" }runtime
PHY/MAC/LAC runtime settings.
| Field | Type | Default | Description |
|---|---|---|---|
spreading_rate | string | "sr1" | Spreading rate: "sr1" or "sr3" |
orthogonal_code_length | integer | 64 | Walsh code length |
chip_rate_hz | integer | 1228800 | Chip rate in Hz |
tx_freq_hz_override | integer | null | null | When set, overrides the TX center frequency derived from channel for loopback or development use. |
tx_lo_offset_hz | integer | 0 | TX LO hardware offset in Hz |
tx_digital_backoff | float | 0.15 (shipped config: 0.3) | Scales the composite before pulse shaping (0.0–1.0) and means the same at every TX sample rate. Sets the total transmit level; the channel power fractions below decide how it is shared. Above 0.3 a fully loaded carrier starts clipping. |
block_size_chips | integer | 64 | Internal processing block size in chips |
tx_batch_chips | integer | 3072 | TX batch size in chips (2× PCG = 3072 for SR1) |
short_code_length_chips | integer | 32768 | Short PN code period in chips |
max_tx_lookahead_ms | integer | 5 | Maximum TX lookahead in milliseconds |
runtime.realtime
Controls scheduling for the BTS TX, RX, and radio-driver threads. Failures are reported in the logs and radio metrics; the BTS continues with the scheduling policy the operating system permits.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Request real-time scheduling for radio and baseband threads |
tx_priority | integer | 80 | Linux SCHED_FIFO priority for the TX thread, 1–99 |
rx_priority | integer | 75 | Linux SCHED_FIFO priority for the RX thread, 1–99 |
driver_priority | integer | 70 | Linux SCHED_FIFO priority used while radio-driver workers start, 1–99 |
tx_cpu | integer | null | null | Optional valid, online Linux CPU index for the TX thread |
rx_cpu | integer | null | null | Optional valid, online Linux CPU index for the RX thread |
driver_cpu | integer | null | null | Optional valid, online Linux CPU index inherited by radio-driver workers |
Linux requires permission to select SCHED_FIFO, normally through the
process’s real-time priority resource limit or CAP_SYS_NICE. On macOS the
priority numbers and CPU fields do not apply; the runtime requests the
platform’s time-constraint or interactive QoS classes instead.
runtime.downlink.pilot
| Field | Type | Default | Description |
|---|---|---|---|
walsh_code | integer | 0 | Walsh code for pilot channel (always W0) |
power_fraction | float | 0.2 | Pilot share of total forward power (20%, −7 dB) |
runtime.downlink.sync
| Field | Type | Default | Description |
|---|---|---|---|
walsh_code | integer | 32 | Walsh code for sync channel (always W32) |
walsh_repetition | integer | 4 | Walsh repetition factor |
data_rate_bps | integer | 1200 | Sync channel data rate |
symbol_repeat | integer | 2 | Symbol repetition count |
interleaver.block_size | integer | 128 | Interleaver block size |
interleaver.m | integer | 7 | Interleaver M parameter |
interleaver.j | integer | 1 | Interleaver J parameter |
power_fraction | float | 0.0471 | Sync share of total forward power (−13.3 dB) |
availability_max_size_bits | integer | 32 | Max bits in sync availability buffer |
runtime.downlink.paging
| Field | Type | Default | Description |
|---|---|---|---|
walsh_code | integer | 1 | Walsh code for paging channel (W1) |
paging_channel_number | integer | 1 | Paging channel number (1–7) |
data_rate_bps | integer | 9600 | Paging channel data rate |
interleaver.block_size | integer | 384 | Interleaver block size |
interleaver.m | integer | 6 | Interleaver M parameter |
interleaver.j | integer | 6 | Interleaver J parameter |
power_fraction | float | 0.1882 | Paging share of total forward power (−7.3 dB) |
availability_max_size_bits | integer | 96 | Max bits in paging availability buffer |
runtime.downlink.traffic
| Field | Type | Default | Description |
|---|---|---|---|
power_fraction | float | 0.5647 | Share of total forward power available to all traffic channels together. Active calls split it evenly and forward power control moves each one inside it. |
max_channel_power_fraction | float | 0.2 | Upper bound on one traffic channel’s share, so a single call does not take the whole allotment. |
The four power_fraction values follow the C.S0010 base station test model and
must not sum to more than 1.0. Pilot, sync, and paging power stay fixed as
calls come and go. The BTS logs the split in percent and dB at startup.
runtime.downlink.paging.message_defaults
Overhead messages broadcast on the paging channel. schedule controls which messages are transmitted and in what order.
The serving band chooses the neighbor-list format automatically. Band Class 0
uses neighbor_list. Every other band uses extended_neighbor_list. Band Class
1 and Band Class 4 also receive the required base-class indicator. The runtime
adds the appropriate neighbor message if it is missing from schedule.
extended_system_parameters — IMSI defaults and soft-handoff thresholds:
| Field | Type | Default | Description |
|---|---|---|---|
mcc | string | "310" | Mobile country code (3-digit string) |
imsi_11_12 | string | "55" | IMSI digits 11–12 (2-digit string) |
pref_msid_type | integer | 3 | Preferred mobile ID type |
p_rev | integer | 6 | Protocol revision |
min_p_rev | integer | 6 | Minimum protocol revision |
soft_slope | integer | 16 | Soft handoff slope |
add_intercept | integer | 8 | T_ADD intercept |
drop_intercept | integer | 6 | T_DROP intercept |
packet_zone_id | integer | 0 | Packet zone ID |
use_tmsi | boolean | false | TMSI assignment enabled |
delete_for_tmsi | boolean | false | Delete TMSI on reassignment |
system_parameters — core cell parameters:
| Field | Type | Default | Description |
|---|---|---|---|
home_reg | boolean | true | Home registration enabled |
for_sid_reg | boolean | true | Foreign SID registration enabled |
for_nid_reg | boolean | true | Foreign NID registration enabled |
power_down_reg | boolean | false | Power-down registration enabled |
reg_prd | integer | 29 | Registration period (timer index) |
base_lat | integer | — | Base station latitude (in units per spec) |
base_long | integer | — | Base station longitude |
reg_dist | integer | 0 | Registration distance |
srch_win_a | integer | 6 | Active set search window |
srch_win_n | integer | 8 | Neighbor set search window |
srch_win_r | integer | 9 | Remaining set search window |
t_add | integer | 18 | Pilot T_ADD threshold (0.5 dB units) |
t_drop | integer | 28 | Pilot T_DROP threshold |
t_comp | integer | 8 | T_COMP comparison threshold |
t_tdrop | integer | 3 | T_TDROP timer index |
pwr_rep_thresh | integer | 2 | Power report threshold |
pwr_rep_frames | integer | 9 | Power report frame count |
pwr_thresh_enable | boolean | true | Threshold-based power reporting |
pwr_period_enable | boolean | true | Periodic power reporting |
pwr_rep_delay | integer | 2 | Power report delay |
access_parameters — reverse access channel configuration:
| Field | Type | Default | Description |
|---|---|---|---|
acc_chan | integer | 0 | Access channel number |
nom_pwr | integer | 0 | Nominal TX power adjustment |
init_pwr | integer | 0 | Initial power offset |
pwr_step | integer | 3 | Power step size (dB) |
num_step | integer | 3 | Number of power steps per probe |
max_cap_sz | integer | 4 | Maximum access capsule size |
pam_sz | integer | 10 | Preamble length |
max_req_seq | integer | 3 | Maximum request sequences |
max_rsp_seq | integer | 3 | Maximum response sequences |
acc_tmo | integer | 3 | Access timeout |
probe_bkoff | integer | 0 | Probe backoff |
bkoff | integer | 0 | Sequence backoff |
neighbor_list — Band Class 0 neighbor pilots:
| Field | Type | Default | Description |
|---|---|---|---|
pilot_inc | integer | 4 | Pilot increment advertised with the list |
neighbors | integer array | [] | Neighbor pilot PN offsets |
extended_neighbor_list — neighbor records for other bands:
| Field | Type | Default | Description |
|---|---|---|---|
pilot_inc | integer | 4 | Pilot increment, from 1 through 15 |
neighbors | object array | [] | Up to 40 extended neighbor records |
Each extended record contains nghbr_config (0..3), nghbr_pn (0..511),
and search_priority (0..3). To put a neighbor on another carrier, provide
both nghbr_band (0..31) and nghbr_freq (0..2047). Omit both for a
neighbor on the current carrier.
runtime.uplink
Reverse link configuration.
| Field | Type | Default | Description |
|---|---|---|---|
access_channels_per_paging_channel | integer | 1 | R-ACH channels per paging channel |
access_channel_numbers | array | [0] | Access channel number list |
access_channel_rate_bps | integer | 4800 | Access channel data rate |
access_frame_ms | integer | 20 | Access frame duration in ms |
require_r_csch_f_csch_arq_ack | boolean | true | Require ACK on access channel messages |
arq_ack_timeout_ms | integer | 400 | ARQ ACK timeout (T1m) |
reverse_access_finger_pool_size | integer | 8 | Number of RAKE fingers for access channel |
global_finger_pool_size | integer | 1 | Global RAKE finger pool size |
runtime.overhead
Overhead channel scheduling.
| Field | Type | Default | Description |
|---|---|---|---|
fragment_availability_interval_chips | integer | 32768 | Paging fragment scheduling interval |
sync_superframe_interval_chips | integer | 98304 | Sync superframe interval |
t1b_ms | integer | 1280 | T1b timer period in ms |
require_spm | boolean | true | Require System Parameters Message |
require_apm | boolean | true | Require Access Parameters Message |
require_cclm | boolean | true | Require CDMA Channel List Message |
require_espm | boolean | true | Require Extended System Parameters Message |
abis
Abis TCP signaling address (BTS side).
| Field | Type | Default | Description |
|---|---|---|---|
bind_addr | string | "127.0.0.1:5604" | Local TCP bind address for the BTS Abis signaling listener |
bearer
Abis UDP bearer addressing (BTS side).
| Field | Type | Default | Description |
|---|---|---|---|
bind_addr | string | "127.0.0.1:17014" | Local UDP bind address |
remote_addr | string | "127.0.0.1:17022" | BSC bearer address |
bsc.json
BSC radio access control and paging policy.
traffic_assignment
| Field | Type | Default | Description |
|---|---|---|---|
supported_for_rcs | array | [1, 2, 3] | Supported forward radio configurations |
supported_rev_rcs | array | [1, 2, 3] | Supported reverse radio configurations |
preferred_pairs | array | [{for_rc:1, rev_rc:1}, {for_rc:2, rev_rc:2}, {for_rc:3, rev_rc:3}] | Preferred forward/reverse RC pairs, tried in order |
idle_timeout_s | integer | 15 | Traffic channel idle timeout before release |
ms_ack_timeout_ms | integer | 5000 | TCH bringup timeout after the BS Ack Order while waiting for the MS Ack |
packet_service_connect_timeout_ms | integer | 5000 | Packet-data timeout while waiting for Service Connect Completion |
rev_fch_gating_mode | boolean | false | Reverse FCH gating mode |
enable_f_sch | boolean | false | Enable Forward Supplemental Channel assignment for eligible SO33/RC3 packet sessions |
f_sch_rate_bps | integer | 19200 | F-SCH rate when enabled; valid values are 19200, 38400, 76800, and 153600 |
f_sch_rate_bps is only used when enable_f_sch is true. 9600 is the fundamental-channel data rate, not a valid F-SCH rate.
This is a carrier-wide packet-data setting: every eligible SO33 packet session gets the configured F-SCH rate.
traffic_retry
| Field | Type | Default | Description |
|---|---|---|---|
ack_timeout_ms | integer | 400 | Traffic assignment ACK timeout (T1m) |
max_retries | integer | 3 | Maximum retransmissions |
paging_retry
| Field | Type | Default | Description |
|---|---|---|---|
ack_timeout_ms | integer | 10000 | Paging ACK timeout in ms |
max_retries | integer | 0 | Maximum paging retries |
abis_timers
BSC-side Abis timers per A.S0003-A §8 Table 8-1. Granularity is 100 ms; ranges are 0–1000 ms except tsetupb_ms (0–500).
| Field | Type | Default | Description |
|---|---|---|---|
tsetupb_ms | integer | 100 | §8.2 — Abis BTS Setup timer (range 0–500) |
tchanstatb_ms | integer | 500 | §8.3 — Abis Traffic Channel Status timer |
tdrptgtb_ms | integer | 500 | §8.5 — Abis BTS Release Ack timer |
tbstreqb_ms | integer | 500 | §8.6 — Abis Burst Response timer |
abis
Abis TCP signaling address (BSC side).
| Field | Type | Default | Description |
|---|---|---|---|
remote_addr | string | "127.0.0.1:5604" | BTS Abis signaling endpoint the BSC connects to |
bearer
Abis UDP bearer addressing (BSC side).
| Field | Type | Default | Description |
|---|---|---|---|
bind_addr | string | "127.0.0.1:17022" | Local UDP bind address |
remote_addr | string | "127.0.0.1:17014" | BTS bearer address |
Other top-level fields
| Field | Type | Default | Description |
|---|---|---|---|
mobile_idle_timeout_s | integer | 3600 | Evict idle registered mobiles with no access activity and no active traffic channel after this many seconds. Set to 0 to disable. |
voice_bearer_bind_ip | string | "127.0.0.1" | Local IP that voice bearer UDP sockets bind to. Set to the host’s network-facing IP when BSC and voice gateway are on separate hosts. |
node_id | string | "bsc" | Stable identifier for this BSC node, written to the HLR on every registration and included in management events. Must be unique across BSC instances. |
msc.json
MSC call control and voice policy.
Top-level
| Field | Type | Default | Description |
|---|---|---|---|
a1_listen_addr | string | "127.0.0.1:17013" | A1 signaling listen address |
mgmt_grpc_addr | string | "127.0.0.1:17017" | MSC management gRPC listen address |
a1_peers | array | [] | Static A1 peer list (peer_id + addr) |
voice
| Field | Type | Default | Description |
|---|---|---|---|
supported_service_options | array | [3, 68, 70, 32768] | Voice options the MSC may propose for mobile-terminated calls. Implemented values are SO1, SO3, SO68, SO70, and SO32768; the first implemented entry is the default. |
wav_file | string | null | WAV audio file path for fallback playback |
media_ringback_enabled | boolean | false | Generate ringback tone in media path |
media_ringback_type | string | "nanp" | Ringback tone type: "nanp" or "etsi" |
sip_ringback_disable | boolean | false | Who plays the ringback the caller hears on outbound SIP calls. false = your network; true = the SIP trunk (the trunk must send early-media ringback). |
inbound_sip_msc_ringback | boolean | true | When true, your network plays the ringback the SIP caller hears (subscriber’s custom ringtone, or the default tone) while the handset is being rung. Set to false to let the trunk play it. |
generate_ringback | boolean | true | Send ringback audio to the calling handset over the call’s audio channel. |
send_tones_alert | boolean | false | Tell the calling handset to play its own ringback tone. Independent of generate_ringback; either, both, or neither are valid. |
failure_tone_duration_ms | integer | 3000 | How long the caller hears the busy tone on a failed call before it ends. 0 ends the call immediately. |
page_retry_cooldown_ms | integer | 1000 | Time between ring attempts when the called handset hasn’t answered yet. |
page_retry_max_duration_ms | integer | 60000 | How long the network keeps trying to reach the called handset before giving up. Must be > 0. SIP callers get 480 Temporarily Unavailable on giveup. |
answer_delay_ms | integer | 10000 | Delay before automatic answer in local simulation paths |
release_timeout_ms | integer | 5000 | Call release timeout in ms |
service_connect_timeout_ms | integer | 20000 | Service connect timeout in ms |
voice_bearer_bind_ip | string | "127.0.0.1" | Local IP that voice bearer UDP sockets bind to. Set to the host’s network-facing IP when MSC and voice gateway run on separate hosts. |
voice.gateway
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable external SIP voice gateway |
endpoint | string | "http://127.0.0.1:17015" | Voice gateway gRPC endpoint |
fallback_to_wav | boolean | true | Play WAV audio if gateway is unreachable |
welcome_sms
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable welcome SMS on registration |
text | string | "Welcome to 1xBTS!" | SMS body text |
originating_number | string | "0000" | Originating number shown to subscriber |
inactive_days_threshold | integer | 30 | Days of inactivity before re-sending |
otasp
Over-the-air provisioning (*228). See the OTASP guide for end-to-end behavior.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Master switch. When false, *228 originations are not handled by the OTASP coordinator. |
feature_codes | array | ["*228"] | Dialed digit strings that start an OTASP session. |
spc_policy | string | "leave_default" | Use "leave_default" to present the subscriber’s stored SPC (or "000000") during Verify SPC without changing the SPC on the device. |
otasp.system_tag
| Field | Type | Default | Description |
|---|---|---|---|
name | string | "1xBTS" | Home System Tag banner shown on the handset status bar. ASCII only; max 31 characters. |
tag_p_rev | integer | 1 | TAG_P_REV value. |
otasp.nam_defaults
Mobile-terminated call acceptance bits written into every CDMA/Analog NAM and CDMA NAM block.
| Field | Type | Default | Description |
|---|---|---|---|
mob_term_home | boolean | true | Accept MT calls when camped on the home SID. |
mob_term_for_sid | boolean | true | Accept MT calls when roaming under a foreign SID in the NAM’s SID/NID list. |
mob_term_for_nid | boolean | true | Accept MT calls when roaming under a foreign NID. |
otasp.mms
| Field | Type | Default | Description |
|---|---|---|---|
uri | string | "" | MMSC URL written to handsets when otasp.writes.mms_uri = true. Must be a valid HTTP/HTTPS URL when used. |
otasp.writes
Per-block opt-in for what *228 overwrites on the handset. Every flag defaults to false so a freshly-installed system reads each block back, shows it on the session detail page, but never changes anything.
| Field | Type | Default | Description |
|---|---|---|---|
cdma_analog_nam | boolean | false | Write the analog NAM block: phone identity (IMSI), access class, home system, paging channel, roaming permissions. |
mdn | boolean | false | Write the Mobile Directory Number — the handset’s stored phone number. |
cdma_nam | boolean | false | Write the CDMA NAM block: same identity / roaming fields as the analog block, for modern CDMA-only handsets. |
home_system_tag | boolean | false | Write the Home System Tag — uses otasp.system_tag.name. |
mms_uri | boolean | false | Write the MMS URL — uses otasp.mms.uri. Skipped on handsets that don’t advertise MMS provisioning support. |
prl | boolean | false | Push the per-subscriber or system-default PRL to the handset. Skipped on handsets that don’t advertise SSPR support, or when no PRL has been uploaded. |
voice-gw.json
cdma-voice-gw SIP/RTP bridge configuration. See the
Voice Gateway Setup guide for end-to-end
deployment instructions.
grpc
| Field | Type | Default | Description |
|---|---|---|---|
listen_addr | string | "127.0.0.1:17015" | gRPC server address the MSC connects to. |
sip
| Field | Type | Default | Description |
|---|---|---|---|
listen_addr | string | "127.0.0.1:5060" | Concrete local IP:port; libre rejects 0.0.0.0 / ::. |
transport | string | "udp" | udp, tcp, or tls. |
request_uri_template | string | "sip:{called}@127.0.0.1:5060" | Request-URI; {called} is replaced with dialed digits. |
from_domain | string | "bts.local" | Domain placed in the From URI. Must match what the trunk expects. |
caller_id_override | string|null | null | DID (E.164) used as the From user. null → handset MDN. |
user_agent | string | "1XBTS-VoiceGW/0.1" | User-Agent header value. |
keepalive_interval_secs | integer | 0 | SIP OPTIONS keepalive cadence. Requires registration.enabled=true. |
inbound_decision_timeout_ms | integer | 30000 | Auto-reject inbound INVITEs with 408 if MSC hasn’t decided in this many ms; 0 disables. |
auth.username | string | "" | SIP digest username. |
auth.password | string|null | null | Inline password — works but never commit it. |
auth.password_env | string|null | null | Env var holding the SIP password. Preferred. Mutually exclusive with auth.password. |
registration.enabled | boolean | false | Send REGISTER to the trunk. |
registration.registrar_uri | string|null | null | Required when registration.enabled=true. |
registration.expires_secs | integer | 300 | Registration lifetime; gateway re-registers before expiry. |
registration.allow_unauthenticated | boolean | false | Allow REGISTER without auth. |
rtp
| Field | Type | Default | Description |
|---|---|---|---|
listen_addr | string | "127.0.0.1" | IP for RTP bind. Use the LAN IP behind NAT. 0.0.0.0 requires advertise_addr. |
port_range | [int, int] | [17100, 17200] | UDP port range for RTP sessions. |
advertise_addr | string|null | null | Public IP placed in outgoing SDP. Set when behind NAT without STUN. |
preferred_codecs | array | ["PCMU", "PCMA"] | G.711 variants. Must include PCMU or PCMA. |
telephone_event_payload_type | integer|null | 101 | Dynamic RTP payload type advertised for RFC 4733 telephone-event (DTMF). Set to null to omit telephone-event from SDP. Required when dtmf_mode = "rfc2833". |
nat
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | "disabled" | "disabled" or "stun_latch". |
stun_server | string|null | null | host:port. Required when mode = stun_latch. |
stun_timeout_ms | integer | 1000 | STUN binding timeout. Must be > 0 when stun_latch is enabled. |
rtp_latch_packets | integer | 5 | Inbound RTP source packets to observe before latching the return path. |
rtp_latch_interval_ms | integer | 20 | Spacing for outgoing latch packets. |
calls
| Field | Type | Default | Description |
|---|---|---|---|
max_concurrent_calls | integer | 32 | Hard cap on active calls. Must be ≤ RTP port-range capacity. |
setup_timeout_ms | integer | 30000 | Outbound INVITE→answer timeout. |
ringing_timeout_ms | integer | 120000 | Maximum alerting duration before cancel. |
media_idle_timeout_ms | integer | 30000 | Idle period (no RTP) before tearing down a call. |
Media
| Field | Type | Default | Description |
|---|---|---|---|
jitter_buffer_ms | integer | 60 | Adaptive buffer (40–80 ms) for inbound RTP reordering. |
dtmf_mode | string | "rfc2833" | "rfc2833" to forward DTMF the mobile pressed during a call as RFC 4733 telephone-event RTP packets. "disabled" to drop them. |
pdsn.json
Packet data transport configuration.
Top-level
| Field | Type | Default | Description |
|---|---|---|---|
packet_grpc_listen_addr | string | "127.0.0.1:17021" | Packet service gRPC listen address |
a10_bearer | object | UDP-encapsulated GRE on 127.0.0.1:17043 ↔ 127.0.0.1:17042 | A10 bearer transport toward the PCF |
a11 | object | 127.0.0.1:17045 ↔ 127.0.0.1:17044 | A11 UDP signaling endpoint toward the PCF |
a11_security | object | required | PCF/PDSN A11 security association. The stock JSON includes matching local values; keep PCF and PDSN in sync. |
ppp_session_timeout_secs | integer | 1800 | Idle lifetime for cached open PPP/LCP/IPCP state across packet traffic-channel changes. Cached sessions reserve the mobile IP until they resume or expire. |
events_endpoint | string | null | Aggregated event bus endpoint (e.g. "http://127.0.0.1:17023"). When set, PDSN publishes packet-session bind/unbind events to the bus. |
a11_security
| Field | Type | Default | Description |
|---|---|---|---|
spi | integer | required | A11 Security Parameter Index. Must be greater than 255; 0..=255 are reserved by A.S0017. |
shared_secret_hex | string | required | Hex-encoded PCF/PDSN shared secret. Must match pcf.json:a11_security.shared_secret_hex. |
packet
| Field | Type | Default | Description |
|---|---|---|---|
transport | string | "tun" | Transport mode: "tun", "fou", or "fou_tcp" |
fou_remote | string | null | FOU or FOU-TCP remote endpoint (host:port) |
fou_local_port | integer | 17011 | Local FOU receive port |
tun_nat_interface | string | null | Network interface name for TUN NAT (required when transport="tun") |
gateway_ip | string | "10.55.0.1" | Packet-data gateway IP advertised/used for the mobile /24 |
primary_dns | string | "10.55.0.1" | Primary DNS server supplied through IPCP or Mobile IPv4 registration |
secondary_dns | string | "10.55.0.1" | Secondary DNS server supplied through IPCP or Mobile IPv4 registration |
enable_uplink_vj_compression | boolean | false | Ask mobiles to use Van Jacobson TCP/IP header compression for traffic sent to the PDSN. |
enable_downlink_vj_compression | boolean | false | Accept mobile requests to use Van Jacobson TCP/IP header compression for traffic sent to the mobile. |
mobile_ip | object | see below | Mobile IPv4 registration for phones that open IPCP without requesting a Simple IP address. Omission default is disabled. The checked-in config enables Sprint compatibility. |
packet.mobile_ip
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enables Mobile IPv4 registration for handsets that open IPCP without an IP-Address option. Simple IP remains the default when this is false. |
fa_address | string | "10.55.0.1" | Foreign Agent address advertised to the handset. |
home_agent_address | string | "10.55.0.1" | Home Agent address returned in local Registration Replies. |
advertisement_count | integer | 3 | Unsolicited Agent Advertisements sent after IPCP opens in Mobile IPv4 mode. |
advertisement_lifetime_secs | integer | 9000 | ICMP Router Advertisement lifetime. |
registration_lifetime_secs | integer | 1200 | Maximum accepted Mobile IPv4 registration lifetime. Must be less than ppp_session_timeout_secs. |
auth_mode | string | "insecure" | "insecure" accepts unauthenticated requests. "mn_ha" validates the configured MN-HA association. |
mn_ha_spi | integer | null | null | MN-HA SPI. Required with auth_mode="mn_ha" and must be greater than 255. |
mn_ha_secret_base64 | string | null | null | Nonempty binary MN-HA shared secret encoded as base64. Required with auth_mode="mn_ha". |
allow_unverified_mn_aaa | boolean | false | Accept MN-AAA without an external AAA check after MN-HA succeeds. Intended only for compatibility with phones that require it. |
home_address_pool | string | null | Optional home-address pool. null uses the packet /24; custom pools are not yet supported. |
Mobile IPv4 is selected only when it is enabled and the peer IPCP request omits
the IP-Address option. A peer request containing IP=0.0.0.0 or another
IP-Address option follows the normal Simple IP negotiation.
In insecure mode, a phone that asks for authenticated registration returns
to Simple IP negotiation. In mn_ha mode, the SPI and secret must match the
phone. If the request also includes MN-AAA and
allow_unverified_mn_aaa is false, the PDSN tries Simple IP instead.
The checked-in pdsn.json enables mn_ha with compatibility values used by
tested legacy Sprint phones. These are not secure, general-purpose credentials.
Change them only when the phone is provisioned with matching values.
By default, DNS points phones at the packet gateway resolver. In the compose
stack this resolves speed and speed.local.1xbts.org to the local speed test.
Simple IP supplies these values through IPCP. Mobile IPv4 supplies them after a
successful registration. Set primary_dns and secondary_dns to external
resolvers if you do not want gateway-local DNS.
Transport modes:
tun— kernel TUN device; packets routed via NAT ontun_nat_interfacefou— FOU (Foo-over-UDP) tunnel; direct UDP encapsulationfou_tcp— FOU with TCP relay (for NAT traversal); connects tofou_remote
hlr.json
HLR subscriber database configuration.
| Field | Type | Default | Description |
|---|---|---|---|
grpc_listen_addr | string | "127.0.0.1:17019" | HLR service gRPC listen address |
postgres_dsn | string | null | null | PostgreSQL connection string. When unset, HLR runs without persistence. Shipped sample: "postgres://1xbts:1xbts@localhost:45432/1xbts". |
smsc.json
SMSC message store configuration.
| Field | Type | Default | Description |
|---|---|---|---|
grpc_listen_addr | string | "127.0.0.1:17020" | SMSC service gRPC listen address |
postgres_dsn | string | null | null | PostgreSQL connection string. When unset, SMSC runs without persistence. Shipped sample: "postgres://1xbts:1xbts@localhost:45432/1xbts". |
management.json
Management gRPC facade configuration.
| Field | Type | Default | Description |
|---|---|---|---|
grpc_listen_addr | string | "127.0.0.1:17016" | Management gRPC listen address |
tokio_console | boolean | false | Enable Tokio console on port 17018 |
iq_capture_dir | string | "capture-iq-wav" | Directory for IQ capture WAV output |
mtls | object | null | mTLS config (see below); omit for plaintext |
mtls (optional)
| Field | Type | Description |
|---|---|---|
cert_path | string | Path to PEM-encoded server certificate |
key_path | string | Path to PEM-encoded server private key |
client_ca_path | string | Path to PEM-encoded CA bundle for client certificate verification |
events.json
Aggregated event bus configuration. When this file is present, cdma-nib starts the events.v1.EventService gRPC service. Producers (e.g. PDSN via pdsn.json’s events_endpoint) publish to it; subscribers consume the unified stream via ListenEvents.
| Field | Type | Default | Description |
|---|---|---|---|
grpc_listen_addr | string | required | Event bus gRPC listen address (e.g. "127.0.0.1:17023") |
subscriber_queue_capacity | integer | 1024 | Per-subscriber buffered queue size. Subscribers that fall behind beyond this depth are disconnected. |
pcf.json
PCF-side packet service client configuration.
| Field | Type | Default | Description |
|---|---|---|---|
packet_grpc_endpoint | string | "http://127.0.0.1:17021" | Packet service endpoint consumed by the BSC-facing PCF client |
a9_bind_addr | string | "127.0.0.1:17046" | A9 signaling bind address for HRPD AN Setup-A8 requests |
a8_bearer | object | UDP-encapsulated GRE on 127.0.0.1:17041 ↔ 127.0.0.1:17040 | A8 bearer transport toward the HRPD AN |
a10_bearer | object | UDP-encapsulated GRE on 127.0.0.1:17042 ↔ 127.0.0.1:17043 | A10 bearer transport toward the PDSN |
a11 | object | 127.0.0.1:17044 ↔ 127.0.0.1:17045 | A11 UDP signaling endpoint toward the PDSN |
a11_security | object | required | PCF/PDSN A11 security association. Must match pdsn.json:a11_security. |
a11_security
| Field | Type | Default | Description |
|---|---|---|---|
spi | integer | required | A11 Security Parameter Index. Must be greater than 255; 0..=255 are reserved by A.S0017. |
shared_secret_hex | string | required | Hex-encoded PCF/PDSN shared secret. Must match pdsn.json:a11_security.shared_secret_hex. |
The checked-in pcf.json and pdsn.json include matching A11 credentials for
local operation. Override both sides together with pcf.local.json and
pdsn.local.json for a deployment-specific association.
Radio Configs
Radio config files are standalone JSON passed via --radio-config. They are independent of the config/ directory.
Common Fields
| Field | Type | Description |
|---|---|---|
kind | string | Backend: "uhd", "lime", "blade_rf", "soapy" |
device | string | Device selector string (empty = first found) |
channel | integer | RF channel index |
tx_antenna | string | TX antenna port name |
tx_gain_db | float | TX gain in dB |
rx_antenna | string | RX antenna port name |
rx_gain_db | float | RX gain in dB |
rx_power_adj | float | Radio-specific dBFS threshold adjustment for reverse-link power control |
rx_sample_delay | integer | RX timing compensation in samples |
rx_batch_pcgs | integer | RX batch size in PCGs (default: 2) |
TX/RX sample rates and RF bandwidths are not radio-config fields. They are
derived from bts.json carrier mode at startup.
UHD (kind: "uhd")
{ "kind": "uhd", "device": "type=b200,num_recv_frames=1024,num_send_frames=1024", "channel": 0, "antenna": "TX/RX", "tx_gain_db": 65.0, "rx_antenna": "RX2", "rx_gain_db": 30.0, "rx_power_adj": 0.0, "rx_sample_delay": 50}LimeSDR Native (kind: "lime")
{ "kind": "lime", "device": "", "channel": 0, "tx_antenna": "BAND1", "tx_gain_db": 80, "rx_antenna": "LNAW", "rx_gain_db": 50, "rx_power_adj": 5.0, "rx_sample_delay": 97}rx_sample_delay compensates for LimeSDR hardware timing offset in the receive path.
bladeRF Native (kind: "blade_rf")
{ "kind": "blade_rf", "device": "", "channel": 0, "tx_antenna": "TXA", "rx_antenna": "A_BALANCED", "tx_gain_db": 60, "rx_gain_db": 35, "rx_reference_dbm": null, "rx_power_adj": 0.0, "rx_sample_delay": 82, "rx_batch_pcgs": 2, "num_buffers": 16, "buffer_size": 8192, "num_transfers": 8, "stream_timeout_ms": 3500}| Field | Description |
|---|---|
fpga_path | Path to .rbf FPGA image; null uses libbladeRF host auto-load (~/.config/Nuand/bladeRF/) |
rx_reference_dbm | Optional RX reference power level in dBm |
num_buffers | Stream buffer count |
buffer_size | Samples per buffer |
num_transfers | Concurrent USB transfers |
stream_timeout_ms | Stream transfer timeout |
SoapySDR (kind: "soapy")
{ "kind": "soapy", "device": "", "channel": 0, "antenna": "TX/RX", "tx_gain_db": 60.0, "rx_antenna": "RX2", "rx_gain_db": 50.0, "rx_sample_delay": 0, "rx_batch_pcgs": 2}Default Ports
| Port | Protocol | Owner | Purpose |
|---|---|---|---|
| 5604 | TCP | BTS/BSC | Abis signaling |
| 17013 | TCP | MSC | A1 signaling listener |
| 17014 | UDP | BTS | Abis bearer (BTS side) |
| 17015 | gRPC | Voice gateway | MSC-controlled SIP/RTP bridge |
| 17016 | gRPC | Management facade | Node-scoped APIs and compatibility APIs |
| 17017 | gRPC | MSC management | Call initiation, call list, SMS |
| 17018 | TCP | Tokio console | Optional async diagnostics |
| 17019 | gRPC | HLR service | Subscriber and registration persistence |
| 17020 | gRPC | SMSC service | SMS submission and delivery persistence |
| 17021 | gRPC | Packet service | Packet sessions and packet service RPCs |
| 17022 | UDP | BSC | Abis bearer (BSC side) |
| 17023 | gRPC | Event bus | Aggregated event stream (events.v1.EventService) |
| 17030 | gRPC | HRPD AN | EV-DO AN session/air service used by cdma-nib |
| 17031 | TCP | BSC/AN | Optional A21 hybrid 1x/HRPD coordination |
| 17040 | UDP/GRE | AN A8 | HRPD A8 bearer endpoint toward PCF |
| 17041 | UDP/GRE | PCF A8 | HRPD/packet A8 bearer endpoint toward AN or 1x radio edge |
| 17042 | UDP/GRE | PCF A10 | A10 bearer endpoint toward PDSN |
| 17043 | UDP/GRE | PDSN A10 | A10 bearer endpoint toward PCF |
| 17044 | UDP | PCF A11 | A11 signaling endpoint toward PDSN |
| 17045 | UDP | PDSN A11 | A11 signaling endpoint toward PCF |
| 17046 | UDP | PCF A9 | A9 signaling endpoint for Setup-A8 requests |
| 17010 | UDP | PDSN | FOU remote default |
| 17011 | UDP | PDSN | FOU local default |
| 17012 | TCP | FOU-NAT | FOU-TCP relay (Docker service) |
| 45432 | TCP | PostgreSQL | HLR and SMSC (Docker service) |