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) |
--msc-mgmt-addr <ADDR> | MSC management gRPC listen address (default 127.0.0.1:17017) |
--component <NAME> | Run only the named component (repeatable). Defaults to all of them: cdma-hlr, cdma-smsc, cdma-events, cdma-pdsn, cdma-pcf, cdma-msc, cdma-bts, cdma-bsc. |
The launcher starts every component as a separate process. Each one reads its own file from the config directory, so a component can also run on its own host with just that file.
Defaults in this reference
The Default column shows the value in the shipped config/*.json. Where the shipped file omits a key, the column shows the built-in default that applies when the key is absent.
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). events.json has no local override.
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. One file per cell.
Top-level
| Field | Type | Default | Description |
|---|---|---|---|
pilot_offset | integer | 0 | Pilot PN offset (0–511, in units of 64 chips) |
sector | integer | 1 | Sector number this BTS operates (1–255). With overhead.base_id it forms the cell identity the BTS enrolls under. Required. |
channel | object | { "band_class": "bc0", "band_subclass": 0, "cdma_channel": 691 } | CDMA band class + channel number. Drives TX/RX frequencies and the broadcast CDMA_FREQ / BAND_CLASS overhead fields. |
radio | object | not set (null radio) | Inline radio profile, same format as the standalone radio configs. When absent and no --radio-config is given, the BTS runs on the null radio. |
iq_capture_dir | string | "captures" | Directory IQ captures requested from the web UI are written to. Built-in default when absent: capture-iq-wav. |
evdo | object | disabled | Optional EV-DO / HRPD Rev 0/Rev A carrier, AN and overhead configuration. |
events_endpoint | string | null | "http://127.0.0.1:17023" | Event bus the HRPD access network publishes session events to. null stops publishing. |
hlr_endpoint | string | null | "http://127.0.0.1:17019" | HLR the HRPD access network resolves subscriber identities against. null leaves HRPD identities unresolved. |
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 | 0 | 5-bit BAND_SUBCLASS; selects the channel-validity profile within the band. Required. |
cdma_channel | integer | 691 | 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. The HRPD access network (AN) runs inside the BTS, so enabling EV-DO on a cell also starts that cell’s AN and its A8/A9 link to the PCF. See the EV-DO guide.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Turn on the EV-DO carrier and HRPD packet-data path. |
channel | integer | 630 | HRPD band-class channel number. Required when enabled. 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 | true | 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. |
an_grpc_bind_addr | string | null | null (127.0.0.1:17030) | Address this cell’s AN serves its session API on. Each EV-DO cell on a host needs its own address. |
an_grpc_advertise_addr | string | null | null (same as bind) | Address the AN reports at enrollment for peers to dial. Set it when the BSC runs on another host and the bind address is loopback or 0.0.0.0. |
a9.pcf_addr | string | "127.0.0.1:17046" | PCF A9 signaling address this AN sends bearer setup and release to. Required when enabled. |
a9.pcf_a8_addr | string | "127.0.0.1:17041" | PCF-side A8 bearer address. |
a9.a8_bind_addr | string | "127.0.0.1:17040" | Address this AN binds for its A8 bearer. Each EV-DO cell needs its own. |
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 | 22 | System ID |
nid | integer | 65535 | Network ID |
base_id | integer | 1 | Base station ID |
reg_zone | integer | 0 | Registration zone |
total_zones | integer | 2 | 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 | 5 | Configuration sequence number |
acc_config_seq | integer | 5 | Access configuration sequence number |
power_up_reg | boolean | true | Require power-up registration |
parameter_reg | boolean | true | 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 | -14 | 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 | "system" | One of "overhead", "system", "user". Built-in default when the section is absent: "overhead". |
tz | string | (none) | IANA zone name; required when source = "user" |
source = "system" reads the host’s IANA zone. 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 | 200000 | TX LO hardware offset in Hz |
tx_digital_backoff | float | 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 | 512 | Internal processing block size in chips |
tx_batch_chips | integer | 6144 | TX batch size in chips (one PCG is 1536 chips for SR1) |
short_code_length_chips | integer | 32768 | Short PN code period in chips |
max_tx_lookahead_ms | integer | 3 | 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 |
ext_pref_msid_type | integer | null | null | EXT_PREF_MSID_TYPE (P_REV 11). Set with meid_reqd when p_rev is 11. |
meid_reqd | boolean | null | null | MEID_REQD (P_REV 11). Whether mobiles must include their MEID. |
tmsi_zone | integer array | [0] | TMSI zone bytes |
bcast_index | integer | 0 | Broadcast slot cycle index |
imsi_t_supported | boolean | false | Whether true IMSI (IMSI_T) is supported |
p_rev | integer | 6 | Protocol revision |
min_p_rev | integer | 3 | 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 |
max_num_alt_so | integer | 0 | Maximum alternative service options a mobile may propose |
reselect_included | boolean | false | Include the system reselection thresholds |
pilot_report | boolean | false | Ask mobiles to report pilots in access messages |
nghbr_set_entry_info | boolean | false | Include neighbor set entry handoff information |
nghbr_set_access_info | boolean | false | Include neighbor set access handoff information |
broadcast_gps_asst | boolean | false | Broadcast GPS assistance |
qpch_supported | boolean | false | Quick paging channel supported |
sdb_supported | boolean | false | Short data burst supported |
rlgain_traffic_pilot | integer | 0 | Reverse traffic-to-pilot gain adjustment |
rev_pwr_cntl_delay_incl | boolean | false | Include the reverse power control delay |
auto_msg_supported | boolean | false | Autonomous message supported |
mob_qos | boolean | false | Mobile QoS requests allowed |
enc_supported | boolean | false | Encryption supported |
use_sync_id | boolean | false | Sync ID supported |
cs_supported | boolean | false | Concurrent services supported |
bcch_supported | boolean | false | Broadcast control channel supported |
ms_init_pos_loc_sup_ind | boolean | false | Mobile-initiated position location supported |
pilot_info_req_supported | boolean | false | Pilot information request supported |
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 |
|---|---|---|---|
mult_sids | boolean | false | Whether mobiles may store multiple SIDs |
mult_nids | boolean | true | Whether mobiles may store multiple NIDs |
base_class | integer | 0 | Base station class |
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 | 35 | Registration period (timer index) |
base_lat | integer | 514084 | Base station latitude (0.25-second units) |
base_long | integer | 2012407 | Base station longitude (0.25-second units) |
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 |
nghbr_max_age | integer | 0 | Maximum age a neighbor stays in the neighbor set |
rescan | boolean | false | Tell mobiles to rescan for a system |
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 |
ext_sys_parameter | boolean | true | Announce that the Extended System Parameters Message is sent |
ext_nghbr_lst | boolean | false | Announce that the Extended Neighbor List Message is sent |
gen_nghbr_lst | boolean | false | Announce that the General Neighbor List Message is sent |
global_redirect | boolean | false | Announce that a Global Service Redirection Message is sent |
pri_nghbr_lst | boolean | false | Announce that a Private Neighbor List Message is sent |
user_zone_id | boolean | false | Announce that a User Zone Identification Message is sent |
ext_global_redirect | boolean | false | Announce that an Extended Global Service Redirection Message is sent |
ext_chan_lst | boolean | false | Announce that an Extended CDMA Channel List Message is sent |
access_parameters — reverse access channel configuration:
| Field | Type | Default | Description |
|---|---|---|---|
acc_chan | integer | 0 | Access channel number |
nom_pwr | integer | -4 | Nominal TX power adjustment (dB) |
init_pwr | integer | -4 | Initial power offset (dB) |
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 | 5 | Preamble length |
psist_0_9 | integer | 0 | Persistence value for access overload classes 0–9 |
psist_10 … psist_15 | integer | 0 | Persistence values for access overload classes 10–15 |
msg_psist | integer | 0 | Persistence modifier for message transmissions |
reg_psist | integer | 0 | Persistence modifier for registrations |
probe_pn_ran | integer | 9 | Time randomization for access probes |
acc_tmo | integer | 3 | Access timeout |
probe_bkoff | integer | 0 | Probe backoff |
bkoff | integer | 0 | Sequence backoff |
max_req_seq | integer | 3 | Maximum request sequences |
max_rsp_seq | integer | 3 | Maximum response sequences |
auth | integer | 0 | Authentication mode |
rand | integer | 0 | Random challenge value |
nom_pwr_ext | integer | 0 | Extended nominal power |
psist_emg_incl | boolean | false | Include the emergency persistence value |
acct_incl | boolean | false | Include access control based on call type |
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.
cdma_channel_list — channels (integer array, []): extra CDMA channel numbers advertised in the CDMA Channel List Message. The serving channel is always included.
general_page and order hold the defaults for General Page and Order messages the BTS builds. Leave them at their shipped values.
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 |
management
The operations endpoint the BSC enrolls this cell through. See the Multiple Cells guide.
| Field | Type | Default | Description |
|---|---|---|---|
bind_addr | string | "127.0.0.1:17024" | Management and enrollment gRPC listener. Each cell on a host needs its own. |
paging_retry
Page retransmission budget. The BTS supplies these values to the BSC at enrollment.
| Field | Type | Default | Description |
|---|---|---|---|
ack_timeout_ms | integer | 15000 | How long to wait for the mobile’s acknowledgement before reporting the page failed |
max_retries | integer | 0 | Slot-aligned over-the-air retransmissions of an unacknowledged page |
abis_timers
BTS-side Abis timers per A.S0003-A §8 Table 8-1, in milliseconds. Not present in the shipped file.
| Field | Type | Default | Description |
|---|---|---|---|
tconnb_ms | integer | 100 | §8.1 — Abis Connect timer |
tdisconb_ms | integer | 100 | §8.4 — Abis Remove Ack timer |
tbstcomb_ms | integer | 500 | §8.7 — Abis Burst Commit timer |
trelreqb_ms | integer | 100 | §8.8 — Abis BTS Release timer |
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: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 | true | Enable Forward Supplemental Channel assignment for eligible SO33/RC3 packet sessions |
f_sch_rate_bps | integer | 153600 | 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 | 3000 | Traffic assignment ACK timeout |
max_retries | integer | 5 | Maximum retransmissions |
paging_retryno longer belongs here. Set it inbts.json. The BSC takes the value from each cell at enrollment.
abis_timers
BSC-side Abis timers per A.S0003-A §8 Table 8-1. Granularity is 100 ms and ranges are 0–1000 ms except tsetupb_ms (0–500). Not present in the shipped file.
| 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 |
bts_peers
The cells this BSC serves — one entry per BTS. The BSC enrolls each peer over its operations endpoint, then brings up Abis to it. See the Multiple Cells guide.
| Field | Type | Default | Description |
|---|---|---|---|
oam_endpoint | string | "http://127.0.0.1:17024" | BTS operations gRPC endpoint the BSC enrolls through |
abis_addr | string | "127.0.0.1:5604" | BTS Abis TCP signaling address the BSC connects to |
bearer_bind_addr | string | "127.0.0.1:17022" | Local UDP address the BSC binds for this peer’s Abis bearer |
bearer_remote_addr | string | "127.0.0.1:17014" | BTS Abis bearer address the BSC sends to |
id | string | oam_endpoint | Optional stable id the management API and web UI address this cell by, kept whether or not the cell is up. Unique across peers. |
voice_timeouts
| Field | Type | Default | Description |
|---|---|---|---|
service_connect_timeout_ms | integer | 20000 | Timeout waiting for Service Connect Completion on a voice call |
release_timeout_ms | integer | 5000 | Timeout waiting for the release handshake to complete |
Other top-level fields
| Field | Type | Default | Description |
|---|---|---|---|
a1_bind_addr | string | "127.0.0.1:17013" | Address the BSC listens for the MSC’s A1 signaling on. The MSC dials this after it enrolls the base station. |
hlr_endpoint | string | "http://127.0.0.1:17019" | HLR gRPC endpoint used for subscriber lookups and registration bindings |
smsc_endpoint | string | "http://127.0.0.1:17020" | SMSC gRPC endpoint used for SMS coordination |
packet_endpoint | string | "http://127.0.0.1:17021" | Packet service gRPC endpoint the packet-data path drives sessions through |
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 |
|---|---|---|---|
mgmt_grpc_addr | string | "0.0.0.0:17017" | MSC management gRPC listen address. The web and management API use this single endpoint. |
hlr_endpoint | string | "http://127.0.0.1:17019" | HLR gRPC endpoint used for subscriber lookups |
smsc_endpoint | string | "http://127.0.0.1:17020" | SMSC gRPC endpoint used for SMS submission and delivery tracking |
packet_endpoint | string | "http://127.0.0.1:17021" | Packet core (PDSN) gRPC endpoint the management interface reads packet sessions from |
base_stations | array | one entry, bts-1 at http://127.0.0.1:17016 | The base stations this MSC serves — one entry per BSC. See base_stations. Required. |
base_stations
The base stations the MSC serves, one entry per BSC. The MSC dials each base station’s management endpoint to enroll it, then connects A1. See the Multiple Base Stations guide.
| Field | Type | Default | Description |
|---|---|---|---|
management_endpoint | string | "http://127.0.0.1:17016" | The base station’s management gRPC endpoint the MSC enrolls it through |
id | string | management_endpoint | Optional stable id the management API and web UI address this base station by. Unique across base stations. |
voice
| Field | Type | Default | Description |
|---|---|---|---|
supported_service_options | array | [32768, 3, 17, 68, 73] | Voice options the MSC accepts and may propose for mobile-terminated calls. Implemented codecs are SO1, SO3, SO68, SO70 and SO32768; the first implemented entry is the default. SO17 and SO73 are listed in the shipped file but have no codec yet, so they are never proposed and originations with them are rejected. See Voice Calls. |
wav_file | string | "config/sample-sound.wav" | WAV audio file path for fallback playback |
media_ringback_enabled | boolean | true | 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 | 3000 | Delay before automatic answer in local simulation paths |
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.release_timeout_msandvoice.service_connect_timeout_msmoved tovoice_timeoutsinbsc.json.
voice.gateway
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | 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 | true | Enable welcome SMS on registration |
text | string | "Welcome! You are now connected to a live CDMA2000 1X base station. …" | SMS body text |
originating_number | string | "0000" | Originating number shown to subscriber |
inactive_days_threshold | integer | 30 | Days of inactivity before re-sending |
sms_retry
Delivery retry settings now belong to sweep in smsc.json. Move sms_retry.enabled and sms_retry.retry_after_secs there, and rename sms_retry.sweep_interval_secs to sweep.interval_secs. The MSC’s legacy sms_retry settings no longer control the retry scan.
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.home_network
| Field | Type | Default | Description |
|---|---|---|---|
sid | integer | 22 | Home SID written into the handset’s NAM. Must match overhead.sid in bts.json, or provisioned handsets will show roaming. |
nid | integer | 65535 | Home NID written into the handset’s NAM. Must match overhead.nid in bts.json. |
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 | "http://mmsc.local.1xbts.org/" | MMSC URL written to handsets when otasp.writes.mms_uri = true. Must be a valid HTTP/HTTPS URL when used. Not present in the shipped file. |
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 | "" | Required when registration.enabled=true. |
registration.to_uri | string|null | null | To URI in REGISTER. null → sip:<contact_user>@<registrar domain>. |
registration.from_uri | string|null | null | From URI in REGISTER. null → same as to_uri. |
registration.from_name | string|null | null | Display name in the From header. |
registration.contact_user | string|null | null | User part of the Contact URI. null → auth.username. One of the two is required when registration is enabled. |
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 | "0.0.0.0" | 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 | "192.0.2.1" | Public IP placed in outgoing SDP. Set when behind NAT without STUN. The shipped placeholder must be replaced. |
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. |
queues
| Field | Type | Default | Description |
|---|---|---|---|
gateway_voice_frames | integer | 512 | Voice frames buffered between the MSC and the gateway per call. |
media_stream_frames | integer | 256 | RTP frames buffered per media stream. |
logging
| Field | Type | Default | Description |
|---|---|---|---|
summary | boolean | true | Log a summary line per call. |
control_events | boolean | true | Log call control events. |
media_frames | boolean | false | Log every media frame (very chatty). |
media_summary | boolean | true | Log periodic media statistics. |
sip_events | boolean | true | Log SIP transaction events. |
sip_trace | boolean | false | Log full SIP messages. |
sip_sdp | boolean | false | Log SDP bodies. |
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 bound on 127.0.0.1:17043 | A10 bearer transport toward the PCFs. udp_peer_addr may be omitted: the PDSN serves several PCFs and learns each one’s bearer address from its A11 registration. |
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 | "http://127.0.0.1:17023" | Aggregated event bus endpoint. 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 | "fou_tcp" | Transport mode: "tun", "fou", or "fou_tcp". Built-in default when absent: "tun". |
fou_remote | string | "127.0.0.1:17012" | 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. |
packet.mobile_ip
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enables Mobile IPv4 registration for handsets that open IPCP without an IP-Address option. Simple IP is always available. Built-in default when absent: 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 | "mn_ha" | "insecure" accepts unauthenticated requests. "mn_ha" validates the configured MN-HA association. Built-in default when absent: "insecure". |
mn_ha_spi | integer | null | 1234 | MN-HA SPI. Required with auth_mode="mn_ha" and must be greater than 255. |
mn_ha_secret_base64 | string | null | "c2VjcmV0" | Nonempty binary MN-HA shared secret encoded as base64. Required with auth_mode="mn_ha". |
allow_unverified_mn_aaa | boolean | true | 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 | "0.0.0.0:17019" | HLR service gRPC listen address. Binds all interfaces so the web dashboard container can reach it. |
postgres_dsn | string | null | "postgres://1xbts:1xbts@localhost:45432/1xbts" | PostgreSQL connection string. When unset, HLR runs without persistence. |
smsc.json
SMS storage, routing, retry, and optional SMPP hub configuration. See the SMS guide for setup and testing.
| Field | Type | Default | Description |
|---|---|---|---|
grpc_listen_addr | string | "0.0.0.0:17020" | SMSC gRPC listen address. |
postgres_dsn | string | "postgres://1xbts:1xbts@localhost:45432/1xbts" | Required PostgreSQL connection string for message storage. |
hlr_endpoint | string | "http://127.0.0.1:17019" | HLR endpoint for subscriber numbers and registration status. |
smpp | object | null | null | Optional connection to an SMPP hub. Omit for local-only messaging. |
sweep
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enables retry scans and recovery of interrupted delivery attempts. |
retry_after_secs | integer | 10 | Minimum wait after a failed attempt before retrying. |
interval_secs | integer | 10 | Time between retry scans. |
stale_after_secs | integer | 120 | Time without an outcome before an in-flight attempt can be recovered. |
smpp
| Field | Type | Default | Description |
|---|---|---|---|
role | string | Required | "client" connects to the hub. "server" listens for the hub. |
hub_addr | string | None | Required for client: hub IP address and TCP port. |
bind_addr | string | None | Required for server: local IP address and TCP port to listen on. |
system_id | string | Required | SMPP system ID used for the bind. |
password | string | Required | SMPP bind password. |
Keep credentials in config/smsc.local.json. The link uses plain TCP and reconnects automatically. It is independent of the voice gateway’s SIP configuration.
management.json
BSC management endpoint configuration. This is the address the MSC enrolls the base station through (base_stations[].management_endpoint in msc.json).
| Field | Type | Default | Description |
|---|---|---|---|
grpc_listen_addr | string | "0.0.0.0:17016" | BSC management gRPC listen address. Binds all interfaces so the packet-data gateway container can reach it. |
iq_capture_dir | string | "capture-iq-wav" | No longer read. IQ captures use iq_capture_dir in bts.json. |
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. The BTS, PDSN and other components publish to it through their events_endpoint, and the web dashboard subscribes to the unified stream.
| Field | Type | Default | Description |
|---|---|---|---|
grpc_listen_addr | string | "127.0.0.1:17023" | Event bus gRPC listen address. Required. |
subscriber_queue_capacity | integer | 1024 | Per-subscriber buffered queue size. Subscribers that fall behind beyond this depth are disconnected. |
hlr_endpoint | string | null | "http://127.0.0.1:17019" | HLR used to attach subscriber details to events. |
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 the EV-DO cells send bearer setup requests to |
a8_bearer | object | UDP-encapsulated GRE on 127.0.0.1:17041 ↔ 127.0.0.1:17040 | A8 bearer transport toward the EV-DO cell’s access network (evdo.a9 in bts.json) |
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, or placed inline under radio in bts.json. The shipped profiles are radio_uhd_b210_native.json, radio_limesdr_mini2_native.json, radio_bladerf_micro2.json, radio_soapydr_example.json and radio_network.json. The mobile station and cdma-radiod take the same files with --radio.
Common Fields
| Field | Type | Description |
|---|---|---|
kind | string | Backend: "uhd", "lime", "blade_rf", "soapy", "network" |
device | string | Device selector string (empty = first found) |
channel | integer | RF channel index |
tx_antenna / antenna | string | TX antenna port name (antenna for uhd and soapy) |
tx_gain_db | float | TX gain in dB |
rx_antenna | string | RX antenna port name |
rx_gain_db | float | RX gain in dB |
rx_reference_dbm | float | null | Optional RX reference level in dBm, shown with received power in the web UI. null leaves it uncalibrated. |
rx_power_adj | float | Radio-specific dBFS threshold adjustment for reverse-link power control |
rx_sample_delay | integer | RX timing compensation in samples |
tx_sample_delay | integer | null | TX timing compensation in samples, used by the mobile station. The shipped profiles include a starting value |
rx_batch_pcgs | integer | RX batch size in PCGs (default: 2) |
traffic_rx_continuity | boolean | Conceal sample discontinuities on active reverse traffic channels (default false; the UHD and Soapy profiles enable it) |
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, "master_clock_rate": 39321600, "clock_source": null, "time_source": null, "rx_antenna": "RX2", "rx_gain_db": 30.0, "rx_reference_dbm": null, "rx_power_adj": 0.0, "rx_sample_delay": 50, "traffic_rx_continuity": true, "rx_batch_pcgs": 2}| Field | Description |
|---|---|
master_clock_rate | USRP master clock in Hz. The default is 32× the chip rate so TX ticks align with samples. |
clock_source | Reference clock source ("external", "gpsdo", …); null uses the internal reference |
time_source | Time source; null uses the internal clock |
LimeSDR Native (kind: "lime")
{ "kind": "lime", "device": "", "channel": 0, "tx_antenna": "BAND1", "tx_gain_db": 80, "rx_antenna": "LNAW", "rx_gain_db": 50, "rx_reference_dbm": null, "rx_power_adj": 5.0, "rx_sample_delay": 97, "oversample": 0}rx_sample_delay compensates for LimeSDR hardware timing offset in the receive path. oversample is the LimeSDR oversampling ratio (0 lets the driver choose).
bladeRF Native (kind: "blade_rf")
{ "kind": "blade_rf", "device": "", "channel": 0, "tx_antenna": "TXA", "rx_antenna": "A_BALANCED", "tx_gain_db": 65, "rx_gain_db": 20, "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 |
|---|---|
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": "driver=lime", "channel": 0, "antenna": "BAND1", "tx_gain_db": 60.0, "rx_antenna": "LNAW", "rx_gain_db": 32.0, "rx_reference_dbm": null, "rx_power_adj": 0.0, "rx_sample_delay": 0, "rx_batch_pcgs": 2, "traffic_rx_continuity": true}Network (kind: "network")
Uses a radio served by cdma-radiod on another machine.
{ "kind": "network", "addr": "radio-host:50710", "data_host": "radio-host", "samples_per_packet": 2200, "tx_transport": "tcp", "rx_enabled": true}| Field | Default | Description |
|---|---|---|
addr | required | cdma-radiod control address |
data_host | host of addr | cdma-radiod host for the sample stream |
samples_per_packet | 350 | Samples per network packet, up to 2200 with jumbo frames |
tx_transport | "udp" | "udp" or "tcp" for transmit samples |
rx_enabled | true | Stream received samples back |
Device, antenna, TX gain and stream settings stay in the radio config cdma-radiod runs with.
ms.json
Mobile station identity, channel and transmit calibration. See Mobile Station for every key.
radiod_network.json
cdma-radiod listeners. See Remote Radio.
Default Ports
| Port | Protocol | Owner | Purpose |
|---|---|---|---|
| 5604 | TCP | BTS | Abis signaling listener (the BSC connects) |
| 17013 | TCP | BSC | A1 signaling listener (the MSC connects after enrolling the base station) |
| 17014 | UDP | BTS | Abis bearer (BTS side) |
| 17015 | gRPC | Voice gateway | MSC-controlled SIP/RTP bridge |
| 17016 | gRPC | BSC | Base station management (the MSC enrolls the BSC here) |
| 17017 | gRPC | MSC | Network management: the web dashboard’s endpoint |
| 17019 | gRPC | HLR | Subscriber and registration persistence |
| 17020 | gRPC | SMSC | SMS submission and delivery persistence |
| 17021 | gRPC | PDSN | Packet sessions |
| 17022 | UDP | BSC | Abis bearer (BSC side) |
| 17023 | gRPC | Event bus | Aggregated event stream |
| 17024 | gRPC | BTS | Cell management and enrollment (the BSC enrolls each cell here) |
| 17030 | gRPC | BTS | HRPD access network session API for an EV-DO cell |
| 17040 | UDP/GRE | BTS | A8 bearer for an EV-DO cell, toward the PCF |
| 17041 | UDP/GRE | PCF | A8 bearer toward the EV-DO cell |
| 17042 | UDP/GRE | PCF | A10 bearer toward the PDSN |
| 17043 | UDP/GRE | PDSN | A10 bearer toward the PCFs |
| 17044 | UDP | PCF | A11 signaling toward the PDSN |
| 17045 | UDP | PDSN | A11 signaling toward the PCFs |
| 17046 | UDP | PCF | A9 signaling from the EV-DO cells |
| 17010 | UDP | Packet gateway | FOU tunnel endpoint (fou-nat container) |
| 17011 | UDP | PDSN | FOU local port |
| 50052 | gRPC | Mobile station | cdma-ms control API (loopback by default) |
| 50710 | gRPC | cdma-radiod | Remote radio control |
| 50711 | UDP | cdma-radiod | Remote radio samples |
| 17012 | TCP | Packet gateway | FOU-TCP relay (fou-nat container) |
| 45432 | TCP | PostgreSQL | HLR and SMSC database (Docker service) |
| 3000 | HTTP | Web dashboard | 1xbts-web (Docker service) |
| 5656 | HTTP | Packet gateway | Speed test, host side (SPEEDTEST_PORT) |
Ports the handsets see on the packet-data tunnel (10.55.0.1):
| Port | Protocol | Purpose |
|---|---|---|
| 53 | DNS | Captive resolver for packet-data sessions |
| 80 | HTTP | Speed test and MMSC proxy |
| 1905 | UDP | UP.Link (HDTP) browser gateway |
| 9200, 9201 | UDP | WAP 1.x browser gateway |