Tag Archives: SMS

SMS over Diameter for Roaming SMS

I know what you’re thinking, again with the SMS transport talk Nick? Ha! As if we’re done talking about SMS. Recently we did something kinda cool – The world’s first SMS sent over NB-IoT (Satellite).

But to do this, we weren’t using IMS, it’s too heavy (I’ve written about NB-IoT’s NIDD functions and the past).

SGs-AP which is used for CSFB & SMS doesn’t span network borders (you can’t roam with SGs-AP), and with SMSoIP out of the question, that gave us the option of MAP or Diameter, so we picked Diameter.

This introduces the S6c and SGd Diameter interfaces, in the diagrams below Orange is the Home Network (HPMN) and the Green is the Visited Network (VPMN).

The S6c interface is used between the SMSc and the HSS, in order to retrieve the routing information. This like the SRI-for-SM in MAP.

The SGd interface is used between the MME serving the UE and the SMSc, and is used for actual delivery of the MO/MT messages.

I haven’t shown the Diameter Routing Agents in these diagrams, but in reality there would be a DRA on the VPLMN and a DRA on the HPMN, and probably a DRA in the IPX between them too.

The Attach

The attach looks like a regular roaming attach, the MME in the Visited PMN sends an Update Location Request to the HSS, so the HSS knows the MME that is serving the subscriber.

S6a Update Location Request to indicate the MME serving the Subscriber

The Mobile Terminated SMS Flow

Now we introduce the S6c interface and the SGd interfaces.

When the Home SMSc has a message to send to the subscriber (Mobile Terminated SMS) it runs a the Send-Routing-Info-for-SM-Request (SRR) dialog to the HSS.

The Send-Routing-Info-for-SM-Answer (SRA) back from the HSS contains the info on the MME Diameter Host name and Diameter Realm serving the subscriber.

S6t – Send-Routing-Info-for-SM request to get the MME serving the subscriber

With this info, we can now craft a Diameter Request that will get sent to the MME serving the subscriber, containing the SMS PDU to send to the UE.

SGd MT-Forward-Short-Message to deliver Mobile Terminated SMS to the serving MME

We make sure it’s sent to the correct MME by setting the Destination-Host and Destination-Realm in the Diameter request.

Here’s how the request looks from the SMSc towards our DRA:

As you can see the Destination Realm and Destination-Host is set, as is the User-Name set to the IMSI of the UE we want to send the message to.

And down the bottom you can see the SMS-TPDU, the same as it’s been all the way back since GSM days.

The Mobile Originated SMS Flow

The Mobile Originated flow is even simpler, because we don’t need to look up where to route it to.

The MME receives the MO SMS from the UE, and shoves it into a Diameter message with Application ID set to SGd and Destination-Realm set to the HPMN Realm.

When the message reaches the DRA in the HPMN it forwards the request to an SMSc and then the Home SMSc has the message ready to roll.

So that’s it, pretty straightforward to set up!

How do you know if they’re roaming? Charging challenges in IMS for Roamers

I got an email the other day asking a simple question:

How do I know if a subscriber is VoLTE roaming or not when they send an SMS to charge for it?

My immediate reaction was to look at the SIP headers, P-Access-Network-Info will tell you where the subscriber is located, end of.


Well not quite, this will tell the SMSc the location of the subscriber sending the SMS. If the PLMN in the P-Access-Network-Info != the home PLMN, the sub is roaming.

But does this information get passed to the OCS / OFCS?

The SMSc uses “Event based charging” to perform credit control, so let’s have a look at what AVPs are present in the Credit Control Request from the SMSc:

Hmm, the SMS-Information AVP (2000) contains a bunch of information about the SMS being sent, but I don’t see anything about the location of the sender in there.

Originator-Interface is just set to “SIP”, of course in a 2G/3G roaming scenario the Originator-SCCP-Address would be that of the Visited PLMN, but for us it is our SCCP address.

Maybe the standard allows for an additional optional AVP in the SMS-Information-AVP we’re missing? Let’s check TS 32.299:


So how to deal with this?

While the standards aren’t totally clear on this, we added an IMS-Info AVP and inside that populated the Access-Network-Information directly from the SIP header, and then picked that off inside our OCS in order to apply the correct rules.

A look at Advanced Mobile Location SMS for Emergency Calls

Advanced Mobile Location (AML) is being rolled out by a large number of mobile network operators to provide accurate caller location to emergency services, so how does it work, what’s going on and what do you need to know?

Recently we’ve been doing a lot of work on emergency calling in IMS, and meeting requirements for NG-112 / e911, etc.

This led me to seeing my first Advanced Mobile Location (AML) SMS in the wild.

For those unfamiliar, AML is a fancy text message that contains the callers location, accuracy, etc, that is passed to emergency services when you make a call to emergency services in some countries.

It’s sent automatically by your handset (if enabled) when making a call to an emergency number, and it provides the dispatch operator with your location information, including extra metadata like the accuracy of the location information, height / floor if known, and level of confidence.

The standard is primarily driven by EENA, and, being backed by the European Union, it’s got almost universal handset support.

Google has their own version of AML called ELS, which they claim is supported on more than 99% of Android phones (I’m unclear on what this means for Harmony OS or other non-Google backed forks of Android), and Apple support for AML starts from iOS 11 onwards, meaning it’s supported on iPhones from the iPhone 5S onards,.

Call Flow

When a call is made to the PSAP based on the Emergency Calling Codes set on the SIM card or set in the OS, the handset starts collecting location information. The phone can pull this from a variety of sources, such as WiFi SSIDs visible, but the best is going to be GPS or one of it’s siblings (GLONASS / Galileo).

Once the handset has a good “lock” of a location (or if 20 seconds has passed since the call started) it bundles up all of this information the phone has, into an SMS and sends it to the PSAP as a regular old SMS.

The routing from the operator’s SMSc to the PSAP, and the routing from the PSAP to the dispatcher screen of the operator taking the call, is all up to implementation. For the most part the SMS destination is the emergency number (911 / 112) but again, this is dependent on the country.

Inside the SMS

To the user, the AML SMS is not seen, in fact, it’s actually forbidden by the standard to show in the “sent” items list in the SMS client.

On the wire, the SMS looks like any regular SMS, it can use GSM7 bit encoding as it doesn’t require any special characters.

Each attribute is a key / value pair, with semicolons (;) delineating the individual attributes, and = separating the key and the value.

Below is an example of an AML SMS body:

0.18305;rd=50;top=20130717141935;lc=90;pm=W;si=123456789012345;ei=1234567890123456;mcc=234;mnc=30; ml=128

If you’ve got a few years of staring at Wireshark traces in Hex under your belt, then this will probably be pretty easy to get the gist of what’s going on, we’ve got the header (A”ML=1″) which denotes this is AML and the version is 1.

After that we have the latitude (lt=), longitude (lg=), radius (rd=), time of positioning (top=), level of confidence (lc=), positioning method (pm=) with G for GNSS, W for Wifi signal, C for Cell
or N for a position was not available, and so on.

AML outside the ordinary

Roaming Scenarios

If an emergency occurs inside my house, there’s a good chance I know the address, and even if I don’t know my own address, it’s probably linked to the account holder information from my telco anyway.

AML and location reporting for emergency calls is primarily relied upon in scenarios where the caller doesn’t know where they’re calling from, and a good example of this would be a call made while roaming.

If I were in a different country, there’s a much higher likelihood that I wouldn’t know my exact address, however AML does not currently work across borders.

The standard suggests disabling SMS when roaming, which is not that surprising considering the current state of SMS transport.

Without a SIM?

Without a SIM in the phone, calls can still be made to emergency services, however SMS cannot be sent.

That’s because the emergency calling standards for unauthenticated emergency calls, only cater for

This is a limitation however this could be addressed by 3GPP in future releases if there is sufficient need.

HTTPS Delivery

The standard was revised to allow HTTPS as the delivery method for AML, for example, the below POST contains the same data encoded for use in a HTTP transaction:


Implementation of this approach is however more complex, and leads to little benefit.

The operator must zero-rate the DNS, to allow the FQDN for this to be resolved (it resolves to a different domain in each country), and allow traffic to this endpoint even if the customer has data disabled (see what happens when your handset has PS Data Off ), or has run out of data.

Due to the EU’s stance on Net Neutrality, “Zero Rating” is a controversial topic that means most operators have limited implementation of this, so most fall back to SMS.

Other methods for sharing location of emergency calls?

In some upcoming posts we’ll look at the GMLC used for E911 Phase 2, and how the network can request the location from the handset.

Further Reading


SMS-over-IP Message Efficiency – K

Recently I read a post from someone talking about efficiency of USSD over IMS, and how crazy it was that such a small amount of data used so much overhead to get transferred across the network.

Having built an SMSc a while ago, my mind immediately jumped to SMS over IMS as being a great example of having so much overhead.

If we’re to consider sending the response “K” to a text message, how much overhead is there?

SMS PDU containing the message “K”

I’m using a common Qualcomm based smartphone, and here’s the numbers I’ve got from Wireshark when I send the message:

Transport Ethernet Header – 14 Bytes
Transport IP Header – 20 Bytes
Transport UDP Header – 8 Bytes
Transport GTP Header – 12 Bytes
User IP Header – 20 Bytes
IPsec ESP Header (For Um interface protection) – 22 Bytes
Encapsulated UDP Header – 8 Bytes
SIP Headers – 707 Bytes
SMS Header – 16 Bytes
SMS Message Body “K” – 1 Byte

Overall SIP, ESP, GTP and Transport PCAP for SIP MESSAGE

That seems pretty bad in terms of efficiency, but let’s look at how that actually works out:

This means our actual message body makes up just 1 byte of 828 bytes, or 0.12% of the size of the overall payload.

Even combined with the SMS header (which contains all the addressing information needed to route an SMS) it’s still just on 2% of the overall message.

So USSD efficiency isn’t great, but it’s not alone!

MMS Deep Dive – MM1 – Mobile Terminated MMS

In our last post we talked about sending an Multimedia Message, and in this post, we’re going to cover the process of receiving a Multimedia Message.

Carl Sagan once famously said “If you wish to make an apple pie from scratch, you must first invent the universe”, we don’t need to go that far back, but if you want to deliver an MMS to a subscriber, first you must deliver an SMS.

Wait, but we’re talking about MMS right? So why are we talking SMS?

Modern MMS transport relies on HTTP, which is client-server based, the phone / UE is the client, and the MMSc is the Server.

The problem with this client-server relationship, is the client requests things from the server, but the server can’t request things from the client.

This presents a problem when it comes to delivering the MMS – The phone / UE will need to request the MMSc provide it the message to be received, but needs to know there is a message to request in the first place.

So this is where SMS comes in. When the MMSc has a message destined for a Subscriber, it sends the phone/UE an SMS, informing that there is an MMS waiting, and providing the URL the MMS can be retrieved from.

This is typically done by MAP or SMPP, to link the MMSc to the SMSc to allow it to send these messages.

This SMS contains the URL to retrieve the MMS at, once the UE receives this SMS, it knows where to retrieve the MMS.

It can then send an HTTP GET to the URL to retrieve the MMS, and lastly sends an HTTP POST to confirm to the MMSc it retrieved it all OK.

MMS Mobile Terminated message flow

So that’s the basics, let’s look at each part of the dialog in some more detail, starting with this magic SMS to tell the UE where to retrieve the MMS from.

WAP PUSH from MMSc sent via SMS

So some things to notice, the user data, which would usually carry the body of our SMS instead contains another protocol, “Wireless Session Protocol” (WSP), and this is the method “Push”.

That in turn is followed by MMS Message Encapsulation, again inside the SMS message body, this time with the MMS specific data.

The From: header contains the sender of the MMS, this is how you can see who the MMS is from, while it’s still downloading.

The expiry indicates to the handset, it it doesn’t download the MMS within the specified time period, it shouldn’t bother, as the message will have expired.

And lastly, and perhaps most importantly, we have the X-MMS-Content-Location header, which tells our subscriber where to download the MMS from.

After this, the UE sends an HTTP GET to the URL in the X-MMS-Content-Location header (typically on the “mms” APN), to retrieve the MMS from the MMSc.

HTTP GET from the UE to the MMSc

The HTTP GET is pretty normal, there’s the usual MMS headers we talked about in the last post, and we just GET the path provided by the MMSc in the WAP PUSH.

The response from the MMSc contains the actual MMS itself, which is almost a mirror of the sending process (the Data component is unchanged from when the sender sent it).

Response to HTTP GET for message retrieval

At this stage our subscriber has retrieve the MMS, but may not have retrieved it fully, or may have had an issue retrieving it.

Instead the UE sends an HTTP POST with the MMS-Message-Type m-notifyresp-ind with the transaction ID, to indicate that it has successfully retrieved the MMS, and at this point the MMS can notify the sender if delivery receipts are enabled, and delete the message from the cache.

And finally the MMSc sends back a 200 OK with no body to confirm it got that too.

Some notes on MMS Security

Reading about unauthenticated GET requests, you may be left wondering what security does MMS have, and what stops you from just going through and sending HTTP GET requests to all the possible URL paths to vacuum up all the MMS?

In the standard, nothing!

Typically the MMSc has some layer of security added by the implementer, to ensure the user retrieving the MMS, is the user the MMS is destined for.
Because MMS has no security in the standard, this is typically achieved through Header Enrichment, whereby the P-GW adds a HTTP header with the MSISDN or IMSI of the subscriber, and then the MMSc can evaluate if this subscriber should be able to retrieve that URL.

Another attack vector I played with was sending a SMS based MMS-Notify with a different URL, which if retrieved, would leak the subscriber’s IP, as it would cause the UE to try and get data from that URL.

SMS with Alphanumeric Source

Sending SMS with an alphanumeric String as the Source

If you’ve ever received an SMS from your operator, and the sender was the Operator name for example, you may be left wondering how it’s done.

In IMS you’d think this could be quite simple – You’d set the From header to be the name rather than the MSISDN, but for most SMSoIP deployments, the From header is ignored and instead the c header inside the SMS body is used.

So how do we get it to show text?

Well the TP-Originating address has the “Type of Number” (ToN) field which is typically set to International/National, but value 5 allows for the Digits to instead be alphanumeric characters.

GSM 7 bit encoding on the text in the TP-Originating Address digits and presto, you can send SMS to subscribers where the message shows as From an alphanumeric source.

On Android SMSs received from alphanumeric sources cannot be responded to (“no more “DO NOT REPLY TO THIS MESSAGE” at the end of each text), but on iOS devices you can respond, but if I send an SMS from “Nick” the reply from the subscriber using the iPhone will be sent to MSISDN 6425 (Nick on the telephone keypad).

The Surprisingly Complicated World of SMS: Apple iPhone MT SMS

In iOS 15, Apple added support for iPhones to support SMS over IMS networks – SMSoIP. Previously iPhone users have been relying on CSFB / SMSoNAS (Using the SGs interface) to send SMS on 4G networks.

Getting this working recently led me to some issues that took me longer than I’d like to admit to work out the root cause of…

I was finding that when sending a Mobile Termianted SMS to an iPhone as a SIP MESSAGE, the iPhone would send back the 200 OK to confirm delivery, but it never showed up on the screen to the user.

The GSM A-I/F headers in an SMS PDU are used primarily for indicating the sender of an SMS (Some carriers are configured to get this from the SIP From header, but the SMS PDU is most common).

The RP-Destination Address is used to indicate the destination for the SMS, and on all the models of handset I’ve been testing with, this is set to the MSISDN of the Subscriber.

But some devices are really finicky about it’s contents. Case in point, Apple iPhones.

If you send a Mobile Terminated SMS to an iPhone, like the one below, the iPhone will accept and send back a 200 OK to this request.

The problem is it will never be displayed to the user… The message is marked as delivered, the phone has accepted it it just hasn’t shown it…

SMS reports as delivered by the iPhone (200 OK back) but never gets displayed to the user of the phone as the RP-Destination Address header is populated

The fix is simple enough, if you set the RP-Destination Address header to 0, the message will be displayed to the user, but still took me a shamefully long time to work out the problem.

RP-Destination Address set to 0 sent to the iPhone, this time it’ll get displayed to the user.

The Surprisingly Complicated World of SMS: Special Characters

SMS by default uses the GSM-7 bit alphabet, thanks to the fact each letter is only 7 bits long, this means you can cram 160 characters into a 140 byte message body.

However, this 7-bit alphabet is, well, limited, because it’s 7 bits long it means we can only have 128 different combinations of these bits, or to put it another way, with only 128 different unique combinations of these bits, we can only define 128 characters.

You have the standard 26 latin alphabet characters that Sesame Street drilled into you, some characters with accents, digits, and a limited set of symbols.

The GSM 7 bit alphabet does not include is character sets and symbols common for non-English written languages.

Shift Tables

To deal with this 3GPP introduced “National Language Shift Tables”, which are enable a sort of find-and-replace approach to the 7-bit alphabet, where certain characters that are unused in one alphabet, take the value of characters from the local alphabet.

So if you want to send the character Ğ (Found in the Turkish and Azerbaijani alphabets) you’d select the Turkish language Shift table, that replaces the capital G (71) with Ğ.

Of course you need to have two things to do this, you need the Language Shift Table to tell you what local-language letters replace what default letters, and a mechanism to state that you’re using a language shift table.

3GPP define the National Language Shift tables in TS 23.038, where you can lookup the character you want to encode, so you know what 7 bit value it uses, for example our character Ğ is 1000111 in the 7-bit alphabet.

Next we need to indicate that we don’t want 1000111 in the 7-bit alphabet to be rendered as “G”, we want to use the “Turkish National Language Single Shift Table” which will render it as “Ğ”. We do this in the User Data Header of the SMS Body, the same way we’d indicate that an SMS is a concatenated SMS.

But by adding a header in the User Data Header of the SMS Body, we eat into the space we can use to send the message body, with a single User Data Header indicating that the Turkish National Language Single Shift Table is being used, we go from a maximum of 160 characters without the User Data Header, to 134 characters.

I’ve shared a lot more information on the User Data Header in this post on Concatenated SMS, should you be interested.

UCS2 Encoding

So that’s all well and good for other languages that have some overlap in letters, where we can substitute “G” for “Ğ”, but Unicode have 3304 emojis defined at the time of writing.

No matter how many shift tables you define, you’re not going to cover all of these in a 7-bit alphabet.

So all this encoding falls to 💩 when someone adds an Emoji.

The “😀” Emoji, represented as U+1F600 in Unicode, can be encoded as 0xF09F9880 in UTF-8 or 0xD83DDE00 in UTF-16.

So in 3GPP Networks, when you need more than 128 characters to work with, and when shift tables won’t cut the mustard, you can change the encoding used to use the International Standards Organisations’ “Universal coded character set 2” (UCS-2).

Unfortunately UCS-2 never really took off, but luckily it overlaps with UTF-16 character set, which is a lot more common.

So if you’ve got a “😀” Emoji in your SMS body the encoding of the message will be changed from GSM-7 to use a different encoding -UTF-16 / UCS2.

SMS Body showing TP-DCS character set is UCS2 / UTF-16 as Emojis are present

There’s a catch here, if you’re moving from a 7-bit alphabet to a 16 bit alphabet, you’re going to have a lot less space to work with.

A single SMS contains 1120 bits for the user data (The actual message).

With GSM-7 bit encoding, each letter takes up 7 bits, so 1120÷7 gives us 160 characters.

With UTF-16/UCS2 encoding, each letter takes up 16 bits so 1120÷16 only give us 70 characters.

So what happens next?

Often when Emojis are used, as our message is now limited to 70 characters concatenated messages are used, which takes a further 8 bytes of our message body if concatenated messages are used, further limiting the message length.

The Surprisingly Complicated World of SMS: Concatenated / Multipart SMS

Most people think of 160 characters as the length of an SMS. But the payload is actually 140 bytes, but with better encoding 1 character doesn’t require 1 byte.

The above paragraph is exactly 160 characters. It would fit into a standard SMS.

By using the GSM 7 bit alphabet, you can cram 16 characters into 140 bytes (octets) of space, which is kind of cool.

140 bytes of data containing 160 characters of text

But people often need to convey more text than just 160 characters, or if you’re using characters that don’t exist in the GSM 7-bit alphabet, that limit becomes even less than 160 characters (different encodings other than GSM-7 need more data to transfer the same number of characters) so we get into multipart SMS, another feature in the surprisingly complicated world of SMS.

You’d think if you took a 160 character SMS, and concatenated it onto another 160 character SMS, you’d get a total of 320 characters, right (160+160=320)?
Alas it’s not that simple.

In order to achieve the concatenation of messages in a way that’s transparent to the users (rather than a series of SMSes coming through one-after-the-ther) a User-Data Header (TP-User-Data-Header-Indicator aka TP-UHDI) is added to the TP-User Data of the TPDU (the part that actually contains the user message).

This User-Data Header takes up 7 bytes, which with GSM encoding robs us of 6 characters from the message length. (Not a typo, GSM7 encoding does not mean 1 character = 1 byte, hence we can get 160 characters into 140 bytes of space)
So a two SMS concatenated message would only allow 268 characters to be sent (134 characters + 134 characters).

Let’s take a look at this header that’s robbing us of message length, but enabling us to concatenate messages.

For starters, the information about how many parts in the concatenated message, and what part number this one is, is located in the message body, hence robbing us of characters.

But we only know about the presence of this header being in the message body because the SMS-SUBMIT TPDU has the TP-UDHI flag (TP-User-Data-Header-Indicator) set, so we know the User Data is prefixed with the User-Data-Header.

Now if we have a look in the TP-User-Data we can see the User-Data Header, this can actually carry a few different payloads, but in our case, it’s carrying the Concatenated Short Messages IE, which tells us the message identifier (unique per single-but-multi-part message, the number of parts in the message (in this case 2) and the part number this is (part 1 of 2).

First part of a two part SMS

Now the phone has indicated this is a multipart message, the length of the data is still 160, but the length of the actual message is now limited to 134 characters with GSM7 encoding.

The encoding isn’t as bad as you might expect:
1st byte indicates the total length of the User Data Headers (After this the actual user data begins),
2nd byte is the IE identifier, for Concatenated Short Messages, this is 00,
3rd byte is the length of the Concatenated Short Messages IE,
4th byte is the message identifier in hex,
5th byte is the number of message parts in hex (So up to 255 message parts)
6th byte is the message part number, to aid in putting it back together in order.

3GPP TS 23.040 – TP-User Data (TP-UD) – Encoding of User Data Header and generic IE
Concatenated short message IE encoding

So what we end up with is a header inside our user payload, advising that this is a concatenated SMS, the message identifier, the number of parts in the message, and the part number of this particular message.

Last part of two part SMS

The SMSc on receipt of these has to spool them back out to the destination with the same message part number, and same headers in place.

The phone receiving the SMS has to wait for all the parts to come through and then reassemble before rendering to the user.

So that’s how concatenated SMS works. While this may seem convoluted and silly in a world where transfering more than 140 bytes of data is trivial, SMS was introduced in the early 1990s, and in theory at least, a user with a phone that supported SMS purchased when SMS was introduced, should still be able to interwork with phones today.

N20 5G SBI for Nsmsf for SMS over 5GC

SMS in 5GC

Like in EPS / LTE, there are two ways to send SMS in Standalone 5G Core networks.

SMS over IMS or SMS over NAS – Both can be used on the same network, or just one, depending on operator preferences.

SMS over IMS in 5G

SMS over IMS uses the IMS network to send SMS. SIP MESSAGE methods are used to deliver SMS between users. While most operators have deployed IMS for 4G/LTE subscribers to use VoLTE some time ago, there are some changes required to the IMS architecture to support VoNR (Voice over New Radio) on the carrier side, and support for VoNR in commercial devices is currently in its early stages. Because of this many 5G devices and networks do not yet support SMS over IMS.

I’ve read in some places that RCS – The GSMA’s Rich Communications Service will replace SMS in 5GC. If this is the case, it reflected in any of the 3GPP standards.

SMS over NAS

To make a voice call on a device or network that does not support VoNR, EPS (VoLTE) fallback is used.
This means when making or receiving a call, the UE drops from the 5G RAN to using a 4G (LTE) basd RAN, and then uses VoLTE to make the call the same as it would when connected to 4G (LTE) networks, because it is connected to a 4G network.
This works technically, but is not the prefered option as it adds extra signaling and complexity to the network, and delays in the call setup, and it’s expected operators will eventually move to VoNR,but works as a stop-gap measure.

But mobile networks see a lot of SMS traffic. If every time an SMS was sent the UE had to rely on EPS fallback to access IMS, this would see users ping-ponging between 4G and 5G every time they sent or received an SMS.

This isn’t a new problem, in fact SMS-over-NAS was initially added to 4G (LTE) to allow devices to stay connected to the EPC (4G Core network) but still send and receive SMS, even if the network or device relied on “Circuit-Switched fallback” (A mechanism to drop from 4G to 2G / 3G for voice calls).

5GC reintroduces the SMS-over-NAS feature, allowing the SMS messages to be carried over NAS messaging on the N1 interface. Voice calls may still require fallback to EPS (4G) to make calls over VoLTE, but SMS can be carried over NAS messaging, minimizing the amount of Inter-RAT handovers required.

The Nsmsf_SMService

For this a new Service Based Interface is introduced between the AMF and the SMSF (SMS Function, typically built into an SMSc), via the N20 / Nsmsf SBI to offer the Nsmsf_SMService service.

There are 3 operations supported for the Nsmsf_SMService:

  • Active – Initiated by the AMF – Used to active the SMS service for a given subscriber,
  • Deactivate – Initiated by the AMF – Used to deactivate the SMS over NAS service for a given subscriber.
  • UplinkSMS – Initiated by the AMF to transfer the SMS payload towards the SMSF.

The UplinkSMS is a HTTP post from the AMF with the SUPI in the Request URI and the request body containing a JSON encoded SmsRecordData.

Astute readers may notice that’s all well and good, but that only covers Mobile Originated (MO) SMS, what about Mobile Terminated (MT) SMS?

Well that’s actually handled by a totally different SBI, the Namf_Communication action “N1N2MessageTransfer” is resused for sending MT SMS, as that interface already exists for use by SMF, LMF and PCF, and 5GC attempts to reuse interfaces as much as possible.

The Surprisingly Complicated world of MO SMS in IMS/VoLTE

Since the beginning of time, SIP has used the 2xx responses to confirm all went OK.

If you thought sending an SMS in a VoLTE/IMS network would see a 2xx OK response and then that’s the end of it, you’d be wrong.

So let’s take a look into sending SMS over VoLTE/IMS networks!

So our story starts with the Subscriber sending an SMS, which generate a SIP MESSAGE.

The Content-Type of this SIP MESSAGE is set to application/vnd.3gpp.sms rather than Text, and that’s because SMS over IMS uses the Short Message Transfer Protocol (SM-TP) inherited from GSM.

The Short Message Transfer Protocol (SM-TP) (Not related to Simple Message Transfer Protocol used in Email clients) is made up of Transfer Protocol Data Units (TPDU) that contain our message information, even though we have the Destination in our SIP headers, it’s again defined in the SM-TP body.

At first this may seem like a bit of duplication, but this allows older SMS Switching Centers (SMSc) to add support for IMS networks without any major changes, just what the SM-TP payload is wrapped up in changes.

SIP MESSAGE Request Body encoded in SM-TP

So back to our SIP MESSAGE request, typed out by the Subscriber, the UE sends this a SIP MESSAGE onto our IMS Network.

The IMS network follows it’s IFCs and routing rules, and makes it to the termination points for SMS traffic – the SMSc.

The SMSc sends back either a 200 OK or a 202 Accepted, and you’d think that’s the end of it, but no.

Our Subscriber still sees “Sending” on the screen, and the SMS is not shown as sent yet.

Instead, when the SMS has been delivered or buffered, relayed, etc, the SMSc generates a new SIP request, (as in new Call-ID / Dialog) with the request type MESSAGE, addressed to the Subscriber.

The payload of this request is another application/vnd.3gpp.sms encoded request body, again, containing SM-TP encoded data.

When the UE receives this, it will then consider the message delivered.

SM-TP encoded Delivery Report

Of course things change slightly when delivery reports are enabled, but that’s another story!

SMS over SGi interface on Open5GS MME and OsmoMSC

Sending SMS in Open5GS LTE Networks using the SGs Interface and OsmoMSC with SMSoS

We recently covered Circuit Switched fallback between LTE EUTRAN and GSM GERAN, and the SGs interface between the MME and the MSC.

One nifty feature of this interface is that you can send SMS using the MSC to switch the SMS traffic and the LTE/EUTRAN to transfer the messaging.

This means you don’t need Circuit Switched Fallback to send or receive SMS on LTE.

I assume this functionality was added to avoid the signalling load of constantly changing RAN technologies each time a subscriber sent or received an SMS, but I couldn’t find much about it’s history.

In order to get this to work you’ll essentially need the exact same setup I outlined in my CSFB example (Osmo-MSC, Osmo-STP, Osmo-HLR populated with the IMSI and MSISDN values you want to use for SMS), although you won’t actually need a GERAN / GSM radio network.

Once that’s in place you can just send SMS between subscribers,

Plus from the VTY terminal of OsmoMSC you can send SMS too:

OsmoMSC# subscriber msisdn 61487654321 sms sender msisdn 61412341234 send Hello World
Using the SGs interface for Circuit Switched Fallback (CSFB) Calls from LTE falling back to GSM

OsmoMSC and Open5GS MME – SGs Interface for InterRAT Handover & SMS

I’ve talked about how LTE’s EUTRAN / EPC has no knowledge about voice calls or SMS and instead relies on IMS/VoLTE for these services.

Circuit Switched Fallback allows UEs to use a 2G or 3G network (Circuit Switched network) if their device isn’t connected to the IMS network to make calls as the 2G/3G network can handle the voice call or SMS routing via the Mobile Switching Center in the 2G/3G network.

However for incoming calls destined to the UE (Mobile Terminated) the MSC needs a way to keep track of which MME is serving the UE so it can get a message to the MME and the MME can relay it to the UE, to tell it to drop to a 2G or 3G network (Circuit Switched network).

The signalling between the MME (In the LTE EPC) and the MSC (In the GSM/UTRAN core) is done over the SGs interface.

While the SGs interface is primarily for managing user location state across multiple RAN types, it’s got a useful function for sending SMS over SGi, allowing users on an LTE RAN to send SMS via the MSC of the 2G/3G network (GSM/UTRAN core).

How it Works:

When a UE connects to the LTE RAN (EUTRAN) the MME signals the GSM/UMTS MSC with an SGsAP-LOCATION-UPDATE-REQUEST,

This request includes the IMSI of the subscriber that just attached and the FQDN of the MME serving that UE.

The MSC now knows that IMSI 001010000000003 is currently on LTE RAN served by MME mmec01.mmegi0002.mme.epc.mnc001.mcc001.3gppnetwork.org,

If a call or SMS comes into the MSC destined for the MSISDN of that IMSI, the MSC can page the UE on the LTE RAN to tell it to do an inter-RAN handover to GSM/UMTS.

Setting it Up

In order to get this working you’ll need OsmoMSC in place, your subscribers to exist on OsmoHLR and the LTE HSS – For example Open5GS-HSS.

If you’re not familiar with OsmoMSC or the Osmocom stack I did a series of posts covering them you can find here. If you want to get this setup I’d suggest following the posts on installing the Osmocom Software, setting up the MSC, the STP and the HLR.

Once you’ve done that the additional config on OsmoMSC is fairly simple, we just define a new SGs interface to listen on:

OsmoMSC Config:

  local-port 29118
  vlr-name vlr.msc001.mnc001.mcc001.3gppnetwork.org

On the Open5GS side we’ve got to include the SGs info the MME config. Keep in mind the Tracking Area Code (TAC) in LTE must exist as the Location Area code (LAC) in GSM, here’s an extract of the MME section of YAML config in the Open5GS MME config:

    freeDiameter: /etc/freeDiameter/mme.conf

            mcc: 001
            mnc: 01
          tac: 7
            mcc: 001
            mnc: 01
          lac: 7

        mcc: 001
        mnc: 01
      mme_gid: 2
      mme_code: 1
        mcc: 001
        mnc: 01
      tac: 7
        integrity_order : [ EIA1, EIA2, EIA0 ]
        ciphering_order : [ EEA0, EEA1, EEA2 ]
        full: Open5GS

        - ::1

Neighbours Configured

The EUTRAN will need to advertise the presence of it’s GERAN neighbours and vise-versa so the UE/terminals know what ARFCN to move to so they don’t need to scan for the presence of other RATs when performing the handover.

Setting this up will depend on your eNB / BSC and goes beyond the scope of this post.

I’ll cover setting up neighbours in a later post as it’s a big topic.

If you don’t have neighbours configured, the handover will still work but will be much slower as the UE will have to scan to find the serving cell it’s reselecting to.

Example Packet Capture

SMS Security – Banks

The other day I got an SMS from my bank, one of the big 4 Australian Banks.

BANKNAME Alert: Block placed on card ending in XXXX, for suspicious transaction at ‘THING NICK PURCHASED ONLINE’ for $29.00 at 13:56. If genuine, reply ‘Yes’. If Fraud, reply ‘No’.

SMS from bank

They’d detected possible fraud on my card, and were asking me to confirm if it was me or not by texting back.

That is my correct card number, and as it happens I had made an online purchase that was what it was querying.

I was already at my computer, so out of curiosity, opened the SMS Gateway I use, and set the caller ID to be my mobile number (Because spoofing Caller ID is trivial) and replied to the number the bank sent me the SMS from.

My phone beeped again:

Thank you for confirming this transaction is genuine. The block will be removed from your card within the next 20 minutes. No further action is required.

SMS from Bank

So what’s the issue here?

The issue is if someone were to steal your card details, and know your mobile number, they could just keep texting the bank’s verification line the word “yes” from an SMS gateway spoofing your Caller ID, the bank won’t block it.

No system is foolproof, but it seems a bit short sighted by this bank.

Texting back a code would be a better solution, because it would allow you to verify the person texting received the original SMS, or cycling the caller IDs from a big pool would decrease the likelihood of this working