Skip to content

Classify delivery-report TP-ST status ranges correctly #112

Description

@Justinabox

Summary

Text-mode delivery reports classify GSM/3GPP TP-ST status-code ranges incorrectly. _parse_cmgr_status_report() currently treats only status code 0 as delivered, 1..31 as pending, and >=32 as failed. Per 3GPP TS 23.040 TP-Status grouping, 0x00..0x1f means the short-message transaction is completed, 0x20..0x3f is a temporary error where the SC is still trying, and 0x40+ represents final failure/reserved ranges.

This means successful reports such as TP-ST 1/2 are surfaced as pending, while still-retrying temporary errors such as 32/33 are surfaced as failed.

Evidence

Affected code:

  • callstack/sms/service.py:431-436 maps only 0 to delivered, 1 <= code <= 31 to pending, and all other codes to failed.
  • tests/test_delivery_reports.py:73-99 currently locks in the inverted mapping for 31 and 32.

No-hardware probe on main (92e0f02042bb7496d7bca2fdd7f29a0625592672):

PYTHONPATH=. uv run --no-project --with pyserial-asyncio python - <<'PY'
from callstack.sms.service import _parse_cmgr_status_report

for code in (0, 1, 2, 16, 31, 32, 33, 63, 64, 96):
    line = f'+CMGR: "REC READ",6,"+120****0123",145,"24/12/25,14:30:00+04","24/12/25,14:30:05+04",{code}'
    print(code, '->', _parse_cmgr_status_report(line))
PY

Actual output:

0 -> (6, '+120****0123', 'delivered')
1 -> (6, '+120****0123', 'pending')
2 -> (6, '+120****0123', 'pending')
16 -> (6, '+120****0123', 'pending')
31 -> (6, '+120****0123', 'pending')
32 -> (6, '+120****0123', 'failed')
33 -> (6, '+120****0123', 'failed')
63 -> (6, '+120****0123', 'failed')
64 -> (6, '+120****0123', 'failed')
96 -> (6, '+120****0123', 'failed')

Spec evidence: 3GPP TS 23.040 section 9.2.3.15 defines 0000000..0011111 as "Short message transaction completed" and 0100000..0111111 as "Temporary error, SC still trying to transfer SM".

Expected behavior

  • TP-ST 0x00..0x1f should be reported as completed/delivered (or a richer completed status if the public API grows one).
  • TP-ST 0x20..0x3f should remain pending/retrying.
  • TP-ST 0x40..0x7f should be treated as failed/final unless a richer status taxonomy is added.
  • Existing delivery-report events and HTTP listing should not regress reference/recipient parsing.

Suggested fix direction

Update _parse_cmgr_status_report() to classify ranges by the TP-ST high bits instead of code == 0. Adjust the delivery-report tests so 1, 2, 31 are completed and 32, 33, 63 are pending.

Acceptance criteria

  • Regression tests cover at least one completed non-zero code (1 or 2), an SC-specific completed code (31), and a temporary retry code (32 or 33).
  • SMSDeliveryReportEvent.status no longer reports completed non-zero delivery reports as pending.
  • Still-retrying temporary failures no longer appear as final failed reports.
  • Documentation/comments around delivery report status mapping mention the TP-ST ranges.

Verification gates

git diff --check
PYTHONPATH=. uv run --no-project --with pytest --with pytest-asyncio --with pytest-aiohttp --with pyserial-asyncio --with aiosqlite pytest tests/test_delivery_reports.py -q
PYTHONPATH=. uv run --no-project --with pytest --with pytest-asyncio --with pytest-aiohttp --with pyserial-asyncio --with aiosqlite pytest tests/ -q

Duplicate check

Checked open/closed issues and PRs for delivery report TP-ST pending delivered status code, status report pending failed, and CDSI CMGR status. Closed issue #38 / merged PR #43 added reference/recipient parsing, but I did not find an issue for the TP-ST range classification bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions