diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh
index 3eb24932bf685b04beaa4b0fa5fe88debb440893..2a358c9bacf09ce8d27577efc3d1572ce98f80e9 100755
--- a/ci-scripts/buildOnVM.sh
+++ b/ci-scripts/buildOnVM.sh
@@ -127,7 +127,7 @@ case $key in
     ARCHIVES_LOC=enb_usrp
     LOG_PATTERN=.Rel14.txt
     NB_PATTERN_FILES=4
-    BUILD_OPTIONS="--eNB -w USRP"
+    BUILD_OPTIONS="--eNB -w USRP --mu"
     shift
     ;;
     -v2)
@@ -181,7 +181,7 @@ case $key in
         ARCHIVES_LOC=enb_usrp
         LOG_PATTERN=.Rel14.txt
         NB_PATTERN_FILES=4
-        BUILD_OPTIONS="--eNB -w USRP"
+        BUILD_OPTIONS="--eNB -w USRP --mu"
         ;;
         basic-sim)
         VM_NAME=ci-basic-sim
diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf
index bae8dcfd9700074768ff0291e5175b8100ede075..ec968e8cefde3241f81e74abb43af82ce5d0298a 100644
--- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf
@@ -13,10 +13,8 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf
index 673d5a7957edfe82726c0525b6d7b479b5b22041..c2f69cb1b9680cc6a609174e0a818e0ca6533552 100644
--- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf
@@ -13,10 +13,8 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf
index fd9de112dcee7aeab48f31ef2c5aca282268fa63..6bdbd4e39b7ff0d5a9d9d7853b967aaa81529e9c 100644
--- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf
@@ -13,10 +13,8 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf
index 3d79fd09863ece7498e6233d960515f96dd484c8..1a566e957900cc5334d7996a60934314213904cb 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf
index b4c20ba644513bfca3387ce63f2efc4cae237226..fd49fe9d837b6a7a2d0a8b6dd2da863f47c16b12 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
index a6ac1f8c140cfcad9883d7190715aa915ec651df..1613dd4c320170e2518aaacb698aa578589f7af0 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf
index 0b02e8f871738ae1c45cde192c1c82b20b5cf17e..0211e126a14708955af6173f279b3c0ac403ebb9 100644
--- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf
+++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "93";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/ci-scripts/conf_files/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf
index fe9b8a3601fd7acce516b43cf21d310730226c15..a7bc31eed804858d35dd99bed1d18a272b579d18 100644
--- a/ci-scripts/conf_files/lte-tdd-basic-sim.conf
+++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf
@@ -13,10 +13,8 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-    mobile_network_code =  "93";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf
index 08eb76e09de3551c53e440f8a80d4bdfde30fc66..398b76388898bd51b8814bd036ade8d45520a6cd 100644
--- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf
index eff42040ad87163f5d6f562377e41394450c18aa..46b648473742a635aba7181cae46388b6d090372 100644
--- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf
index 8eb66d46438e24e943db10c19a62837a42e550a1..93b82773e6461939d1dc6e9cb74e49e428fc2c18 100644
--- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf
index dc3b3bc4f03a5b93efb03eee80f96c1440950ab0..b412b00e523074bbe34f547c76d2978572fdb451 100644
--- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf
index 6af71831f5416490f0df81a67b6a70f6192c263e..f0d688903a6894508928af20ac76002badb57798 100644
--- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf
index 077b6e4ead5def0feab001a00900221b93437f40..929c91fffbdb6c1a2b4a00db9208c760f23bf8b6 100644
--- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf
index e2f5981418f4487e92bd9c9d03796b4d3dbe8b05..98358eb269bd7305c7a94c28e3278ae4f49a3e29 100644
--- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf
+++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf
index 9e08414ab3de7152cb674eac96eb7ee8310cd455..bc31e051e57db834520b1bc29ccf60fac7ce97d7 100644
--- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf
+++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf
index 2a598c31d317478bfe78751745adce6ee8f9cf4f..2cfc227e67aeef229152a853908bbb9648da88be 100644
--- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf
+++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf
index 4966108d034d82e20e0df8d72c619bdb63b03ea3..9b135a94982c8214a6bfc17270d04c4e1b815cab 100644
--- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf
+++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf
index 4f3b25349a64ad0368875ba70d6e150ec0f3e5b7..9f84057299cd8ce552598399e85d52edd45c142e 100644
--- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf
+++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf
index 54e5a327cd61e7cc5568f9e6267787a231020826..7197e93322e56c63a6b77abd0a4256bdc6fdaeee 100644
--- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf
+++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 3363bd2e7658feef8f91ec18b80f738b43cc440b..18e0d5474612541276573ec79ed74927423679ca 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -683,7 +683,7 @@ install_asn1c_from_source(){
     # better to use a given commit than a branch in case the branch
     # is updated and requires modifications in the source of OAI
     #git checkout velichkov_s1ap_plus_option_group
-    git checkout 73d6b23dcec9ab36605b4af884143824392134c1
+    git checkout d3aed06bb2bec7df1b5c6d0333f8c7dfc5993372
     autoreconf -iv
     ./configure
     make -j`nproc`
diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c
index 57a680044b1c772382f1d6a5fec30bda4e6a3e10..0ec2e2379042042841ceac490adc58be97ee9de2 100644
--- a/common/config/config_userapi.c
+++ b/common/config/config_userapi.c
@@ -29,6 +29,9 @@
  * \note
  * \warning
  */
+
+#define _GNU_SOURCE
+
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -210,6 +213,36 @@ configmodule_interface_t *cfgif = config_get_if();
 return ret;
 }
 
+int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix)
+{
+  if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
+    fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n");
+    return -1;
+  }
+  if (!config_get_if())
+    return -1;
+
+  const int ret = config_get_if()->getlist(ParamList, params, numparams, prefix);
+  if (ret >= 0 && params) {
+    char *newprefix;
+    if (prefix) {
+      int rc = asprintf(&newprefix, "%s.%s", prefix, ParamList->listname);
+      if (rc < 0) newprefix = NULL;
+    } else {
+      newprefix = ParamList->listname;
+    }
+    char cfgpath[MAX_OPTNAME_SIZE*2 + 6]; /* prefix.listname.[listindex] */
+    for (int i = 0; i < ParamList->numelt; ++i) {
+      // TODO config_process_cmdline?
+      sprintf(cfgpath, "%s.[%i]", newprefix, i);
+      config_execcheck(ParamList->paramarray[i], numparams, cfgpath);
+    }
+    if (prefix)
+      free(newprefix);
+  }
+  return ret;
+}
+
 int config_isparamset(paramdef_t *params,int paramidx)
 {
   if ((params[paramidx].paramflags & PARAMFLAG_PARAMSET) != 0) {
diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h
index 25306b8778d844f70db17826d14e26fccc72b35d..2b40f8401be2466cda9adfbbb3725910b83fd828 100644
--- a/common/config/config_userapi.h
+++ b/common/config/config_userapi.h
@@ -57,7 +57,7 @@ extern int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr);
 
 /* apis to get parameters, to be used by oai modules, at configuration time */
 extern int config_get(paramdef_t *params,int numparams, char *prefix);
-#define config_getlist config_get_if()->getlist
+extern int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix);
 
 /* apis to retrieve parameters info after calling get or getlist functions */
 extern int config_isparamset(paramdef_t *params,int paramidx);
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 4a0137d4b6e5ae560e0371663566adc493519d94..12a06f7c659838334b8ff87f175840810f16c0ef 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -97,9 +97,10 @@ typedef struct RrcConfigurationReq_s {
 
   uint16_t            tac;
 
-  uint16_t            mcc;
-  uint16_t            mnc;
-  uint8_t             mnc_digit_length;
+  uint16_t            mcc[PLMN_LIST_MAX_SIZE];
+  uint16_t            mnc[PLMN_LIST_MAX_SIZE];
+  uint8_t             mnc_digit_length[PLMN_LIST_MAX_SIZE];
+  uint8_t             num_plmn;
 
   
   paging_drx_t            default_drx;
diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index 4a5f492b0baa3f4685c8de48f342ff6075e02d8f..f56a340cb24d7df4c9db45b4c6f6b156568c2817 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -325,12 +325,14 @@ typedef struct s1ap_register_enb_req_s {
   /* Tracking area code */
   uint16_t tac;
 
+#define PLMN_LIST_MAX_SIZE 6
   /* Mobile Country Code
    * Mobile Network Code
    */
-  uint16_t mcc;
-  uint16_t mnc;
-  uint8_t  mnc_digit_length;
+  uint16_t mcc[PLMN_LIST_MAX_SIZE];
+  uint16_t mnc[PLMN_LIST_MAX_SIZE];
+  uint8_t  mnc_digit_length[PLMN_LIST_MAX_SIZE];
+  uint8_t  num_plmn;
 
   /* Default Paging DRX of the eNB as defined in TS 36.304 */
   paging_drx_t default_drx;
@@ -342,6 +344,8 @@ typedef struct s1ap_register_enb_req_s {
   uint8_t          nb_mme;
   /* List of MME to connect to */
   net_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS];
+  uint8_t          broadcast_plmn_num[S1AP_MAX_NB_MME_IP_ADDRESS];
+  uint8_t          broadcast_plmn_index[S1AP_MAX_NB_MME_IP_ADDRESS][PLMN_LIST_MAX_SIZE];
 
   /* Number of SCTP streams used for a mme association */
   uint16_t sctp_in_streams;
@@ -372,6 +376,10 @@ typedef struct s1ap_nas_first_req_s {
   /* UE id for initial connection to S1AP */
   uint16_t ue_initial_id;
 
+  /* the chosen PLMN identity as index, see TS 36.331 6.2.2 RRC Connection
+   * Setup Complete. This index here is zero-based, unlike the standard! */
+  int selected_plmn_identity;
+
   /* Establishment cause as sent by UE */
   rrc_establishment_cause_t establishment_cause;
 
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 2506a0a9dca71261a67156ec4bcec93ec5b648e6..2675e4454c8d549a6a6bcf38da84f6f2bf88f518 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -36,13 +36,13 @@
 #include "UTIL/OTG/otg.h"
 #include "UTIL/OTG/otg_externs.h"
 #if defined(ENABLE_ITTI)
-  #include "intertask_interface.h"
-  #if defined(ENABLE_USE_MME)
-    #include "s1ap_eNB.h"
-    #include "sctp_eNB_task.h"
-  #else
-    #define EPC_MODE_ENABLED 0
-  #endif
+#include "intertask_interface.h"
+#if defined(ENABLE_USE_MME)
+#include "s1ap_eNB.h"
+#include "sctp_eNB_task.h"
+#else
+#define EPC_MODE_ENABLED 0
+#endif
 #endif
 #include "sctp_default_values.h"
 #include "SystemInformationBlockType2.h"
@@ -61,8 +61,8 @@
 #include "enb_paramdef.h"
 
 extern uint16_t sf_ahead;
-extern void set_parallel_conf(char* parallel_conf);
-extern void set_worker_conf(char* worker_conf);
+extern void set_parallel_conf(char *parallel_conf);
+extern void set_worker_conf(char *worker_conf);
 extern PARALLEL_CONF_t get_thread_parallel_conf(void);
 extern WORKER_CONF_t   get_thread_worker_conf(void);
 extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
@@ -234,7 +234,7 @@ void RCconfig_L1(void) {
   paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
 
   if (RC.eNB == NULL) {
-    RC.eNB                       = (PHY_VARS_eNB ***)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **));
+    RC.eNB                       = (PHY_VARS_eNB ** *)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **));
     LOG_I(PHY,"RC.eNB = %p\n",RC.eNB);
     memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **));
     RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int));
@@ -283,7 +283,8 @@ void RCconfig_L1(void) {
         LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_CC[0]=%d for init_eNB_afterRU()\n", __FUNCTION__, RC.nb_CC[0]);
         LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_macrlc_inst:%d because used by mac_top_init_eNB()\n", __FUNCTION__, RC.nb_macrlc_inst);
         //mac_top_init_eNB();
-        configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n     .remote_portd);
+        configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd,
+                            RC.eNB[j][0]->eth_params_n     .remote_portd);
       } else { // other midhaul
       }
     }// j=0..num_inst
@@ -300,7 +301,7 @@ void RCconfig_L1(void) {
     if (RC.eNB[j] == NULL) {
       RC.eNB[j]                       = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB **));
       LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]);
-      memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB ***));
+      memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB ** *));
     }
 
     for (i=0; i<RC.nb_L1_CC[j]; i++) {
@@ -569,31 +570,46 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
     for (k=0; k <num_enbs ; k++) {
       if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[k], *(ENBParamList.paramarray[i][ENB_ENB_NAME_IDX].strptr) )== 0) {
         char enbpath[MAX_OPTNAME_SIZE + 8];
+        sprintf(enbpath,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
+        paramdef_t PLMNParams[] = PLMNPARAMS_DESC;
+        paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0};
+        /* map parameter checking array instances to parameter definition array instances */
+        checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
+
+        for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
+          PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
+
         RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id;
-        /*
-          if (strcmp(*(ENBParamList.paramarray[i][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
-          enb_properties_loc.properties[enb_properties_loc_index]->cell_type = CELL_MACRO_ENB;
-          } else  if (strcmp(cell_type, "CELL_HOME_ENB") == 0) {
-          enb_properties_loc.properties[enb_properties_loc_index]->cell_type = CELL_HOME_ENB;
-          } else {
-          AssertFatal (0,
-          "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
-          lib_config_file_name_pP, i, cell_type);
-          }
+        RRC_CONFIGURATION_REQ(msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr;
+        AssertFatal(!ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr
+                    && !ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr,
+                    "It seems that you use an old configuration file. Please change the existing\n"
+                    "    tracking_area_code  =  \"1\";\n"
+                    "    mobile_country_code =  \"208\";\n"
+                    "    mobile_network_code =  \"93\";\n"
+                    "to\n"
+                    "    tracking_area_code  =  1; // no string!!\n"
+                    "    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n");
+        config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), enbpath);
+
+        if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
+          AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
+                      PLMNParamList.numelt);
+
+        RRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt;
+
+        for (int l = 0; l < PLMNParamList.numelt; ++l) {
+          RRC_CONFIGURATION_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
+          RRC_CONFIGURATION_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
+          RRC_CONFIGURATION_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr;
+          AssertFatal(RRC_CONFIGURATION_REQ(msg_p).mnc_digit_length[l] == 3
+                      || RRC_CONFIGURATION_REQ(msg_p).mnc[l] < 100,
+                      "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
+                      RRC_CONFIGURATION_REQ(msg_p).mnc[l]);
+        }
 
-          enb_properties_loc.properties[enb_properties_loc_index]->eNB_name         = strdup(enb_name);
-        */
-        RRC_CONFIGURATION_REQ (msg_p).tac              = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].strptr) );
-        RRC_CONFIGURATION_REQ (msg_p).mcc              = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX].strptr) );
-        RRC_CONFIGURATION_REQ (msg_p).mnc              = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr) );
-        RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
-        AssertFatal((RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length == 2) ||
-                    (RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length == 3),
-                    "BAD MNC DIGIT LENGTH %d",
-                    RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length);
         // Parse optional physical parameters
-        sprintf(enbpath,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k),
-                config_getlist( &CCsParamList,NULL,0,enbpath);
+        config_getlist( &CCsParamList,NULL,0,enbpath);
         LOG_I(RRC,"num component carriers %d \n",CCsParamList.numelt);
 
         if ( CCsParamList.numelt> 0) {
@@ -1983,35 +1999,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
           rrc->srb1_max_retx_threshold    = UL_AM_RLC__maxRetxThreshold_t8;
         }
 
-        /*
-          // Network Controller
-          subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG);
-
-          if (subsetting != NULL) {
-          if (  (
-           config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME,
-                 (const char **)&flexran_agent_interface_name)
-           && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS,
-                    (const char **)&flexran_agent_ipv4_address)
-           && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT,
-                &flexran_agent_port)
-           && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE,
-                    (const char **)&flexran_agent_cache)
-           )
-          ) {
-          enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_interface_name = strdup(flexran_agent_interface_name);
-          cidr = flexran_agent_ipv4_address;
-          address = strtok(cidr, "/");
-          //enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address = strdup(address);
-          if (address) {
-          IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" );
-          }
-
-          enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_port = flexran_agent_port;
-          enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_cache = strdup(flexran_agent_cache);
-          }
-          }
-        */
         break;
       }
     }
@@ -2031,7 +2018,6 @@ int RCconfig_gtpu(void ) {
   paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
   paramdef_t GTPUParams[]  = GTPUPARAMS_DESC;
   LOG_I(GTPU,"Configuring GTPu\n");
-
   /* get number of active eNodeBs */
   config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL);
   num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
@@ -2097,11 +2083,20 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
         // search if in active list
         for (j=0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) {
           if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) {
+            paramdef_t PLMNParams[] = PLMNPARAMS_DESC;
+            paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0};
+            /* map parameter checking array instances to parameter definition array instances */
+            checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
+
+            for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
+              PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
+
             paramdef_t S1Params[]  = S1PARAMS_DESC;
             paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS,NULL,0};
             paramdef_t SCTPParams[]  = SCTPPARAMS_DESC;
             paramdef_t NETParams[]  =  NETPARAMS_DESC;
             char aprefix[MAX_OPTNAME_SIZE*2 + 8];
+            sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
             S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id;
 
             if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
@@ -2115,16 +2110,35 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
             }
 
             S1AP_REGISTER_ENB_REQ (msg_p).eNB_name         = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
-            S1AP_REGISTER_ENB_REQ (msg_p).tac              = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].strptr));
-            S1AP_REGISTER_ENB_REQ (msg_p).mcc              = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX].strptr));
-            S1AP_REGISTER_ENB_REQ (msg_p).mnc              = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
-            S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
-            S1AP_REGISTER_ENB_REQ (msg_p).default_drx      = 0;
-            AssertFatal((S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 2) ||
-                        (S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 3),
-                        "BAD MNC DIGIT LENGTH %d",
-                        S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length);
-            sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
+            S1AP_REGISTER_ENB_REQ(msg_p).tac               = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
+            AssertFatal(!ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr
+                        && !ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr,
+                        "It seems that you use an old configuration file. Please change the existing\n"
+                        "    tracking_area_code  =  \"1\";\n"
+                        "    mobile_country_code =  \"208\";\n"
+                        "    mobile_network_code =  \"93\";\n"
+                        "to\n"
+                        "    tracking_area_code  =  1; // no string!!\n"
+                        "    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n");
+            config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
+
+            if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
+              AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
+                          PLMNParamList.numelt);
+
+            S1AP_REGISTER_ENB_REQ(msg_p).num_plmn = PLMNParamList.numelt;
+
+            for (int l = 0; l < PLMNParamList.numelt; ++l) {
+              S1AP_REGISTER_ENB_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
+              S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
+              S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr;
+              AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] == 3
+                          || S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] < 100,
+                          "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
+                          S1AP_REGISTER_ENB_REQ(msg_p).mnc[l]);
+            }
+
+            S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0;
             config_getlist( &S1ParamList,S1Params,sizeof(S1Params)/sizeof(paramdef_t),aprefix);
             S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0;
 
@@ -2141,6 +2155,35 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
                 S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1;
                 S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1;
               }
+
+              if (S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr)
+                S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].numelt;
+              else
+                S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = 0;
+
+              AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] <= S1AP_REGISTER_ENB_REQ(msg_p).num_plmn,
+                          "List of broadcast PLMN to be sent to MME can not be longer than actual "
+                          "PLMN list (max %d, but is %d)\n",
+                          S1AP_REGISTER_ENB_REQ(msg_p).num_plmn,
+                          S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]);
+
+              for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]; ++el) {
+                /* UINTARRAY gets mapped to int, see config_libconfig.c:223 */
+                S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr[el];
+                AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0
+                            && S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn,
+                            "index for MME's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n",
+                            S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el],
+                            S1AP_REGISTER_ENB_REQ(msg_p).num_plmn);
+              }
+
+              /* if no broadcasst_plmn array is defined, fill default values */
+              if (S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] == 0) {
+                S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1AP_REGISTER_ENB_REQ(msg_p).num_plmn;
+
+                for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el)
+                  S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = el;
+              }
             }
 
             // SCTP SETTING
@@ -2183,80 +2226,73 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
   paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0};
   /* get global parameters, defined outside any section in the config file */
   config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL);
-
   /* define CC params */
-
   int32_t Nid_cell = 0;
-
   char *frame_type, *prefix_type, *pbch_repetition, *prach_high_speed,
-    *pusch_hoppingMode, *pusch_enable64QAM, *pusch_groupHoppingEnabled,
-    *pusch_sequenceHoppingEnabled, *phich_duration, *phich_resource,
-    *srs_enable, *srs_ackNackST, *srs_MaxUpPts, *pusch_alpha,
-    *pucch_deltaF_Format1, *pucch_deltaF_Format1b, *pucch_deltaF_Format2,
-    *pucch_deltaF_Format2a, *pucch_deltaF_Format2b,
-    *rach_preamblesGroupAConfig, *rach_messagePowerOffsetGroupB, *pcch_nB;
+       *pusch_hoppingMode, *pusch_enable64QAM, *pusch_groupHoppingEnabled,
+       *pusch_sequenceHoppingEnabled, *phich_duration, *phich_resource,
+       *srs_enable, *srs_ackNackST, *srs_MaxUpPts, *pusch_alpha,
+       *pucch_deltaF_Format1, *pucch_deltaF_Format1b, *pucch_deltaF_Format2,
+       *pucch_deltaF_Format2a, *pucch_deltaF_Format2b,
+       *rach_preamblesGroupAConfig, *rach_messagePowerOffsetGroupB, *pcch_nB;
   long long int     downlink_frequency;
   int32_t tdd_config, tdd_config_s, eutra_band, uplink_frequency_offset,
-    Nid_cell_mbsfn, N_RB_DL, nb_antenna_ports, prach_root, prach_config_index,
-    prach_zero_correlation, prach_freq_offset, pucch_delta_shift,
-    pucch_nRB_CQI, pucch_nCS_AN, pucch_n1_AN, pdsch_referenceSignalPower,
-    pdsch_p_b, pusch_n_SB, pusch_hoppingOffset, pusch_groupAssignment,
-    pusch_nDMRS1, srs_BandwidthConfig, srs_SubframeConfig, pusch_p0_Nominal,
-    pucch_p0_Nominal, msg3_delta_Preamble, rach_numberOfRA_Preambles,
-    rach_sizeOfRA_PreamblesGroupA, rach_messageSizeGroupA,
-    rach_powerRampingStep, rach_preambleInitialReceivedTargetPower,
-    rach_preambleTransMax, rach_raResponseWindowSize,
-    rach_macContentionResolutionTimer, rach_maxHARQ_Msg3Tx,
-    pcch_defaultPagingCycle, bcch_modificationPeriodCoeff,
-    ue_TimersAndConstants_t300, ue_TimersAndConstants_t301,
-    ue_TimersAndConstants_t310, ue_TimersAndConstants_t311,
-    ue_TimersAndConstants_n310, ue_TimersAndConstants_n311,
-    ue_TransmissionMode, ue_multiple_max;
-
-  const char*       rxPool_sc_CP_Len;
-  const char*       rxPool_sc_Period;
-  const char*       rxPool_data_CP_Len;
+          Nid_cell_mbsfn, N_RB_DL, nb_antenna_ports, prach_root, prach_config_index,
+          prach_zero_correlation, prach_freq_offset, pucch_delta_shift,
+          pucch_nRB_CQI, pucch_nCS_AN, pucch_n1_AN, pdsch_referenceSignalPower,
+          pdsch_p_b, pusch_n_SB, pusch_hoppingOffset, pusch_groupAssignment,
+          pusch_nDMRS1, srs_BandwidthConfig, srs_SubframeConfig, pusch_p0_Nominal,
+          pucch_p0_Nominal, msg3_delta_Preamble, rach_numberOfRA_Preambles,
+          rach_sizeOfRA_PreamblesGroupA, rach_messageSizeGroupA,
+          rach_powerRampingStep, rach_preambleInitialReceivedTargetPower,
+          rach_preambleTransMax, rach_raResponseWindowSize,
+          rach_macContentionResolutionTimer, rach_maxHARQ_Msg3Tx,
+          pcch_defaultPagingCycle, bcch_modificationPeriodCoeff,
+          ue_TimersAndConstants_t300, ue_TimersAndConstants_t301,
+          ue_TimersAndConstants_t310, ue_TimersAndConstants_t311,
+          ue_TimersAndConstants_n310, ue_TimersAndConstants_n311,
+          ue_TransmissionMode, ue_multiple_max;
+  const char       *rxPool_sc_CP_Len;
+  const char       *rxPool_sc_Period;
+  const char       *rxPool_data_CP_Len;
   libconfig_int     rxPool_ResourceConfig_prb_Num;
   libconfig_int     rxPool_ResourceConfig_prb_Start;
   libconfig_int     rxPool_ResourceConfig_prb_End;
-  const char*       rxPool_ResourceConfig_offsetIndicator_present;
+  const char       *rxPool_ResourceConfig_offsetIndicator_present;
   libconfig_int     rxPool_ResourceConfig_offsetIndicator_choice;
-  const char*       rxPool_ResourceConfig_subframeBitmap_present;
-  char*             rxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
+  const char       *rxPool_ResourceConfig_subframeBitmap_present;
+  char             *rxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
   libconfig_int     rxPool_ResourceConfig_subframeBitmap_choice_bs_size;
   libconfig_int     rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
-
   //SIB19
   //for discRxPool
-  const char*       discRxPool_cp_Len;
-  const char*       discRxPool_discPeriod;
+  const char       *discRxPool_cp_Len;
+  const char       *discRxPool_discPeriod;
   libconfig_int     discRxPool_numRetx;
   libconfig_int     discRxPool_numRepetition;
   libconfig_int     discRxPool_ResourceConfig_prb_Num;
   libconfig_int     discRxPool_ResourceConfig_prb_Start;
   libconfig_int     discRxPool_ResourceConfig_prb_End;
-  const char*       discRxPool_ResourceConfig_offsetIndicator_present;
+  const char       *discRxPool_ResourceConfig_offsetIndicator_present;
   libconfig_int     discRxPool_ResourceConfig_offsetIndicator_choice;
-  const char*       discRxPool_ResourceConfig_subframeBitmap_present;
-  char*             discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
+  const char       *discRxPool_ResourceConfig_subframeBitmap_present;
+  char             *discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
   libconfig_int     discRxPool_ResourceConfig_subframeBitmap_choice_bs_size;
   libconfig_int     discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
-
   //for discRxPoolPS
-  const char*       discRxPoolPS_cp_Len;
-  const char*       discRxPoolPS_discPeriod;
+  const char       *discRxPoolPS_cp_Len;
+  const char       *discRxPoolPS_discPeriod;
   libconfig_int     discRxPoolPS_numRetx;
   libconfig_int     discRxPoolPS_numRepetition;
   libconfig_int     discRxPoolPS_ResourceConfig_prb_Num;
   libconfig_int     discRxPoolPS_ResourceConfig_prb_Start;
   libconfig_int     discRxPoolPS_ResourceConfig_prb_End;
-  const char*       discRxPoolPS_ResourceConfig_offsetIndicator_present;
+  const char       *discRxPoolPS_ResourceConfig_offsetIndicator_present;
   libconfig_int     discRxPoolPS_ResourceConfig_offsetIndicator_choice;
-  const char*       discRxPoolPS_ResourceConfig_subframeBitmap_present;
-  char*             discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf;
+  const char       *discRxPoolPS_ResourceConfig_subframeBitmap_present;
+  char             *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf;
   libconfig_int     discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size;
   libconfig_int     discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
-
   checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
   paramdef_t CCsParams[] = CCPARAMS_DESC;
   paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0};
@@ -2265,22 +2301,22 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
   for (I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) {
     CCsParams[I].chkPptr = &(config_check_CCparams[I]);
   }
-/*#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
-    if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
-      asn_debug      = 0;
-      asn1_xer_print = 0;
-    } else if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) {
-      asn_debug      = 1;
-      asn1_xer_print = 1;
-    } else if (strcasecmp(*(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr) , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) {
-      asn_debug      = 1;
-      asn1_xer_print = 2;
-    } else {
-      asn_debug      = 0;
-      asn1_xer_print = 0;
-    }
-#endif */
 
+  /*#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
+      if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
+        asn_debug      = 0;
+        asn1_xer_print = 0;
+      } else if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) {
+        asn_debug      = 1;
+        asn1_xer_print = 1;
+      } else if (strcasecmp(*(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr) , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) {
+        asn_debug      = 1;
+        asn1_xer_print = 2;
+      } else {
+        asn_debug      = 0;
+        asn1_xer_print = 0;
+      }
+  #endif */
   AssertFatal(i < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt,
               "Failed to parse config file %s, %uth attribute %s \n",
               RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
@@ -2307,6 +2343,14 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
         // search if in active list
         for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) {
           if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) {
+            paramdef_t PLMNParams[] = PLMNPARAMS_DESC;
+            paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0};
+            /* map parameter checking array instances to parameter definition array instances */
+            checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
+
+            for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
+              PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
+
             paramdef_t X2Params[]  = X2PARAMS_DESC;
             paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0};
             paramdef_t SCTPParams[]  = SCTPPARAMS_DESC;
@@ -2314,6 +2358,7 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
             /* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */
             /* this is most probably a problem with the config module */
             char aprefix[MAX_OPTNAME_SIZE*80 + 8];
+            sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
             /* Some default/random parameters */
             X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id;
 
@@ -2328,58 +2373,62 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
             }
 
             X2AP_REGISTER_ENB_REQ (msg_p).eNB_name         = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
-            X2AP_REGISTER_ENB_REQ (msg_p).tac              = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].strptr));
-            X2AP_REGISTER_ENB_REQ (msg_p).mcc              = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX].strptr));
-            X2AP_REGISTER_ENB_REQ (msg_p).mnc              = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
-            X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
-            AssertFatal((X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 2) ||
-                        (X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 3),
-                        "BAD MNC DIGIT LENGTH %d",
-                        X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length);
+            X2AP_REGISTER_ENB_REQ (msg_p).tac              = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
+            config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
+
+            if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
+              AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
+                          PLMNParamList.numelt);
+
+            if (PLMNParamList.numelt > 1)
+              LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n");
+
+            X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
+            X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
+            X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr;
+            AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3
+                        || X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100,
+                        "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
+                        X2AP_REGISTER_ENB_REQ(msg_p).mnc);
 
             /* CC params */
-            sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k);
             config_getlist(&CCsParamList, NULL, 0, aprefix);
 
             X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt;
 
             if (CCsParamList.numelt > 0) {
-
               //char ccspath[MAX_OPTNAME_SIZE*2 + 16];
-
               for (J = 0; J < CCsParamList.numelt ; J++) {
-
                 sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J);
                 config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix);
-
                 X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = eutra_band;
-	        X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) downlink_frequency;
-	        X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) uplink_frequency_offset;
-	        X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= Nid_cell;
+                X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) downlink_frequency;
+                X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) uplink_frequency_offset;
+                X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= Nid_cell;
 
-	        if (Nid_cell>503) {
-	          AssertFatal (0,
-	            "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
-                         RC.config_file_name, k, Nid_cell);
-	        }
+                if (Nid_cell>503) {
+                  AssertFatal (0,
+                               "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
+                               RC.config_file_name, k, Nid_cell);
+                }
 
-	        X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= N_RB_DL;
+                X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= N_RB_DL;
 
-	        if ((N_RB_DL!=6) && (N_RB_DL!=15) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=75) && (N_RB_DL!=100)) {
-	          AssertFatal (0,
-                    "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
-                         RC.config_file_name, k, N_RB_DL);
-	        }
+                if ((N_RB_DL!=6) && (N_RB_DL!=15) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=75) && (N_RB_DL!=100)) {
+                  AssertFatal (0,
+                               "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
+                               RC.config_file_name, k, N_RB_DL);
+                }
 
-	        if (strcmp(frame_type, "FDD") == 0) {
+                if (strcmp(frame_type, "FDD") == 0) {
                   X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD;
-	        } else  if (strcmp(frame_type, "TDD") == 0) {
+                } else  if (strcmp(frame_type, "TDD") == 0) {
                   X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
                 } else {
-	          AssertFatal (0,
-                    "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
-		         RC.config_file_name, k, frame_type);
-	        }
+                  AssertFatal (0,
+                               "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
+                               RC.config_file_name, k, frame_type);
+                }
 
                 X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(eutra_band, downlink_frequency, N_RB_DL);
                 X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(eutra_band, downlink_frequency + uplink_frequency_offset, N_RB_DL);
@@ -2388,11 +2437,9 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 
             sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
             config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix);
-
-            if(X2ParamList.numelt>X2AP_MAX_NB_ENB_IP_ADDRESS) {
-              LOG_E(RRC,"value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n",X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS);
-              exit(1);
-            }
+            AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS,
+                        "value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n",
+                        X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS);
 
             X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0;
 
@@ -2444,39 +2491,31 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
   return 0;
 }
 
-int RCconfig_parallel(void)
-{
+int RCconfig_parallel(void) {
   char *parallel_conf = NULL;
   char *worker_conf   = NULL;
   extern char *parallel_config;
   extern char *worker_config;
-
   paramdef_t ThreadParams[]  = THREAD_CONF_DESC;
   paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0};
-  
   config_getlist( &THREADParamList,NULL,0,NULL);
 
-  if(THREADParamList.numelt>0)
-  {
+  if(THREADParamList.numelt>0) {
     config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL);
     parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr));
-  }
-  else
-  {
+  } else {
     parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT");
   }
-  if(THREADParamList.numelt>0)
-  {
+
+  if(THREADParamList.numelt>0) {
     config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL);
     worker_conf   = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr));
-  }
-  else
-  {
+  } else {
     worker_conf   = strdup("WORKER_ENABLE");
   }
 
-
   if(parallel_config == NULL) set_parallel_conf(parallel_conf);
+
   if(worker_config == NULL)   set_worker_conf(worker_conf);
 
   return 0;
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index fa622ce5d7a88f24d8103bb623c44e7d4d28a7ac..524daac43d12563f6cad5b12d1eee209012fab10 100755
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -185,8 +185,8 @@ typedef enum {
 #define ENB_CONFIG_STRING_CELL_TYPE                     "cell_type"
 #define ENB_CONFIG_STRING_ENB_NAME                      "eNB_name"
 #define ENB_CONFIG_STRING_TRACKING_AREA_CODE            "tracking_area_code"
-#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE           "mobile_country_code"
-#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE           "mobile_network_code"
+#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE_OLD       "mobile_country_code"
+#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD       "mobile_network_code"
 #define ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE        "tr_s_preference"
 #define ENB_CONFIG_STRING_LOCAL_S_IF_NAME               "local_s_if_name"
 #define ENB_CONFIG_STRING_LOCAL_S_ADDRESS               "local_s_address"
@@ -204,9 +204,9 @@ typedef enum {
 {ENB_CONFIG_STRING_ENB_ID,                       NULL,   0,            uptr:NULL,   defintval:0,                 TYPE_UINT,      0},  \
 {ENB_CONFIG_STRING_CELL_TYPE,                    NULL,   0,            strptr:NULL, defstrval:"CELL_MACRO_ENB",  TYPE_STRING,    0},  \
 {ENB_CONFIG_STRING_ENB_NAME,                     NULL,   0,            strptr:NULL, defstrval:"OAIeNodeB",       TYPE_STRING,    0},  \
-{ENB_CONFIG_STRING_TRACKING_AREA_CODE,           NULL,   0,            strptr:NULL, defstrval:"0",               TYPE_STRING,    0},  \
-{ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE,          NULL,   0,            strptr:NULL, defstrval:"0",               TYPE_STRING,    0},  \
-{ENB_CONFIG_STRING_MOBILE_NETWORK_CODE,          NULL,   0,            strptr:NULL, defstrval:"0",               TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_TRACKING_AREA_CODE,           NULL,   0,            uptr:NULL,   defuintval:0,                TYPE_UINT,      0},  \
+{ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE_OLD,      NULL,   0,            strptr:NULL, defstrval:NULL,              TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD,      NULL,   0,            strptr:NULL, defstrval:NULL,              TYPE_STRING,    0},  \
 {ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE,       NULL,   0,            strptr:NULL, defstrval:"local_mac",       TYPE_STRING,    0},  \
 {ENB_CONFIG_STRING_LOCAL_S_IF_NAME,              NULL,   0,            strptr:NULL, defstrval:"lo",              TYPE_STRING,    0},  \
 {ENB_CONFIG_STRING_LOCAL_S_ADDRESS,              NULL,   0,            strptr:NULL, defstrval:"127.0.0.1",       TYPE_STRING,    0},  \
@@ -220,8 +220,8 @@ typedef enum {
 #define ENB_CELL_TYPE_IDX               1
 #define ENB_ENB_NAME_IDX                2
 #define ENB_TRACKING_AREA_CODE_IDX      3
-#define ENB_MOBILE_COUNTRY_CODE_IDX     4
-#define ENB_MOBILE_NETWORK_CODE_IDX     5
+#define ENB_MOBILE_COUNTRY_CODE_IDX_OLD 4
+#define ENB_MOBILE_NETWORK_CODE_IDX_OLD 5
 #define ENB_TRANSPORT_S_PREFERENCE_IDX  6
 #define ENB_LOCAL_S_IF_NAME_IDX         7
 #define ENB_LOCAL_S_ADDRESS_IDX         8
@@ -230,9 +230,56 @@ typedef enum {
 #define ENB_REMOTE_S_PORTC_IDX          11
 #define ENB_LOCAL_S_PORTD_IDX           12
 #define ENB_REMOTE_S_PORTD_IDX          13
+
+#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
+#define ENBPARAMS_CHECK {                                         \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s2 = { config_check_intrange, TRACKING_AREA_CODE_OKRANGE } },\
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
+}
+
 /*-------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------------------------------------------------------------------------------*/		  
 
+/* PLMN ID configuration */
+
+#define ENB_CONFIG_STRING_PLMN_LIST                     "plmn_list"
+
+#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE           "mcc"
+#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE           "mnc"
+#define ENB_CONFIG_STRING_MNC_DIGIT_LENGTH              "mnc_length"
+
+#define ENB_MOBILE_COUNTRY_CODE_IDX     0
+#define ENB_MOBILE_NETWORK_CODE_IDX     1
+#define ENB_MNC_DIGIT_LENGTH            2
+
+#define PLMNPARAMS_DESC {                                                                  \
+/*   optname                              helpstr               paramflags XXXptr     def val          type    numelt */ \
+  {ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, "mobile country code",        0, uptr:NULL, defuintval:1000, TYPE_UINT, 0},    \
+  {ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, "mobile network code",        0, uptr:NULL, defuintval:1000, TYPE_UINT, 0},    \
+  {ENB_CONFIG_STRING_MNC_DIGIT_LENGTH,    "length of the MNC (2 or 3)", 0, uptr:NULL, defuintval:0,    TYPE_UINT, 0},    \
+}
+
+#define MCC_MNC_OKRANGES           {0,999}
+#define MNC_DIGIT_LENGTH_OKVALUES  {2,3}
+
+#define PLMNPARAMS_CHECK {                                           \
+  { .s2 = { config_check_intrange, MCC_MNC_OKRANGES } },             \
+  { .s2 = { config_check_intrange, MCC_MNC_OKRANGES } },             \
+  { .s1 = { config_check_intval,   MNC_DIGIT_LENGTH_OKVALUES, 2 } }, \
+}
+
 
 /* component carries configuration parameters name */
 
@@ -681,6 +728,7 @@ typedef enum {
 #define ENB_CONFIG_STRING_MME_IPV6_ADDRESS              "ipv6"
 #define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE         "active"
 #define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE     "preference"
+#define ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX      "broadcast_plmn_index"
 
 
 /*-------------------------------------------------------------------------------------------------------------------------------------*/
@@ -692,12 +740,14 @@ typedef enum {
 {ENB_CONFIG_STRING_MME_IPV6_ADDRESS,                   NULL,      0,         uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},          \
 {ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE,              NULL,      0,         uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},          \
 {ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE,          NULL,      0,         uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},          \
+{ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX,           NULL,      0,         uptr:NULL,   defintarrayval:NULL,TYPE_UINTARRAY, 6}           \
 }
 
 #define ENB_MME_IPV4_ADDRESS_IDX          0
 #define ENB_MME_IPV6_ADDRESS_IDX          1
 #define ENB_MME_IP_ADDRESS_ACTIVE_IDX     2
 #define ENB_MME_IP_ADDRESS_PREFERENCE_IDX 3
+#define ENB_MME_BROADCAST_PLMN_INDEX      4
 /*---------------------------------------------------------------------------------------------------------------------------------------*/
 
 /* X2 configuration parameters section name */
diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
index 5e07d9e936243594e6aaedf9ac8bc17b6944d9d7..f75d73224e534251eac09ce94bfb82e84a500343 100644
--- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
@@ -345,8 +345,13 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,
 {
 
   //  SystemInformation_t systemInformation;
-  PLMN_IdentityInfo_t PLMN_identity_info;
-  MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3];
+#if defined(ENABLE_ITTI)
+  int num_plmn = configuration->num_plmn;
+#else
+  int num_plmn = 1;
+#endif
+  PLMN_IdentityInfo_t PLMN_identity_info[num_plmn];
+  MCC_MNC_Digit_t dummy_mcc[num_plmn][3], dummy_mnc[num_plmn][3];
   asn_enc_rval_t enc_rval;
   SchedulingInfo_t schedulingInfo;
   SIB_Type_t sib_type;
@@ -354,6 +359,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,
   uint8_t *buffer                      = carrier->SIB1;
   BCCH_DL_SCH_Message_t *bcch_message  = &carrier->siblock1;
   SystemInformationBlockType1_t **sib1 = &carrier->sib1;
+  int i;
 
   
   memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_t));
@@ -363,66 +369,67 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,
 
   *sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1;
 
-  memset(&PLMN_identity_info,0,sizeof(PLMN_IdentityInfo_t));
+  memset(PLMN_identity_info,0,num_plmn * sizeof(PLMN_IdentityInfo_t));
   memset(&schedulingInfo,0,sizeof(SchedulingInfo_t));
   memset(&sib_type,0,sizeof(SIB_Type_t));
 
+  /* as per TS 36.311, up to 6 PLMN_identity_info are allowed in list -> add one by one */
+  for (i = 0; i < configuration->num_plmn; ++i) {
+    PLMN_identity_info[i].plmn_Identity.mcc = CALLOC(1,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc));
+    memset(PLMN_identity_info[i].plmn_Identity.mcc,0,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc));
 
-
-  PLMN_identity_info.plmn_Identity.mcc = CALLOC(1,sizeof(*PLMN_identity_info.plmn_Identity.mcc));
-  memset(PLMN_identity_info.plmn_Identity.mcc,0,sizeof(*PLMN_identity_info.plmn_Identity.mcc));
-
-  asn_set_empty(&PLMN_identity_info.plmn_Identity.mcc->list);//.size=0;
+    asn_set_empty(&PLMN_identity_info[i].plmn_Identity.mcc->list);//.size=0;
 
 #if defined(ENABLE_ITTI)
-  dummy_mcc[0] = (configuration->mcc / 100) % 10;
-  dummy_mcc[1] = (configuration->mcc / 10) % 10;
-  dummy_mcc[2] = (configuration->mcc / 1) % 10;
+    dummy_mcc[i][0] = (configuration->mcc[i] / 100) % 10;
+    dummy_mcc[i][1] = (configuration->mcc[i] / 10) % 10;
+    dummy_mcc[i][2] = (configuration->mcc[i] / 1) % 10;
 #else
-  dummy_mcc[0] = 0;
-  dummy_mcc[1] = 0;
-  dummy_mcc[2] = 1;
+    dummy_mcc[i][0] = 0;
+    dummy_mcc[i][1] = 0;
+    dummy_mcc[i][2] = 1;
 #endif
-  ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mcc->list,&dummy_mcc[0]);
-  ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mcc->list,&dummy_mcc[1]);
-  ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mcc->list,&dummy_mcc[2]);
+    ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][0]);
+    ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][1]);
+    ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][2]);
 
-  PLMN_identity_info.plmn_Identity.mnc.list.size=0;
-  PLMN_identity_info.plmn_Identity.mnc.list.count=0;
+    PLMN_identity_info[i].plmn_Identity.mnc.list.size=0;
+    PLMN_identity_info[i].plmn_Identity.mnc.list.count=0;
 #if defined(ENABLE_ITTI)
 
-  if (configuration->mnc >= 100) {
-    dummy_mnc[0] = (configuration->mnc / 100) % 10;
-    dummy_mnc[1] = (configuration->mnc / 10) % 10;
-    dummy_mnc[2] = (configuration->mnc / 1) % 10;
-  } else {
-    if (configuration->mnc_digit_length == 2) {
-      dummy_mnc[0] = (configuration->mnc / 10) % 10;
-      dummy_mnc[1] = (configuration->mnc / 1) % 10;
-      dummy_mnc[2] = 0xf;
+    if (configuration->mnc[i] >= 100) {
+      dummy_mnc[i][0] = (configuration->mnc[i] / 100) % 10;
+      dummy_mnc[i][1] = (configuration->mnc[i] / 10) % 10;
+      dummy_mnc[i][2] = (configuration->mnc[i] / 1) % 10;
     } else {
-      dummy_mnc[0] = (configuration->mnc / 100) % 100;
-      dummy_mnc[1] = (configuration->mnc / 10) % 10;
-      dummy_mnc[2] = (configuration->mnc / 1) % 10;
+      if (configuration->mnc_digit_length[i] == 2) {
+        dummy_mnc[i][0] = (configuration->mnc[i] / 10) % 10;
+        dummy_mnc[i][1] = (configuration->mnc[i] / 1) % 10;
+        dummy_mnc[i][2] = 0xf;
+      } else {
+        dummy_mnc[i][0] = (configuration->mnc[i] / 100) % 100;
+        dummy_mnc[i][1] = (configuration->mnc[i] / 10) % 10;
+        dummy_mnc[i][2] = (configuration->mnc[i] / 1) % 10;
+      }
     }
-  }
 
 #else
-  dummy_mnc[0] = 0;
-  dummy_mnc[1] = 1;
-  dummy_mnc[2] = 0xf;
+    dummy_mnc[i][0] = 0;
+    dummy_mnc[i][1] = 1;
+    dummy_mnc[i][2] = 0xf;
 #endif
-  ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mnc.list,&dummy_mnc[0]);
-  ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mnc.list,&dummy_mnc[1]);
+    ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][0]);
+    ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][1]);
 
-  if (dummy_mnc[2] != 0xf) {
-    ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mnc.list,&dummy_mnc[2]);
-  }
+    if (dummy_mnc[i][2] != 0xf) {
+      ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][2]);
+    }
 
-  //assign_enum(&PLMN_identity_info.cellReservedForOperatorUse,PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved);
-  PLMN_identity_info.cellReservedForOperatorUse=PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved;
+    //assign_enum(&PLMN_identity_info.cellReservedForOperatorUse,PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved);
+    PLMN_identity_info[i].cellReservedForOperatorUse=PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved;
 
-  ASN_SEQUENCE_ADD(&(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list,&PLMN_identity_info);
+    ASN_SEQUENCE_ADD(&(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list,&PLMN_identity_info[i]);
+  }
 
 
   // 16 bits
@@ -1670,10 +1677,7 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin
   rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension=CALLOC(1,
       sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension));
 
-  if(usim_test == 0)
-      rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 2;
-  else
-      rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 1;
+  rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 1;
 
   rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME =
     NULL;//calloc(1,sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME));
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index e21cb9255a6a0cc7cb275b3c21230383ae987820..ae87075489f970602c2e34f0e04492368ef7a97d 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -699,13 +699,6 @@ typedef struct eNB_RRC_INST_s {
 #if defined(ENABLE_ITTI)
   RrcConfigurationReq configuration;
 #endif
-  // other PLMN parameters
-  /// Mobile country code
-  int mcc;
-  /// Mobile network code
-  int mnc;
-  /// number of mnc digits
-  int mnc_digit_length;
 
   // other RAN parameters
   int srb1_timer_poll_retransmit;
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index 7d242286023985c1002562d25feb32040285603e..d225b6eae0a48c77ba4bf580e6dda295a84347c0 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -755,17 +755,20 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
             ue_context_pP->ue_context.rnti);
       }
 
+      /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */
+      int selected_plmn_identity = rrcConnectionSetupComplete->selectedPLMN_Identity - 1;
+      S1AP_NAS_FIRST_REQ(message_p).selected_plmn_identity = selected_plmn_identity;
+
       if (rrcConnectionSetupComplete->registeredMME != NULL) {
         /* Fill GUMMEI */
         struct RegisteredMME *r_mme = rrcConnectionSetupComplete->registeredMME;
-        //int selected_plmn_identity = rrcConnectionSetupComplete->selectedPLMN_Identity;
 
         S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei;
 
         if (r_mme->plmn_Identity != NULL) {
           if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) {
             /* Use first indicated PLMN MCC if it is defined */
-            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[0];
+            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity];
             LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
                 ctxt_pP->module_id,
                 S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc,
@@ -774,20 +777,16 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
 
           if (r_mme->plmn_Identity->mnc.list.count > 0) {
             /* Use first indicated PLMN MNC if it is defined */
-            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[0];
+            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity];
             LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n",
                   ctxt_pP->module_id,
                   S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
                   ue_context_pP->ue_context.rnti);
           }
         } else {
-	  //          const Enb_properties_array_t   *enb_properties_p  = NULL;
-	  //          enb_properties_p = enb_config_get();
-
-          // actually the eNB configuration contains only one PLMN (can be up to 6)
-          S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = rrc->mcc;
-          S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = rrc->mnc;
-          S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = rrc->mnc_digit_length;
+          S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mcc = rrc->configuration.mcc[selected_plmn_identity];
+          S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc = rrc->configuration.mnc[selected_plmn_identity];
+          S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc_len = rrc->configuration.mnc_digit_length[selected_plmn_identity];
         }
 
         S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code     = BIT_STRING_to_uint8 (&r_mme->mmec);
@@ -1850,125 +1849,127 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance
   for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) {
        LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc,
              S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]);
-      if (RC.rrc[instance]->configuration.mcc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc
-          && RC.rrc[instance]->configuration.mnc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
-          && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) {
-          for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-              lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
-              /* get nB from configuration */
-              /* get default DRX cycle from configuration */
-              Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id];
-              if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) {
-                  continue;
-              }
-              Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx;
-              /* set T = min(Tc,Tue) */
-              T = Tc < Tue ? Ttab[Tc] : Ttab[Tue];
-              /* set pcch_nB = PCCH-Config->nB */
-              pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id];
-              switch (pcch_nB) {
-                case PCCH_Config__nB_fourT:
-                    Ns = 4;
-                    break;
-                case PCCH_Config__nB_twoT:
-                    Ns = 2;
-                    break;
-                default:
-                    Ns = 1;
-                    break;
-              }
-              /* set N = min(T,nB) */
-              if (pcch_nB > PCCH_Config__nB_oneT) {
-                switch (pcch_nB) {
-                case PCCH_Config__nB_halfT:
-                  N = T/2;
-                  break;
-                case PCCH_Config__nB_quarterT:
-                  N = T/4;
-                  break;
-                case PCCH_Config__nB_oneEighthT:
-                  N = T/8;
-                  break;
-                case PCCH_Config__nB_oneSixteenthT:
-                  N = T/16;
-                  break;
-                case PCCH_Config__nB_oneThirtySecondT:
-                  N = T/32;
-                  break;
-                default:
-                  /* pcch_nB error */
-                  LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND:  pcch_nB error (pcch_nB %d) \n",
-                      instance, pcch_nB);
-                  return (-1);
-                }
-              } else {
-                N = T;
-              }
-
-              /* insert data to UE_PF_PO or update data in UE_PF_PO */
-              pthread_mutex_lock(&ue_pf_po_mutex);
-              uint16_t i = 0;
-              for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
-                if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value))
-                    || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) {
-                    /* set T = min(Tc,Tue) */
-                    UE_PF_PO[CC_id][i].T = T;
-                    /* set UE_ID */
-                    UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value;
-                    /* calculate PF and PO */
-                    /* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */
-                    UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N);
-                    /* set PO */
-                    /* i_s = floor(UE_ID/N) mod Ns */
-                    i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns);
-                    if (Ns == 1) {
-                        UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0;
-                    } else if (Ns==2) {
-                        UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s);
-                    } else if (Ns==4) {
-                        UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1)));
+      for (uint8_t j = 0; j < RC.rrc[instance]->configuration.num_plmn; j++) {
+          if (RC.rrc[instance]->configuration.mcc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc
+              && RC.rrc[instance]->configuration.mnc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
+              && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) {
+              for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+                  lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
+                  /* get nB from configuration */
+                  /* get default DRX cycle from configuration */
+                  Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id];
+                  if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) {
+                      continue;
+                  }
+                  Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx;
+                  /* set T = min(Tc,Tue) */
+                  T = Tc < Tue ? Ttab[Tc] : Ttab[Tue];
+                  /* set pcch_nB = PCCH-Config->nB */
+                  pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id];
+                  switch (pcch_nB) {
+                    case PCCH_Config__nB_fourT:
+                        Ns = 4;
+                        break;
+                    case PCCH_Config__nB_twoT:
+                        Ns = 2;
+                        break;
+                    default:
+                        Ns = 1;
+                        break;
+                  }
+                  /* set N = min(T,nB) */
+                  if (pcch_nB > PCCH_Config__nB_oneT) {
+                    switch (pcch_nB) {
+                    case PCCH_Config__nB_halfT:
+                      N = T/2;
+                      break;
+                    case PCCH_Config__nB_quarterT:
+                      N = T/4;
+                      break;
+                    case PCCH_Config__nB_oneEighthT:
+                      N = T/8;
+                      break;
+                    case PCCH_Config__nB_oneSixteenthT:
+                      N = T/16;
+                      break;
+                    case PCCH_Config__nB_oneThirtySecondT:
+                      N = T/32;
+                      break;
+                    default:
+                      /* pcch_nB error */
+                      LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND:  pcch_nB error (pcch_nB %d) \n",
+                          instance, pcch_nB);
+                      return (-1);
                     }
-                    if (UE_PF_PO[CC_id][i].enable_flag == TRUE) {
-                        //paging exist UE log
-                        LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
-                    } else {
-                        /* set enable_flag */
-                        UE_PF_PO[CC_id][i].enable_flag = TRUE;
-                        //paging new UE log
-                        LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
+                  } else {
+                    N = T;
+                  }
+
+                  /* insert data to UE_PF_PO or update data in UE_PF_PO */
+                  pthread_mutex_lock(&ue_pf_po_mutex);
+                  uint8_t i = 0;
+                  for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+                    if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value))
+                        || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) {
+                        /* set T = min(Tc,Tue) */
+                        UE_PF_PO[CC_id][i].T = T;
+                        /* set UE_ID */
+                        UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value;
+                        /* calculate PF and PO */
+                        /* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */
+                        UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N);
+                        /* set PO */
+                        /* i_s = floor(UE_ID/N) mod Ns */
+                        i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns);
+                        if (Ns == 1) {
+                            UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0;
+                        } else if (Ns==2) {
+                            UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s);
+                        } else if (Ns==4) {
+                            UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1)));
+                        }
+                        if (UE_PF_PO[CC_id][i].enable_flag == TRUE) {
+                            //paging exist UE log
+                            LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
+                        } else {
+                            /* set enable_flag */
+                            UE_PF_PO[CC_id][i].enable_flag = TRUE;
+                            //paging new UE log
+                            LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
+                        }
+                        break;
                     }
-                    break;
-                }
-              }
-              pthread_mutex_unlock(&ue_pf_po_mutex);
-
-              uint32_t length;
-              uint8_t buffer[RRC_BUF_SIZE];
-              uint8_t *message_buffer;
-              /* Transfer data to PDCP */
-              MessageDef *message_p;
-              message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ);
-              /* Create message for PDCP (DLInformationTransfer_t) */
-              length = do_Paging (instance,
-                                  buffer,
-                                  S1AP_PAGING_IND(msg_p).ue_paging_identity,
-                                  S1AP_PAGING_IND(msg_p).cn_domain);
-              if(length == -1)
-              {
-                LOG_I(RRC, "do_Paging error");
-                return -1;
+                  }
+                  pthread_mutex_unlock(&ue_pf_po_mutex);
+
+                  uint32_t length;
+                  uint8_t buffer[RRC_BUF_SIZE];
+                  uint8_t *message_buffer;
+                  /* Transfer data to PDCP */
+                  MessageDef *message_p;
+                  message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ);
+                  /* Create message for PDCP (DLInformationTransfer_t) */
+                  length = do_Paging (instance,
+                                      buffer,
+                                      S1AP_PAGING_IND(msg_p).ue_paging_identity,
+                                      S1AP_PAGING_IND(msg_p).cn_domain);
+                  if(length == -1)
+                  {
+                    LOG_I(RRC, "do_Paging error");
+                    return -1;
+                  }
+                  message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length);
+                  /* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */
+                  memcpy (message_buffer, buffer, length);
+                  RRC_PCCH_DATA_REQ (message_p).sdu_size  = length;
+                  RRC_PCCH_DATA_REQ (message_p).sdu_p     = message_buffer;
+                  RRC_PCCH_DATA_REQ (message_p).mode      = PDCP_TRANSMISSION_MODE_TRANSPARENT;  /* not used */
+                  RRC_PCCH_DATA_REQ (message_p).rnti      = P_RNTI;
+                  RRC_PCCH_DATA_REQ (message_p).ue_index  = i;
+                  RRC_PCCH_DATA_REQ (message_p).CC_id  = CC_id;
+                  LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length);
+                  itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p);
               }
-              message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length);
-              /* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */
-              memcpy (message_buffer, buffer, length);
-              RRC_PCCH_DATA_REQ (message_p).sdu_size  = length;
-              RRC_PCCH_DATA_REQ (message_p).sdu_p     = message_buffer;
-              RRC_PCCH_DATA_REQ (message_p).mode      = PDCP_TRANSMISSION_MODE_TRANSPARENT;  /* not used */
-              RRC_PCCH_DATA_REQ (message_p).rnti      = P_RNTI;
-              RRC_PCCH_DATA_REQ (message_p).ue_index  = i;
-              RRC_PCCH_DATA_REQ (message_p).CC_id  = CC_id;
-              LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length);
-              itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p);
           }
       }
   }
diff --git a/openair2/UTIL/MEM/mem_block.c b/openair2/UTIL/MEM/mem_block.c
index 6d1a289f08ea4ac93583a8fb910d6999ac565382..0150ef00cdaf208120828c54840d80545b6908ca 100644
--- a/openair2/UTIL/MEM/mem_block.c
+++ b/openair2/UTIL/MEM/mem_block.c
@@ -61,6 +61,7 @@ uint32_t             counters[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 /*
  * initialize all ures
  */
+extern mem_pool  *memBlockVar;
 void           *
 pool_buffer_init (void)
 {
@@ -68,6 +69,7 @@ pool_buffer_init (void)
 
   uint32_t             index, mb_index, pool_index;
   mem_pool       *memory = (mem_pool *) &mem_block_var;
+  memBlockVar=malloc(sizeof(mem_pool));
   int             pool_sizes[14] = { MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB1_NB_BLOCKS,
                                      MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS,
                                      MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS,
diff --git a/openair2/UTIL/MEM/mem_block.h b/openair2/UTIL/MEM/mem_block.h
index 861e4a8ea469598c034913959c7f6922a9ebef98..18ded1a5990da3297c9abde96dc8615443fe329c 100644
--- a/openair2/UTIL/MEM/mem_block.h
+++ b/openair2/UTIL/MEM/mem_block.h
@@ -178,7 +178,8 @@ typedef struct {
 
 } mem_pool;
 
-mem_pool  mem_block_var;
+mem_pool  *memBlockVar;
+#define mem_block_var (*memBlockVar)
 
 #ifdef __cplusplus
 }
diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c
index a617963686d054d10842e55c78ecf8c19156f9fc..3edc5be0d5f42e66758dab67e42789d8edcc9d49 100644
--- a/openair3/S1AP/s1ap_eNB.c
+++ b/openair3/S1AP/s1ap_eNB.c
@@ -97,7 +97,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
                                   net_ip_address_t    *mme_ip_address,
                                   net_ip_address_t    *local_ip_addr,
                                   uint16_t             in_streams,
-                                  uint16_t             out_streams)
+                                  uint16_t             out_streams,
+                                  uint8_t              broadcast_plmn_num,
+                                  uint8_t              broadcast_plmn_index[PLMN_LIST_MAX_SIZE])
 {
   MessageDef                 *message_p                   = NULL;
   sctp_new_association_req_t *sctp_new_association_req_p  = NULL;
@@ -126,8 +128,8 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
          sizeof(*local_ip_addr));
 
   S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance);
-
-  mme = s1ap_eNB_get_MME_from_instance(instance_p);
+	      
+  mme = NULL;
 
   if ( mme == NULL ) {
 
@@ -139,6 +141,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
     sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
 
     s1ap_mme_data_p->assoc_id          = -1;
+    s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num;
+    for (int i = 0; i < broadcast_plmn_num; ++i)
+      s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
     s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
 
     STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
@@ -190,10 +195,14 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
     /* Checks if it is a retry on the same eNB */
     DevCheck(new_instance->eNB_id == s1ap_register_eNB->eNB_id, new_instance->eNB_id, s1ap_register_eNB->eNB_id, 0);
     DevCheck(new_instance->cell_type == s1ap_register_eNB->cell_type, new_instance->cell_type, s1ap_register_eNB->cell_type, 0);
+    DevCheck(new_instance->num_plmn == s1ap_register_eNB->num_plmn, new_instance->num_plmn, s1ap_register_eNB->num_plmn, 0);
     DevCheck(new_instance->tac == s1ap_register_eNB->tac, new_instance->tac, s1ap_register_eNB->tac, 0);
-    DevCheck(new_instance->mcc == s1ap_register_eNB->mcc, new_instance->mcc, s1ap_register_eNB->mcc, 0);
-    DevCheck(new_instance->mnc == s1ap_register_eNB->mnc, new_instance->mnc, s1ap_register_eNB->mnc, 0);
-    DevCheck(new_instance->mnc_digit_length == s1ap_register_eNB->mnc_digit_length, new_instance->mnc_digit_length, s1ap_register_eNB->mnc_digit_length, 0);
+    for (int i = 0; i < new_instance->num_plmn; i++)
+    {
+      DevCheck(new_instance->mcc[i] == s1ap_register_eNB->mcc[i], new_instance->mcc[i], s1ap_register_eNB->mcc[i], 0);
+      DevCheck(new_instance->mnc[i] == s1ap_register_eNB->mnc[i], new_instance->mnc[i], s1ap_register_eNB->mnc[i], 0);
+      DevCheck(new_instance->mnc_digit_length[i] == s1ap_register_eNB->mnc_digit_length[i], new_instance->mnc_digit_length[i], s1ap_register_eNB->mnc_digit_length[i], 0);
+    }
     DevCheck(new_instance->default_drx == s1ap_register_eNB->default_drx, new_instance->default_drx, s1ap_register_eNB->default_drx, 0);
   } else {
     new_instance = calloc(1, sizeof(s1ap_eNB_instance_t));
@@ -208,9 +217,13 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
     new_instance->eNB_id           = s1ap_register_eNB->eNB_id;
     new_instance->cell_type        = s1ap_register_eNB->cell_type;
     new_instance->tac              = s1ap_register_eNB->tac;
-    new_instance->mcc              = s1ap_register_eNB->mcc;
-    new_instance->mnc              = s1ap_register_eNB->mnc;
-    new_instance->mnc_digit_length = s1ap_register_eNB->mnc_digit_length;
+    for (int i = 0; i < s1ap_register_eNB->num_plmn; i++)
+    {
+      new_instance->mcc[i]              = s1ap_register_eNB->mcc[i];
+      new_instance->mnc[i]              = s1ap_register_eNB->mnc[i];
+      new_instance->mnc_digit_length[i] = s1ap_register_eNB->mnc_digit_length[i];
+    }
+    new_instance->num_plmn         = s1ap_register_eNB->num_plmn;
     new_instance->default_drx      = s1ap_register_eNB->default_drx;
 
     /* Add the new instance to the list of eNB (meaningfull in virtual mode) */
@@ -231,7 +244,9 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
                           &s1ap_register_eNB->mme_ip_address[index],
                           &s1ap_register_eNB->enb_ip_address,
                           s1ap_register_eNB->sctp_in_streams,
-                          s1ap_register_eNB->sctp_out_streams);
+                          s1ap_register_eNB->sctp_out_streams,
+                          s1ap_register_eNB->broadcast_plmn_num[index],
+                          s1ap_register_eNB->broadcast_plmn_index[index]);
   }
 }
 
@@ -459,7 +474,9 @@ static int s1ap_eNB_generate_s1_setup_request(
   ie->id = S1AP_ProtocolIE_ID_id_Global_ENB_ID;
   ie->criticality = S1AP_Criticality_reject;
   ie->value.present = S1AP_S1SetupRequestIEs__value_PR_Global_ENB_ID;
-  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+  MCC_MNC_TO_PLMNID(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[0]],
+                    instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[0]],
+                    instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[0]],
                     &ie->value.choice.Global_ENB_ID.pLMNidentity);
   ie->value.choice.Global_ENB_ID.eNB_ID.present = S1AP_ENB_ID_PR_macroENB_ID;
   MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
@@ -490,9 +507,14 @@ static int s1ap_eNB_generate_s1_setup_request(
     ta = (S1AP_SupportedTAs_Item_t *)calloc(1, sizeof(S1AP_SupportedTAs_Item_t));
     INT16_TO_OCTET_STRING(instance_p->tac, &ta->tAC);
     {
-      plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t));
-      MCC_MNC_TO_TBCD(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
-      ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn);
+      for (int i = 0; i < s1ap_mme_data_p->broadcast_plmn_num; ++i) {
+        plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t));
+        MCC_MNC_TO_TBCD(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[i]],
+                        instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[i]],
+                        instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[i]],
+                        plmn);
+        ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn);
+      }
     }
     ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAs.list, ta);
   }
diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h
index 11e64703ec1625538daf17f375265e7380c63e85..5bffa0df0cb4c123bef19d44b978cfca7738c8fe 100644
--- a/openair3/S1AP/s1ap_eNB_defs.h
+++ b/openair3/S1AP/s1ap_eNB_defs.h
@@ -154,6 +154,11 @@ typedef struct s1ap_eNB_mme_data_s {
   /* SCTP association id */
   int32_t  assoc_id;
 
+  /* This is served PLMN IDs communicated to the MME via an index over the
+   * MCC/MNC array in s1ap_eNB_instance */
+  uint8_t  broadcast_plmn_num;
+  uint8_t  broadcast_plmn_index[PLMN_LIST_MAX_SIZE];
+
   /* Only meaningfull in virtual mode */
   struct s1ap_eNB_instance_s *s1ap_eNB_instance;
 } s1ap_eNB_mme_data_t;
@@ -198,9 +203,10 @@ typedef struct s1ap_eNB_instance_s {
   /* Mobile Country Code
    * Mobile Network Code
    */
-  uint16_t  mcc;
-  uint16_t  mnc;
-  uint8_t   mnc_digit_length;
+  uint16_t  mcc[PLMN_LIST_MAX_SIZE];
+  uint16_t  mnc[PLMN_LIST_MAX_SIZE];
+  uint8_t   mnc_digit_length[PLMN_LIST_MAX_SIZE];
+  uint8_t   num_plmn;
 
   /* Default Paging DRX of the eNB as defined in TS 36.304 */
   paging_drx_t default_drx;
diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c
index ebd5bab4fdd8e1b80ec8a61025fafac4501c19ed..80266a4d9ca5546766d0bcbfc81e702f8f6899f9 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c
@@ -81,6 +81,16 @@ int s1ap_eNB_handle_nas_first_req(
                    instance_p,
                    s1ap_nas_first_req_p->establishment_cause,
                    s1ap_nas_first_req_p->ue_identity.gummei);
+    if (mme_desc_p) {
+      S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through GUMMEI MCC %d MNC %d MMEGI %d MMEC %d\n",
+                instance,
+                mme_desc_p->mme_name,
+                mme_desc_p->assoc_id,
+                s1ap_nas_first_req_p->ue_identity.gummei.mcc,
+                s1ap_nas_first_req_p->ue_identity.gummei.mnc,
+                s1ap_nas_first_req_p->ue_identity.gummei.mme_group_id,
+                s1ap_nas_first_req_p->ue_identity.gummei.mme_code);
+    }
   }
 
   if (mme_desc_p == NULL) {
@@ -89,18 +99,53 @@ int s1ap_eNB_handle_nas_first_req(
       mme_desc_p = s1ap_eNB_nnsf_select_mme_by_mme_code(
                      instance_p,
                      s1ap_nas_first_req_p->establishment_cause,
+                     s1ap_nas_first_req_p->selected_plmn_identity,
                      s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code);
+      if (mme_desc_p) {
+        S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through S-TMSI MMEC %d and selected PLMN Identity index %d MCC %d MNC %d\n",
+                  instance,
+                  mme_desc_p->mme_name,
+                  mme_desc_p->assoc_id,
+                  s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code,
+                  s1ap_nas_first_req_p->selected_plmn_identity,
+                  instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity],
+                  instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]);
+      }
+    }
+  }
+
+  if (mme_desc_p == NULL) {
+    /* Select MME based on the selected PLMN identity, received through RRC
+     * Connection Setup Complete */
+    mme_desc_p = s1ap_eNB_nnsf_select_mme_by_plmn_id(
+                   instance_p,
+                   s1ap_nas_first_req_p->establishment_cause,
+                   s1ap_nas_first_req_p->selected_plmn_identity);
+    if (mme_desc_p) {
+      S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n",
+                instance,
+                mme_desc_p->mme_name,
+                mme_desc_p->assoc_id,
+                s1ap_nas_first_req_p->selected_plmn_identity,
+                instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity],
+                instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]);
     }
   }
 
   if (mme_desc_p == NULL) {
     /*
-     * If no MME corresponds to the GUMMEI or the s-TMSI, selects the MME with the
-     * highest capacity.
+     * If no MME corresponds to the GUMMEI, the s-TMSI, or the selected PLMN
+     * identity, selects the MME with the highest capacity.
      */
     mme_desc_p = s1ap_eNB_nnsf_select_mme(
                    instance_p,
                    s1ap_nas_first_req_p->establishment_cause);
+    if (mme_desc_p) {
+      S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n",
+                instance,
+                mme_desc_p->mme_name,
+                mme_desc_p->assoc_id);
+    }
   }
 
   if (mme_desc_p == NULL) {
@@ -124,6 +169,7 @@ int s1ap_eNB_handle_nas_first_req(
   ue_desc_p->mme_ref       = mme_desc_p;
   ue_desc_p->ue_initial_id = s1ap_nas_first_req_p->ue_initial_id;
   ue_desc_p->eNB_instance  = instance_p;
+  ue_desc_p->selected_plmn_identity = s1ap_nas_first_req_p->selected_plmn_identity;
 
   do {
     struct s1ap_eNB_ue_context_s *collision_p;
@@ -172,9 +218,9 @@ int s1ap_eNB_handle_nas_first_req(
   ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TAI;
   /* Assuming TAI is the TAI from the cell */
   INT16_TO_OCTET_STRING(instance_p->tac, &ie->value.choice.TAI.tAC);
-  MCC_MNC_TO_PLMNID(instance_p->mcc,
-                    instance_p->mnc,
-                    instance_p->mnc_digit_length,
+  MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity],
+                    instance_p->mnc[ue_desc_p->selected_plmn_identity],
+                    instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity],
                     &ie->value.choice.TAI.pLMNidentity);
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
@@ -191,9 +237,9 @@ int s1ap_eNB_handle_nas_first_req(
   MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,
                                 0, // Cell ID
                                 &ie->value.choice.EUTRAN_CGI.cell_ID);
-  MCC_MNC_TO_TBCD(instance_p->mcc,
-                  instance_p->mnc,
-                  instance_p->mnc_digit_length,
+  MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity],
+                  instance_p->mnc[ue_desc_p->selected_plmn_identity],
+                  instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity],
                   &ie->value.choice.EUTRAN_CGI.pLMNidentity);
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
@@ -608,9 +654,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_
   ie->criticality = S1AP_Criticality_ignore;
   ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI;
   MCC_MNC_TO_PLMNID(
-    s1ap_eNB_instance_p->mcc,
-    s1ap_eNB_instance_p->mnc,
-    s1ap_eNB_instance_p->mnc_digit_length,
+    s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity],
+    s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity],
+    s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity],
     &ie->value.choice.EUTRAN_CGI.pLMNidentity);
   //#warning "TODO get cell id from RRC"
   MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id,
@@ -624,9 +670,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_
   ie->criticality = S1AP_Criticality_ignore;
   ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_TAI;
   MCC_MNC_TO_PLMNID(
-    s1ap_eNB_instance_p->mcc,
-    s1ap_eNB_instance_p->mnc,
-    s1ap_eNB_instance_p->mnc_digit_length,
+    s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity],
+    s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity],
+    s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity],
     &ie->value.choice.TAI.pLMNidentity);
   TAC_TO_ASN1(s1ap_eNB_instance_p->tac, &ie->value.choice.TAI.tAC);
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c
index 8b7d65cb011194b3846dea521bf0e6bcd0c4bd89..63dc92b5e260e33c82a3dd076788b4761b1d763c 100644
--- a/openair3/S1AP/s1ap_eNB_nnsf.c
+++ b/openair3/S1AP/s1ap_eNB_nnsf.c
@@ -90,9 +90,9 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t       *instance_p,
 }
 
 struct s1ap_eNB_mme_data_s *
-s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t       *instance_p,
-                                     rrc_establishment_cause_t  cause,
-                                     uint8_t                    mme_code)
+s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t       *instance_p,
+                                    rrc_establishment_cause_t  cause,
+                                    int                        selected_plmn_identity)
 {
   struct s1ap_eNB_mme_data_s *mme_data_p = NULL;
   struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL;
@@ -100,7 +100,7 @@ s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t       *instance_p,
 
   RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
     struct served_gummei_s *gummei_p = NULL;
-
+    struct plmn_identity_s *served_plmn_p = NULL;
     if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) {
       /* The association between MME and eNB is not ready for the moment,
        * go to the next known MME.
@@ -135,30 +135,106 @@ s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t       *instance_p,
       }
     }
 
+    /* Looking for served GUMMEI PLMN Identity selected matching the one provided by the UE */
+    STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) {
+      STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
+        if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
+            (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
+          break;
+        }
+      }
+      /* if found, we can stop the outer loop, too */
+      if (served_plmn_p) break;
+    }
+    /* if we didn't find such a served PLMN, go on with the next MME */
+    if (!served_plmn_p) continue;
+
     if (current_capacity < mme_data_p->relative_mme_capacity) {
       /* We find a better MME, keep a reference to it */
       current_capacity = mme_data_p->relative_mme_capacity;
       mme_highest_capacity_p = mme_data_p;
     }
+  }
+
+  return mme_highest_capacity_p;
+}
+
+struct s1ap_eNB_mme_data_s *
+s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t       *instance_p,
+                                     rrc_establishment_cause_t  cause,
+                                     int                        selected_plmn_identity,
+                                     uint8_t                    mme_code)
+{
+  struct s1ap_eNB_mme_data_s *mme_data_p = NULL;
+
+  RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
+    struct served_gummei_s *gummei_p = NULL;
+
+    if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) {
+      /* The association between MME and eNB is not ready for the moment,
+       * go to the next known MME.
+       */
+      if (mme_data_p->state == S1AP_ENB_OVERLOAD) {
+        /* MME is overloaded. We have to check the RRC establishment
+         * cause and take decision to the select this MME depending on
+         * the overload state.
+         */
+        if ((cause == RRC_CAUSE_MO_DATA)
+            && (mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_MO_DATA)) {
+          continue;
+        }
+
+        if ((mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_ALL_SIGNALLING)
+            && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) {
+          continue;
+        }
+
+        if ((mme_data_p->overload_state == S1AP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
+            && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA)
+                || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) {
+          continue;
+        }
+
+        /* At this point, the RRC establishment can be handled by the MME
+         * even if it is in overload state.
+         */
+      } else {
+        /* The MME is not overloaded, association is simply not ready. */
+        continue;
+      }
+    }
 
     /* Looking for MME code matching the one provided by NAS */
     STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) {
       struct mme_code_s *mme_code_p = NULL;
+      struct plmn_identity_s   *served_plmn_p = NULL;
 
+      STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
+        if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
+            (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
+          break;
+        }
+      }
       STAILQ_FOREACH(mme_code_p, &gummei_p->mme_codes, next) {
         if (mme_code_p->mme_code == mme_code) {
-          return mme_data_p;
+          break;
         }
       }
+
+      /* The MME matches the parameters provided by the NAS layer ->
+      * the MME is knwown and the association is ready.
+      * Return the reference to the MME to use it for this UE.
+      */
+      if (mme_code_p && served_plmn_p) {
+        return mme_data_p;
+      }
     }
   }
 
-  /* At this point no MME matches the provided GUMMEI. Select the one with the
-   * highest relative capacity.
-   * In case the list of known MME is empty, simply return NULL, that way the RRC
-   * layer should know about it and reject RRC connectivity.
-   */
-  return mme_highest_capacity_p;
+  /* At this point no MME matches the selected PLMN and MME code. In this case,
+   * return NULL. That way the RRC layer should know about it and reject RRC
+   * connectivity. */
+  return NULL;
 }
 
 struct s1ap_eNB_mme_data_s *
@@ -167,8 +243,6 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t       *instance_p,
                                    s1ap_gummei_t                   gummei)
 {
   struct s1ap_eNB_mme_data_s *mme_data_p             = NULL;
-  struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL;
-  uint8_t                     current_capacity       = 0;
 
   RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
     struct served_gummei_s *gummei_p = NULL;
@@ -207,12 +281,6 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t       *instance_p,
       }
     }
 
-    if (current_capacity < mme_data_p->relative_mme_capacity) {
-      /* We find a better MME, keep a reference to it */
-      current_capacity = mme_data_p->relative_mme_capacity;
-      mme_highest_capacity_p = mme_data_p;
-    }
-
     /* Looking for MME gummei matching the one provided by NAS */
     STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) {
       struct served_group_id_s *group_id_p = NULL;
@@ -248,10 +316,8 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t       *instance_p,
     }
   }
 
-  /* At this point no MME matches the provided GUMMEI. Select the one with the
-   * highest relative capacity.
-   * In case the list of known MME is empty, simply return NULL, that way the RRC
-   * layer should know about it and reject RRC connectivity.
-   */
-  return mme_highest_capacity_p;
+  /* At this point no MME matches the provided GUMMEI. In this case, return
+   * NULL. That way the RRC layer should know about it and reject RRC
+   * connectivity. */
+  return NULL;
 }
diff --git a/openair3/S1AP/s1ap_eNB_nnsf.h b/openair3/S1AP/s1ap_eNB_nnsf.h
index 78405f34d1b17e0995cfa70e91c57b98cf087786..706f3ada6ff8380bf7e94d6a541817eb83064e07 100644
--- a/openair3/S1AP/s1ap_eNB_nnsf.h
+++ b/openair3/S1AP/s1ap_eNB_nnsf.h
@@ -26,9 +26,15 @@ struct s1ap_eNB_mme_data_s *
 s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t       *instance_p,
                          rrc_establishment_cause_t  cause);
 
+struct s1ap_eNB_mme_data_s *
+s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t       *instance_p,
+                                    rrc_establishment_cause_t  cause,
+                                    int                        selected_plmn_identity);
+
 struct s1ap_eNB_mme_data_s*
 s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t       *instance_p,
                                      rrc_establishment_cause_t  cause,
+                                     int                        selected_plmn_identity,
                                      uint8_t                    mme_code);
 
 struct s1ap_eNB_mme_data_s*
diff --git a/openair3/S1AP/s1ap_eNB_ue_context.h b/openair3/S1AP/s1ap_eNB_ue_context.h
index d78c6f7f1a97d42e2654de02b5fb921439c98f21..9adbc5fb2c8af9c9e649a4de05b56f329997cc2b 100644
--- a/openair3/S1AP/s1ap_eNB_ue_context.h
+++ b/openair3/S1AP/s1ap_eNB_ue_context.h
@@ -67,6 +67,11 @@ typedef struct s1ap_eNB_ue_context_s {
   /* Reference to MME data this UE is attached to */
   struct s1ap_eNB_mme_data_s *mme_ref;
 
+  /* Signaled by the UE in RRC Connection Setup Complete and used in NAS Uplink
+   * to route NAS messages correctly. 0-based, not 1-based as in TS 36.331
+   * 6.2.2 RRC Connection Setup Complete! */
+  int selected_plmn_identity;
+
   /* Reference to eNB data this UE is attached to */
   s1ap_eNB_instance_t *eNB_instance;
 } s1ap_eNB_ue_context_t;
diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf
index 2571db70a059ac2ec190196b927a159c4a65d540..85cee4dda0685d20afa6b3e6604a45881974d7f1 100644
--- a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf
+++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf
@@ -13,11 +13,8 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "95";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf
index e71e7e03f5d368597401d40916d1724aef9114d6..df06231e4a54706a8725faf4fc760cb1bc04753d 100755
--- a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf
+++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf
@@ -13,10 +13,8 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
-
-    mobile_country_code =  "208";
-    mobile_network_code =  "95";
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf
index 7ec670d5686e889e589444f2ec7d9b62831c602c..86131b3e8e97e0b98fadfe7d6617a37f67a9e569 100755
--- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf
+++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf
@@ -15,12 +15,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
     
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "15";
-    
-    mobile_country_code =  "208";
-    
-    mobile_network_code =  "92";
-    
+    tracking_area_code = 15;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
+
     ////////// Channel parameters:
     // Default Paging DRX of the eNB as defined in TS 36.304
     default_paging_drx  =  "PAGING_DRX_256";
diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf
index e3a0ea3c56f8d9513c47116c84de41a5746a9c10..e87a37f9fb8cc5a3fd9e523307f0e18fc17a6bd6 100755
--- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf
+++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf
@@ -15,12 +15,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
     
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "15";
-    
-    mobile_country_code =  "208";
-    
-    mobile_network_code =  "92";
-    
+    tracking_area_code = 15;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
+
     ////////// Channel parameters:
     // Default Paging DRX of the eNB as defined in TS 36.304
     default_paging_drx  =  "PAGING_DRX_256";
diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf
index 591257ff713003544f33bb4f6c7a388267509b51..af4f4236a7b2059f04193edd9d9be5eb56ff6eeb 100755
--- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf
+++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf
@@ -14,12 +14,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
     
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "15";
-    
-    mobile_country_code =  "208";
-    
-    mobile_network_code =  "92";
-    
+    tracking_area_code = 15;
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
+
     ////////// Channel parameters:
     // Default Paging DRX of the eNB as defined in TS 36.304
     default_paging_drx  =  "PAGING_DRX_256";
diff --git a/targets/PROJECTS/E-MBMS/enb.conf b/targets/PROJECTS/E-MBMS/enb.conf
index 852f7bbf5f146c260713a64a396e99f4c452a16b..ea256487b078c12f14d046ba4b44d2a02ff91058 100755
--- a/targets/PROJECTS/E-MBMS/enb.conf
+++ b/targets/PROJECTS/E-MBMS/enb.conf
@@ -11,12 +11,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_0";
     
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  1;
-    
-    mobile_country_code =  208;
-    
-    mobile_network_code =  10;
-    
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 10; mnc_length = 2; } );
+
     ////////// Channel parameters:
     // Default Paging DRX of the eNB as defined in TS 36.304
     default_paging_drx  =  "PAGING_DRX_256";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf
index 2761fe5fdbed1ff753c32dfa5402b40325860c57..8c080b7d1059c6cc4bfd03808b24f3fba1779bef 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf
@@ -13,10 +13,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-    mobile_network_code =  "92";
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf
index 56b3c37c0a62eee61c575d941556b232f30403b1..83954a00d52c3e2522371336db87fb6b574ff051 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf
@@ -13,10 +13,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-    mobile_network_code =  "92";
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
        ////////// Physical parameters:
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf
index f088eda84f39a093ce6640f363d0be013f709243..60b47c5c493e62a245dbbcb8d50a5267a21b9ed8 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf
@@ -13,11 +13,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "93";
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf
index 3bd4b1275adcd38c2f7870e6475ce81a7790741b..823c5fb1c3e7ec1c9e04fd42fe3cee6af3afac72 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf
@@ -13,11 +13,9 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "92";
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf
index a41912284663542ad4735b072a47ee70c3efd7ed..476d4903f1c5b04e16b3caa927c68ed2e057fc76 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf
@@ -13,11 +13,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "93";
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
index e08b83d58a87d920e44639e2f4c2db6012be2e85..83834bfeca6d51a6c8866d95d31d3ef680eed9aa 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
@@ -13,11 +13,9 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code  =  1;
 
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "93";
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf
index f0a3cb524a1f094aba901fa51d6d78679e60f5a1..403e5f24f54cb114dfd9e971f5d2a9541c7625e7 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf
@@ -13,11 +13,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "93";
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf
index 039f0c39c1839aa35397ba9f233a1bce53ae99d7..7eb16a3b7a9f0f0da3fdd706c254211c6cf53d01 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf
@@ -16,11 +16,9 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "93";
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf
index 8f6aac632b4b5b17f049dbfee8d61e8ef77dfcc3..47047e5626cbf9e170515b920507b665030dfe25 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf
@@ -13,12 +13,9 @@ eNBs =
     eNB_name  =  "eNB_Eurecom_LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-
-    #mobile_network_code =  "93";
-    mobile_network_code =  "92";
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
index f4ac5a9aa3b13ef63f846da88c01e6d624a522d1..ced031163d242aef51b065bf8a73cdc5142547cc 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
@@ -13,11 +13,9 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "93";
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf
index ea205e44d178d594670cd812c120108b1a145671..d989ac8b1087ec181e1da88ffca01aee0130ed7f 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf
@@ -16,11 +16,9 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "93";
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
index a2e97648c9ec532b9a23d24acd856270dd3e50e7..79bd48cd0c5dac9287810cdf377c8322aec000ca 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
@@ -16,11 +16,9 @@ eNBs =
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  "1";
+    tracking_area_code = 1;
 
-    mobile_country_code =  "208";
-
-    mobile_network_code =  "93";
+    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"