Diameter¶
The diameter namespace exposes the IMS Diameter interfaces — Cx (HSS),
Rx (PCRF), Sh (HSS AS), and Rf (offline charging) — plus a unified inbound
@diameter.on_request hook for serving requests (RAR, PNR, ASR, …).
from siphon import diameter
@diameter.on_request
async def handle(request):
if request.command_name == "RAR":
return request.answer(2001)
return request.reject(3002)
What siphon answers when the handler does not¶
A request the script does not answer itself gets one of three codes, and they are meant to be distinguishable at the peer:
| Result-Code | When |
|---|---|
3002 DIAMETER_UNABLE_TO_DELIVER |
Nothing serves the request: no @diameter.on_request matched its application and command, or the handler that matched returned None. |
5012 DIAMETER_UNABLE_TO_COMPLY |
siphon has a handler and could not carry it out: it raised, returned something that is not a DiameterAnswer, or produced an answer that would not serialize. Logged at error with the handler's name and the exception. |
5014 DIAMETER_INVALID_AVP_LENGTH |
The inbound message did not parse. |
The 3002/5012 split matters most on Ro, where a 3002 to a CCR-UPDATE is read
as a credit denial and the call is torn down. A handler that raises is a fault
on siphon's side of the interface, not a decision about the subscriber's
credit, so it answers 5012 — which lets an operator tell a script fault from
an OCS denial instead of seeing every live call die at its first
re-authorisation with nothing pointing at the script.
Returning None stays 3002 on purpose: declining is a routing answer, and it
is the documented way for a handler to say "not mine".
Rx: QoS and bearer events¶
diameter.rx_aar asks the PCRF to authorize the media of a call. With
specific_actions it also subscribes to IP-CAN events (TS 29.214 §5.3.13),
one Specific-Action AVP per value. The PCRF reports each event in an RAR,
which arrives at @diameter.on_request. The values and their names are listed
under rx_aar below; 0 and 5 are void in TS 29.214 and raise ValueError,
like any value it does not define.
from siphon import diameter, qos
result = await diameter.rx_aar(
framed_ip=request.source_ip,
media_components=qos.media_flows_from_sdp(
offer=request.body, answer=reply.body, direction="orig",
),
# loss of bearer, release of bearer, failed resources allocation
specific_actions=[2, 4, 9],
)
Subscribe in the first AAR for a session. Apart from one-time actions such as ACCESS_NETWORK_INFO_REPORT, a Specific-Action only counts there and then holds for the life of the Rx session.
Every AAR carries Rx-Request-Type: INITIAL_REQUEST, or UPDATE_REQUEST when
session_id reuses an existing session (TS 29.214 §4.4.1, §4.4.2). It is sent
without the M-bit, so a PCRF that does not know the AVP skips it. When the Rx
peer has a destination_host configured, the AAR carries it as
Destination-Host.
diameter namespace¶
Mock Diameter namespace for testing scripts that use from siphon import diameter.
Exposes connection status and Cx/Rx methods matching the Rust DiameterNamespace.
Example::
import asyncio
from siphon_sdk import mock_module
mock_module.install()
diameter = mock_module.get_diameter()
diameter.add_peer("hss1", connected=True)
diameter.set_default_server_name("sip:scscf.ims.example.com:6060")
from siphon import diameter
assert diameter.is_connected("hss1")
# The request methods are awaitable, as they are in siphon, so a
# synchronous test drives one through asyncio.run.
result = asyncio.run(diameter.cx_uar("sip:alice@ims.example.com"))
assert result["server_name"] == "sip:scscf.ims.example.com:6060"
config
property
¶
Read-only view of the parsed diameter config (tenants/listen).
Set it in tests with diameter.set_config({...}).
event_sink
property
¶
The generic event sink (diameter.event_sink.emit(row)).
is_connected
¶
Check if a Diameter peer is connected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
peer_name
|
str
|
Name of the peer (e.g. "hss1"). |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
peer_count
¶
Get the number of connected peers.
Returns:
| Type | Description |
|---|---|
int
|
Count of peers that are marked as connected. |
decode_isdn_address
¶
Decode an ISDN-AddressString to its E.164 digit string.
Accepts the raw AVP bytes (0x91 ToN/NPI + TBCD digits) or an
already-decoded str — the latter is returned unchanged, so it is
safe to call on the result of req.get_avp("MSISDN") regardless of
the AVP's dictionary type. A missing ToN/NPI byte is tolerated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Union[bytes, str]
|
|
required |
Returns:
| Type | Description |
|---|---|
str
|
The E.164 digit string (no leading |
Example
diameter.decode_isdn_address(req.get_avp("MSISDN")) '31612345678'
encode_isdn_address
¶
Encode an E.164 digit string as an ISDN-AddressString — one ToN/NPI octet followed by the TBCD digit string.
Use when building a raw OctetString AVP by hand for an unknown code;
dictionary-typed AVPs (MSISDN / SC-Address / SGSN-Number /
MME-Number-for-MT-SMS) encode digit strings automatically. A leading
+ is stripped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
digits
|
str
|
The E.164 number as a digit string. |
required |
ton_npi
|
int
|
ToN/NPI byte (default |
TON_NPI_INTERNATIONAL_E164
|
Returns:
| Type | Description |
|---|---|
bytes
|
The encoded ISDN-AddressString |
Example
diameter.encode_isdn_address("31612345678") b'\x91\x13\x16\x32\x54\x76\xf8'
cx_uar
async
¶
cx_uar(
public_identity: str,
visited_network_id: Optional[str] = None,
user_auth_type: Optional[int] = None,
) -> Optional[dict]
Send a User-Authorization-Request to discover S-CSCF assignment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_identity
|
str
|
User's public identity (e.g. |
required |
visited_network_id
|
Optional[str]
|
Visited network identifier. |
None
|
user_auth_type
|
Optional[int]
|
User-Authorization-Type AVP value (3GPP TS 29.229).
|
None
|
Returns:
| Type | Description |
|---|---|
Optional[dict]
|
Dict with |
cx_sar
async
¶
cx_sar(
public_identity: str,
server_name: Optional[str] = None,
assignment_type: int = 1,
) -> Optional[dict]
Send a Server-Assignment-Request after REGISTER auth.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_identity
|
str
|
User's public identity. |
required |
server_name
|
Optional[str]
|
This S-CSCF's SIP URI. |
None
|
assignment_type
|
int
|
Server-Assignment-Type (default 1 = REGISTRATION). |
1
|
Returns:
| Type | Description |
|---|---|
Optional[dict]
|
Dict with |
cx_lir
async
¶
Send a Location-Info-Request to find the serving S-CSCF.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_identity
|
str
|
Target user's public identity. |
required |
Returns:
| Type | Description |
|---|---|
Optional[dict]
|
Dict with |
rx_aar
¶
rx_aar(
session_id: Optional[str] = None,
framed_ip: Optional[str] = None,
framed_ipv6: Union[str, bytes, None] = None,
media_components: Optional[list] = None,
af_application_id: str = "IMS Services",
subscription_id: Optional[tuple] = None,
specific_actions: Optional[list[int]] = None,
) -> Awaitable[Optional[dict]]
Send an Rx AA-Request for QoS resource reservation.
Without session_id the AAR is sent as Rx-Request-Type
INITIAL_REQUEST; with one it is UPDATE_REQUEST (TS 29.214 §4.4.1,
§4.4.2). The Rx peer's configured destination_host, if set, goes
out as Destination-Host.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
Optional[str]
|
Reuse an existing Rx session ID (modification AAR
per TS 29.214 §4.4.5). |
None
|
framed_ip
|
Optional[str]
|
UE IPv4 address (Framed-IP-Address AVP). |
None
|
framed_ipv6
|
Union[str, bytes, None]
|
UE IPv6 address (str or bytes). |
None
|
media_components
|
Optional[list]
|
list of media-component dicts shaped per TS 29.214 §5.3.7 (see project docs for the full schema). |
None
|
af_application_id
|
str
|
AF-Application-Identifier (default
|
'IMS Services'
|
subscription_id
|
Optional[tuple]
|
Optional |
None
|
specific_actions
|
Optional[list[int]]
|
Events the PCRF should report back, as ints.
Each entry becomes one Specific-Action AVP
(TS 29.214 §5.3.13).
|
None
|
Returns:
| Type | Description |
|---|---|
Awaitable[Optional[dict]]
|
Dict with |
Raises:
| Type | Description |
|---|---|
ValueError
|
A |
TypeError
|
|
Example::
result = await diameter.rx_aar(
framed_ip=request.source_ip,
media_components=components,
# loss of bearer, release of bearer, failed allocation
specific_actions=[2, 4, 9],
)
rx_str
async
¶
Send an Rx Session-Termination-Request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
The Rx session ID from the original AAR. |
required |
Returns:
| Type | Description |
|---|---|
Optional[int]
|
Result code (int), or |
sh_udr
async
¶
sh_udr(
public_identity: str,
data_reference: Union[int, list[int]],
service_indication: Optional[str] = None,
) -> Optional[dict]
Send a Sh User-Data-Request to fetch user profile data from the HSS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_identity
|
str
|
Target user's public identity. |
required |
data_reference
|
Union[int, list[int]]
|
Data-Reference int or list[int] (TS 29.328 §7.6). |
required |
service_indication
|
Optional[str]
|
e.g. |
None
|
Returns:
| Type | Description |
|---|---|
Optional[dict]
|
Dict with |
sh_pur
async
¶
sh_pur(
public_identity: str,
data_reference: int,
xml: str,
service_indication: Optional[str] = None,
) -> Optional[dict]
Send a Sh Profile-Update-Request to push user profile data to the HSS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_identity
|
str
|
Target user's public identity. |
required |
data_reference
|
int
|
Data-Reference (e.g. |
required |
xml
|
str
|
UTF-8 XML payload. |
required |
service_indication
|
Optional[str]
|
e.g. |
None
|
Returns:
| Type | Description |
|---|---|
Optional[dict]
|
Dict with |
sh_snr
async
¶
sh_snr(
public_identity: str,
data_reference: Union[int, list[int]],
subs_req_type: int,
service_indication: Optional[str] = None,
) -> Optional[dict]
Send a Sh Subscribe-Notifications-Request to the HSS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_identity
|
str
|
Target user's public identity. |
required |
data_reference
|
Union[int, list[int]]
|
Data-Reference int or list[int] to subscribe to. |
required |
subs_req_type
|
int
|
|
required |
service_indication
|
Optional[str]
|
e.g. |
None
|
Returns:
| Type | Description |
|---|---|
Optional[dict]
|
Dict with |
add_peer
¶
Register a mock Diameter peer (test helper).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Peer name. |
required |
connected
|
bool
|
Whether the peer should appear as connected. |
True
|
set_default_server_name
¶
Set a default S-CSCF name returned by UAR/LIR when no per-user response is configured.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
server_name
|
str
|
S-CSCF SIP URI (e.g. |
required |
set_uar_response
¶
set_uar_response(
public_identity: str,
result_code: int = 2001,
server_name: Optional[str] = None,
) -> None
Configure a mock UAA response for a specific user (test helper).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_identity
|
str
|
User's public identity. |
required |
result_code
|
int
|
Diameter result code (default 2001 = SUCCESS). |
2001
|
server_name
|
Optional[str]
|
Assigned S-CSCF URI. |
None
|
set_sar_response
¶
set_sar_response(
public_identity: str,
result_code: int = 2001,
user_data: Optional[str] = None,
) -> None
Configure a mock SAA response for a specific user (test helper).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_identity
|
str
|
User's public identity. |
required |
result_code
|
int
|
Diameter result code. |
2001
|
user_data
|
Optional[str]
|
iFC XML string from user profile. |
None
|
set_lir_response
¶
set_lir_response(
public_identity: str,
result_code: int = 2001,
server_name: Optional[str] = None,
) -> None
Configure a mock LIA response for a specific user (test helper).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_identity
|
str
|
User's public identity. |
required |
result_code
|
int
|
Diameter result code. |
2001
|
server_name
|
Optional[str]
|
Serving S-CSCF URI. |
None
|
set_aar_response
¶
Configure a mock AAA response for a specific Rx session (test helper).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Rx session ID. |
required |
result_code
|
int
|
Diameter result code. |
2001
|
rf_acr_start
async
¶
rf_acr_start(
*,
calling_party: Optional[str] = None,
called_party: Optional[str] = None,
sip_method: Optional[str] = None,
role_of_node: Optional[str] = None,
node_functionality: Optional[str] = None,
ims_charging_identifier: Optional[str] = None,
user_session_id: Optional[str] = None,
originating_ioi: Optional[str] = None,
terminating_ioi: Optional[str] = None,
application_server: Optional[str] = None,
application_provided_called_party_address: Optional[
str
] = None,
incoming_trunk_group_id: Optional[str] = None,
outgoing_trunk_group_id: Optional[str] = None,
visited_network_id: Optional[str] = None,
user_name: Optional[str] = None,
subscription_id: Optional[Union[str, list[str]]] = None,
subscription_id_type: Optional[
Union[str, list[str]]
] = None,
cause_code: Optional[int] = None,
service_context_id: Optional[str] = None,
peer: Optional[str] = None
) -> Optional[dict]
Send Rf ACR-START to the CDF (TS 32.299 §6.2.2).
rf_acr_interim
async
¶
rf_acr_interim(
session_id: str,
record_number: int,
*,
calling_party: Optional[str] = None,
called_party: Optional[str] = None,
sip_method: Optional[str] = None,
role_of_node: Optional[str] = None,
node_functionality: Optional[str] = None,
ims_charging_identifier: Optional[str] = None,
user_session_id: Optional[str] = None,
originating_ioi: Optional[str] = None,
terminating_ioi: Optional[str] = None,
application_server: Optional[str] = None,
application_provided_called_party_address: Optional[
str
] = None,
incoming_trunk_group_id: Optional[str] = None,
outgoing_trunk_group_id: Optional[str] = None,
visited_network_id: Optional[str] = None,
user_name: Optional[str] = None,
subscription_id: Optional[Union[str, list[str]]] = None,
subscription_id_type: Optional[
Union[str, list[str]]
] = None,
cause_code: Optional[int] = None,
service_context_id: Optional[str] = None,
peer: Optional[str] = None
) -> Optional[dict]
Send Rf ACR-INTERIM (mid-session accounting update).
rf_acr_stop
async
¶
rf_acr_stop(
session_id: str,
record_number: int,
*,
termination_cause: int = 1,
calling_party: Optional[str] = None,
called_party: Optional[str] = None,
sip_method: Optional[str] = None,
role_of_node: Optional[str] = None,
node_functionality: Optional[str] = None,
ims_charging_identifier: Optional[str] = None,
user_session_id: Optional[str] = None,
originating_ioi: Optional[str] = None,
terminating_ioi: Optional[str] = None,
application_server: Optional[str] = None,
application_provided_called_party_address: Optional[
str
] = None,
incoming_trunk_group_id: Optional[str] = None,
outgoing_trunk_group_id: Optional[str] = None,
visited_network_id: Optional[str] = None,
user_name: Optional[str] = None,
subscription_id: Optional[Union[str, list[str]]] = None,
subscription_id_type: Optional[
Union[str, list[str]]
] = None,
cause_code: Optional[int] = None,
service_context_id: Optional[str] = None,
peer: Optional[str] = None
) -> Optional[dict]
Send Rf ACR-STOP. termination_cause per RFC 6733 §8.15
(1=LOGOUT, 4=ADMINISTRATIVE, 5=LINK_BROKEN, 8=SESSION_TIMEOUT).
rf_acr_event
async
¶
rf_acr_event(
*,
calling_party: Optional[str] = None,
called_party: Optional[str] = None,
sip_method: Optional[str] = None,
role_of_node: Optional[str] = None,
node_functionality: Optional[str] = None,
ims_charging_identifier: Optional[str] = None,
user_session_id: Optional[str] = None,
originating_ioi: Optional[str] = None,
terminating_ioi: Optional[str] = None,
application_server: Optional[str] = None,
application_provided_called_party_address: Optional[
str
] = None,
incoming_trunk_group_id: Optional[str] = None,
outgoing_trunk_group_id: Optional[str] = None,
visited_network_id: Optional[str] = None,
user_name: Optional[str] = None,
subscription_id: Optional[Union[str, list[str]]] = None,
subscription_id_type: Optional[
Union[str, list[str]]
] = None,
cause_code: Optional[int] = None,
service_context_id: Optional[str] = None,
peer: Optional[str] = None
) -> Optional[dict]
Send Rf ACR-EVENT (one-shot accounting — REGISTER/MESSAGE).
set_rf_result_code
¶
Override the Result-Code returned by every Rf ACA (default 2001).
set_rf_interim_interval
¶
Configure the Acct-Interim-Interval returned in ACA-START.
captured_acrs
¶
Return all ACRs the script has emitted via rf_acr_*.
Returns a fresh copy on each call. Useful for asserting on accounting flows in tests.
ro_ccr_initial
async
¶
ro_ccr_initial(
subscription_id: str,
*,
subscription_id_type: Optional[str] = None,
service_context_id: Optional[str] = None,
requested_seconds: Optional[int] = None,
rating_group: Optional[int] = None,
service_identifier: Optional[int] = None,
calling_party: Optional[str] = None,
called_party: Optional[str] = None,
sip_method: Optional[str] = None,
role_of_node: Optional[str] = None,
node_functionality: Optional[str] = None,
ims_charging_identifier: Optional[str] = None,
user_session_id: Optional[str] = None,
originating_ioi: Optional[str] = None,
terminating_ioi: Optional[str] = None,
application_server: Optional[str] = None,
application_provided_called_party_address: Optional[
str
] = None,
incoming_trunk_group_id: Optional[str] = None,
outgoing_trunk_group_id: Optional[str] = None,
visited_network_id: Optional[str] = None,
cause_code: Optional[int] = None,
peer: Optional[str] = None
) -> Optional[dict]
Send a Ro CCR-INITIAL and return the CCA dict.
Returns {result_code, session_id, request_number, granted_time,
validity_time, final_unit_action}. For SCUR, thread the returned
session_id through :meth:ro_ccr_update / :meth:ro_ccr_terminate.
Example
answer = await diameter.ro_ccr_initial( "+310000000001", requested_seconds=30, rating_group=100, calling_party="sip:alice@ims", called_party="sip:bob@ims") if answer["result_code"] != 2001: call.reject(402, "Payment Required")
ro_ccr_update
async
¶
ro_ccr_update(
subscription_id: str,
session_id: str,
request_number: int,
*,
subscription_id_type: Optional[str] = None,
service_context_id: Optional[str] = None,
used_seconds: Optional[int] = None,
requested_seconds: Optional[int] = None,
rating_group: Optional[int] = None,
service_identifier: Optional[int] = None,
peer: Optional[str] = None
) -> Optional[dict]
Send a Ro CCR-UPDATE reporting usage and requesting the next quota.
ro_ccr_terminate
async
¶
ro_ccr_terminate(
subscription_id: str,
session_id: str,
request_number: int,
*,
subscription_id_type: Optional[str] = None,
service_context_id: Optional[str] = None,
used_seconds: Optional[int] = None,
rating_group: Optional[int] = None,
service_identifier: Optional[int] = None,
peer: Optional[str] = None
) -> Optional[dict]
Send a Ro CCR-TERMINATION closing the session with final usage.
ro_ccr_event
async
¶
ro_ccr_event(
subscription_id: str,
*,
subscription_id_type: Optional[str] = None,
service_context_id: Optional[str] = None,
requested_action: Optional[int] = None,
calling_party: Optional[str] = None,
called_party: Optional[str] = None,
node_functionality: Optional[str] = None,
user_session_id: Optional[str] = None,
originator_address: Optional[str] = None,
recipient_address: Optional[str] = None,
sm_message_type: Optional[int] = None,
sm_service_type: Optional[int] = None,
sms_node: Optional[int] = None,
data_coding_scheme: Optional[int] = None,
peer: Optional[str] = None
) -> Optional[dict]
Send a one-shot Ro CCR-EVENT (IEC — SMS/RCS DIRECT_DEBITING).
Example
answer = await diameter.ro_ccr_event( "+310000000001", service_context_id="32274@3gpp.org", originator_address="+310000000001", recipient_address="+310000000002", sm_message_type=0) if answer["result_code"] != 2001: request.reply(402, "Payment Required") # no balance
set_ro_result_code
¶
Override the Result-Code returned by every Ro CCA (default 2001).
set_ro_granted_time
¶
Configure the granted CC-Time (seconds) returned in a successful CCA.
set_ro_final_unit_action
¶
Configure the Final-Unit-Action (0=TERMINATE) returned in the CCA.
captured_ccrs
¶
Return all CCRs the script has emitted via ro_ccr_* (fresh copy).
on_inbound_cer
staticmethod
¶
Register the server-mode CER identity callback.
Called for an already-authenticated peer (both Rust auth gates have
passed) with (peer_addr, peer_name, asserted_origin_host). Return
(origin_host, origin_realm) to accept, or None to reject.
Example::
@diameter.on_inbound_cer
def cer_received(peer_addr, peer_name, asserted_origin_host):
identity = diameter.config["tenants"]["default"]["identity"]
return identity["origin_host"], identity["origin_realm"]
on_request
staticmethod
¶
Register the server-mode inbound-request dispatcher.
Called for inbound requests (R-bit set). Return req.reject(code),
await req.forward_to(peer, ...), req.answer(code), or None
(→ DIAMETER_UNABLE_TO_DELIVER, 3002).
An optional command filter scopes the handler — bare
@diameter.on_request (all), @diameter.on_request("ULR"),
"ULR|AIR", or app-qualified "S6a:ULR". The mock treats it as an
identity decorator either way.
The filter has the same shape as @proxy.on_request("INVITE") but
not the same dispatch rule: exactly one Diameter handler runs per
request — the most specific filter that matches — and a bare
@diameter.on_request is the lowest-specificity fallback, reached
only when nothing more specific matched. @proxy.on_request instead
runs every handler whose filter matches, unfiltered ones included.
Deliberate, not an inconsistency: a Diameter request needs exactly one
answer, so one handler must own it. A SIP request can legitimately
interest several handlers at once (metrics, lawful intercept,
authentication, routing), so they compose — and
request.stop_propagation() is how one of them claims the outcome.
Example::
@diameter.on_request("S6a:ULR")
async def update_location(req):
return req.answer(2001)
on_reply
staticmethod
¶
Register the server-mode answer-rewrite hook.
Called with (req, answer) on the answer an on_request handler
produced — relayed via forward_to or built by answer/reject
— just before it goes back upstream. A central place to rewrite answer
AVPs for every reply (topology hiding, Origin-Host/Result-Code mapping).
Mutate answer in place; the return value is ignored.
on_request_completed
staticmethod
¶
Register the server-mode post-answer hook.
Called after the answer is sent upstream with
(req, answer, latency_us) — typically to emit an event.
peer_pool
¶
Build a mock backend peer pool. target is a peer name or list of
names; tenant is an optional scope label (defaults to "default" —
single-domain servers leave it unset). Register backends with
:meth:add_peer(connected=True).
ip_in_cidr
staticmethod
¶
Whether addr falls within cidr (mirrors the Rust helper).
s6a_air
async
¶
s6a_air(
imsi: str,
visited_plmn_id: bytes,
num_vectors: int = 1,
immediate_response_preferred: bool = True,
resync_info: Optional[bytes] = None,
peer: Optional[str] = None,
) -> Optional[dict]
Mock Authentication-Information. Returns canned E-UTRAN vectors;
configure with :meth:set_air_response.
s6a_ulr
async
¶
s6a_ulr(
imsi: str,
visited_plmn_id: bytes,
rat_type: int = 1004,
ulr_flags: int = 0,
peer: Optional[str] = None,
) -> Optional[dict]
Mock Update-Location. Returns a 2001 with subscription data present.
s6a_purge_ue
async
¶
s6a_purge_ue(
imsi: str,
pur_flags: Optional[int] = None,
peer: Optional[str] = None,
) -> Optional[dict]
Mock Purge-UE. Returns a 2001.
s6c_srr
async
¶
Mock Send-Routing-Info-for-SM. Configure responses via
:meth:set_srr_response; default is a successful answer with
an empty served-node (test scripts can detect the unset case).
set_srr_response
¶
set_srr_response(
msisdn: str,
*,
result_code: int = 2001,
user_name: Optional[str] = None,
sgsn_number: Optional[str] = None,
mme_number_for_mt_sms: Optional[str] = None,
mme_name: Optional[str] = None,
mme_realm: Optional[str] = None,
sgsn_name: Optional[str] = None,
sgsn_realm: Optional[str] = None,
msc_number: Optional[str] = None,
experimental_result_code: Optional[int] = None
) -> None
mme_name / mme_realm are the located node's Diameter identity from the
grouped Serving-Node — for a UE doing SMS over NAS on 5G that is the SMSF
(TS 29.338 §6.3.2.4), which is what an MT-Forward-Short-Message is addressed to.
s6c_rsr
async
¶
Mock Report-SM-Delivery-Status. Records the call on
self.rsrs for assertions and returns a 2001.
sgd_tfr
async
¶
sgd_tfr(
user_name: str,
sc_address: str,
sm_rp_ui: bytes,
smsmi_correlation_id: Optional[str] = None,
sm_rp_mti: Optional[int] = None,
destination_host: Optional[str] = None,
destination_realm: Optional[str] = None,
) -> Optional[dict]
Mock MT-Forward-Short-Message. Records the TPDU on self.tfrs
for assertions; returns 2001 unless overridden via
:meth:set_tfr_response.
destination_host is the node the preceding SRI-SM located (mme_name).
Omitting it falls back to static peer config, which addresses the request at
whatever the relay's catch-all route resolves to rather than at the serving node.
send_request
async
¶
send_request(
command: str,
application: str,
peer: Optional[str] = None,
timeout_ms: int = 10000,
**avps: Any
) -> Optional[dict]
Generic Diameter request by spec name.
Records every call on self.generic_requests for assertions.
Returns a default 2001-success answer unless overridden via
:meth:set_generic_response.
set_generic_response
¶
Configure a mock answer for send_request(command, application, ...).
set_udr_response
¶
set_udr_response(
public_identity: str,
result_code: int = 2001,
user_data: Optional[str] = None,
) -> None
Configure a mock UDA response for a specific user (test helper).
set_pur_response
¶
Configure a mock PUA response for a specific user (test helper).
set_snr_response
¶
Configure a mock SNA response for a specific user (test helper).
DiameterRequest¶
The inbound request passed to @diameter.on_request.
Mock DiameterRequest passed to @diameter.on_request in tests.
Construct one in your test and invoke your handler with it.
answer
¶
Build a local answer to serve this request (HSS-style). Populate it
with :meth:MockDiameterAnswer.set_avp, including grouped AVPs (pass a
list of (code, value[, vendor]) child tuples as the value).
forward_to
async
¶
Mock relay — returns a 2001 success answer (override in tests by monkeypatching if a different result is needed).
DiameterAnswer¶
The value a handler returns via request.answer(...) / request.reject(...).
Mock DiameterAnswer — the value a handler returns / forwards.