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/
This commit is contained in:
committed by
Frédéric Leroy
parent
c4707bd8b7
commit
17d155325a
+23
-21
@@ -82,7 +82,7 @@ Options
|
|||||||
--eNB
|
--eNB
|
||||||
Makes the LTE softmodem
|
Makes the LTE softmodem
|
||||||
--UE
|
--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
|
--RRH
|
||||||
Makes the RRH
|
Makes the RRH
|
||||||
-a | --agent
|
-a | --agent
|
||||||
@@ -145,6 +145,10 @@ Usage (Regular):
|
|||||||
|
|
||||||
|
|
||||||
function main() {
|
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" ]
|
until [ -z "$1" ]
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@@ -182,7 +186,16 @@ function main() {
|
|||||||
--UE)
|
--UE)
|
||||||
UE=1
|
UE=1
|
||||||
echo_info "Will compile UE"
|
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)
|
||||||
RRH=1
|
RRH=1
|
||||||
echo_info "Will compile RRH"
|
echo_info "Will compile RRH"
|
||||||
@@ -507,20 +520,12 @@ function main() {
|
|||||||
|
|
||||||
cmake ..
|
cmake ..
|
||||||
compilations \
|
compilations \
|
||||||
nas_sim_tools usim \
|
nas_sim_tools conf2uedata \
|
||||||
usim $dbin/usim
|
conf2uedata $dbin/conf2uedata
|
||||||
compilations \
|
|
||||||
nas_sim_tools nvram \
|
|
||||||
nvram $dbin/nvram
|
|
||||||
|
|
||||||
# generate USIM data
|
# generate USIM data
|
||||||
if [ -f $dbin/nvram ]; then
|
if [ -f $dbin/conf2uedata ]; then
|
||||||
install_nas_tools $dbin $dconf
|
install_nas_tools $conf_nvram_path $gen_nvram_path
|
||||||
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
|
|
||||||
|
|
||||||
else
|
else
|
||||||
echo_warning "not generated UE NAS files: binaries not found"
|
echo_warning "not generated UE NAS files: binaries not found"
|
||||||
fi
|
fi
|
||||||
@@ -637,15 +642,12 @@ function main() {
|
|||||||
cd $DIR/nas_sim_tools/build
|
cd $DIR/nas_sim_tools/build
|
||||||
cmake ..
|
cmake ..
|
||||||
compilations \
|
compilations \
|
||||||
nas_sim_tools usim \
|
nas_sim_tools conf2uedata \
|
||||||
usim $dbin/usim
|
conf2uedata $dbin/conf2uedata
|
||||||
compilations \
|
|
||||||
nas_sim_tools nvram \
|
|
||||||
nvram $dbin/nvram
|
|
||||||
|
|
||||||
# generate USIM data
|
# generate USIM data
|
||||||
if [ -f $dbin/nvram ]; then
|
if [ -f $dbin/conf2uedata ]; then
|
||||||
install_nas_tools $dbin $dconf
|
install_nas_tools $conf_nvram_path $gen_nvram_path
|
||||||
else
|
else
|
||||||
echo_warning "not generated UE NAS files: binaries not found"
|
echo_warning "not generated UE NAS files: binaries not found"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -2,25 +2,21 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
|
|
||||||
project(NAS_SIM_TOOLS)
|
project(NAS_SIM_TOOLS)
|
||||||
|
|
||||||
|
include(FindPkgConfig)
|
||||||
|
pkg_search_module(CONFIG libconfig REQUIRED)
|
||||||
|
include_directories(${CONFIG_INCLUDE_DIRS})
|
||||||
|
add_definitions(-std=gnu99)
|
||||||
|
|
||||||
ENABLE_LANGUAGE(C)
|
ENABLE_LANGUAGE(C)
|
||||||
#Sends the -std=c99 flag to the gcc compiler
|
|
||||||
add_definitions(-std=c99)
|
set(CMAKE_C_FLAGS
|
||||||
add_definitions(-DNAS_UE)
|
"${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat")
|
||||||
|
|
||||||
set(OPENAIR_DIR $ENV{OPENAIR_DIR})
|
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(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
|
|
||||||
set(OPENAIR_TARGETS $ENV{OPENAIR_DIR}/targets)
|
|
||||||
|
|
||||||
#set(EXECUTABLE_OUTPUT_PATH ${OPENAIR_DIR}/targets/bin)
|
set(conf2uedata_SRC
|
||||||
|
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c
|
||||||
|
|
||||||
# Add .h files for dependancies
|
|
||||||
set(usim_SRC
|
|
||||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/usim_data.c
|
|
||||||
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.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/UE/API/USIM/aka_functions.c
|
||||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.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}/openair3/NAS/COMMON/UTIL/TLVEncoder.c
|
||||||
${OPENAIR_DIR}/common/utils/utils.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/usim_api.h
|
||||||
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.h
|
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.h
|
||||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.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}/openair3/NAS/COMMON/UTIL/TLVEncoder.h
|
||||||
${OPENAIR_DIR}/common/utils/utils.h
|
${OPENAIR_DIR}/common/utils/utils.h
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${OPENAIR_DIR}/common/utils
|
${OPENAIR_DIR}/common/utils
|
||||||
${OPENAIR_DIR}/openair3/NAS/UE
|
${OPENAIR_DIR}/openair3/NAS/UE
|
||||||
${OPENAIR_DIR}/openair3/NAS/COMMON
|
${OPENAIR_DIR}/openair3/NAS/COMMON
|
||||||
|
${OPENAIR_DIR}/openair3/NAS/UE/API/USER
|
||||||
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM
|
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM
|
||||||
${OPENAIR_DIR}/openair3/NAS/UE/EMM/
|
${OPENAIR_DIR}/openair3/NAS/UE/EMM/
|
||||||
${OPENAIR_DIR}/openair3/NAS/UE/ESM/
|
${OPENAIR_DIR}/openair3/NAS/UE/ESM/
|
||||||
${OPENAIR_DIR}/openair3/NAS/COMMON/IES/
|
${OPENAIR_DIR}/openair3/NAS/COMMON/IES/
|
||||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL
|
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL
|
||||||
)
|
)
|
||||||
ADD_EXECUTABLE(usim ${usim_SRC} ${usim_HDR})
|
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(conf2uedata ${conf2uedata_SRC} ${conf2uedata_HDR})
|
||||||
|
target_link_libraries(conf2uedata ${CONFIG_LIBRARIES})
|
||||||
|
|
||||||
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)")
|
|
||||||
|
|||||||
@@ -450,24 +450,13 @@ install_asn1c_from_source(){
|
|||||||
################################################
|
################################################
|
||||||
|
|
||||||
install_nas_tools() {
|
install_nas_tools() {
|
||||||
cd $1
|
if [ ! -f $2/§.ue.nvram -o ! -f $2/.usim.nvram ]; then
|
||||||
if [ ! -f .ue.nvram ]; then
|
cd $OPENAIR_DIR/targets/bin
|
||||||
echo_success "generate .ue_emm.nvram .ue.nvram"
|
./conf2uedata -c $1 -o $2
|
||||||
./nvram --gen
|
echo_success "$1 $2"
|
||||||
else
|
|
||||||
[ ./nvram -nt .ue.nvram -o ./nvram -nt .ue_emm.nvram ] && ./nvram --gen
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f .usim.nvram ]; then
|
|
||||||
echo_success "generate .usim.nvram"
|
|
||||||
./usim --gen
|
|
||||||
else
|
|
||||||
[ ./usim -nt .usim.nvram ] && ./usim --gen
|
|
||||||
fi
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
# set_openair_env
|
# set_openair_env
|
||||||
###############################
|
###############################
|
||||||
|
|||||||
@@ -103,6 +103,30 @@ char* memory_get_path(const char* dirname, const char* filename)
|
|||||||
return data_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() **
|
** 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(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_read(const char* datafile, void* data, size_t size);
|
||||||
|
|
||||||
int memory_write(const char* datafile, const void* data, size_t size);
|
int memory_write(const char* datafile, const void* data, size_t size);
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
#/*
|
|
||||||
# * 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.
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
|||||||
|
#ifndef _CONF2UEDATA_H
|
||||||
|
#define _CONF2UEDATA_H
|
||||||
|
|
||||||
|
#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"
|
||||||
|
#define SIM "SIM"
|
||||||
|
#define PLMN "PLMN"
|
||||||
|
|
||||||
|
#define FULLNAME "FULLNAME"
|
||||||
|
#define SHORTNAME "SHORTNAME"
|
||||||
|
#define MNC "MNC"
|
||||||
|
#define MCC "MCC"
|
||||||
|
|
||||||
|
#define MSIN "MSIN"
|
||||||
|
#define USIM_API_K "USIM_API_K"
|
||||||
|
#define OPC "OPC"
|
||||||
|
#define MSISDN "MSISDN"
|
||||||
|
|
||||||
|
#define UE_IMEI "IMEI"
|
||||||
|
#define MANUFACTURER "MANUFACTURER"
|
||||||
|
#define MODEL "MODEL"
|
||||||
|
#define PINCODE "PIN"
|
||||||
|
|
||||||
|
#define HPLMN "HPLMN"
|
||||||
|
#define UCPLMN "UCPLMN_LIST"
|
||||||
|
#define OPLMN "OPLMN_LIST"
|
||||||
|
#define OCPLMN "OCPLMN_LIST"
|
||||||
|
#define FPLMN "FPLMN_LIST"
|
||||||
|
#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
|
||||||
|
#define ENC_ALGO USIM_ENC_EEA0
|
||||||
|
#define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO)
|
||||||
|
#define OPC_SIZE 16
|
||||||
|
#define MIN_TAC 0x0000
|
||||||
|
#define MAX_TAC 0xFFFE
|
||||||
|
|
||||||
|
#define DEFAULT_TMSI 0x0000000D
|
||||||
|
#define DEFAULT_P_TMSI 0x0000000D
|
||||||
|
#define DEFAULT_M_TMSI 0x0000000D
|
||||||
|
#define DEFAULT_LAC 0xFFFE
|
||||||
|
#define DEFAULT_RAC 0x01
|
||||||
|
#define DEFAULT_TAC 0x0001
|
||||||
|
|
||||||
|
#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
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned int num;
|
||||||
|
plmn_t plmn;
|
||||||
|
char fullname[NET_FORMAT_LONG_SIZE + 1];
|
||||||
|
char shortname[NET_FORMAT_SHORT_SIZE + 1];
|
||||||
|
tac_t tac_start;
|
||||||
|
tac_t tac_end;
|
||||||
|
} network_record_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char* fullname;
|
||||||
|
const char* shortname;
|
||||||
|
const char* mnc;
|
||||||
|
const char* mcc;
|
||||||
|
} plmn_conf_param_t;
|
||||||
|
|
||||||
|
const char options[]="c:o:h";
|
||||||
|
unsigned char parse_data=FALSE;
|
||||||
|
unsigned char print_data=FALSE;
|
||||||
|
unsigned char output=FALSE;
|
||||||
|
const char* conf_file = NULL;
|
||||||
|
const char* output_dir = NULL;
|
||||||
|
|
||||||
|
const char* imsi=NULL;
|
||||||
|
const char* msin=NULL;
|
||||||
|
const char* usim_api_k = NULL;
|
||||||
|
const char* msisdn = NULL;
|
||||||
|
const char* opc=NULL;
|
||||||
|
const char* hplmn=NULL;
|
||||||
|
|
||||||
|
int* ucplmn=NULL;
|
||||||
|
int* oplmn=NULL;
|
||||||
|
int* ocplmn=NULL;
|
||||||
|
int* fplmn=NULL;
|
||||||
|
int* ehplmn=NULL;
|
||||||
|
|
||||||
|
int hplmn_index =0;
|
||||||
|
int plmn_nb = 0;
|
||||||
|
int ucplmn_nb=0;
|
||||||
|
int oplmn_nb=0;
|
||||||
|
int ocplmn_nb=0;
|
||||||
|
int fplmn_nb=0;
|
||||||
|
int ehplmn_nb=0;
|
||||||
|
|
||||||
|
plmn_conf_param_t* user_plmn_list=NULL;
|
||||||
|
network_record_t* user_network_record_list = NULL;
|
||||||
|
|
||||||
|
void _display_usim_data(int user_id);
|
||||||
|
|
||||||
|
void _display_usage(void);
|
||||||
|
void gen_emm_data(int user_id) ;
|
||||||
|
void gen_usim_data(int user_id);
|
||||||
|
void fill_network_record_list(void);
|
||||||
|
|
||||||
|
int _luhn(const char* cc);
|
||||||
|
|
||||||
|
void _display_ue_data(int user_id);
|
||||||
|
|
||||||
|
void _display_emm_data(int user_id);
|
||||||
|
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);
|
||||||
|
int parse_plmns(config_setting_t *all_plmn_setting);
|
||||||
|
int get_msin_parity(const char * msin);
|
||||||
|
int get_plmn_index(const char * mccmnc);
|
||||||
|
int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id);
|
||||||
|
int fill_ucplmn(config_setting_t* setting, int use_id);
|
||||||
|
int fill_oplmn(config_setting_t* setting, int use_id);
|
||||||
|
int fill_ocplmn(config_setting_t* setting, int use_id);
|
||||||
|
int fill_fplmn(config_setting_t* setting, int use_id);
|
||||||
|
int fill_ehplmn(config_setting_t* setting, int use_id);
|
||||||
|
|
||||||
|
#endif // _CONF2UEDATA_H
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,536 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
Source ue_data.c
|
|
||||||
|
|
||||||
Version 0.1
|
|
||||||
|
|
||||||
Date 2012/11/02
|
|
||||||
|
|
||||||
Product UE data generator
|
|
||||||
|
|
||||||
Subsystem UE data generator main process
|
|
||||||
|
|
||||||
Author Frederic Maurel
|
|
||||||
|
|
||||||
Description Implements the utility used to generate data stored in the
|
|
||||||
UE's non-volatile memory device
|
|
||||||
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "userDef.h"
|
|
||||||
#include "memory.h"
|
|
||||||
|
|
||||||
#include "emmData.h"
|
|
||||||
#include "network.h"
|
|
||||||
|
|
||||||
#include <stdio.h> // perror, printf, fprintf, snprintf
|
|
||||||
#include <stdlib.h> // exit, free
|
|
||||||
#include <string.h> // memset, strncpy
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
#define USER_IMEI "35611302209414"
|
|
||||||
#define USER_MANUFACTURER "EURECOM"
|
|
||||||
#define USER_MODEL "LTE Android PC"
|
|
||||||
//#define USER_MANUFACTURER "SAGEM"
|
|
||||||
//#define USER_MODEL "my225x"
|
|
||||||
#define USER_PIN "0000"
|
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/******************* L O C A L D E F I N I T I O N S *******************/
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
static void _display_usage(const char* command);
|
|
||||||
|
|
||||||
static void _gen_user_data(user_nvdata_t* data);
|
|
||||||
static void _gen_emm_data(emm_nvdata_t* data);
|
|
||||||
|
|
||||||
static int _luhn(const char* cc);
|
|
||||||
static void _display_ue_data(const user_nvdata_t* data);
|
|
||||||
static void _display_emm_data(const emm_nvdata_t* data);
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/****************** E X P O R T E D F U N C T I O N S ******************/
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
int main (int argc, const char* argv[])
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
char* path;
|
|
||||||
user_nvdata_t user_data;
|
|
||||||
emm_nvdata_t emm_data;
|
|
||||||
|
|
||||||
unsigned char gen_data;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ----------------------------
|
|
||||||
* Read command line parameters
|
|
||||||
* ----------------------------
|
|
||||||
*/
|
|
||||||
if (argc != 2) {
|
|
||||||
fprintf(stderr, "Invalid parameter\n");
|
|
||||||
_display_usage(argv[0]);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else if ( (strcmp(argv[1], "--gen") == 0) ||
|
|
||||||
(strcmp(argv[1], "-g") == 0) ) {
|
|
||||||
/* Generate UE data files */
|
|
||||||
gen_data = TRUE;
|
|
||||||
} else if ( (strcmp(argv[1], "--print") == 0) ||
|
|
||||||
(strcmp(argv[1], "-p") == 0) ) {
|
|
||||||
/* Display content of UE data files */
|
|
||||||
gen_data = FALSE;
|
|
||||||
} else {
|
|
||||||
/* Display usage */
|
|
||||||
_display_usage(argv[0]);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* ----------------------
|
|
||||||
* UE's non-volatile data
|
|
||||||
* ----------------------
|
|
||||||
*/
|
|
||||||
path = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME);
|
|
||||||
|
|
||||||
if (path == NULL) {
|
|
||||||
perror("ERROR\t: memory_get_path() failed");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gen_data) {
|
|
||||||
/*
|
|
||||||
* Initialize UE's non-volatile data
|
|
||||||
*/
|
|
||||||
memset(&user_data, 0, sizeof(user_nvdata_t));
|
|
||||||
_gen_user_data(&user_data);
|
|
||||||
/*
|
|
||||||
* Write UE's non-volatile data
|
|
||||||
*/
|
|
||||||
rc = memory_write(path, &user_data, sizeof(user_nvdata_t));
|
|
||||||
|
|
||||||
if (rc != RETURNok) {
|
|
||||||
perror("ERROR\t: memory_write() failed");
|
|
||||||
free(path);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read UE's non-volatile data
|
|
||||||
*/
|
|
||||||
memset(&user_data, 0, sizeof(user_nvdata_t));
|
|
||||||
rc = memory_read(path, &user_data, sizeof(user_nvdata_t));
|
|
||||||
|
|
||||||
if (rc != RETURNok) {
|
|
||||||
perror("ERROR\t: memory_read() failed");
|
|
||||||
free(path);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(path);
|
|
||||||
/*
|
|
||||||
* Display UE's non-volatile data
|
|
||||||
*/
|
|
||||||
printf("\nUE's non-volatile data:\n\n");
|
|
||||||
_display_ue_data(&user_data);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ---------------------
|
|
||||||
* EMM non-volatile data
|
|
||||||
* ---------------------
|
|
||||||
*/
|
|
||||||
path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME);
|
|
||||||
|
|
||||||
if (path == NULL) {
|
|
||||||
perror("ERROR\t: memory_get_path() failed");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gen_data) {
|
|
||||||
/*
|
|
||||||
* Initialize EMM non-volatile data
|
|
||||||
*/
|
|
||||||
memset(&emm_data, 0, sizeof(emm_nvdata_t));
|
|
||||||
_gen_emm_data(&emm_data);
|
|
||||||
/*
|
|
||||||
* Write EMM non-volatile data
|
|
||||||
*/
|
|
||||||
rc = memory_write(path, &emm_data, sizeof(emm_nvdata_t));
|
|
||||||
|
|
||||||
if (rc != RETURNok) {
|
|
||||||
perror("ERROR\t: memory_write() failed");
|
|
||||||
free(path);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read EMM non-volatile data
|
|
||||||
*/
|
|
||||||
memset(&emm_data, 0, sizeof(emm_nvdata_t));
|
|
||||||
rc = memory_read(path, &emm_data, sizeof(emm_nvdata_t));
|
|
||||||
|
|
||||||
if (rc != RETURNok) {
|
|
||||||
perror("ERROR\t: memory_read() failed ");
|
|
||||||
free(path);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(path);
|
|
||||||
/*
|
|
||||||
* Display EMM non-volatile data
|
|
||||||
*/
|
|
||||||
printf("\nEMM non-volatile data:\n\n");
|
|
||||||
_display_emm_data(&emm_data);
|
|
||||||
|
|
||||||
/*
|
|
||||||
*---------------
|
|
||||||
* Files location
|
|
||||||
*---------------
|
|
||||||
*/
|
|
||||||
path = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME);
|
|
||||||
printf("\nUE identity data file: %s\n", path);
|
|
||||||
free(path);
|
|
||||||
path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME);
|
|
||||||
printf("EPS Mobility Management data file: %s\n", path);
|
|
||||||
free(path);
|
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/********************* L O C A L F U N C T I O N S *********************/
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Displays command line usage
|
|
||||||
*/
|
|
||||||
static void _display_usage(const char* command)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "usage: %s [OPTION]\n", command);
|
|
||||||
fprintf(stderr, "\t[--gen|-g]\tGenerate the UE data files\n");
|
|
||||||
fprintf(stderr, "\t[--print|-p]\tDisplay the content of the UE data files\n");
|
|
||||||
fprintf(stderr, "\t[--help|-h]\tDisplay this usage\n");
|
|
||||||
const char* path = getenv("NVRAM_DIR");
|
|
||||||
|
|
||||||
if (path != NULL) {
|
|
||||||
fprintf(stderr, "NVRAM_DIR = %s\n", path);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "NVRAM_DIR environment variable is not defined\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generates UE's non-volatile data
|
|
||||||
*/
|
|
||||||
static void _gen_user_data(user_nvdata_t* data)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Product Serial Number Identification
|
|
||||||
* IMEI = AA-BBBBBB-CCCCCC-D
|
|
||||||
* AA-BBBBBB: Type Allocation Code (TAC)
|
|
||||||
* CCCCCC: Serial Number
|
|
||||||
* D: Luhn check digit
|
|
||||||
*/
|
|
||||||
snprintf(data->IMEI, USER_IMEI_SIZE+1, "%s%d",
|
|
||||||
USER_IMEI, _luhn(USER_IMEI));
|
|
||||||
/*
|
|
||||||
* Manufacturer identifier
|
|
||||||
*/
|
|
||||||
strncpy(data->manufacturer, USER_MANUFACTURER, USER_MANUFACTURER_SIZE);
|
|
||||||
/*
|
|
||||||
* Model identifier
|
|
||||||
*/
|
|
||||||
strncpy(data->model, USER_MODEL, USER_MODEL_SIZE);
|
|
||||||
/*
|
|
||||||
* SIM Personal Identification Number
|
|
||||||
*/
|
|
||||||
strncpy(data->PIN, USER_PIN, USER_PIN_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generates UE's non-volatile EMM data
|
|
||||||
*/
|
|
||||||
static void _gen_emm_data(emm_nvdata_t* data)
|
|
||||||
{
|
|
||||||
#if (SELECTED_PLMN == FCT1)
|
|
||||||
/*
|
|
||||||
* International Mobile Subscriber Identity
|
|
||||||
* IMSI = MCC + MNC + MSIN = 310 (USA) + 028 (UNKNOWN) + 90832150
|
|
||||||
*/
|
|
||||||
#warning "IMSI 310.028.90832150"
|
|
||||||
data->imsi.length = 8;
|
|
||||||
data->imsi.u.num.parity = 0x0; // Type of identity = IMSI, even
|
|
||||||
data->imsi.u.num.digit1 = 3; // MCC digit 1
|
|
||||||
data->imsi.u.num.digit2 = 1; // MCC digit 2
|
|
||||||
data->imsi.u.num.digit3 = 0; // MCC digit 3
|
|
||||||
data->imsi.u.num.digit4 = 0; // MNC digit 1
|
|
||||||
data->imsi.u.num.digit5 = 2; // MNC digit 2
|
|
||||||
data->imsi.u.num.digit6 = 8; // MNC digit 3
|
|
||||||
data->imsi.u.num.digit7 = 9;
|
|
||||||
data->imsi.u.num.digit8 = 0;
|
|
||||||
data->imsi.u.num.digit9 = 8;
|
|
||||||
data->imsi.u.num.digit10 = 3;
|
|
||||||
data->imsi.u.num.digit11 = 2;
|
|
||||||
data->imsi.u.num.digit12 = 1;
|
|
||||||
data->imsi.u.num.digit13 = 5;
|
|
||||||
data->imsi.u.num.digit14 = 0;
|
|
||||||
data->imsi.u.num.digit15 = 0xF;
|
|
||||||
/*
|
|
||||||
* Last registered home PLMN
|
|
||||||
*/
|
|
||||||
data->rplmn.MCCdigit1 = 3;
|
|
||||||
data->rplmn.MCCdigit2 = 1;
|
|
||||||
data->rplmn.MCCdigit3 = 0;
|
|
||||||
data->rplmn.MNCdigit1 = 0;
|
|
||||||
data->rplmn.MNCdigit2 = 2;
|
|
||||||
data->rplmn.MNCdigit3 = 8;
|
|
||||||
#endif
|
|
||||||
#if (SELECTED_PLMN == SFR1)
|
|
||||||
/*
|
|
||||||
* International Mobile Subscriber Identity
|
|
||||||
* IMSI = MCC + MNC + MSIN = 208 (France) + 10 (SFR) + 00001234
|
|
||||||
*/
|
|
||||||
data->imsi.length = 8;
|
|
||||||
data->imsi.u.num.parity = 0x0; // Type of identity = IMSI, even
|
|
||||||
data->imsi.u.num.digit1 = 2; // MCC digit 1
|
|
||||||
data->imsi.u.num.digit2 = 0; // MCC digit 2
|
|
||||||
data->imsi.u.num.digit3 = 8; // MCC digit 3
|
|
||||||
data->imsi.u.num.digit4 = 1; // MNC digit 1
|
|
||||||
data->imsi.u.num.digit5 = 0; // MNC digit 2
|
|
||||||
data->imsi.u.num.digit6 = 0;//0xF; // MNC digit 3
|
|
||||||
data->imsi.u.num.digit7 = 0;
|
|
||||||
data->imsi.u.num.digit8 = 0;
|
|
||||||
data->imsi.u.num.digit9 = 0;
|
|
||||||
data->imsi.u.num.digit10 = 0;
|
|
||||||
data->imsi.u.num.digit11 = 1;
|
|
||||||
data->imsi.u.num.digit12 = 2;
|
|
||||||
data->imsi.u.num.digit13 = 3;
|
|
||||||
data->imsi.u.num.digit14 = 4;
|
|
||||||
data->imsi.u.num.digit15 = 0xF;
|
|
||||||
|
|
||||||
data->rplmn.MCCdigit1 = 2;
|
|
||||||
data->rplmn.MCCdigit2 = 0;
|
|
||||||
data->rplmn.MCCdigit3 = 8;
|
|
||||||
data->rplmn.MNCdigit1 = 1;
|
|
||||||
data->rplmn.MNCdigit2 = 0;
|
|
||||||
data->rplmn.MNCdigit3 = 0xf;
|
|
||||||
#endif
|
|
||||||
#if (SELECTED_PLMN == OAI_LTEBOX)
|
|
||||||
/*
|
|
||||||
* International Mobile Subscriber Identity
|
|
||||||
* IMSI = MCC + MNC + MSIN = 208 (France) + 93 (OAI) + 00001110
|
|
||||||
*/
|
|
||||||
data->imsi.length = 8;
|
|
||||||
data->imsi.u.num.parity = ODD_PARITY; // Type of identity = IMSI, even
|
|
||||||
data->imsi.u.num.digit1 = 2; // MCC digit 1
|
|
||||||
data->imsi.u.num.digit2 = 0; // MCC digit 2
|
|
||||||
data->imsi.u.num.digit3 = 8; // MCC digit 3
|
|
||||||
data->imsi.u.num.digit4 = 9; // MNC digit 1
|
|
||||||
data->imsi.u.num.digit5 = 3; // MNC digit 2
|
|
||||||
data->imsi.u.num.digit6 = 0; // MNC digit 3
|
|
||||||
data->imsi.u.num.digit7 = 1;
|
|
||||||
data->imsi.u.num.digit8 = 0;
|
|
||||||
data->imsi.u.num.digit9 = 0;
|
|
||||||
data->imsi.u.num.digit10 = 0;
|
|
||||||
data->imsi.u.num.digit11 = 0;
|
|
||||||
data->imsi.u.num.digit12 = 1;
|
|
||||||
data->imsi.u.num.digit13 = 1;
|
|
||||||
data->imsi.u.num.digit14 = 1;
|
|
||||||
data->imsi.u.num.digit15 = 1;
|
|
||||||
|
|
||||||
data->rplmn.MCCdigit1 = 2;
|
|
||||||
data->rplmn.MCCdigit2 = 0;
|
|
||||||
data->rplmn.MCCdigit3 = 8;
|
|
||||||
data->rplmn.MNCdigit1 = 9;
|
|
||||||
data->rplmn.MNCdigit2 = 3;
|
|
||||||
data->rplmn.MNCdigit3 = 0xf;
|
|
||||||
#endif
|
|
||||||
#if (SELECTED_PLMN == TEST1)
|
|
||||||
/*
|
|
||||||
* International Mobile Subscriber Identity
|
|
||||||
* IMSI = MCC + MNC + MSIN = 001 + 01 + 00001234
|
|
||||||
*/
|
|
||||||
data->imsi.length = 8;
|
|
||||||
data->imsi.u.num.parity = 0x0; // Type of identity = IMSI, even
|
|
||||||
data->imsi.u.num.digit1 = 0; // MCC digit 1
|
|
||||||
data->imsi.u.num.digit2 = 0; // MCC digit 2
|
|
||||||
data->imsi.u.num.digit3 = 1; // MCC digit 3
|
|
||||||
data->imsi.u.num.digit4 = 0; // MNC digit 1
|
|
||||||
data->imsi.u.num.digit5 = 1; // MNC digit 2
|
|
||||||
data->imsi.u.num.digit6 = 0;
|
|
||||||
data->imsi.u.num.digit7 = 0;
|
|
||||||
data->imsi.u.num.digit8 = 0;
|
|
||||||
data->imsi.u.num.digit9 = 0;
|
|
||||||
data->imsi.u.num.digit10 = 0;
|
|
||||||
data->imsi.u.num.digit11 = 1;
|
|
||||||
data->imsi.u.num.digit12 = 2;
|
|
||||||
data->imsi.u.num.digit13 = 3;
|
|
||||||
data->imsi.u.num.digit14 = 4;
|
|
||||||
data->imsi.u.num.digit15 = 0xF;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Last registered home PLMN
|
|
||||||
*/
|
|
||||||
data->rplmn.MCCdigit1 = 0;
|
|
||||||
data->rplmn.MCCdigit2 = 0;
|
|
||||||
data->rplmn.MCCdigit3 = 1;
|
|
||||||
data->rplmn.MNCdigit1 = 0;
|
|
||||||
data->rplmn.MNCdigit2 = 1;
|
|
||||||
data->rplmn.MNCdigit3 = 0xf;
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* List of Equivalent PLMNs
|
|
||||||
*/
|
|
||||||
data->eplmn.n_plmns = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Computes the check digit using Luhn algorithm
|
|
||||||
*/
|
|
||||||
static int _luhn(const char* cc)
|
|
||||||
{
|
|
||||||
const int m[] = {0,2,4,6,8,1,3,5,7,9};
|
|
||||||
int odd = 1, sum = 0;
|
|
||||||
|
|
||||||
for (int i = strlen(cc); i--; odd = !odd) {
|
|
||||||
int digit = cc[i] - '0';
|
|
||||||
sum += odd ? m[digit] : digit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 10 - (sum % 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Displays UE's non-volatile data
|
|
||||||
*/
|
|
||||||
static void _display_ue_data(const user_nvdata_t* data)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
static void _display_emm_data(const emm_nvdata_t* data)
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
# List of known PLMNS
|
||||||
|
PLMN: {
|
||||||
|
PLMN0: {
|
||||||
|
FULLNAME="Test network";
|
||||||
|
SHORTNAME="OAI4G";
|
||||||
|
MNC="01";
|
||||||
|
MCC="001";
|
||||||
|
|
||||||
|
};
|
||||||
|
PLMN1: {
|
||||||
|
FULLNAME="SFR France";
|
||||||
|
SHORTNAME="SFR";
|
||||||
|
MNC="10";
|
||||||
|
MCC="208";
|
||||||
|
|
||||||
|
};
|
||||||
|
PLMN2: {
|
||||||
|
FULLNAME="SFR France";
|
||||||
|
SHORTNAME="SFR";
|
||||||
|
MNC="11";
|
||||||
|
MCC="208";
|
||||||
|
};
|
||||||
|
PLMN3: {
|
||||||
|
FULLNAME="SFR France";
|
||||||
|
SHORTNAME="SFR";
|
||||||
|
MNC="13";
|
||||||
|
MCC="208";
|
||||||
|
};
|
||||||
|
PLMN4: {
|
||||||
|
FULLNAME="OAI LTEBOX";
|
||||||
|
SHORTNAME="OAIALU";
|
||||||
|
MNC="93";
|
||||||
|
MCC="208";
|
||||||
|
};
|
||||||
|
PLMN5: {
|
||||||
|
FULLNAME="T-Mobile USA";
|
||||||
|
SHORTNAME="T-Mobile";
|
||||||
|
MNC="280";
|
||||||
|
MCC="310";
|
||||||
|
};
|
||||||
|
PLMN6: {
|
||||||
|
FULLNAME="FICTITIOUS USA";
|
||||||
|
SHORTNAME="FICTITIO";
|
||||||
|
MNC="028";
|
||||||
|
MCC="310";
|
||||||
|
};
|
||||||
|
PLMN7: {
|
||||||
|
FULLNAME="Vodafone Italia";
|
||||||
|
SHORTNAME="VODAFONE";
|
||||||
|
MNC="10";
|
||||||
|
MCC="222";
|
||||||
|
};
|
||||||
|
PLMN8: {
|
||||||
|
FULLNAME="Vodafone Spain";
|
||||||
|
SHORTNAME="VODAFONE";
|
||||||
|
MNC="01";
|
||||||
|
MCC="214";
|
||||||
|
};
|
||||||
|
PLMN9: {
|
||||||
|
FULLNAME="Vodafone Spain";
|
||||||
|
SHORTNAME="VODAFONE";
|
||||||
|
MNC="06";
|
||||||
|
MCC="214";
|
||||||
|
};
|
||||||
|
PLMN10: {
|
||||||
|
FULLNAME="Vodafone Germ";
|
||||||
|
SHORTNAME="VODAFONE";
|
||||||
|
MNC="02";
|
||||||
|
MCC="262";
|
||||||
|
};
|
||||||
|
PLMN11: {
|
||||||
|
FULLNAME="Vodafone Germ";
|
||||||
|
SHORTNAME="VODAFONE";
|
||||||
|
MNC="04";
|
||||||
|
MCC="262";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
UE0:
|
||||||
|
{
|
||||||
|
USER: {
|
||||||
|
IMEI="356113022094149";
|
||||||
|
MANUFACTURER="EURECOM";
|
||||||
|
MODEL="LTE Android PC";
|
||||||
|
PIN="0000";
|
||||||
|
};
|
||||||
|
|
||||||
|
SIM: {
|
||||||
|
MSIN="0000001234";
|
||||||
|
USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f";
|
||||||
|
OPC="00000000000000000000000000000000";
|
||||||
|
MSISDN="33611123456";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Home PLMN Selector with Access Technology
|
||||||
|
HPLMN= "20810";
|
||||||
|
|
||||||
|
# User controlled PLMN Selector with Access Technology
|
||||||
|
UCPLMN_LIST = ();
|
||||||
|
|
||||||
|
# Operator PLMN List
|
||||||
|
OPLMN_LIST = ("00101", "20810", "20811", "20813", "310280", "310028");
|
||||||
|
|
||||||
|
# Operator controlled PLMN Selector with Access Technology
|
||||||
|
OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204");
|
||||||
|
|
||||||
|
# Forbidden plmns
|
||||||
|
FPLMN_LIST = ();
|
||||||
|
|
||||||
|
# List of Equivalent HPLMNs
|
||||||
|
EHPLMN_LIST= ("20811", "20813");
|
||||||
|
};
|
||||||
@@ -1,668 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
Source usim_data.c
|
|
||||||
|
|
||||||
Version 0.1
|
|
||||||
|
|
||||||
Date 2012/10/31
|
|
||||||
|
|
||||||
Product USIM data generator
|
|
||||||
|
|
||||||
Subsystem USIM data generator main process
|
|
||||||
|
|
||||||
Author Frederic Maurel
|
|
||||||
|
|
||||||
Description Implements the utility used to generate data stored in the
|
|
||||||
USIM application
|
|
||||||
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "network.h"
|
|
||||||
|
|
||||||
#include "usim_api.h"
|
|
||||||
#include "memory.h"
|
|
||||||
#include "network.h"
|
|
||||||
|
|
||||||
#include <stdio.h> // perror, printf
|
|
||||||
#include <stdlib.h> // exit
|
|
||||||
#include <string.h> // memset, memcpy, strncpy
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
#define KSI USIM_KSI_NOT_AVAILABLE
|
|
||||||
#define KSI_ASME USIM_KSI_NOT_AVAILABLE
|
|
||||||
#define INT_ALGO USIM_INT_EIA2
|
|
||||||
#define ENC_ALGO USIM_ENC_EEA0
|
|
||||||
#define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO)
|
|
||||||
|
|
||||||
#define MIN_TAC 0x0000
|
|
||||||
#define MAX_TAC 0xFFFE
|
|
||||||
|
|
||||||
#define DEFAULT_TMSI 0x0000000D
|
|
||||||
#define DEFAULT_P_TMSI 0x0000000D
|
|
||||||
#define DEFAULT_M_TMSI 0x0000000D
|
|
||||||
#define DEFAULT_LAC 0xFFFE
|
|
||||||
#define DEFAULT_RAC 0x01
|
|
||||||
#define DEFAULT_TAC 0x0001
|
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/******************* L O C A L D E F I N I T I O N S *******************/
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
static void _display_usage(const char* command);
|
|
||||||
|
|
||||||
static void _display_usim_data(const usim_data_t* data);
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/****************** E X P O R T E D F U N C T I O N S ******************/
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
int main (int argc, const char* argv[])
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
usim_data_t usim_data;
|
|
||||||
|
|
||||||
unsigned char gen_data;
|
|
||||||
|
|
||||||
/* Get USIM application pathname */
|
|
||||||
char* path = memory_get_path(USIM_API_NVRAM_DIRNAME,
|
|
||||||
USIM_API_NVRAM_FILENAME);
|
|
||||||
|
|
||||||
if (path == NULL) {
|
|
||||||
fprintf(stderr, "USIM-API - Failed to get USIM pathname");
|
|
||||||
free(path);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read command line parameters
|
|
||||||
*/
|
|
||||||
if (argc != 2) {
|
|
||||||
fprintf(stderr, "Invalid parameter\n");
|
|
||||||
_display_usage(argv[0]);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else if ( (strcmp(argv[1], "--gen") == 0) ||
|
|
||||||
(strcmp(argv[1], "-g") == 0) ) {
|
|
||||||
/* Generate USIM data files */
|
|
||||||
gen_data = TRUE;
|
|
||||||
} else if ( (strcmp(argv[1], "--print") == 0) ||
|
|
||||||
(strcmp(argv[1], "-p") == 0) ) {
|
|
||||||
/* Display content of USIM data files */
|
|
||||||
gen_data = FALSE;
|
|
||||||
} else {
|
|
||||||
/* Display usage */
|
|
||||||
_display_usage(argv[0]);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gen_data) {
|
|
||||||
/*
|
|
||||||
* Initialize USIM data
|
|
||||||
*/
|
|
||||||
memset(&usim_data, 0, sizeof(usim_data_t));
|
|
||||||
|
|
||||||
#if (SELECTED_PLMN == FCT1)
|
|
||||||
/*
|
|
||||||
* International Mobile Subscriber Identity
|
|
||||||
* IMSI = MCC + MNC + MSIN = 310 (USA) + 028 (UNKNOWN) + 90832150
|
|
||||||
*/
|
|
||||||
#warning "IMSI 310.028.90832150"
|
|
||||||
usim_data.imsi.length = 8;
|
|
||||||
usim_data.imsi.u.num.parity = EVEN_PARITY; // Parity: even
|
|
||||||
usim_data.imsi.u.num.digit1 = 3; // MCC digit 1
|
|
||||||
usim_data.imsi.u.num.digit2 = 1; // MCC digit 2
|
|
||||||
usim_data.imsi.u.num.digit3 = 0; // MCC digit 3
|
|
||||||
usim_data.imsi.u.num.digit4 = 0; // MNC digit 1
|
|
||||||
usim_data.imsi.u.num.digit5 = 2; // MNC digit 2
|
|
||||||
usim_data.imsi.u.num.digit6 = 8; // MNC digit 3
|
|
||||||
usim_data.imsi.u.num.digit7 = 9;
|
|
||||||
usim_data.imsi.u.num.digit8 = 0;
|
|
||||||
usim_data.imsi.u.num.digit9 = 8;
|
|
||||||
usim_data.imsi.u.num.digit10 = 3;
|
|
||||||
usim_data.imsi.u.num.digit11 = 2;
|
|
||||||
usim_data.imsi.u.num.digit12 = 1;
|
|
||||||
usim_data.imsi.u.num.digit13 = 5;
|
|
||||||
usim_data.imsi.u.num.digit14 = 0;
|
|
||||||
usim_data.imsi.u.num.digit15 = 0b1111;
|
|
||||||
#endif
|
|
||||||
#if (SELECTED_PLMN == SFR1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* International Mobile Subscriber Identity
|
|
||||||
* IMSI = MCC + MNC + MSIN = 208 (France) + 10 (SFR) + 00001234
|
|
||||||
*/
|
|
||||||
#warning "IMSI 208.10.00001234"
|
|
||||||
|
|
||||||
usim_data.imsi.length = 8;
|
|
||||||
usim_data.imsi.u.num.parity = EVEN_PARITY; // Parity: even
|
|
||||||
usim_data.imsi.u.num.digit1 = 2; // MCC digit 1
|
|
||||||
usim_data.imsi.u.num.digit2 = 0; // MCC digit 2
|
|
||||||
usim_data.imsi.u.num.digit3 = 8; // MCC digit 3
|
|
||||||
usim_data.imsi.u.num.digit4 = 1; // MNC digit 1
|
|
||||||
usim_data.imsi.u.num.digit5 = 0; // MNC digit 2
|
|
||||||
usim_data.imsi.u.num.digit6 = 0;//0b1111; // MNC digit 3
|
|
||||||
usim_data.imsi.u.num.digit7 = 0;
|
|
||||||
usim_data.imsi.u.num.digit8 = 0;
|
|
||||||
usim_data.imsi.u.num.digit9 = 0;
|
|
||||||
usim_data.imsi.u.num.digit10 = 0;
|
|
||||||
usim_data.imsi.u.num.digit11 = 1;
|
|
||||||
usim_data.imsi.u.num.digit12 = 2;
|
|
||||||
usim_data.imsi.u.num.digit13 = 3;
|
|
||||||
usim_data.imsi.u.num.digit14 = 4;
|
|
||||||
usim_data.imsi.u.num.digit15 = 0b1111;
|
|
||||||
#endif
|
|
||||||
#if (SELECTED_PLMN == OAI_LTEBOX)
|
|
||||||
/*
|
|
||||||
* International Mobile Subscriber Identity
|
|
||||||
* IMSI = MCC + MNC + MSIN = 208 (France) + 10 (SFR) + 00001234
|
|
||||||
*/
|
|
||||||
#warning "IMSI 208.93.0100001111"
|
|
||||||
usim_data.imsi.length = 8;
|
|
||||||
usim_data.imsi.u.num.parity = ODD_PARITY; // Parity: even
|
|
||||||
usim_data.imsi.u.num.digit1 = 2; // MCC digit 1
|
|
||||||
usim_data.imsi.u.num.digit2 = 0; // MCC digit 2
|
|
||||||
usim_data.imsi.u.num.digit3 = 8; // MCC digit 3
|
|
||||||
usim_data.imsi.u.num.digit4 = 9; // MNC digit 1
|
|
||||||
usim_data.imsi.u.num.digit5 = 3; // MNC digit 2
|
|
||||||
usim_data.imsi.u.num.digit6 = 0; // MNC digit 3
|
|
||||||
usim_data.imsi.u.num.digit7 = 1;
|
|
||||||
usim_data.imsi.u.num.digit8 = 0;
|
|
||||||
usim_data.imsi.u.num.digit9 = 0;
|
|
||||||
usim_data.imsi.u.num.digit10 = 0;
|
|
||||||
usim_data.imsi.u.num.digit11 = 0;
|
|
||||||
usim_data.imsi.u.num.digit12 = 1;
|
|
||||||
usim_data.imsi.u.num.digit13 = 1;
|
|
||||||
usim_data.imsi.u.num.digit14 = 1;
|
|
||||||
usim_data.imsi.u.num.digit15 = 1;
|
|
||||||
#endif
|
|
||||||
#if (SELECTED_PLMN == TEST1)
|
|
||||||
#warning "IMSI 001.01.000001234"
|
|
||||||
usim_data.imsi.length = 8;
|
|
||||||
usim_data.imsi.u.num.parity = 0x0; // Type of identity = IMSI, even
|
|
||||||
usim_data.imsi.u.num.digit1 = 0; // MCC digit 1
|
|
||||||
usim_data.imsi.u.num.digit2 = 0; // MCC digit 2
|
|
||||||
usim_data.imsi.u.num.digit3 = 1; // MCC digit 3
|
|
||||||
usim_data.imsi.u.num.digit4 = 0; // MNC digit 1
|
|
||||||
usim_data.imsi.u.num.digit5 = 1; // MNC digit 2
|
|
||||||
usim_data.imsi.u.num.digit6 = 0;
|
|
||||||
usim_data.imsi.u.num.digit7 = 0;
|
|
||||||
usim_data.imsi.u.num.digit8 = 0;
|
|
||||||
usim_data.imsi.u.num.digit9 = 0;
|
|
||||||
usim_data.imsi.u.num.digit10 = 0;
|
|
||||||
usim_data.imsi.u.num.digit11 = 1;
|
|
||||||
usim_data.imsi.u.num.digit12 = 2;
|
|
||||||
usim_data.imsi.u.num.digit13 = 3;
|
|
||||||
usim_data.imsi.u.num.digit14 = 4;
|
|
||||||
usim_data.imsi.u.num.digit15 = 0xF;
|
|
||||||
usim_data.usimtestmode = 1; // set usim in test mode in order to get the CMW500 K key
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Location Information
|
|
||||||
*/
|
|
||||||
usim_data.loci.tmsi = DEFAULT_TMSI;
|
|
||||||
usim_data.loci.lai.plmn = network_records[SELECTED_PLMN].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 = network_records[SELECTED_PLMN].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 = 2;
|
|
||||||
/*
|
|
||||||
* 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.number.digit[0].msb = 3;
|
|
||||||
usim_data.msisdn.number.digit[0].lsb = 3;
|
|
||||||
usim_data.msisdn.number.digit[1].msb = 6;
|
|
||||||
usim_data.msisdn.number.digit[1].lsb = 1;
|
|
||||||
usim_data.msisdn.number.digit[2].msb = 1;
|
|
||||||
usim_data.msisdn.number.digit[2].lsb = 1;
|
|
||||||
usim_data.msisdn.number.digit[3].msb = 2;
|
|
||||||
usim_data.msisdn.number.digit[3].lsb = 3;
|
|
||||||
usim_data.msisdn.number.digit[4].msb = 4;
|
|
||||||
usim_data.msisdn.number.digit[4].lsb = 5;
|
|
||||||
usim_data.msisdn.number.digit[5].msb = 6;
|
|
||||||
usim_data.msisdn.number.digit[5].lsb = 0xf;
|
|
||||||
usim_data.msisdn.number.digit[6].msb = 0xf;
|
|
||||||
usim_data.msisdn.number.digit[6].lsb = 0xf;
|
|
||||||
usim_data.msisdn.number.digit[7].msb = 0xf;
|
|
||||||
usim_data.msisdn.number.digit[7].lsb = 0xf;
|
|
||||||
usim_data.msisdn.number.digit[8].msb = 0xf;
|
|
||||||
usim_data.msisdn.number.digit[8].lsb = 0xf;
|
|
||||||
usim_data.msisdn.number.digit[9].msb = 0xf;
|
|
||||||
usim_data.msisdn.number.digit[9].lsb = 0xf;
|
|
||||||
usim_data.msisdn.conf1_record_id = 0xff; /* Not used */
|
|
||||||
usim_data.msisdn.ext1_record_id = 0xff; /* Not used */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PLMN Network Name and Operator PLMN List
|
|
||||||
*/
|
|
||||||
for (int i = TEST1; i < VDF1; i++) {
|
|
||||||
network_record_t record = network_records[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;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = VDF2; i < USIM_OPL_MAX; i++) {
|
|
||||||
memset(&usim_data.opl[i].plmn, 0xff, sizeof(plmn_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* List of Equivalent HPLMNs
|
|
||||||
*/
|
|
||||||
usim_data.ehplmn[0] = network_records[SFR2].plmn;
|
|
||||||
usim_data.ehplmn[1] = network_records[SFR3].plmn;
|
|
||||||
/*
|
|
||||||
* Home PLMN Selector with Access Technology
|
|
||||||
*/
|
|
||||||
usim_data.hplmn.plmn = network_records[SELECTED_PLMN].plmn;
|
|
||||||
usim_data.hplmn.AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* List of user controlled PLMN selector with Access Technology
|
|
||||||
*/
|
|
||||||
for (int i = 0; i < USIM_PLMN_MAX; i++) {
|
|
||||||
memset(&usim_data.plmn[i], 0xff, sizeof(plmn_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* List of operator controlled PLMN selector with Access Technology
|
|
||||||
*/
|
|
||||||
usim_data.oplmn[0].plmn = network_records[VDF1].plmn;
|
|
||||||
usim_data.oplmn[0].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN);
|
|
||||||
usim_data.oplmn[1].plmn = network_records[VDF2].plmn;
|
|
||||||
usim_data.oplmn[1].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN);
|
|
||||||
usim_data.oplmn[2].plmn = network_records[VDF3].plmn;
|
|
||||||
usim_data.oplmn[2].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN);
|
|
||||||
usim_data.oplmn[3].plmn = network_records[VDF4].plmn;
|
|
||||||
usim_data.oplmn[3].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN);
|
|
||||||
usim_data.oplmn[4].plmn = network_records[VDF5].plmn;
|
|
||||||
usim_data.oplmn[4].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN);
|
|
||||||
|
|
||||||
for (int i = 5; i < USIM_OPLMN_MAX; i++) {
|
|
||||||
memset(&usim_data.oplmn[i], 0xff, sizeof(plmn_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* EPS Location Information
|
|
||||||
*/
|
|
||||||
usim_data.epsloci.guti.gummei.plmn = network_records[SELECTED_PLMN].plmn;
|
|
||||||
usim_data.epsloci.guti.gummei.MMEgid = DEFAULT_MME_ID;
|
|
||||||
usim_data.epsloci.guti.gummei.MMEcode = DEFAULT_MME_CODE;
|
|
||||||
usim_data.epsloci.guti.m_tmsi = DEFAULT_M_TMSI;
|
|
||||||
usim_data.epsloci.tai.plmn = usim_data.epsloci.guti.gummei.plmn;
|
|
||||||
usim_data.epsloci.tai.tac = DEFAULT_TAC;
|
|
||||||
usim_data.epsloci.status = USIM_EPSLOCI_UPDATED;
|
|
||||||
/*
|
|
||||||
* Non-Access Stratum configuration
|
|
||||||
*/
|
|
||||||
usim_data.nasconfig.NAS_SignallingPriority.type = USIM_NAS_SIGNALLING_PRIORITY_TAG;
|
|
||||||
usim_data.nasconfig.NAS_SignallingPriority.length = 1;
|
|
||||||
usim_data.nasconfig.NAS_SignallingPriority.value[0] = 0x00;
|
|
||||||
usim_data.nasconfig.NMO_I_Behaviour.type = USIM_NMO_I_BEHAVIOUR_TAG;
|
|
||||||
usim_data.nasconfig.NMO_I_Behaviour.length = 1;
|
|
||||||
usim_data.nasconfig.NMO_I_Behaviour.value[0] = 0x00;
|
|
||||||
usim_data.nasconfig.AttachWithImsi.type = USIM_ATTACH_WITH_IMSI_TAG;
|
|
||||||
usim_data.nasconfig.AttachWithImsi.length = 1;
|
|
||||||
#if defined(START_WITH_GUTI)
|
|
||||||
usim_data.nasconfig.AttachWithImsi.value[0] = 0x00;
|
|
||||||
#else
|
|
||||||
usim_data.nasconfig.AttachWithImsi.value[0] = 0x01;
|
|
||||||
#endif
|
|
||||||
usim_data.nasconfig.MinimumPeriodicSearchTimer.type = USIM_MINIMUM_PERIODIC_SEARCH_TIMER_TAG;
|
|
||||||
usim_data.nasconfig.MinimumPeriodicSearchTimer.length = 1;
|
|
||||||
usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0] = 0x00;
|
|
||||||
usim_data.nasconfig.ExtendedAccessBarring.type = USIM_EXTENDED_ACCESS_BARRING_TAG;
|
|
||||||
usim_data.nasconfig.ExtendedAccessBarring.length = 1;
|
|
||||||
usim_data.nasconfig.ExtendedAccessBarring.value[0] = 0x00;
|
|
||||||
usim_data.nasconfig.Timer_T3245_Behaviour.type = USIM_TIMER_T3245_BEHAVIOUR_TAG;
|
|
||||||
usim_data.nasconfig.Timer_T3245_Behaviour.length = 1;
|
|
||||||
usim_data.nasconfig.Timer_T3245_Behaviour.value[0] = 0x00;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write USIM application data
|
|
||||||
*/
|
|
||||||
rc = usim_api_write(path, &usim_data);
|
|
||||||
|
|
||||||
if (rc != RETURNok) {
|
|
||||||
perror("ERROR\t: usim_api_write() failed");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read USIM application data
|
|
||||||
*/
|
|
||||||
memset(&usim_data, 0, sizeof(usim_data_t));
|
|
||||||
rc = usim_api_read(path, &usim_data);
|
|
||||||
|
|
||||||
if (rc != RETURNok) {
|
|
||||||
perror("ERROR\t: usim_api_read() failed");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Display USIM application data
|
|
||||||
*/
|
|
||||||
printf("\nUSIM data:\n\n");
|
|
||||||
_display_usim_data(&usim_data);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Display USIM file location
|
|
||||||
*/
|
|
||||||
printf("\nUSIM data file: %s\n", path);
|
|
||||||
free(path);
|
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/********************* L O C A L F U N C T I O N S *********************/
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Displays command line usage
|
|
||||||
*/
|
|
||||||
static void _display_usage(const char* command)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "usage: %s [OPTION]\n", command);
|
|
||||||
fprintf(stderr, "\t[--gen|-g]\tGenerate the USIM data file\n");
|
|
||||||
fprintf(stderr, "\t[--print|-p]\tDisplay the content of the USIM data file\n");
|
|
||||||
fprintf(stderr, "\t[--help|-h]\tDisplay this usage\n");
|
|
||||||
const char* path = getenv("USIM_DIR");
|
|
||||||
|
|
||||||
if (path != NULL) {
|
|
||||||
fprintf(stderr, "USIM_DIR = %s\n", path);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "USIM_DIR environment variable is not defined\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Displays USIM application data
|
|
||||||
*/
|
|
||||||
static void _display_usim_data(const usim_data_t* data)
|
|
||||||
{
|
|
||||||
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==0xf?0: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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -49,16 +49,14 @@
|
|||||||
*
|
*
|
||||||
*-----------------------------------------------------------------*/
|
*-----------------------------------------------------------------*/
|
||||||
void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2],
|
void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2],
|
||||||
u8 mac_a_pP[8], const u8 op[16])
|
u8 mac_a_pP[8], const u8 op_c[16])
|
||||||
{
|
{
|
||||||
u8 op_c[16];
|
|
||||||
u8 temp[16];
|
u8 temp[16];
|
||||||
u8 in1[16];
|
u8 in1[16];
|
||||||
u8 out1[16];
|
u8 out1[16];
|
||||||
u8 rijndaelInput[16];
|
u8 rijndaelInput[16];
|
||||||
u8 i;
|
u8 i;
|
||||||
RijndaelKeySchedule( k_pP );
|
RijndaelKeySchedule( k_pP );
|
||||||
ComputeOPc(op, op_c);
|
|
||||||
|
|
||||||
for (i=0; i<16; i++)
|
for (i=0; i<16; i++)
|
||||||
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
|
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
|
||||||
@@ -104,9 +102,8 @@ void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2],
|
|||||||
*
|
*
|
||||||
*-----------------------------------------------------------------*/
|
*-----------------------------------------------------------------*/
|
||||||
void f2345 ( u8 k_pP[16], u8 rand_pP[16],
|
void f2345 ( u8 k_pP[16], u8 rand_pP[16],
|
||||||
u8 res_pP[8], u8 ck_pP[16], u8 ik_pP[16], u8 ak_pP[6],const u8 op[16])
|
u8 res_pP[8], u8 ck_pP[16], u8 ik_pP[16], u8 ak_pP[6],const u8 op_c[16])
|
||||||
{
|
{
|
||||||
u8 op_c[16];
|
|
||||||
u8 temp[16];
|
u8 temp[16];
|
||||||
u8 out[16];
|
u8 out[16];
|
||||||
u8 rijndaelInput[16];
|
u8 rijndaelInput[16];
|
||||||
@@ -122,7 +119,6 @@ void f2345 ( u8 k_pP[16], u8 rand_pP[16],
|
|||||||
rand_pP[8],rand_pP[9],rand_pP[10],rand_pP[11],rand_pP[12],rand_pP[13],rand_pP[14],rand_pP[15]);
|
rand_pP[8],rand_pP[9],rand_pP[10],rand_pP[11],rand_pP[12],rand_pP[13],rand_pP[14],rand_pP[15]);
|
||||||
|
|
||||||
RijndaelKeySchedule( k_pP );
|
RijndaelKeySchedule( k_pP );
|
||||||
ComputeOPc(op, op_c);
|
|
||||||
|
|
||||||
for (i=0; i<16; i++)
|
for (i=0; i<16; i++)
|
||||||
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
|
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
|
||||||
@@ -205,16 +201,14 @@ void f2345 ( u8 k_pP[16], u8 rand_pP[16],
|
|||||||
*
|
*
|
||||||
*-----------------------------------------------------------------*/
|
*-----------------------------------------------------------------*/
|
||||||
void f1star( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2],
|
void f1star( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2],
|
||||||
u8 mac_s_pP[8],const u8 op[16])
|
u8 mac_s_pP[8],const u8 op_c[16])
|
||||||
{
|
{
|
||||||
u8 op_c[16];
|
|
||||||
u8 temp[16];
|
u8 temp[16];
|
||||||
u8 in1[16];
|
u8 in1[16];
|
||||||
u8 out1[16];
|
u8 out1[16];
|
||||||
u8 rijndaelInput[16];
|
u8 rijndaelInput[16];
|
||||||
u8 i;
|
u8 i;
|
||||||
RijndaelKeySchedule( k_pP );
|
RijndaelKeySchedule( k_pP );
|
||||||
ComputeOPc(op, op_c);
|
|
||||||
|
|
||||||
for (i=0; i<16; i++)
|
for (i=0; i<16; i++)
|
||||||
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
|
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
|
||||||
@@ -260,15 +254,13 @@ void f1star( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2],
|
|||||||
*
|
*
|
||||||
*-----------------------------------------------------------------*/
|
*-----------------------------------------------------------------*/
|
||||||
void f5star( u8 k_pP[16], u8 rand_pP[16],
|
void f5star( u8 k_pP[16], u8 rand_pP[16],
|
||||||
u8 ak_pP[6], const u8 op[16])
|
u8 ak_pP[6], const u8 op_c[16])
|
||||||
{
|
{
|
||||||
u8 op_c[16];
|
|
||||||
u8 temp[16];
|
u8 temp[16];
|
||||||
u8 out[16];
|
u8 out[16];
|
||||||
u8 rijndaelInput[16];
|
u8 rijndaelInput[16];
|
||||||
u8 i;
|
u8 i;
|
||||||
RijndaelKeySchedule( k_pP );
|
RijndaelKeySchedule( k_pP );
|
||||||
ComputeOPc(op, op_c);
|
|
||||||
|
|
||||||
for (i=0; i<16; i++)
|
for (i=0; i<16; i++)
|
||||||
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
|
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
|
||||||
|
|||||||
@@ -88,22 +88,6 @@ int usim_api_read(const char *filename, usim_data_t* data)
|
|||||||
LOG_FUNC_RETURN (RETURNerror);
|
LOG_FUNC_RETURN (RETURNerror);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize the subscriber authentication security key */
|
|
||||||
hex_string_to_hex_value(data->keys.usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE);
|
|
||||||
|
|
||||||
// initialize OP
|
|
||||||
/* PFT OP used currently in HSS (OPENAIRHSS/auc/kdf.c) */
|
|
||||||
#define OAI_LTEBOX
|
|
||||||
|
|
||||||
#ifdef OAI_LTEBOX
|
|
||||||
u8 _op[16] = {0x10, 0x06, 0x02, 0x0f, 0x0a, 0x47, 0x8b, 0xf6,
|
|
||||||
0xb6, 0x99, 0xf1, 0x5c, 0x06, 0x2e, 0x42, 0xb3 };
|
|
||||||
#else
|
|
||||||
u8 _op[16] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
|
||||||
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
|
|
||||||
#endif
|
|
||||||
memcpy(data->keys.op, _op, sizeof(_op));
|
|
||||||
|
|
||||||
LOG_FUNC_RETURN (RETURNok);
|
LOG_FUNC_RETURN (RETURNok);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,7 +351,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co
|
|||||||
|
|
||||||
u8 ak[USIM_API_AK_SIZE];
|
u8 ak[USIM_API_AK_SIZE];
|
||||||
f2345(usim_data->keys.usim_api_k, rand_pP->value,
|
f2345(usim_data->keys.usim_api_k, rand_pP->value,
|
||||||
res_pP->value, ck_pP->value, ik_pP->value, ak, usim_data->keys.op);
|
res_pP->value, ck_pP->value, ik_pP->value, ak, usim_data->keys.opc);
|
||||||
LOG_TRACE(INFO, "USIM-API - res(f2) :%s",dump_octet_string(res_pP));
|
LOG_TRACE(INFO, "USIM-API - res(f2) :%s",dump_octet_string(res_pP));
|
||||||
LOG_TRACE(INFO, "USIM-API - ck(f3) :%s",dump_octet_string(ck_pP));
|
LOG_TRACE(INFO, "USIM-API - ck(f3) :%s",dump_octet_string(ck_pP));
|
||||||
LOG_TRACE(INFO, "USIM-API - ik(f4) :%s",dump_octet_string(ik_pP));
|
LOG_TRACE(INFO, "USIM-API - ik(f4) :%s",dump_octet_string(ik_pP));
|
||||||
@@ -388,7 +372,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co
|
|||||||
/* Compute XMAC = f1K (SQN || RAND || AMF) */
|
/* Compute XMAC = f1K (SQN || RAND || AMF) */
|
||||||
#define USIM_API_XMAC_SIZE 8
|
#define USIM_API_XMAC_SIZE 8
|
||||||
u8 xmac[USIM_API_XMAC_SIZE];
|
u8 xmac[USIM_API_XMAC_SIZE];
|
||||||
f1(usim_data->keys.usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac, usim_data->keys.op);
|
f1(usim_data->keys.usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac, usim_data->keys.opc);
|
||||||
LOG_TRACE(DEBUG,
|
LOG_TRACE(DEBUG,
|
||||||
"USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X",
|
"USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||||
xmac[0],xmac[1],xmac[2],xmac[3],
|
xmac[0],xmac[1],xmac[2],xmac[3],
|
||||||
@@ -416,7 +400,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co
|
|||||||
|
|
||||||
/* Concealed value of the counter SQNms in the USIM:
|
/* Concealed value of the counter SQNms in the USIM:
|
||||||
* Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */
|
* Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */
|
||||||
f5star(usim_data->keys.usim_api_k, rand_pP->value, ak, usim_data->keys.op);
|
f5star(usim_data->keys.usim_api_k, rand_pP->value, ak, usim_data->keys.opc);
|
||||||
|
|
||||||
|
|
||||||
u8 sqn_ms[USIM_API_SQNMS_SIZE];
|
u8 sqn_ms[USIM_API_SQNMS_SIZE];
|
||||||
@@ -445,7 +429,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co
|
|||||||
#define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE
|
#define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE
|
||||||
u8 macs[USIM_API_MACS_SIZE];
|
u8 macs[USIM_API_MACS_SIZE];
|
||||||
f1star(usim_data->keys.usim_api_k, rand_pP->value, sqn_ms,
|
f1star(usim_data->keys.usim_api_k, rand_pP->value, sqn_ms,
|
||||||
&rand_pP->value[USIM_API_SQN_SIZE], macs, usim_data->keys.op);
|
&rand_pP->value[USIM_API_SQN_SIZE], macs, usim_data->keys.opc);
|
||||||
LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X",
|
LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||||
macs[0],macs[1],macs[2],macs[3],
|
macs[0],macs[1],macs[2],macs[3],
|
||||||
macs[4],macs[5],macs[6],macs[7]);
|
macs[4],macs[5],macs[6],macs[7]);
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ typedef struct {
|
|||||||
#define USIM_IK_SIZE 16
|
#define USIM_IK_SIZE 16
|
||||||
Byte_t ik[USIM_IK_SIZE];
|
Byte_t ik[USIM_IK_SIZE];
|
||||||
uint8_t usim_api_k[USIM_API_K_SIZE];
|
uint8_t usim_api_k[USIM_API_K_SIZE];
|
||||||
uint8_t op[16];
|
uint8_t opc[16];
|
||||||
} usim_keys_t;
|
} usim_keys_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -104,21 +104,21 @@ void *nas_ue_task(void *args_p)
|
|||||||
user->ueid=i;
|
user->ueid=i;
|
||||||
|
|
||||||
/* Get USIM data application filename */
|
/* Get USIM data application filename */
|
||||||
user->usim_data_store = memory_get_path(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME);
|
user->usim_data_store = memory_get_path_from_ueid(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME, user->ueid);
|
||||||
if ( user->usim_data_store == NULL ) {
|
if ( user->usim_data_store == NULL ) {
|
||||||
LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid);
|
LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid, user->ueid);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get UE's data pathname */
|
/* Get UE's data pathname */
|
||||||
user->user_nvdata_store = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME);
|
user->user_nvdata_store = memory_get_path_from_ueid(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME, user->ueid);
|
||||||
if ( user->user_nvdata_store == NULL ) {
|
if ( user->user_nvdata_store == NULL ) {
|
||||||
LOG_E(NAS, "[UE %d] - Failed to get USIM nvdata filename", user->ueid);
|
LOG_E(NAS, "[UE %d] - Failed to get USIM nvdata filename", user->ueid);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get EMM data pathname */
|
/* Get EMM data pathname */
|
||||||
user->emm_nvdata_store = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME);
|
user->emm_nvdata_store = memory_get_path_from_ueid(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME, user->ueid);
|
||||||
if ( user->emm_nvdata_store == NULL ) {
|
if ( user->emm_nvdata_store == NULL ) {
|
||||||
LOG_E(NAS, "[UE %d] - Failed to get EMM nvdata filename", user->ueid);
|
LOG_E(NAS, "[UE %d] - Failed to get EMM nvdata filename", user->ueid);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|||||||
Reference in New Issue
Block a user