1xBTS 1xBTS

OTASP

*228 is over-the-air provisioning. Dial it on the handset and the network reads the phone’s current settings (identity, dialed number, system banner, MMS URL, roaming list), optionally overwrites each one with values from the HLR, and ends with a commit that makes the writes survive a power cycle.

OTASP currently runs in soft mode by default — read-only, the network never overwrites anything. That means handsets will report “Activation Unsuccessful” at the end of a *228 session even though everything actually worked; the phone expected a Commit with downloaded blocks and got a Commit with no writes. The session detail page shows the full read-back so you can see what’s on each device. Writes can be enabled per block for advanced users (see Per-block writes below).

What you see without enabling any writes

With the shipped msc.json defaults, *228 runs end-to-end without changing anything on the handset:

  • The MSC asks the phone for each block and decodes the response.
  • Each block lands on the session timeline in the web UI as a “NAM Read-Back — …” entry showing the decoded fields (phone number, system banner, roaming list, etc.).
  • The handset’s capabilities are decoded into plain labels (dual-mode, slotted, 25 MHz bandwidth, …).
  • The Preferred Roaming List read-back shows counts and a download link for the raw file — handy for grabbing a known-good carrier PRL.

A read-only *228 is operationally safe. Use it to verify what each phone has from its prior carrier before deciding what to overwrite.

Per-block writes

In config/msc.json:

{
  "otasp": {
    "enabled": true,
    "feature_codes": ["*228"],
    "writes": {
      "cdma_analog_nam": false,
      "mdn": false,
      "cdma_nam": false,
      "home_system_tag": false,
      "mms_uri": false,
      "prl": false
    }
  }
}

Each flag corresponds to one block on the handset:

FlagWhat it writesWhen to enable
cdma_analog_namNetwork identity: phone IMSI, access class, home system ID, paging channel, roaming permissionsAfter IMSI and phone number assignments are correct in the HLR
mdnMobile Directory Number — the handset’s stored phone numberSame time as cdma_analog_nam
cdma_namSame identity / roaming fields as the analog block, for modern CDMA-only handsetsAlways pair with cdma_analog_nam
home_system_tagThe system banner shown on the phone status barAnytime
mms_uriThe MMSC URL the handset uses for picture messagesRequires otasp.mms.uri to be set
prlThe Preferred Roaming List that tells the phone which networks to camp onAfter at least one PRL has been uploaded and a default is marked (see PRL management)

Reads still happen for every block regardless of the flag. If the handset rejects any write, the session stops before commit and nothing persists on the device — half-written state is impossible by design.

Where each identity field comes from

When a block is enabled for writing, the values come from:

FieldSource
IMSI componentsThe subscriber’s HLR IMSI record (split into prefix + identifier)
Access classDerived from the subscriber’s phone number
Home system ID, network ID, paging channelThe cell’s overhead settings in bts.json
Roaming pairOne entry, the cell’s home system ID and network ID
MT call acceptanceotasp.nam_defaults in msc.json
Operator bannerotasp.system_tag.name
MMS URLotasp.mms.uri
PRLThe subscriber’s override if set, otherwise the system default PRL

That means a *228 write makes the handset’s identity match what the HLR says it is, on the cell that’s currently providing service. If the HLR IMSI prefix doesn’t match what the cell broadcasts, the phone won’t register correctly after the write — use the Generate button (below) to keep them aligned.

IMSI Generate

On the subscriber edit page, the IMSI input has a Generate button. It builds an IMSI from the cell’s broadcast settings and the subscriber’s phone number — short numbers are zero-padded, longer numbers (e.g. with a country code) use their last 10 digits. You can always edit the result manually if your numbering plan needs something different.

Per-subscriber PRL override

The runtime picks the system-default PRL — whichever one is marked default in the PRL list — for every subscriber. On the subscriber edit page, the PRL override section lets you pin a specific PRL for one subscriber, useful for test devices or carrier-specific provisioning. Clearing the dropdown restores the default fallback.

When PRL writes are enabled, the runtime checks the override first, then the system default, then skips the PRL write entirely if neither exists.

Per-subscriber Service Programming Code

The MSC has to present the handset’s lock code before any write. The shipped default is 000000, which every never-locked handset accepts.

For devices a prior carrier locked with a custom code, the Service Programming Code section on the subscriber edit page accepts the 6 digits and the MSC will use them on the next *228. Blank means “use the default 000000”.

This is only the lock code we present to the phone*228 never changes the lock code stored on a device.

PRL management

The PRLs section of the web UI is a full editor for classic and Extended PRLs. Either upload a .prl file (the format used by every commercial CDMA PRL editor) or build one from scratch with header, acquisition records, system records, and the Common Subnet Table. Every save round-trips through the encoder so the bytes you commit decode back to the structure you edited.

Mark one PRL as the system default with the Set default button on its detail page. The PRL override dropdown on the subscriber edit page pins a specific PRL for one subscriber.

Session history viewer

Every *228 session is persisted. The Recent OTASP Sessions section on the mobile and subscriber pages paginates through history. Each row shows the ESN/MEID, phone number, feature code dialed, outcome (Committed, Rejected, TimedOut, …), and how many blocks succeeded.

Click a session to see every step: capability decode, Station Class Mark, NAM Read-Back entries with all decoded fields, Block Downloaded entries showing exactly what was written, PRL push progress, and the final Commit Result.

  1. Leave all writes.* flags off. Dial *228 on a few handsets and read the session detail page. Verify the cell’s identity settings, what each phone has from a prior carrier, and the PRL summary.
  2. Use the Generate button when creating or editing subscribers so the HLR record matches what the cell broadcasts.
  3. Upload a PRL (or build one in the editor) and mark it the system default. Confirm a couple of read-backs decode cleanly before flipping writes on.
  4. Turn on cdma_analog_nam, mdn, cdma_nam first — those are the writes that make the network usable. Re-dial *228 on one device and confirm the post-write read-back matches.
  5. Turn on home_system_tag after setting the system banner in otasp.system_tag.name.
  6. Turn on mms_uri after otasp.mms.uri points at the MMSC.
  7. Turn on prl last — it’s the longest write and slightly more involved.