Packet Data
Service Options
| SO | RC | RLP | Forward Data | Status |
|---|---|---|---|---|
| SO7 | RC1 | Type 1 (8-bit SEQ) | 9.6 kbps FCH | Done |
| SO33 | RC3 | Type 3 (12-bit SEQ) | 9.6 kbps FCH, optional F-SCH to 153.6 kbps | Done |
SO33 can add a Forward Supplemental Channel for downlink data. Reverse data still uses the reverse fundamental channel; R-SCH is not implemented yet.
F-SCH Capacity
| Configured F-SCH Rate | Walsh Length | RLP Payload / 20 ms | RLP Payload Capacity | Max Packet Sessions / Carrier |
|---|---|---|---|---|
| 19.2 kbps | W(32) | 40 bytes | 16.0 kbps | 17 |
| 38.4 kbps | W(16) | 80 bytes | 32.0 kbps | 10 |
| 76.8 kbps | W(8) | 160 bytes | 64.0 kbps | 5 |
| 153.6 kbps | W(4) | 336 bytes | 134.4 kbps | 2 |
These are downlink RLP payload capacities before PPP/IP/TCP overhead and retransmissions. The session count assumes no other traffic users on the carrier; each packet session still consumes one F-FCH plus one F-SCH allocation.
Session Flow
Session Establishment
| Phase | What Happens |
|---|---|
| Radio call setup | Mobile sends Origination (SO7/SO33), BTS forwards it over Abis, and BSC assigns the traffic channel |
| Service negotiation | Service Connect specifies SO, RC, RLP parameters, and F-SCH config when enabled |
| F-SCH activation | BSC allocates a supplemental channel over Abis, sends ESCAM, and starts SCH data after the mobile accepts |
| A8/A10 setup | BSC asks the PCF client to set up radio packet-edge state; packet sessions currently cross the local packet gRPC boundary |
| RLP sync | RLP Type 1 or 3 synchronizes sequence counters |
| LCP | PPP link negotiation terminates in the packet-core path |
| IPCP | PDSN assigns an IP address from the mobile pool (10.55.0.0/24), unless opt-in Mobile IPv4 is enabled and the handset opens IPCP without an IP-Address option |
| Mobile IPv4 | Optional: PDSN sends a Foreign Agent advertisement and waits for a Mobile IPv4 Registration Request before enabling IP forwarding |
| Data transfer | IP packets flow over RLP/PPP on the radio side, then through the packet service path to TUN/FOU/FOU-TCP transport |
Simple IP vs Mobile IPv4
Simple IP is the default. In that flow, the handset includes the IPCP
IP-Address option, usually IP=0.0.0.0, and the PDSN NAKs with the assigned
pool address. Once the handset requests that assigned address and ACKs the
PDSN’s IPCP request, IPCP opens and IP forwarding starts.
Mobile IPv4 support is disabled unless pdsn.packet.mobile_ip.enabled is set.
When enabled, it is selected only if the handset opens IPCP without an
IP-Address option. The PDSN may ACK a DNS-only IPCP request, then enters a
registration-pending state instead of forwarding user traffic. It sends a
Mobile IPv4 Agent Advertisement and accepts a Registration Request on UDP/434;
only a successful Registration Reply makes the packet session active.
The implementation rejects the RFC 2290 IPCP Mobile IPv4 option. Mobile IPv4
registration happens as IP packets over PPP after IPCP opens. The current
auth_mode is insecure, intended for local and/or testing use with handsets
that send MN-HA/MN-AAA material the local PDSN does not validate yet.
PPP Session Resume
The PDSN keeps an open PPP/LCP/IPCP session cache per device identity. The key
uses IMSI and ESN when both are known, otherwise whichever identity is available.
When a packet traffic channel closes, the radio-side RLP state is discarded, but
an open PPP state can remain cached for pdsn.ppp_session_timeout_secs.
If the same mobile opens another packet traffic channel before that timeout, the new channel still performs a fresh RLP sync. After RLP reaches data transfer, the PDSN restores the cached LCP/IPCP state and resumes IP transfer without renegotiating PPP. If the cache is missing or expired, the session follows the normal RLP -> LCP -> IPCP flow.
Cached PPP sessions keep their mobile IP allocation reserved so the resumed session receives the same peer IP. Expired cached sessions are reaped periodically and release their IP allocation.
PCF / PDSN Split
The BSC reaches packet-data control through a PcfClient boundary. The integrated cdma-nib runtime currently wires that boundary to a gRPC-backed client pointed at the packet service on 127.0.0.1:17021. The packet service owns the session path before delegating payload bytes to TUN, FOU, or FOU-TCP transport.
| Boundary | Current Shape |
|---|---|
| BSC → PCF | PcfClient trait, currently wired to a gRPC-backed client in cdma-nib |
| PCF state | packet radio-edge session metadata, A8/A9-facing control, per-session A11 registration queueing before activation; reached through packet gRPC today |
| PDSN state | packet anchor state, PPP/IPCP, mobile IP allocation, A10/A11-facing state; reached through packet gRPC today |
| A8/A10 bearer transport | GRE codecs and bearer tables exist, but no UDP socket driver sends or receives GRE frames yet |
| A9/A11 signaling transport | state machines and messages exist, but the live path is local service RPCs, not standards UDP signaling |
Real standards packet-core separation is still TODO: replace the local packet service path with BSC ↔ PCF A8/A9 transport and PCF ↔ PDSN A10/A11 transport. The FOU and FOU-TCP options are IP offload paths behind the current packet service; they are not the standards A10 GRE bearer.
Duplicate Service Connect Completion handling is idempotent. If the mobile retransmits completion during setup, the BSC does not leak an extra packet session. The PCF queues pending A11 registrations per packet session while the PDSN-side transport comes up, then drains them after activation. If an existing packet traffic channel is converted to voice, the BSC closes the old packet session after voice service connects.
IP Routing
| Parameter | Default |
|---|---|
| Subnet | 10.55.0.0/24 |
| Gateway | 10.55.0.1 |
| Mobile pool | 10.55.0.2 – 10.55.0.254 |
| DNS | 10.55.0.1, 10.55.0.1 |
Transport modes: TUN (local kernel interface, requires root), FOU (UDP tunnel), or FOU-TCP (TCP relay path).
The default DNS points mobiles at the packet gateway resolver. In the compose
stack, that resolver serves the local speed test at http://speed/ and
http://speed.local.1xbts.org/.
See Packet Data Setup for FOU configuration.
Configuration
{
"packet_grpc_listen_addr": "127.0.0.1:17021",
"ppp_session_timeout_secs": 1800,
"packet": {
"transport": "fou_tcp",
"fou_remote": "127.0.0.1:17012",
"fou_local_port": 17011,
"gateway_ip": "10.55.0.1",
"primary_dns": "10.55.0.1",
"secondary_dns": "10.55.0.1",
"enable_vj_compression_default": false,
"mobile_ip": {
"enabled": false,
"fa_address": "10.55.0.1",
"home_agent_address": "10.55.0.1",
"advertisement_count": 3,
"advertisement_lifetime_secs": 9000,
"registration_lifetime_secs": 1200,
"auth_mode": "insecure",
"home_address_pool": null
}
}
}
enable_vj_compression_default controls whether the PDSN asks mobiles to send
Van Jacobson TCP/IP header-compressed PPP packets. Leave it false unless you
are testing a handset that handles VJ reliably; mobiles can still request VJ
themselves for downlink compression.
mobile_ip.enabled controls Mobile IPv4 registration. Sprint handsets are
known to require this when they complete IPCP without taking a Simple IP
address. Leave it false for the normal Simple IP path. When enabled,
registration_lifetime_secs must be lower than ppp_session_timeout_secs, and
auth_mode currently accepts only "insecure".
F-SCH is controlled from bsc.json:
{
"traffic_assignment": {
"enable_f_sch": true,
"f_sch_rate_bps": 153600
}
}
Valid F-SCH rates are 19200, 38400, 76800, and 153600. 9600 is the fundamental-channel data rate and is not valid for f_sch_rate_bps.
The configured rate is currently a global packet-data policy: every eligible SO33 packet session gets the same F-SCH rate. Future burstable SCH support is planned, where the BSC can allocate and release supplemental channels dynamically based on traffic demand.
Dashboard
The /packets page shows active sessions, assigned IPs, RLP statistics, PPP state, and throughput.
Live session events
PDSN publishes session bind/unbind events to the aggregated event bus. Subscribe to EVENT_SOURCE_PDSN on events.v1.EventService to receive a PacketSessionBound when a mobile acquires an IP and a PacketSessionUnbound when the session is torn down:
grpcurl -plaintext -d '{"source_filter":["EVENT_SOURCE_PDSN"]}' \
localhost:17023 events.v1.EventService/ListenEvents
See gRPC API → EventService for the full event schema.