All posts by Nick

About Nick

Dialtone.

Nokia 3310 connected to test GSM network running with Osmocom

Twenty years of the Nokia 3310

This year I started writing a series of blog posts about building GSM networks.

I already had a bunch of phones for testing available, but there’s only one phone I wanted for running the tests…

The Nokia 3310.

To my amazement, you can still buy refurbished Nokia 3310s (new case, battery and screen) for about $12 USD each.

So I bought one;

I learned that 1 September 2000 was when the 3310 was released, making it 20 years old this month. 20 years is also about the time between charges…

Happy Birthday 3310!

AS/CA S009:2020 Key Changes for Cablers

Recently, ACMA / Communications Alliance updated the rules defining cabling – S009 – “Installation requirements for customer cabling” aka the “Wiring Rules” or “Cabling Bible”.

I don’t talk much about cabling on this blog – but I’m still a registered cabler so need to keep up to date on the changes, and quite a lot has changed since the last update in 2013 – Authority to Alter (A2A) has moved from Telstra to NBNco, PayTV over HFC is far less common, and the NBN rollout is “finished”.

So what are the key changes I need to know about? I had a read and compared to S009 / 2013, and here are they are:

“Supervised” Definition

In order to gain cabling registration you need 360 hours of supervised cabling experience. The specification has been updated to define exactly what supervised means,

4.2.59 instructed person
a person instructed or supervised by a Skilled Person as to energy sources and who can responsibly use equipment safeguards and precautionary safeguards with respect to those energy sources.
Note: Supervised, as used in the definition, means having the direction and oversight of the performance of others.

ES3 (Electrical energy source class 3 (ES3)) Definition & Rules

Reverse power feed, used in NBN FTTC tech, as well as higher voltages used for EWIS and PA systems, has led to the introduction of a new classification – ES3, for cabling that exceeds the ES2 limits,

a metallic circuit utilised for communications or Power Feeding, or both, that—
(a) exceeds the ES2 voltage and touch current limits;
(b) does not exceed 400 V d.c. between conductors; and
(c) does not exceed current as specified in AS/NZS 11801.1 or ISO/IEC 11801-1.

4.2.45 ES3 generic circuit

ES3 falls into two categories, which specific whether it can be carried over generic cabling or not,

(a) over Generic Cabling, in this Standard, are based on—
(i) circuit voltage not exceeding 400 V d.c. between conductors; and
(ii) circuit current not exceeding that specified in AS/NZS 11801.1 or ISO/IEC 11801-1.
Where voltages and currents exceed these limits, then Special Application Cabling, as classified in Item F.2(b), should be used.
(b) over Special Application Cabling in this Standard, are based on a voltage limit and current limit set by Cable manufacturer for the specific Cable and its installation requirements

F.2

So if part a is exceeded, Special Application cabling is required;

  • the cabling must meet a higher standard defined for ES3
  • must be identified by it’s sheath colour and markings at regular intervals
  • cabling has to be separated from other services (sub-ducted or separated by a barrier or more than 150mm)
  • must carry a warning label wherever the conductive part of the circuit is exposed (frames / joints) stating it is an ES3 service
  • service may not be terminated on a plug if the plug may have exposed contacts (requires a plug / socket with shutters)

RFT (Remote feeding telecommunication circuit) Definition

an equipment circuit within the ICT Network not connected to Mains power, intended to supply or receive DC power at voltages exceeding the limits of ES2, and on which transient overvoltages or overcurrents may occur.

4.2.85

Examples are PoE, ring current, USB-C / USB3, etc.

RFT circuits are classified as ES3 circuits and subject to the same conditions.


New Conductor Size / Temperature Recommendations

S009 / 2013 did not specific recommended (not mandated) size & temperature rating for generic cabling / jumpering.

It comes down to:

“have a maximum conductor resistance of 0.0938 Ω/m at 20° C “
and
“the cable should not be installed in a manner that may cause the maximum operating temperature rating of the Cable to be exceeded.”

5.6.2


Plug Terminated Cabling Requirements

Moveable cabling / plug terminated cabling must not be used unless:

the Plug is an integral part of a device that is fastened to a
wall, floor or ceiling or other permanent building element; or
(b) the Plug is not fixed and—
(i) the Plug terminates a section of Movable Cabling;
(ii) the Plug is to mate with a Port on an item of fixed Customer Equipment; and
(iii) in every position to which it may be moved when the Plug is not mated with the Port, every part of the section of Movable Cabling is either out of Arm’s Reach or housed in a Secure Enclosure that is fastened to a wall, floor or ceiling or other permanent building element.

5.9.1

Network Boundary Definition Update

A new Appendix (J) has been added with updated (informative only) definitions of Network Boundaries with examples, to support all the new network boundary definitions introduced with the access technology mix(fibre, HFC and wireless terminations).

FTTC Deployment Information (Informative)

A new Appendix (O) has been added providing information in regards to FTTC and it’s requirement to isolate the first socket from the rest of the cabling – Something that in practice seems to be a rarity.

Labelling & Safety Rules for Fibre Optic Cabling

A new requirement has been added to 11.1 in regards to Fibre Optic cabling must:

  • Have a Warning of potential hazardous laser levels
  • Have a warning regarding Access to emitted radiation
  • Types of laser warning markings
  • Laser warning marking style
  • Laser explanatory label wording
  • Marking durability of labels
  • Fibre outlets in work areas are except
  • Groups of optical fibre connectors may be marked as a group
  • Multiple markings – ie one inside the container one outside
  • Unused optical fibre connectors and adaptors must be covered

Of course, this is all just a summary of the changes I thought were key, but you can get the latest version of S009 from the Comms Alliance website.

Do your records!

Wireshark Filtering S1AP to find Subscriber Signaling

The S1 interface can be pretty noisy, which makes it hard to find the info you’re looking for.

So how do we find all the packets relating to a single subscriber / IMSI amidst a sea of S1 packets?

The S1 interface only contains the IMSI in certain NAS messages, so the first step in tracing a subscriber is to find the initial attach request from that subscriber containing the IMSI.

Luckily we can filter in Wireshark to find the IMSI we’re after;

e212.imsi == "001010000000001"

The Wireshark e212 filter filters for ITU-T E.212 payloads (ITU-T E.212 is the spec for PLMN identifiers).

Quick note – Not all IntialUEMessages will contain the IMSI – If the subscriber has already established comms with the MME it’ll instead be using a temporary identifier – M-TMSI, unless you’ve got a way to see the M-TMSI -> IMSI mapping on the MME you’ll be out of luck.

Next up let’s take a look at the contents of one of these packets,

Inside the protocolIEs is the MME_UE_S1AP_ID – This unique identifier will identify all S1 signalling for a single user.

The MME_UE_S1AP_ID is a unique identifier, assigned by the MME to identify which signaling messages are for which subscriber.

(It’s worth noting the MME_UE_S1AP_ID is only unique to the MME – If you’ve got multiple MMEs the same MME_UE_S1AP_ID could be assigned by each).

So now we have the MME_UE_S1AP_ID, we can filter all S1 messaging containing that MME_UE_S1AP_ID, we’ll use this Wireshark filter to get it:

s1ap.MME_UE_S1AP_ID == 2

Boom, there’s a all the signalling for that subscriber.

Alternatively you can just right click on the value and apply it as a filter instead of typing everything in,

Hopefully that’ll help you filter to find what you’re looking for!

List of Open Source Evolved Packet Core (EPC) Implementations

Open5Gs

Formerly NextEPC.

OpenAI Core Network

Related to / branched from OMEC.

Magma

Based on OMEC, with a focus on Fixed Wireless more than mobile.

Not fair to consider it just an EPC, Magma is highly scaleable and designed with a focus on Fixed Wireless offerings.

Supported by the Facebook Telecom Infra Project.

OMEC – Open Evolved Mobile Core

Supported by Open Networking Foundation, Sprint and several other large players.

OMEC has each Network Element in it’s own repo in GitHub and each is managed by a different team.

OpenMME – MME

In use by at least one commercial operator (in some capacity).

Next Generation Infrastructure Core (S-GW & P-GW)

Seems to only compile on 16.04 and not really

c3po – HSS / CDR / CTF

OpenCORD

srsEPC

(from the guys who produced srsLTE / srsENB / srsUE)

Android Carrier Privileges

So a problem had arisen, carriers wanted to change certain carrier related settings on devices (Specifically the Carrier Config Manager) in the Android ecosystem. The Android maintainers didn’t want to open the permissions to change these settings to everyone, only the carrier providing service to that device.

And if you purchased a phone from Carrier A, and moved to Carrier B, how do you manage the permissions for Carrier B’s app and then restrict Carrier A’s app?

Enter the Android UICC Carrier Privileges.

The carrier loads a certificate onto the SIM Cards, and signing Android Apps with this certificate, allowing the Android OS to verify the certificate on the card and the App are known to each other, and thus the carrier issuing the SIM card also issued the app, and presto, the permissions are granted to the app.

Carriers have full control of the UICC, so this mechanism provides a secure and flexible way to manage apps from the mobile network operator (MNO) hosted on generic app distribution channels (such as Google Play) while retaining special privileges on devices and without the need to sign apps with the per-device platform certificate or preinstall as a system app.

UICC Carrier Privileges doc

Once these permissions are granted your app is able to make API calls related to:

  • APN Settings
  • Roaming/nonroaming networks
  • Visual voicemail
  • SMS/MMS network settings
  • VoLTE/IMS configurations
  • OTA Updating SIM Cards
  • Sending PDUs to the card

Getting TEID up with GTP Tunnels

If you’re using an GSM / GPRS, UMTS, LTE or NR network, there’s a good chance all your data to and from the terminal is encapsulated in GTP.

GTP encapsulates user’s data into a GTP PDU / packet that can be redirected easily. This means as users of the network roam around from one part of the network to another, the destination IP of the GTP tunnel just needs to be updated, but the user’s IP address doesn’t change for the duration of their session as the user’s data is in the GTP payload.

One thing that’s a bit confusing is the TEID – Tunnel Endpoint Identifier.

Each tunnel has a sender TEID and transmitter TEID pair, as setup in the Create Session Request / Create Session Response, but in our GTP packet we only see one TEID.

There’s not much to a GTP-U header; at 8 bytes in all it’s pretty lightweight. Flags, message type and length are all pretty self explanatory. There’s an optional sequence number, the TEID value and the payload itself.

So the TEID identifies the tunnel, but it’s worth keeping in mind that the TEID only identifies a data flow from one Network Element to another, for example eNB to S-GW would have one TEID, while S-GW to P-GW would have another TEID.

Each tunnel has two TEIDs, a sending TEID and a receiving TEID. For some reason (Minimize overhead on backhaul maybe?) only the sender TEID is included in the GTP header;

This means a packet that’s coming from a mobile / UE will have one TEID, while a packet that’s going to the same mobile / UE will have a different TEID.

Mapping out TIEDs is typically done by looking at the Create Session Request / Responses, the Create Session Request will have one TIED, while the Create Session Response will have a different TIED, thus giving you your TIED pair.

GSM with Osmocom: Handovers

With just one cell/BTS, your mobile phone isn’t all that mobile.

So GSM has the concept of handovers – Once BTS (cell) can handover a call to another cell (BTS), thus allowing us to move between BTSs and keep talking on a call.

Note: I’ll use the term BTS here, because we’ve talked a lot about BTSs throughout this series. Technically a BTS can be made up of one or more cells, but to keep the language consistent with the rest of the posts I’ll use BTS, even though were talking about the cell of a BTS.

If we’re on a call, in an area served by BTS1, and we’re moving towards BTS2, at some point the signal strength from BTS2 will surpass the signal strength from BTS1, and the phone will be handed over from BTS1 to BTS2.

Handovers typically only occur when a channel is in use (ie on a phone call) if a phone isn’t in use, there’s no need to seamlessly handover as a brief loss of connectivity isn’t going to be noticed by the users.

Measurements

The question as to when to handover a call to a neighbouring cell, comes down to the signal strength levels the phone is experiencing.

The phone measures the signal strength of up to 6 nearby (neighbouring) BTSs, and reports what signal strength it’s receiving to the BTS that’s currently serving it.

The BTS then sends this info to the BSC, in the RXLEV fields of a RSL Measurement Report packet.

RXLEV fields of a RSL Measurement Report packet.

With this information the BSC makes the determination of when to handover the call to a neighbouring BTS.

There’s a lot of parameters that the BSC takes into account when making the decision to handover to a neighbouring BTS, but for the purposes of this explanation, we’ll simplify this and just imagine it’s based on which BTS has the strongest signal strength as seen by the phone.

Everybody needs good Neighbors

Our phone can only monitor the signal strength of so many neighboring cells at once (Up to 6). So in order to know which frequency (known as ARFCNs) to take signal strength measurements on, our phone needs to know the frequencies it should expect to see neighbours, so it can measure these frequencies.

The System Information Block 2 is broadcast by the BTS on the BCCH and SACCH channels, and contains the ARFCNs (Frequencies) of the BTSs that neighbour that cell.

With this info our Phone only needs to monitor the frequencies (ARFCNs) of the cells nearby it’s been told about in the SIB2 to check the received power levels on those frequences.

The Handover

This is vastly simplified…

So our phone is armed with the list of neighbouring cell frequencies (ARFCNs) and it’s taking signal strength measurements and sending them to the BTS, and onto the BSC. The BSC knows the strength of the signals around our phone on a call.

With this information the BSC makes the decision that the serving cell (BTS) the phone is currently connected to is no longer the best candidate, as another BTS would provide a higher signal strength and begins a handover to a neighbouring BTS with a better signal to the phone.

Our BSC starts by giving the new BTS a heads up it’s going to hand a call of to it, by setting up the channel to use on the new BTS, through a Channel Activation message.

Next a handover command is sent to the phone via the BTS it was initially connected to (RSL Handover Command), telling the phone to begin handover to the new BTS and the channel it should move to on the new BTS it setup earier.

Screenshot of a packet capture showing a GSM Handover

The phone moves to the new BTS, and is acknowledged by the phone. The channels the phone was using on the old BTS are released and the handover is complete.

Simplified Diagram of the Process

There is a lot more to handovers than just this, which we’ll cover in a future post.

Diameter Dispatches: S6a Authentication Information Request / Answer

This is part of a series of posts focusing on common Diameter request pairs, looking at what’s inside and what they do.

The Authentication Information Request (AIR) and Authentication Information Answer (AIA) are one of the first steps in authenticating a subscriber, and a very common Diameter transaction.

The Process

The Authentication Information Request (AIR) is sent by the MME to the HSS to request when a Subscriber begins to attach containing the IMSI of the subscriber trying to connect.

If the subscriber’s IMSI is known to the HSS, the AuC will generate Authentication Vectors for the Subscriber, and repond back to the MME in an Authentication Information Answer (AIA).

For more information on how the Authentication process works and what the authentication vectors do, I’ve written about that quite extensively here.- HSS & USIM Authentication in LTE.

The Authentication Information Request (AIR)

The AIR is a comparatively simple request, without many AVPs;

The Session-Id, Auth-Session-State, Origin-Host, Origin-Realm & Destination-Realm are all common AVPs that have to be included.

The Username AVP (AVP 1) contains the username of the subscriber, which in this case is the IMSI.

The Requested-EUTRAN-Authentication-Info AVP ( AVP 1408 ) contains information in regards to what authentication info the MME is requesting from the subscriber, typically this indicates the MME is requesting 1 vector (Number-Of-Requested-Vectors (AVP 1410)), an immediate response is preferred (Immediate-Response-Preferred (AVP 1412)), and if the subscriber is re-resyncing the SQN will include a Re-Synchronization-Info AVP (AVP 1411).

The Visited-PLMN-Id AVP (AVP 1407) contains information regarding the PLMN of the RAN the Subscriber is connecting to.

The Authentication Information Answer (AIA)

The Authentication Information Answer contains several mandatory AVPs that would be expected, The Session-Id, Auth-Session-State, Origin-Host and Origin-Realm.

The Result Code (AVP 268) indicates if the request was successful or not, 2001 indicates DIAMETER SUCCESS.

The Authentication-Info (AVP 1413) contains the returned vectors, in LTE typically only one vector is returned, a sub AVP called E-UTRAN-Vector (AVP 1414), which contains AVPs with the RAND, XRES, AUTN and KASME keys.

Further Reading & References

3GPP TS 29.272 version 15.10.0 Release 15

Example Packet Capture (PCAP) of Message Flow

Osmocom Logo

GSM with Osmocom: Channel Types

When setting up the timeslots on the TRX for each BTS on your BSC, you’ll notice you have to set a channel type.

So what do these acronyms mean, and how do they affect the performance of the network?

GSM channels break down into one of to categories, control channels – used for signalling, and traffic channels, used for carrying information to/from a user.

A network with only control channels wouldn’t allow a call to be made, as there would be no traffic channels to carry the audio of the call,

Conversely a network with only traffic channels would have plenty of capacity for calls, but without a control channel would have no way of setting them up.

Traffic Channels

Traffic channels break down into a further two categories, voice channels for carrying call audio, and data channels for carrying GPRS data.

Traffic Channels for Voice

There’s a few variants of voice channel based on the codec used for encoding the voice data, the more compressed / small the audio signal is, the more you can cram in per channel, at the sacrifice of voice quality.

Common options are Traffic Channel – Full Rate (TCH/F), & Traffic Channel – Half Rate (TCH/F) channels.

Traffic Channels for Data

When GPRS was introduced it needed to be transported on a traffic channel, but unlike a voice channel, the resources weren’t going to be used 100% of the time (like in a voice call) and could be shared on an as-needed basis.

Data channels are also also broken down into full rate and half rate channels, like Traffic Channel – Full Rate (TCH/F), & Traffic Channel – Half Rate (TCH/F) channels.

Control Channels

Control channels carry the out of band signalling between the Phone and the BTS.

Broadcast Channels

Broadcast Channels are by their very nature – Broadcasted, this means every phone on the BTS gets these messages.

There are 3 broadcast channels, the FCCH for frequency corrections, SCH for synchronisation and BCCH for a common channel that transmits information to all phones, containing info on the network such as the PLMN, neighbouring cells, etc.

Common Channels

The PCH – Paging Channel, is used to page phones in idle mode. All phones will listen on the paging channel, and if they hear their identifier will establish a connection back to the network.

RACH the Random Access Control Channel is used for when the phone wants to establish a connection with the network, by picking a random timeslot to transmit it’s data on the RACH.

The ACGC is the Access Grant Channel, containing information about dedicated channels to be assigned to phones.

Dedicated Control Channels

Like dedicated traffic channels, dedicated channels are only in use by one phone at a time.

The SDCCH is the standalone dedicated control channel, over which location updates, SMS, authentication & call setup / teardown signalling is transferred.

The SACCH – slow Associated Control Channel is used for timing advance (when users are further from the BTS timing advances are needed to ensure propogation time is taken into account), power control information, signaling data and radio measurements.

Finally the FACCH – Fast Associated Control is used for transferring larger messages such as for handover information,

Ansible – Timeout on Become

I’ve written a playbook that provisions some server infrastructure, however one of the steps is to change the hostname.

A common headache when changing the hostname on a Linux machine is that if the hostname you set for the machine, isn’t in the machine’s /etc/hosts file, then when you run sudo su or su, it takes a really long time before it shows you the prompt as the machine struggles to do a DNS lookup for it’s own hostname and fails,

This becomes an even bigger problem when you’re using Ansible to setup these machines, Ansible times out when changing the hostname;

Simple fix, edit the /etc/ansible/ansible.cfg file and include

# SSH timeout
timeout = 300

And that’s it.

GSM with Osmocom: Silent SMS & Silent Calls

Depending on if you’re wearing a tin foil hat or not, silent SMS and silent calls could be a useful tool to for administering the network or a backdoor put in to track citizenry!

Regardless of it’s reasons for existence, let’s take a look at what it actually does, and how we can use it.

To conserve battery and radio resources, terminals / UEs go into an idle state where they monitor the RSSI of the BTS/NodeB and the broadcast/paging channels, but don’t actively send anything on the uplink.

Let’s say we wanted to get the RSSI measurements from a terminal/UE we would need the terminal to go into an active state.

We could do this by calling the terminal, or sending an SMS, but if we wanted to do it without alerting the user, that’s when we can use Silent SMS and silent calls, to do so without alerting the user.

If you want to try this you can send a Silent SMS from Osmo-MSC.

OsmoMSC# subscriber msisdn 61487654321 silent-sms sender msisdn 61412341234 send Hello World
Packet capture shows no traffic on the Abis interface until the Silent SMS is sent

On top of Silent SMS there’s also silent calls, allowing for a continued stream of measurements from the UE, which can also be super useful for creating a single call leg.

Another use for Silent SMS it to interface with the SIM Card, many card manufacturers provide support for “over the air” updating of the SIM Card parameters (think if MNO A purchases MNO B and they want to share a network, you don’t want to have to re-issue every SIM card with the updated PLMN, just update the parameters on the SIM).

Messages from the network operator to their SIM cards don’t need to be shown to the user, so are can be carried via Silent SMS. – SIM card manufacturers don’t make the nitty gritty details of this functionality public – it’s a proprietary interface defined by the manufacturer, simply transported by SMS.

S1AP – Relative Capacity (87) on MME

In the S1-SETUP-RESPONSE and MME-CONFIGURATION-UPDATE there’s a RelativeMMECapacity (87) IE,

So what does it do?

Most eNBs support connections to multiple MMEs, for redundancy and scalability.

By returning a value from 0 to 255 the MME is able to indicate it’s available capacity to the eNB.

The eNB uses this information to determine which MME to dispatch to, for example:

MME PoolRelative Capacity
mme001.example.com20/255
mme002.example.com230/255
Example MME Pooling table

The eNB with the table above would likely dispatch any incoming traffic to MME002 as MME001 has very little at capacity.

If the capacity was at 1/255 then the MME would very rarely be used.

The exact mechanism for how the MME sets it’s relative capacity is up to the MME implementer, and may vary from MME to MME, but many MMEs support setting a base capacity (for example a less powerful MME you may want to set the relative capacity to make it look more utilised).

I looked to 3GPP to find what the spec says:

On S1, no specific procedure corresponds to the NAS node selection function.
The S1 interface supports the indication by the MME of its relative capacity to the eNB, in order to achieve loadbalanced MMEs within the pool area.

3GPP TS 36.410 – 5.9.2 NAS node selection function

Viewing the SIB – The LTE System Information Block with SDRs

I’ve been experimenting with Inter-RAT & Inter-Frequency handovers recetly, and had an issue where what I thought was configured on the eNB I wasn’t seeing reflected on the UEs.

I understood the Neighbouring Cell reelection parameters are broadcast in the System Information Blocks, but how could I view them?

The answer – srsUE!

I can’t get over how cool the stuff coming out of Software Radio Systems is, but being able to simulate a UE and eNB on SDR hardware is pretty awesome, and also allows you to view low layer traces the vast majority of commercial UEs will never expose to a user.

After running srsUE with the PCAP option I let it scan for networks and find mine. I didn’t actually need to authenticate with the network, just lock to the cell.

Deocoding it using the steps I laid out here for decoding LTE MAC traces in Wireshark, there it all was!

I’ve attached a copy of the pcap here for your reference.

GSM with Osmocom: GPRS & Packet Data

So far we’ve focused on building a plain “2G” (voice and SMS only) network, which was all consumers expected twenty years ago.

As the number of users accessing the internet through DSL, Dial Up & ISDN grew, the idea of getting this data “on the go” became more appealing. TCP/IP was becoming the dominant standard for networking, the first 802.11 WiFi spec had recently been published and demand for mobile data was growing.

There’s a catch however – TCP/IP was never designed to be mobile.

An IP address exists in a single location.

(Disclaimer: While you can “move” a subnet by advertising itself out in a different location via BGP peering relationships with other operators, it’s cumbersome, can only be done per /24 or larger, and most importantly it’s painfully slow. IPv6 has MIPv6 which attempts to fix some of these points, but that’s outside of this scope.)

GPRS addressed the mobility issue by having a single fixed point the IP Address is assigned to (the Gateway GPRS Support Node), which encapsulates IP traffic to/from a mobile user into GTP Packet (GPRS Tunnelling Protocol), like GRE or any of the other common routing encapsulation protocols, allowing the traffic to be rerouted to different destinations as the users move from being served by one BTS to another BTS.

I’ve written about GTP here if you’d like to learn more.

So now we’ve got a method of encapsulating our data we’ve got to work out how to get that data out over the air.

BTS Time Slots

Way back when we were first setting up our BSC and adding our BTS(s) you will have configured timeslots for each BTS configured on your BSC.

Chances are if you’ve been following along with this tutorial, that you configured the first time slot (timeslot 0) as a CCCH+SDCCH4, meaning Common Control Channel and 4 standalone dedicated control channels, and all the subsequent timeslots (timeslot 1 – 7) as Traffic Channels (full rate) – TCH/F.

This works well if we’re only carrying voice, but to carry data we need timeslots to put the data traffic on.

For this we’ll re assign a timeslot we were using on our BSC as a voice traffic channel (TCH/F) as a PDCH – a Packet Data Channel.

This means that on the BSC your timeslot config will look something like this:

   timeslot 6
    phys_chan_config PDCH
    hopping enabled 0
   timeslot 7
    phys_chan_config PDCH
    hopping enabled 0

In the above example I’ve assigned two timeslots for Packet Data Channels,

The more timeslots you allocate for data, the more bandwidth available, but the fewer voice resources available.

(Most GSM networks today have few data timeslots as more recent RATs like 3G/4G are taking the data traffic, and GSM is used primarily for voice and low bandwidth M2M communications)

GPRS and EDGE

GPRS comes in two flavors, GPRS and EDGE.

GPRS (General Packet Radio Services) was the first of the two, standardised in R97, and allowed users to reach a downlink speeds of up to 171Kbps using GMSK on the air interface to encode the data.

Users quickly expected more speed, so EDGE (Enhanced Data rates for Global Evolution) was standardised, from a core perspective it was the same, but from a BTS / Air interface perspective it relied on 8PSK instead of GMSK allowed users to reach a blistering 384Kbps on the downlink.

These speeds are the theoretical maximums.

As the difference between GPRS and EDGE is encoding on the air interface, from a core perspective it’s treated the same way, however as our BTS gets all it’s brains from the BSC, we’ll need to specify if the BTS should use EDGE or GPRS it in the BSC’s BTS config.

BSC Config

On the BSC for each BTS we want to enable for packet data, we’ll need to define the parameters.

There’s two other values we’ll introduce when setting this up,

The first is NSEI – the Network Service Entity Identifier, which is the identifier of the BTS’s Packet Control Unit, like the cell identity.

The second value we’ll touch on is the BVCI – the BSSGP Virtual Connections Identifier, which is used for addressing between the BTS PCU and the SGSN.

bts 0
  gprs mode egprs
  gprs 11bit_rach_support_for_egprs 0
  gprs routing area 0
  gprs network-control-order nc0
  gprs cell bvci 2
  gprs cell timer blocking-timer 3
  gprs cell timer blocking-retries 3
  gprs cell timer unblocking-retries 3
  gprs cell timer reset-timer 3
  gprs cell timer reset-retries 3
  gprs cell timer suspend-timer 10
  gprs cell timer suspend-retries 3
  gprs cell timer resume-timer 10
  gprs cell timer resume-retries 3
  gprs cell timer capability-update-timer 10
  gprs cell timer capability-update-retries 3
  gprs nsei 101
  gprs ns timer tns-block 3
  gprs ns timer tns-block-retries 3
  gprs ns timer tns-reset 3
  gprs ns timer tns-reset-retries 3
  gprs ns timer tns-test 30
  gprs ns timer tns-alive 3
  gprs ns timer tns-alive-retries 10
  gprs nsvc 0 nsvci 101
  gprs nsvc 0 local udp port 23001
  gprs nsvc 0 remote udp port 23000
  gprs nsvc 0 remote ip 10.0.1.201

The OsmoBSC docs cover each of these values, they’re essentially defaults.

There are quite a few changes required on the BSC for each BTS we’re setting this up for. Instead of giving you info on what fields to change, here’s the diffs.

In the next post we’ll cover the GGSN and the SGSN and then getting a device on “the net”.

GSM with Osmocom: SS7 & Sigtran

SS7 was first introduced in the 1970s and initially was designed for large scale setting up and tearing down of calls, but due to it’s layered architecture and prominence in the industry has been used for signalling between some CS network elements in Mobile Networks, including transporting messages between the MSC and any BSCs or RNCs it’s serving.

This is going to be fairly brief and Osmocom specific, keep in mind SS7 is a giant topic so there’s a huge amount we won’t cover.

Point Codes – SS7 Addressing & Routing

Historically SS7 networks were carried over TDM links of various types, and not over TCP/IP.

A point code is a unique address associated with each network element for addressing messages between network elements, it’s function is similar to that of an IP Address you’d use in IP networks.

When STP messaging is sent it includes a Source Point Code (SPC) and Destination Point Code (DPC).

The Signalling Transfer Point

Instead of a one-to-one connection between each SS7 device and every other SS7 device, a network element called a Signaling Transfer Point (STP) is used, which acts somewhat like a router.

The STP has an internal routing table made up of the Point Codes it has connections to and some logic to know how to get to each of them.

When it receives an SS7 message, the STP looks at the Destination point code, and finds if it has a path to that point code. If it does, it forwards the SS7 message on to the destination.

Like a router, an STP doesn’t really concern itself with the upper layer protocols and what they contain – As point codes are set in the MTP3 layer that’s the only layer the STP looks at and the upper layers aren’t really “any of its business”.

Sigtran & SS7 Over IP

As the world moved towards IP enabled everything, TDM based Sigtran Networks became increasingly expensive to maintain and operate, so a IETF taskforce called SIGTRAN was created to look at moving SS7 traffic to IP.

The first layer of SS7 were dropped it primarily concerned the physical side of the network, and in the Osmocom implementation the MTP3 layer and up were put into SCTP packets and carried on the network.

Notice I said SCTP and not TCP or UDP? I’ve touched upon SCTP on this blog before, it’s as if you took the best bits of TCP without the issues like head of line blocking and added multi-homing of connections.

To establish an SS7 connection over IP the MTP3 message an SCTP socket is established from the device to the STP, and then an ASP Maintenance message is sent, followed by a Registration Request containing it’s point code, and presto, we have a connection.

The Osmo STP

The Osmocom STP acts in a very trusting manner by default,

When a device wants to connect to the STP it does so via a REG_REQ (Registration Request) containing it’s Point Code. The STP accepts the connection with a REG_RSP (Registration Response).

For as long as that connection stays up any SS7 messages destined to that point code of the device that just registered, the STP will now how to get it there.

Assuming you’ve already installed the OsmoSTP you can access it on 4239:

root@gsm-bts:/etc/osmocom# telnet localhost 4239
Trying 127.0.0.1…
Connected to localhost.
Welcome to the OsmoSTP VTY interface
OsmoSTP>

After running enable we can check the current routing table:

OsmoSTP# show cs7 instance 0 sccp users
SS7 instance 0 has no SCCP
OsmoSTP# show cs7 instance 0 ro
OsmoSTP# show cs7 instance 0 route
Routing table = system
C=Cong Q=QoS P=Prio
Destination C Q P Linkset Name Linkset Non-adj Route

0.23.1/14 0 as-rkm-1 ? ? ?
0.23.3/14 0 as-rkm-2 ? ? ?

OsmoSTP# show cs7 instance 0 as all
Routing Routing Key Cic Cic Traffic
AS Name State Context Dpc Si Opc Ssn Min Max Mode

as-rkm-1 AS_ACTIVE 1 0.23.1 override
as-rkm-2 AS_ACTIVE 2 0.23.3 override

OsmoSTP# show cs7 instance 0 asp
Effect Primary
ASP Name AS Name State Type Remote IP Addr:Rmt Port SCTP
------------ ------------ ------------- ---- ----------------------- ----------
asp-dyn-0 ? ASP_ACTIVE m3ua 127.0.0.1:52192
asp-dyn-1 ? ASP_ACTIVE m3ua 127.0.0.1:33570

Packet Capture

Below is a packet capture showing a connection from an MSC to the STP.

FreeSWITCH + ESL = Programmable Voice

No great secret, I’m a big Python fan.

Recently I’ve been working on a few projects with FreeSWITCH, and looking at options for programmatically generating dialplans, instead of static XML files.

Why not Static XML?

So let’s say I define a static XML dialplan.

It works great, but if I want to change the way a call routes I need to do it from the dialplan,

That’s not ideal if you’re using a distributed cluster of FreeSWITCH instances, or if you want to update on the fly.

Static XML means we have to define our dialplan when setting up the server, and would have to reconfigure the server to change it.

So what about mod_xml_curl?

When I’ve done this in the past I’ve relied on the mod_xml_curl module.

mod_xml_curl gets the XML dialplan using Curl from a web server, and so you setup a web server using Flask/PHP/etc, and dynamically generate the dialplan when the call comes in.

This sounds good, except you can’t update it on the fly.

mod_xml_curl means call routing decisions are made at the start of the call, and can’t be changed midway through the call.

So what’s ESL?

ESL is the Event Socket Library, essentially a call comes in, an ESL request is made to an external server.

For each step in the dialplan, an ESL request will be sent to the external server which tells it to do,

ESL allows us to use all FreeSWITCH’s fantastic modules, without being limited as to having to perform the call routing logic in FreeSWITCH.

So how do I use ESL?

You’ll need two create an ESL server,

Luckily there’s premade examples for popular languages;

Once you’ve got a basic server defined we’ll need to put some config in our XML Dialplan to say “transfer all your thinking to ESL!”;

<!-- Send everything that's numbers to ESL for Processing --> 
    <extension name="esl_route">
      <condition field="destination_number" expression="^\d*$">
        <action application="socket" data="10.0.1.252:5000"/>
        <action application="log" data="ERR Made it past ESL - Play error."/>
        <action application="playback" data="ivr/ivr-call_cannot_be_completed_as_dialed"/>
      </condition>
    </extension>

In the above example my ESL server is on 10.0.1.252 / port 5000.

Now any calls coming in will be transfered to ESL and where it goes from there, is something you define in your prefered programming language.

In the next post I’ll cover how I’ve been addressing this using Python and Greenswitch.

Open5Gs Logo

Open5GS EPC: SGW selection by eNodeB ID / TAC

Thanks to Kenny Barlee the Open5GS EPC MME now has the functionality to select which S-GW to send traffic to based on the Tracking Area Code of the eNodeB or the eNodeB ID.

This is a really useful Feature that allows you to break up your S-GW (And by extension P-GW) selection based on geographical areas.

This can be used to enable Local Breakout to a S/P-GW located at the same site as the tower, but controlled by a central MME / HSS.

After updating to the latest version the configuration is pretty straightforard,

P-GW Selection based on eNB ID

# o SGW selection by eNodeB ID (either single enb_id or multiple enb_ids, decimal or hex representation)
#
   selection_mode: enb_id
   gtpc:
     - addr: 127.0.2.3
       enb_id: [9413, 0x98765]

The above config will send any traffic from eNBs with the eNB ID 9413 (encoded as an intiger) or 0x98765 (Encoded as hex int equivilent 624485) to an S-GW at 127.0.2.3.

P-GW Selection based on TAC

# SGW selection by eNodeB TAC (either single TAC or multiple TACs)
#
selection_mode: tac
   gtpc:
     - addr: 127.0.2.2
       tac: [25000, 27000, 28000]

The above config will send any traffic from eNBs with TACs of 25000, 27000, 28000 to an S-GW at 127.0.2.2.

Diameter Dispatches – Origin-State-Id AVP

The Origin-State-Id AVP solves a kind of tricky problem – how do you know if a Diameter peer has restarted?

It seems like a simple problem until you think about it.
One possible solution would be to add an AVP for “Recently Rebooted”, to be added on the first command queried of it from an endpoint, but what if there are multiple devices connecting to a Diameter endpoint?

The Origin-State AVP is a strikingly simple way to solve this problem. It’s a constantly incrementing counter that resets if the Diameter peer restarts.

If a client receives a Answer/Response where the Origin-State AVP is set to 10, and then the next request it’s set to 11, then the one after that is set to 12, 13, 14, etc, and then a request has the Origin-State AVP set to 5, the client can tell when it’s restarted by the fact 5 is lower than 14, the one before it.

It’s a constantly incrementing counter, that allows Diameter peers to detect if the endpoint has restarted.

Simple but effective.

You can find more about this in RFC3588 – the Diameter Base Protocol.

BaiCells USIM PLMN Issues (MCC 314 / MNC 030 vs MCC 311 / MNC 98)

If you’re using BaiCells hardware you may have noticed the new eNBs and USIMs are shipping with the PLMN of MCC 314 / MNC 030.

First thing I do is change the PLMN, but I was curious as to why the change.

It seems 314 / 030 was never assigned to BaiCells to use and when someone picked this up they were forced to change it.

The MCC (Mobile Country Code) part is dictated by the country / geographic area the subscribers’ are in, as defined by ITU, whereas the MNC (Mobile Network Code) allocation is managed by the regional authority and ITU are informed as to what the allocations are and publish in their bulletins.

ITU advertised this in Operational Bulletin No. 1198 (15.VI.2020)

What does this mean if you’re a BaiCells user?

Well, SIM cards will have a different IMSI / PLMN, but the hardware supports Multi-Operator Core Network which allows one eNB to broadcast multiple PLMNs, so if you update your eNB it can broadcast both!

I’ve written more about that in my post on MOCN.

Kamailio Bytes – UAC – Authenticate Outbound Calls

Sometimes you need Kamailio to serve as a User Agent Client, we covered using UAC to send SIP REGISTER messages and respond with the authentication info, but if you find you’re getting 401 or 407 responses back when sending an INVITE, you’ll need to use the UAC module, specifically the uac_auth() to authenticate the INVITE,

When Kamailio relays an INVITE to a destination, typically any replies / responses that are part of that dialog will go back to the originator using the Via headers.

This would be fine except if the originator doesn’t know the user name and password requested by the carrier, but Kamailio does,

Instead what we need Kamailio to do is if the response to the INVITE is a 401 Unauthorised Response, or a 407 Proxy Authentication required, intercept the request, generate the response to the authentication challenge, and send it to the carrier.

To do this we’ll need to use the UAC module in Kamailio and set some basic params:

loadmodule "uac.so"
modparam("uac", "reg_contact_addr", "10.0.1.252:5060")
modparam("uac", "reg_db_url", DBURL)
modparam("uac","auth_username_avp","$avp(auser)")
modparam("uac","auth_password_avp","$avp(apass)")
modparam("uac","auth_realm_avp","$avp(arealm)")

Next up when we relay the INVITE (using the Transaction module because we need the response to be transaction stateful).

Before we can call the t_relay() command, we need to specify a failure route, to be called if a negative response code comes back, we’ll use one called TRUNKAUTH and tell the transaction module that’s the one we’ll use by adding t_on_failure(“TRUNKAUTH”);

	$du = "sip:sip.nickvsnetworking.com:5060";
	if(is_method("INVITE")) {
		t_on_failure("TRUNKAUTH");
		t_relay();
		exit;
	   }

What we’ve done is specified to rewrite the destination URI to sip.nickvsnetworking.com, if the request type is an INVITE, it’ll load a failure route called TRUNKAUTH and proxy the request with the transaction module to sip.nickvsnetworking.com.

What we get is a 401 response back from our imaginary carrier, and included in it is a www-auth header for authentication.

To catch this we’ll create an on failure route named “TRUNKAUTH”

failure_route[TRUNKAUTH] {
    xlog("trunk auth");
    }

We’ll make sure the transaction hasn’t been cancelled, and if it has bail out (no point processing subsequent requests on a cancelled dialog).

failure_route[TRUNKAUTH] {
    xlog("trunk auth");
    if (t_is_canceled()) {
        exit;
    }

And determine if the response code is a 401 Unauthorised Response, or a 407 Proxy Authentication required (Authentication requests from our upstream carrier):

failure_route[TRUNKAUTH] {
    xlog("trunk auth");
    if (t_is_canceled()) {
        exit;
    }
	xlog("Checking status code");
    if(t_check_status("401|407")) {
	xlog("status code is valid auth challenge");
    }
}

Next we’ll define the username and password we want to call upon for this challenge, and generate an authentication response based on these values using the uac_auth() command,

failure_route[TRUNKAUTH] {
    xlog("trunk auth");
    if (t_is_canceled()) {
        exit;
    }
	xlog("Checking status code");
    if(t_check_status("401|407")) {
	xlog("status code is valid auth challenge");
        $avp(auser) = "test";
        $avp(apass) = "test";
        uac_auth();

    }
}

Then finally we’ll relay that back to the carrier with our www-auth header populated with the challenge response;

failure_route[TRUNKAUTH] {
    xlog("trunk auth");
    if (t_is_canceled()) {
        exit;
    }
	xlog("Checking status code");
    if(t_check_status("401|407")) {
	xlog("status code is valid auth challenge");
        $avp(auser) = "test";
        $avp(apass) = "test";
        uac_auth();
	xlog("after uac_auth");
        t_relay();
        exit;
    }
}

And done!

We can get this data from the UAC database so we don’t need to load these values directly into our config file too using the SQLops module.

As always I’ve put the running code example on my GitHub.