mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr.git
synced 2025-11-02 13:13:29 +00:00
492 lines
20 KiB
Plaintext
492 lines
20 KiB
Plaintext
== Distributed GSM / Multicast MS Lookup
|
|
|
|
Distributed GSM (D-GSM) allows independent mobile core network stacks to provide voice, SMS and Roaming services to each
|
|
other, without the need for centralised entities or administration authority, and in a way that is resilient against
|
|
unstable network links between sites.
|
|
|
|
D-GSM aims at communal networks, where several independent sites, let's call them villages, each have a full mobile core
|
|
network infrastructure. It elegantly provides ad-hoc service for subscribers moving across villages, and allows villages
|
|
to dynamically join or leave the cooperative network without the need for configuration changes at other sites.
|
|
|
|
A challenge for linking separate sites is to find the current location of a subscriber. Typically, in mobile networks, a
|
|
centralized entity keeps track of where to Page for subscribers. Running several fully independent sites with unreliable
|
|
links between them makes it hard to provide such centralisation.
|
|
|
|
D-GSM finds subscribers by mslookup, a service provided by OsmoHLR, typically using multicast DNS queries. This allows
|
|
routing Location Updating requests, calls, and SMS to the right site without administrative delay nor the need for a
|
|
reliable link to a central database.
|
|
|
|
D-GSM is highly resilient against single sites or links becoming temporarily unavailable. Service between still
|
|
reachable sites simply continues; Service to a disconnected site resumes as soon as it becomes reachable again.
|
|
|
|
This brings an entirely new paradigm to mobile core network infrastructure: as sites become reachable on the IP network
|
|
and join the common IP multicast group, services between them become available immediately. Basically, the only premise
|
|
is that IP routing and multicast works across sites, and that each site uses unique IPA names in the GSUP config.
|
|
|
|
This chapter describes how D-GSM and mslookup work, and how to configure sites to use D-GSM, using Osmocom core network
|
|
infrastructure.
|
|
|
|
=== Finding Subscribers: mslookup Clients
|
|
|
|
There are two fundamentally distinct subscriber lookups provided by the mslookup service.
|
|
|
|
==== Find the Current Location of an MSISDN
|
|
|
|
[[fig_dgsm_connect]]
|
|
.mslookup for connecting subscribers: Alice is visiting village C; a phone call gets routed directly to her current location independently from her resident village infrastructure
|
|
[graphviz]
|
|
----
|
|
digraph G {
|
|
rankdir=LR
|
|
|
|
subgraph cluster_village_b {
|
|
label="Village B"
|
|
ms_bob [label="Bob\n(from village B)",shape=box]
|
|
pbx_b [label="SIP B"]
|
|
}
|
|
|
|
subgraph cluster_village_c {
|
|
label="Village C"
|
|
ms_alice [label="Alice\n(from village A)",shape=box]
|
|
msc_c [label="MSC C"]
|
|
hlr_c [label="HLR C"]
|
|
sip_c [label="SIP C"]
|
|
}
|
|
|
|
ms_alice -> msc_c [style=dashed,arrowhead=none]
|
|
msc_c -> hlr_c [label="attached",style=dashed,arrowhead=none]
|
|
ms_bob -> pbx_b [label="call Alice"]
|
|
pbx_b -> hlr_c [label="mslookup by MSISDN",style=dotted,dir=both]
|
|
pbx_b -> sip_c -> msc_c -> ms_alice [label="call"]
|
|
}
|
|
----
|
|
|
|
For example, if a subscriber is currently visiting another village, establish a phone call / send SMS towards that
|
|
village.
|
|
|
|
- To deliver a phone call, a SIP agent integrates an mslookup client to request the SIP service of an MSISDN's current
|
|
location (example: <<dgsm_conf_dialplan>>). It receives an IP address and port to send the SIP Invite to.
|
|
|
|
- To deliver an SMS, an ESME integrates an mslookup client to request the SMPP service of an MSISDN's current location
|
|
(example: <<dgsm_conf_esme_smpp>>).
|
|
|
|
The current location of a subscriber may change at any time, and, when moving across locations, a subscriber may
|
|
suddenly lose reception to the previous location without explicitly detaching. Hence an mslookup request for the current
|
|
location of an MSISDN may get numerous responses. To find the currently valid location, mslookup includes the age of the
|
|
subscriber record, i.e. how long ago the subscriber was last reached. The one response with the youngest age reflects
|
|
the current location.
|
|
|
|
In order to evaluate several responses, mslookup always waits for a fixed amount of time (1 second), and then evaluates
|
|
the available responses.
|
|
|
|
Services are not limited to SIP and SMPP, arbitrarily named services can be added to the mslookup configuration.
|
|
|
|
.Message sequence for locating an MSISDN to deliver a voice call
|
|
["mscgen"]
|
|
----
|
|
msc {
|
|
hscale="2";
|
|
moms[label="MS,BSS\nvillage A"],momsc[label="MSC,MGW\nvillage A"],mosipcon[label="osmo-sip-connector\nvillage A"],mopbx[label="PBX\nvillage A"],mthlr[label="OsmoHLR\nvillage B"],mtsipcon[label="osmo-sip-connector\nvillage B"],mtmsc[label="MGW,MSC\nvillage B"],mtms[label="RAN,MS\nvillage B"];
|
|
|
|
moms =>> momsc [label="CC Setup"];
|
|
momsc =>> mosipcon [label="MNCC_SETUP_IND"];
|
|
mosipcon =>> mopbx [label="SIP INVITE"];
|
|
mopbx rbox mopbx [label="dialplan: launch mslookup by MSISDN"];
|
|
--- [label="multicast-DNS query to all connected sites"];
|
|
...;
|
|
mopbx <<= mthlr [label="mDNS response\n(age)"];
|
|
mopbx rbox mopbx [label="wait ~ 1s for more mDNS responses"];
|
|
...;
|
|
mopbx =>> mtsipcon [label="SIP INVITE (MT)"];
|
|
mtmsc <<= mtsipcon [label="MNCC_SETUP_REQ"];
|
|
mtms <<= mtmsc [label="Paging (CC)"];
|
|
moms rbox mtms [label="voice call commences"];
|
|
|
|
}
|
|
----
|
|
|
|
==== Find the Home HLR for an IMSI
|
|
|
|
[[fig_dgsm_roaming]]
|
|
.mslookup for Roaming: Alice visits village B; she can attach to the local mobile network, which proxies HLR administration to her home village.
|
|
[graphviz]
|
|
----
|
|
digraph G {
|
|
rankdir=LR
|
|
|
|
subgraph cluster_village_b {
|
|
label="Village B"
|
|
|
|
ms_alice [label="Alice\n(from village A)",shape=box]
|
|
msc_b [label="MSC B"]
|
|
hlr_b [label="HLR B"]
|
|
}
|
|
|
|
subgraph cluster_village_a {
|
|
label="Village A"
|
|
hlr_alice [label="Alice's home HLR"]
|
|
}
|
|
|
|
ms_alice -> msc_b -> hlr_b [label="Location\nUpdating"]
|
|
hlr_b -> hlr_alice [label="mslookup by IMSI",style=dotted,dir=both]
|
|
hlr_b -> hlr_alice [label="GSUP proxy forwarding"]
|
|
}
|
|
----
|
|
|
|
For example, when attaching to a local network, a local resident gets serviced directly by the local village's HLR,
|
|
while a visitor from another village gets serviced by the remote village's HLR (Roaming).
|
|
|
|
A home HLR typically stays the same for a given IMSI. If the home site is reachable, there should be exactly one
|
|
response to an mslookup request asking for it. The age of such a home-HLR response is always sent as zero.
|
|
|
|
If a response's age is zero, mslookup does not wait for further responses and immediately uses the result.
|
|
|
|
If there were more than one HLR accepting service for an IMSI, the one with the shortest response latency is used.
|
|
|
|
=== mslookup Configuration
|
|
|
|
OsmoHLR the main mslookup agent. It provides the responses for both current location services as well as for locating
|
|
the fixed home-HLR. But naturally, depending on the mslookup request's purpose, different OsmoHLR instances will respond
|
|
for a given subscriber.
|
|
|
|
- When querying the home HLR, it is always the (typically single) home HLR instance that sends the mslookup response. As
|
|
soon as it finds the queried IMSI in the local HLR database, an OsmoHLR will respond to home-HLR requests.
|
|
In <<fig_dgsm_roaming>>, Alice's home HLR responds to the Roaming request ("where is the home HLR?").
|
|
|
|
- When querying the location of an MSISDN, it is always the HLR proxy nearest to the servicing MSC that sends the
|
|
mslookup response. Even though the home HLR keeps the Location Updating record also for Roaming cases, it will only
|
|
respond to an mslookup service request if the subscriber has attached at a directly connected MSC. If attached at a
|
|
remote MSC, that MSC's remote HLR will be the GSUP proxy for the home HLR, and the remote HLR is responsible for
|
|
responding to service requests.
|
|
In <<fig_dgsm_roaming>>, HLR B is the nearest proxy and will answer all service requests ("where is this MSISDN?").
|
|
Alice's home HLR will not answer service requests, because it detects that the servicing MSC is connected via another
|
|
HLR proxy.
|
|
|
|
[[dgsm_example_config]]
|
|
==== Example
|
|
|
|
Here is an osmo-hlr.cfg mslookup configuration example for one site, which is explained in subsequent chapters.
|
|
|
|
hlr
|
|
gsup
|
|
bind ip 10.9.8.7
|
|
ipa-name hlr-23
|
|
mslookup
|
|
mdns bind
|
|
server
|
|
service sip.voice at 10.9.8.7 5060
|
|
service smpp.sms at 10.9.8.7 2775
|
|
|
|
OsmoHLR has both an mslookup server and a client.
|
|
|
|
- The server responds to incoming service and home-HLR requests, when the local HLR is responsible.
|
|
- The client is used as GSUP proxy to a remote home HLR (found by mslookup upon a locally unknown IMSI).
|
|
- The client may also be used for forwarding SMS-over-GSUP.
|
|
|
|
The mslookup service can be implemented by various methods.
|
|
At the time of writing, the only method implemented is mDNS.
|
|
|
|
==== mDNS
|
|
|
|
The stock mslookup method is mDNS, multicast DNS. It consists of standard DNS encoding according to <<ietf-rfc1035>> and
|
|
<<ietf-rfc3596>>, but sent and received on IP multicast. In the response, standard A and AAAA records return the
|
|
service's IP address, while additional TXT records provide the service's port number and the MS attach age.
|
|
|
|
TIP: To watch D-GSM mDNS conversations in wireshark, select "udp.port == 4266" (the default mslookup mDNS port
|
|
number), right click on the packet to "Decode as...", and select "DNS".
|
|
|
|
In OsmoHLR, the mDNS server and client are typically both enabled at the same time:
|
|
|
|
mslookup
|
|
mdns bind
|
|
|
|
Server and client can also be enabled/disabled individually:
|
|
|
|
mslookup
|
|
server
|
|
mdns bind
|
|
client
|
|
mdns bind
|
|
|
|
These examples use the default mslookup multicast IP address and port. It is possible to configure custom IP address and
|
|
port, but beware that the IP address must be from a multicast range, see <<ietf-rfc5771>>:
|
|
|
|
mslookup
|
|
mdns bind 239.192.23.42 4266
|
|
|
|
Domain names generated from mslookup queries (e.g. "sip.voice.123.msisdn") should not collide with IANA permitted
|
|
domains. Therefore we add the "mdns.osmocom.org" suffix. It can be overridden as follows:
|
|
|
|
mslookup
|
|
mdns domain-suffix mdns.osmocom.org
|
|
|
|
==== Server: Site Services
|
|
|
|
The mslookup server requires a list of service addresses provided at the local site, in order to respond to service
|
|
requests matching locally attached subscribers.
|
|
|
|
mslookup
|
|
server
|
|
service sip.voice at 10.9.8.7 5060
|
|
service smpp.sms at 10.9.8.7 2775
|
|
|
|
In this example:
|
|
|
|
- "10.9.8.7 5060" are the IP address and port on which the local site's osmo-sip-connector is bound to receive SIP
|
|
Invite requests.
|
|
- "10.9.8.7 2775" are the local site's OsmoMSC SMPP bind address and port.
|
|
|
|
Obviously, these IP addresses must be routable back to this site from all other sites. Using link-local or "ANY"
|
|
addresses, like 127.0.0.1 or 0.0.0.0, will not work here. Instead, each service config requires a public IP address that
|
|
all remote requestors are able to reach (not necessarily on the host that osmo-hlr is running on).
|
|
|
|
If a site has more than one MSC, services can also be configured for each MSC individually, keyed by the IPA unit name
|
|
that each MSC sends on the GSUP link:
|
|
|
|
mslookup
|
|
server
|
|
msc ipa-name msc-262-42-0
|
|
service sip.voice at 10.11.12.13 5060
|
|
service smpp.sms at 10.11.12.13 2775
|
|
msc ipa-name msc-901-70-0
|
|
service sip.voice at 10.9.8.7 5060
|
|
service smpp.sms at 10.9.8.7 2775
|
|
|
|
Here, "msc-262-42-0" is the IPA name of a local OsmoMSC instance. To configure an OsmoMSC's IPA name on the GSUP link,
|
|
see osmo-msc.cfg, setting `hlr` / `ipa-name`.
|
|
|
|
For mslookup service responses, only Location Updatings in the Circuit Switched domain are relevant. OsmoHLR does manage
|
|
IMSIs attaching in the Packet Switched domain (via an SGSN) similarly to Circuit Switched (via an MSC), but mslookup
|
|
completely ignores the Packet Switched attach status.
|
|
|
|
==== Server: Own GSUP Address
|
|
|
|
When responding to home-HLR requests, OsmoHLR implicitly by default responds with its locally configured GSUP bind
|
|
address (setting `hlr` / `gsup` / `bind ip`). If required, an explicit local GSUP address and port can be configured,
|
|
for example:
|
|
|
|
hlr
|
|
gsup
|
|
bind ip 0.0.0.0
|
|
ipa-name hlr-23
|
|
mslookup
|
|
server
|
|
# osmo-hlr's own GSUP address to send in mslookup responses:
|
|
service gsup.hlr at 10.9.8.7 4222
|
|
|
|
The gsup.hlr service can only be configured globally (because requests come from arbitrary mDNS clients, before a
|
|
Location Updating has associated the IMSI with the requesting MSC).
|
|
|
|
==== Client IPA Naming
|
|
|
|
For reliable GSUP proxy routing to a remote HLR (Roaming), it is important that each GSUP client, i.e. each HLR, MSC and
|
|
SGSN instance, has a unique IPA name.
|
|
|
|
Example for configuring an OsmoHLR instance's IPA name:
|
|
|
|
hlr
|
|
gsup
|
|
ipa-name hlr-23
|
|
|
|
Here, "hlr-23" is the unique identification of this OsmoHLR instance across all potentially connected D-GSM sites.
|
|
|
|
Furthermore, each MSC and SGSN must have a uniquely distinct IPA name across all sites (here "msc-262-42-0" and
|
|
"msc-901-70-0" are used as example IPA names for local MSCs).
|
|
|
|
When this OsmoHLR connects to a remote HLR, be it for GSUP proxying or SMS-over-GSUP, it communicates its own IPA name
|
|
(on GSUP link-up) as well as the IPA name of the requesting client MSC/SGSN (as Source Name in each message) to the
|
|
remote OsmoHLR GSUP server. These names are used to route GSUP responses back to the respective requesting peer.
|
|
|
|
If two MSCs were accidentally configured with identical names, a problem will occur as soon as both MSCs attempt to
|
|
attach to the same OsmoHLR (either directly or via GSUP proxying). The MSC that shows up first will work normally, but
|
|
any duplicate that shows up later will be rejected, since a route for its name already exists.
|
|
|
|
=== Queries
|
|
|
|
In URL notation, typical mslookup queries look like:
|
|
|
|
gsup.hlr.123456789.imsi
|
|
sip.voice.123.msisdn
|
|
smpp.sms.123.msisdn
|
|
|
|
A query consists of
|
|
|
|
- a service name ("gsup.hlr"),
|
|
- an id ("123456789"),
|
|
- the id type ("imsi").
|
|
|
|
The calling client also defines a timeout to wait for responses.
|
|
|
|
The mslookup ID types are fixed, while service names can be chosen arbitrarily.
|
|
|
|
.mslookup ID types, no other ID types are understood by mslookup
|
|
[options="header",width="100%",cols="20%,80%"]
|
|
|===
|
|
|ID Type|Description
|
|
|imsi|An IMSI as existing in an OsmoHLR subscriber database
|
|
|msisdn|A phone number as configured in an OsmoHLR subscriber database
|
|
|===
|
|
|
|
.mslookup service name conventions, arbitrary service names can be added as required
|
|
[options="header",width="100%",cols="20%,20%,60%"]
|
|
|===
|
|
|Service Name|Protocol|Description
|
|
|gsup.hlr | GSUP | Home HLR's GSUP server, to handle Location Updating related procedures
|
|
|sip.voice | SIP | OsmoSIPConnector, to receive a SIP Invite (MT side of a call)
|
|
|smpp.sms | SMPP | Destination OsmoMSC (or other SMPP server) to deliver an SMS to the recipient
|
|
|gsup.sms | GSUP | GSUP peer to deliver an SMS to the recipient using SMS-over-GSUP
|
|
|===
|
|
|
|
Arbitrarily named services can be added to the mslookup configuration and queried by mslookup clients; as soon as a
|
|
service name is present in osmo-hlr.cfg, it can be queried from any mslookup client.
|
|
|
|
Service names should consist of a protocol name (like "sip", "gsup", "english") and an intended action/entity (like
|
|
"voice", "hlr", "greeting").
|
|
|
|
=== Service Client Implementation
|
|
|
|
In principle, arbitrary services could query target addresses via mslookup, leaving it up to any and all kinds of
|
|
clients to find their respective destination addresses. But of course, mslookup was designed with specific services in
|
|
mind, namely:
|
|
|
|
- SIP call agents and
|
|
- SMS delivery (an ESME or SMSC)
|
|
|
|
The following chapters describe examples of setting up a working distributed core network providing SIP voice calls and
|
|
SMS forwarding across sites.
|
|
|
|
==== mslookup Library
|
|
|
|
The OsmoHLR provides an mslookup client C library, libosmo-mslookup. Service lookups can be integrated directly
|
|
in client programs using this library. However, its mDNS implementation requires the libosmocore select() loop, which
|
|
can be challenging to integrate in practice. An alternative solution is the osmo-mslookup-client tool.
|
|
|
|
[[dgsm_osmo_mslookup_client]]
|
|
==== osmo-mslookup-client
|
|
|
|
The mslookup C library is available, but often, a simpler approach for client implementations is desirable:
|
|
|
|
- When querying for a service address, the client is typically interested in the single final best result (youngest age
|
|
/ first responding home HLR).
|
|
- Voice call and SMS clients typically would block until an mslookup result is known. For example, the FreeSwitch
|
|
dialplan integration expects a result synchronously, i.e. without waiting for mslookup responses via a select() loop.
|
|
- Integrating the libosmocore select() loop required for mDNS can break the already existing socket handling in the
|
|
client program.
|
|
|
|
The osmo-mslookup-client cmdline tool provides a trivial way to synchronously acquire the single result for an mslookup
|
|
request. The service client can invoke an osmo-mslookup-client process per request and read the result from stdout.
|
|
|
|
Each invocation obviously spawns a separate process and opens a multicast socket for mDNS. For better scalability,
|
|
osmo-mslookup-client can also be run as a daemon, providing results via a unix domain socket. Using synchronous write()
|
|
and recv() allows blocking until a result is received without interfering with the client program's select() setup.
|
|
|
|
By itself, osmo-mslookup-client is also helpful as a diagnostic tool:
|
|
|
|
----
|
|
$ osmo-mslookup-client sip.voice.1001.msisdn
|
|
sip.voice.1001.msisdn ok 10.9.8.7 5060
|
|
|
|
$ osmo-mslookup-client gsup.hlr.901700000014701.imsi
|
|
gsup.hlr.901700000014701.imsi ok 10.9.8.7 4222
|
|
|
|
$ osmo-mslookup-client gsup.hlr.111111.imsi
|
|
gsup.hlr.111111.imsi not-found
|
|
|
|
$ osmo-mslookup-client gsup.hlr.1001.msisdn sip.voice.1001.msisdn smpp.sms.1001.msisdn foo.1001.msisdn
|
|
gsup.hlr.1001.msisdn ok 10.9.8.7 4222
|
|
foo.1001.msisdn not-found
|
|
smpp.sms.1001.msisdn ok 10.9.8.7 2775
|
|
sip.voice.1001.msisdn ok 10.9.8.7 5060
|
|
|
|
$ osmo-mslookup-client --csv-headers gsup.hlr.901700000014701.imsi
|
|
QUERY RESULT V4_IP V4_PORT V6_IP V6_PORT
|
|
gsup.hlr.901700000014701.imsi ok 10.9.8.7 4222
|
|
|
|
$ osmo-mslookup-client -f json gsup.hlr.901700000014701.imsi
|
|
{"query": "gsup.hlr.901700000014701.imsi", "result": "ok", "v4": ["10.9.8.7", "4222"]}
|
|
----
|
|
|
|
For full help including example client invocations in Python, see the output of:
|
|
|
|
osmo-mslookup-client -h
|
|
|
|
==== SIP Service Client
|
|
|
|
[[dgsm_conf_dialplan]]
|
|
===== FreeSwitch dialplan.py
|
|
|
|
The FreeSWITCH PBX software <<freeswitch_pbx>> offers a Python integration to determine a SIP call recipient by a custom
|
|
dialplan implementation. An example dialplan implementation for FreeSWITCH that uses D-GSM mslookup is provided in the
|
|
osmo-hlr source tree under `contrib`, called `freeswitch_dialplan_dgsm.py`.
|
|
|
|
To integrate it with your FREESWITCH setup, add a new `extension` block to your `dialplan/public.xml`:
|
|
|
|
----
|
|
<extension name="outbound">
|
|
<condition field="destination_number" expression=".*">
|
|
<action application="set" data="hangup_after_bridge=true"/>
|
|
<action application="set" data="session_in_hangup_hook=true"/>
|
|
<action application="set" data="ringback=%(2000, 4000, 440.0, 480.0)"/>
|
|
<action application="python" data="freeswitch_dialplan_dgsm"/>
|
|
</condition>
|
|
</extension>
|
|
----
|
|
|
|
Make sure that the dir containing `freeswitch_dialplan_dgsm.py` is in your `PYTHONPATH` environment variable, and start
|
|
the server:
|
|
|
|
----
|
|
$ export PYTHONPATH="$PYTHONPATH:/home/user/code/osmo-hlr/contrib/dgsm"
|
|
$ freeswitch -nf -nonat -nonatmap -nocal -nort -c
|
|
----
|
|
|
|
==== SMS Service Client
|
|
|
|
[[dgsm_conf_esme_smpp]]
|
|
===== SMS via SMPP Port
|
|
|
|
An example ESME using D-GSM mslookup, `esme_dgsm.py`, is provided in the osmo-hlr source tree under `contrib`. It
|
|
attaches to OsmoMSC's SMPP port to send SMS to recipients determined by mslookup.
|
|
|
|
OsmoMSC should be configured as "smpp-first", so that all SMS routing is determined by mslookup. If configured without
|
|
smpp-first, OsmoMSC may try to deliver an SMS locally, even though the recipient has recently moved to a different site.
|
|
|
|
An example OsmoMSC configuration to work with esme_dgsm.py:
|
|
|
|
----
|
|
smpp
|
|
local-tcp-ip 127.0.0.1 2775
|
|
system-id test-msc
|
|
policy closed
|
|
smpp-first
|
|
# outgoing to esme_dgsm.py
|
|
esme OSMPP
|
|
no alert-notifications
|
|
password foo
|
|
default-route
|
|
# incoming from esme_dgsm.py
|
|
esme ISMPP
|
|
no alert-notifications
|
|
password foo
|
|
----
|
|
|
|
Launch esme_dgsm.py alongside OsmoMSC:
|
|
|
|
----
|
|
./esme_dgsm.py --src-host 127.0.0.1
|
|
----
|
|
|
|
esme_dgsm.py will be notified via SMPP for each SMS to be delivered, and will forward them either to a remote
|
|
recipient, or back to the same OsmoMSC, depending on the mslookup result. If the MSISDN is not reachable (or
|
|
esme_dgsm.py can't handle the message for other reasons), it returns the RSYSERR code back to OsmoMSC.
|
|
|
|
Note that the esme_dgsm.py is a proof of concept and should not be used in production. It has several limitations, such
|
|
as not supporting multipart SMS messages.
|
|
|
|
===== SMS-Over-GSUP
|
|
|
|
The GSUP protocol defines SMS delivery messages. When OsmoMSC is configured to deliver SMS via GSUP, MO SMS are directly
|
|
forwarded to the HLR, which will determine where to forward the SMS-over-GSUP messages using its mslookup client.
|
|
|
|
FIXME implement this
|