Commit 17d15532 authored by Imad ALAWE's avatar Imad ALAWE Committed by FredericLeroy
Browse files

feat: add conf2uedata tool for generating .*.nvram

This patch adds the conf2uedata tool for generating .ue.nvram* .ue.emm.nvram*
and .usim.nvram* files from a textual configuration file.

The configuration file define most usefull values like plmns, mnc, mcc, msin, K,
OPc for several users.
The files generated will always ends with a number corresponding to the user
entry in the configuration file.

This breaks oai5g because other script have not be updated for using
conf2uedata.
This breaks also the at_nas_ue command.

Examples of configuration files are in openair3/NAS/TOOLS/
parent c4707bd8
......@@ -82,7 +82,7 @@ Options
--eNB
Makes the LTE softmodem
--UE
Makes the UE specific parts (ue_ip, usim, nvram)
Makes the UE specific parts (ue_ip, usim, nvram) from the given configuration file
--RRH
Makes the RRH
-a | --agent
......@@ -145,6 +145,10 @@ Usage (Regular):
function main() {
local gen_nvram_path=$OPENAIR_DIR/targets/bin
local conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
until [ -z "$1" ]
do
case "$1" in
......@@ -182,7 +186,16 @@ function main() {
--UE)
UE=1
echo_info "Will compile UE"
shift;;
shift
if test -n "$1"
then
[ -f "$1" ] || echo_fatal "file invalid for --UE"
conf_nvram_path=$(readlink -f "$1")
shift 1
fi;;
--UE-OUTPUT)
gen_nvram_path=$(readlink -f $2)
shift 2;;
--RRH)
RRH=1
echo_info "Will compile RRH"
......@@ -507,20 +520,12 @@ function main() {
cmake ..
compilations \
nas_sim_tools usim \
usim $dbin/usim
compilations \
nas_sim_tools nvram \
nvram $dbin/nvram
nas_sim_tools conf2uedata \
conf2uedata $dbin/conf2uedata
# generate USIM data
if [ -f $dbin/nvram ]; then
install_nas_tools $dbin $dconf
echo_info "Copying UE specific part to $DIR/$lte_build_dir/build"
cp -Rvf $dbin/.ue_emm.nvram $DIR/$lte_build_dir/build
cp -Rvf $dbin/.ue.nvram $DIR/$lte_build_dir/build
cp -Rvf $dbin/.usim.nvram $DIR/$lte_build_dir/build
if [ -f $dbin/conf2uedata ]; then
install_nas_tools $conf_nvram_path $gen_nvram_path
else
echo_warning "not generated UE NAS files: binaries not found"
fi
......@@ -637,15 +642,12 @@ function main() {
cd $DIR/nas_sim_tools/build
cmake ..
compilations \
nas_sim_tools usim \
usim $dbin/usim
compilations \
nas_sim_tools nvram \
nvram $dbin/nvram
nas_sim_tools conf2uedata \
conf2uedata $dbin/conf2uedata
# generate USIM data
if [ -f $dbin/nvram ]; then
install_nas_tools $dbin $dconf
if [ -f $dbin/conf2uedata ]; then
install_nas_tools $conf_nvram_path $gen_nvram_path
else
echo_warning "not generated UE NAS files: binaries not found"
fi
......
......@@ -2,25 +2,21 @@ cmake_minimum_required(VERSION 2.8)
project(NAS_SIM_TOOLS)
include(FindPkgConfig)
pkg_search_module(CONFIG libconfig REQUIRED)
include_directories(${CONFIG_INCLUDE_DIRS})
add_definitions(-std=gnu99)
ENABLE_LANGUAGE(C)
#Sends the -std=c99 flag to the gcc compiler
add_definitions(-std=c99)
add_definitions(-DNAS_UE)
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat")
set(OPENAIR_DIR $ENV{OPENAIR_DIR})
set(OPENAIR1_DIR $ENV{OPENAIR_DIR}/openair1)
set(OPENAIR2_DIR $ENV{OPENAIR_DIR}/openair2)
set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
set(OPENAIR_TARGETS $ENV{OPENAIR_DIR}/targets)
#set(EXECUTABLE_OUTPUT_PATH ${OPENAIR_DIR}/targets/bin)
# Add .h files for dependancies
set(usim_SRC
${OPENAIR_DIR}/openair3/NAS/TOOLS/usim_data.c
set(conf2uedata_SRC
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.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
......@@ -29,8 +25,9 @@ set(usim_SRC
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.c
${OPENAIR_DIR}/common/utils/utils.c
)
set(usim_HDR
${OPENAIR_DIR}/openair3/NAS/TOOLS/network.h
set(conf2uedata_HDR
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.h
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.h
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.h
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.h
......@@ -39,37 +36,18 @@ set(usim_HDR
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.h
${OPENAIR_DIR}/common/utils/utils.h
)
include_directories(
${OPENAIR_DIR}/common/utils
${OPENAIR_DIR}/openair3/NAS/UE
${OPENAIR_DIR}/openair3/NAS/COMMON
${OPENAIR_DIR}/openair3/NAS/UE/API/USER
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM
${OPENAIR_DIR}/openair3/NAS/UE/EMM/
${OPENAIR_DIR}/openair3/NAS/UE/ESM/
${OPENAIR_DIR}/openair3/NAS/COMMON/IES/
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL
)
ADD_EXECUTABLE(usim ${usim_SRC} ${usim_HDR})
set(nvram_SRC
${OPENAIR_DIR}/openair3/NAS/TOOLS/ue_data.c
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.c
)
set(nvram_HDR
${OPENAIR_DIR}/openair3/NAS/UE/EMM/emmData.h
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.h
${OPENAIR_DIR}/openair3/NAS/COMMON/userDef.h
)
ADD_EXECUTABLE(nvram ${nvram_SRC} ${nvram_HDR})
#install (TARGETS usim DESTINATION ${EXECUTABLE_OUTPUT_PATH})
#install (TARGETS nvram DESTINATION ${EXECUTABLE_OUTPUT_PATH})
#install(CODE "EXECUTE_PROCESS (COMMAND ${OPENAIR_TARGETS}/bin/nvram --gen WORKING_DIRECTORY ${OPENAIR_TARGETS}/bin)")
#install(CODE "EXECUTE_PROCESS (COMMAND ${OPENAIR_TARGETS}/bin/usim --gen WORKING_DIRECTORY ${OPENAIR_TARGETS}/bin)")
ADD_EXECUTABLE(conf2uedata ${conf2uedata_SRC} ${conf2uedata_HDR})
target_link_libraries(conf2uedata ${CONFIG_LIBRARIES})
......@@ -450,24 +450,13 @@ install_asn1c_from_source(){
################################################
install_nas_tools() {
cd $1
if [ ! -f .ue.nvram ]; then
echo_success "generate .ue_emm.nvram .ue.nvram"
./nvram --gen
else
[ ./nvram -nt .ue.nvram -o ./nvram -nt .ue_emm.nvram ] && ./nvram --gen
fi
if [ ! -f .usim.nvram ]; then
echo_success "generate .usim.nvram"
./usim --gen
else
[ ./usim -nt .usim.nvram ] && ./usim --gen
if [ ! -f $2/§.ue.nvram -o ! -f $2/.usim.nvram ]; then
cd $OPENAIR_DIR/targets/bin
./conf2uedata -c $1 -o $2
echo_success "$1 $2"
fi
}
################################
# set_openair_env
###############################
......
......@@ -103,6 +103,30 @@ char* memory_get_path(const char* dirname, const char* filename)
return data_filename;
}
char* memory_get_path_from_ueid(const char* dirname, const char* filename, int ueid)
{
/* Get non-volatile data directory */
const char* path = getenv(dirname);
char buffer[2048];
if (path == NULL) {
path = getenv(DEFAULT_NAS_PATH);
}
if (path == NULL) {
LOG_TRACE(WARNING, "MEMORY - %s and %s environment variables are not defined trying local directory", dirname, DEFAULT_NAS_PATH);
path = ".";
}
/* Append non-volatile data file name */
if ( snprintf(buffer, sizeof(buffer), "%s/%s%d", path, filename, ueid) < 0 ) {
return NULL;
}
return strdup(buffer);
}
/****************************************************************************
** **
** Name: memory_read() **
......
......@@ -58,6 +58,8 @@ Description Memory access utilities
char* memory_get_path(const char* dirname, const char* filename);
char* memory_get_path_from_ueid(const char* dirname, const char* filename, int ueid);
int memory_read(const char* datafile, void* data, size_t size);
int memory_write(const char* datafile, const void* data, size_t size);
......
#/*
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under
# * the OAI Public License, Version 1.0 (the "License"); you may not use this file
# * except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.openairinterface.org/?page_id=698
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance:
# * contact@openairinterface.org
# */
export PROCESS = UE
ifndef PROJDIR
PROJDIR = $(PWD)/..
endif
include $(PROJDIR)/Makerules
include $(PROJDIR)/Makefile.inc
include $(PROJDIR)/../Makefile.tools
export LD_RUN_PATH = $(LIBDIR):$(LIBPROCESS)
LIBS = -luenas.a -lrt
INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(USIMAPIDIR) -I$(EMMDIR) -I$(ESMDIR) -I$(IESDIR)
#LIBSUTIL = $(LIBDIR)/$(LIBUTIL).a $(LIBDIR)/$(LIBUTIL).so
USIM_OBJ = usim_data.o
UE_OBJ = ue_data.o
USIM_TARGET = usim_data
UE_TARGET = ue_data
TARGETS = $(USIM_TARGET) $(UE_TARGET)
all: $(TARGETS)
#-DIMSI_USA_MNC_3DIGITS
%.o: %.c Makefile
$(CC) $(CFLAGS) -c $< -o $@
$(USIM_TARGET): $(USIM_OBJ) $(LIBSUTIL)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) -lnettle -lcrypto -lm
@echo Replacing $@ to $(BINDIR)
@$(RM) $(BINDIR)/$@
@$(CP) $@ $(BINDIR)
$(UE_TARGET): $(UE_OBJ) $(LIBSUTIL)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) -lnettle -lcrypto -lm
@echo Replacing $@ to $(BINDIR)
@$(RM) $(BINDIR)/$@
@$(CP) $@ $(BINDIR)
clean:
$(RM) $(OBJS) *.bak *~
veryclean: clean
$(RM) $(TARGETS)
veryveryclean: veryclean
$(RM) -Rf *.o $(PROJDIR)
$(RM) -Rf *.a $(PROJDIR)
depend:
makedepend -- ${CFLAGS} -- ${SRCS}
# DO NOT DELETE THIS LINE -- make depend depends on it.
#include <stdio.h> // perror, printf, fprintf, snprintf
#include <stdlib.h> // exit, free
#include <string.h> // memset, strncpy
#include "conf2uedata.h"
#include "user_api.h"
#include "utils.h"
char * make_filename(const char *output_dir, const char *filename, int ueid);
int main(int argc, char**argv) {
int rc = EXIT_SUCCESS;
int option;
while ((option = getopt(argc, argv, options)) != -1) {
switch (option) {
case 'c':
parse_data = TRUE;
conf_file = optarg;
break;
case 'o':
output_dir = optarg;
output = TRUE;
break;
case 'h':
_display_usage();
return EXIT_SUCCESS;
break;
default:
break;
}
}
if (output == FALSE && parse_data == TRUE) {
printf("No output option found\n");
_display_usage();
return EXIT_FAILURE;
} else if (output == TRUE && parse_data == FALSE) {
printf("No Configuration file is given\n");
_display_usage();
return EXIT_FAILURE;
} else if (parse_data == FALSE && print_data == FALSE) {
printf("No options found\n");
_display_usage();
return EXIT_FAILURE;
} else if (parse_data) {
int ue_nb = 0;
config_t cfg;
config_setting_t *root_setting = NULL;
config_setting_t *ue_setting = NULL;
config_setting_t *all_plmn_setting = NULL;
char user[10];
config_init(&cfg);
if (conf_file != NULL) {
/* Read the file. If there is an error, report it and exit. */
if (!config_read_file(&cfg, conf_file)) {
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg);
return (EXIT_FAILURE);
}
} else {
config_destroy(&cfg);
perror("ERROR\t: config_read failed");
exit(EXIT_FAILURE);
}
root_setting = config_root_setting(&cfg);
ue_nb = config_setting_length(root_setting) - 1;
all_plmn_setting = config_setting_get_member(root_setting, PLMN);
if (all_plmn_setting != NULL) {
rc = parse_plmns(all_plmn_setting);
if (rc == EXIT_FAILURE) {
return rc;
}
fill_network_record_list();
for (int i = 0; i < ue_nb; i++) {
sprintf(user, "%s%d", UE, i);
ue_setting = config_setting_get_member(root_setting, user);
if (ue_setting != NULL) {
rc = parse_ue_user_param(ue_setting, i);
if (rc != EXIT_SUCCESS) {
printf("Problem in USER section for UE%d. EXITING...\n",
i);
return EXIT_FAILURE;
}
_display_ue_data(i);
rc = parse_ue_sim_param(ue_setting, i);
if (rc != EXIT_SUCCESS) {
printf("Problem in SIM section for UE%d. EXITING...\n",
i);
return EXIT_FAILURE;
}
rc = parse_ue_plmn_param(ue_setting, i);
if (rc != EXIT_SUCCESS) {
return EXIT_FAILURE;
}
gen_emm_data(i);
_display_emm_data(i);
gen_usim_data(i);
_display_usim_data(i);
} else {
printf("Check UE%d settings\n", i);
return EXIT_FAILURE;
}
}
config_destroy(&cfg);
} else {
printf("NO PLMN SECTION...EXITING...\n");
return (EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
void gen_usim_data(int user_id) {
usim_data_t usim_data = { };
memset(&usim_data, 0, sizeof(usim_data_t));
usim_data.imsi.length = 8;
usim_data.imsi.u.num.parity = get_msin_parity(msin);
usim_data.imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0];
usim_data.imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1];
usim_data.imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2];
usim_data.imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0];
usim_data.imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1];
if (strlen(user_plmn_list[hplmn_index].mnc) == 2) {
usim_data.imsi.u.num.digit6 = msin[0];
usim_data.imsi.u.num.digit7 = msin[1];
usim_data.imsi.u.num.digit8 = msin[2];
usim_data.imsi.u.num.digit9 = msin[3];
usim_data.imsi.u.num.digit10 = msin[4];
usim_data.imsi.u.num.digit11 = msin[5];
usim_data.imsi.u.num.digit12 = msin[6];
usim_data.imsi.u.num.digit13 = msin[7];
usim_data.imsi.u.num.digit14 = msin[8];
usim_data.imsi.u.num.digit15 = msin[9];
} else {
usim_data.imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2];
usim_data.imsi.u.num.digit7 = msin[0];
usim_data.imsi.u.num.digit8 = msin[1];
usim_data.imsi.u.num.digit9 = msin[2];
usim_data.imsi.u.num.digit10 = msin[3];
usim_data.imsi.u.num.digit11 = msin[4];
usim_data.imsi.u.num.digit12 = msin[5];
usim_data.imsi.u.num.digit13 = msin[6];
usim_data.imsi.u.num.digit14 = msin[7];
usim_data.imsi.u.num.digit15 = msin[8];
}
/*
* Ciphering and Integrity Keys
*/
usim_data.keys.ksi = KSI;
memset(&usim_data.keys.ck, 0, USIM_CK_SIZE);
memset(&usim_data.keys.ik, 0, USIM_IK_SIZE);
/*
* Higher Priority PLMN search period
*/
usim_data.hpplmn = 0x00; /* Disable timer */
/*
* List of Forbidden PLMNs
*/
for (int i = 0; i < USIM_FPLMN_MAX; i++) {
memset(&usim_data.fplmn[i], 0xff, sizeof(plmn_t));
}
if (fplmn_nb > 0) {
for (int i = 0; i < fplmn_nb; i++) {
usim_data.fplmn[i] = user_network_record_list[fplmn[i]].plmn;
}
}
/*
* Location Information
*/
usim_data.loci.tmsi = DEFAULT_TMSI;
usim_data.loci.lai.plmn = user_network_record_list[hplmn_index].plmn;
usim_data.loci.lai.lac = DEFAULT_LAC;
usim_data.loci.status = USIM_LOCI_NOT_UPDATED;
/*
* Packet Switched Location Information
*/
usim_data.psloci.p_tmsi = DEFAULT_P_TMSI;
usim_data.psloci.signature[0] = 0x01;
usim_data.psloci.signature[1] = 0x02;
usim_data.psloci.signature[2] = 0x03;
usim_data.psloci.rai.plmn = user_network_record_list[hplmn_index].plmn;
usim_data.psloci.rai.lac = DEFAULT_LAC;
usim_data.psloci.rai.rac = DEFAULT_RAC;
usim_data.psloci.status = USIM_PSLOCI_NOT_UPDATED;
/*
* Administrative Data
*/
usim_data.ad.UE_Operation_Mode = USIM_NORMAL_MODE;
usim_data.ad.Additional_Info = 0xffff;
usim_data.ad.MNC_Length = strlen(user_plmn_list[hplmn_index].mnc);
/*
* EPS NAS security context
*/
usim_data.securityctx.length = 52;
usim_data.securityctx.KSIasme.type = USIM_KSI_ASME_TAG;
usim_data.securityctx.KSIasme.length = 1;
usim_data.securityctx.KSIasme.value[0] = KSI_ASME;
usim_data.securityctx.Kasme.type = USIM_K_ASME_TAG;
usim_data.securityctx.Kasme.length = USIM_K_ASME_SIZE;
memset(usim_data.securityctx.Kasme.value, 0,
usim_data.securityctx.Kasme.length);
usim_data.securityctx.ulNAScount.type = USIM_UL_NAS_COUNT_TAG;
usim_data.securityctx.ulNAScount.length = USIM_UL_NAS_COUNT_SIZE;
memset(usim_data.securityctx.ulNAScount.value, 0,
usim_data.securityctx.ulNAScount.length);
usim_data.securityctx.dlNAScount.type = USIM_DL_NAS_COUNT_TAG;
usim_data.securityctx.dlNAScount.length = USIM_DL_NAS_COUNT_SIZE;
memset(usim_data.securityctx.dlNAScount.value, 0,
usim_data.securityctx.dlNAScount.length);
usim_data.securityctx.algorithmID.type = USIM_INT_ENC_ALGORITHMS_TAG;
usim_data.securityctx.algorithmID.length = 1;
usim_data.securityctx.algorithmID.value[0] = SECURITY_ALGORITHMS;
/*
* Subcriber's Number
*/
usim_data.msisdn.length = 7;
usim_data.msisdn.number.ext = 1;
usim_data.msisdn.number.ton = MSISDN_TON_UNKNOWKN;
usim_data.msisdn.number.npi = MSISDN_NPI_ISDN_TELEPHONY;
usim_data.msisdn.conf1_record_id = 0xff; /* Not used */
usim_data.msisdn.ext1_record_id = 0xff; /* Not used */
int j = 0;
for (int i = 0; i < strlen(msisdn); i += 2) {
usim_data.msisdn.number.digit[j].msb = msisdn[i];
j++;
}
j = 0;
for (int i = 1; i < strlen(msisdn); i += 2) {
usim_data.msisdn.number.digit[j].lsb = msisdn[i];
j++;
}
if (strlen(msisdn) % 2 == 0) {
for (int i = strlen(msisdn) / 2; i < 10; i++) {
usim_data.msisdn.number.digit[i].msb = 0xf;
usim_data.msisdn.number.digit[i].lsb = 0xf;
}
} else {
usim_data.msisdn.number.digit[strlen(msisdn) / 2].lsb = 0xf;
for (int i = (strlen(msisdn) / 2) + 1; i < 10; i++) {
usim_data.msisdn.number.digit[i].msb = 0xf;
usim_data.msisdn.number.digit[i].lsb = 0xf;
}
}
/*
* PLMN Network Name and Operator PLMN List
*/
for (int i = 0; i < oplmn_nb; i++) {
network_record_t record = user_network_record_list[oplmn[i]];
usim_data.pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG;
usim_data.pnn[i].fullname.length = strlen(record.fullname);
strncpy((char*) usim_data.pnn[i].fullname.value, record.fullname,
usim_data.pnn[i].fullname.length);
usim_data.pnn[i].shortname.type = USIM_PNN_SHORTNAME_TAG;
usim_data.pnn[i].shortname.length = strlen(record.shortname);
strncpy((char*) usim_data.pnn[i].shortname.value, record.shortname,
usim_data.pnn[i].shortname.length);
usim_data.opl[i].plmn = record.plmn;
usim_data.opl[i].start = record.tac_start;
usim_data.opl[i].end = record.tac_end;
usim_data.opl[i].record_id = i;
}
if (oplmn_nb < USIM_OPL_MAX) {
for (int i = oplmn_nb; i < USIM_OPL_MAX; i++) {
memset(&usim_data.opl[i].plmn, 0xff, sizeof(plmn_t));
}
}
/*
* List of Equivalent HPLMNs
*/
for (int i = 0; i < ehplmn_nb; i++) {
usim_data.ehplmn[i] = user_network_record_list[ehplmn[i]].plmn;
}
if (ehplmn_nb < USIM_EHPLMN_MAX) {
for (int i = ehplmn_nb; i < USIM_EHPLMN_MAX; i++) {
memset(&usim_data.ehplmn[i], 0xff, sizeof(plmn_t));
}
}
/*
* Home PLMN Selector with Access Technology