Category Archives: Software

Kamailio Bytes – Docker and Containers

I wrote about using Ansible to automate Kamailio config management, Ansible is great at managing VMs or bare metal deployments, but for Containers using Docker to build and manage the deployments is where it’s at.

I’m going to assume you’ve got Docker in place, if not there’s heaps of info online about getting started with Docker.

The Dockerfile

The Kamailio team publish a Docker image for use, there’s no master branch at the moment, so you’ve got to specify the version; in this case kamailio:5.3.3-stretch.

Once we’ve got that we can start on the Dockerfile,

For this example I’m going to include

#Kamailio Test Stuff
FROM kamailio/kamailio:5.3.3-stretch

#Copy the config file onto the Filesystem of the Docker instance
COPY kamailio.cfg /etc/kamailio/

#Print out the current IP Address info
RUN ip add

#Expose port 5060 (SIP) for TCP and UDP
EXPOSE 5060
EXPOSE 5060/udp

Once the dockerfile is created we can build an image,

docker image build -t kamtest:0.1 .

And then run it,

docker run kamtest:0.1

Boom, now Kamailio is running, with the config file I pushed to it from my Dockerfile directory,

Now I can setup a Softphone on my local machine and point it to the IP of the Docker instance and away we go,

Where the real power here comes in is that I can run that docker run command another 10 times, and have another 10 Kamailio instannces running.

Tie this in with Kubernetes or a similar platform and you’ve got a way to scale and manage upgrades unlike anything you’d get on Bare Metal or VMs.

I’ve uploaded a copy of my Dockerfile for reference, you can find it on my GitHub.

Kamailio Proxy-CSCF Pull

I had a few headaches getting the example P-CSCF example configs from the Kamailio team to run, recent improvements with the IPsec support and code evolution meant that the example config just didn’t run.

So, after finally working out the changes I needed to make to get Kamailio to function as a P-CSCF, I took the plunge and made my first pull request on the Kamailio project.

And here it is!

https://github.com/kamailio/kamailio/pull/2203

It’s now in the master branch, so if you want to setup a P-CSCF using Kamailio, give it a shot, as the example config finally works!

Radio Planning with Forsk Atoll Tutorial – Part 1 – The Basics: Sites and Transmitters

This series of post covers RF Planning using Forsk Atoll.
We cover the basics of RF Planning in the process of learning how to use the software.

Forsk Atoll is software for RF Planning and Optimization of mobile networks.

We’ll start by creating a new document from template:

Create new document in Forsk Atoll

In our example we’re working with LTE, so, we’ll pick the LTE template.

(The templates setup the basic information on what we’re looking at, prediction models and defaults.)

So now we’ll be looking at a blank white document, showing our map, with no data on it, Atoll doesn’t know if the area is hilly, heavily populated, densely treed, what we’re dealing with is a flat void with no features – “flatland” a perfect place to start.

Blank Document in Forsk Atoll showing no sites.

We’ll add an eNodeB (Transmitter Station and Site) from the top menu bar, clicking the transmitter icon to add a new Transmitter or Station.

Now we’ll click in the white of our map to place the transmitter site, and repeat this a few times.

Populating the map for LTE planning in Forsk Atoll

Now we’ve added a few transmitter sites, let’s take a bit of a look at one.

Atoll single cell

If we take a closer look we’ll see it’s actually created us a 3 sector site, and each of the arrows coming from the site is a cell sector.

Double clicking on the transmitter will allow us to change the basic info about the site, such as it’s location, as well as display parameters, etc.

In the General tab I’ve renamed Site0 to “Example Street Cell Site”, given it an altitude (for the base of the site) and some comments,

In the Support tab I’ve put some information about the support structure the antennas are one, in our case it’s on a 30m pylon / monopole.

In the LTE tab we can specify S1 throughput (backhaul) and in the Display tab we can set the color / icon used to display this site, but we’ll keep it simple for now and confirm these changes by pressing OK.

We can give each of our other Transmitters a bit of basic info, again, same process, double click on them and add some info:

So in my example I’ve got 3 transmitter sites, labeled and each given a bit of basic info. The main thing we need to have correct for each site is the location (In our case we’re placing them anywhere so it doesn’t matter), the height of the site (Altitude -Real) and the height of the structure (Support Height) the antennas are on.

Now we’ve got our 3 cell sites in our imaginary town devoid of any features, let’s get some coverage predictions for the inhabitants of desolate featureless town!

We’ll right click on Predictions and select “New Prediction”,

There’s a lot of different prediction types, but let’s look at the Effective Service Area Analysis for Uplink and Downlink from our eNodeBs.

We’ll be asked to give this coverage prediction a name, and also specify a Resolution – The higher the resolution the more processing time but the higher the accuracy calculated.

At 50m it means Atoll will split the map into 50m squares and calculate the coverage in each square. This would be suitable for planning in really rural areas where you want a rough idea of footprint, but for In Building Coverage you’d want far more resolution, so you might want select 5m resolution say.

We’ll click Ok and now if we expand “Predictions” we’ll see our catchily named “Effective Service Area Analysis” there.

By right clicking on our prediction we can select “Calculate” and presto, we’ll have a prediction of service area from each of our cells,

Each of those pink cherry blobs represents the effective usable area of coverage provided by our network.

We may have some unhappy customers looking at this, our users will only be able to use their devices around Fake Street, Flatland Water Tower and the Our Lady of Bandwidth church.

But if we have a look at the scale in the bottom left of the screen that’s understandable, our sites are ~10km apart…

So let’s cheat a little by clicking and dragging on each cell site to bring them closer together, in real life we can’t move sites quite so easily…

You’ll notice our prediction hasn’t changed, so let’s recalculate that by right clicking on our Prediction and selecting Calculate again,

We’ll also set our zoom level from 1:250,000 to something a bit more reasonable like 1:100,000

So now our 3 sites have got one area fairly well covered, let’s throw in a few more sites to expand our footprint a bit.

We’ll add extra sites as we did at the start, and fill in those coverage gaps.

After we’ve added some extra sites we’ll recalculate our Coverage Predictions and have a look at how we’ve done.

As you can see we’ve done Ok, a few holes in the coverage but mostly covered.

So next let’s do some tweaking to try and increase our predicted coverage,

By clicking on a site’s sector we can reorient the antenna to a different angle, by recalculating the coverage prediction we can see how this effects the predicted coverage.

By now you’ve probably got an idea of the basics of what we’re doing in Atoll, how changing the location, orientation and height of cells / sites affects the coverage, and how you can predict coverage.

In the upcoming posts we’ll cover adding real world data to Atoll so we can accurately model and predict how our RAN will perform.

We’ll look at how we can use Automatic Cell Planning to get the most optimal setup in terms of power settings, antenna orientations and tilts, etc for our existing sites.

We’ll be able to simulate subscribers, traffic flow, backhaul, and model our network all before a single truck rolls.

So stick around, the next post will be coming soon and will cover adding environment data.

Forsk Atoll 101 – Part 3 – Manual Site Placement

In our last post we talked about getting our geospatial data right, and in our first post we covered the basics of adding sites and transmitters.

There’s a bit of a chicken-and-egg problem with site placement, antenna orientation, type and down-tilt.

If all our sites were populated and in place, we could look at optimizing coverage by changing azimuths / orientations, plug in our data and run some predictions / modeling and coming up with some solutions. Likewise if we’ve already done that we might want to calculate ideal down-tilt angles to get the most out of network.

But we’ve got no sites, no transmitters and no coverage predictions yet, so we’re probably going to need to ask ourselves a more basic, but harder question: Where will we put the cell sites?

To keep this easy we’ll focus on providing the South Western corner of the Island, a town called Tankerton, with only 3 cell sites.

Manual Site Selection

In the very first post we put up a few sites, we’ll do the same, let’s place 3 sites in the bottom right of the island and attempt to provide contiguous coverage for the town with them;

We’ll pick our Station Template and set it to FDD Rural as this is pretty remote.

Next we’ll add some sites and transmitters:

Click to place it on the map and add our cell sites;

When we’re looking at where to place it, it’s good to remember that height (elevation) is good (To an extent), so when looking at where to place sites, keep an eye on the Z (Height) value in the bottom right, and try and pick sites with a good elevation.

Setting Computation Zone

As we’re only focusing on a small part of the island we’ll set a Computation Zone to limit the calculations / computations Atoll has to do to a set region.

I’ve chosen to draw a Polygon around the area, but you could also just get away with drawing a Rectangle, around the area we’re interested in.

This just constrains everything so we’re only crunching numbers inside that area.

Predictions

So now we’ve put our 3 sites out & constrained to the Tankerton area, let’s see how much of the area we’ve covered, we’ll jump to the Network tab, right click on Predictions and select New Prediction

There’s a lot of predictions we can run, but we’ll go simple and select Effective Service Area Analysis (UL + DL) & click Calculate

Atoll will crunch the numbers and give us a simple overlay, showing the areas with and without coverage.

The areas in red are predicted to have coverage, and the areas with no shading will be our blackspots / “notspots”.

We’ve covered most of the area, but we can improve.

Manually Tweaking Attributes

So there’s still some holes in our coverage, so let’s adjust the azimuth of some of the antennas and see if we can fill them.

Click on each of the arrows on the site, each of these represents an antenna / cell and we can change the angles.

So after a bit of fiddling I think I’ve got a better antenna azimuth for each of the sectors on each of my 3 sites.

Let’s compare that to what we had before to see if we’ve made it better or worse,

We’ll Duplicate the Effective Service Area Analysis prediction we created before & calculate it.

To make viewing a bit easier we’ll edit the properties of the copy and set it to a different colour:

Now I can see at a glance how much better we’re looking;

The obvious problem here is I could tweak and tweak and improve some things, make others worse, and we’d be here forever.

Luckily Atoll can do a better job of fiddling with each parameter for us and selecting the configuration that leads to the best performance in our RAN.

Automatic Cell Planning

Enter Automatic Cell Planning, to adjust the parameters we set to find the most optimal setup,

We’ll right click on ACP – Automatic Cell Planning and create a new one.

From here we set how many iterations we want to try out (more leads to better results but takes longer to compute), the parameters we want to change (ie Azimuth, Tilt, Antenna type, etc).

Setting number of iterations – Higher leads to better results but takes longer to calculate and has diminishing returns
We’ll allow the Tilt (Electrical & Mechanical) to be adjusted as well as the Azimuth of each antenna.

When you’ve set the parameters you want, click Run and Atoll will start running through possible parameter combinations and measuring how they perform.

Once it’s run you’ll be able to view the Optomization

The report shows you the results, improvements in RSSI and RSSQ;

Here we can see we boosted the RSRQ (The quality of the signal) by 9.5%, but had to sacrifice RSRP (Signal power) by 1%.

Sacrificies have to be made, and if you’re happy with this you can view the details of the changes, and commit the adjustments.

Committing the changes adjusts all the Transmitters in the area to the listed values, after which we can run our Predictions again to compare like we did earlier.

So that’s what we’ve got when we randomly place sites, we can use Atoll to optomize what we’ve already got, but what if we left the picking of cell sites up to Atoll to look for better options?

In our next post we’ll look at Site Selection using ACP, and constraining it. This means we can tell Atoll to just find the best sites, or load in a list of possible sites and let Atoll determine which are the best candidates.

RF Planning with Forsk Atoll - Laying out environmental data

Forsk Atoll 101 – Part 2 – Where are we?

So you’re here, reading this.

You’ve done the flatland model we did Part 1 and now you’re pumped up and ready to start plotting your cell sites, optimizing your coverage and boosting the services you’re offering.

But one thing stands in your way – The predicted & modeled data we get out of Atoll is only going to be as good as the data we’ve given it, the old garbage in garbage out adage.

So welcome, to the world of GIS my friend.

So let’s start with a location we’ll plan a cell service roll out for, in this case I’ve picked French Island, an island in Port Philip bay in Australia, 61 Km from Australia’s 2nd largest city. French Island has no mains power, water or sewerage, no connection to the mainland, no council, hosted an Alcatraz style prison and at one stage was going to be the site of Australia’s only nuclear power plant. Most of it’s inhabitants are Kolas, and thought this tutorial, we’ll setup the island with cell coverage.

So let’s get started, we’ll create a new document from Template again and select LTE.

Setting our Projection

Now before we go throwing out cell sites we’re going to have to tell Atoll where we are, this can get a little tricky if you’re setting this up for a different real world location, but stick with me and I’ll give you the data you need for this example.

We’ll select Document -> Properties and we’ve got to define a projection,

A projection is essentially a coordinate system, like Latitude and Longitude, that constrains our project to somewhere on this planet.

In this example we’re in Australia, so we’ll select Asia Pacific from the “Find In” section and scroll until we find MGA Zone 55. We’ll select it and click OK.

All this Zone information makes sense to GIS folks, there’s lots of information online about UTM datums, projections and GIS, which can help you select the right Coordinate system and projection for your particular area – But for us we’ll select MGA Zone 55 and that’s the last we’ll hear about it.

So now we’ve got that information setup we’ll hit Ok again and be on our way. Atoll now knows where in the world we are and we can start filling in the specifics.

So now we’ve still got an empty map with nothing to show, so let’s add some data.

Adding Population and Roads

We’ll start by adding some base data, we’ll import a footprint of the Island and a map of all the roads.

First we’ll import the populated area outline it into Atoll from File -> Import and select the file called EXTRACT_POLYGON.shp

We’ll put it into the population folder, this will be useful later when we try and ensure this area is covered by our network.

Although the population data is kind of rough ( <100 for the entire area) it’s still very useful for limiting our coverage area and saying “We’ve got everyone covered” when it comes to coverage.

Next up we’ll import the roads file, same thing, File -> Import, TR_ROAD.shp

We’ll import it to the Geo folder – This is just data that Atoll doesn’t process but is useful to us as humans.

Finally we’ll enable the layers we’ve just imported and center the map on our imported data to get us in the right region. We’ll do this by expanding “Population”, right clicking on the file we just imported and selecting “Center in Map Window”

You may have to tick the layer to enable it
Population footprint with roads

Adding Elevation Data

Again, like our Datum elevation data is a standard GIS concept, but if you’re from an RF background you’ve probably not come across it, essentially it’s an image where the shade of each pixel translates to a height above sea level.

We import it into Atoll and it’s used in propagation modeling – after all we need to know if there’s a hill / mountain / valley in the way, and even slight rises / dips in the geography can have an impact on your coverage.

We’ll start by downloading the file above, and then importing it into Atoll

Next we’ll need to tell Atoll the type of data we’re importing (Altitudes) and it’s offset from the 0 point of our coordinate system, I’ve put the information we need for this into a handy table below:

West337,966
North5,768,108
Pixel Size5m

Now when we move our cursor around we’ll see the elevation change in the bottom right ( z is height).

This is because the elevation data is kind of invisible (We’re looking top down) but it’s there.

Adding a Map Overlay

Ok, you’ve made it this far, let’s finally get out of our white blank map and give it some things that make it look like a map!

I’ve written a post on how to add these map layers, it’s very simple and involves editing just one file. Save your work, close Atoll, follow the instructions in this link and reopen your Atoll file.

In order to add Google Maps / Bing Maps etc as an overlay for the first time, we’ve got to restart Atoll, be sure to save your work first.

Done that? Good, let’s add some map tiles.

We’ll right click on Online Maps -> New and select a map source from the drop down menu,

Next we’ll select a tile server, I’m using Open Street Map Standard Map, which I selected from the drop down menu,

Finally we’ll enable the layer by ticking it on the Geo panel on the right hand side. You may need to drag the layer to the top if you’ve added other layers.

All going well you’ll be looking at a map of the area, and by hovering over an area of land you should see the elevation data too.

We can even add other map layers and toggle between them or set the order by dragging them up and down.

Summary

So now we’ve got Atoll configured for our part of the world, imported height data, population data and roads, and added some map layers so we can see what we’re up to.

An important point to keep in mind is the more accurate the data you feed into Atoll, the more real-world the results you’ll get out of it will be.

Although filling in map layers and adding information seems tedious – and it is – the data-in data-out approach applies here, so the more quality data we put in the better.

If you’re doing this yourself in the real world contact your Government, they often publish large amounts of geospatial data like elevation, population, roads, land boundaries, and it’s often free.

I’ve attached my working file for you to play with in case you had any issues.

In the next post we’ll add some cell sites and look at placement.

SRS LTE – Software Defined LTE Stack with BladeRF x40

The team at Software Radio Systems in Ireland have been working on an open source LTE stack for some time, to be used with software defined radio (SDR) hardware like the USRP, BladeRF and LimeSDR.

They’ve released SRSUE and SRSENB their open source EUTRAN UE and eNodeB, which allow your SDR hardware to function as a LTE UE and connect to a commercial eNB like a standard UE while getting all the juicy logs and debug info, or as a LTE eNB and have commercial UEs connect to a network you’re running, all on COTS hardware.

The eNB supports S1AP to connect to a 3GPP compliant EPC, like Open5Gs, but also comes bundled with a barebones EPC for testing.

The UE allows you to do performance testing and gather packet captures on the MAC & PHY layers, something you can’t do on a commericial UE. It also supports software-USIMs (IMSI / K / OP variables stored in a text file) or physical USIMs using a card reader.

I’ve got a draw full of SDR hardware, from the first RTL-SDR dongle I got years ago, to a few HackRFs, a LimeSDR up to the BladeRF x40.

Really cool software to have a play with, I’ve been using SRSUE to get a better understanding of the lower layers of the Uu interface.

Installation

After mucking around trying to satisfy all the dependencies from source I found everything I needed could be found in Debian packages from the repos of the maintainers.

To begin with we need to install the BladeRF drivers and SopySDR modules to abstract it to UHD:

sudo add-apt-repository -y ppa:myriadrf/drivers
sudo add-apt-repository -y ppa:bladerf/bladerf
apt-get install *bladerf*
apt-get install libgnuradio-uhd3.7.11 libuhd-dev soapysdr-module-uhd uhd-soapysdr

Next up installing Software Radio System’s repo:

sudo add-apt-repository -y ppa:srslte/releases
sudo apt-get update
sudo apt-get install srslte -y 

And that’s it!

PyHSS Update – IMS Cx Support!

As I’ve been doing more and more work with IMS / VoLTE, the requirements / features on PyHSS has grown.

Some key features I’ve added recently:

IMS HSS Features

IMS Cx Server Assignment Request / Answer

IMS Cx Multimedia Authentication Request / Answer

IMS Cx User Authentication Request / Answer

IMS Cx Location Information Request / Answer

General HSS Features

Better logging (IPs instead of Diameter hostnames)

Better Resync Support (For USIMs with different sync windows)

ToDo

There’s still some functions in the 3GPP Cx interface description I need to implement:

IMS Cx Registration-Termination Request / Answer

IMS Cx Push-Profile-Request / Answer

Support for Resync in IMS Cx Multimedia Authentication Answer

Keep an eye on the GitLab repo where I’m pushing the changes.

If you’re leaning about VoLTE & IMS networks, or building your own, I’d suggest checking out my other posts on the topic.

Kamailio Bytes – Dispatcher States

You may already be familiar with Kamailio’s Disptacher module, if you’re not, you can learn all about it in my Kamailio Bytes – Dispatcher Module post.

One question that’s not as obvious as it perhaps should be is the different states shown with kamcmd dispatcher.list command;

So what do the flags for state mean?

The first letter in the flag means is the current state, Active (A), Inactive (I) or Disabled (D).

The second letter in the flag means monitor status, Probing (P) meaning actively checked with SIP Options pings, or Not Set (X) denoting the device isn’t actively checked with SIP Options pings.

AP Actively Probing – SIP OPTIONS are getting a response, routing to this destination is possible, and it’s “Up” for all intents and purposes.

IPInactively Probing – Destination is not meeting the threshold of SIP OPTIONS request responses it needs to be considered active. The destination is either down or not responding to all SIP OPTIONS pings. Often this is due to needing X number of positive responses before considering the destination as “Up”.

DX Disabled & Not Probing – This device is disabled, no SIP OPTIONS are sent.

AX Active & Not Probing– No SIP OPTIONS are sent to check state, but is is effectively “Up” even though the remote end may not be reachable.

Kamailio Bytes – Rewriting SIP Headers (Caller ID Example)

Back to basics today,

In the third part of the Kamailio 101 series I briefly touched upon pseudovariables, but let’s look into what exactly they are and how we can manipulate them to change headers.

The term “pseudo-variable” is used for special tokens that can be given as parameters to different script functions and they will be replaced with a value before the execution of the function.

https://www.kamailio.org/wiki/cookbooks/devel/pseudovariables

You’ve probably seen in any number of the previous Kamailio Bytes posts me use pseudovariables, often in xlog or in if statements, they’re generally short strings prefixed with a $ sign like $fU, $tU, $ua, etc.

When Kamailio gets a SIP message it explodes it into a pile of variables, getting the To URI and putting it into a psudovariable called $tU, etc.

We can update the value of say $tU and then forward the SIP message on, but the To URI will now use our updated value.

When it comes to rewriting caller ID, changing domains, manipulating specific headers etc, pseudovariables is where it mostly happens.

Kamailio allows us to read these variables and for most of them rewrite them – But there’s a catch. We can mess with the headers which could result in our traffic being considered invalid by the next SIP proxy / device in the chain, or we could mess with the routing headers like Route, Via, etc, and find that our responses never get where they need to go.

So be careful! Headers exist for a reason, some are informational for end users, others are functional so other SIP proxies and UACs can know what’s going on.

Rewriting SIP From Username Header (Caller ID)

When Kamailio’s SIP parser receives a SIP request/response it decodes the vast majority of the SIP headers into a variety of pseudovariables, we can then reference these variables we can then reference from our routing logic.

Let’s pause here and go back to the Stateless SIP Proxy Example, as we’ll build directly on that.

Follow the instructions in that post to get your stateless SIP proxy up and running, and we’ll make this simple change:

####### Routing Logic ########


/* Main SIP request routing logic
 * - processing of any incoming SIP request starts with this route
 * - note: this is the same as route { ... } */
request_route {

        xlog("Received $rm to $ru - Forwarding");
        $fU = "Nick Blog Example";   #Set From Username to this value
        #Forward to new IP
        forward("192.168.1.110");

}

Now when our traffic is proxied the From Username will show “Nick Blog Example” instead of what it previously showed.

Pretty simple, but very powerful.

As you’ve made it this far might be worth familiarising yourself with the different types of SIP proxy – Stateless, Transaction Stateful and Dialog Stateful.

OTP Authentication required to unlock IMS Debugging and TCPDUMP on Samsung Sysdump tool

Reverse Engineering Samsung Sysdump Utils to Unlock IMS Debug & TCPdump on Samsung Phones

Note: This post is just about the how I reverse engineered the tool, for info on how to use it, you want this post.

While poking around the development and debugging features on Samsung handsets I found the ability to run IMS Debugging directly from the handset.

Alas, the option is only available in the commercial version, it’s just there for carriers, and requires a One Time Password to unlock.

OTP Authentication required to unlock IMS Debugging and TCPDUMP on Samsung Sysdump tool "This menu is not allowed for commercial version. You can activate this menu after OTP Authentication enabled"

When tapping on the option a challenge is generated with a key.

Interestingly I noticed that the key changes each time and can reject you even in aeroplane mode, suggesting the authentication happens client side.

This left me thinking – If the authentication happens client side, then the App has to know what the valid password for the key shown is…

Some research revealed you can pull APKs off an Android phone, so I downloaded a utility called “APK Extractor” from the Play store, and used it to extract the Samsung Sysdump utility.

So now I was armed with the APK on my local machine, the next step was to see if I could decompile the APK back into source code.

Some Googling found me an online APK decompiler, which I fed the compiled APK file and got back the source code.

I did some poking around inside the source code, and then I found an interesting directory:

Here’s a screenshot of the vanilla code that came out of the app.

Samsung OTPSecurty Source Code

I’m not a Java expert, but even I could see the “CheckOTP” function and understand that that’s what validates the One Time Passwords.

The while loop threw me a little – until I read through the rest of the code; the “key” in the popup box is actually a text string representing the current UNIX timestamp down to the minute level. The correct password is an operation done on the “key”, however the CheckOTP function doesn’t know the challenge key, but has the current time, so generates a challenge key for each timestamp back a few minutes and a few minutes into the future.

I modified the code slightly to allow me to enter the presented “key” and get the correct password back. It’s worth noting you need to act quickly, enter the “key” and enter the response within a minute or so.

In the end I’ve posted the code on an online Java compiler,

Generate OTP Response from Key (Challenge)

Replace yy182 with your challenge. I suggest you try the 0 offset and type it in quickly.

I did a write up on how to use the features this unlocks in this post.

If you’re leaning about VoLTE & IMS networks, or building your own, I’d suggest checking out my other posts on the topic.

Samsung-Sysdump-IMS-Debug-DM-View_Cropped

VoLTE/IMS Debugging on Samsung Handsets using Sysdump & Samsung IMS Logger

Samsung handsets have a feature built in to allow debugging from the handset, called Sysdump.

Entering *#9900# from the Dialing Screen will bring up the Sysdump App, from here you can dump logs from the device, and run a variety of debugging procedures.

Samsung share information about this app publicly on their website,

Sysdump App in Samsung handsets used for debugging the device

But for private LTE operators, the two most interesting options are by far the TCPDUMP START option and IMS Logger, but both are grayed out.

Tapping on them asks for a one-time password and has a challenge key.

OTP Authentication required to unlock IMS Debugging and TCPDUMP on Samsung Sysdump tool

These options are not available in the commercial version of the OS and need to be unlocked with a one time key generated by a tool Samsung for unlocking engineering firmware on handsets.

Luckily this authentication happens client side, which means we can work out the password it’s expecting.

For those interested I’ve done a write up of how I reversed the password validation algorithm to take the key given in the OTP challenge and generate a valid response.

For those who just want to unlock these features you can click here to run the tool that generates the response.

Once you’ve entered the code and successfully unlocked the IMS Debugging tool there’s a few really cool features in the hamburger menu in the top right.

DM View

This shows the SIP / IMS Messaging and the current signal strength parameters (used to determine which RAN type to use (Ie falling back from VoLTE to UMTS / Circuit Switched when the LTE signal strength drops).

Screenshot of Samsung Sysdump tool in the IMS Debug - DM View section

Tapping on the SIP messages expands them and allows you to see the contents of the SIP messages.

Viewing SIP Messaging directly from the handset

Interesting the actual nitty-gritty parameters in the SIP headers are missing, replaced with X for anything “private” or identifiable.

Luckily all this info can be found in the Pcap.

The DM View is great for getting a quick look at what’s going on, on the mobile device itself, without needing a PC.

Logging

The real power comes in the logging functions,

There’s a lot of logging options, including screen recording, TCPdump (as in Packet Captures) and Syslog logging.

From the hamburger menu we can select the logging parameters we want to change.

Settings for Samsung IMS Logger

From the Filter Options menu we can set what info we’re going to log,

Filter options used in Dump output of Samsung IMS Logger application

If you’re leaning about VoLTE & IMS networks, or building your own, I’d suggest checking out my other posts on the topic.

PLMN Identity from Wireshark in Hex Form

PLMN Identifier Calculation (MCC & MNC to PLMN)

Note: This didn’t handle 3 digit MNCs, an updated version is available here and in the code sample below.

The PLMN Identifier is used to identify the radio networks in use, it’s made up of the MCC – Mobile Country Code and MNC – Mobile Network Code.

But sadly it’s not as simple as just concatenating MCC and MNC like in the IMSI, there’s a bit more to it.

In the example above the Tracking Area Identity includes the PLMN Identity, and Wireshark has been kind enough to split it out into MCC and MNC, but how does it get that from the value 12f410?

This one took me longer to work out than I’d like to admit, and saw me looking through the GSM spec, but here goes:

PLMN Contents: Mobile Country Code (MCC) followed by the Mobile Network Code (MNC).
Coding: according to TS GSM 04.08 [14].

If storage for fewer than the maximum possible number n is required, the excess bytes shall be set to ‘FF’. For instance, using 246 for the MCC and 81 for the MNC and if this is the first and only PLMN, the contents reads as follows: Bytes 1-3: ’42’ ‘F6′ ’18’ Bytes 4-6: ‘FF’ ‘FF’ ‘FF’ etc.

TS GSM 04.08 [14].

Making sense to you now? Me neither.

Here’s the Python code I wrote to encode MCC and MNCs to PLMN Identifiers and to decode PLMN into MCC and MNC, and then we’ll talk about what’s happening:

def Reverse(str):
    stringlength=len(str)
    slicedString=str[stringlength::-1]
    return (slicedString)    

def DecodePLMN(plmn):
    print("Decoding PLMN: " + str(plmn))
    
    if "f" in plmn:
        mcc = Reverse(plmn[0:2]) + Reverse(plmn[2:4]).replace('f', '')
        print("Decoded MCC: " + str(mcc))
        mnc = Reverse(plmn[4:6])
    else:
        mcc = Reverse(plmn[0:2]) + Reverse(plmn[2:4][1])
        print("Decoded MCC: " + str(mcc))
        mnc = Reverse(plmn[4:6]) + str(Reverse(plmn[2:4][0]))
    print("Decoded MNC: " + str(mnc))
    return mcc, mnc

def EncodePLMN(mcc, mnc):
        plmn = list('XXXXXX')
        if len(mnc) == 2:
            plmn[0] = Reverse(mcc)[1]
            plmn[1] = Reverse(mcc)[2]
            plmn[2] = "f"
            plmn[3] = Reverse(mcc)[0]
            plmn[4] = Reverse(mnc)[0]
            plmn[5] = Reverse(mnc)[1]
            plmn_list = plmn
            plmn = ''
        else:
            plmn[0] = Reverse(mcc)[1]
            plmn[1] = Reverse(mcc)[2]
            plmn[2] = Reverse(mnc)[0]
            plmn[3] = Reverse(mcc)[0]
            plmn[4] = Reverse(mnc)[1]
            plmn[5] = Reverse(mnc)[2]
            plmn_list = plmn
            plmn = ''
        for bits in plmn_list:
            plmn = plmn + bits
        print("Encoded PLMN: " + str(plmn))
        return plmn

EncodePLMN('505', '93')
EncodePLMN('310', '410')

DecodePLMN("05f539")
DecodePLMN("130014")

In the above example I take MCC 505 (Australia) and MCC 93 and generate the PLMN ID 05f539.

The first step in decoding is to take the first two bits (in our case 05 and reverse them – 50, then we take the third and fourth bits (f5) and reverse them too, and strip the letter f, now we have just 5. We join that with what we had earlier and there’s our MCC – 505.

Next we get our MNC, for this we take bytes 5 & 6 (39) and reverse them, and there’s our MNC – 93.

Together we’ve got MCC 505 and MNC 93.

The one answer I’m still looking for; why not just encode 50593? What is gained by encoding it as 05f539?

PyHSS Update – MongoDB Backend & SQN Resync

After a few quiet months I’m excited to say I’ve pushed through some improvements recently to PyHSS and it’s growing into a more usable HSS platform.

MongoDB Backend

This has a few obvious advantages – More salable, etc, but also opens up the ability to customize more of the subscriber parameters, like GBR bearers, etc, that simple flat text files just wouldn’t support, as well as the obvious issues with threading and writing to and from text files at scale.

Knock knock.

Race condition.

Who’s there?

— Threading Joke.

For now I’m using the Open5GS MongoDB schema, so the Open5Gs web UI can be used for administering the system and adding subscribers.

The CSV / text file backend is still there and still works, the MongoDB backend is only used if you enable it in the YAML file.

The documentation for setting this up is in the readme.

SQN Resync

If you’re working across multiple different HSS’ or perhaps messing with some crypto stuff on your USIM, there’s a chance you’ll get the SQN (The Sequence Number) on the USIM out of sync with what’s on the HSS.

This manifests itself as an Update Location Request being sent from the UE in response to an Authentication Information Answer and coming back with a Re-Syncronization-Info AVP in the Authentication Info AVP. I’ll talk more about how this works in another post, but in short PyHSS now looks at this value and uses it combined with the original RAND value sent in the Authentication Information Answer, to find the correct SQN value and update whichever database backend you’re using accordingly, and then send another Authentication Information Answer with authentication vectors with the correct SQN.

SQN Resync is something that’s really cryptographically difficult to implement / confusing, hence this taking so long.

What’s next? – IMS / Multimedia Auth

The next feature that’s coming soon is the Multimedia Authentication Request / Answer to allow CSCFs to query for IMS Registration and manage the Cx and Dx interfaces.

Code for this is already in place but failing some tests, not sure if that’s to do with the MAA response or something on my CSCFs,

Keep an eye on the GitLab repo!

Making use of Australian Elevation Data in Forsk Atoll

The Australian Government publishes elevation data online that’s freely available for anyone to use. There’s a catch – If you’re using Forsk Atoll, it won’t import without a fair bit of monkeying around with the data…

The data is published on a a system called ELVIS – Elevation – Foundation Spatial Data.

You draw around the area you want to download, enter your email address and you’re linked to a download of the dataset you’ve selected.

So now we download the data from the link, unzip it and we’re provided with a .tiff image with the elevation data in the pixel colour and geocoded with the positional information.

Problem is, this won’t import into Atoll – Unsupported depth.

Forsk Atoll - Unsupported Depth when importing

I found a tool called VTBuilder – A tool for messing with terrain data.

I fired it up, and imported the elevation tiff file we’d downloaded.

Selected “Elevation” waited a few seconds and presto!

We can export from here in the PNG 16 bit grayscale format Atoll takes, but there’s a catch, negative elevation values and blank data will show up as giant spikes which will totally mess with your propagation modeling.

So I found an option to remove elevation data from a set range, but it won’t deal with negative values…

So I found another option in the elevation menu to offset elevation vertically, I added 100 ft (It’s all in ft for some reason) to everything which meant my elevation data that was previously negative was now just under 100.

So if an area was -1ft before it was now 99ft.

Now I was able to use the remove range for anything from 0 100 ft (previously sea level)

Now my map only shows data above sea level

Now I offset the elevation vertically again and remove 100ft so we get back to real values

Now I was able to export the elevation data from the Elevation -> Export to menu

Atoll seems to like PNG 16 bit greyscale so that’s what we’ll feed it.

In Atoll we’ll select File -> Import and open the PNG we just generated.

Data type will be Altitude, Pixel size is 5m (as denoted in email / dataset metadata).

Next question is offset, which took me a while to work out…

The email has the Lat & Long but Atoll deals in WGS co-ordinates,

Luckily the GeoPlanner website allows you to enter the lat & long of the top corner and get the equivalent West and North values for the UTM dataum.

Enter these values as your coordinates and you’re sorted.

I can even able a Map layer and confirm it lines up:

Open5Gs Logo

Open5GS – Splitting Network Elements

Note: NextEPC the Open Source project rebranded as Open5Gs in 2019 due to a naming issue. The remaining software called NextEPC is a branch of an old version of Open5Gs. This post was written before the rebranding.

I’ve been working for some time on Private LTE networks, and wrote my own HSS (See PyHSS – Python Home Subscriber Server).

The packet core I’m using is NextEPC, it’s well written, flexible and well supported.

I joined the Open5Gs group and I’ve contributed a few bits and pieces to the project.

One of which was how to split all the network elements in NextEPC:

NextEPC Splitting Network Elements

In a production network network elements would typically not all be on the same machine, as is the default example that ships with NextEPC.

NextEPC is designed to be standards compliant, so in theory you can connect any core network element (MME, PGW, SGW, PCRF, HSS) from NextEPC or any other vendor to form a functioning network, so long as they are 3GPP compliant.

To demonstrate this we will cover isolating each network element onto it’s on machine and connect each network element to the other. For some interfaces specifying multiple interfaces is supported to allow connection to multiple

In these examples we’ll be connecting NextEPC elements together, but it could just as easily be EPC elements from a different vendor in the place of any NextEPC network element.

ServiceIPIdentity
P-GW10.0.1.121pgw.localdomain
S-GW10.0.1.122 
PCRF10.0.1.123pcrf.localdomain
MME10.0.1.124mme.localdomain
HSS10.0.1.118hss.localdomain

External P-GW

In it’s simplest from the P-GW has 3 interfaces:

  • S5 – Connection to home network S-GW (GTP-C)
  • Gx – Connection to PCRF (Diameter)
  • Sgi – Connection to external network (Generally the Internet via standard TCP/IP)

S5 Interface Configuration

Edit /etc/nextepc/pgw.confand change the address to IP of the server running the P-GW for the listener on GTP-C and GTP-U interfaces.

pgw:
    freeDiameter: pgw.conf
    gtpc: 
      addr:
        - 10.0.1.121
     gtpu: 
      addr:
        - 10.0.1.121

Gx Interface Configuration

Edit /etc/nextepc/freeDiameter/pgwd.conf

Update ListenOn address to IP of the server running the P-GW:

ListenOn = "10.0.1.121";

Update ConnectPeer to connect to the PCRF on it’s IP.

ConnectPeer = "pcrf.localdomain" { ConnectTo = "10.0.1.123"; No_TLS; };

Restart Services

Restart NextEPC PGW Daemon:

$ sudo systemctl restart nextepc-pgwd

External S-GW

In it’s simplest form the S-GW has 2 interfaces:

  • S11 – Connection to MME (GTP-C)
  • S5 – Connection to the home network P-GW (GTP-C)

S5 Interface Configuration

Edit /etc/nextepc/sgw.confand change the address to IP of the server running the S-GW for the listener on GTP-C interface.

sgw:
    freeDiameter: pgw.conf
    gtpc: 
      addr:
        - 10.0.1.122

Restart NextEPC SGW Daemon:

$ sudo systemctl restart nextepc-sgwd

External PCRF

In it’s simplest from the PCRF has 1 network interface:

  • Gx – Connection to P-GW (Diameter)

Gx Interface Configuration

Edit /etc/nextepc/freeDiameter/hss.conf

Update ListenOn address to IP of the server running the HSS on it’s IP:

ListenOn = "10.0.1.123";

Update ConnectPeer to connect to the MME.

ConnectPeer = "pgw.localdomain" { ConnectTo = "10.0.1.121"; No_TLS; };

MongoDB Interface Configuration (NextEPC HSS only)

Edit /etc/nextepc/freeDiameter/hss.conf and change the db_uri: to point at the HSS: db_uri: mongodb://10.0.1.118/nextepc

Restart NextEPC PCRF Daemon:

$ sudo systemctl restart nextepc-pcrfd

External HSS

In it’s simplest form the HSS has 1 network interface:

  • S6a – Connection to MME (Diameter)

S6a Interface Configuration

Edit /etc/nextepc/freeDiameter/hss.conf

Update ListenOn address to IP of the server running the HSS on it’s IP:

ListenOn = "10.0.1.118";

Update ConnectPeer to connect to the MME.

ConnectPeer = "mme.localdomain" { ConnectTo = "10.0.1.124"; No_TLS; };

Restart NextEPC HSS Daemon:

$ sudo systemctl restart nextepc-hssd

MongoDB Interface Configuration (NextEPC specific)

If you are using NextEPC’s HSS you may need to enable MongoDB access from the PCRF. This is done by editing ‘‘/etc/mongodb.conf’’ and changing the bind IP to: bind_ip = 0.0.0.0

Restart MongoDB for changes to take effect.

$ /etc/init.d/mongodb restart

External MME

In it’s simplest form the MME has 3 interfaces:

  • S1AP – Connections from eNodeBs
  • S6a – Connection to HSS (Diameter)
  • S11 – Connection to S-GW (GTP-C)

S11 Interface Configuration

Edit /etc/nextepc/mme.conf, filling the IP address of the S-GW and P-GW servers.

sgw:
    gtpc:
      addr: 10.0.1.122

pgw:
    gtpc:
      addr:
        - 10.0.1.121

S6a Interface Configuration

Edit /etc/nextepc/freeDiameter/mme.conf

Update ListenOn address to IP of the server running the MME:

ListenOn = "10.0.1.124";

Update ConnectPeer to connect to the PCRF on it’s IP.

ConnectPeer = "hss.localdomain" { ConnectTo = "10.0.1.118"; No_TLS; };

Restart Services

Restart NextEPC MME Daemon:

$ sudo systemctl restart nextepc-mmed

Building Android APN / Carrier Config

As anyone who’s setup a private LTE network can generally attest, APNs can be a real headache.

SIM/USIM cards, don’t store any APN details. In this past you may remember having to plug all these settings into your new phone when you upgraded so you could get online again.

Today when you insert a USIM belonging to a commercial operator, you generally don’t need to put APN settings in, this is because Android OS has its own index of APNs. When the USIM is inserted into the baseband module, the handset’s OS looks at the MCC & MNC in the IMSI and gets the APN settings automatically from Android’s database of APN details.

There is an option for the network to send the connectivity details to the UE in a special type of SMS, but we won’t go into that.

All this info is stored on the Android OS in apns-full-conf.xml which for non-rooted (stock) devices is not editable.

Instead the devices get updates through the OS updates which pull the latest copy of this file from Google’s Android Open Source Git repo, you can view the current master file here.

This file can override the user’s APN configuration, which can lead to some really confusing times as your EPC rejects the connection due to an unrecognized APN which is not what you have configured on the UE’s operating system, but it instead uses APN details from it’s database.

The only way around this is to change the apns-full-conf.xml file, either by modifying it per handset or submitting a push request to Android Open Source with your updated settings.

(I’ve only tried the former with rooted devices)

The XML file itself is fairly self explanatory, taking the MCC and MNC and the APN details for your network:

<apn carrier="CarrierXYZ"
      mcc="123"
      mnc="123"
      apn="carrierxyz"
      type="default,supl,mms,ims,cbs"
      mmsc="http://mms.carrierxyz.com"
      mmsproxy="0.0.0.0"
      mmsport="80"
      bearer_bitmask="4|5|6|7|8|12"
/>

Once you’ve added yours to the file, inserting the USIM, rebooting the handset or restarting the carrier app is all that’s required for it to be re-read and auto provision APN settings from the XML file.

Further reading

APN and CarrierConfig | Android Open Source Project

Carrier Configuration | Android Open Source Project

UICC Carrier Privileges | Android Open Source Project

/etc/apns-full-conf.xml – Master Branch

Kamailio Bytes – Geoip2

GeoIP2 allows simple Geo IP location parsing using mmdb files, to allow us to map IP addresses to geographic locations in standardized format.

Getting the GeoIP Data

MaxMind provide GeoIP2 formatted data ready for use, albeit with limited accuracy.

We need to download them from MaxMind and extract them for use, so let’s download the file:

#> wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz

Next we’ll extract the data:

#> tar -xzvf GeoLite2-City.tar.gz

Next we’ll add the below to our Kamailio config (replace the path to the GeoLite2-City.mmdb to your directory).

loadmodule "geoip2.so"
modparam("geoip2", "path", "/home/ubuntu/GeoLite2-City_20190709/GeoLite2-City.mmdb");

If you’re planning on using this in production you probably want to automate the pulling of this data on a regular basis and keep it in a different directory.

I’ve made a very simple example Kamailio config that shows off some of the features of GeoIP2’s logic and what can be shown, so let’s look at the basics of the module:

if(geoip2_match("$si", "src")){
                xlog("Packet received from IP $si");
                xlog("Country is: $gip2(src=>cc)\n");
}

If we put this at the top of our request_route block every time we recieve a new request we can see the country from which the packet came from.

Let’s take a look at the output of syslog (with my IP removed):

#> tail -f /var/log/syslog
ERROR: <script>: Packet received from IP 203.###.###.###
ERROR: <script>: Country is: AU
ERROR: <script>: City is:  Melbourne
ERROR: <script>: ZIP is:  3004
ERROR: <script>: Regc is:  VIC
ERROR: <script>: Regn is:  Victoria
ERROR: <script>: Metro Code is:  <null>

We can add a bunch more smarts to this and get back a bunch more variables, including city, ZIP code, Lat & Long (Approx), timezone, etc.

        if(geoip2_match("$si", "src")){
                xlog("Packet received from IP $si");
                xlog("Country is: $gip2(src=>cc)\n");
                xlog("City is:  $gip2(src=>city)");
                xlog("ZIP is:  $gip2(src=>zip)");
                xlog("Regc is:  $gip2(src=>regc)");
                xlog("Regn is:  $gip2(src=>regn)");
                xlog("Metro Code is:  $gip2(src=>metro)");

                if($gip2(src=>cc)=="AU"){
                        xlog("Traffic is from Australia");
                }
        }else{
                xlog("No GeoIP Match for  $si");
        }
#> tail -f /var/log/syslog
ERROR: <script>: Packet received from IP ###.###.###.###
ERROR: <script>: Country is: AU
ERROR: <script>: City is:  Melbourne
ERROR: <script>: ZIP is:  3004
ERROR: <script>: Regc is:  VIC
ERROR: <script>: Regn is:  Victoria
ERROR: <script>: Metro Code is:  <null>

Using GeoIP2 you could use different rate limits for domestic users vs overseas users, guess the dialling rules based on the location of the caller and generate alerts if accounts are used outside their standard areas.

We’ll touch upon this again in our next post on RTPengine where we’ll use an RTPengine closes to the area in which the traffic originates.

Full example config on GitHub here.

Forsk Atoll – Setting up Environmental Data

Forsk Atoll is software for wireless network planning, simulation and optimization.

Atoll can do some amazingly powerful things, especially when you start feeding real world data and results back into it, but for today we’ll be touching upon the basics.

As I’m learning it myself I thought I’d write up a basic tutorial on setting up the environment, importing some data, adding some sites and transmitters to your network and then simulating it.

We’ll be using Christmas Island, a small island in the Indian ocean that’s part of Australia, as it’s size makes it easy and the files small.

The Environment (Geographic Data)

The more data we can feed into Atoll the more accurate the predictions that come out of it.

Factors like terrain, obstructions, population density, land usage (residential, agricultural, etc) will all need to be modeled to produce accurate results, so getting your geographic data correct is imperative.

Starting a new Document

We’ll start by creating a new document:

We’ll simulate an LTE network, so we’ll create it using the LTE project template.

Coordinate Reference

Before we can get to that we’re going to have to tell Atoll where we are and what datum we’re working in.

The data sets we’re working were provided by the Government, who use the Australian Geodetic Datum, and Christmas Island is in Zone 48.

We’ll select Document -> Properties

We’ll set the projection first.

Once that’s set we’ll set our display coordinates, this is what we’ll actually work in.

I’m using WGS 84 in the -xx.xxxxxx format, aka Lat & Long in decimal format.

Elevation

Elevation data is hugely important when network planning, your point-to-point links need LOS, and if your modeling / simulation doesn’t know there’s a hill or obstruction between the two sites, it’s not going to work.

There’s plenty of online sources for this data, some of which is paid, but others are provided free by Government agencies.

In this case the Digital Elevation Models for Christmas Island data can be downloaded from Geo-science Australia.

We’ll download the 5m DEM GDA94 UTM zone 48 Christmas Island.

The real reason I picked Christmas Island is that it’s DEM data is 16Mb instead of many Gigabytes and I didn’t want to wait for the download…

After a lot of messing around I found I couldn’t import the multi layered TIF provided by Geo Science Australia, Atoll gave me this error:

Atoll: RasterFile Unsupported data format (Tiled)

I found I could the TIFF formatted DEM files it in a package called VTBuilder, export it as a PNG and then import it into Atoll.

Using VTBuilder to convert DEMs in TIFF to PNG for importing into Atoll

To save some steps I’ve attached a copy of the converted file here.

You can then import the files straight into Atoll,

We’ll need to define what this dataset is, in our cases our Digital Elevation Models (aka Digital Terrain Models) contain Altitude information, so we’ll select Altitude (DTM)

We know from the metadata on the Geo Science Australia site we got the files from the resolution is 5m, so we’ll set pixel size to 5m (Each pixel represents 5 meters).

We’ll need a Geographic Coordinate, this is the Easting and Westing in relation to UTM Zone 48. The values are:

West557999.9999999991
North8849000

All going well you should see the imported topography showing up in Atoll.

I’ve noticed on the version I’m on I had some weirdness when zoomed out, if you try Zooming in to more than 1:10,000 you should see the terrain data. Not sure why this is but I’ve attached a copy of my Atoll config so far so you in case you get stuck with this.

Comms Sites

We’ll download real world sites from the ACMA’s database,

I’ll use the cheat way by just looking it up on their map and exporting the data.

We’ll download the CSV file from the Map.

One thing we’ll need to change in the CSV is that when no Altitude is set for the site ACMA puts “undefined” which Atoll won’t be able to parse. So I’ve just opened it up in N++ and replaced undefined with 0.

I’ve attached a copy here for you to import / skip this step. Mastering messing with CSV is a super useful skill to have anyways, but that’s a topic for another day.

Next we’ll import the sites into Atoll, to define our sites, we’ll jump to the Network Tab and double click on Sites.

Now we’ll import our CSV file

Next we’ll need to define the fields for the import

All going well you’ll now have a populated site list.

Now if we go back to view we should see these points plotted.

Clutter

Forested areas, large bodies of water, urban sprawl, farmland, etc, all have different characteristics and will cause different interference patterns, refraction, shadow fading, etc.

Clutter Data is the classification of land use or land cover which impacts on RF propagation.

There’s several online sources of Clutter data, including the Australian Government Land Use data.

However this dataset doesn’t include Christmas Island. Really shot myself in the foot there, huh?

For examples’ sake we’ll import the terrain data again as clutter.

We’d normally define terrain classes, for example, this area is residential low rise etc, but as we don’t have areas set out we’ll skip that for now.

You can set different layer visibility by enabling and disabling layers in the Geo tab, in this case I’ve disabled my Digital Terrain Model layer and just left the Clutter Heights we just imported.

I got hit with the same Zoom bug here, not sure if it’s still loading in the background or something but the clutter data is only visible when zoomed to 1:10,000 or more, but after doing so you should see the clutter data:

So now we’ve got our environment stuff we can start to add some cell sites and model the propagation & expected signal levels throughout the island in the next post.

RF Planning with Forsk Atoll - Importing environmental data

Forsk Atoll – WMS Map Tiles

A hack I found useful to add Google Maps / Google Satelite View / Bing Maps / Bing Arial / Open Street Maps in Forsk Atoll.

Close Atoll,

Go to C -> Program Files -> Atoll

Edit the file named atoll.ini

Paste the following into it:

[OnlineMaps]
Name1 = OpenStreetMap Standard Map
URL1 = http://a.tile.openstreetmap.org/%z/%x/%y.png
Name2 = MapQuest Open Aerial
URL2 = http://otile1.mqcdn.com/tiles/1.0.0/sat/%z/%x/%y.jpg
Name3 = 2Gis
URL3 = http://static.maps.api.2gis.ru/1.0?c...z&size=256,256
Name4 = 2Gis without logo
URL4 = http://tile2.maps.2gis.com/tiles?x=%x&y=%y&z=%z&v=37 
Name5 = Bing Aerial
URL5 = http://ecn.t3.tiles.virtualearth.net.../a%q.jpg?g=392
Name6 = Bing Hybrid
URL6 = http://ecn.t3.tiles.virtualearth.net.../h%q.jpg?g=392
Name7 = Bing Road
URL7 = http://ecn.t3.tiles.virtualearth.net.../r%q.jpg?g=392
Name8 = Yandex Road
URL8 = http://static-maps.yandex.ru/1.x/?ll...=%z&l=map&key=
Name9 = Yandex Aerial
URL9 = http://static-maps.yandex.ru/1.x/?ll...=%z&l=sat&key=
Name10 = Yandex Hybrid
URL10 = http://static-maps.yandex.ru/1.x/?ll...l=sat,skl&key=
Name11 = ArcGIS
URL11 = http://services.arcgisonline.com/Arc...e/%z/%y/%x.png
Name12 = opencyclemap
URL12 = http://tile.opencyclemap.org/cycle/%z/%x/%y.png
Name13 = Google Terrain
URL13 = http://mt.google.com/vt/lyrs=t&hl=en&x=%x&y=%y&z=%z
Name14 = Google Map
URL14 = http://mt.google.com/vt/lyrs=m&hl=en&x=%x&y=%y&z=%z
Name15 = Google Hybrid (Map + Terrain)
URL15 = http://mt.google.com/vt/lyrs=p&hl=en&x=%x&y=%y&z=%z
Name16 = Google Hybrid (Map + Satellite)
URL16 = http://mt.google.com/vt/lyrs=y&hl=en&x=%x&y=%y&z=%z
Name17 = Google Satellite
URL17 = http://mt.google.com/vt/lyrs=m&hl=en&x=%x&y=%y&z=%z
Name18 = Google Scheme
URL18 = http://mt.google.com/vt/lyrs=h&hl=en&x=%x&y=%y&z=%z
Name19 = Google Scheme2 
URL19 = http://mt.google.com/vt/lyrs=r&hl=en&x=%x&y=%y&z=%z

Save and open Atoll,

Open the Geo Tab,

Right click on Online Maps, click “New”

Select the map source (In this example I’m using OSM) & hit Ok.

Enable the Online Map layer by ticking the layer.

Bam, done.

RF Planning with Forsk Atoll - Laying out environmental data

Magma – Facebook’s Open Source LTE / 4G EPC/OSS Platform

In February Facebook announced they’d open sourced their Magma project,

Magma provides a software-centric distributed mobile packet core and tools for automating network management.

Open-sourcing Magma to extend mobile networks

Magma’s modular software based architecture means you can scale up extra resources as needed, with no need to have physical hardware to run your EPC.

(Cisco’s Ultra Packet Core does have a virtualisation option, but it’s not cheap)

I got pretty excited by this, so I’ve ordered myself an eNodeB (Just a Picocell), a pile of USIMs, programmer and started installing an environment.

In the past I’ve used srsEPC and NextEPC and software-defined radio hardware (BladeRF) to run LTE stuff, so I’m looking forward to seeing if I can implement parts of them into Magma, and also eventually use Kamailio’s IMS modules to implement an IMS core and run VoLTE.

So let’s install Magma, explore it and lurk on the Discord, all while we kill time waiting for hardware to arrive!