---
# System prepended metadata

title: 4G & 5G OAI deplyment at 6Gmobile research lab

---

# 4G & 5G OAI deplyment at 6Gmobile research lab
# 
# Prerequisities
Setup OS
Install Ubuntu 18.04
Install required low-latency kernel

`sudo apt-get install linux-image-lowlatency linux-headers-lowlatency`

Set CPU to C1
Remove all power management features in the BIOS (sleep states, in particular
C-states) and CPU frequency scaling (Intel SpeedStep). In some cases, you can
also do this with cpufreqtool. Also, disable hyperthreading in BIOS and make sure its turned off in Linux

* check this using this command: `watch grep \"cpu MHz\" /proc/cpuinfo`
*  have a look at this [link](https://askubuntu.com/questions/523640/how-i-can-disable-cpu-frequency-scaling-and-set-the-system-to-performance) for further information.
* you must disable p-state and c-state in linux so you need to add `intel_pstate=disable` to the Linux boot options, i.e `GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_pstate=disable"` in `/etc/default/grub`, then perform update-grub. You may optionally add the following as well `"processor.max_cstate=1 intel_idle.max_cstate=0 idle=poll"`
* Append `"blacklist intel_powerclamp"` to the end of `/etc/modprobe.d/blacklist.conf`, to blacklist the intel_powerclamp" module. If the file does not exist, create one, and add the line into it.
* You also need to disable hyperthreading, CPU frequency control, C-States, P-States and any other power management from BIOS as well.
* Install i7z utility to check the cpu

```
sudo apt-get install i7z
sudo i7z
```

Install cpufrequtils:

`sudo apt-get install cpufrequtils`

Then edit the following file (if it doesn't exist, create it):

```
sudo nano /etc/default/cpufrequtils
```

And add the following line to it:

```
GOVERNOR="performance"
```

Save and exit.

Now you need to disable ondemand daemon, otherwise after you reboot the settings will be overwritten.

```
sudo update-rc.d ondemand disable
```

Set governor of all CPUs to performance

` echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor`


# RAN
```
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
cd openairinterface5g
git checkout develop
source oaienv
cd cmake_targets
#./build_oai -h #to get help & just copy & paste it
./build_oai -I -i --eNB -w USRP
```
**Configure RAN**
Modify configuration in
`openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/`
 
* MCC = 230
* MNC = 77
* number of RB to 25/50
* Number of antennas to 2 (FDD mode)
* Set MME IP (192.168.61.149 - magma)
* Set RAN interfaces

**Run eNB**
Go to `ran_build/build` and run via `./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf`

## UHD version issues
If in the UHD repository for the Ubuntu the correctly working uhd version is missing, exploit the following to compile from the source the working uhd version. Most recently there is issue in Ubuntu 18.04 where there is uhd version 4.1 (in this case remove the uhd packagesthat does not work properly as of now.

```
export BUILD_UHD_FROM_SOURCE=True
export UHD_VERSION=3.15.0.0
./build_oai -I -w USRP
```

# Setting up N310
Connect Mgmt port (PC - enp3s0f1 to N310 - Ethernet ) and SPF+ port (PC - enp3s0f0 to N310 - 1/10 Gbit/s SFP+)
Set up DCHP server/ IP address on PC and via serial line configure N310 IP address


View from the back of PC (SFP+ interfaces to be confirmed)
| Interfaces | Interfaces |
| -------- | -------- |
| enp1s0f1(SFP+)     | enp1s0f0 (SFP+)     |
| enp3s0f1    |  enp3s0f0  |

# Updating the UHD
https://kb.ettus.com/Writing_the_USRP_File_System_Disk_Image_to_a_SD_Card

To set both SFP+ ports to 10 GBit/s install XG image
Right now PCs run UHD version, so install the same on the USRP N310s 3.15.0 

Unmount Auto-mounted Partitions

Some operating systems by default will auto-mount the partitions on a block device when it is attached. Before writing a new disk image to the SD card, you should first unmount any mounted partitions. This can be done with the Linux utility umount as shown below:

```
   $ sudo umount /media/user/data
   $ sudo umount /media/user/primary
   $ sudo umount /media/user/secondary
   $ sudo umount /media/user/boot
```

Running the command lsblk again will show these partitions have been unmounted:

Example Output:

```
   $ lsblk
   NAME           MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
   sdb      8:16   1 14.9G  0 disk
   ├─sdb1   8:17   1   16M  0 part
   ├─sdb2   8:18   1  1.9G  0 part
   ├─sdb3   8:19   1  1.9G  0 part
   └─sdb4   8:20   1   11G  0 part
```

Update the filesystem:
Download image
sudo uhd_images_downloader -t n3xx_common_sdig_default -i <UHD_INSTALL_DIR>
sudo dd if= <UHD_INSTALL_DIR>/usrp_n3xx_fs.sdimg of=/dev/mmcblk0 bs=1M

[Connect a Serial connection over USB](https://kb.ettus.com/USRP_N300/N310/N320/N321_Getting_Started_Guide#Setting_up_a_Serial_Console_Connection)
It is possible to gain shell access to the device using a serial terminal emulator via the Serial Console port. Most Linux, OSX, or other Unix based operating systems have a tool called screen which can be used for this purpose.

If you do not have screen installed, it can be installed via your package manager. For Ubuntu/Debian based operating systems it can be installed with apt such as:

   sudo apt install screen

The default Baud Rate for the Serial Console is: 115200

The exact device node you should attach to depends on your operating system's driver and other USB devices that might already be connected. Modern Linux systems offer alternatives to simply trying device nodes; instead, the OS might have a directory of symlinks under /dev/serial/by-id:

   $ ls /dev/serial/by-id
   usb-Digilent_Digilent_USB_Device_25163511FE00-if00-port0
   usb-Digilent_Digilent_USB_Device_25163511FE00-if01-port0
   usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if00-port0
   usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if01-port0

NOTE: Exact names depend on the host operating system version and may differ.

Every N3XX series device connected to USB will by default show up as four different devices. The devices labeled "USB_to_UART_Bridge_Controller" are the devices that offer a serial prompt. The first (with the if00 suffix) connects to the ARM CPU, whereas the second connects to the STM32 Microcontroller.

If you have multiple N3xx Serial Consoles connected to a single host, you may have to empirically test nodes.

Connecting to the ARM CPU can be performed with the command:

   $ sudo screen /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if00-port0 115200

Upon starting the USRP N3xx, boot messages will appear and rapidly update. Once the boot process successfully completes, a login prompt like the following should appear:

   OpenEmbedded test ni-n3xx-313ABDA ttyPS0
   
   ni-n3xx-313ABDA login: 

Enter the username: ​root​

By default, the root user's password is left blank. Press the Enter key when prompted for a password.

You should now be presented with a shell prompt similar to the following:

   root@ni-n3xx-<motherboard serial #>:~#

Using the default configuration, the serial console will show all kernel log messages (which are not available when using SSH), and give access to the boot loader (U-boot prompt). This can be used to debug kernel or boot-loader issues more efficiently than when logged in via SSH.
Connecting to the microcontroller

Using the Serial Console interface, it is possible to connect to the STM32 microcontroller with the command below. The STM32 controls the power sequencing and several other low level device operations.

   $ sudo screen /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if01-port0 115200

The STM32 interface provides a very simple prompt. The command help will list all available commands. A direct connection to the microcontroller can be used to hard-reset the device without physically accessing it (i.e., emulating a power button press) and other low-level diagnostics. 

## HOW to connect to serial interface FROM (https://kb.ettus.com/USRP_N300/N310/N320/N321_Getting_Started_Guide)
Setting up a Serial Console Connection

It is possible to gain shell access to the device using a serial terminal emulator via the Serial Console port. Most Linux, OSX, or other Unix based operating systems have a tool called screen which can be used for this purpose.

If you do not have screen installed, it can be installed via your package manager. For Ubuntu/Debian based operating systems it can be installed with apt such as:

    sudo apt install screen

The default Baud Rate for the Serial Console is: 115200

The exact device node you should attach to depends on your operating system's driver and other USB devices that might already be connected. Modern Linux systems offer alternatives to simply trying device nodes; instead, the OS might have a directory of symlinks under /dev/serial/by-id:

    $ ls /dev/serial/by-id
        usb-Digilent_Digilent_USB_Device_25163511FE00-if00-port0
        usb-Digilent_Digilent_USB_Device_25163511FE00-if01-port0
        usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if00-port0
        usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if01-port0

NOTE: Exact names depend on the host operating system version and may differ.

Every N3XX series device connected to USB will by default show up as four different devices. The devices labeled "USB_to_UART_Bridge_Controller" are the devices that offer a serial prompt. The first (with the if00 suffix) connects to the ARM CPU, whereas the second connects to the STM32 Microcontroller.

If you have multiple N3xx Serial Consoles connected to a single host, you may have to empirically test nodes.

Connecting to the ARM CPU can be performed with the command:

    $ sudo screen /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if00-port0 115200

Upon starting the USRP N3xx, boot messages will appear and rapidly update. Once the boot process successfully completes, a login prompt like the following should appear:

    OpenEmbedded test ni-n3xx-313ABDA ttyPS0
   
    ni-n3xx-313ABDA login: 

Enter the username: ​root​

By default, the root user's password is left blank. Press the Enter key when prompted for a password.

You should now be presented with a shell prompt similar to the following:

    root@ni-n3xx-<motherboard serial #>:~#

Using the default configuration, the serial console will show all kernel log messages (which are not available when using SSH), and give access to the boot loader (U-boot prompt). This can be used to debug kernel or boot-loader issues more efficiently than when logged in via SSH. 
### PC & N310 configuration assuming connection from previous section
Configuring USRP N310 over serial line can be done via vi but it creates undo files that mess up the configuration, so do the following:
1. Connect over serial line
2. set manually Mgmt port via ifconfig
3. set manually sfp0 or sfp1 port via ifconfig
4. update firmware from connected PC
5. test ssh connection to mgmt IP of N310
    6. ssh root@<N310_MGMT_IP>
7. Create eth0.network,sfp0.network and sfp1.network files at PC and configure them appropriatelly
8. Upload them to N310
    9. scp root@<N310_MGMT_IP>:/etc/systemd/network/
10. Reboot N310 and check configuration

### netconf

`eth0.network`
```
[Match]
Name=eth0
KernelCommandLine=!nfsroot

[Network]
Address=192.168.32.17/24
```

```
sfp0.network
```

```
[Match]
Name=sfp0

[Network]
Address=192.168.30.17/24

[Link]
MTUBytes=9000
```


```
sfp1.network
```

```
[Match]
Name=sfp1

[Network]
Address=192.168.31.17/24

[Link]
MTUBytes=9000
```


**On PC**:
Disable network manager (it may work with it enabled, but often it interferes by overriding the netconf):
```
sudo systemctl stop NetworkManager.service
sudo systemctl disable NetworkManager.service
```

##### Configuration for Ubuntu 18:
Configure Mgmt inteface (both ifconfig and ip examples):
```
sudo ip addr add 192.168.32.2/24 dev enp3s0f1 # Ubuntu 18
```
Configure SFP+0 inteface:
```
sudo ip addr add 192.168.30.2/24 dev enp1s0f1
sudo ip link set enp1s0f1 mtu 9000
sudo ip link set enp1s0f1 up
```  
Configure SFP+1 inteface:
```
sudo ip addr add 192.168.30.2/24 dev enp1s0f0
sudo ip link set enp1s0f0 mtu 9000
sudo ip link set enp1s0f0 up
```
##### Configuration for Ubuntu 20:
Configure Mgmt inteface (both ifconfig and ip examples):
```
sudo ip addr add 192.168.32.2/24 dev ens4f1
```
Configure SFP+0 inteface:
```
sudo ip addr add 192.168.30.2/24 dev ens8191f1
sudo ip link set ens8191f1 mtu 9000
sudo ip link set ens8191f1 up
```  
Configure SFP+1 inteface:
```
sudo ip addr add 192.168.30.2/24 dev ens8191f0
sudo ip link set ens8191f0 mtu 9000
sudo ip link set ens8191f0 up
```

##### Old (ifconfig)
```
sudo ifconfig enp3s0f1 192.168.11.1 netmask 255.255.255.0 up # ifconfig is available
```

On N310 via serial line connection:
Configure Mgmt inteface:
```
ifconfig eth0 192.168.11.2 netmask 255.255.255.0 up
```
Configure SFP+ inteface:
```
ifconfig sfp0 192.168.10.2 netmask 255.255.255.0 up
``` 
#### enb config
Add following to RUs configuration block:

`sdr_addrs      =     "addr=192.168.10.2,second_addr=192.168.12.2,mgmt_addr=192.168.25.29"`


# EPC

Docker deployment

# 1. Pre-requisities
## 1.1 Install the proper version of Docker #

At time of writing (2021 / 02 / 01):

```bash
$ dpkg --list | grep docker
ii  docker-ce                              5:20.10.2~3-0~ubuntu-bionic                     amd64        Docker: the open-source application container engine
ii  docker-ce-cli                          5:20.10.2~3-0~ubuntu-bionic                     amd64        Docker CLI: the open-source application container engine
ii  docker-ce-rootless-extras              5:20.10.2~3-0~ubuntu-bionic                     amd64        Rootless support for Docker.
```

**CAUTION: do not forget to add your username to the `docker` group**

Otherwise you will have to run in `sudo` mode.

```bash
$ sudo usermod -a -G docker myusername
```

**CAUTION: At time of writing (2021 / 02 / 01), we only support Ubuntu18.04 deployment.**

Please refer to the official [docker engine installation guide page](https://docs.docker.com/engine/install/).

You will get more details than here.

### 1.1.1. Install a recent version of `docker-compose` ##

Official [installation guide](https://docs.docker.com/compose/install/).

We recommend a version newer than `1.27`.

## 1.2. Create an account on Docker Hub #

Go to [https://hub.docker.com/](https://hub.docker.com/) website and create an account.

## 1.3. Pull base images #

* Ubuntu  version: We need 3 base images: `ubuntu:bionic`, `cassandra:2.1` and `redis:6.0.5`

First log with your Docker Hub credentials.

```bash
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: 
Password: 
```

Then pull base images.

On a Ubuntu18.04 host:

```bash
$ docker pull ubuntu:bionic
$ docker pull cassandra:2.1
$ docker pull redis:6.0.5
```

Finally you may logoff --> your token is stored in plain text..

```bash
$ docker logout
```

## 1.4. Network Configuration #

**CAUTION: THIS FIRST STEP IS MANDATORY**

Based on this [recommendation](https://docs.docker.com/network/bridge/#enable-forwarding-from-docker-containers-to-the-outside-world):

```bash
$ sudo sysctl net.ipv4.conf.all.forwarding=1
$ sudo iptables -P FORWARD ACCEPT
```

**CAUTION: THIS SECOND STEP MAY NOT BE NEEDED IN YOUR ENVIRONMENT.**

* The default docker network (ie "bridge") is on "172.17.0.0/16" range.
* In our Eurecom private network, this IP address range is already in use.
  - We have to change it to another IP range is free in our private network configuration.
  - We picked a **new/IDLE** IP range by adding a `/etc/docker/daemon.json` file:

```json
{
	"bip": "192.168.17.1/24"
}
```

Restart the docker daemon:

```bash
$ sudo service docker restart
$ docker info
```

Check the new network configuration:

```bash
$ docker network inspect bridge
[
    {
        "Name": "bridge",
....
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "192.168.17.1/24",
                    "Gateway": "192.168.17.1"
                }
            ]
        },
....
```

# 2A. Custom build images


## 2A.1. Build HSS Image on a Ubuntu 18.04 Host

On our CI server (a 48-CPU server), this operation takes around 13 minutes. Please be patient.

```
$ docker build --target oai-hss --tag oai-hss:production \
               --file component/oai-hss/docker/Dockerfile.ubuntu18.04 \
               component/oai-hss
$ docker image prune --force
$ docker image ls
oai-hss                 production             f478bafd7a06        1 minute ago          341MB
...
```

## 2A.2. Build SPGW-C Image On a Ubuntu 18.04 Host


On our CI server (a 48-CPU server), this operation takes around 10 minutes. Please be patient.

```
$ docker build --target oai-spgwc --tag oai-spgwc:production \
               --file component/oai-spgwc/docker/Dockerfile.ubuntu18.04 \
               component/oai-spgwc
$ docker image prune --force
$ docker image ls
oai-spgwc               production             b1ba7dd16bc5        1 minute ago          218MB
...
```

## 2A.3. Build SPGW-U Image on a Ubuntu 18.04 Host

On our CI server (a 48-CPU server), this operation takes around 9 minutes. Please be patient.

```
$ docker build --target oai-spgwu-tiny --tag oai-spgwu-tiny:production \
               --file component/oai-spgwu-tiny/docker/Dockerfile.ubuntu18.04 \
               component/oai-spgwu-tiny
$ docker image prune --force
$ docker image ls
oai-spgwu-tiny          production             588e14481f2b        1 minute ago          220MB
...
```

## 2A.4. Retrieve the MAGMA source code - Get the NSA-Support source code

Important Update (2021 / 03 / 20), the NSA Support was merged into master.

```
$ cd ~
$ git clone https://github.com/magma/magma.git
$ cd magma
$ git log | grep -i NSA
```

You should see Mohit's Pull request being merged ([Converged MME]NSA-Addition (#4513)).
6.2. Prepare the source code for a MAGMA-MME Docker Image build

The .dockerignore file is meant for the image building on the Orchestrator.

It is NOT suitable for the MAGMA-MME image building. If you don't remove/rename, build won't complete.

```
$ rm .dockerignore
```

During the UE attachment, we have seen that when UE receives the EMM-Information NAS packet, the UE disconnects.

So at the time of writing (2021 / 02 / 01), we are disabling the sending of EMM-INFO packet.

```
$ git diff lte/gateway/c/core/oai/tasks/nas/emm/Attach.c
diff --git a/lte/gateway/c/core/oai/tasks/nas/emm/Attach.c b/lte/gateway/c/core/oai/tasks/nas/emm/Attach.c
index 34f353a88..b354b18b7 100644
--- a/lte/gateway/c/core/oai/tasks/nas/emm/Attach.c
+++ b/lte/gateway/c/core/oai/tasks/nas/emm/Attach.c
@@ -840,7 +840,7 @@ int emm_proc_attach_complete(
           LOG_NAS_EMM,
           " Sending EMM INFORMATION for ue_id = " MME_UE_S1AP_ID_FMT "\n",
           ue_id);
-      emm_proc_emm_informtion(ue_mm_context);
+      //emm_proc_emm_informtion(ue_mm_context);
       increment_counter("ue_attach", 1, 1, "result", "attach_proc_successful");
       attach_success_event(ue_mm_context->emm_context._imsi64);
     }
```

This issue is in our TODO list and we are still investigating.

Another known issue is if the UE send a TAU request to the MME. Currently the MAGMA MME with an OAI eNB does not handle it well. We are also working on providing a fix for this issue.

## 2A.5. Build the MAGMA-MME Ubuntu18 Docker image

On our CI server (a 48-CPU server), this operation takes around 30-35 minutes. Please be patient.

The reason: a lot of needed packages/libraries are installed from source for a very specific version.

Once again, if you need a proxy, add your proxy URL. If not, remove the option.

```
$ docker build --target magma-mme --tag magma-mme:master \
               --file lte/gateway/docker/mme/Dockerfile.ubuntu18.04 .
$ docker image ls
magma-mme               nsa-support            b6fb01eb0d07        1 minute ago          492MB
...
```

If you are planning to re-build MAGMA-MME Docker image, here is is a trick:

Normally after the 35 minutes, you should get the MME image but also a dangling image that should be quite large (5+ GBytes).

```
$ docker image ls
magma-mme               nsa-support            b6fb01eb0d07        1 minute ago          492MB
<none>                  <none>                 91259fd827ee        5 minutes ago         5.24GB
...
```

Re-tag the dangling image (replace tag by the actual tag you got in previous step):

```
$ docker image tag 91259fd827ee magma-dev-mme:ci-base-image
```

And use the CI docker file.

`$ docker build --target magma-mme --tag magma-mme:next-image-tag --file ci-scripts/docker/Dockerfile.mme.ci.ubuntu18 .`

This will only take 5 minutes to re-build a MAGMA-MME image.

Normally you are ready to deploy and test.

#### Inbetween OLD MME
```
docker build --target oai-hss --tag oai-hss:production-old \
               --file component/oai-hss/docker/Dockerfile.ubuntu18.04 \
               component/oai-hss
docker image prune --force
docker image ls


docker build --target oai-mme --tag oai-mme:production-old \
            --file component/oai-mme/docker/Dockerfile.ubuntu18.04 \
               component/oai-mme
docker image prune --force
docker image ls

docker build --target oai-spgwc --tag oai-spgwc:production-old \
               --file component/oai-spgwc/docker/Dockerfile.ubuntu18.04 \
               component/oai-spgwc
docker image prune --force
docker image ls

docker build --target oai-spgwu-tiny --tag oai-spgwu-tiny:production-old \
               --file component/oai-spgwu-tiny/docker/Dockerfile.ubuntu18.04 \
               component/oai-spgwu-tiny
```
               

# 2b. Build images (now we go with develop)
## 2.1.  Retrieve the proper code version on the OAI-CN part #

At the time of writing (2021 / 02 / 08), if you want to use the OpenAir-CN for a Dual Connectivity use case, you need to use proper branches:

**cNF Name** | **Branch Name** | **Tags**   | **Commit at time of writing**              | Ubuntu18 |
------------ | --------------- | ---------- | ------------------------------------------ | -------- |
HSS          | `develop`       | `2021.w10` | `93dfcbca245ec97652c4d62ba3913a899d956d68` | X        |
SPGW-C       | `develop`       | `2021.w10` | `b10256535e47ffb86c86a8581d9c50b1f380dcf5` | X        |
SPGW-U-TINY  | `develop`       | `2021.w10` | `acd293e616f879f4dacead152c59384d1e533167` | X        |

```bash
$ git clone https://github.com/OPENAIRINTERFACE/openair-epc-fed.git
$ cd openair-epc-fed

# You can specify a tag on the parent GIT repository such as `2021.w22`
$ git checkout 2021.w22
# Or you can sync to the latest version
$ git checkout master

# Then you need to resync the sub-modules (ie HSS, SPGW-CUPS).
# You can specify:
#   ---  a valid tag (such as seen)
#   ---  a newer tag
#   ---  a branch to get the latest (`develop` being the latest stable)
#        Usually the better option is to specify `develop`

$ ./scripts/syncComponents.sh --hss-branch 2021.w10 --spgwc-branch 2021.w10 --spgwu-tiny-branch 2021.w10
---------------------------------------------------------
OAI-HSS    component branch : 2021.w10
OAI-SPGW-C component branch : 2021.w10
OAI-SPGW-U component branch : 2021.w10
---------------------------------------------------------
....

# Or to not specify anything
$ ./scripts/syncComponentsLegacy.sh
---------------------------------------------------------
OAI-HSS    component branch : develop
OAI-SPGW-C component branch : develop
OAI-SPGW-U component branch : develop
---------------------------------------------------------
....
```

In general, the `docker-compose` files (even in the tutorials) are up-to-date w/ `develop` latest commits in each sub-module.

## 2.2. Generic Parameters #

Here in our network configuration, we need to pass the "GIT PROXY" configuration.

*   If you do not need, remove the `--build-arg EURECOM_PROXY=".."` option.
*   If you do need it, change with your proxy value.

## 2.3. Build HSS Image #

### 2.3.1 On a Ubuntu 18.04 Host ##

On our CI server (a 48-CPU server), this operation takes around **13 minutes**. Please be patient.

```bash
$ docker build --target oai-hss --tag oai-hss:production \
               --file component/oai-hss/docker/Dockerfile.ubuntu18.04 \
                component/oai-hss
$ docker image prune --force
$ docker image ls
oai-hss                 production             f478bafd7a06        1 minute ago          341MB
...
```
If proxy is needed include in the build following:
```
--build-arg EURECOM_PROXY="http://proxy.eurecom.fr:8080"
```
## 2.4. Build SPGW-C Image #

### 2.4.1 On a Ubuntu 18.04 Host ##

On our CI server (a 48-CPU server), this operation takes around **10 minutes**. Please be patient.

```bash
$ docker build --target oai-spgwc --tag oai-spgwc:production \
               --file component/oai-spgwc/docker/Dockerfile.ubuntu18.04 \
               component/oai-spgwc
$ docker image prune --force
$ docker image ls
oai-spgwc               production             b1ba7dd16bc5        1 minute ago          218MB
...
```
If proxy is needed include in the build following:
```
--build-arg EURECOM_PROXY="http://proxy.eurecom.fr:8080"
```

## 2.5. Build SPGW-U Image #

### 2.5.1 On a Ubuntu 18.04 Host ##

On our CI server (a 48-CPU server), this operation takes around **9 minutes**. Please be patient.

```bash
$ docker build --target oai-spgwu-tiny --tag oai-spgwu-tiny:production \
               --file component/oai-spgwu-tiny/docker/Dockerfile.ubuntu18.04 \
               component/oai-spgwu-tiny
$ docker image prune --force
$ docker image ls
oai-spgwu-tiny          production             588e14481f2b        1 minute ago          220MB
...
```

If proxy is needed include in the build following:
```
--build-arg EURECOM_PROXY="http://proxy.eurecom.fr:8080"
```

## 2.6. Retrieve the MAGMA source code #

### 2.6.1. Get the NSA-Support source code ##

**Important Update (2021 / 03 / 20), the NSA Support was merged into `master`.**

```bash
$ cd ~
$ git clone https://github.com/magma/magma.git
$ cd magma
$ git log | grep -i NSA
```

You should see Mohit's Pull request being merged (`[Converged MME]NSA-Addition (#4513)`).

### 2.6.2. Prepare the source code for a MAGMA-MME Docker Image build ##

The `.dockerignore` file is meant for the image building on the Orchestrator.

**It is NOT suitable for the MAGMA-MME image building. If you don't remove/rename, build won't complete.**

```bash
$ rm .dockerignore
```

During the UE attachment, we have seen that when UE receives the `EMM-Information` NAS packet, the UE disconnects.

**So at the time of writing (2021 / 02 / 01), we are disabling the sending of EMM-INFO packet.**

```bash
$ git diff lte/gateway/c/core/oai/tasks/nas/emm/Attach.c
diff --git a/lte/gateway/c/core/oai/tasks/nas/emm/Attach.c b/lte/gateway/c/core/oai/tasks/nas/emm/Attach.c
index 34f353a88..b354b18b7 100644
--- a/lte/gateway/c/core/oai/tasks/nas/emm/Attach.c
+++ b/lte/gateway/c/core/oai/tasks/nas/emm/Attach.c
@@ -840,7 +840,7 @@ int emm_proc_attach_complete(
           LOG_NAS_EMM,
           " Sending EMM INFORMATION for ue_id = " MME_UE_S1AP_ID_FMT "\n",
           ue_id);
-      emm_proc_emm_informtion(ue_mm_context);
+      //emm_proc_emm_informtion(ue_mm_context);
       increment_counter("ue_attach", 1, 1, "result", "attach_proc_successful");
       attach_success_event(ue_mm_context->emm_context._imsi64);
     }
```

This issue is in our **TODO** list and we are still investigating.

### 2.6.3. Build the MAGMA-MME Ubuntu18 Docker image ##

On our CI server (a 48-CPU server), this operation takes around **30-35 minutes**. Please be patient.

The reason: a lot of needed packages/libraries are installed from source for a very specific version.

Once again, if you need a proxy, add your proxy URL. If not, remove the option.

```bash
$ docker build --target magma-mme --tag magma-mme:master \
               --file lte/gateway/docker/mme/Dockerfile.ubuntu18.04 \
               --build-arg GIT_PROXY="http://proxy.eurecom.fr:8080" .
$ docker image ls
magma-mme               nsa-support            b6fb01eb0d07        1 minute ago          492MB
...
```

If you are planning to re-build MAGMA-MME Docker image, here is is a trick:

Normally after the 35 minutes, you should get the MME image but also a dangling image that should
be quite large (5+ GBytes).

```bash
$ docker image ls
magma-mme               nsa-support            b6fb01eb0d07        1 minute ago          492MB
<none>                  <none>                 91259fd827ee        5 minutes ago         5.24GB
...
```

Re-tag the dangling image:

```bash
$ docker image tag 91259fd827ee magma-dev-mme:ci-base-image
```

And use the CI docker file.

```bash
$ docker build --target magma-mme --tag magma-mme:next-image-tag --file ci-scripts/docker/Dockerfile.mme.ci.ubuntu18 .
```

This will only take **5 minutes** to re-build a MAGMA-MME image.

Normally you are ready to deploy and test.

# 3. Deploy images
## 3.1. Initialize the Cassandra DB #

Starting and initializing a data-base takes a bit of time.

In `docker-compose 3.x`, there are no more support for conditional healthy dependency when deploying.

This step is now **manual**.

```bash
$ cd docker-compose/magma-mme-demo
$ docker-compose up -d db_init
Creating network "demo-oai-private-net" with the default driver
Creating network "demo-oai-public-net" with the default driver
Creating demo-cassandra ... done
Creating demo-db-init   ... done

$ docker logs demo-db-init --follow
Connection error: ('Unable to connect to any servers', {'192.168.68.130': error(111, "Tried connecting to [('192.168.68.130', 9042)]. Last error: Connection refused")})
Connection error: ('Unable to connect to any servers', {'192.168.68.130': error(111, "Tried connecting to [('192.168.68.130', 9042)]. Last error: Connection refused")})
Connection error: ('Unable to connect to any servers', {'192.168.68.130': error(111, "Tried connecting to [('192.168.68.130', 9042)]. Last error: Connection refused")})
Connection error: ('Unable to connect to any servers', {'192.168.68.130': error(111, "Tried connecting to [('192.168.68.130', 9042)]. Last error: Connection refused")})
OK

$ docker rm -f demo-db-init
demo-db-init
```

Note: we are removing the `demo-db-init` container because it is not needed anymore.

You can keep the container but it is dead.

To go to the next step, you **SHALL** have the "OK" message in the `demo-db-init` container logs.

## 3.2. Deploy the rest of EPC #

```bash
$ docker-compose up -d oai_spgwu
demo-cassandra is up-to-date
Creating demo-redis   ... done
Creating demo-oai-hss ... done
Creating demo-magma-mme ... done
Creating demo-oai-spgwc ... done
Creating demo-oai-spgwu-tiny ... done

# wait a bit

$ docker ps -a
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS                    PORTS                                         NAMES
cf93fa4c5fdf        oai-spgwu-tiny:production   "/openair-spgwu-tiny…"   46 seconds ago      Up 44 seconds (healthy)   2152/udp, 8805/udp                            demo-oai-spgwu-tiny
f59ceac1dba5        oai-spgwc:production        "/openair-spgwc/bin/…"   49 seconds ago      Up 46 seconds (healthy)   2123/udp, 8805/udp                            demo-oai-spgwc
80d71373ef4d        magma-mme:nsa-support       "/bin/bash -c 'cd /m…"   51 seconds ago      Up 49 seconds             3870/tcp, 2123/udp, 5870/tcp                  demo-magma-mme
7b2f67eeeac0        oai-hss:production          "/openair-hss/bin/en…"   56 seconds ago      Up 51 seconds (healthy)   5868/tcp, 9042/tcp, 9080-9081/tcp             demo-oai-hss
b94d74330f92        redis:6.0.5                 "/bin/bash -c 'redis…"   56 seconds ago      Up 52 seconds             6379/tcp                                      demo-redis
e51afc6e107c        cassandra:2.1               "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes (healthy)    7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp   demo-cassandra

```

You are ready to connect the RAN and UE.

## 3.3. Undeploy the EPC #

```
$ docker-compose down
Stopping demo-oai-spgwu-tiny ... done
Stopping demo-oai-spgwc      ... done
Stopping demo-magma-mme      ... done
Stopping demo-oai-hss        ... done
Stopping demo-redis          ... done
Stopping demo-cassandra      ... done
Removing demo-oai-spgwu-tiny ... done
Removing demo-oai-spgwc      ... done
Removing demo-magma-mme      ... done
Removing demo-oai-hss        ... done
Removing demo-redis          ... done
Removing demo-cassandra      ... done
Removing network demo-oai-private-net
Removing network demo-oai-public-net
```

## 3.4. How to edit the docker-compose file

Obviously you want an EPC that runs for your environment. It means:

*  Dedicated UE simcard configuration
*  A different PLMN
*  Your network configuration is certainly different

**Try to modify as little as possible the number of environment variables values in the docker-compose file.**

The variables I describe in the next few sections should be the ones you shall focus on!

* They are formatted in this markdown page as **<code>ENV_VARIABLE</code>**

If you don't understand a value, it is better to **NOT** touch it!

### 3.4.1. UE simcard and other UE configurations ##

The final purpose of deploying an EPC is to connect a 4G UE (smartphone or dongle) to internet through an eNB.

When "burning" a simcard, you need to decide the following parameters:

* **IMSI** : International Mobile Subscriber Identity
  * Formatting is explained [here](https://en.wikipedia.org/wiki/International_mobile_subscriber_identity)
* **LTE_KEY** and **OPC_KEY**
* There are more but I won't go into details.

Once you've done this, put the simcard in your smartphone and power up it. You will need to add an new **APN** (Access Point Name).

Here you can be creative. It's a string. Our only requirement --> It **SHALL** have at least one "." (dot). In our example "oai.ipv4".

Now you need to provision the user(s) into the Cassandra Database, hence some of the **HSS** parameters:

* **<code>LTE_K</code>** SHALL match **LTE_KEY** you used in burning the simcard
* **<code>OP_KEY</code>** **is not** the **OPC_KEY** but it can be calculated from it and **LTE_KEY**.
  * A example of a generator can be found at [Ki/OPc Generator](https://github.com/PodgroupConnectivity/kiopcgenerator)
* **<code>APN1</code>** SHALL match the one you created on your smartphone.
* **<code>FIRST_IMSI</code>** should match the one you chose

The **SPGW-C**, since the introduction of FDQN support, has 2 variables:

* **<code>APN_NI_1</code>**
* **<code>DEFAULT_APN_NI_1</code>**

that shall match also the APN you created.

### 3.4.2. Your Public Land Mobile Network ##

AKA PLMN.

I strongly recommend to only modify the **MCC**-type and **MNC**-type parameters.

You could touch the **TAC**-type ones but it's quite more difficult for a simple tutorial.

In our example, we used **230** and **77** with TACs **1**, **2**, **3** (**1** being primary TAC).

**CAUTION** : for **MCC**, **MNC** values, I am using a `'` -- 2 or 3 digits -- `'` notation:

- I do this especially if your **MNC** is something like **'02'**, 2 digits with 1st being '0'
- This 1st `zero` digit **SHALL** present in all of the cNF configuration files!

Note that the **MNC3**-type parameters are encoded over 3 characters. This is mandatory.
You have to fill with `zeroes` if needed.

For the **MME**, at the time of writing, the configuration file is hard-coded in the same folder as the docker-compose file (`mme.conf`):

```bash
    # ------- MME served GUMMEIs
    GUMMEI_LIST = (
         { MCC="230" ; MNC="77"; MME_GID="32768" ; MME_CODE="3"; }
    );

    # ------- MME served TAIs
    TAI_LIST = (
         {MCC="230" ; MNC="77";  TAC = "1"; },
         {MCC="230" ; MNC="77";  TAC = "2"; },
         {MCC="230" ; MNC="77";  TAC = "3"; }
    );

    TAC_LIST = (
         {MCC="230" ; MNC="77";  TAC = "1"; }
    );

    CSFB :
    {
        NON_EPS_SERVICE_CONTROL = "OFF";
        CSFB_MCC = "230";
        CSFB_MNC = "77";
        LAC = "1";
    };
```

For the **SPGWC-C** and **SPGW-U-TINY** section of the docker-compose file:

* **<code>MCC</code>**
* **<code>MNC</code>**
* **<code>MNC03</code>**
* **<code>TAC</code>**

**Last important point:** Your MME PLMN **SHALL** match the one in your eNB configuration!

For example, if you are using OAI eNB configuration file:

```bash
    tracking_area_code  =  1;
    plmn_list = (
      { mcc = 230; mnc = 77; mnc_length = 2; }
    );
```

### 3.4.3. Your network configuration ##

#### 3.DNS Settings ###

Your EPC Docker host has its own gateway --> you need to provide it as "Local DNS server".

**Otherwise** you won't have Internet access on your UE when it is connected to the Core Network!

On your EPC docker host, type:

```bash
$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.18.129  0.0.0.0         UG    300    0        0 nm-bond
....
```

In the **SPGW-C** section of the docker-compose file.

Use the 2nd field value as **<code>DEFAULT_DNS_IPV4_ADDRESS</code>** field.

In our example, as **<code>DEFAULT_DNS_SEC_IPV4_ADDRESS</code>** we are using Google's 2nd one. You can pick anything else.

You can also ask your IT team!

You can tweak with the following 2 variables (but they are already at best values):

* **<code>PUSH_PROTOCOL_OPTION</code>**
* **<code>NETWORK_UE_NAT_OPTION</code>**

### the UE IP address allocation pool ###

Last point: the UE IP address allocation pool is used to assign an IP address to the UE when it gets connected.

In our example, I chose "12.1.1.2 - 12.1.1.254" range.

Note that it is also defined in **CICDR** format for SPGW-U "12.1.1.0/24"

If you have to change, please respect both formats.

**SPGW-C** section of docker-compose file:

* **<code>UE_IP_ADDRESS_POOL_1</code>**

**SPGW-U-TINY** section of docker-compose file:

* **<code>NETWORK_UE_IP</code>**

### 3.4.4. Miscellaneous ##

At the time of writing (2021 / 02 / 01), the automation on the MAGMA-MME image is not completed.

There are no entry-point scripts, no default MME configuration file.

Hence there are 2 files in this folder:

- `mme-cfg.sh` that behaves as `entrypoint`
- `mme.conf` already completed MME configuration file

Both files do have pre-filled parameters such realm, IP addresses...

Be careful when modifying them.

Note that in the `mme.conf`, the **S6A** section has changed: the MME supports now the connection with an HSS entity in a different realm.

```bash
    S6A :
    {
        S6A_CONF                   = "/magma-mme/etc/mme_fd.conf"; # YOUR MME freeDiameter config file path
        HSS_HOSTNAME               = "hss.openairinterface.org";
        HSS_REALM                  = "openairinterface.org";
    };
```

#### Time-Zone Settings ###

You can specify the timezone at deployment time in each container.

Just modify **<code>TZ</code>** in each container section!

Note that by default at build I've set up `Europe/Paris`.

Proper values can be found in your Linux system at `/usr/share/zoneinfo/`.

## 3.5. Connecting an eNB #

The network configuration on eNB server(s) still is valid.

See [here](../../docs/CONFIGURE_NETWORKS_MAGMA.md#step-2-create-a-route-on-your-enbgnb-servers) for the commands to do

And see [here](../../docs/CONFIGURE_NETWORKS_MAGMA.md#verify-your-network-configuration) for commands to verify.

## 3.6. Connecting a Smartphone in 5G using NSA support from OAI RAN #

This part explains the RAN-related section to the demo made during MAGMA-dev conference in February 3rd, 2021.
See [here](../../docs/NSA_SUPPORT_OAI_RAN.md)

# 4. Connecting eNB to EPC
## 4.1. Networking #

Accessing a Docker container from the server you've deployed it on is easy.

Accessing a Docker container from another server is NOT.

Here is a picture of what we will be doing:

![Block Diagram](./images/OAICN-Network-Deployment-Explanation.png)

**The objective is to be able to ping the MME and SPGW-U containers from the eNB server(s)**.


### Step 1 : create a docker network on your EPC docker host. ##

By just deploying the Cassandra container(s), you will create 2 docker networks:

```bash
$ cd docker-compose/magma-mme-demo
$ docker-compose up -d db_init
Creating network "demo-oai-private-net" with the default driver
Creating network "demo-oai-public-net" with the default driver
Creating demo-cassandra ... done
Creating demo-db-init   ... done
$ docker network ls
NETWORK ID          NAME                       DRIVER              SCOPE
db9d51755702        bridge                     bridge              local
c3605ce9dbf6        host                       host                local
3dffd2ec9ad2        none                       null                local
a2774c5b14ee        demo-oai-private-net       bridge              local
4a2fc2f18d63        demo-oai-public-net        bridge              local
$ docker network inspect demo-oai-public-net
[
    {
        "Name": "demo-oai-public-net",
...
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "192.168.61.128/26"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
...
    }
]
```

As you can see, the public network (`demo-oai-public-net`) is using the range `192.168.61.128/26`.

If this IP range **DOES NOT** suit your network environment, you have a lot of editing.

### Step 2: create a route on your eNB/gNB server(s) ##

In the servers that are hosting the eNB(s) and/or gNB(s), create IP route(s):

The following are examples. **PLEASE ADAPT TO YOUR ENVIRONMENT.**

```bash
# On eNB & similarily on gNB
sudo ip route add 192.168.61.128/26 via 192.168.25.22 dev eno1
```

- Where `192.168.25.22` is the IP address of the **Docker Host**
- Where `eno1` is the **Network Interface Controller(NIC)** of the eNB server (minimassive in our case).


## 4.2. After deploying your cNF containers #

Normally you did:

```bash
$ docker-compose up -d oai_spgwu
```

### Verify your network configuration ##

Let make sure your routing on the eNB server is correct.

**On your EPC Docker Host:** recover the MME IP address:

```bash
$ docker inspect --format="{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" demo-magma-mme
192.168.61.149
```

You can also find in the `docker-compose.yml` file.

**On your eNB server:**

```bash
$ ping -c 5 192.168.61.149
PING 192.168.61.149 (192.168.61.149) 56(84) bytes of data.
64 bytes from 192.168.61.149: icmp_seq=1 ttl=63 time=0.306 ms
64 bytes from 192.168.61.149: icmp_seq=2 ttl=63 time=0.269 ms
64 bytes from 192.168.61.149: icmp_seq=3 ttl=63 time=0.234 ms
64 bytes from 192.168.61.149: icmp_seq=4 ttl=63 time=0.266 ms
64 bytes from 192.168.61.149: icmp_seq=5 ttl=63 time=0.233 ms

--- 192.168.61.149 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 129ms
rtt min/avg/max/mdev = 0.233/0.261/0.306/0.032 ms
```

Same thing for SPGW-U IP address:

```bash
$ ping -c 5 192.168.61.133
...
5 packets transmitted, 5 received, 0% packet loss, time 129ms
...
```

**NOTE: YOU CAN TRY TO PING THE HSS CONTAINER BUT IT WON'T WORK.**

You are ready to [generate some traffic](./GENERATE_TRAFFIC.md).


# Usefull commands
Docker
```bash
#check if all containers are running
docker ps

# check logs
docker logs prod-db-init --follow

#access container bash
docker exec -t -i demo-magma-mme /bin/bash

#see the MME log
docker exec -t -i demo-magma-mme /bin/bash -c "tail -f /var/log/mme.log"

#accessing cassanda
docker exec -t -i demo-cassandra /bin/bash
cqlsh
SELECT * FROM vhss.users_imsi;
SELECT * FROM vhss.msisdn_imsi;

```
# UE
## SIM programming
### PCSC
First install dependencies:

```
sudo apt-get install pcscd pcsc-tools libccid libpcsclite-dev
```

Connect your SIM card reader, plug thhe programmable SIM card in, and check connectivity by running the following command:

```
sudo pcsc_scan
```

If your reader and card got recognised, you will see something similar:

```
PC/SC device scanner
V 1.4.22 (c) 2001-2011, Ludovic Rousseau <ludovic.rousseau@free.fr>
Compiled with PC/SC lite version: 1.8.10
Using reader plug'n play mechanism
Scanning present readers...
0: OMNIKEY AG CardMan 3121 01 00

Wed Dec 24 14:56:32 2014
Reader 0: OMNIKEY AG CardMan 3121 01 00
  Card state: Card inserted,
  ATR: 3B 9F 95 80 1F C7 80 31 E0 73 FE 21 13 57 12 29 11 02 01 00 00 C2

ATR: 3B 9F 95 80 1F C7 80 31 E0 73 FE 21 13 57 12 29 11 02 01 00 00 C2
+ TS = 3B --> Direct Convention
+ T0 = 9F, Y(1): 1001, K: 15 (historical bytes)
  TA(1) = 95 --> Fi=512, Di=16, 32 cycles/ETU
    125000 bits/s at 4 MHz, fMax for Fi = 5 MHz => 156250 bits/s
  TD(1) = 80 --> Y(i+1) = 1000, Protocol T = 0
-----
  TD(2) = 1F --> Y(i+1) = 0001, Protocol T = 15 - Global interface bytes following
-----
  TA(3) = C7 --> Clock stop: no preference - Class accepted by the card: (3G) A 5V B 3V C 1.8V
+ Historical bytes: 80 31 E0 73 FE 21 13 57 12 29 11 02 01 00 00
  Category indicator byte: 80 (compact TLV data object)
    Tag: 3, len: 1 (card service data byte)
      Card service data byte: E0
        - Application selection: by full DF name
        - Application selection: by partial DF name
        - BER-TLV data objects available in EF.DIR
        - EF.DIR and EF.ATR access services: by GET RECORD(s) command
        - Card with MF
    Tag: 7, len: 3 (card capabilities)
      Selection methods: FE
        - DF selection by full DF name
        - DF selection by partial DF name
        - DF selection by path
        - DF selection by file identifier
        - Implicit DF selection
        - Short EF identifier supported
        - Record number supported
      Data coding byte: 21
        - Behaviour of write functions: proprietary
        - Value 'FF' for the first byte of BER-TLV tag fields: invalid
        - Data unit in quartets: 2
      Command chaining, length fields and logical channels: 13
        - Logical channel number assignment: by the card
        - Maximum number of logical channels: 4
    Tag: 5, len: 7 (card issuer's data)
      Card issuer data: 12 29 11 02 01 00 00
+ TCK = C2 (correct checksum)


Possibly identified card (using /usr/share/pcsc/smartcard_list.txt):
3B 9F 95 80 1F C7 80 31 E0 73 FE 21 13 57 12 29 11 02 01 00 00 C2
        sysmocom sysmoUSIM-GR1
        http://sysmocom.de/

Hit Ctrl+C to exit pcsc_scan.
```

### Pyscard

Now you need to download and install Pyscard:

http://pyscard.sourceforge.net/

Download and extract the latest Pyscard version:

https://sourceforge.net/projects/pyscard/files/pyscard/
#### Install swig
```
sudo apt-get install -y swig
```

Go to the extracted Pyscard folder (where the setup.py file is located) and run the following command:

`sudo python setup.py build_ext install`

### PySIM

Now get the code of PySIM:

```
git clone git://git.osmocom.org/pysim pysim

cd pysim
```

and run the /pySim-read.py to read your card:

`./pySim-read.py`

if you done everything allright, you will see something similar:

```
Reading ...
ICCID: 8901901550000123456
IMSI: 901550000123456
SMSP: fffffffffffffffffffffffffdffffffffffffffffffffffff069186770700f9ffffffffffffffff
ACC: ffff
MSISDN: Not available
Done !
```

Sometimes it is necessary to give the program the number of the card programmer:

```
./pySim-read.py -p 0      or       ./pySim-read.py -p 1
```

Now we are ready to program the USIM finally.

# **Important (must be done otherwise the SIM will be unusable):**

In order to program the SysmoUSIM-SJS1 (orange) USIM cards, you must use the "zecke/tmp" branch of Pysim. Please note that with the "zecke/tmp" branch you can program but cannot read the cards. If you want to read the cards you will need to swtich back to the "master" branch. If you are not using the "zecke/tmp" branch or you are not giving the ADM1 pin correctly, you can permanently damage your card!!!

To change branch to "zecke/tmp", use this command:

```
git checkout zecke/tmp
```

It runs as a Python2, therefore you need to have python2 and pip

```
sudo apt install python-pip
sudo apt-get install python-setuptools
```

Example to program a Sysmo-USIM GR1 card:

Use the following command to program your USIM (use "-p 0" or "-p 1" at the end like previously):

`./pySim-prog.py -t sysmoUSIM-GR1 -j 0 --op=63bfa50ee6523365ff14c1f45f88737d -p 1`

You will see something similar:

```
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8901901550000123456
 > MCC/MNC : 901/55
 > IMSI    : 901550000123456
 > Ki      : 98f7b38ac0d2887637e67d9fd1234567
 > OPC     : 49cd0845dd1b0d819a496e27a16c0916
 > ACC     : None

Programming ...
Done !
```

Example to program a SysmoUSIM-SJS1 (orange) card:

```
./pySim-prog.py -p 0 -x 101 -y 02 -t sysmoUSIM-SJS1 -i 101020000000003 -s 8988211000000012345 --op=11111111111111111111111111111111 -k 8BAF473F2F8FD09487CCCBD7097C6862 -a 53770832
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000012345
 > MCC/MNC : 101/2
 > IMSI    : 101020000000003
 > Ki      : 8BAF473F2F8FD09487CCCBD7097C6862
 > OPC     : 8e27b6af0e692e750f32667a3b14605d
 > ACC     : None

Programming ...
Done !
```

Where -a is the part where you need to give the ADM1 for this specific SIM card. Again, if you are not using the "zecke/tmp" branch or not giving the proper ADM1 pin when you try to program the Sysmo-USIm S1J1 (orange) SIMs, you will likely end up with a permamnently damaged card!


### SIM programming examples
```
./pySim-prog.py -p 0 -x 230 -y 77 -t sysmoUSIM-SJS1 -i 230770000000001 -s 8988211000000094626 --op=11111111111111111111111111111111 -k 3BA565A6CFEF4BCBC5D697C31B5ECDD1 -a 37571034

Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000094626
 > MCC/MNC : 230/77
 > IMSI    : 230770000000001
 > Ki      : 3BA565A6CFEF4BCBC5D697C31B5ECDD1
 > OPC     : 2676c1534fad3446bd888c13e006431b
 > ACC     : None

```


```
./pySim-prog.py -p 0 -x 230 -y 77 -t sysmoUSIM-SJS1 -i 230770000000002 -s 8988211000000247968 --op=11111111111111111111111111111111 -k C1818293A5A8564392C61FEE3A0DE140 -a 67263880 

opc  2676c1534fad3446bd888c13e006431b
```



```
./pySim-prog.py -p 0 -x 230 -y 77 -t sysmoUSIM-SJS1 -i 230770000000001 -s 8988211000000094626 --op=11111111111111111111111111111111 -k 3BA565A6CFEF4BCBC5D697C31B5ECDD1 -a 37571034

OPC  12acdb0de1960e6ea2573905f8bff568
```


```
 ./pySim-prog.py -p 0 -x 230 -y 77 -t sysmoUSIM-SJS1 -i 230770000000002 -s 8988211000000094642 --op=11111111111111111111111111111111 -k 3F2FC18FC3091C4B9392B8A09CCBE192 -a 34722135
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000094642
 > MCC/MNC : 230/77
 > IMSI    : 230770000000002
 > Ki      : 3F2FC18FC3091C4B9392B8A09CCBE192
 > OPC     : 144faf75ca2b63485303b7bacec50861
 > ACC     : None
```

```
./pySim-prog.py -p 0 -x 505 -y 01 -t sysmoUSIM-SJS1 -i 505010000000002 -s 8988211000000094642 --op=11111111111111111111111111111111 -k 3F2FC18FC3091C4B9392B8A09CCBE192 -a 34722135
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000094642
 > MCC/MNC : 505/1
 > IMSI    : 505010000000002
 > Ki      : 3F2FC18FC3091C4B9392B8A09CCBE192
 > OPC     : 144faf75ca2b63485303b7bacec50861
 > ACC     : None

```

```
./pySim-prog.py -p 0 -x 230 -y 01 -t sysmoUSIM-SJS1 -i 230010000000002 -s 8988211000000094642 --op=11111111111111111111111111111111 -k 3F2FC18FC3091C4B9392B8A09CCBE192 -a 34722135
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000094642
 > MCC/MNC : 230/1
 > IMSI    : 230010000000002
 > Ki      : 3F2FC18FC3091C4B9392B8A09CCBE192
 > OPC     : 144faf75ca2b63485303b7bacec50861
 > ACC     : None

```

```
./pySim-prog.py -p 0 -x 230 -y 99 -t sysmoUSIM-SJS1 -i 230990000000002 -s 8988211000000094642 --op=11111111111111111111111111111111 -k 3F2FC18FC3091C4B9392B8A09CCBE192 -a 34722135
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000094642
 > MCC/MNC : 230/99
 > IMSI    : 230990000000002
 > Ki      : 3F2FC18FC3091C4B9392B8A09CCBE192
 > OPC     : 144faf75ca2b63485303b7bacec50861
 > ACC     : None
```

```
./pySim-prog.py -p 0 -x 208 -y 95 -t sysmoUSIM-SJS1 -i 208950000000002 -s 8988211000000247992 --op=11111111111111111111111111111111 -k 2DA48B00AA76A3A22CC85599D7B79E81 -a 53121511
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000247992
 > MCC/MNC : 208/95
 > IMSI    : 208950000000002
 > Ki      : 2DA48B00AA76A3A22CC85599D7B79E81
 > OPC     : 711ee78411f6566dc0b46e0c05c716ba
 > ACC     : None
```

```
./pySim-prog.py -p 0 -x 230 -y 33 -t sysmoUSIM-SJS1 -i 230330000000001 -s 8988211000000094667 --op=11111111111111111111111111111111 -k 448848546F26f0e15f39e2a8ff466fc0 -a 20615272
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000094667
 > MCC/MNC : 230/33
 > IMSI    : 230330000000001
 > Ki      : 448848546F26f0e15f39e2a8ff466fc0
 > OPC     : 9109c6f16fca8ea04cc2cd44b64c00e6
 > ACC     : None
```


```
./pySim-prog.py -p 0 -x 230 -y 77 -t sysmoUSIM-SJS1 -i 230770000000001 -s 8988211000000247992 --op=11111111111111111111111111111111 -k 2DA48B00AA76A3A22CC85599D7B79E81 -a 53121511
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000247992
 > MCC/MNC : 230/77
 > IMSI    : 230770000000001
 > Ki      : 2DA48B00AA76A3A22CC85599D7B79E81
 > OPC     : 711ee78411f6566dc0b46e0c05c716ba
 > ACC     : None
```


```
./pySim-prog.py -p 0 -x 208 -y 92 -t sysmoUSIM-SJS1 -i 208920100009111 -s 8988211000000247992 --op=11111111111111111111111111111111 -k 2DA48B00AA76A3A22CC85599D7B79E81 -a 53121511
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000247992
 > MCC/MNC : 208/92
 > IMSI    : 208920100009111
 > Ki      : 2DA48B00AA76A3A22CC85599D7B79E81
 > OPC     : 711ee78411f6566dc0b46e0c05c716ba
 > ACC     : None

```

```
./pySim-prog.py -p 0 -x 230 -y 77 -t sysmoUSIM-SJS1 -i 230770000000002 -s 8988211000000247968 --op=11111111111111111111111111111111 -k C1818293A5A8564392C61FEE3A0DE140 -a 67263880 
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000247968
 > MCC/MNC : 230/77
 > IMSI    : 230770000000002
 > Ki      : C1818293A5A8564392C61FEE3A0DE140
 > OPC     : 12acdb0de1960e6ea2573905f8bff568
 > ACC     : None

Programming ...
Done !
```



`./pySim-prog.py -p 0 -x 230 -y 77 -t sysmoUSIM-SJS1 -i 230770000000002 -s 8988211000000247976 --op=11111111111111111111111111111111 -k 909AE6849954E0483540DCAD7AF90523 -a 35595026`

```
./pySim-prog.py -p 0 -x 001 -y 01 -t sysmoUSIM-SJS1 -i 001010000000001 -s 8988211000000247992 --op=11111111111111111111111111111111 -k 2DA48B00AA76A3A22CC85599D7B79E81 -a 53121511
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000247992
 > MCC/MNC : 1/1
 > IMSI    : 001010000000001
 > Ki      : 2DA48B00AA76A3A22CC85599D7B79E81
 > OPC     : 711ee78411f6566dc0b46e0c05c716ba
 > ACC     : None

Programming ...
Done !
```


```
./pySim-prog.py -p 0 -x 505 -y 01 -t sysmoUSIM-SJS1 -i 505010000000001 -s 8988211000000094642 --op=11111111111111111111111111111111 -k 3F2FC18FC3091C4B9392B8A09CCBE192 -a 34722135
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000094642
 > MCC/MNC : 505/1
 > IMSI    : 505010000000001
 > Ki      : 3F2FC18FC3091C4B9392B8A09CCBE192
 > OPC     : 144faf75ca2b63485303b7bacec50861
 > ACC     : None

Programming ...
Done !
```


```
./pySim-prog.py -p 0 -x 505 -y 01 -t sysmoUSIM-SJS1 -i 505010000000002 -s 8988211000000247992 --op=11111111111111111111111111111111 -k 2DA48B00AA76A3A22CC85599D7B79E81 -a 53121511
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000247992
 > MCC/MNC : 505/1
 > IMSI    : 505010000000002
 > Ki      : 2DA48B00AA76A3A22CC85599D7B79E81
 > OPC     : 711ee78411f6566dc0b46e0c05c716ba
 > ACC     : None

Programming ...
Done !

```
```
./pySim-prog.py -p 0 -x 230 -y 31 -t sysmoUSIM-SJS1 -i 230310000000001 -s 8988211000000094618 --op=11111111111111111111111111111111 -k 4EAB3C9B06B630AC3DCEF2F2312E9B85 -a 28168282
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000094618
 > MCC/MNC : 230/31
 > IMSI    : 230310000000001
 > Ki      : 4EAB3C9B06B630AC3DCEF2F2312E9B85
 > OPC     : 3269a7e9eb4b43b7eff8e6d9e28700d0
 > ACC     : None

Programming ...
Done !
```

```
./pySim-prog.py -p 0 -x 505 -y 01 -t sysmoUSIM-SJS1 -i 505010000000003 -s 8988211000000247984 --op=11111111111111111111111111111111 -k 4813D9662B87883D40FAC5874C76BCBF -a 55373033
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000247984
 > MCC/MNC : 505/1
 > IMSI    : 505010000000003
 > Ki      : 4813D9662B87883D40FAC5874C76BCBF
 > OPC     : 0aa9293fb353b8672cc48b4e5b3a019e
 > ACC     : None

Programming ...
Done !
```

```
 ./pySim-prog.py -p 0 -x 208 -y 99 -t sysmoUSIM-SJS1 -i 208990000000001 -s 8988211000000094626 --op=C42449363BBAD02B66D16BC975D77CC1 -k 3BA565A6CFEF4BCBC5D697C31B5ECDD1 -a 37571034
Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name    : Magic
 > SMSP    : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID   : 8988211000000094626
 > MCC/MNC : 208/99
 > IMSI    : 208990000000001
 > Ki      : 3BA565A6CFEF4BCBC5D697C31B5ECDD1
 > OPC     : 2e2a34e138e207cdeafc47fe2716031a
 > ACC     : None

Programming ...
Done !
```

```
 ./pySim-prog.py -p 0 -x 208 -y 93 -t sysmoUSIM-SJS1 -i 208930000000005 -s 8988211000000247976 --op=e734f8734007d6c5ce7a0508809e7e9c -k 8baf473f2f8fd09487cccbd7097c6862 -a 35595026


algo = milenage
opc  = e734f8734007d6c5ce7a0508809e7e9c
k    = 8baf473f2f8fd09487cccbd7097c6862
imsi = 208930000000005
imei = 35609204079305
```

```
 ./pySim-prog.py -p 0 -x 230 -y 30 -t sysmoUSIM-SJS1 -i 230300000000001 -s 8988211000000094642 --op=11111111111111111111111111111111 -k 3F2FC18FC3091C4B9392B8A09CCBE192 -a 34722135
Using PC/SC reader interface
Ready for Programming: Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name     : Magic
 > SMSP     : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID    : 8988211000000094642
 > MCC/MNC  : 230/30
 > IMSI     : 230300000000001
 > Ki       : 3F2FC18FC3091C4B9392B8A09CCBE192
 > OPC      : 144faf75ca2b63485303b7bacec50861
 > ACC      : None
 > ADM1(hex): 3334373232313335
 > OPMODE   : None
Programming ...
Programming successful: Remove card from reader

```

ue4,mil,230300000000002,2DA48B00AA76A3A22CC85599D7B79E81,opc,711ee78411f6566dc0b46e0c05c716ba,9000,000000007aa0,9,dynamic

```
./pySim-prog.py -p 0 -x 230 -y 30 -t sysmoUSIM-SJS1 -i 230300000000002 -s 8988211000000247992 --op=11111111111111111111111111111111 -k 2DA48B00AA76A3A22CC85599D7B79E81 -a 53121511
Using PC/SC reader interface
Ready for Programming: Insert card now (or CTRL-C to cancel)
Generated card parameters :
 > Name     : Magic
 > SMSP     : e1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 > ICCID    : 8988211000000247992
 > MCC/MNC  : 230/30
 > IMSI     : 230300000000002
 > Ki       : 2DA48B00AA76A3A22CC85599D7B79E81
 > OPC      : 711ee78411f6566dc0b46e0c05c716ba
 > ACC      : None
 > ADM1(hex): 3533313231353131
 > OPMODE   : None
Programming ...
Programming successful: Remove card from reader
```


## srsran
```
Lab@5GM-Z4-1:~/pysim$ ./pySim-prog.py -p 0 a 39302484 -x 001 -y 01 -1 901700000070598 -s 8988211000000700000 - 398153093661279FB1FC74BE07059FEF -
k B5A16E285DEA3A1BD46B57EBCB8A460A
```
## tips & remote control

Use [Scrcpy app](https://github.com/Genymobile/scrcpy) for remote control.
Install via:
```
sudo snap install scrcpy
```
Run as user not root!
```
scrcpy
```
If there are issues kill and restart adb process

# it can be setup to run wirelessly

Scrcpy uses adb to communicate with the device, and adb can connect to a device over TCP/IP:

1. Connect the device to the same Wi-Fi as your computer.
1. Get your device IP address, in Settings → About phone → Status, or by executing this command: `adb shell ip route | awk '{print $9}'`
1. Enable adb over TCP/IP on your device: `adb tcpip 5555`.
1. Unplug your device.
1. Connect to your device: `adb connect DEVICE_IP:5555` (replace DEVICE_IP).
1. Run `scrcpy` as usual.

It may be useful to decrease the bit-rate and the definition:

scrcpy --bit-rate 2M --max-size 800
scrcpy -b2M -m800  # short version


./scripts/syncComponentsLegacy.sh --hss-branch develop --mme-branch develop --spgwc-branch develop --spgwu-tiny-branch develop

# Octoclock
https://files.ettus.com/manual/page_octoclock.html
https://kb.ettus.com/Enabling_Ethernet_Connectivity_on_Octoclock_and_Octoclock-G
https://files.ettus.com/manual/page_octoclock.html

## h2

win10
route 0.0.0.0 MASK 0.0.0.0 IP_UBUNTU
# Create the tunnel to TUM PC from the VPN interface
sudo ip tunnel add gre_tum remote 10.162.148.134 local 10.0.15.6

# Bring the new interface up
sudo ip link set gre_tum up

# Set the ip on the new interface
sudo ip addr add 10.10.10.2/24 dev gre_tum

# Make the necessary routing to reach the network of UEs that are connected to the core
sudo ip route add 10.162.0.0/24 via 10.10.10.1


route add 0.0.0.0 mask 0.0.0.0 <ubuntu IP>
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE