diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt
index 123b274714b882f04ed416b79801d88b42bad0b3..815836291255351219b75646b1f49f38839234ea 100644
--- a/cmake_targets/nas_sim_tools/CMakeLists.txt
+++ b/cmake_targets/nas_sim_tools/CMakeLists.txt
@@ -10,13 +10,15 @@ add_definitions(-std=gnu99)
 ENABLE_LANGUAGE(C)
 
 set(CMAKE_C_FLAGS
-  "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat")
+  "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat -g")
 
 set(OPENAIR_DIR     $ENV{OPENAIR_DIR})
 set(OPENAIR3_DIR    $ENV{OPENAIR_DIR}/openair3)
 
 set(conf2uedata_SRC
     ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c
+    ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c
+    ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c
     ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c
     ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.c
     ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c
diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c
index e6d9554b0c77436b9e6d0a88970ae2284eb5c482..cef55dbcb76cf2744a6f20e35edc525f33988fd8 100644
--- a/openair3/NAS/TOOLS/conf2uedata.c
+++ b/openair3/NAS/TOOLS/conf2uedata.c
@@ -1,10 +1,15 @@
 #include <stdio.h>  // perror, printf, fprintf, snprintf
 #include <stdlib.h> // exit, free
 #include <string.h> // memset, strncpy
+#include <getopt.h>
 
 #include "conf2uedata.h"
-#include "user_api.h"
+#include "memory.h"
+#include "userDef.h"
+#include "usim_api.h"
 #include "utils.h"
+#include "display.h"
+#include "fs.h"
 
 const char *output_dir = NULL;
 
@@ -852,299 +857,6 @@ int _luhn(const char* cc) {
 	return 10 - (sum % 10);
 }
 
-void display_usim_data(const char *filename) {
-
-	int rc;
-	usim_data_t data = { };
-
-    rc = usim_api_read(filename, &data);
-
-	if (rc != RETURNok) {
-		perror("ERROR\t: usim_api_read() failed");
-		exit(EXIT_FAILURE);
-	}
-
-	/*
-	 * Display USIM application data
-	 */
-	printf("\nUSIM data:\n\n");
-	int digits;
-
-	printf("Administrative Data:\n");
-	printf("\tUE_Operation_Mode\t= 0x%.2x\n", data.ad.UE_Operation_Mode);
-	printf("\tAdditional_Info\t\t= 0x%.4x\n", data.ad.Additional_Info);
-	printf("\tMNC_Length\t\t= %d\n\n", data.ad.MNC_Length);
-
-	printf("IMSI:\n");
-	printf("\tlength\t= %d\n", data.imsi.length);
-	printf("\tparity\t= %s\n",
-			data.imsi.u.num.parity == EVEN_PARITY ? "Even" : "Odd");
-	digits = (data.imsi.length * 2) - 1
-			- (data.imsi.u.num.parity == EVEN_PARITY ? 1 : 0);
-	printf("\tdigits\t= %d\n", digits);
-	printf("\tdigits\t= %u%u%u%u%u%x%u%u%u%u",
-			data.imsi.u.num.digit1, // MCC digit 1
-			data.imsi.u.num.digit2, // MCC digit 2
-			data.imsi.u.num.digit3, // MCC digit 3
-			data.imsi.u.num.digit4, // MNC digit 1
-			data.imsi.u.num.digit5, // MNC digit 2
-			data.imsi.u.num.digit6, // MNC digit 3
-			data.imsi.u.num.digit7, data.imsi.u.num.digit8,
-			data.imsi.u.num.digit9, data.imsi.u.num.digit10);
-
-	if (digits >= 11)
-		printf("%x", data.imsi.u.num.digit11);
-
-	if (digits >= 12)
-		printf("%x", data.imsi.u.num.digit12);
-
-	if (digits >= 13)
-		printf("%x", data.imsi.u.num.digit13);
-
-	if (digits >= 14)
-		printf("%x", data.imsi.u.num.digit14);
-
-	if (digits >= 15)
-		printf("%x", data.imsi.u.num.digit15);
-
-	printf("\n\n");
-
-	printf("Ciphering and Integrity Keys:\n");
-	printf("\tKSI\t: 0x%.2x\n", data.keys.ksi);
-	char key[USIM_CK_SIZE + 1];
-	key[USIM_CK_SIZE] = '\0';
-	memcpy(key, data.keys.ck, USIM_CK_SIZE);
-	printf("\tCK\t: \"%s\"\n", key);
-	memcpy(key, data.keys.ik, USIM_IK_SIZE);
-	printf("\tIK\t: \"%s\"\n", key);
-
-	printf("EPS NAS security context:\n");
-	printf("\tKSIasme\t: 0x%.2x\n", data.securityctx.KSIasme.value[0]);
-	char kasme[USIM_K_ASME_SIZE + 1];
-	kasme[USIM_K_ASME_SIZE] = '\0';
-	memcpy(kasme, data.securityctx.Kasme.value, USIM_K_ASME_SIZE);
-	printf("\tKasme\t: \"%s\"\n", kasme);
-	printf("\tulNAScount\t: 0x%.8x\n",
-			*(uint32_t*) data.securityctx.ulNAScount.value);
-	printf("\tdlNAScount\t: 0x%.8x\n",
-			*(uint32_t*) data.securityctx.dlNAScount.value);
-	printf("\talgorithmID\t: 0x%.2x\n\n",
-			data.securityctx.algorithmID.value[0]);
-
-	printf("MSISDN\t= %u%u%u %u%u%u%u %u%u%u%u\n\n",
-			data.msisdn.number.digit[0].msb, data.msisdn.number.digit[0].lsb,
-			data.msisdn.number.digit[1].msb, data.msisdn.number.digit[1].lsb,
-			data.msisdn.number.digit[2].msb, data.msisdn.number.digit[2].lsb,
-			data.msisdn.number.digit[3].msb, data.msisdn.number.digit[3].lsb,
-			data.msisdn.number.digit[4].msb, data.msisdn.number.digit[4].lsb,
-			data.msisdn.number.digit[5].msb);
-
-	for (int i = 0; i < USIM_PNN_MAX; i++) {
-		printf("PNN[%d]\t= {%s, %s}\n", i, data.pnn[i].fullname.value,
-				data.pnn[i].shortname.value);
-	}
-
-	printf("\n");
-
-	for (int i = 0; i < USIM_OPL_MAX; i++) {
-		printf("OPL[%d]\t= ", i);
-		PRINT_PLMN(data.opl[i].plmn);
-		printf(", TAC = [%.4x - %.4x], record_id = %d\n", data.opl[i].start,
-				data.opl[i].end, data.opl[i].record_id);
-	}
-
-	printf("\n");
-
-	printf("HPLMN\t\t= ");
-	PRINT_PLMN(data.hplmn.plmn);
-	printf(", AcT = 0x%x\n\n", data.hplmn.AcT);
-
-	for (int i = 0; i < USIM_FPLMN_MAX; i++) {
-		printf("FPLMN[%d]\t= ", i);
-		PRINT_PLMN(data.fplmn[i]);
-		printf("\n");
-	}
-
-	printf("\n");
-
-	for (int i = 0; i < USIM_EHPLMN_MAX; i++) {
-		printf("EHPLMN[%d]\t= ", i);
-		PRINT_PLMN(data.ehplmn[i]);
-		printf("\n");
-	}
-
-	printf("\n");
-
-	for (int i = 0; i < USIM_PLMN_MAX; i++) {
-		printf("PLMN[%d]\t\t= ", i);
-		PRINT_PLMN(data.plmn[i].plmn);
-		printf(", AcTPLMN = 0x%x", data.plmn[i].AcT);
-		printf("\n");
-	}
-
-	printf("\n");
-
-	for (int i = 0; i < USIM_OPLMN_MAX; i++) {
-		printf("OPLMN[%d]\t= ", i);
-		PRINT_PLMN(data.oplmn[i].plmn);
-		printf(", AcTPLMN = 0x%x", data.oplmn[i].AcT);
-		printf("\n");
-	}
-
-	printf("\n");
-
-	printf("HPPLMN\t\t= 0x%.2x (%d minutes)\n\n", data.hpplmn, data.hpplmn);
-
-	printf("LOCI:\n");
-	printf("\tTMSI = 0x%.4x\n", data.loci.tmsi);
-	printf("\tLAI\t: PLMN = ");
-	PRINT_PLMN(data.loci.lai.plmn);
-	printf(", LAC = 0x%.2x\n", data.loci.lai.lac);
-	printf("\tstatus\t= %d\n\n", data.loci.status);
-
-	printf("PSLOCI:\n");
-	printf("\tP-TMSI = 0x%.4x\n", data.psloci.p_tmsi);
-	printf("\tsignature = 0x%x 0x%x 0x%x\n", data.psloci.signature[0],
-			data.psloci.signature[1], data.psloci.signature[2]);
-	printf("\tRAI\t: PLMN = ");
-	PRINT_PLMN(data.psloci.rai.plmn);
-	printf(", LAC = 0x%.2x, RAC = 0x%.1x\n", data.psloci.rai.lac,
-			data.psloci.rai.rac);
-	printf("\tstatus\t= %d\n\n", data.psloci.status);
-
-	printf("EPSLOCI:\n");
-	printf("\tGUTI\t: GUMMEI\t: (PLMN = ");
-	PRINT_PLMN(data.epsloci.guti.gummei.plmn);
-	printf(", MMEgid = 0x%.2x, MMEcode = 0x%.1x)",
-			data.epsloci.guti.gummei.MMEgid, data.epsloci.guti.gummei.MMEcode);
-	printf(", M-TMSI = 0x%.4x\n", data.epsloci.guti.m_tmsi);
-	printf("\tTAI\t: PLMN = ");
-	PRINT_PLMN(data.epsloci.tai.plmn);
-	printf(", TAC = 0x%.2x\n", data.epsloci.tai.tac);
-	printf("\tstatus\t= %d\n\n", data.epsloci.status);
-
-	printf("NASCONFIG:\n");
-	printf("\tNAS_SignallingPriority\t\t: 0x%.2x\n",
-			data.nasconfig.NAS_SignallingPriority.value[0]);
-	printf("\tNMO_I_Behaviour\t\t\t: 0x%.2x\n",
-			data.nasconfig.NMO_I_Behaviour.value[0]);
-	printf("\tAttachWithImsi\t\t\t: 0x%.2x\n",
-			data.nasconfig.AttachWithImsi.value[0]);
-	printf("\tMinimumPeriodicSearchTimer\t: 0x%.2x\n",
-			data.nasconfig.MinimumPeriodicSearchTimer.value[0]);
-	printf("\tExtendedAccessBarring\t\t: 0x%.2x\n",
-			data.nasconfig.ExtendedAccessBarring.value[0]);
-	printf("\tTimer_T3245_Behaviour\t\t: 0x%.2x\n",
-			data.nasconfig.Timer_T3245_Behaviour.value[0]);
-
-}
-
-void display_ue_data(const char *filename) {
-	user_nvdata_t data;
-	int rc;
-	/*
-	 * Read UE's non-volatile data
-	 */
-	memset(&data, 0, sizeof(user_nvdata_t));
-	rc = memory_read(filename, &data, sizeof(user_nvdata_t));
-
-	if (rc != RETURNok) {
-		perror("ERROR\t: memory_read() failed");
-		exit(EXIT_FAILURE);
-	}
-
-	/*
-	 * Display UE's non-volatile data
-	 */
-	printf("\nUE's non-volatile data:\n\n");
-	printf("IMEI\t\t= %s\n", data.IMEI);
-	printf("manufacturer\t= %s\n", data.manufacturer);
-	printf("model\t\t= %s\n", data.model);
-	printf("PIN\t\t= %s\n", data.PIN);
-}
-
-/*
- * Displays UE's non-volatile EMM data
- */
-void display_emm_data(const char *filename) {
-
-	int rc;
-	emm_nvdata_t data;
-
-	/*
-	 * Read EMM non-volatile data
-	 */
-	memset(&data, 0, sizeof(emm_nvdata_t));
-	rc = memory_read(filename, &data, sizeof(emm_nvdata_t));
-	if (rc != RETURNok) {
-		perror("ERROR\t: memory_read() failed ");
-		exit(EXIT_FAILURE);
-	}
-
-	/*
-	 * Display EMM non-volatile data
-	 */
-	printf("\nEMM non-volatile data:\n\n");
-
-	printf("IMSI\t\t= ");
-
-	if (data.imsi.u.num.digit6 == 0b1111) {
-		if (data.imsi.u.num.digit15 == 0b1111) {
-			printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1,
-					data.imsi.u.num.digit2, data.imsi.u.num.digit3,
-					data.imsi.u.num.digit4, data.imsi.u.num.digit5,
-
-					data.imsi.u.num.digit7, data.imsi.u.num.digit8,
-					data.imsi.u.num.digit9, data.imsi.u.num.digit10,
-					data.imsi.u.num.digit11, data.imsi.u.num.digit12,
-					data.imsi.u.num.digit13, data.imsi.u.num.digit14);
-		} else {
-			printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1,
-					data.imsi.u.num.digit2, data.imsi.u.num.digit3,
-					data.imsi.u.num.digit4, data.imsi.u.num.digit5,
-
-					data.imsi.u.num.digit7, data.imsi.u.num.digit8,
-					data.imsi.u.num.digit9, data.imsi.u.num.digit10,
-					data.imsi.u.num.digit11, data.imsi.u.num.digit12,
-					data.imsi.u.num.digit13, data.imsi.u.num.digit14,
-					data.imsi.u.num.digit15);
-		}
-	} else {
-		if (data.imsi.u.num.digit15 == 0b1111) {
-			printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1,
-					data.imsi.u.num.digit2, data.imsi.u.num.digit3,
-					data.imsi.u.num.digit4, data.imsi.u.num.digit5,
-					data.imsi.u.num.digit6,
-
-					data.imsi.u.num.digit7, data.imsi.u.num.digit8,
-					data.imsi.u.num.digit9, data.imsi.u.num.digit10,
-					data.imsi.u.num.digit11, data.imsi.u.num.digit12,
-					data.imsi.u.num.digit13, data.imsi.u.num.digit14);
-		} else {
-			printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1,
-					data.imsi.u.num.digit2, data.imsi.u.num.digit3,
-					data.imsi.u.num.digit4, data.imsi.u.num.digit5,
-					data.imsi.u.num.digit6,
-
-					data.imsi.u.num.digit7, data.imsi.u.num.digit8,
-					data.imsi.u.num.digit9, data.imsi.u.num.digit10,
-					data.imsi.u.num.digit11, data.imsi.u.num.digit12,
-					data.imsi.u.num.digit13, data.imsi.u.num.digit14,
-					data.imsi.u.num.digit15);
-		}
-	}
-
-	printf("RPLMN\t\t= ");
-	PRINT_PLMN(data.rplmn);
-	printf("\n");
-
-	for (int i = 0; i < data.eplmn.n_plmns; i++) {
-		printf("EPLMN[%d]\t= ", i);
-		PRINT_PLMN(data.eplmn.plmn[i]);
-		printf("\n");
-	}
-}
-
 /*
  * Displays command line usage
  */
@@ -1154,73 +866,3 @@ void _display_usage(void) {
 	fprintf(stderr, "\t[-o]\toutput file directory\n");
 	fprintf(stderr, "\t[-h]\tDisplay this usage\n");
 }
-
-void display_data_from_directory(const char *directory) {
-    int user_id = 0;
-    char *filename;
-
-    filename = get_ue_filename(directory, user_id);
-    while ( file_exist_and_is_readable(filename) ) {
-
-        display_ue_data(filename);
-        free(filename);
-
-        filename = get_emm_filename(directory, user_id);
-        display_emm_data(filename);
-        free(filename);
-
-        filename = get_usim_filename(directory, user_id);
-        display_usim_data(filename);
-        free(filename);
-
-
-        user_id += 1;
-        filename = get_ue_filename(directory, user_id);
-    }
-    free(filename);
-}
-
-bool file_exist_and_is_readable(const char *filename) {
-    FILE *file ;
-    file = fopen(filename, "r");
-    if ( file == NULL )
-        return false;
-    fclose(file);
-    return true;
-}
-
-char *get_ue_filename(const char *output_dir, int user_id) {
-    return make_filename(output_dir, USER_NVRAM_FILENAME, user_id);
-}
-
-char *get_emm_filename(const char *output_dir, int user_id) {
-    return make_filename(output_dir, EMM_NVRAM_FILENAME, user_id);
-}
-
-char *get_usim_filename(const char *output_dir, int user_id) {
-	return make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id);
-}
-
-char *make_filename(const char *output_dir, const char *filename, int ueid) {
-	size_t size;
-    char *str_ueid, *str;
-
-    str_ueid = itoa(ueid);
-
-    if (str_ueid == NULL) {
-        perror("ERROR\t: itoa() failed");
-        exit(EXIT_FAILURE);
-    }
-
-    size = strlen(output_dir)+strlen(filename) + sizeof(ueid) + 1 + 1; // for \0 and for '/'
-    str = malloc(size);
-    if (str == NULL) {
-        perror("ERROR\t: make_filename() failed");
-        exit(EXIT_FAILURE);
-    }
-
-    snprintf(str, size, "%s/%s%s",output_dir, filename, str_ueid);
-    free(str_ueid);
-
- return str;
-}
diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h
index 0fba9aa960031091ccb4a97a92fb1091e3de7fbd..98c4752743ef2f1d828d03503ef346c17b3b0f1d 100644
--- a/openair3/NAS/TOOLS/conf2uedata.h
+++ b/openair3/NAS/TOOLS/conf2uedata.h
@@ -3,10 +3,6 @@
 
 #include <libconfig.h>
 #include "emmData.h"
-#include "usim_api.h"
-#include "userDef.h"
-#include "memory.h"
-#include "getopt.h"
 
 #define USER "USER"
 #define UE "UE"
@@ -36,16 +32,6 @@
 #define EHPLMN "EHPLMN_LIST"
 
 #define KSI     USIM_KSI_NOT_AVAILABLE
-#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d))
-
-#define PRINT_PLMN(plmn)    \
-    PRINT_PLMN_DIGIT((plmn).MCCdigit1); \
-    PRINT_PLMN_DIGIT((plmn).MCCdigit2); \
-    PRINT_PLMN_DIGIT((plmn).MCCdigit3); \
-    PRINT_PLMN_DIGIT((plmn).MNCdigit1); \
-    PRINT_PLMN_DIGIT((plmn).MNCdigit2); \
-    PRINT_PLMN_DIGIT((plmn).MNCdigit3)
-
 
 #define KSI_ASME    USIM_KSI_NOT_AVAILABLE
 #define INT_ALGO    USIM_INT_EIA1
@@ -65,16 +51,6 @@
 #define DEFAULT_MME_ID    0x0102
 #define DEFAULT_MME_CODE  0x0F
 
-#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d))
-
-#define PRINT_PLMN(plmn)    \
-    PRINT_PLMN_DIGIT((plmn).MCCdigit1); \
-    PRINT_PLMN_DIGIT((plmn).MCCdigit2); \
-    PRINT_PLMN_DIGIT((plmn).MCCdigit3); \
-    PRINT_PLMN_DIGIT((plmn).MNCdigit1); \
-    PRINT_PLMN_DIGIT((plmn).MNCdigit2); \
-    PRINT_PLMN_DIGIT((plmn).MNCdigit3)
-
 /*
  * PLMN network operator record
  */
@@ -122,7 +98,6 @@ extern network_record_t* user_network_record_list;
 int get_config_from_file(const char *filename, config_t *config);
 int parse_config_file(const char *filename);
 
-
 void _display_usage(void);
 void gen_emm_data(int user_id) ;
 void gen_usim_data(int user_id);
@@ -130,17 +105,6 @@ void fill_network_record_list(void);
 
 int _luhn(const char* cc);
 
-void display_data_from_directory(const char *directory);
-void display_ue_data(const char *filename);
-void display_emm_data(const char *filename);
-void display_usim_data(const char *filename);
-
-bool file_exist_and_is_readable(const char *filename);
-char *get_ue_filename(const char *output_dir, int user_id);
-char *get_emm_filename(const char *output_dir, int user_id);
-char *get_usim_filename(const char *output_dir, int user_id);
-char *make_filename(const char *output_dir, const char *filename, int ueid);
-
 int parse_ue_user_param(config_setting_t *ue_setting, int user_id);
 int parse_ue_sim_param(config_setting_t *ue_setting, int user_id);
 int parse_plmn_param(config_setting_t *plmn_setting, int index);
diff --git a/openair3/NAS/TOOLS/display.c b/openair3/NAS/TOOLS/display.c
new file mode 100644
index 0000000000000000000000000000000000000000..b130ef2c071b60a9cc82412543dc0abfaf624702
--- /dev/null
+++ b/openair3/NAS/TOOLS/display.c
@@ -0,0 +1,349 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "userDef.h"
+#include "usim_api.h"
+#include "emmData.h"
+#include "display.h"
+#include "memory.h"
+#include "fs.h"
+
+#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d))
+
+#define PRINT_PLMN(plmn)    \
+    PRINT_PLMN_DIGIT((plmn).MCCdigit1); \
+    PRINT_PLMN_DIGIT((plmn).MCCdigit2); \
+    PRINT_PLMN_DIGIT((plmn).MCCdigit3); \
+    PRINT_PLMN_DIGIT((plmn).MNCdigit1); \
+    PRINT_PLMN_DIGIT((plmn).MNCdigit2); \
+    PRINT_PLMN_DIGIT((plmn).MNCdigit3)
+
+#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d))
+
+#define PRINT_PLMN(plmn)    \
+    PRINT_PLMN_DIGIT((plmn).MCCdigit1); \
+    PRINT_PLMN_DIGIT((plmn).MCCdigit2); \
+    PRINT_PLMN_DIGIT((plmn).MCCdigit3); \
+    PRINT_PLMN_DIGIT((plmn).MNCdigit1); \
+    PRINT_PLMN_DIGIT((plmn).MNCdigit2); \
+    PRINT_PLMN_DIGIT((plmn).MNCdigit3)
+
+void display_data_from_directory(const char *directory) {
+    int user_id = 0;
+    char *filename;
+
+    filename = get_ue_filename(directory, user_id);
+    while ( file_exist_and_is_readable(filename) ) {
+
+        display_ue_data(filename);
+        free(filename);
+
+        filename = get_emm_filename(directory, user_id);
+        display_emm_data(filename);
+        free(filename);
+
+        filename = get_usim_filename(directory, user_id);
+        display_usim_data(filename);
+        free(filename);
+
+
+        user_id += 1;
+        filename = get_ue_filename(directory, user_id);
+    }
+    free(filename);
+}
+
+void display_ue_data(const char *filename) {
+	user_nvdata_t data;
+	int rc;
+	/*
+	 * Read UE's non-volatile data
+	 */
+	memset(&data, 0, sizeof(user_nvdata_t));
+	rc = memory_read(filename, &data, sizeof(user_nvdata_t));
+
+	if (rc != RETURNok) {
+		perror("ERROR\t: memory_read() failed");
+		exit(EXIT_FAILURE);
+	}
+
+	/*
+	 * Display UE's non-volatile data
+	 */
+	printf("\nUE's non-volatile data:\n\n");
+	printf("IMEI\t\t= %s\n", data.IMEI);
+	printf("manufacturer\t= %s\n", data.manufacturer);
+	printf("model\t\t= %s\n", data.model);
+	printf("PIN\t\t= %s\n", data.PIN);
+}
+
+/*
+ * Displays UE's non-volatile EMM data
+ */
+void display_emm_data(const char *filename) {
+
+	int rc;
+	emm_nvdata_t data;
+
+	/*
+	 * Read EMM non-volatile data
+	 */
+	memset(&data, 0, sizeof(emm_nvdata_t));
+	rc = memory_read(filename, &data, sizeof(emm_nvdata_t));
+	if (rc != RETURNok) {
+		perror("ERROR\t: memory_read() failed ");
+		exit(EXIT_FAILURE);
+	}
+
+	/*
+	 * Display EMM non-volatile data
+	 */
+	printf("\nEMM non-volatile data:\n\n");
+
+	printf("IMSI\t\t= ");
+
+	if (data.imsi.u.num.digit6 == 0b1111) {
+		if (data.imsi.u.num.digit15 == 0b1111) {
+			printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1,
+					data.imsi.u.num.digit2, data.imsi.u.num.digit3,
+					data.imsi.u.num.digit4, data.imsi.u.num.digit5,
+
+					data.imsi.u.num.digit7, data.imsi.u.num.digit8,
+					data.imsi.u.num.digit9, data.imsi.u.num.digit10,
+					data.imsi.u.num.digit11, data.imsi.u.num.digit12,
+					data.imsi.u.num.digit13, data.imsi.u.num.digit14);
+		} else {
+			printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1,
+					data.imsi.u.num.digit2, data.imsi.u.num.digit3,
+					data.imsi.u.num.digit4, data.imsi.u.num.digit5,
+
+					data.imsi.u.num.digit7, data.imsi.u.num.digit8,
+					data.imsi.u.num.digit9, data.imsi.u.num.digit10,
+					data.imsi.u.num.digit11, data.imsi.u.num.digit12,
+					data.imsi.u.num.digit13, data.imsi.u.num.digit14,
+					data.imsi.u.num.digit15);
+		}
+	} else {
+		if (data.imsi.u.num.digit15 == 0b1111) {
+			printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1,
+					data.imsi.u.num.digit2, data.imsi.u.num.digit3,
+					data.imsi.u.num.digit4, data.imsi.u.num.digit5,
+					data.imsi.u.num.digit6,
+
+					data.imsi.u.num.digit7, data.imsi.u.num.digit8,
+					data.imsi.u.num.digit9, data.imsi.u.num.digit10,
+					data.imsi.u.num.digit11, data.imsi.u.num.digit12,
+					data.imsi.u.num.digit13, data.imsi.u.num.digit14);
+		} else {
+			printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1,
+					data.imsi.u.num.digit2, data.imsi.u.num.digit3,
+					data.imsi.u.num.digit4, data.imsi.u.num.digit5,
+					data.imsi.u.num.digit6,
+
+					data.imsi.u.num.digit7, data.imsi.u.num.digit8,
+					data.imsi.u.num.digit9, data.imsi.u.num.digit10,
+					data.imsi.u.num.digit11, data.imsi.u.num.digit12,
+					data.imsi.u.num.digit13, data.imsi.u.num.digit14,
+					data.imsi.u.num.digit15);
+		}
+	}
+
+	printf("RPLMN\t\t= ");
+	PRINT_PLMN(data.rplmn);
+	printf("\n");
+
+	for (int i = 0; i < data.eplmn.n_plmns; i++) {
+		printf("EPLMN[%d]\t= ", i);
+		PRINT_PLMN(data.eplmn.plmn[i]);
+		printf("\n");
+	}
+}
+
+void display_usim_data(const char *filename) {
+
+	int rc;
+	usim_data_t data = { };
+
+    rc = usim_api_read(filename, &data);
+
+	if (rc != RETURNok) {
+		perror("ERROR\t: usim_api_read() failed");
+		exit(EXIT_FAILURE);
+	}
+
+	/*
+	 * Display USIM application data
+	 */
+	printf("\nUSIM data:\n\n");
+	int digits;
+
+	printf("Administrative Data:\n");
+	printf("\tUE_Operation_Mode\t= 0x%.2x\n", data.ad.UE_Operation_Mode);
+	printf("\tAdditional_Info\t\t= 0x%.4x\n", data.ad.Additional_Info);
+	printf("\tMNC_Length\t\t= %d\n\n", data.ad.MNC_Length);
+
+	printf("IMSI:\n");
+	printf("\tlength\t= %d\n", data.imsi.length);
+	printf("\tparity\t= %s\n",
+			data.imsi.u.num.parity == EVEN_PARITY ? "Even" : "Odd");
+	digits = (data.imsi.length * 2) - 1
+			- (data.imsi.u.num.parity == EVEN_PARITY ? 1 : 0);
+	printf("\tdigits\t= %d\n", digits);
+	printf("\tdigits\t= %u%u%u%u%u%x%u%u%u%u",
+			data.imsi.u.num.digit1, // MCC digit 1
+			data.imsi.u.num.digit2, // MCC digit 2
+			data.imsi.u.num.digit3, // MCC digit 3
+			data.imsi.u.num.digit4, // MNC digit 1
+			data.imsi.u.num.digit5, // MNC digit 2
+			data.imsi.u.num.digit6, // MNC digit 3
+			data.imsi.u.num.digit7, data.imsi.u.num.digit8,
+			data.imsi.u.num.digit9, data.imsi.u.num.digit10);
+
+	if (digits >= 11)
+		printf("%x", data.imsi.u.num.digit11);
+
+	if (digits >= 12)
+		printf("%x", data.imsi.u.num.digit12);
+
+	if (digits >= 13)
+		printf("%x", data.imsi.u.num.digit13);
+
+	if (digits >= 14)
+		printf("%x", data.imsi.u.num.digit14);
+
+	if (digits >= 15)
+		printf("%x", data.imsi.u.num.digit15);
+
+	printf("\n\n");
+
+	printf("Ciphering and Integrity Keys:\n");
+	printf("\tKSI\t: 0x%.2x\n", data.keys.ksi);
+	char key[USIM_CK_SIZE + 1];
+	key[USIM_CK_SIZE] = '\0';
+	memcpy(key, data.keys.ck, USIM_CK_SIZE);
+	printf("\tCK\t: \"%s\"\n", key);
+	memcpy(key, data.keys.ik, USIM_IK_SIZE);
+	printf("\tIK\t: \"%s\"\n", key);
+
+	printf("EPS NAS security context:\n");
+	printf("\tKSIasme\t: 0x%.2x\n", data.securityctx.KSIasme.value[0]);
+	char kasme[USIM_K_ASME_SIZE + 1];
+	kasme[USIM_K_ASME_SIZE] = '\0';
+	memcpy(kasme, data.securityctx.Kasme.value, USIM_K_ASME_SIZE);
+	printf("\tKasme\t: \"%s\"\n", kasme);
+	printf("\tulNAScount\t: 0x%.8x\n",
+			*(uint32_t*) data.securityctx.ulNAScount.value);
+	printf("\tdlNAScount\t: 0x%.8x\n",
+			*(uint32_t*) data.securityctx.dlNAScount.value);
+	printf("\talgorithmID\t: 0x%.2x\n\n",
+			data.securityctx.algorithmID.value[0]);
+
+	printf("MSISDN\t= %u%u%u %u%u%u%u %u%u%u%u\n\n",
+			data.msisdn.number.digit[0].msb, data.msisdn.number.digit[0].lsb,
+			data.msisdn.number.digit[1].msb, data.msisdn.number.digit[1].lsb,
+			data.msisdn.number.digit[2].msb, data.msisdn.number.digit[2].lsb,
+			data.msisdn.number.digit[3].msb, data.msisdn.number.digit[3].lsb,
+			data.msisdn.number.digit[4].msb, data.msisdn.number.digit[4].lsb,
+			data.msisdn.number.digit[5].msb);
+
+	for (int i = 0; i < USIM_PNN_MAX; i++) {
+		printf("PNN[%d]\t= {%s, %s}\n", i, data.pnn[i].fullname.value,
+				data.pnn[i].shortname.value);
+	}
+
+	printf("\n");
+
+	for (int i = 0; i < USIM_OPL_MAX; i++) {
+		printf("OPL[%d]\t= ", i);
+		PRINT_PLMN(data.opl[i].plmn);
+		printf(", TAC = [%.4x - %.4x], record_id = %d\n", data.opl[i].start,
+				data.opl[i].end, data.opl[i].record_id);
+	}
+
+	printf("\n");
+
+	printf("HPLMN\t\t= ");
+	PRINT_PLMN(data.hplmn.plmn);
+	printf(", AcT = 0x%x\n\n", data.hplmn.AcT);
+
+	for (int i = 0; i < USIM_FPLMN_MAX; i++) {
+		printf("FPLMN[%d]\t= ", i);
+		PRINT_PLMN(data.fplmn[i]);
+		printf("\n");
+	}
+
+	printf("\n");
+
+	for (int i = 0; i < USIM_EHPLMN_MAX; i++) {
+		printf("EHPLMN[%d]\t= ", i);
+		PRINT_PLMN(data.ehplmn[i]);
+		printf("\n");
+	}
+
+	printf("\n");
+
+	for (int i = 0; i < USIM_PLMN_MAX; i++) {
+		printf("PLMN[%d]\t\t= ", i);
+		PRINT_PLMN(data.plmn[i].plmn);
+		printf(", AcTPLMN = 0x%x", data.plmn[i].AcT);
+		printf("\n");
+	}
+
+	printf("\n");
+
+	for (int i = 0; i < USIM_OPLMN_MAX; i++) {
+		printf("OPLMN[%d]\t= ", i);
+		PRINT_PLMN(data.oplmn[i].plmn);
+		printf(", AcTPLMN = 0x%x", data.oplmn[i].AcT);
+		printf("\n");
+	}
+
+	printf("\n");
+
+	printf("HPPLMN\t\t= 0x%.2x (%d minutes)\n\n", data.hpplmn, data.hpplmn);
+
+	printf("LOCI:\n");
+	printf("\tTMSI = 0x%.4x\n", data.loci.tmsi);
+	printf("\tLAI\t: PLMN = ");
+	PRINT_PLMN(data.loci.lai.plmn);
+	printf(", LAC = 0x%.2x\n", data.loci.lai.lac);
+	printf("\tstatus\t= %d\n\n", data.loci.status);
+
+	printf("PSLOCI:\n");
+	printf("\tP-TMSI = 0x%.4x\n", data.psloci.p_tmsi);
+	printf("\tsignature = 0x%x 0x%x 0x%x\n", data.psloci.signature[0],
+			data.psloci.signature[1], data.psloci.signature[2]);
+	printf("\tRAI\t: PLMN = ");
+	PRINT_PLMN(data.psloci.rai.plmn);
+	printf(", LAC = 0x%.2x, RAC = 0x%.1x\n", data.psloci.rai.lac,
+			data.psloci.rai.rac);
+	printf("\tstatus\t= %d\n\n", data.psloci.status);
+
+	printf("EPSLOCI:\n");
+	printf("\tGUTI\t: GUMMEI\t: (PLMN = ");
+	PRINT_PLMN(data.epsloci.guti.gummei.plmn);
+	printf(", MMEgid = 0x%.2x, MMEcode = 0x%.1x)",
+			data.epsloci.guti.gummei.MMEgid, data.epsloci.guti.gummei.MMEcode);
+	printf(", M-TMSI = 0x%.4x\n", data.epsloci.guti.m_tmsi);
+	printf("\tTAI\t: PLMN = ");
+	PRINT_PLMN(data.epsloci.tai.plmn);
+	printf(", TAC = 0x%.2x\n", data.epsloci.tai.tac);
+	printf("\tstatus\t= %d\n\n", data.epsloci.status);
+
+	printf("NASCONFIG:\n");
+	printf("\tNAS_SignallingPriority\t\t: 0x%.2x\n",
+			data.nasconfig.NAS_SignallingPriority.value[0]);
+	printf("\tNMO_I_Behaviour\t\t\t: 0x%.2x\n",
+			data.nasconfig.NMO_I_Behaviour.value[0]);
+	printf("\tAttachWithImsi\t\t\t: 0x%.2x\n",
+			data.nasconfig.AttachWithImsi.value[0]);
+	printf("\tMinimumPeriodicSearchTimer\t: 0x%.2x\n",
+			data.nasconfig.MinimumPeriodicSearchTimer.value[0]);
+	printf("\tExtendedAccessBarring\t\t: 0x%.2x\n",
+			data.nasconfig.ExtendedAccessBarring.value[0]);
+	printf("\tTimer_T3245_Behaviour\t\t: 0x%.2x\n",
+			data.nasconfig.Timer_T3245_Behaviour.value[0]);
+
+}
+
+
diff --git a/openair3/NAS/TOOLS/display.h b/openair3/NAS/TOOLS/display.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd4f4ff1e35a000893e8ef396134444f4decbb42
--- /dev/null
+++ b/openair3/NAS/TOOLS/display.h
@@ -0,0 +1,9 @@
+#ifndef _DISPLAY_H
+#define _DISPLAY_H
+
+void display_data_from_directory(const char *directory);
+void display_ue_data(const char *filename);
+void display_emm_data(const char *filename);
+void display_usim_data(const char *filename);
+
+#endif
diff --git a/openair3/NAS/TOOLS/fs.c b/openair3/NAS/TOOLS/fs.c
new file mode 100644
index 0000000000000000000000000000000000000000..c25f10a1e790d8c9d34051e32831781948ebf77f
--- /dev/null
+++ b/openair3/NAS/TOOLS/fs.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "fs.h"
+#include "user_api.h"
+#include "utils.h"
+
+bool file_exist_and_is_readable(const char *filename) {
+    FILE *file ;
+    file = fopen(filename, "r");
+    if ( file == NULL )
+        return false;
+    fclose(file);
+    return true;
+}
+
+char *get_ue_filename(const char *output_dir, int user_id) {
+    return make_filename(output_dir, USER_NVRAM_FILENAME, user_id);
+}
+
+char *get_emm_filename(const char *output_dir, int user_id) {
+    return make_filename(output_dir, EMM_NVRAM_FILENAME, user_id);
+}
+
+char *get_usim_filename(const char *output_dir, int user_id) {
+	return make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id);
+}
+
+char *make_filename(const char *output_dir, const char *filename, int ueid) {
+	size_t size;
+    char *str_ueid, *str;
+
+    str_ueid = itoa(ueid);
+
+    if (str_ueid == NULL) {
+        perror("ERROR\t: itoa() failed");
+        exit(EXIT_FAILURE);
+    }
+
+    size = strlen(output_dir)+strlen(filename) + sizeof(ueid) + 1 + 1; // for \0 and for '/'
+    str = malloc(size);
+    if (str == NULL) {
+        perror("ERROR\t: make_filename() failed");
+        exit(EXIT_FAILURE);
+    }
+
+    snprintf(str, size, "%s/%s%s",output_dir, filename, str_ueid);
+    free(str_ueid);
+
+ return str;
+}
diff --git a/openair3/NAS/TOOLS/fs.h b/openair3/NAS/TOOLS/fs.h
new file mode 100644
index 0000000000000000000000000000000000000000..ecfca559550a2a440727f39045637a165209222d
--- /dev/null
+++ b/openair3/NAS/TOOLS/fs.h
@@ -0,0 +1,12 @@
+#ifndef _FS_H
+#define _FS_H
+
+#include <stdbool.h>
+
+bool file_exist_and_is_readable(const char *filename);
+char *get_ue_filename(const char *output_dir, int user_id);
+char *get_emm_filename(const char *output_dir, int user_id);
+char *get_usim_filename(const char *output_dir, int user_id);
+char *make_filename(const char *output_dir, const char *filename, int ueid);
+
+#endif