diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 582bfdd74273db91c0a5ef0a4db054255353d23b..e4d3acf4b1c976540a95e6cbd033bfa26b9d9ecd 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1759,6 +1759,7 @@ add_executable(lte-softmodem ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c + ${OPENAIR_DIR}/common/utils/utils.c ${GTPU_need_ITTI} ${HW_SOURCE} ${TRANSPORT_SOURCE} @@ -1889,6 +1890,7 @@ add_executable(oaisim ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c + ${OPENAIR_DIR}/common/utils/utils.c ${GTPU_need_ITTI} ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${HW_SOURCE} diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index ca9a30546324be9cd3fa008e3b6b34bffd4af6b6..61d1565bac912d2e03eb6c183a3d0f479ce161f2 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -88,31 +88,47 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -std=gnu99 -Wall -Wstrict-prototype set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -DMALLOC_CHECK_=3") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb -DMALLOC_CHECK_=3 -O2") -#This is to detect nettle version changes between Ubuntu 14.04/16.04 -set ( nettle_cmd "nettle-hash" ) -set ( nettle_arg "-V" ) -execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev) +##This is to detect nettle version changes between Ubuntu 14.04/16.04 +#set ( nettle_cmd "nettle-hash" ) +#set ( nettle_arg "-V" ) +#execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev) +# +#string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov}) +# +#message("NETTLE_VERSION = ${nv}") +# +## we need to remove decimal as floating point arithematic does not work properly with C preprocessor +#STRING(REGEX REPLACE "[.]" "" nv ${nv}) +# +#if ("${nv}" STREQUAL "") +# message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) +#endif() +# +#set (NETTLE_VERSION "${nv}") +#add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}") + +include(FindPkgConfig) -string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov}) +pkg_search_module(NETTLE nettle) +if(NOT ${NETTLE_FOUND}) + message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") +else() + include_directories(${NETTLE_INCLUDE_DIRS}) +endif() -message("NETTLE_VERSION = ${nv}") +message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") -# we need to remove decimal as floating point arithematic does not work properly with C preprocessor -STRING(REGEX REPLACE "[.]" "" nv ${nv}) +string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) +string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) +message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") +message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") -if ("${nv}" STREQUAL "") +if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) endif() -set (NETTLE_VERSION "${nv}") -add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}") - -include(FindPkgConfig) - -INCLUDE(FindNettle) -IF( NOT NETTLE_FOUND ) - MESSAGE( SEND_ERROR "Nettle is required" ) -ENDIF( NOT NETTLE_FOUND ) +add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") +add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") pkg_search_module(OPENSSL openssl REQUIRED) @@ -215,8 +231,8 @@ set(api_user_HDR add_library(api_user ${api_user_SRC} ${api_user_HDR}) target_include_directories(api_user PRIVATE ${OPENAIR_NAS_DIR}/UE/API/USER - ${OPENAIR_NAS_DIR}/UE ${OPENAIR_NAS_DIR}/COMMON + ${OPENAIR_NAS_DIR}/UE ) ################################################################################ @@ -397,6 +413,7 @@ target_include_directories(emm PRIVATE ${OPENAIR_DIR}/common/utils/msc ${OPENAIR_DIR}/common/utils ${OPENAIR_DIR}/openair2/COMMON + ${OPENAIR_NAS_DIR}/UE ${OPENAIR_NAS_DIR}/UE/API/USIM ${OPENAIR_NAS_DIR}/UE/EMM ${OPENAIR_NAS_DIR}/COMMON/EMM/MSG @@ -409,7 +426,6 @@ target_include_directories(emm PRIVATE # esm LIB ################################################################################ set(esm_SRC - ${OPENAIR_NAS_DIR}/UE/ESM/esm_main.c ${OPENAIR_NAS_DIR}/UE/ESM/DedicatedEpsBearerContextActivation.c ${OPENAIR_NAS_DIR}/UE/ESM/DefaultEpsBearerContextActivation.c ${OPENAIR_NAS_DIR}/UE/ESM/EpsBearerContextDeactivation.c @@ -452,6 +468,7 @@ set(esm_SRC ) set(esm_HDR + ${OPENAIR_TARGETS}/COMMON/openairinterface5g_limits.h ${OPENAIR_NAS_DIR}/UE/ESM/esm_main.h ${OPENAIR_NAS_DIR}/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.h ${OPENAIR_NAS_DIR}/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.h @@ -481,13 +498,17 @@ set(esm_HDR ${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_recv.h ${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_sap.h ${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_send.h + ${OPENAIR_DIR}/common/utils/utils.h ) add_library(esm ${esm_SRC} ${esm_HDR}) target_include_directories(esm PRIVATE + ${OPENAIR_DIR}/common/utils + ${OPENAIR_NAS_DIR}/UE ${OPENAIR_NAS_DIR}/UE/API/USER ${OPENAIR_NAS_DIR}/UE/ESM + ${OPENAIR_TARGETS}/COMMON ${OPENAIR_NAS_DIR}/COMMON/ESM/MSG ${OPENAIR_NAS_DIR}/UE/ESM/SAP ${OPENAIR_NAS_DIR}/COMMON/IES @@ -670,6 +691,9 @@ target_include_directories(ies PRIVATE # EXECUTABLE at_nas_ue ################################################################################ include_directories( + ${OPENAIR_TARGETS}/COMMON + ${OPENAIR_NAS_DIR}/UE + ${OPENAIR_DIR}/common/utils ${OPENAIR_DIR}/common/utils/msc ${OPENAIR3_DIR}/COMMON ${OPENAIR3_DIR}/SECU @@ -691,6 +715,7 @@ ADD_EXECUTABLE(at_nas_ue ${OPENAIR_NAS_DIR}/UE/UEprocess.c ${OPENAIR_NAS_DIR}/UE/nas_parser.c ${OPENAIR_NAS_DIR}/UE/nas_proc.c ${OPENAIR_NAS_DIR}/UE/nas_user.c + ${OPENAIR_DIR}/common/utils/utils.c ) target_link_libraries (at_nas_ue diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 9565e365e3d63cc76d50dd993f5bdaa04f317def..6a61d36cfa7cb90e8f1c24c63fed2590e1c0b9e4 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -57,17 +57,20 @@ CMAKE_BUILD_TYPE="" UE_AUTOTEST_TRACE="False" trap handle_ctrl_c INT +gen_nvram_path=$OPENAIR_DIR/targets/bin +conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf + function print_help() { - echo_info ' + echo_info " This program installs OpenAirInterface Software You should have ubuntu 14.xx, updated, and the Linux kernel >= 3.14 Options -h This help -c | --clean - Erase all files to make a rebuild from start" + Erase all files to make a rebuild from start -C | --clean-all - Erase all files made by previous compilations, installations" + Erase all files made by previous compilations, installations --clean-kernel Erase previously installed features in kernel: iptables, drivers, ... -I | --install-external-packages @@ -82,7 +85,11 @@ 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 +--UE-conf-nvram [configuration file] + Specify conf_nvram_path (default \"$conf_nvram_path\") +--UE-gen-nvram [output path] + Specify gen_nvram_path (default \"$gen_nvram_path\") --RRH Makes the RRH -a | --agent @@ -97,7 +104,7 @@ Options ETHERNET , None Adds this trasport protocol support in compilation --oaisim - Makes the oaisim simulator. Hardware will be defaulted to "None". + Makes the oaisim simulator. Hardware will be defaulted to \"None\". --phy_simulators Makes the unitary tests Layer 1 simulators --core_simulators @@ -140,11 +147,12 @@ Usage (first build): Usage (Regular): oaisim : ./build_oai --oaisim -x Eurecom EXMIMO + OAI ENB : ./build_oai --eNB -x - NI/ETTUS B201 + OAI ENB : ./build_oai --eNB -x -w USRP' + NI/ETTUS B201 + OAI ENB : ./build_oai --eNB -x -w USRP" } function main() { + until [ -z "$1" ] do case "$1" in @@ -183,6 +191,12 @@ function main() { UE=1 echo_info "Will compile UE" shift;; + --UE-conf-nvram) + conf_nvram_path=$(readlink -f "$1") + shift 2;; + --UE-gen-nvram) + gen_nvram_path=$(readlink -f $2) + shift 2;; --RRH) RRH=1 echo_info "Will compile RRH" @@ -517,15 +531,17 @@ function main() { compilations \ nas_sim_tools nvram \ nvram $dbin/nvram + compilations \ + 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 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 - + cp -Rvf $dbin/.ue_emm.nvram0 $DIR/$lte_build_dir/build + cp -Rvf $dbin/.ue.nvram0 $DIR/$lte_build_dir/build + cp -Rvf $dbin/.usim.nvram0 $DIR/$lte_build_dir/build else echo_warning "not generated UE NAS files: binaries not found" fi @@ -647,10 +663,13 @@ function main() { compilations \ nas_sim_tools nvram \ nvram $dbin/nvram + compilations \ + 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 diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 732ede3f94006466ae8afb9603b4f892f3d19855..81e3fe4b3ce7ac256ed4fea630ee30ec9425b2a1 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -2,70 +2,89 @@ 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 -g") 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_LIB_SRC + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_data.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_usim.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_network.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_plmn.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_parser.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.c ${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/TOOLS/conf_emm.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 ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.h ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.h ${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}) +# conf2uedata binary +set(conf2uedata_SRC + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c + ${CONF2UEDATA_LIB_SRC} +) +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 -) +# usim binary -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 +set(usim_SRC + ${OPENAIR_DIR}/openair3/NAS/TOOLS/usim.c + ${CONF2UEDATA_LIB_SRC} ) -ADD_EXECUTABLE(nvram ${nvram_SRC} ${nvram_HDR}) -#install (TARGETS usim DESTINATION ${EXECUTABLE_OUTPUT_PATH}) -#install (TARGETS nvram DESTINATION ${EXECUTABLE_OUTPUT_PATH}) +add_executable(usim ${usim_SRC} ${conf2uedata_HDR} ) +target_link_libraries(usim ${CONFIG_LIBRARIES}) + +# nvram binary + +set(nvram_SRC + ${OPENAIR_DIR}/openair3/NAS/TOOLS/nvram.c + ${CONF2UEDATA_LIB_SRC} +) + -#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(nvram ${nvram_SRC} ${conf2uedata_HDR} ) +target_link_libraries(nvram ${CONFIG_LIBRARIES}) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index f73078afc5e2a1be7075d520a4e5f5f0ed8685c5..c53194747413fd90a2b6cc672c4de17a9a95e803 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -450,19 +450,18 @@ install_asn1c_from_source(){ ################################################ install_nas_tools() { - cd $1 - if [ ! -f .ue.nvram ]; then + if [ ! -f .ue.nvram0 ]; then echo_success "generate .ue_emm.nvram .ue.nvram" - ./nvram --gen + ./nvram --gen -c $1 -o $2 else - [ ./nvram -nt .ue.nvram -o ./nvram -nt .ue_emm.nvram ] && ./nvram --gen + [ ./nvram -nt .ue.nvram0 -o ./nvram -nt .ue_emm.nvram0 ] && ./nvram --gen -c $1 -o $2 fi - if [ ! -f .usim.nvram ]; then + if [ ! -f .usim.nvram0 ]; then echo_success "generate .usim.nvram" - ./usim --gen + ./usim --gen -c $1 -o $2 else - [ ./usim -nt .usim.nvram ] && ./usim --gen + [ ./usim -nt .usim.nvram0 ] && ./usim --gen -c $1 -o $2 fi } diff --git a/cmake_targets/tools/run_enb_ue_virt_s1 b/cmake_targets/tools/run_enb_ue_virt_s1 index ecd5993ff47e65769d1867e72d83f875fa3ca757..ff659468038f21939eb5ae9f45fd05343aafcb65 100755 --- a/cmake_targets/tools/run_enb_ue_virt_s1 +++ b/cmake_targets/tools/run_enb_ue_virt_s1 @@ -247,12 +247,6 @@ function main() if [ $? -ne 0 ]; then echo "200 lte " >> /etc/iproute2/rt_tables fi - ip rule add fwmark 1 table lte - ifconfig oip1 up - ip route add default dev oip1 table lte - # the actual IP address depends on the EPC/MME config file for address pool - ip route add from 192.188.0.0/24 table lte - ip route add to 192.188.0.0/24 table lte exe_arguments="$exe_arguments -s15 -AAWGN -y1 -b1 -u1 -Q0" diff --git a/common/utils/Makefile.inc b/common/utils/Makefile.inc deleted file mode 100644 index 33c126b8d73230a685451ff9d86136c608c1982d..0000000000000000000000000000000000000000 --- a/common/utils/Makefile.inc +++ /dev/null @@ -1,59 +0,0 @@ -export KERNEL_DIR=/lib/modules/$(shell uname -r)/ -CC=gcc -CCC=gcc -linux := $(shell if [ `uname` = "Linux" ] ; then echo "1" ; else echo "0" ; fi) - - -CFLAGS += -std=gnu99 -CFLAGS += -Wall -g -ggdb -Wstrict-prototypes -fno-strict-aliasing - -# Need to force this option because default kernel module builder is wrong -CFLAGS += $(call cc-option,-mpreferred-stack-boundary=4) - -#For performance, if some option doesn't exist in all gcc versions, use $(call cc-option,MY_OPTION) -#CFLAGS += -O2 -#CFLAGS += -funroll-loops -CFLAGS += -Wno-packed-bitfield-compat - -# This is the minimum CPU faetures for OAI -CFLAGS += -mmmx -msse -msse2 -mssse3 -msse4.1 -# Add CPU features from local CPU -#CFLAGS += -march=native - -ifeq ($(OSTYPE),Cygwin) -cygwin=1 -CFLAGS += -DCYGWIN -else -cygwin=0 -endif - -ifeq ($(linux),1) -CFLAGS += -LDFLAGS += -endif - -ITTI_DIR = $(COMMON_UTILS_DIR)/itti - -ITTI_OBJS = $(ITTI_DIR)/intertask_interface.o -ITTI_OBJS += $(ITTI_DIR)/intertask_interface_dump.o -ITTI_OBJS += $(ITTI_DIR)/backtrace.o -ITTI_OBJS += $(ITTI_DIR)/memory_pools.o -ITTI_OBJS += $(ITTI_DIR)/signals.o -ITTI_OBJS += $(ITTI_DIR)/timer.o - - -HASHTABLE_DIR = $(COMMON_UTILS_DIR)/collection/hashtable -MSC_DIR = $(COMMON_UTILS_DIR)/msc - -HASHTABLE_OBJS = $(HASHTABLE_DIR)/hashtable.o -HASHTABLE_OBJS += $(HASHTABLE_DIR)/obj_hashtable.o - -UTILS_OBJS = $(ITTI_OBJS) $(HASHTABLE_OBJS) - -UTILS_incl = \ - -I$(COMMON_UTILS_DIR) \ - -I$(HASHTABLE_DIR) \ - -I$(ITTI_DIR) \ - -I$(MSC_DIR) - -print-% : ; @echo $* = $($*) diff --git a/common/utils/utils.c b/common/utils/utils.c new file mode 100644 index 0000000000000000000000000000000000000000..a807a27096f661002d87ab5023291aa62b34fe89 --- /dev/null +++ b/common/utils/utils.c @@ -0,0 +1,107 @@ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "utils.h" + +void *calloc_or_fail(size_t size) { + void *ptr = calloc(1, size); + if (ptr == NULL) { + fprintf(stderr, "[UE] Failed to calloc %zu bytes", size); + exit(EXIT_FAILURE); + } + return ptr; +} + +void *malloc_or_fail(size_t size) { + void *ptr = malloc(size); + if (ptr == NULL) { + fprintf(stderr, "[UE] Failed to malloc %zu bytes", size); + exit(EXIT_FAILURE); + } + return ptr; +} + +/**************************************************************************** + ** ** + ** Name: hex_char_to_hex_value() ** + ** ** + ** Description: Converts an hexadecimal ASCII coded digit into its value. ** + ** ** + ** Inputs: c: A char holding the ASCII coded value ** + ** Others: None ** + ** ** + ** Outputs: None ** + ** Return: Converted value (-1 on error) ** + ** Others: None ** + ** ** + ***************************************************************************/ +int hex_char_to_hex_value (char c) +{ + if (!((c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F') || + (c >= '0' && c <= '9'))) + return -1; + + if (c >= 'A') { + /* Remove case bit */ + c &= ~('a' ^ 'A'); + + return (c - 'A' + 10); + } else { + return (c - '0'); + } +} + +/**************************************************************************** + ** ** + ** Name: hex_string_to_hex_value() ** + ** ** + ** Description: Converts an hexadecimal ASCII coded string into its value.** + ** ** + ** Inputs: hex_value: A pointer to the location to store the ** + ** conversion result ** + ** size: The size of hex_value in bytes ** + ** Others: None ** + ** ** + ** Outputs: hex_value: Converted value ** + ** Return: 0 on success, -1 on error ** + ** Others: None ** + ** ** + ***************************************************************************/ +int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size) +{ + int i; + + if (strlen(hex_string) != size*2) { + fprintf(stderr, "the string '%s' should be of length %d\n", hex_string, size*2); + return -1; + } + + for (i=0; i < size; i++) { + int a = hex_char_to_hex_value(hex_string[2 * i]); + int b = hex_char_to_hex_value(hex_string[2 * i + 1]); + if (a == -1 || b == -1) goto error; + hex_value[i] = (a << 4) | b; + } + return 0; + +error: + fprintf(stderr, "the string '%s' is not a valid hexadecimal string\n", hex_string); + for (i=0; i < size; i++) + hex_value[i] = 0; + return -1; +} + +char *itoa(int i) { + char buffer[64]; + int ret; + + ret = snprintf(buffer, sizeof(buffer), "%d",i); + if ( ret <= 0 ) { + return NULL; + } + + return strdup(buffer); +} + diff --git a/common/utils/utils.h b/common/utils/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..cfe3df34b9356e02fe33e050198af154b415a472 --- /dev/null +++ b/common/utils/utils.h @@ -0,0 +1,17 @@ +#ifndef _UTILS_H +#define _UTILS_H + +#include <stdint.h> +#include <sys/types.h> + +void *calloc_or_fail(size_t size); +void *malloc_or_fail(size_t size); + +// Converts an hexadecimal ASCII coded digit into its value. ** +int hex_char_to_hex_value (char c); +// Converts an hexadecimal ASCII coded string into its value.** +int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size); + +char *itoa(int i); + +#endif diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c index df6a55eaf35560a90f619b01e824e145cea2e212..02b5102ae544a16b04e527ac9aed30fc1fc84009 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c @@ -1,31 +1,24 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom +/* + * 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 + */ - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ #ifdef USER_MODE #include <string.h> #endif diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c index 4a9010fca0daa712a9db006f0bbf87594283668f..b4199d9b605e36e2f0ca7fa7002d1b9890e25e11 100644 --- a/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c +++ b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c @@ -1,31 +1,23 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ +/* + * 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 + */ /*! \file PHY/LTE_TRANSPORT/uespec_pilots.c * \brief Top-level routines for generating DL ue-specific reference signals V12.5 2015-03 diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 88ac12b0a711a71bac32e18f0de528cfccd425f5..d2336f6187792869fdd286c94d8831d3b43e6156 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -1,31 +1,23 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - -Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ +/* + * 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 + */ /*! \file PHY/MODULATION/beamforming.c * \brief diff --git a/openair1/PHY/TOOLS/twiddle18432.h b/openair1/PHY/TOOLS/twiddle18432.h index f21987c4cb2b49e201f5d404bbfd9cb15987aeee..8c6c9822dc69c7c15ef1141b40a5ea4454e323bd 100644 --- a/openair1/PHY/TOOLS/twiddle18432.h +++ b/openair1/PHY/TOOLS/twiddle18432.h @@ -1,31 +1,23 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ +/* + * 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 + */ /* Twiddles generated with twa = floor(32767*exp(-sqrt(-1)*2*pi*(0:6143)/18432)); diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 1273fb9cf4f94c64b55c65ace0010c315fd6eb6d..be63ea00cc3a7e5a4d7350651001f642026f33b0 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -284,21 +284,7 @@ typedef enum { #define NUMBER_OF_HARQ_PID_MAX 8 #define MAX_FRAME_NUMBER 0x400 -#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) -#define NUMBER_OF_eNB_MAX 1 -#define NUMBER_OF_UE_MAX 16 -#define NUMBER_OF_CONNECTED_eNB_MAX 3 -#else -#ifdef LARGE_SCALE -#define NUMBER_OF_eNB_MAX 2 -#define NUMBER_OF_UE_MAX 120 -#define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory -#else -#define NUMBER_OF_eNB_MAX 7 -#define NUMBER_OF_UE_MAX 16 -#define NUMBER_OF_CONNECTED_eNB_MAX 3 -#endif -#endif +#include "openairinterface5g_limits.h" #define NUMBER_OF_RN_MAX 3 typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 503ba84ea89d1a16b6adfc44d535782bd4344e44..b9662fd5d5491e7380d17741c97f1511bacf1823 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1040,8 +1040,8 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt int subframe_tx = proc->subframe_tx; int frame_tx = proc->frame_tx; int ulsch_start; -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) int overflow=0; +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) int k,l; int dummy_tx_buffer[3840*4] __attribute__((aligned(16))); #endif @@ -1069,7 +1069,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance; #endif //else EXMIMO -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) if (empty_subframe) { //#if 1 @@ -1098,7 +1098,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt #endif*/ return; } -#endif +//#endif if ((frame_tx%100) == 0) LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n", diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c index 874af41f45c3c4cb9cb951c6eb543f0503a47f6f..195f27f72e9960527cc0f8d0c379768ad79b2f23 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c @@ -1,31 +1,23 @@ - /****************************************************************************** - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ +/* + * 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 + */ /*! \file dlsim.c \brief Top-level DL simulator diff --git a/openair2/COMMON/commonDef.h b/openair2/COMMON/commonDef.h index b1ec47449af1a7f0da1fa7257c16db49ad7eda6d..37d05f3fda8a858737384a3627c6a6306a2d7bbc 100644 --- a/openair2/COMMON/commonDef.h +++ b/openair2/COMMON/commonDef.h @@ -316,15 +316,6 @@ typedef struct { */ #define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];} -/* - * User notification callback, executed whenever a change of data with - * respect of network information (e.g. network registration and/or - * location change, new PLMN becomes available) is notified by the - * EPS Mobility Management sublayer - */ -typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t, - const char*, size_t); - typedef enum eps_protocol_discriminator_e { /* Protocol discriminator identifier for EPS Mobility Management */ EPS_MOBILITY_MANAGEMENT_MESSAGE = 0x7, diff --git a/openair2/COMMON/networkDef.h b/openair2/COMMON/networkDef.h index c52a58a527e32faaaa187bb6c976f76a3feb3cf7..42c812baada0127cc8c15c2ad014863f7bbc5523 100644 --- a/openair2/COMMON/networkDef.h +++ b/openair2/COMMON/networkDef.h @@ -252,13 +252,6 @@ typedef struct { network_pkf_t* pkf[NET_PACKET_FILTER_MAX]; } network_tft_t; -/* - * User notification callback, executed whenever a change of status with - * respect of PDN connection or EPS bearer context is notified by the EPS - * Session Management sublayer - */ -typedef int (*esm_indication_callback_t) (int, network_pdn_state_t); - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index d812ec0087a892f0144e11c2172f79f83eecce2d..8553c118dcb92ffee80d0a3ae3dab7fc8801ece2 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -62,24 +62,27 @@ #endif //PHY_EMUL #include "SCHED/defs.h" - +/* TODO: this abstraction_flag here is very hackish - find a proper solution */ +extern uint8_t abstraction_flag; void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) //init as MR { LOG_D(MAC,"[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n", module_idP, frameP, eNB_index); -#if ! defined(ENABLE_USE_MME) +#if defined(ENABLE_USE_MME) + int mme_enabled=1; +#else + int mme_enabled=0; +#endif - if (first_sync==1) { + if (first_sync==1 && !(mme_enabled==1 && abstraction_flag==0)) { layer2_init_UE(module_idP); openair_rrc_ue_init(module_idP,eNB_index); } else -#endif { rrc_in_sync_ind(module_idP,frameP,eNB_index); } - } void mrbch_phy_sync_failure(module_id_t module_idP, frame_t frameP, uint8_t free_eNB_index) //init as CH diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 4c67f80e207a84f42a56ed0d7cafbed9f7a1b26c..0c5e4cb9e1e3d4b237c181d9afdb7a691a4e3106 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -816,6 +816,14 @@ pdcp_data_ind( ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id; #if defined(OAI_EMU) ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id + oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local; +#else +# if defined(ENABLE_USE_MME) + /* for the UE compiled in S1 mode, we need 1 here + * for the UE compiled in noS1 mode, we need 0 + * TODO: be sure of this + */ + ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; +# endif #endif } else { ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index e380bc6098bd6e7e98d8d6bb5558435e6fb2fc89..37b38121b9d8b03c9b177839044144fc1cef48a7 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -167,7 +167,8 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) ((pdcp_data_ind_header_t *) sdu_p->data)->data_size); #else #if ! defined(OAI_EMU) - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; + /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ +// ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; #endif #endif @@ -571,7 +572,8 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : pdcp_read_header_g.inst + oai_emulation.info.first_enb_local;*/ #else // OAI_EMU - pdcp_read_header_g.inst = 0; + /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ +// pdcp_read_header_g.inst = 0; //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ctxt_cpy.enb_flag; diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 86968015975e09e05e37a6639bdcf6eee3cd6cff..1ea5df0d30c9600b0b3e9009639096350fe6d61c 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -345,7 +345,7 @@ void ue_ip_common_wireless2ip(struct nlmsghdr *nlh_pP) ue_ip_common_class_wireless2ip(pdcph_p->data_size, (unsigned char *)NLMSG_DATA(nlh_pP) + UE_IP_PDCPH_SIZE, - 1, //pdcph_p->inst, + pdcph_p->inst, pdcph_p->rb_id); } diff --git a/openair2/NETWORK_DRIVER/UE_IP/constant.h b/openair2/NETWORK_DRIVER/UE_IP/constant.h index 9b4017773b0c84726ecc1846f50bfbe617b86b51..42fd0b6303c0bcaca9665e0eae52c135a31d6a0b 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/constant.h +++ b/openair2/NETWORK_DRIVER/UE_IP/constant.h @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include "openairinterface5g_limits.h" #ifndef _UE_IP_CST #define _UE_IP_CST @@ -51,7 +52,7 @@ -#define UE_IP_NB_INSTANCES_MAX 8 +#define UE_IP_NB_INSTANCES_MAX NUMBER_OF_UE_MAX #endif diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 8039fcfb7560f90ba633e2b9c84f6784e7334dea..4c877ebe23d5a194b19738ef13267f47ca1679f8 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -4406,7 +4406,6 @@ void *rrc_ue_task( void *args_p ) /* NAS messages */ case NAS_CELL_SELECTION_REQ: - ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */ LOG_D(RRC, "[UE %d] Received %s: state %d, plmnID (%d%d%d.%d%d%d), rat %x\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id), NAS_CELL_SELECTION_REQ (msg_p).plmnID.MCCdigit1, @@ -4707,7 +4706,6 @@ void *rrc_ue_task( void *args_p ) break; case RRC_RAL_CONNECTION_RELEASE_REQ: - ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */ LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, msg_name); break; #endif diff --git a/openair2/UTIL/OMV/structures.h b/openair2/UTIL/OMV/structures.h index c50e7b22973c05f7c1c212485685ad955d59a137..434fa4c3836e888697328ae182b422b78fb1d1b0 100644 --- a/openair2/UTIL/OMV/structures.h +++ b/openair2/UTIL/OMV/structures.h @@ -31,13 +31,12 @@ #ifndef STRUCTURES_H #define STRUCTURES_H +#include "openairinterface5g_limits.h" #ifndef __PHY_IMPLEMENTATION_DEFS_H__ -#define Maxneighbor 64 -#define NUMBER_OF_UE_MAX 64 -#define NUMBER_OF_eNB_MAX 3 -#ifndef NB_ANTENNAS_RX -# define NB_ANTENNAS_RX 4 -#endif + #define Maxneighbor NUMBER_OF_UE_MAX + #ifndef NB_ANTENNAS_RX + #define NB_ANTENNAS_RX 4 + #endif #endif // diff --git a/openair2/UTIL/OTG/otg_defs.h b/openair2/UTIL/OTG/otg_defs.h index 0cef777b8f0b98eddeb42b61323bc985ff1e9b6b..ebb3f299897031f17ae140f61091d177121aae60 100644 --- a/openair2/UTIL/OTG/otg_defs.h +++ b/openair2/UTIL/OTG/otg_defs.h @@ -33,12 +33,12 @@ #ifndef __OTG_DEFS_H__ # define __OTG_DEFS_H__ - +/* \brief To define the NUMBER_OF_eNB_MAX and NUMBER_OF_UE_MAX */ #if STANDALONE==1 -# define NUMBER_OF_eNB_MAX 3 -# define NUMBER_OF_UE_MAX 3 + #include "openairinterface5g_limits.h" #else -#include "PHY/impl_defs_top.h" /* \brief To define the NUMBER_OF_eNB_MAX and NUMBER_OF_UE_MAX */ + // impl_defs_top.h includes openairinterface5g_limits.h + #include "PHY/impl_defs_top.h" #endif #include "otg_config.h" diff --git a/openair3/NAS/COMMON/EMM/MSG/emm_msg.c b/openair3/NAS/COMMON/EMM/MSG/emm_msg.c index b067b9c0d1584929fdcab190bca92de17e470af9..c357e8784f803827e9e83041033472d1b571bb86 100644 --- a/openair3/NAS/COMMON/EMM/MSG/emm_msg.c +++ b/openair3/NAS/COMMON/EMM/MSG/emm_msg.c @@ -464,6 +464,9 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) #endif } + if (encode_result < 0) + LOG_FUNC_RETURN (encode_result); + LOG_FUNC_RETURN (header_result + encode_result); } diff --git a/openair3/NAS/COMMON/UTIL/memory.c b/openair3/NAS/COMMON/UTIL/memory.c index df94d40cfcc7a89d9d1c343e184c8e87b798d775..3b3b6e7f9e1d47caf3e5a2f4736a38eb9f8a1e4b 100644 --- a/openair3/NAS/COMMON/UTIL/memory.c +++ b/openair3/NAS/COMMON/UTIL/memory.c @@ -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() ** diff --git a/openair3/NAS/COMMON/UTIL/memory.h b/openair3/NAS/COMMON/UTIL/memory.h index f41f4d586b51b9aaf32df5031700cbb423ba51c9..f7f0733044b50163c262036e5cc0abd9cc85fdc6 100644 --- a/openair3/NAS/COMMON/UTIL/memory.h +++ b/openair3/NAS/COMMON/UTIL/memory.h @@ -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); diff --git a/openair3/NAS/COMMON/commonDef.h b/openair3/NAS/COMMON/commonDef.h index 64216b009465119c56e0d357dab48875b7c4be08..84d97fc4a8cb954386d0bd7976d5b11630f1d084 100644 --- a/openair3/NAS/COMMON/commonDef.h +++ b/openair3/NAS/COMMON/commonDef.h @@ -314,6 +314,7 @@ typedef struct { */ #define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];} +#if 0 /* * User notification callback, executed whenever a change of data with * respect of network information (e.g. network registration and/or @@ -322,6 +323,7 @@ typedef struct { */ typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t, const char*, size_t); +#endif typedef enum eps_protocol_discriminator_e { /* Protocol discriminator identifier for EPS Mobility Management */ diff --git a/openair3/NAS/COMMON/networkDef.h b/openair3/NAS/COMMON/networkDef.h index 46716bee24714ab2273744c4634a0924d9320207..e3e8e1f08b3487d6613dcbbf450b810204f01aaf 100644 --- a/openair3/NAS/COMMON/networkDef.h +++ b/openair3/NAS/COMMON/networkDef.h @@ -260,12 +260,14 @@ typedef struct { network_pkf_t* pkf[NET_PACKET_FILTER_MAX]; } network_tft_t; +#if 0 /* * User notification callback, executed whenever a change of status with * respect of PDN connection or EPS bearer context is notified by the EPS * Session Management sublayer */ typedef int (*esm_indication_callback_t) (int, network_pdn_state_t); +#endif /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ diff --git a/openair3/NAS/TEST/NETWORK/README b/openair3/NAS/TEST/NETWORK/README index 25a6de5d147600feaa5b5d0f2edabcf73bb27477..465e355e784ff3a7f529d22a8487dac5cd9d486e 100644 --- a/openair3/NAS/TEST/NETWORK/README +++ b/openair3/NAS/TEST/NETWORK/README @@ -18,9 +18,9 @@ EURECOM-NAS directory should contain following files: EURECOM-NAS |-- bin -| |-- .ue.nvram -| |-- .ue_emm.nvram -| |-- .usim.nvram +| |-- .ue.nvram0 +| |-- .ue_emm.nvram0 +| |-- .usim.nvram0 | |-- NetworkProcess | |-- UEprocess | `-- UserProcess @@ -57,10 +57,10 @@ UE for testing purpose. When starting up, UEprocess reads configuration data from .nvram binary files used as UE's non-volatile memory. -.usim.nvram contains data stored into the USIM -.ue.nvram contains data related to the UE identification (IMEI, +.usim.nvram0 contains data stored into the USIM +.ue.nvram0 contains data related to the UE identification (IMEI, manufacturer, model, PIN code) -.ue_emm.nvram contains data related to EPS Mobility Management (IMSI, last +.ue_emm.nvram0 contains data related to EPS Mobility Management (IMSI, last registered PLMN) -------------------------------------------------------------------------------- diff --git a/openair3/NAS/TOOLS/Makefile b/openair3/NAS/TOOLS/Makefile deleted file mode 100644 index ca2e884c1110f9d3fa6e53e0e9df0fd0f2bfb509..0000000000000000000000000000000000000000 --- a/openair3/NAS/TOOLS/Makefile +++ /dev/null @@ -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. - diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c new file mode 100644 index 0000000000000000000000000000000000000000..80a6933c05b080d7125284efab0f62734fe3e630 --- /dev/null +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -0,0 +1,62 @@ +#include <stdio.h> // perror, printf, fprintf, snprintf +#include <stdlib.h> // exit, free +#include <string.h> // memset, strncpy +#include <getopt.h> + +#include "conf2uedata.h" +#include "display.h" +#include "conf_parser.h" + +int main(int argc, char**argv) { + int option; + const char* conf_file = NULL; + const char* output_dir = NULL; + const char options[]="c:o:h"; + + while ((option = getopt(argc, argv, options)) != -1) { + switch (option) { + case 'c': + conf_file = optarg; + break; + case 'o': + output_dir = optarg; + break; + case 'h': + _display_usage(); + return true; + break; + default: + break; + } + } + + if (output_dir == NULL ) { + printf("No output option found\n"); + _display_usage(); + exit(1); + } + + if ( conf_file == NULL ) { + printf("No Configuration file is given\n"); + _display_usage(); + exit(1); + } + + if ( parse_config_file(output_dir, conf_file, OUTPUT_ALL) == false ) { + exit(1); + } + + display_data_from_directory(output_dir, DISPLAY_ALL); + + exit(0); +} + +/* + * Displays command line usage + */ +void _display_usage(void) { + fprintf(stderr, "usage: conf2uedata [OPTION]...\n"); + fprintf(stderr, "\t[-c]\tConfig file to use\n"); + fprintf(stderr, "\t[-o]\toutput file directory\n"); + fprintf(stderr, "\t[-h]\tDisplay this usage\n"); +} diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h new file mode 100644 index 0000000000000000000000000000000000000000..ed56a22718fb96ba16c892d089d0ba1560a77a3b --- /dev/null +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -0,0 +1,6 @@ +#ifndef _CONF2UEDATA_H +#define _CONF2UEDATA_H + +void _display_usage(void); + +#endif // _CONF2UEDATA_H diff --git a/openair3/NAS/TOOLS/conf_emm.c b/openair3/NAS/TOOLS/conf_emm.c new file mode 100644 index 0000000000000000000000000000000000000000..668b90a0ae0514de07872b092789c68b5a187773 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_emm.c @@ -0,0 +1,88 @@ +#include <string.h> + +#include "memory.h" +#include "conf_emm.h" +#include "fs.h" + +void gen_emm_data( + emm_nvdata_t *emm_data, + const char *hplmn, + const char *msin, + const plmns_list *eplmn, + const networks_t networks) +{ + memset(emm_data, 0, sizeof(emm_nvdata_t)); + int hplmn_index = get_plmn_index(hplmn, networks); + plmn_conf_param_t *conf = &networks.items[hplmn_index].conf; + int i; + + emm_data->imsi.length = 8; + emm_data->imsi.u.num.parity = get_msin_parity(msin, conf->mcc, conf->mnc); + emm_data->imsi.u.num.digit1 = conf->mcc[0]; + emm_data->imsi.u.num.digit2 = conf->mcc[1]; + emm_data->imsi.u.num.digit3 = conf->mcc[2]; + + emm_data->imsi.u.num.digit4 = conf->mnc[0]; + emm_data->imsi.u.num.digit5 = conf->mnc[1]; + + if (strlen(conf->mnc) == 3) { + emm_data->rplmn.MNCdigit3 = conf->mnc[2]; + + emm_data->imsi.u.num.digit6 = conf->mnc[2]; + emm_data->imsi.u.num.digit7 = msin[0]; + emm_data->imsi.u.num.digit8 = msin[1]; + emm_data->imsi.u.num.digit9 = msin[2]; + emm_data->imsi.u.num.digit10 = msin[3]; + emm_data->imsi.u.num.digit11 = msin[4]; + emm_data->imsi.u.num.digit12 = msin[5]; + emm_data->imsi.u.num.digit13 = msin[6]; + emm_data->imsi.u.num.digit14 = msin[7]; + emm_data->imsi.u.num.digit15 = msin[8]; + } else { + emm_data->rplmn.MNCdigit3 = 0xf; + + emm_data->imsi.u.num.digit6 = msin[0]; + emm_data->imsi.u.num.digit7 = msin[1]; + emm_data->imsi.u.num.digit8 = msin[2]; + emm_data->imsi.u.num.digit9 = msin[3]; + emm_data->imsi.u.num.digit10 = msin[4]; + emm_data->imsi.u.num.digit11 = msin[5]; + emm_data->imsi.u.num.digit12 = msin[6]; + emm_data->imsi.u.num.digit13 = msin[7]; + emm_data->imsi.u.num.digit14 = msin[8]; + emm_data->imsi.u.num.digit15 = msin[9]; + } + + emm_data->rplmn.MCCdigit1 = conf->mcc[0]; + emm_data->rplmn.MCCdigit2 = conf->mcc[1]; + emm_data->rplmn.MCCdigit3 = conf->mcc[2]; + emm_data->rplmn.MNCdigit1 = conf->mnc[0]; + emm_data->rplmn.MNCdigit2 = conf->mnc[1]; + + emm_data->eplmn.n_plmns = eplmn->size; + for (i = 0; i < eplmn->size; i++) { + emm_data->eplmn.plmn[i] = networks.items[eplmn->items[i]].plmn; + } +} + +bool write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { + int rc; + char* filename = make_filename(directory, EMM_NVRAM_FILENAME, user_id); + rc = memory_write(filename, emm_data, sizeof(emm_nvdata_t)); + free(filename); + if (rc != RETURNok) { + perror("ERROR\t: memory_write() failed"); + exit(false); + } + return(true); +} + +int get_msin_parity(const char * msin, const char *mcc, const char *mnc) { + int imsi_size = strlen(msin) + strlen(mcc) + + strlen(mnc); + int result = (imsi_size % 2 == 0) ? 0 : 1; + return result; + +} + + diff --git a/openair3/NAS/TOOLS/conf_emm.h b/openair3/NAS/TOOLS/conf_emm.h new file mode 100644 index 0000000000000000000000000000000000000000..f9c30d31c9523f2bb67ab27c6722883de76d52ba --- /dev/null +++ b/openair3/NAS/TOOLS/conf_emm.h @@ -0,0 +1,18 @@ +#ifndef _CONF_EMM_H +#define _CONF_EMM_H + +#include "emmData.h" +#include "conf_network.h" +#include "conf_user_plmn.h" + +void gen_emm_data( + emm_nvdata_t *emm_data, + const char *hplmn, + const char *msin, + const plmns_list *eplmn, + const networks_t networks); + +bool write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); +int get_msin_parity(const char * msin, const char *mcc, const char *mnc); + +#endif diff --git a/openair3/NAS/TOOLS/conf_network.c b/openair3/NAS/TOOLS/conf_network.c new file mode 100644 index 0000000000000000000000000000000000000000..96e2183327ad1c8d35215f898566582efe2ee994 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_network.c @@ -0,0 +1,112 @@ +#include <stdlib.h> +#include <string.h> + +#include "conf_network.h" + +int get_plmn_index(const char * mccmnc, const networks_t networks) { + char mcc[4]; + char mnc[strlen(mccmnc) - 2]; + strncpy(mcc, mccmnc, 3); + mcc[3] = '\0'; + strncpy(mnc, mccmnc + 3, 3); + mnc[strlen(mccmnc) - 3] = '\0'; + for (int i = 0; i < networks.size; i++) { + if (strcmp(networks.items[i].conf.mcc, mcc) == 0) { + if (strcmp(networks.items[i].conf.mnc, mnc) == 0) { + return i; + } + } + } + return -1; +} + +plmn_t make_plmn_from_conf(const plmn_conf_param_t *plmn_conf) { + plmn_t plmn; + char num[6]; + + memset(&plmn, 0xff, sizeof(plmn)); + + snprintf(num, 6, "%s%s", plmn_conf->mcc, plmn_conf->mnc); + + plmn.MCCdigit2 = plmn_conf->mcc[1]; + plmn.MCCdigit1 = plmn_conf->mcc[0]; + plmn.MCCdigit3 = plmn_conf->mcc[2]; + plmn.MNCdigit2 = plmn_conf->mnc[1]; + plmn.MNCdigit1 = plmn_conf->mnc[0]; + if (strlen(plmn_conf->mnc) > 2) { + plmn.MNCdigit3 = plmn_conf->mnc[2]; + } + return plmn; +} + +void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record) { + strcpy(record->fullname, conf->fullname); + strcpy(record->shortname, conf->shortname); + + char num[6]; + sprintf(num, "%s%s", conf->mcc, conf->mnc); + record->num = atoi(num); + + record->plmn = make_plmn_from_conf(conf); + record->tac_end = 0xfffd; + record->tac_start = 0x0001; +} + +bool parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf) { + int rc = 0; + rc = config_setting_lookup_string(plmn_setting, FULLNAME, &conf->fullname); + if (rc != 1) { + printf("Error on FULLNAME\n"); + return false; + } + rc = config_setting_lookup_string(plmn_setting, SHORTNAME, &conf->shortname); + if (rc != 1) { + printf("Error on SHORTNAME\n"); + return false; + } + rc = config_setting_lookup_string(plmn_setting, MNC, &conf->mnc); + if (rc != 1 || strlen(conf->mnc) > 3 + || strlen(conf->mnc) < 2) { + printf("Error ond MNC. Exiting\n"); + return false; + } + rc = config_setting_lookup_string(plmn_setting, MCC, &conf->mcc); + if (rc != 1 || strlen(conf->mcc) != 3) { + printf("Error on MCC\n"); + return false; + } + return true; +} + +bool parse_plmns(config_setting_t *all_plmn_setting, networks_t *networks) { + config_setting_t *plmn_setting = NULL; + char plmn[10]; + int size = 0; + + size = config_setting_length(all_plmn_setting); + + networks->size = size; + networks->items = malloc(sizeof(network_t) * size); + for (int i = 0; i < size; i++) { + memset(&networks->items[i].record, 0xff, sizeof(network_record_t)); + } + + for (int i = 0; i < networks->size; i++) { + network_t *network = &networks->items[i]; + sprintf(plmn, "%s%d", PLMN, i); + plmn_setting = config_setting_get_member(all_plmn_setting, plmn); + if (plmn_setting == NULL) { + printf("PLMN%d not fouund\n", i); + return false; + } + + if ( parse_plmn_param(plmn_setting, &network->conf) == false ) { + return false; + } + gen_network_record_from_conf(&network->conf, &network->record); + network->plmn = network->record.plmn; + } + return true; +} + + diff --git a/openair3/NAS/TOOLS/conf_network.h b/openair3/NAS/TOOLS/conf_network.h new file mode 100644 index 0000000000000000000000000000000000000000..a535841a4cfbc7bc4b41a186ab28dc476a793dbc --- /dev/null +++ b/openair3/NAS/TOOLS/conf_network.h @@ -0,0 +1,54 @@ +#ifndef _CONF_NETWORK_H +#define _CONF_NETWORK_H + +#include <stdbool.h> +#include <libconfig.h> +#include "usim_api.h" + +#define PLMN "PLMN" + +#define FULLNAME "FULLNAME" +#define SHORTNAME "SHORTNAME" +#define MNC "MNC" +#define MCC "MCC" + +#define MIN_TAC 0x0000 +#define MAX_TAC 0xFFFE + +/* + * 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; + +typedef struct { + plmn_conf_param_t conf; + network_record_t record; + plmn_t plmn; +} network_t; + +typedef struct { + int size; + network_t *items; +} networks_t; + +bool parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf); +bool parse_plmns(config_setting_t *all_plmn_setting, networks_t *plmns); + +void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record); +int get_plmn_index(const char * mccmnc, const networks_t networks); + +#endif diff --git a/openair3/NAS/TOOLS/conf_parser.c b/openair3/NAS/TOOLS/conf_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..d46142c4614970827c3a050323297480670f848e --- /dev/null +++ b/openair3/NAS/TOOLS/conf_parser.c @@ -0,0 +1,119 @@ +#include "conf_parser.h" + +#include "conf_network.h" +#include "conf_emm.h" +#include "conf_usim.h" +#include "conf_user_data.h" +#include "conf_user_plmn.h" + +bool parse_config_file(const char *output_dir, const char *conf_filename, int output_flags) { + int rc = true; + int ret; + int ue_nb = 0; + config_setting_t *root_setting = NULL; + config_setting_t *ue_setting = NULL; + config_setting_t *all_plmn_setting = NULL; + char user[10]; + config_t cfg; + + networks_t networks;; + + ret = get_config_from_file(conf_filename, &cfg); + if (ret == false) { + exit(1); + } + + 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) { + printf("NO PLMN SECTION...EXITING...\n"); + return (false); + } + + if ( parse_plmns(all_plmn_setting, &networks) == false ) { + return false; + } + + for (int i = 0; i < ue_nb; i++) { + emm_nvdata_t emm_data; + + user_nvdata_t user_data; + user_data_conf_t user_data_conf; + + usim_data_t usim_data; + usim_data_conf_t usim_data_conf; + + user_plmns_t user_plmns; + + sprintf(user, "%s%d", UE, i); + + ue_setting = config_setting_get_member(root_setting, user); + if (ue_setting == NULL) { + printf("Check UE%d settings\n", i); + return false; + } + + if ( parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn, networks) == false ) { + return false; + } + + rc = parse_ue_user_data(ue_setting, i, &user_data_conf); + if (rc != true) { + printf("Problem in USER section for UE%d. EXITING...\n", i); + return false; + } + gen_user_data(&user_data_conf, &user_data); + + rc = parse_ue_sim_param(ue_setting, i, &usim_data_conf); + if (rc != true) { + printf("Problem in SIM section for UE%d. EXITING...\n", i); + return false; + } + gen_usim_data(&usim_data_conf, &usim_data, &user_plmns, networks); + + gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin, + &user_plmns.equivalents_home, networks); + + if ( output_flags & OUTPUT_UEDATA ) { + write_user_data(output_dir, i, &user_data); + } + + if ( output_flags & OUTPUT_USIM ) { + write_usim_data(output_dir, i, &usim_data); + } + + if ( output_flags & OUTPUT_EMM ) { + write_emm_data(output_dir, i, &emm_data); + } + + user_plmns_free(&user_plmns); + + } + free(networks.items); + networks.size=0; + config_destroy(&cfg); + return(true); +} + +bool get_config_from_file(const char *filename, config_t *config) { + config_init(config); + if (filename == NULL) { + // XXX write error message ? + return(false); + } + + /* Read the file. If there is an error, report it and exit. */ + if (!config_read_file(config, filename)) { + fprintf(stderr, "Cant read config file '%s': %s\n", filename, + config_error_text(config)); + if ( config_error_type(config) == CONFIG_ERR_PARSE ) { + fprintf(stderr, "This is line %d\n", config_error_line(config)); + } + config_destroy(config); + return (false); + } + return true; +} + diff --git a/openair3/NAS/TOOLS/conf_parser.h b/openair3/NAS/TOOLS/conf_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..49d3645faf02a76aa134e5b08ed76c3efbd42bdf --- /dev/null +++ b/openair3/NAS/TOOLS/conf_parser.h @@ -0,0 +1,17 @@ +#ifndef _CONF_PARSER_H +#define _CONF_PARSER_H + +#include <stdbool.h> +#include <libconfig.h> + +#define UE "UE" + +#define OUTPUT_EMM 1 +#define OUTPUT_USIM 2 +#define OUTPUT_UEDATA 4 +#define OUTPUT_ALL 7 + +bool get_config_from_file(const char *filename, config_t *config); +bool parse_config_file(const char *output_dir, const char *filename, int output_flags); + +#endif diff --git a/openair3/NAS/TOOLS/conf_user_data.c b/openair3/NAS/TOOLS/conf_user_data.c new file mode 100644 index 0000000000000000000000000000000000000000..5e14797e166fad8c3ba5a9c5e85ae3ab79ecf2f1 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_user_data.c @@ -0,0 +1,86 @@ +#include <string.h> +#include <stdlib.h> + +#include "commonDef.h" +#include "memory.h" +#include "fs.h" +#include "conf_user_data.h" + +int parse_ue_user_data(config_setting_t *ue_setting, int user_id, user_data_conf_t *u) { + config_setting_t *ue_param_setting = NULL; + + int rc = true; + ue_param_setting = config_setting_get_member(ue_setting, USER); + if (ue_param_setting == NULL) { + printf("Check USER section of UE%d. EXITING...\n", user_id); + return false; + } + rc = config_setting_lookup_string(ue_param_setting, UE_IMEI, &u->imei); + if (rc != 1) { + printf("Check USER IMEI section for UE%d. Exiting\n", user_id); + return false; + } + rc = config_setting_lookup_string(ue_param_setting, MANUFACTURER, + &u->manufacturer); + if (rc != 1) { + printf("Check USER MANUFACTURER for UE%d FULLNAME. Exiting\n", user_id); + return false; + } + rc = config_setting_lookup_string(ue_param_setting, MODEL, &u->model); + if (rc != 1) { + printf("Check USER MODEL for UE%d FULLNAME. Exiting\n", user_id); + return false; + } + rc = config_setting_lookup_string(ue_param_setting, PINCODE, &u->pin); + if (rc != 1) { + printf("Check USER PIN for UE%d FULLNAME. Exiting\n", user_id); + return false; + } + return true; +} + +void gen_user_data(user_data_conf_t *u, user_nvdata_t *user_data) { + memset(user_data, 0, sizeof(user_nvdata_t)); + snprintf(user_data->IMEI, USER_IMEI_SIZE + 1, "%s%d", u->imei, _luhn(u->imei)); + /* + * Manufacturer identifier + */ + strncpy(user_data->manufacturer, u->manufacturer, USER_MANUFACTURER_SIZE); + /* + * Model identifier + */ + strncpy(user_data->model, u->model, USER_MODEL_SIZE); + /* + * SIM Personal Identification Number + */ + strncpy(user_data->PIN, u->pin, USER_PIN_SIZE); +} + +bool write_user_data(const char *directory, int user_id, user_nvdata_t *data) { + int rc; + char* filename = make_filename(directory, USER_NVRAM_FILENAME, user_id); + rc = memory_write(filename, data, sizeof(user_nvdata_t)); + free(filename); + if (rc != RETURNok) { + perror("ERROR\t: memory_write() failed"); + return false; + } + return true; +} + +/* + * Computes the check digit using Luhn algorithm + */ +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); +} + + diff --git a/openair3/NAS/TOOLS/conf_user_data.h b/openair3/NAS/TOOLS/conf_user_data.h new file mode 100644 index 0000000000000000000000000000000000000000..6b1d641e030c5f4bea3f529ca19531808c504481 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_user_data.h @@ -0,0 +1,27 @@ +#ifndef _CONF_USER_DATA_H +#define _CONF_USER_DATA_H + +#include <stdbool.h> +#include <libconfig.h> +#include "userDef.h" + +#define USER "USER" +#define MANUFACTURER "MANUFACTURER" +#define MODEL "MODEL" +#define UE_IMEI "IMEI" +#define PINCODE "PIN" + +typedef struct { + const char* imei; + const char* manufacturer; + const char* model; + const char* pin; +} user_data_conf_t; + +void gen_user_data(user_data_conf_t *u, user_nvdata_t *user_data); +bool write_user_data(const char *directory, int user_id, user_nvdata_t *data); +int parse_ue_user_data(config_setting_t *ue_setting, int user_id, user_data_conf_t *u); + +int _luhn(const char* cc); + +#endif diff --git a/openair3/NAS/TOOLS/conf_user_plmn.c b/openair3/NAS/TOOLS/conf_user_plmn.c new file mode 100644 index 0000000000000000000000000000000000000000..3b3c6dd3e6c1f2759d06e39274d711de512f0e96 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_user_plmn.c @@ -0,0 +1,81 @@ +#include <stdlib.h> +#include <string.h> +#include "conf_user_plmn.h" + +bool parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, + user_plmns_t *user_plmns, const char **h, + const networks_t networks) { + int nb_errors = 0; + const char *hplmn; + + if ( config_setting_lookup_string(ue_setting, HPLMN, h) != 1 ) { + printf("Check HPLMN section for UE%d. Exiting\n", user_id); + return false; + } + hplmn = *h; + if (get_plmn_index(hplmn, networks) == -1) { + printf("HPLMN for UE%d is not defined in PLMN section. Exiting\n", + user_id); + return false; + } + + if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &user_plmns->users_controlled, networks) == false ) + nb_errors++; + if ( parse_Xplmn(ue_setting, OPLMN, user_id, &user_plmns->operators, networks) == false ) + nb_errors++; + if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &user_plmns->operators_controlled, networks) == false ) + nb_errors++; + if ( parse_Xplmn(ue_setting, FPLMN, user_id, &user_plmns->forbiddens, networks) == false ) + nb_errors++; + if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &user_plmns->equivalents_home, networks) == false ) + nb_errors++; + + if ( nb_errors > 0 ) + return false; + return true; +} + +bool parse_Xplmn(config_setting_t *ue_setting, const char *section, + int user_id, plmns_list *plmns, const networks_t networks) { + int rc; + int item_count; + config_setting_t *setting; + + setting = config_setting_get_member(ue_setting, section); + if (setting == NULL) { + printf("Check %s section for UE%d. Exiting\n", section, user_id); + return false; + } + + item_count = config_setting_length(setting); + int *datas = malloc(item_count * sizeof(int)); + for (int i = 0; i < item_count; i++) { + const char *mccmnc = config_setting_get_string_elem(setting, i); + if (mccmnc == NULL) { + printf("Check %s section for UE%d. Exiting\n", section, user_id); + free(datas); + return false; + } + rc = get_plmn_index(mccmnc, networks); + if (rc == -1) { + printf("The PLMN %s is not defined in PLMN section. Exiting...\n", + mccmnc); + free(datas); + return false; + } + datas[i] = rc; + } + + plmns->size = item_count; + plmns->items = datas; + return true; +} + +void user_plmns_free(user_plmns_t *user_plmns) { + free(user_plmns->users_controlled.items); + free(user_plmns->operators.items); + free(user_plmns->operators_controlled.items); + free(user_plmns->forbiddens.items); + free(user_plmns->equivalents_home.items); + memset(user_plmns, 0, sizeof(user_plmns_t)); +} diff --git a/openair3/NAS/TOOLS/conf_user_plmn.h b/openair3/NAS/TOOLS/conf_user_plmn.h new file mode 100644 index 0000000000000000000000000000000000000000..561767b6c4823471171e1bd5e628707d88581b23 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_user_plmn.h @@ -0,0 +1,37 @@ +#ifndef _CONF_USER_H +#define _CONF_USER_H + +#include <stdbool.h> +#include <libconfig.h> +#include "conf_network.h" + +#define HPLMN "HPLMN" +#define UCPLMN "UCPLMN_LIST" +#define OPLMN "OPLMN_LIST" +#define OCPLMN "OCPLMN_LIST" +#define FPLMN "FPLMN_LIST" +#define EHPLMN "EHPLMN_LIST" + +typedef struct { + int size; + int *items; +} plmns_list; + +typedef struct { + plmns_list users_controlled; + plmns_list operators; + plmns_list operators_controlled; + plmns_list forbiddens; + plmns_list equivalents_home; +} user_plmns_t; + +bool parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, + user_plmns_t *user_plmns, const char **h, + const networks_t networks); + +bool parse_Xplmn(config_setting_t *ue_setting, const char *section, + int user_id, plmns_list *plmns, const networks_t networks); + +void user_plmns_free(user_plmns_t *user_plmns); + +#endif diff --git a/openair3/NAS/TOOLS/conf_usim.c b/openair3/NAS/TOOLS/conf_usim.c new file mode 100644 index 0000000000000000000000000000000000000000..3a5c6dbf6d146285fd0e3dedc37b5b8bf6d07ecf --- /dev/null +++ b/openair3/NAS/TOOLS/conf_usim.c @@ -0,0 +1,308 @@ +#include <string.h> +#include <stdlib.h> + +#include "userDef.h" +#include "utils.h" +#include "conf_emm.h" +#include "fs.h" +#include "conf_usim.h" + +bool parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u) { + int rc = true; + config_setting_t *ue_param_setting = NULL; + ue_param_setting = config_setting_get_member(ue_setting, SIM); + if (ue_param_setting == NULL) { + printf("Check SIM section for UE%d. EXITING...\n", user_id); + return false; + } + rc = config_setting_lookup_string(ue_param_setting, MSIN, &u->msin); + if (rc != 1 || strlen(u->msin) > 10 || strlen(u->msin) < 9) { + printf("Check SIM MSIN section for UE%d. Exiting\n", user_id); + return false; + } + rc = config_setting_lookup_string(ue_param_setting, USIM_API_K, + &u->usim_api_k); + if (rc != 1) { + printf("Check SIM USIM_API_K section for UE%d. Exiting\n", user_id); + return false; + } + rc = config_setting_lookup_string(ue_param_setting, OPC, &u->opc); + if (rc != 1) { + printf("Check SIM OPC section for UE%d. Exiting\n", user_id); + return false; + } + rc = config_setting_lookup_string(ue_param_setting, MSISDN, &u->msisdn); + if (rc != 1) { + printf("Check SIM MSISDN section for UE%d. Exiting\n", user_id); + return false; + } + return true; +} + +void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, + const user_plmns_t *user_plmns, const networks_t networks) { + int hplmn_index = get_plmn_index(u->hplmn, networks); + const plmn_conf_param_t *conf = &networks.items[hplmn_index].conf; + memset(usim_data, 0, sizeof(usim_data_t)); + usim_data->imsi.length = 8; + usim_data->imsi.u.num.parity = get_msin_parity(u->msin, + conf->mcc, + conf->mnc); + + usim_data->imsi.u.num.digit1 = conf->mcc[0]; + usim_data->imsi.u.num.digit2 = conf->mcc[1]; + usim_data->imsi.u.num.digit3 = conf->mcc[2]; + + usim_data->imsi.u.num.digit4 = conf->mnc[0]; + usim_data->imsi.u.num.digit5 = conf->mnc[1]; + + if (strlen(conf->mnc) == 2) { + usim_data->imsi.u.num.digit6 = u->msin[0]; + usim_data->imsi.u.num.digit7 = u->msin[1]; + usim_data->imsi.u.num.digit8 = u->msin[2]; + usim_data->imsi.u.num.digit9 = u->msin[3]; + usim_data->imsi.u.num.digit10 = u->msin[4]; + usim_data->imsi.u.num.digit11 = u->msin[5]; + usim_data->imsi.u.num.digit12 = u->msin[6]; + usim_data->imsi.u.num.digit13 = u->msin[7]; + usim_data->imsi.u.num.digit14 = u->msin[8]; + usim_data->imsi.u.num.digit15 = u->msin[9]; + } else { + usim_data->imsi.u.num.digit6 = conf->mnc[2]; + usim_data->imsi.u.num.digit7 = u->msin[0]; + usim_data->imsi.u.num.digit8 = u->msin[1]; + usim_data->imsi.u.num.digit9 = u->msin[2]; + usim_data->imsi.u.num.digit10 = u->msin[3]; + usim_data->imsi.u.num.digit11 = u->msin[4]; + usim_data->imsi.u.num.digit12 = u->msin[5]; + usim_data->imsi.u.num.digit13 = u->msin[6]; + usim_data->imsi.u.num.digit14 = u->msin[7]; + usim_data->imsi.u.num.digit15 = u->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 (user_plmns->forbiddens.size > 0) { + for (int i = 0; i < user_plmns->forbiddens.size; i++) { + usim_data->fplmn[i] = networks.items[user_plmns->forbiddens.items[i]].plmn; + } + } + + /* + * Location Information + */ + usim_data->loci.tmsi = DEFAULT_TMSI; + usim_data->loci.lai.plmn = networks.items[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 = networks.items[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(conf->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(u->msisdn); i += 2) { + usim_data->msisdn.number.digit[j].msb = u->msisdn[i]; + j++; + } + j = 0; + for (int i = 1; i < strlen(u->msisdn); i += 2) { + usim_data->msisdn.number.digit[j].lsb = u->msisdn[i]; + j++; + + } + if (strlen(u->msisdn) % 2 == 0) { + for (int i = strlen(u->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(u->msisdn) / 2].lsb = 0xf; + for (int i = (strlen(u->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 < user_plmns->operators.size; i++) { + network_record_t record = networks.items[user_plmns->operators.items[i]].record; + 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 (user_plmns->operators.size < USIM_OPL_MAX) { + for (int i = user_plmns->operators.size; i < USIM_OPL_MAX; i++) { + memset(&usim_data->opl[i].plmn, 0xff, sizeof(plmn_t)); + } + } + + /* + * List of Equivalent HPLMNs + */ + for (int i = 0; i < user_plmns->equivalents_home.size; i++) { + usim_data->ehplmn[i] = networks.items[user_plmns->equivalents_home.items[i]].plmn; + } + if (user_plmns->equivalents_home.size < USIM_EHPLMN_MAX) { + for (int i = user_plmns->equivalents_home.size; i < USIM_EHPLMN_MAX; i++) { + memset(&usim_data->ehplmn[i], 0xff, sizeof(plmn_t)); + } + } + /* + * Home PLMN Selector with Access Technology + */ + usim_data->hplmn.plmn = networks.items[hplmn_index].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)); + } + if (user_plmns->users_controlled.size > 0) { + for (int i = 0; i < user_plmns->users_controlled.size; i++) { + usim_data->plmn[i].plmn = networks.items[user_plmns->users_controlled.items[i]].plmn; + } + } + + // List of operator controlled PLMN selector with Access Technology + + for (int i = 0; i < USIM_OPLMN_MAX; i++) { + memset(&usim_data->oplmn[i], 0xff, sizeof(plmn_t)); + } + if (user_plmns->operators_controlled.size > 0) { + for (int i = 0; i < user_plmns->operators_controlled.size; i++) { + usim_data->oplmn[i].plmn = networks.items[user_plmns->operators_controlled.items[i]].plmn; + usim_data->oplmn[i].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN + | USIM_ACT_EUTRAN); + } + } + /* + * EPS Location Information + */ + usim_data->epsloci.guti.gummei.plmn = + networks.items[hplmn_index].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; + + /* initialize the subscriber authentication security key */ + if (hex_string_to_hex_value(usim_data->keys.usim_api_k, + u->usim_api_k, USIM_API_K_SIZE) == -1 || + hex_string_to_hex_value(usim_data->keys.opc, + u->opc, OPC_SIZE) == -1) { + fprintf(stderr, "fix your configuration file\n"); + exit(1); + } +} + +bool write_usim_data(const char *directory, int user_id, usim_data_t *usim_data){ + int rc; + char *filename = make_filename(directory, USIM_API_NVRAM_FILENAME, user_id); + rc = usim_api_write(filename, usim_data); + free(filename); + return rc; +} + + diff --git a/openair3/NAS/TOOLS/conf_usim.h b/openair3/NAS/TOOLS/conf_usim.h new file mode 100644 index 0000000000000000000000000000000000000000..4768a6d8c0c9239a639fa82b5946ca013d0ad98b --- /dev/null +++ b/openair3/NAS/TOOLS/conf_usim.h @@ -0,0 +1,48 @@ +#ifndef _CONF_USIM_H +#define _CONF_USIM_H + +#include <libconfig.h> +#include "usim_api.h" +#include "conf_user_plmn.h" + +#define SIM "SIM" +#define MSIN "MSIN" +#define USIM_API_K "USIM_API_K" +#define OPC "OPC" +#define MSISDN "MSISDN" + +#define KSI USIM_KSI_NOT_AVAILABLE +#define KSI_ASME USIM_KSI_NOT_AVAILABLE + +#define OPC_SIZE 16 + +#define DEFAULT_TMSI 0x0000000D +#define DEFAULT_P_TMSI 0x0000000D +#define DEFAULT_M_TMSI 0x0000000D + +#define DEFAULT_RAC 0x01 +#define DEFAULT_TAC 0x0001 +#define DEFAULT_LAC 0xFFFE + +#define DEFAULT_MME_ID 0x0102 +#define DEFAULT_MME_CODE 0x0F + +// TODO add this setting in configuration file +#define INT_ALGO USIM_INT_EIA2 +#define ENC_ALGO USIM_ENC_EEA0 +#define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO) + +typedef struct { + const char *msin; + const char *usim_api_k; + const char *msisdn; + const char *opc; + const char *hplmn; +} usim_data_conf_t; + +bool parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u); +bool write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); +void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, + const user_plmns_t *user_plmns, const networks_t networks); + +#endif diff --git a/openair3/NAS/TOOLS/display.c b/openair3/NAS/TOOLS/display.c new file mode 100644 index 0000000000000000000000000000000000000000..7d145d1f3b6dd648e229bb41c7900132dbe86b2d --- /dev/null +++ b/openair3/NAS/TOOLS/display.c @@ -0,0 +1,372 @@ +#include <stdlib.h> +#include <string.h> + +#include "userDef.h" +#include "usim_api.h" +#include "emmData.h" +#include "display.h" +#include "memory.h" +#include "fs.h" + +#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) + +#define PRINT_PLMN(plmn) \ + PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit3) + +#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) + +#define PRINT_PLMN(plmn) \ + PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit3) + +// return number of files displayed +int display_data_from_directory(const char *directory, int flags) { + int user_id = 0; + char *filename; + bool found = true; + int displayed_count = 0; + + while ( found ) { + found = false; + + if ( flags & DISPLAY_UEDATA ) { + filename = get_ue_filename(directory, user_id); + if ( file_exist_and_is_readable(filename) ) { + display_ue_data(filename); + displayed_count += 1; + found = true; + printf("UE identity data file: %s\n", filename); + } + free(filename); + } + + if ( flags & DISPLAY_EMM ) { + filename = get_emm_filename(directory, user_id); + if ( file_exist_and_is_readable(filename) ) { + display_emm_data(filename); + displayed_count += 1; + found = true; + printf("EPS Mobility Management data file: %s\n", filename); + } + free(filename); + } + + if ( flags & DISPLAY_USIM ) { + filename = get_usim_filename(directory, user_id); + if ( file_exist_and_is_readable(filename) ) { + display_usim_data(filename); + displayed_count += 1; + found = true; + printf("USIM data file: %s\n", filename); + } + free(filename); + } + + user_id += 1; + } + return displayed_count; +} + +void display_ue_data(const char *filename) { + user_nvdata_t data; + int rc; + /* + * Read UE's non-volatile data + */ + memset(&data, 0, sizeof(user_nvdata_t)); + rc = memory_read(filename, &data, sizeof(user_nvdata_t)); + + if (rc != RETURNok) { + perror("ERROR\t: memory_read() failed"); + exit(false); + } + + /* + * Display UE's non-volatile data + */ + printf("\nUE's non-volatile data:\n\n"); + printf("IMEI\t\t= %s\n", data.IMEI); + printf("manufacturer\t= %s\n", data.manufacturer); + printf("model\t\t= %s\n", data.model); + printf("PIN\t\t= %s\n", data.PIN); +} + +/* + * Displays UE's non-volatile EMM data + */ +void display_emm_data(const char *filename) { + + int rc; + emm_nvdata_t data; + + /* + * Read EMM non-volatile data + */ + memset(&data, 0, sizeof(emm_nvdata_t)); + rc = memory_read(filename, &data, sizeof(emm_nvdata_t)); + if (rc != RETURNok) { + perror("ERROR\t: memory_read() failed "); + exit(false); + } + + /* + * Display EMM non-volatile data + */ + printf("\nEMM non-volatile data:\n\n"); + + printf("IMSI\t\t= "); + + if (data.imsi.u.num.digit6 == 0b1111) { + if (data.imsi.u.num.digit15 == 0b1111) { + printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14); + } else { + printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14, + data.imsi.u.num.digit15); + } + } else { + if (data.imsi.u.num.digit15 == 0b1111) { + printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + data.imsi.u.num.digit6, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14); + } else { + printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + data.imsi.u.num.digit6, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14, + data.imsi.u.num.digit15); + } + } + + printf("RPLMN\t\t= "); + PRINT_PLMN(data.rplmn); + printf("\n"); + + for (int i = 0; i < data.eplmn.n_plmns; i++) { + printf("EPLMN[%d]\t= ", i); + PRINT_PLMN(data.eplmn.plmn[i]); + printf("\n"); + } +} + +void display_usim_data(const char *filename) { + + int rc; + usim_data_t data = { }; + + rc = usim_api_read(filename, &data); + + if (rc != RETURNok) { + perror("ERROR\t: usim_api_read() failed"); + exit(2); + } + + /* + * Display USIM application data + */ + printf("\nUSIM data:\n\n"); + int digits; + + printf("Administrative Data:\n"); + printf("\tUE_Operation_Mode\t= 0x%.2x\n", data.ad.UE_Operation_Mode); + printf("\tAdditional_Info\t\t= 0x%.4x\n", data.ad.Additional_Info); + printf("\tMNC_Length\t\t= %d\n\n", data.ad.MNC_Length); + + printf("IMSI:\n"); + printf("\tlength\t= %d\n", data.imsi.length); + printf("\tparity\t= %s\n", + data.imsi.u.num.parity == EVEN_PARITY ? "Even" : "Odd"); + digits = (data.imsi.length * 2) - 1 + - (data.imsi.u.num.parity == EVEN_PARITY ? 1 : 0); + printf("\tdigits\t= %d\n", digits); + printf("\tdigits\t= %u%u%u%u%u%x%u%u%u%u", + data.imsi.u.num.digit1, // MCC digit 1 + data.imsi.u.num.digit2, // MCC digit 2 + data.imsi.u.num.digit3, // MCC digit 3 + data.imsi.u.num.digit4, // MNC digit 1 + data.imsi.u.num.digit5, // MNC digit 2 + data.imsi.u.num.digit6, // MNC digit 3 + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10); + + if (digits >= 11) + printf("%x", data.imsi.u.num.digit11); + + if (digits >= 12) + printf("%x", data.imsi.u.num.digit12); + + if (digits >= 13) + printf("%x", data.imsi.u.num.digit13); + + if (digits >= 14) + printf("%x", data.imsi.u.num.digit14); + + if (digits >= 15) + printf("%x", data.imsi.u.num.digit15); + + printf("\n\n"); + + printf("Ciphering and Integrity Keys:\n"); + printf("\tKSI\t: 0x%.2x\n", data.keys.ksi); + char key[USIM_CK_SIZE + 1]; + key[USIM_CK_SIZE] = '\0'; + memcpy(key, data.keys.ck, USIM_CK_SIZE); + printf("\tCK\t: \"%s\"\n", key); + memcpy(key, data.keys.ik, USIM_IK_SIZE); + printf("\tIK\t: \"%s\"\n", key); + + printf("EPS NAS security context:\n"); + printf("\tKSIasme\t: 0x%.2x\n", data.securityctx.KSIasme.value[0]); + char kasme[USIM_K_ASME_SIZE + 1]; + kasme[USIM_K_ASME_SIZE] = '\0'; + memcpy(kasme, data.securityctx.Kasme.value, USIM_K_ASME_SIZE); + printf("\tKasme\t: \"%s\"\n", kasme); + printf("\tulNAScount\t: 0x%.8x\n", + *(uint32_t*) data.securityctx.ulNAScount.value); + printf("\tdlNAScount\t: 0x%.8x\n", + *(uint32_t*) data.securityctx.dlNAScount.value); + printf("\talgorithmID\t: 0x%.2x\n\n", + data.securityctx.algorithmID.value[0]); + + printf("MSISDN\t= %u%u%u %u%u%u%u %u%u%u%u\n\n", + data.msisdn.number.digit[0].msb, data.msisdn.number.digit[0].lsb, + data.msisdn.number.digit[1].msb, data.msisdn.number.digit[1].lsb, + data.msisdn.number.digit[2].msb, data.msisdn.number.digit[2].lsb, + data.msisdn.number.digit[3].msb, data.msisdn.number.digit[3].lsb, + data.msisdn.number.digit[4].msb, data.msisdn.number.digit[4].lsb, + data.msisdn.number.digit[5].msb); + + for (int i = 0; i < USIM_PNN_MAX; i++) { + printf("PNN[%d]\t= {%s, %s}\n", i, data.pnn[i].fullname.value, + data.pnn[i].shortname.value); + } + + printf("\n"); + + for (int i = 0; i < USIM_OPL_MAX; i++) { + printf("OPL[%d]\t= ", i); + PRINT_PLMN(data.opl[i].plmn); + printf(", TAC = [%.4x - %.4x], record_id = %d\n", data.opl[i].start, + data.opl[i].end, data.opl[i].record_id); + } + + printf("\n"); + + printf("HPLMN\t\t= "); + PRINT_PLMN(data.hplmn.plmn); + printf(", AcT = 0x%x\n\n", data.hplmn.AcT); + + for (int i = 0; i < USIM_FPLMN_MAX; i++) { + printf("FPLMN[%d]\t= ", i); + PRINT_PLMN(data.fplmn[i]); + printf("\n"); + } + + printf("\n"); + + for (int i = 0; i < USIM_EHPLMN_MAX; i++) { + printf("EHPLMN[%d]\t= ", i); + PRINT_PLMN(data.ehplmn[i]); + printf("\n"); + } + + printf("\n"); + + for (int i = 0; i < USIM_PLMN_MAX; i++) { + printf("PLMN[%d]\t\t= ", i); + PRINT_PLMN(data.plmn[i].plmn); + printf(", AcTPLMN = 0x%x", data.plmn[i].AcT); + printf("\n"); + } + + printf("\n"); + + for (int i = 0; i < USIM_OPLMN_MAX; i++) { + printf("OPLMN[%d]\t= ", i); + PRINT_PLMN(data.oplmn[i].plmn); + printf(", AcTPLMN = 0x%x", data.oplmn[i].AcT); + printf("\n"); + } + + printf("\n"); + + printf("HPPLMN\t\t= 0x%.2x (%d minutes)\n\n", data.hpplmn, data.hpplmn); + + printf("LOCI:\n"); + printf("\tTMSI = 0x%.4x\n", data.loci.tmsi); + printf("\tLAI\t: PLMN = "); + PRINT_PLMN(data.loci.lai.plmn); + printf(", LAC = 0x%.2x\n", data.loci.lai.lac); + printf("\tstatus\t= %d\n\n", data.loci.status); + + printf("PSLOCI:\n"); + printf("\tP-TMSI = 0x%.4x\n", data.psloci.p_tmsi); + printf("\tsignature = 0x%x 0x%x 0x%x\n", data.psloci.signature[0], + data.psloci.signature[1], data.psloci.signature[2]); + printf("\tRAI\t: PLMN = "); + PRINT_PLMN(data.psloci.rai.plmn); + printf(", LAC = 0x%.2x, RAC = 0x%.1x\n", data.psloci.rai.lac, + data.psloci.rai.rac); + printf("\tstatus\t= %d\n\n", data.psloci.status); + + printf("EPSLOCI:\n"); + printf("\tGUTI\t: GUMMEI\t: (PLMN = "); + PRINT_PLMN(data.epsloci.guti.gummei.plmn); + printf(", MMEgid = 0x%.2x, MMEcode = 0x%.1x)", + data.epsloci.guti.gummei.MMEgid, data.epsloci.guti.gummei.MMEcode); + printf(", M-TMSI = 0x%.4x\n", data.epsloci.guti.m_tmsi); + printf("\tTAI\t: PLMN = "); + PRINT_PLMN(data.epsloci.tai.plmn); + printf(", TAC = 0x%.2x\n", data.epsloci.tai.tac); + printf("\tstatus\t= %d\n\n", data.epsloci.status); + + printf("NASCONFIG:\n"); + printf("\tNAS_SignallingPriority\t\t: 0x%.2x\n", + data.nasconfig.NAS_SignallingPriority.value[0]); + printf("\tNMO_I_Behaviour\t\t\t: 0x%.2x\n", + data.nasconfig.NMO_I_Behaviour.value[0]); + printf("\tAttachWithImsi\t\t\t: 0x%.2x\n", + data.nasconfig.AttachWithImsi.value[0]); + printf("\tMinimumPeriodicSearchTimer\t: 0x%.2x\n", + data.nasconfig.MinimumPeriodicSearchTimer.value[0]); + printf("\tExtendedAccessBarring\t\t: 0x%.2x\n", + data.nasconfig.ExtendedAccessBarring.value[0]); + printf("\tTimer_T3245_Behaviour\t\t: 0x%.2x\n", + data.nasconfig.Timer_T3245_Behaviour.value[0]); + +} + + diff --git a/openair3/NAS/TOOLS/display.h b/openair3/NAS/TOOLS/display.h new file mode 100644 index 0000000000000000000000000000000000000000..fef721c490b8cf82b70416d493e86340f7d16d3e --- /dev/null +++ b/openair3/NAS/TOOLS/display.h @@ -0,0 +1,16 @@ +#ifndef _DISPLAY_H +#define _DISPLAY_H + +#define DISPLAY_EMM 1 +#define DISPLAY_USIM 2 +#define DISPLAY_UEDATA 4 +#define DISPLAY_ALL 7 + +// return number of files displayed +int display_data_from_directory(const char *directory, int flags); + +void display_ue_data(const char *filename); +void display_emm_data(const char *filename); +void display_usim_data(const char *filename); + +#endif diff --git a/openair3/NAS/TOOLS/fs.c b/openair3/NAS/TOOLS/fs.c new file mode 100644 index 0000000000000000000000000000000000000000..c25f10a1e790d8c9d34051e32831781948ebf77f --- /dev/null +++ b/openair3/NAS/TOOLS/fs.c @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "fs.h" +#include "user_api.h" +#include "utils.h" + +bool file_exist_and_is_readable(const char *filename) { + FILE *file ; + file = fopen(filename, "r"); + if ( file == NULL ) + return false; + fclose(file); + return true; +} + +char *get_ue_filename(const char *output_dir, int user_id) { + return make_filename(output_dir, USER_NVRAM_FILENAME, user_id); +} + +char *get_emm_filename(const char *output_dir, int user_id) { + return make_filename(output_dir, EMM_NVRAM_FILENAME, user_id); +} + +char *get_usim_filename(const char *output_dir, int user_id) { + return make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id); +} + +char *make_filename(const char *output_dir, const char *filename, int ueid) { + size_t size; + char *str_ueid, *str; + + str_ueid = itoa(ueid); + + if (str_ueid == NULL) { + perror("ERROR\t: itoa() failed"); + exit(EXIT_FAILURE); + } + + size = strlen(output_dir)+strlen(filename) + sizeof(ueid) + 1 + 1; // for \0 and for '/' + str = malloc(size); + if (str == NULL) { + perror("ERROR\t: make_filename() failed"); + exit(EXIT_FAILURE); + } + + snprintf(str, size, "%s/%s%s",output_dir, filename, str_ueid); + free(str_ueid); + + return str; +} diff --git a/openair3/NAS/TOOLS/fs.h b/openair3/NAS/TOOLS/fs.h new file mode 100644 index 0000000000000000000000000000000000000000..ecfca559550a2a440727f39045637a165209222d --- /dev/null +++ b/openair3/NAS/TOOLS/fs.h @@ -0,0 +1,12 @@ +#ifndef _FS_H +#define _FS_H + +#include <stdbool.h> + +bool file_exist_and_is_readable(const char *filename); +char *get_ue_filename(const char *output_dir, int user_id); +char *get_emm_filename(const char *output_dir, int user_id); +char *get_usim_filename(const char *output_dir, int user_id); +char *make_filename(const char *output_dir, const char *filename, int ueid); + +#endif diff --git a/openair3/NAS/TOOLS/nvram.c b/openair3/NAS/TOOLS/nvram.c new file mode 100644 index 0000000000000000000000000000000000000000..b10511f2fc94ca8f6acc92d2f08e235e54e61638 --- /dev/null +++ b/openair3/NAS/TOOLS/nvram.c @@ -0,0 +1,162 @@ +/* + * 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 NVRAM data generator + +Subsystem NVRAM data generator main process + +Author Frederic Maurel + +Description Implements the utility used to generate data stored in the + NVRAM application + + *****************************************************************************/ + +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <getopt.h> + +#include "conf_parser.h" +#include "display.h" + +#define DEFAULT_NAS_PATH "PWD" +#define OUTPUT_DIR_ENV "NVRAM_DIR" +void _display_usage(const char* command); + +int main (int argc, char * const argv[]) +{ + enum usim_command { + NVRAM_COMMAND_NONE, + NVRAM_COMMAND_PRINT, + NVRAM_COMMAND_GEN, + } command = NVRAM_COMMAND_NONE; + + char *output_dir = NULL; + char *conf_file = NULL; + const char options[]="gpc:o:h"; + const struct option options_long_option[] = { + {"gen", no_argument, NULL, 'g'}, + {"print", no_argument, NULL, 'p'}, + {"conf", required_argument, NULL, 'c'}, + {"output", required_argument, NULL, 'o'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0} + }; + int option_index; + char option_short; + + /* + * Read command line parameters + */ + while ( true ) { + option_short = getopt_long(argc, argv, options, options_long_option, &option_index ); + + if ( option_short == -1 ) + break; + + switch (option_short) { + case 'c': + conf_file = optarg; + break; + case 'g': + command = NVRAM_COMMAND_GEN; + break; + case 'p': + command = NVRAM_COMMAND_PRINT; + break; + case 'o': + output_dir = optarg; + break; + default: + break; + } + } + + if ( command == NVRAM_COMMAND_NONE ) { + _display_usage(argv[0]); + exit(EXIT_SUCCESS); + } + + /* compute default data directory if no output_dir is given */ + if ( output_dir == NULL ) { + output_dir = getenv(OUTPUT_DIR_ENV); + + if (output_dir == NULL) { + output_dir = getenv(DEFAULT_NAS_PATH); + } + + if (output_dir == NULL) { + fprintf(stderr, "%s and %s environment variables are not defined trying local directory", + OUTPUT_DIR_ENV, DEFAULT_NAS_PATH); + output_dir = "."; + } + } + + if ( command == NVRAM_COMMAND_GEN ) { + if ( conf_file == NULL ) { + printf("No Configuration file is given\n"); + _display_usage(argv[0]); + exit(EXIT_FAILURE); + } + + if ( parse_config_file(output_dir, conf_file, OUTPUT_UEDATA|OUTPUT_EMM) == false ) { + exit(EXIT_FAILURE); + } + } + + if ( display_data_from_directory(output_dir, DISPLAY_UEDATA|DISPLAY_EMM) == 0) { + fprintf(stderr, "No NVRAM files found in %s\n", output_dir); + } + + exit(EXIT_SUCCESS); +} + +/****************************************************************************/ +/********************* L O C A L F U N C T I O N S *********************/ +/****************************************************************************/ + +/* + * Displays command line usage + */ +void _display_usage(const char* command) +{ + fprintf(stderr, "usage: %s [OPTION]\n", command); + fprintf(stderr, "\t[--gen|-g]\tGenerate the NVRAM data file\n"); + fprintf(stderr, "\t[--print|-p]\tDisplay the content of the NVRAM data file\n"); + fprintf(stderr, "\t[-c]\tConfig file to use\n"); + fprintf(stderr, "\t[-o]\toutput file directory\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"); + } +} diff --git a/openair3/NAS/TOOLS/ue_bcom_test.conf b/openair3/NAS/TOOLS/ue_bcom_test.conf new file mode 100644 index 0000000000000000000000000000000000000000..c60b628941dbdc0090a567ec0ad67e575efc7b03 --- /dev/null +++ b/openair3/NAS/TOOLS/ue_bcom_test.conf @@ -0,0 +1,2334 @@ +PLMN: +{ + PLMN0: + { + FULLNAME="B<>COM Cubiq"; + SHORTNAME="BCOM"; + MNC="89"; + MCC="208"; + }; +}; + +UE0: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000000"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000000"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE1: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000001"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000001"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE2: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000002"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000002"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE3: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000003"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000003"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE4: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000004"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000004"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE5: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000005"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000005"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE6: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000006"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000006"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE7: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000007"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000007"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE8: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000008"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000008"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE9: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000009"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000009"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE10: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000010"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000010"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE11: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000011"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000011"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE12: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000012"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000012"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE13: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000013"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000013"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE14: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000014"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000014"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE15: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000015"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000015"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE16: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000016"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000016"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE17: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000017"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000017"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE18: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000018"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000018"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE19: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000019"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000019"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE20: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000020"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000020"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE21: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000021"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000021"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE22: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000022"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000022"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE23: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000023"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000023"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE24: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000024"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000024"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE25: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000025"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000025"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE26: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000026"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000026"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE27: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000027"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000027"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE28: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000028"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000028"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE29: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000029"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000029"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE30: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000030"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000030"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE31: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000031"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000031"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE32: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000032"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000032"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE33: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000033"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000033"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE34: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000034"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000034"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE35: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000035"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000035"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE36: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000036"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000036"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE37: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000037"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000037"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE38: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000038"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000038"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE39: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000039"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000039"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE40: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000040"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000040"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE41: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000041"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000041"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE42: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000042"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000042"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE43: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000043"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000043"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE44: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000044"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000044"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE45: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000045"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000045"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE46: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000046"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000046"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE47: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000047"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000047"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE48: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000048"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000048"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE49: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000049"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000049"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE50: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000050"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000050"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE51: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000051"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000051"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE52: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000052"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000052"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE53: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000053"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000053"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE54: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000054"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000054"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE55: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000055"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000055"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE56: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000056"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000056"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE57: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000057"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000057"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE58: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000058"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000058"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE59: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000059"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000059"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE60: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000060"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000060"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE61: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000061"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000061"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE62: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000062"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000062"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE63: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000063"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000063"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE64: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000064"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000064"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE65: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000065"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000065"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE66: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000066"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000066"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE67: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000067"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000067"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE68: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000068"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000068"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE69: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000069"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000069"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE70: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000070"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000070"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE71: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000071"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000071"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE72: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000072"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000072"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE73: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000073"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000073"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE74: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000074"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000074"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE75: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000075"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000075"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE76: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000076"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000076"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE77: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000077"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000077"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE78: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000078"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000078"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE79: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000079"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000079"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE80: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000080"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000080"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE81: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000081"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000081"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE82: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000082"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000082"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE83: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000083"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000083"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE84: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000084"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000084"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE85: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000085"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000085"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE86: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000086"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000086"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE87: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000087"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000087"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE88: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000088"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000088"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE89: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000089"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000089"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE90: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000090"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000090"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE91: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000091"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000091"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE92: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000092"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000092"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE93: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000093"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000093"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE94: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000094"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000094"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE95: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000095"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000095"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE96: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000096"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000096"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE97: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000097"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000097"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE98: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000098"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000098"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE99: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000099"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000099"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE100: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000100"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000100"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; diff --git a/openair3/NAS/TOOLS/ue_data.c b/openair3/NAS/TOOLS/ue_data.c deleted file mode 100644 index 3636ad6ee3d5519ecb61e81976f84a671be15bbe..0000000000000000000000000000000000000000 --- a/openair3/NAS/TOOLS/ue_data.c +++ /dev/null @@ -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"); - } -} diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf new file mode 100644 index 0000000000000000000000000000000000000000..84ec59a36bcb9906c8f9010a7dabfbfb2e62412e --- /dev/null +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -0,0 +1,114 @@ +# 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="0100001111"; + USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; + OPC="C42449363BBAD02B66D16BC975D77CC1"; + MSISDN="33611123456"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "20893"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20893", "310280", "310028"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; diff --git a/openair3/NAS/TOOLS/usim.c b/openair3/NAS/TOOLS/usim.c new file mode 100644 index 0000000000000000000000000000000000000000..242b30d65558e3a1c4f31aa89f61267bcac533a0 --- /dev/null +++ b/openair3/NAS/TOOLS/usim.c @@ -0,0 +1,162 @@ +/* + * 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 <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <getopt.h> + +#include "conf_parser.h" +#include "display.h" + +#define DEFAULT_NAS_PATH "PWD" +#define OUTPUT_DIR_ENV "USIM_DIR" +void _display_usage(const char* command); + +int main (int argc, char * const argv[]) +{ + enum usim_command { + USIM_COMMAND_NONE, + USIM_COMMAND_PRINT, + USIM_COMMAND_GEN, + } command = USIM_COMMAND_NONE; + + char *output_dir = NULL; + char *conf_file = NULL; + const char options[]="gpc:o:h"; + const struct option options_long_option[] = { + {"gen", no_argument, NULL, 'g'}, + {"print", no_argument, NULL, 'p'}, + {"conf", required_argument, NULL, 'c'}, + {"output", required_argument, NULL, 'o'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0} + }; + int option_index; + char option_short; + + /* + * Read command line parameters + */ + while ( true ) { + option_short = getopt_long(argc, argv, options, options_long_option, &option_index ); + + if ( option_short == -1 ) + break; + + switch (option_short) { + case 'c': + conf_file = optarg; + break; + case 'g': + command = USIM_COMMAND_GEN; + break; + case 'p': + command = USIM_COMMAND_PRINT; + break; + case 'o': + output_dir = optarg; + break; + default: + break; + } + } + + if ( command == USIM_COMMAND_NONE ) { + _display_usage(argv[0]); + exit(EXIT_SUCCESS); + } + + /* compute default data directory if no output_dir is given */ + if ( output_dir == NULL ) { + output_dir = getenv(OUTPUT_DIR_ENV); + + if (output_dir == NULL) { + output_dir = getenv(DEFAULT_NAS_PATH); + } + + if (output_dir == NULL) { + fprintf(stderr, "%s and %s environment variables are not defined trying local directory", + OUTPUT_DIR_ENV, DEFAULT_NAS_PATH); + output_dir = "."; + } + } + + if ( command == USIM_COMMAND_GEN ) { + if ( conf_file == NULL ) { + printf("No Configuration file is given\n"); + _display_usage(argv[0]); + exit(EXIT_FAILURE); + } + + if ( parse_config_file(output_dir, conf_file, OUTPUT_USIM) == false ) { + exit(EXIT_FAILURE); + } + } + + if ( display_data_from_directory(output_dir, DISPLAY_USIM) == 0) { + fprintf(stderr, "No USIM files found in %s\n", output_dir); + } + + exit(EXIT_SUCCESS); +} + +/****************************************************************************/ +/********************* L O C A L F U N C T I O N S *********************/ +/****************************************************************************/ + +/* + * Displays command line usage + */ +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[-c]\tConfig file to use\n"); + fprintf(stderr, "\t[-o]\toutput file directory\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"); + } +} diff --git a/openair3/NAS/TOOLS/usim_data.c b/openair3/NAS/TOOLS/usim_data.c deleted file mode 100644 index 23eba29bb134cf1fa3ad8a9bacec4f546d23cd96..0000000000000000000000000000000000000000 --- a/openair3/NAS/TOOLS/usim_data.c +++ /dev/null @@ -1,659 +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; - - /* - * 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(&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(&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 - */ - char* path = memory_get_path("USIM_DIR", ".usim.nvram"); - 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]); -} - diff --git a/openair3/NAS/UE/API/USER/Makefile b/openair3/NAS/UE/API/USER/Makefile deleted file mode 100644 index d5f4d6fffba2deb77a25a7739e06ac10e10b858e..0000000000000000000000000000000000000000 --- a/openair3/NAS/UE/API/USER/Makefile +++ /dev/null @@ -1,42 +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 -# */ - -ifndef PROJDIR -PROJDIR = $(PWD)/../../.. -INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(IESDIR) -I$(EMMMSGDIR) -I$(ESMMSGDIR) -endif - -include $(PROJDIR)/Makerules -include $(PROJDIR)/Makefile.inc - -all: $(OBJS) - -%.o: %.c Makefile - @echo Compiling $< - @$(CC) $(CFLAGS) -c $< -o $@ - -clean: - $(RM) $(OBJS) *.bak *~ - -depend: - makedepend -- ${CFLAGS} -- ${SRCS} - -# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/openair3/NAS/UE/API/USER/at_command.c b/openair3/NAS/UE/API/USER/at_command.c index 89793a55ae3bdb38ba1b61f5390678628ec053e8..8f40ba93c434f7f06e7765ff09774318db28f13e 100644 --- a/openair3/NAS/UE/API/USER/at_command.c +++ b/openair3/NAS/UE/API/USER/at_command.c @@ -54,6 +54,7 @@ Description Defines the ATtention (AT) command set supported by the NAS /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ +// FIXME Put this in .h extern int at_response_format_v1; extern int at_error_code_suppression_q1; extern at_error_format_t at_error_format; @@ -278,6 +279,7 @@ int at_command_decode(const char* buffer, int length, at_command_t* at_command) char* buf = strdup(buffer+2); char* cmd = strtok(buf, ";"); + // FIXME check overflow for (i=0; cmd && (rc != RETURNerror); i++) { rc = ParseString(cmd, &at_command[i]); cmd = strtok(NULL, ";"); diff --git a/openair3/NAS/UE/API/USER/at_error.c b/openair3/NAS/UE/API/USER/at_error.c index 443c6a3300c5b2f2e336906f1b43fc37e739c954..7548fb513effb3d502cac4ce593b1f55e7be55f1 100644 --- a/openair3/NAS/UE/API/USER/at_error.c +++ b/openair3/NAS/UE/API/USER/at_error.c @@ -49,6 +49,7 @@ Description Defines error codes returned when execution of AT command /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ +// FIXME put this in .h extern int at_response_format_v1; /* diff --git a/openair3/NAS/UE/API/USER/tst/Makefile b/openair3/NAS/UE/API/USER/tst/Makefile deleted file mode 100644 index 48681f31a515265263b44c36873018bfb7ed1dec..0000000000000000000000000000000000000000 --- a/openair3/NAS/UE/API/USER/tst/Makefile +++ /dev/null @@ -1,58 +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 -# */ - -ifndef PROJDIR -PROJDIR = $(PWD)/../../../.. -endif - -include $(PROJDIR)/Makerules -include $(PROJDIR)/Makefile.inc - -LIBS = -lutil -lapi -lEMMmsg -lESMmsg -lies -INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(USERAPIDIR) - -LIBSAPI = $(LIBDIR)/$(LIBAPI).a $(LIBDIR)/$(LIBAPI).so - -TST_OBJ = at_parser.o - -TST_TARGET = at_parser - -TARGETS = $(TST_TARGET) - -all: $(TARGETS) - -%.o: %.c Makefile - $(CC) $(CFLAGS) -c $< -o $@ - -$(TST_TARGET): $(TST_OBJ) - $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) - -clean: - $(RM) $(OBJS) $(TARGETS) *.bak *~ - -depend: - makedepend -- ${CFLAGS} -- ${SRCS} - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -at_parser.o: $(USERAPIDIR)/at_command.h -at_parser.o: $(INCDIR)/commonDef.h $(INCDIR)/userDef.h -at_parser.o: $(INCDIR)/networkDef.h $(UTILDIR)/log.h diff --git a/openair3/NAS/UE/API/USER/user_api.c b/openair3/NAS/UE/API/USER/user_api.c index 9c2364629276e16338711ae481a8f9e601b7fe9d..a1300ea059d9dac26cfe107c3c6d9c0e02fc4f38 100644 --- a/openair3/NAS/UE/API/USER/user_api.c +++ b/openair3/NAS/UE/API/USER/user_api.c @@ -45,9 +45,9 @@ Description Implements the API used by the NAS layer running in the UE #include "device.h" #include "nas_user.h" -#include "at_command.h" #include "at_response.h" #include "at_error.h" +#include "esm_ebr.h" #include "user_indication.h" @@ -68,63 +68,12 @@ Description Implements the API used by the NAS layer running in the UE /* * Asynchronous notification procedure handlers */ -static int _user_api_registration_handler(unsigned char id, const void* data, size_t size); -static int _user_api_location_handler(unsigned char id, const void* data, size_t size); -static int _user_api_network_handler(unsigned char id, const void* data, size_t size); -static int _user_api_pdn_connection_handler(unsigned char id, const void* data, size_t size); - -static int _user_api_send(at_response_t* data); - -/* ------------------- - * Connection endpoint - * ------------------- - * The connection endpoint is used to send/receive data to/from the - * user application layer. Its definition depends on the underlaying - * mechanism chosen to communicate (network socket, I/O terminal device). - * A connection endpoint is handled using an identifier, and functions - * used to retreive the file descriptor actually allocated by the system, - * to receive data, to send data, and to perform clean up when connection - * is shut down. - * Only one single end to end connection with the user is managed at a - * time. - */ -static struct { - /* Connection endpoint reference */ - void* endpoint; - /* Connection endpoint handlers */ - void* (*open) (int, const char*, const char*); - int (*getfd)(const void*); - ssize_t (*recv) (void*, char*, size_t); - ssize_t (*send) (const void*, const char*, size_t); - void (*close)(void*); -} _user_api_id; - -#define USER_API_OPEN(a, b, c) _user_api_id.open(a, b, c) -#define USER_API_GETFD() _user_api_id.getfd(_user_api_id.endpoint) -#define USER_API_RECV(a, b) _user_api_id.recv(_user_api_id.endpoint, a, b) -#define USER_API_SEND(a, b) _user_api_id.send(_user_api_id.endpoint, a, b) -#define USER_API_CLOSE() _user_api_id.close(_user_api_id.endpoint) +static int _user_api_registration_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size); +static int _user_api_location_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size); +static int _user_api_network_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size); +static int _user_api_pdn_connection_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size); -/* - * The buffer used to receive data from the user application layer - */ -#define USER_API_RECV_BUFFER_SIZE 4096 -static char _user_api_recv_buffer[USER_API_RECV_BUFFER_SIZE]; - -/* - * The buffer used to send data to the user application layer - */ -#define USER_API_SEND_BUFFER_SIZE USER_API_RECV_BUFFER_SIZE -static char _user_api_send_buffer[USER_API_SEND_BUFFER_SIZE]; - -/* - * The decoded data received from the user application layer - */ -static struct { - int n_cmd; /* number of user data to be processed */ -#define USER_DATA_MAX 10 - at_command_t cmd[USER_DATA_MAX]; /* user data to be processed */ -} _user_data = {}; +static int _user_api_send(user_api_id_t *user_api_id, at_response_t* data); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -147,44 +96,44 @@ static struct { ** Others: _user_api_id ** ** ** ***************************************************************************/ -int user_api_initialize(const char* host, const char* port, +int user_api_initialize(user_api_id_t *user_api_id, const char* host, const char* port, const char* devname, const char* devparams) { LOG_FUNC_IN; - gethostname(_user_api_send_buffer, USER_API_SEND_BUFFER_SIZE); + gethostname(user_api_id->send_buffer, USER_API_SEND_BUFFER_SIZE); if (devname != NULL) { /* Initialize device handlers */ - _user_api_id.open = device_open; - _user_api_id.getfd = device_get_fd; - _user_api_id.recv = device_read; - _user_api_id.send = device_write; - _user_api_id.close = device_close; + user_api_id->open = device_open; + user_api_id->getfd = device_get_fd; + user_api_id->recv = device_read; + user_api_id->send = device_write; + user_api_id->close = device_close; /* Initialize communication channel */ - _user_api_id.endpoint = USER_API_OPEN(DEVICE, devname, devparams); + user_api_id->endpoint = user_api_id->open(DEVICE, devname, devparams); - if (_user_api_id.endpoint == NULL) { + if (user_api_id->endpoint == NULL) { LOG_TRACE(ERROR, "USR-API - Failed to open connection endpoint, " "%s", strerror(errno)); LOG_FUNC_RETURN (RETURNerror); } LOG_TRACE(INFO, "USR-API - User's communication device %d is OPENED " - "on %s/%s", user_api_get_fd(), _user_api_send_buffer, devname); + "on %s/%s", user_api_get_fd(user_api_id), user_api_id->send_buffer, devname); } else { /* Initialize network socket handlers */ - _user_api_id.open = socket_udp_open; - _user_api_id.getfd = socket_get_fd; - _user_api_id.recv = socket_recv; - _user_api_id.send = socket_send; - _user_api_id.close = socket_close; + user_api_id->open = socket_udp_open; + user_api_id->getfd = socket_get_fd; + user_api_id->recv = socket_recv; + user_api_id->send = socket_send; + user_api_id->close = socket_close; /* Initialize communication channel */ - _user_api_id.endpoint = USER_API_OPEN(SOCKET_SERVER, host, port); + user_api_id->endpoint = user_api_id->open(SOCKET_SERVER, host, port); - if (_user_api_id.endpoint == NULL) { + if (user_api_id->endpoint == NULL) { const char* error = ( (errno < 0) ? gai_strerror(errno) : strerror(errno) ); LOG_TRACE(ERROR, "USR-API - Failed to open connection endpoint, " @@ -193,7 +142,7 @@ int user_api_initialize(const char* host, const char* port, } LOG_TRACE(INFO, "USR-API - User's UDP socket %d is BOUND to %s/%s", - user_api_get_fd(), _user_api_send_buffer, port); + user_api_get_fd(user_api_id), user_api_id->send_buffer, port); } /* Register the asynchronous notification handlers */ @@ -238,10 +187,10 @@ int user_api_initialize(const char* host, const char* port, ** Others: None ** ** ** ***************************************************************************/ -int user_api_get_fd(void) +int user_api_get_fd(user_api_id_t *user_api_id) { LOG_FUNC_IN; - LOG_FUNC_RETURN (USER_API_GETFD()); + LOG_FUNC_RETURN (user_api_id->getfd(user_api_id->endpoint)); } /**************************************************************************** @@ -253,19 +202,18 @@ int user_api_get_fd(void) ** before its usage. ** ** ** ** Inputs: index: Index of the user data structure to get ** - ** Others: _user_data ** ** ** ** Outputs: Return: A generic pointer to the user data ** ** structure ** ** Others: None ** ** ** ***************************************************************************/ -const void* user_api_get_data(int index) +const void* user_api_get_data(user_at_commands_t *commands, int index) { LOG_FUNC_IN; - if (index < _user_data.n_cmd) { - LOG_FUNC_RETURN ((void*)(&_user_data.cmd[index])); + if (index < commands->n_cmd) { + LOG_FUNC_RETURN ((void*)(&commands->cmd[index])); } LOG_FUNC_RETURN (NULL); @@ -277,33 +225,23 @@ const void* user_api_get_data(int index) ** ** ** Description: Read data received from the user application layer ** ** ** - ** Inputs: fd: File descriptor of the connection endpoint ** - ** from which data have been received ** ** Others: _user_api_id ** ** ** ** Outputs: Return: The number of bytes read when success; ** ** RETURNerror Otherwise ** - ** Others: _user_api_recv_buffer, _user_api_id ** + ** Others: user_api_id->recv_buffer, _user_api_id ** ** ** ***************************************************************************/ -int user_api_read_data(int fd) +int user_api_read_data(user_api_id_t *user_api_id) { LOG_FUNC_IN; int rbytes; - /* Sanity check */ - int sfd = user_api_get_fd(); - - if (fd != sfd) { - LOG_TRACE(ERROR, "USR-API - Endpoint %d is not the one created for communication with the user application layer (%d)", fd, sfd); - LOG_FUNC_RETURN (RETURNerror); - } - - memset(_user_api_recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); + memset(user_api_id->recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); /* Receive data from the user application layer */ - rbytes = USER_API_RECV(_user_api_recv_buffer, USER_API_RECV_BUFFER_SIZE); + rbytes = user_api_id->recv(user_api_id->endpoint, user_api_id->recv_buffer, USER_API_RECV_BUFFER_SIZE); if (rbytes == RETURNerror) { LOG_TRACE(ERROR, "USR-API - recv() failed, %s", strerror(errno)); @@ -313,7 +251,7 @@ int user_api_read_data(int fd) } else { LOG_TRACE(INFO, "USR-API - %d bytes received " "from the user application layer", rbytes); - LOG_DUMP(_user_api_recv_buffer, rbytes); + LOG_DUMP(user_api_id->recv_buffer, rbytes); } LOG_FUNC_RETURN (rbytes); @@ -329,45 +267,42 @@ int user_api_read_data(int fd) ** ** ** Outputs: Return: The number of bytes write when success; ** ** RETURNerror Otherwise ** - ** Others: _user_api_recv_buffer ** + ** Others: user_api_id->recv_buffer ** ** ** ***************************************************************************/ -int user_api_set_data(char *message) +int user_api_set_data(user_api_id_t *user_api_id, char *message) { LOG_FUNC_IN; int rbytes; - memset(_user_api_recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); + memset(user_api_id->recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); - strncpy(_user_api_recv_buffer, message, USER_API_RECV_BUFFER_SIZE); - rbytes = strlen(_user_api_recv_buffer); + strncpy(user_api_id->recv_buffer, message, USER_API_RECV_BUFFER_SIZE); + rbytes = strlen(user_api_id->recv_buffer); LOG_TRACE(INFO, "USR-API - %d bytes write", rbytes); - LOG_DUMP(_user_api_recv_buffer, rbytes); + LOG_DUMP(user_api_id->recv_buffer, rbytes); LOG_FUNC_RETURN (rbytes); } /**************************************************************************** ** ** - ** Name: user_api_send_data() ** +** Name: user_api_send_data() ** ** ** ** Description: Send data to the user application layer ** ** ** - ** Inputs: fd: File descriptor of the connection endpoint ** - ** to which data have to be sent ** ** length: Number of bytes to send ** - ** Others: _user_api_send_buffer, _user_api_id ** ** ** ** Outputs: Return: The number of bytes sent when success; ** ** RETURNerror Otherwise ** ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_send_data(int length) +static int _user_api_send_data(user_api_id_t *user_api_id, int length) { - int sbytes = USER_API_SEND(_user_api_send_buffer, length); + int sbytes = user_api_id->send(user_api_id->endpoint, user_api_id->send_buffer, length); if (sbytes == RETURNerror) { LOG_TRACE(ERROR, "USR-API - send() failed, %s", strerror(errno)); @@ -377,28 +312,25 @@ static int _user_api_send_data(int length) } else { LOG_TRACE(INFO, "USR-API - %d bytes sent " "to the user application layer", sbytes); - LOG_DUMP(_user_api_send_buffer, sbytes); + LOG_DUMP(user_api_id->send_buffer, sbytes); } return sbytes; } -int user_api_send_data(int fd, int length) + +/**************************************************************************** + ** ** + ** Name: user_api_close() ** + ***************************************************************************/ + int user_api_send_data(user_api_id_t *user_api_id, int length) { LOG_FUNC_IN; - /* Sanity check */ - int sfd = user_api_get_fd(); - - if (fd != sfd) { - LOG_TRACE(ERROR, "USR-API - Endpoint %d is not the one created for communication with the user application layer (%d)", fd, sfd); - LOG_FUNC_RETURN (RETURNerror); - } - /* Send data to the user application layer */ int sbytes = 0; if (length > 0) { - sbytes = _user_api_send_data(length); + sbytes = _user_api_send_data(user_api_id, length); } LOG_FUNC_RETURN (sbytes); @@ -411,31 +343,18 @@ int user_api_send_data(int fd, int length) ** Description: Close the user API from which the NAS layer sent/received ** ** messages to/from the user application layer ** ** ** - ** Inputs: fd: File descriptor of the connection endpoint ** - ** allocated by the system to communicate ** - ** with the user application layer ** ** Others: None ** ** ** ** Outputs: Return: None ** - ** Others: _user_api_id ** ** ** ***************************************************************************/ -void user_api_close(int fd) +void user_api_close(user_api_id_t *user_api_id) { LOG_FUNC_IN; - /* Sanity check */ - int sfd = user_api_get_fd(); - - if (fd != sfd) { - LOG_TRACE(ERROR, "USR-API - Endpoint %d is not the one created for communication with the user application layer (%d)", fd, sfd); - LOG_FUNC_OUT; - return; - } - /* Cleanup the connection endpoint */ - USER_API_CLOSE(); - _user_api_id.endpoint = NULL; + user_api_id->close(user_api_id->endpoint) ; + user_api_id->endpoint = NULL; LOG_FUNC_OUT; } @@ -450,46 +369,45 @@ void user_api_close(int fd) ** layer when the AT command failed to be decoded. ** ** ** ** Inputs: length: Number of bytes to decode ** - ** Others: _user_api_recv_buffer ** ** ** ** Outputs: Return: The number of AT commands succeessfully ** ** decoded ** - ** Others: _user_api_send_buffer, _user_data ** ** ** ***************************************************************************/ -int user_api_decode_data(int length) +int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *commands, int length) { LOG_FUNC_IN; /* Parse the AT command line */ - LOG_TRACE(INFO, "USR-API - Decode user data: %s", _user_api_recv_buffer); - _user_data.n_cmd = at_command_decode(_user_api_recv_buffer, length, - _user_data.cmd); + LOG_TRACE(INFO, "USR-API - Decode user data: %s", user_api_id->recv_buffer); + commands->n_cmd = at_command_decode(user_api_id->recv_buffer, length, + commands->cmd); - if (_user_data.n_cmd > 0) { + if (commands->n_cmd > 0) { /* AT command data received from the user application layer * has been successfully decoded */ LOG_TRACE(INFO, "USR-API - %d AT command%s ha%s been successfully " - "decoded", _user_data.n_cmd, - (_user_data.n_cmd > 1) ? "s" : "", - (_user_data.n_cmd > 1) ? "ve" : "s"); + "decoded", commands->n_cmd, + (commands->n_cmd > 1) ? "s" : "", + (commands->n_cmd > 1) ? "ve" : "s"); } else { int bytes; /* Failed to decode AT command data received from the user * application layer; Return syntax error code message */ LOG_TRACE(ERROR, "USR-API - Syntax error: Failed to decode " - "AT command data %s", _user_api_recv_buffer); + "AT command data %s", user_api_id->recv_buffer); /* Encode the syntax error code message */ - bytes = at_error_encode(_user_api_send_buffer, AT_ERROR_SYNTAX, + bytes = at_error_encode(user_api_id->send_buffer, AT_ERROR_SYNTAX, AT_ERROR_OPERATION_NOT_SUPPORTED); + // FIXME move _user_data call /* Send the syntax error code message */ - (void) _user_api_send_data(bytes); + _user_api_send_data(user_api_id, bytes); } - LOG_FUNC_RETURN (_user_data.n_cmd); + LOG_FUNC_RETURN (commands->n_cmd); } /**************************************************************************** @@ -508,10 +426,9 @@ int user_api_decode_data(int length) ** Outputs: Return: The number of characters that have been ** ** successfully encoded; ** ** RETURNerror otherwise. ** - ** Others: _user_api_send_buffer ** ** ** ***************************************************************************/ -int user_api_encode_data(const void* data, int success_code) +int user_api_encode_data(user_api_id_t *user_api_id, const void* data, int success_code) { LOG_FUNC_IN; @@ -520,16 +437,16 @@ int user_api_encode_data(const void* data, int success_code) /* Encode AT command error message */ if (user_data->cause_code != AT_ERROR_SUCCESS) { - bytes = at_error_encode(_user_api_send_buffer, AT_ERROR_CME, + bytes = at_error_encode(user_api_id->send_buffer, AT_ERROR_CME, user_data->cause_code); } /* Encode AT command response message */ else { - bytes = at_response_encode(_user_api_send_buffer, user_data); + bytes = at_response_encode(user_api_id->send_buffer, user_data); /* Add success result code */ if ( (success_code) && (bytes != RETURNerror) ) { - bytes += at_error_encode(&_user_api_send_buffer[bytes], + bytes += at_error_encode(&user_api_id->send_buffer[bytes], AT_ERROR_OK, 0); } } @@ -567,7 +484,7 @@ int user_api_encode_data(const void* data, int success_code) ** Others: None ** ** ** ***************************************************************************/ -int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, +int user_api_emm_callback(user_api_id_t *user_api_id, Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, const char* data, size_t size) { LOG_FUNC_IN; @@ -579,14 +496,14 @@ int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, * The list of available operators present in the network has to be * displayed to the user application */ - rc = user_ind_notify(USER_IND_PLMN, (void*)data, size); + rc = user_ind_notify(user_api_id, USER_IND_PLMN, (void*)data, size); } else { user_indication_t ind; ind.notification.reg.status = stat; if (size > 0) { /* The UE's network registration status has changed */ - rc = user_ind_notify(USER_IND_REG, (void*)&ind, 0); + rc = user_ind_notify(user_api_id, USER_IND_REG, (void*)&ind, 0); } if (rc != RETURNerror) { @@ -596,7 +513,7 @@ int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, ind.notification.loc.tac = tac; ind.notification.loc.ci = ci; ind.notification.loc.AcT = AcT; - rc = user_ind_notify(USER_IND_LOC, (void*)&ind, 0); + rc = user_ind_notify(user_api_id, USER_IND_LOC, (void*)&ind, 0); } } @@ -624,7 +541,7 @@ int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, ** Others: None ** ** ** ***************************************************************************/ -int user_api_esm_callback(int cid, network_pdn_state_t state) +int user_api_esm_callback(user_api_id_t *user_api_id, int cid, network_pdn_state_t state) { LOG_FUNC_IN; @@ -634,7 +551,7 @@ int user_api_esm_callback(int cid, network_pdn_state_t state) ind.notification.pdn.cid = cid; ind.notification.pdn.status = state; /* The status of the specified PDN connection has changed */ - rc = user_ind_notify(USER_IND_PDN, (void*)&ind, 0); + rc = user_ind_notify(user_api_id, USER_IND_PDN, (void*)&ind, 0); LOG_FUNC_RETURN (rc); } @@ -650,23 +567,22 @@ int user_api_esm_callback(int cid, network_pdn_state_t state) ** Description: Encodes and sends data to the user application layer ** ** ** ** Inputs: data: The data to send ** - ** Others: _user_api_send_buffer, _user_api_id ** ** ** ** Outputs: Return: The number of bytes sent when success; ** ** RETURNerror Otherwise ** ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_send(at_response_t* data) +static int _user_api_send(user_api_id_t *user_api_id, at_response_t* data) { LOG_FUNC_IN; /* Encode AT command response message */ - int bytes = at_response_encode(_user_api_send_buffer, data); + int bytes = at_response_encode(user_api_id->send_buffer, data); /* Send the AT command response message to the user application */ if (bytes != RETURNerror) { - bytes = _user_api_send_data(bytes); + bytes = _user_api_send_data(user_api_id, bytes); } LOG_FUNC_RETURN (bytes); @@ -693,7 +609,7 @@ static int _user_api_send(at_response_t* data) ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_registration_handler(unsigned char id, const void* data, +static int _user_api_registration_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size) { LOG_FUNC_IN; @@ -710,7 +626,7 @@ static int _user_api_registration_handler(unsigned char id, const void* data, at_response.response.cereg.stat = reg->status; /* Encode and send the AT command response message to the user */ - int bytes = _user_api_send(&at_response); + int bytes = _user_api_send(user_api_id, &at_response); LOG_FUNC_RETURN (bytes); } @@ -735,7 +651,7 @@ static int _user_api_registration_handler(unsigned char id, const void* data, ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_location_handler(unsigned char id, const void* data, +static int _user_api_location_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size) { LOG_FUNC_IN; @@ -759,7 +675,7 @@ static int _user_api_location_handler(unsigned char id, const void* data, } /* Encode and send the AT command response message to the user */ - int bytes = _user_api_send(&at_response); + int bytes = _user_api_send(user_api_id, &at_response); LOG_FUNC_RETURN (bytes); } @@ -782,7 +698,7 @@ static int _user_api_location_handler(unsigned char id, const void* data, ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_network_handler(unsigned char id, const void* data, +static int _user_api_network_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size) { LOG_FUNC_IN; @@ -795,7 +711,7 @@ static int _user_api_network_handler(unsigned char id, const void* data, at_response.response.cops.tst.size = size; /* Encode and send the AT command response message to the user */ - int bytes = _user_api_send(&at_response); + int bytes = _user_api_send(user_api_id, &at_response); LOG_FUNC_RETURN (bytes); } @@ -820,7 +736,7 @@ static int _user_api_network_handler(unsigned char id, const void* data, ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_pdn_connection_handler(unsigned char id, const void* data, +static int _user_api_pdn_connection_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size) { LOG_FUNC_IN; @@ -837,7 +753,7 @@ static int _user_api_pdn_connection_handler(unsigned char id, const void* data, at_response.response.cgev.code = pdn->status; /* Encode and send the AT command response message to the user */ - int bytes = _user_api_send(&at_response); + int bytes = _user_api_send(user_api_id, &at_response); LOG_FUNC_RETURN (bytes); } diff --git a/openair3/NAS/UE/API/USER/user_api.h b/openair3/NAS/UE/API/USER/user_api.h index 9597c0f1d1bbcedb1908abf4bde53cf9247fb2cd..6536144165b540bd9bf186d888aaf14c41eeb00b 100644 --- a/openair3/NAS/UE/API/USER/user_api.h +++ b/openair3/NAS/UE/API/USER/user_api.h @@ -42,15 +42,14 @@ Description Implements the API used by the NAS layer running in the UE #include "commonDef.h" #include "networkDef.h" +#include "at_command.h" +#include "user_api_defs.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -59,20 +58,20 @@ Description Implements the API used by the NAS layer running in the UE /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int user_api_initialize(const char* host, const char* port, const char* devname, const char* devparams); +int user_api_initialize(user_api_id_t *user_api_id, const char* host, const char* port, const char* devname, const char* devparams); -int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, const char* data, size_t size); -int user_api_esm_callback(int cid, network_pdn_state_t state); +int user_api_emm_callback(user_api_id_t *user_api_id, Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, const char* data, size_t size); +int user_api_esm_callback(user_api_id_t *user_api_id, int cid, network_pdn_state_t state); -int user_api_get_fd(void); -const void* user_api_get_data(int index); +int user_api_get_fd(user_api_id_t *user_api_id); +const void* user_api_get_data(user_at_commands_t *commands, int index); -int user_api_read_data(int fd); -int user_api_set_data(char *message); -int user_api_send_data(int fd, int length); -void user_api_close(int fd); +int user_api_read_data(user_api_id_t *user_api_id); +int user_api_set_data(user_api_id_t *user_api_id, char *message); +int user_api_send_data(user_api_id_t *user_api_id, int length); +void user_api_close(user_api_id_t *user_api_id); -int user_api_decode_data(int length); -int user_api_encode_data(const void* data, int add_success_code); +int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *commands, int length); +int user_api_encode_data(user_api_id_t *user_api_id, const void* data, int add_success_code); #endif /* __USER_API_H__ */ diff --git a/openair3/NAS/UE/API/USER/user_api_defs.h b/openair3/NAS/UE/API/USER/user_api_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..ef4d8cd383b93d49fad48011d87ac1531886578d --- /dev/null +++ b/openair3/NAS/UE/API/USER/user_api_defs.h @@ -0,0 +1,50 @@ +#ifndef _USER_API_DEFS_H +#define _USER_API_DEFS_H + +#include <sys/types.h> +#include "at_command.h" + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +#define USER_API_RECV_BUFFER_SIZE 4096 +#define USER_API_SEND_BUFFER_SIZE USER_API_RECV_BUFFER_SIZE +#define USER_DATA_MAX 10 + +/* + * The decoded data received from the user application layer + */ +typedef struct { + int n_cmd; /* number of user data to be processed */ + at_command_t cmd[USER_DATA_MAX]; /* user data to be processed */ +} user_at_commands_t; + +/* ------------------- + * Connection endpoint + * ------------------- + * The connection endpoint is used to send/receive data to/from the + * user application layer. Its definition depends on the underlaying + * mechanism chosen to communicate (network socket, I/O terminal device). + * A connection endpoint is handled using an identifier, and functions + * used to retreive the file descriptor actually allocated by the system, + * to receive data, to send data, and to perform clean up when connection + * is shut down. + * Only one single end to end connection with the user is managed at a + * time. + */ +typedef struct { + /* Connection endpoint reference */ + void* endpoint; + /* Connection endpoint handlers */ + void* (*open) (int, const char*, const char*); + int (*getfd)(const void*); + ssize_t (*recv) (void*, char*, size_t); + ssize_t (*send) (const void*, const char*, size_t); + void (*close)(void*); + char recv_buffer[USER_API_RECV_BUFFER_SIZE]; + char send_buffer[USER_API_SEND_BUFFER_SIZE]; +} user_api_id_t; + + +#endif diff --git a/openair3/NAS/UE/API/USER/user_indication.c b/openair3/NAS/UE/API/USER/user_indication.c index d7495f46e767ffbe61ad9cd9133163fc2f76d496..620596005df5d3fdd1513a85d947486d242d7ac8 100644 --- a/openair3/NAS/UE/API/USER/user_indication.c +++ b/openair3/NAS/UE/API/USER/user_indication.c @@ -146,7 +146,7 @@ int user_ind_deregister(user_ind_t ind) ** Others: None ** ** ** ***************************************************************************/ -int user_ind_notify(user_ind_t ind, const void* data, size_t size) +int user_ind_notify(user_api_id_t *user_api_id, user_ind_t ind, const void* data, size_t size) { LOG_FUNC_IN; @@ -158,7 +158,7 @@ int user_ind_notify(user_ind_t ind, const void* data, size_t size) user_ind_callback_t notify = _user_ind_handler.callback[ind]; if (notify != NULL) { - rc = (*notify)(_user_ind_handler.id, data, size); + rc = (*notify)(user_api_id, _user_ind_handler.id, data, size); } } else { /* Silently discard not registered notification */ diff --git a/openair3/NAS/UE/API/USER/user_indication.h b/openair3/NAS/UE/API/USER/user_indication.h index d31a8754e49dc7ca85834d0d3f566124fb1741fb..39aba424e7a755f88ce91b3980d405dd5f819cba 100644 --- a/openair3/NAS/UE/API/USER/user_indication.h +++ b/openair3/NAS/UE/API/USER/user_indication.h @@ -43,6 +43,7 @@ Description Defines functions which allow the user application to register #include "commonDef.h" #include "networkDef.h" +#include "user_api_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -101,7 +102,7 @@ typedef struct { /* * Type of procedure executed upon receiving registered notification */ -typedef int (*user_ind_callback_t) (unsigned char, const void*, size_t); +typedef int (*user_ind_callback_t) (user_api_id_t *user_api_id, unsigned char, const void*, size_t); /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ @@ -117,6 +118,6 @@ typedef int (*user_ind_callback_t) (unsigned char, const void*, size_t); int user_ind_register(user_ind_t ind, unsigned char id, user_ind_callback_t cb); int user_ind_deregister(user_ind_t ind); -int user_ind_notify(user_ind_t ind, const void* data, size_t size); +int user_ind_notify(user_api_id_t *user_api_id, user_ind_t ind, const void* data, size_t size); #endif /* __USER_IND_H__*/ diff --git a/openair3/NAS/UE/API/USIM/Makefile b/openair3/NAS/UE/API/USIM/Makefile deleted file mode 100644 index d5f4d6fffba2deb77a25a7739e06ac10e10b858e..0000000000000000000000000000000000000000 --- a/openair3/NAS/UE/API/USIM/Makefile +++ /dev/null @@ -1,42 +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 -# */ - -ifndef PROJDIR -PROJDIR = $(PWD)/../../.. -INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(IESDIR) -I$(EMMMSGDIR) -I$(ESMMSGDIR) -endif - -include $(PROJDIR)/Makerules -include $(PROJDIR)/Makefile.inc - -all: $(OBJS) - -%.o: %.c Makefile - @echo Compiling $< - @$(CC) $(CFLAGS) -c $< -o $@ - -clean: - $(RM) $(OBJS) *.bak *~ - -depend: - makedepend -- ${CFLAGS} -- ${SRCS} - -# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/openair3/NAS/UE/API/USIM/aka_functions.c b/openair3/NAS/UE/API/USIM/aka_functions.c index 415ba695f21b4812bcd4828e296ee201499e8aaa..4d8f4cd1d31b33370056cea6e4b9556319e5a369 100644 --- a/openair3/NAS/UE/API/USIM/aka_functions.c +++ b/openair3/NAS/UE/API/USIM/aka_functions.c @@ -39,26 +39,6 @@ #include "aka_functions.h" #include "nas_log.h" -/*--------- Operator Variant Algorithm Configuration Field --------*/ -/*------- Insert your value of OP here -------*/ -/* PFT OP used currently in HSS (OPENAIRHSS/auc/kdf.c) */ -#define OAI_LTEBOX - -#ifdef OAI_LTEBOX -//1006020f0a478bf6b699f15c062e42b3 -/*u8 OP[16] = {0xb3, 0x42, 0x2e, 0x06, 0x5c, 0xf1, 0x99, 0xb6, - 0xf6, 0x8b, 0x47, 0x0a, 0x0f, 0x02, 0x06, 0x10 - };*/ -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 -/*------- Insert your value of OP here -------*/ - /*------------------------------------------------------------------- * Algorithm f1 *------------------------------------------------------------------- @@ -69,16 +49,14 @@ u8 OP[16] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, * *-----------------------------------------------------------------*/ void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], - u8 mac_a_pP[8] ) + u8 mac_a_pP[8], const u8 op_c[16]) { - u8 op_c[16]; u8 temp[16]; u8 in1[16]; u8 out1[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k_pP ); - ComputeOPc( op_c ); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -124,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], - u8 res_pP[8], u8 ck_pP[16], u8 ik_pP[16], u8 ak_pP[6] ) + 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 out[16]; u8 rijndaelInput[16]; @@ -142,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]); RijndaelKeySchedule( k_pP ); - ComputeOPc( op_c ); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -225,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], - u8 mac_s_pP[8] ) + u8 mac_s_pP[8],const u8 op_c[16]) { - u8 op_c[16]; u8 temp[16]; u8 in1[16]; u8 out1[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k_pP ); - ComputeOPc( op_c ); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -280,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], - u8 ak_pP[6] ) + u8 ak_pP[6], const u8 op_c[16]) { - u8 op_c[16]; u8 temp[16]; u8 out[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k_pP ); - ComputeOPc( op_c ); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -316,22 +288,17 @@ void f5star( u8 k_pP[16], u8 rand_pP[16], * Function to compute OPc from OP and K. Assumes key schedule has already been performed. *-----------------------------------------------------------------*/ -void ComputeOPc( u8 op_c_pP[16] ) +void ComputeOPc(const u8 op[16], u8 op_c_pP[16]) { u8 i; LOG_TRACE(DEBUG, - "USIM-API - ComputeOPc : OP[0..15]=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", - OP[0],OP[1],OP[2], OP[3], OP[4], OP[5], OP[6], OP[7], - OP[8],OP[9],OP[10],OP[11],OP[12],OP[13],OP[14],OP[15]); - RijndaelEncrypt( OP, op_c_pP ); + "USIM-API - ComputeOPc : op[0..15]=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", + op[0],op[1],op[2], op[3], op[4], op[5], op[6], op[7], + op[8],op[9],op[10],op[11],op[12],op[13],op[14],op[15]); + RijndaelEncrypt( op, op_c_pP ); for (i=0; i<16; i++) - op_c_pP[i] ^= OP[i]; - LOG_TRACE(DEBUG, - "USIM-API - OPc[0..15]=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", - op_c_pP[0],op_c_pP[1],op_c_pP[2], op_c_pP[3], op_c_pP[4], op_c_pP[5], op_c_pP[6], op_c_pP[7], - op_c_pP[8],op_c_pP[9],op_c_pP[10],op_c_pP[11],op_c_pP[12],op_c_pP[13],op_c_pP[14],op_c_pP[15]); - + op_c_pP[i] ^= op[i]; return; } /* end of function ComputeOPc */ @@ -489,7 +456,7 @@ void MixColumn(u8 state[4][4]) * 16-byte output (using round keys already derived from 16-byte * key). *-----------------------------------------------------------------*/ -void RijndaelEncrypt( u8 input[16], u8 output[16] ) +void RijndaelEncrypt(const u8 input[16], u8 output[16] ) { u8 state[4][4]; int i, r; diff --git a/openair3/NAS/UE/API/USIM/aka_functions.h b/openair3/NAS/UE/API/USIM/aka_functions.h index 66b5a90fbca6c356f057a733b4b5a2d72db7b43e..8c370bb76c8df239839cf6ab7f810495418301a7 100644 --- a/openair3/NAS/UE/API/USIM/aka_functions.h +++ b/openair3/NAS/UE/API/USIM/aka_functions.h @@ -23,13 +23,13 @@ typedef unsigned char u8; /*--------------------------- prototypes --------------------------*/ void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], - u8 mac_a[8] ); + u8 mac_a[8], const u8 op[16]); void f2345 ( u8 k[16], u8 rand[16], - u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6] ); + u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], const u8 op[16]); void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], - u8 mac_s[8] ); + u8 mac_s[8], const u8 op[16]); void f5star( u8 k[16], u8 rand[16], - u8 ak[6] ); -void ComputeOPc( u8 op_c[16] ); + u8 ak[6], const u8 op[16]); +void ComputeOPc(const u8 op[16], u8 op_c_pP[16] ); void RijndaelKeySchedule( u8 key[16] ); -void RijndaelEncrypt( u8 input[16], u8 output[16] ); +void RijndaelEncrypt(const u8 input[16], u8 output[16] ); diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index 58ca9aa279e95e66375647e3760bf490f833dded..efb0383596dfc885bf20137c2673c25aa48909ea 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -41,11 +41,13 @@ Description Implements the API used by the NAS layer to read/write #include "usim_api.h" #include "nas_log.h" +#include "utils.h" #include "memory.h" #include <stdio.h> #include "aka_functions.h" #include <string.h> // memcpy, memset #include <stdlib.h> // malloc, free +#include <stdio.h> /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -55,46 +57,6 @@ Description Implements the API used by the NAS layer to read/write /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -/* - * The name of the file where are stored data of the USIM application - */ -#define USIM_API_NVRAM_FILENAME ".usim.nvram" - -/* - * The name of the environment variable which defines the directory - * where the USIM application file is located - */ -#define USIM_API_NVRAM_DIRNAME "USIM_DIR" - -/* - * Subscriber authentication security key - */ -#define USIM_API_K_SIZE 16 -//#define USIM_API_K_VALUE "fec86ba6eb707ed08905757b1bb44b8f" -#define USIM_API_K_VALUE "8BAF473F2F8FD09487CCCBD7097C6862" -#define TEST_USIM_API_K_VALUE "000102030405060708090a0b0c0d0e0f" // CMW500 K key - -static uint8_t _usim_api_k[USIM_API_K_SIZE]; - - -/* - * List of last used Sequence Numbers SQN - */ -#define USIM_API_AK_SIZE 6 -#define USIM_API_SQN_SIZE USIM_API_AK_SIZE -#define USIM_API_SQNMS_SIZE USIM_API_SQN_SIZE - -static struct _usim_api_data_s { - /* Highest sequence number the USIM has ever accepted */ - uint8_t sqn_ms[USIM_API_SQNMS_SIZE]; - /* List of the last used sequence numbers */ -#define USIM_API_SQN_LIST_SIZE 32 - uint8_t n_sqns; - uint32_t sqn[USIM_API_SQN_LIST_SIZE]; -} _usim_api_data; - -static uint8_t _usim_api_hex_char_to_hex_value (char c); -static void _usim_api_hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size); static int _usim_api_check_sqn(uint32_t seq, uint8_t ind); /****************************************************************************/ @@ -115,38 +77,17 @@ static int _usim_api_check_sqn(uint32_t seq, uint8_t ind); ** Others: None ** ** ** ***************************************************************************/ -int usim_api_read(usim_data_t* data) +int usim_api_read(const char *filename, usim_data_t* data) { LOG_FUNC_IN; - /* Get USIM application pathname */ - char* path = memory_get_path(USIM_API_NVRAM_DIRNAME, - USIM_API_NVRAM_FILENAME); - - if (path == NULL) { - LOG_TRACE(ERROR, "USIM-API - Failed to get USIM pathname"); - LOG_FUNC_RETURN (RETURNerror); - } - /* Read USIM application data */ - if (memory_read(path, data, sizeof(usim_data_t)) != RETURNok) { + if (memory_read(filename, data, sizeof(usim_data_t)) != RETURNok) { LOG_TRACE(ERROR, "USIM-API - %s file is either not valid " - "or not present", path); - free(path); + "or not present", filename); LOG_FUNC_RETURN (RETURNerror); } - /* initialize the subscriber authentication security key */ - if(data->usimtestmode == 0) - { - _usim_api_hex_string_to_hex_value(_usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE); - } - else - { - _usim_api_hex_string_to_hex_value(_usim_api_k, TEST_USIM_API_K_VALUE, USIM_API_K_SIZE); - } - - free(path); LOG_FUNC_RETURN (RETURNok); } @@ -164,28 +105,17 @@ int usim_api_read(usim_data_t* data) ** Others: None ** ** ** ***************************************************************************/ -int usim_api_write(const usim_data_t* data) +int usim_api_write(const char *filename, const usim_data_t* data) { LOG_FUNC_IN; - /* Get USIM application pathname */ - char* path = memory_get_path(USIM_API_NVRAM_DIRNAME, - USIM_API_NVRAM_FILENAME); - - if (path == NULL) { - LOG_TRACE(ERROR, "USIM-API - Failed to get USIM pathname"); - LOG_FUNC_RETURN (RETURNerror); - } - /* Write USIM application data */ - if (memory_write(path, data, sizeof(usim_data_t)) != RETURNok) { + if (memory_write(filename, data, sizeof(usim_data_t)) != RETURNok) { - LOG_TRACE(ERROR, "USIM-API - Unable to write USIM file %s", path); - free(path); + LOG_TRACE(ERROR, "USIM-API - Unable to write USIM file %s", filename); LOG_FUNC_RETURN (RETURNerror); } - free(path); LOG_FUNC_RETURN (RETURNok); } @@ -220,7 +150,8 @@ int usim_api_write(const usim_data_t* data) ** Others: None ** ** ** ***************************************************************************/ -int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* autn_pP, +int usim_api_authenticate_test(usim_data_t *usim_data, + const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts_pP, OctetString* res_pP, OctetString* ck_pP, OctetString* ik_pP) { @@ -236,7 +167,7 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au // RES = XDOUT for (i=0; i<USIM_API_K_SIZE; i++) { - res_pP->value[i] = rand_pP->value[i] ^ _usim_api_k[i]; + res_pP->value[i] = rand_pP->value[i] ^ usim_data->keys.usim_api_k[i]; } //step2: res = f2(xdout,n) @@ -327,19 +258,19 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au /* Concealed value of the counter SQNms in the USIM: * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */ - f5star(_usim_api_k, rand_pP->value, ak); + f5star(usim_data->keys.usim_api_k, rand_pP->value, ak, usim_data->keys.opc); u8 sqn_ms[USIM_API_SQNMS_SIZE]; memset(sqn_ms, 0, USIM_API_SQNMS_SIZE); //#define USIM_API_SQN_MS_SIZE 3 - printf("_usim_api_data.sqn_ms %p\n",_usim_api_data.sqn_ms); + printf("usim_data->usim_sqn_data.sqn_ms %p\n", usim_data->usim_sqn_data.sqn_ms); for (i = 0; i < USIM_API_SQNMS_SIZE; i++) { //#warning "LG:BUG HERE TODO" - printf("i %d: ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]); + printf("i %d: ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]); sqn_ms[USIM_API_SQNMS_SIZE - i] = - ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]; + ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]; } u8 sqnms[USIM_API_SQNMS_SIZE]; @@ -355,8 +286,8 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au * MACS = f1*K(SQNMS || RAND || AMF) */ #define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE u8 macs[USIM_API_MACS_SIZE]; - f1star(_usim_api_k, rand_pP->value, sqn_ms, - &rand_pP->value[USIM_API_SQN_SIZE], macs); + f1star(usim_data->keys.usim_api_k, rand_pP->value, sqn_ms, + &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", macs[0],macs[1],macs[2],macs[3], macs[4],macs[5],macs[6],macs[7]); @@ -392,7 +323,6 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au ** autn_pP: Authentication token ** ** AUTN = (SQN xor AK) || AMF || MAC ** ** 48 16 64 bits ** - ** Others: Security key ** ** ** ** Outputs: auts_pP: Re-synchronization token ** ** res_pP: Authentication response ** @@ -403,7 +333,7 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au ** Others: None ** ** ** ***************************************************************************/ -int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP, +int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts_pP, OctetString* res_pP, OctetString* ck_pP, OctetString* ik_pP) { @@ -421,8 +351,8 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP /* Compute the anonymity key AK = f5K (RAND) */ u8 ak[USIM_API_AK_SIZE]; - f2345(_usim_api_k, rand_pP->value, - res_pP->value, ck_pP->value, ik_pP->value, ak); + f2345(usim_data->keys.usim_api_k, rand_pP->value, + 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 - ck(f3) :%s",dump_octet_string(ck_pP)); LOG_TRACE(INFO, "USIM-API - ik(f4) :%s",dump_octet_string(ik_pP)); @@ -443,7 +373,7 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP /* Compute XMAC = f1K (SQN || RAND || AMF) */ #define USIM_API_XMAC_SIZE 8 u8 xmac[USIM_API_XMAC_SIZE]; - f1(_usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac); + 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, "USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X", xmac[0],xmac[1],xmac[2],xmac[3], @@ -471,19 +401,19 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP /* Concealed value of the counter SQNms in the USIM: * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */ - f5star(_usim_api_k, rand_pP->value, ak); + f5star(usim_data->keys.usim_api_k, rand_pP->value, ak, usim_data->keys.opc); u8 sqn_ms[USIM_API_SQNMS_SIZE]; memset(sqn_ms, 0, USIM_API_SQNMS_SIZE); //#define USIM_API_SQN_MS_SIZE 3 - printf("_usim_api_data.sqn_ms %p\n",_usim_api_data.sqn_ms); + printf("usim_data->usim_sqn.sqn_ms %p\n",usim_data->usim_sqn_data.sqn_ms); for (i = 0; i < USIM_API_SQNMS_SIZE; i++) { //#warning "LG:BUG HERE TODO" - printf("i %d: ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]); + printf("i %d: ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]); sqn_ms[USIM_API_SQNMS_SIZE - i] = - ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]; + ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]; } u8 sqnms[USIM_API_SQNMS_SIZE]; @@ -499,8 +429,8 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP * MACS = f1*K(SQNMS || RAND || AMF) */ #define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE u8 macs[USIM_API_MACS_SIZE]; - f1star(_usim_api_k, rand_pP->value, sqn_ms, - &rand_pP->value[USIM_API_SQN_SIZE], macs); + f1star(usim_data->keys.usim_api_k, rand_pP->value, sqn_ms, + &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", macs[0],macs[1],macs[2],macs[3], macs[4],macs[5],macs[6],macs[7]); @@ -520,57 +450,6 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP /********************* L O C A L F U N C T I O N S *********************/ /****************************************************************************/ -/**************************************************************************** - ** ** - ** Name: _usim_api_hex_char_to_hex_value() ** - ** ** - ** Description: Converts an hexadecimal ASCII coded digit into its value. ** - ** ** - ** Inputs: c: A char holding the ASCII coded value ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: Converted value ** - ** Others: None ** - ** ** - ***************************************************************************/ -static uint8_t _usim_api_hex_char_to_hex_value (char c) -{ - if (c >= 'A') { - /* Remove case bit */ - c &= ~('a' ^ 'A'); - - return (c - 'A' + 10); - } else { - return (c - '0'); - } -} - -/**************************************************************************** - ** ** - ** Name: _usim_api_hex_string_to_hex_value() ** - ** ** - ** Description: Converts an hexadecimal ASCII coded string into its value.** - ** ** - ** Inputs: hex_value: A pointer to the location to store the ** - ** conversion result ** - ** size: The size of hex_value in bytes ** - ** Others: None ** - ** ** - ** Outputs: hex_value: Converted value ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -static void _usim_api_hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size) -{ - int i; - - for (i=0; i < size; i++) { - hex_value[i] = (_usim_api_hex_char_to_hex_value(hex_string[2 * i]) << 4) | _usim_api_hex_char_to_hex_value(hex_string[2 * i + 1]); - } -} - /**************************************************************************** ** ** ** Name: _usim_api_check_sqn() ** diff --git a/openair3/NAS/UE/API/USIM/usim_api.h b/openair3/NAS/UE/API/USIM/usim_api.h index 8cfaeb8aed67d14a0ca3cecde85eeba9433ce3d1..f2f80d610c5d0601be4baa837125f2d2bff6a8d5 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.h +++ b/openair3/NAS/UE/API/USIM/usim_api.h @@ -48,6 +48,23 @@ Description Implements the API used by the NAS layer to read/write /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ +/* + * Subscriber authentication security key + */ +#define USIM_API_K_SIZE 16 +#define USIM_API_K_VALUE "fec86ba6eb707ed08905757b1bb44b8f" + +/* + * The name of the file where are stored data of the USIM application + */ +#define USIM_API_NVRAM_FILENAME ".usim.nvram" + +/* + * The name of the environment variable which defines the directory + * where the USIM application file is located + */ +#define USIM_API_NVRAM_DIRNAME "USIM_DIR" + /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ @@ -106,8 +123,27 @@ typedef struct { /* Integrity key */ #define USIM_IK_SIZE 16 Byte_t ik[USIM_IK_SIZE]; + uint8_t usim_api_k[USIM_API_K_SIZE]; + uint8_t opc[16]; } usim_keys_t; +/* + * List of last used Sequence Numbers SQN + */ +#define USIM_API_AK_SIZE 6 +#define USIM_API_SQN_SIZE USIM_API_AK_SIZE +#define USIM_API_SQNMS_SIZE USIM_API_SQN_SIZE + +typedef struct { + /* Highest sequence number the USIM has ever accepted */ + uint8_t sqn_ms[USIM_API_SQNMS_SIZE]; + /* List of the last used sequence numbers */ +#define USIM_API_SQN_LIST_SIZE 32 + uint8_t n_sqns; + uint32_t sqn[USIM_API_SQN_LIST_SIZE]; +} usim_sqn_data_t; + + /* * EPS NAS Security Context * ------------------------ @@ -329,6 +365,7 @@ typedef struct { usim_nasconfig_t nasconfig; /* usim test mode */ uint8_t usimtestmode; + usim_sqn_data_t usim_sqn_data; } usim_data_t; /****************************************************************************/ @@ -339,14 +376,15 @@ typedef struct { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int usim_api_read(usim_data_t* data); +int usim_api_read(const char *filename, usim_data_t* data); -int usim_api_write(const usim_data_t* data); +int usim_api_write(const char *filename, const usim_data_t* data); -int usim_api_authenticate(const OctetString* rand, const OctetString* autn, +int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts, OctetString* res, OctetString* ck, OctetString* ik); -int usim_api_authenticate_test(const OctetString* rand, const OctetString* autn, +int usim_api_authenticate_test(usim_data_t *usim_data, + const OctetString* rand, const OctetString* autn, OctetString* auts, OctetString* res, OctetString* ck, OctetString* ik); diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index 939c5b4afdd7796e58ab66b76372e446336674ff..c0c82b9b4ccf258567f414882fa368e513b1bcb9 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -59,6 +59,7 @@ Description Defines the attach related EMM procedure executed by the #include "nas_timer.h" #include "emmData.h" +#include "emm_timers.h" #include "emm_sap.h" #include "esm_sap.h" @@ -90,24 +91,12 @@ static const char *_emm_attach_type_str[] = { /* * Timer handlers */ -void *_emm_attach_t3410_handler(void *); -static void *_emm_attach_t3411_handler(void *); -static void *_emm_attach_t3402_handler(void *); +static void *_emm_attach_t3411_handler(void *args); /* * Abnormal case attach procedure */ -static void _emm_attach_abnormal_cases_bcd(emm_sap_t *); - -/* - * Internal data used for attach procedure - */ -static struct { -#define EMM_ATTACH_COUNTER_MAX 5 - unsigned int attempt_count; /* Counter used to limit the number of - * subsequently rejected attach attempts */ -} _emm_attach_data = {0}; - +static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -133,14 +122,14 @@ static struct { ** INITIATED. ** ** ** ** Inputs: type: Type of the requested attach ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3402, T3410, T3411 ** ** ** ***************************************************************************/ -int emm_proc_attach(emm_proc_attach_type_t type) +int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) { LOG_FUNC_IN; @@ -148,13 +137,14 @@ int emm_proc_attach(emm_proc_attach_type_t type) emm_as_establish_t *emm_as = &emm_sap.u.emm_as.u.establish; esm_sap_t esm_sap; int rc; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach type = %s (%d)", _emm_attach_type_str[type], type); /* Update the emergency bearer service indicator */ if (type == EMM_ATTACH_TYPE_EMERGENCY) { - _emm_data.is_emergency = TRUE; + user->emm_data->is_emergency = TRUE; } /* Setup initial NAS information message to transfer */ @@ -163,7 +153,7 @@ int emm_proc_attach(emm_proc_attach_type_t type) emm_as->type = type; /* Set the RRC connection establishment cause */ - if (_emm_data.is_emergency) { + if (user->emm_data->is_emergency) { emm_as->RRCcause = NET_ESTABLISH_CAUSE_EMERGENCY; emm_as->RRCtype = NET_ESTABLISH_TYPE_EMERGENCY_CALLS; } else { @@ -172,7 +162,7 @@ int emm_proc_attach(emm_proc_attach_type_t type) } /* Set the PLMN identifier of the selected PLMN */ - emm_as->plmnID = &_emm_data.splmn; + emm_as->plmnID = &user->emm_data->splmn; /* * Process the EPS mobile identity */ @@ -182,55 +172,55 @@ int emm_proc_attach(emm_proc_attach_type_t type) emm_as->UEid.imei = NULL; /* Check whether the UE is configured for "AttachWithIMSI" */ - if (_emm_data.AttachWithImsi) { + if (user->emm_data->AttachWithImsi) { /* Check whether the selected PLMN is neither the registered PLMN * nor in the list of equivalent PLMNs */ - if ( (!_emm_data.is_rplmn) && (!_emm_data.is_eplmn) ) { + if ( (!user->emm_data->is_rplmn) && (!user->emm_data->is_eplmn) ) { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with IMSI"); /* Include the IMSI */ - emm_as->UEid.imsi = _emm_data.imsi; + emm_as->UEid.imsi = user->emm_data->imsi; } else { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with NO IMSI, is registered PLMN %d, is equivalent PLMN %d", - _emm_data.is_rplmn, - _emm_data.is_eplmn); + user->emm_data->is_rplmn, + user->emm_data->is_eplmn); } - } else if (_emm_data.guti) { + } else if (user->emm_data->guti) { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with GUTI"); /* Include a valid GUTI and the last visited registered TAI */ - emm_as->UEid.guti = _emm_data.guti; - emm_as->UEid.tai = _emm_data.tai; - } else if (!_emm_data.is_emergency) { + emm_as->UEid.guti = user->emm_data->guti; + emm_as->UEid.tai = user->emm_data->tai; + } else if (!user->emm_data->is_emergency) { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with IMSI cause is no emergency and no GUTI"); /* Include the IMSI if no valid GUTI is available */ - emm_as->UEid.imsi = _emm_data.imsi; + emm_as->UEid.imsi = user->emm_data->imsi; } else { /* The UE is attaching for emergency bearer services and * does not hold a valid GUTI */ - if (_emm_data.imsi) { + if (user->emm_data->imsi) { /* Include the IMSI if valid (USIM is present) */ LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with IMSI cause is emergency and no GUTI"); - emm_as->UEid.imsi = _emm_data.imsi; + emm_as->UEid.imsi = user->emm_data->imsi; } else { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with IMSI cause is emergency and no GUTI and no IMSI"); /* Include the IMEI if the IMSI is not valid */ - emm_as->UEid.imei = _emm_data.imei; + emm_as->UEid.imei = user->emm_data->imei; } } /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, _emm_data.security, FALSE, FALSE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, FALSE); emm_as->ksi = EMM_AS_NO_KEY_AVAILABLE; - if (_emm_data.security) { - if (_emm_data.security->type != EMM_KSI_NOT_AVAILABLE) { - emm_as->ksi = _emm_data.security->eksi; + if (user->emm_data->security) { + if (user->emm_data->security->type != EMM_KSI_NOT_AVAILABLE) { + emm_as->ksi = user->emm_data->security->eksi; } - LOG_TRACE(INFO, "EMM-PROC - eps_encryption 0x%X", _emm_data.security->capability.eps_encryption); - LOG_TRACE(INFO, "EMM-PROC - eps_integrity 0x%X", _emm_data.security->capability.eps_integrity); - emm_as->encryption = _emm_data.security->capability.eps_encryption; - emm_as->integrity = _emm_data.security->capability.eps_integrity; + LOG_TRACE(INFO, "EMM-PROC - eps_encryption 0x%X", user->emm_data->security->capability.eps_encryption); + LOG_TRACE(INFO, "EMM-PROC - eps_integrity 0x%X", user->emm_data->security->capability.eps_integrity); + emm_as->encryption = user->emm_data->security->capability.eps_encryption; + emm_as->integrity = user->emm_data->security->capability.eps_integrity; } /* @@ -244,15 +234,15 @@ int emm_proc_attach(emm_proc_attach_type_t type) /* TODO: PDN type should be set according to the IP capability of the UE */ esm_sap.data.pdn_connect.pdn_type = NET_PDN_TYPE_IPV4; esm_sap.data.pdn_connect.apn = NULL; - esm_sap.data.pdn_connect.is_emergency = _emm_data.is_emergency; - rc = esm_sap_send(&esm_sap); + esm_sap.data.pdn_connect.is_emergency = user->emm_data->is_emergency; + rc = esm_sap_send(user, &esm_sap); if (rc != RETURNerror) { /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(emm_proc_attach_request, + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, emm_proc_attach_request, emm_proc_attach_failure, - emm_proc_attach_release, NULL); + emm_proc_attach_release, user); if (rc != RETURNok) { LOG_TRACE(WARNING, "Failed to initialize EMM procedure handler"); @@ -260,12 +250,12 @@ int emm_proc_attach(emm_proc_attach_type_t type) } /* Start T3410 timer */ - T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL); + emm_timers->T3410.id = nas_timer_start(emm_timers->T3410.sec, emm_attach_t3410_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in %ld seconds", - T3410.id, T3410.sec); + emm_timers->T3410.id, emm_timers->T3410.sec); /* Stop T3402 and T3411 timers if running */ - T3402.id = nas_timer_stop(T3402.id); - T3411.id = nas_timer_stop(T3411.id); + emm_timers->T3402.id = nas_timer_stop(emm_timers->T3402.id); + emm_timers->T3411.id = nas_timer_stop(emm_timers->T3411.id); /* * Notify EMM-AS SAP that a RRC connection establishment procedure @@ -276,7 +266,7 @@ int emm_proc_attach(emm_proc_attach_type_t type) /* Get the PDN connectivity request to transfer within the ESM * container of the initial attach request message */ emm_sap.u.emm_as.u.establish.NASmsg = esm_sap.send; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN(rc); @@ -301,7 +291,7 @@ int emm_proc_attach(emm_proc_attach_type_t type) int emm_proc_attach_request(void *args) { LOG_FUNC_IN; - + nas_user_t *user=args; emm_sap_t emm_sap; int rc; @@ -309,7 +299,7 @@ int emm_proc_attach_request(void *args) * Notify EMM that Attach Request has been sent to the network */ emm_sap.primitive = EMMREG_ATTACH_REQ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -342,10 +332,10 @@ int emm_proc_attach_request(void *args) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, T3412, T3402, T3423 ** + ** Others: user->emm_data-> T3412, T3402, T3423 ** ** ** ***************************************************************************/ -int emm_proc_attach_accept(long t3412, long t3402, long t3423, +int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, int n_tais, tai_t *tai, GUTI_t *guti, int n_eplmns, plmn_t *eplmn, const OctetString *esm_msg_pP) @@ -357,51 +347,52 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, int rc; int i; int j; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - EPS attach accepted by the network"); /* Stop timer T3410 */ - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); /* Delete old TAI list and store the received TAI list */ - _emm_data.ltai.n_tais = n_tais; + user->emm_data->ltai.n_tais = n_tais; for (i = 0; (i < n_tais) && (i < EMM_DATA_TAI_MAX); i++) { - _emm_data.ltai.tai[i] = tai[i]; + user->emm_data->ltai.tai[i] = tai[i]; } /* Update periodic tracking area update timer value */ - T3412.sec = t3412; + emm_timers->T3412.sec = t3412; /* Update attach failure timer value */ if ( !(t3402 < 0) ) { - T3402.sec = t3402; + emm_timers->T3402.sec = t3402; } /* Update E-UTRAN deactivate ISR timer value */ if ( !(t3423 < 0) ) { - T3423.sec = t3423; + emm_timers->T3423.sec = t3423; } /* Delete old GUTI and store the new assigned GUTI if provided */ if (guti) { - *_emm_data.guti = *guti; + *user->emm_data->guti = *guti; } /* Update the stored list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; + user->emm_data->nvdata.eplmn.n_plmns = 0; if (n_eplmns > 0) { for (i = 0; (i < n_eplmns) && (i < EMM_DATA_EPLMN_MAX); i++) { int is_forbidden = FALSE; - if (!_emm_data.is_emergency) { + if (!user->emm_data->is_emergency) { /* If the attach procedure is not for emergency bearer * services, the UE shall remove from the list any PLMN * code that is already in the list of forbidden PLMNs */ - for (j = 0; j < _emm_data.fplmn.n_plmns; j++) { - if (PLMNS_ARE_EQUAL(eplmn[i], _emm_data.fplmn.plmn[j])) { + for (j = 0; j < user->emm_data->fplmn.n_plmns; j++) { + if (PLMNS_ARE_EQUAL(eplmn[i], user->emm_data->fplmn.plmn[j])) { is_forbidden = TRUE; break; } @@ -409,15 +400,15 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, } if ( !is_forbidden ) { - _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] = + user->emm_data->nvdata.eplmn.plmn[user->emm_data->nvdata.eplmn.n_plmns++] = eplmn[i]; } } /* Add the PLMN code of the registered PLMN that sent the list */ - if (_emm_data.nvdata.eplmn.n_plmns < EMM_DATA_EPLMN_MAX) { - _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] = - _emm_data.splmn; + if (user->emm_data->nvdata.eplmn.n_plmns < EMM_DATA_EPLMN_MAX) { + user->emm_data->nvdata.eplmn.plmn[user->emm_data->nvdata.eplmn.n_plmns++] = + user->emm_data->splmn; } } @@ -427,14 +418,14 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ; esm_sap.is_standalone = FALSE; esm_sap.recv = esm_msg_pP; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); if ( (rc != RETURNerror) && (esm_sap.err == ESM_SAP_SUCCESS) ) { /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(emm_proc_attach_complete, + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, emm_proc_attach_complete, emm_proc_attach_failure, - NULL, NULL); + NULL, user); if (rc != RETURNok) { LOG_TRACE(WARNING, @@ -448,17 +439,17 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, * be sent to the network */ emm_sap.primitive = EMMAS_DATA_REQ; - emm_sap.u.emm_as.u.data.guti = _emm_data.guti; - emm_sap.u.emm_as.u.data.ueid = 0; + emm_sap.u.emm_as.u.data.guti = user->emm_data->guti; + emm_sap.u.emm_as.u.data.ueid = user->ueid; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, - _emm_data.security, FALSE, TRUE); + user->emm_data->security, FALSE, TRUE); /* Get the activate default EPS bearer context accept message * to be transfered within the ESM container of the attach * complete message */ emm_sap.u.emm_as.u.data.NASinfo = EMM_AS_NAS_DATA_ATTACH; emm_sap.u.emm_as.u.data.NASmsg = esm_sap.send; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } else if (esm_sap.err != ESM_SAP_DISCARDED) { /* 3GPP TS 24.301, section 5.5.1.2.6, case j * If the ACTIVATE DEFAULT BEARER CONTEXT REQUEST message combined @@ -467,7 +458,7 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, * procedure by sending a DETACH REQUEST message to the network. */ emm_sap.primitive = EMMREG_DETACH_INIT; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } else { /* * ESM procedure failed and, received message has been discarded or @@ -497,22 +488,23 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _emm_attach_data, T3410 ** ** ** ***************************************************************************/ -int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) +int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *esm_msg_pP) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; + emm_timers_t *emm_timers = user->emm_data->emm_timers; + emm_attach_data_t *emm_attach_data = user->emm_data->emm_attach_data; LOG_TRACE(WARNING, "EMM-PROC - EPS attach rejected by the network, " "EMM cause = %d", emm_cause); /* Stop timer T3410 */ - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); /* Update the EPS update status, the GUTI, the visited registered TAI and * the eKSI */ @@ -528,15 +520,15 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) case EMM_CAUSE_ROAMING_NOT_ALLOWED: case EMM_CAUSE_NO_SUITABLE_CELLS: /* Set the EPS update status to EU3 ROAMING NOT ALLOWED */ - _emm_data.status = EU3_ROAMING_NOT_ALLOWED; + user->emm_data->status = EU3_ROAMING_NOT_ALLOWED; /* Delete the GUTI */ - _emm_data.guti = NULL; + user->emm_data->guti = NULL; /* Delete the last visited registered TAI */ - _emm_data.tai = NULL; + user->emm_data->tai = NULL; /* Delete the eKSI */ - if (_emm_data.security) { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + if (user->emm_data->security) { + user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE; } break; @@ -552,34 +544,34 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) case EMM_CAUSE_EPS_NOT_ALLOWED: case EMM_CAUSE_BOTH_NOT_ALLOWED: /* Consider the USIM as invalid for EPS services */ - _emm_data.usim_is_valid = FALSE; + user->emm_data->usim_is_valid = FALSE; /* Delete the list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; + user->emm_data->nvdata.eplmn.n_plmns = 0; break; case EMM_CAUSE_PLMN_NOT_ALLOWED: case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: case EMM_CAUSE_ROAMING_NOT_ALLOWED: /* Delete the list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; + user->emm_data->nvdata.eplmn.n_plmns = 0; /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; + emm_attach_data->attempt_count = 0; break; case EMM_CAUSE_TA_NOT_ALLOWED: case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: case EMM_CAUSE_NO_SUITABLE_CELLS: /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; + emm_attach_data->attempt_count = 0; break; case EMM_CAUSE_ESM_FAILURE: /* 3GPP TS 24.301, section 5.5.1.2.6, case d */ - if (_emm_data.NAS_SignallingPriority != 1) { + if (user->emm_data->NAS_SignallingPriority != 1) { /* The UE is not configured for NAS signalling low priority; * set the attach attempt counter to 5 */ - _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX; + emm_attach_data->attempt_count = EMM_ATTACH_COUNTER_MAX; } break; @@ -591,7 +583,7 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) case EMM_CAUSE_PROTOCOL_ERROR: /* 3GPP TS 24.301, section 5.5.1.2.6, case d * Set the attach attempt counter to 5 */ - _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX; + emm_attach_data->attempt_count = EMM_ATTACH_COUNTER_MAX; break; default : @@ -603,25 +595,25 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) case EMM_CAUSE_PLMN_NOT_ALLOWED: case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: /* Store the PLMN identity in the "forbidden PLMN list" */ - _emm_data.fplmn.plmn[_emm_data.fplmn.n_plmns++] = _emm_data.splmn; + user->emm_data->fplmn.plmn[user->emm_data->fplmn.n_plmns++] = user->emm_data->splmn; break; case EMM_CAUSE_TA_NOT_ALLOWED: /* Store the current TAI in the list of "forbidden tracking * areas for regional provision of service" */ - _emm_data.ftai.tai[_emm_data.ftai.n_tais++] = *_emm_data.tai; + user->emm_data->ftai.tai[user->emm_data->ftai.n_tais++] = *user->emm_data->tai; break; case EMM_CAUSE_ROAMING_NOT_ALLOWED: /* Store the current TAI in the list of "forbidden tracking * areas for roaming" */ - _emm_data.ftai_roaming.tai[_emm_data.ftai_roaming.n_tais++] = *_emm_data.tai; + user->emm_data->ftai_roaming.tai[user->emm_data->ftai_roaming.n_tais++] = *user->emm_data->tai; break; case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: /* Store the PLMN identity in the "forbidden PLMNs for GPRS * service" list */ - _emm_data.fplmn_gprs.plmn[_emm_data.fplmn_gprs.n_plmns++] = _emm_data.splmn; + user->emm_data->fplmn_gprs.plmn[user->emm_data->fplmn_gprs.n_plmns++] = user->emm_data->splmn; break; default : @@ -662,7 +654,7 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) break; case EMM_CAUSE_IMEI_NOT_ACCEPTED: - if (_emm_data.is_emergency) { + if (user->emm_data->is_emergency) { /* * Notify EMM that the UE failed to register to the network * for emergency bearer services because "IMEI not accepted" @@ -676,11 +668,11 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) default : /* Other values are considered as abnormal cases * 3GPP TS 24.301, section 5.5.1.2.6, case d */ - _emm_attach_abnormal_cases_bcd(&emm_sap); + _emm_attach_abnormal_cases_bcd(user, &emm_sap); break; } - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); /* * Notify ESM that the network rejected connectivity to the PDN @@ -690,7 +682,7 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; esm_sap.is_standalone = FALSE; esm_sap.recv = esm_msg_pP; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } LOG_FUNC_RETURN(rc); @@ -714,13 +706,14 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _emm_attach_data ** ** ** ***************************************************************************/ int emm_proc_attach_complete(void *args) { LOG_FUNC_IN; + nas_user_t *user = args; + emm_attach_data_t *emm_attach_data = user->emm_data->emm_attach_data; emm_sap_t emm_sap; esm_sap_t esm_sap; int rc; @@ -728,22 +721,22 @@ int emm_proc_attach_complete(void *args) LOG_TRACE(INFO, "EMM-PROC - EPS attach complete"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; + emm_attach_data->attempt_count = 0; /* TODO: Reset the tracking area updating attempt counter */ /* Set the EPS update status to EU1 UPDATED */ - _emm_data.status = EU1_UPDATED; - _emm_data.is_attached = TRUE; + user->emm_data->status = EU1_UPDATED; + user->emm_data->is_attached = TRUE; /* * Notify EMM that network attach complete message has been delivered * to the network */ emm_sap.primitive = EMMREG_ATTACH_CNF; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* @@ -753,7 +746,7 @@ int emm_proc_attach_complete(void *args) */ esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_CNF; esm_sap.is_standalone = FALSE; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } LOG_FUNC_RETURN(rc); @@ -786,19 +779,20 @@ int emm_proc_attach_complete(void *args) int emm_proc_attach_failure(int is_initial, void *args) { LOG_FUNC_IN; - int rc = RETURNok; esm_sap_t esm_sap; + nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - EPS attach failure"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Stop timer T3410 if still running */ - if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); } if (is_initial) { @@ -821,13 +815,13 @@ int emm_proc_attach_failure(int is_initial, void *args) esm_sap.recv = NULL; } - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); if (rc != RETURNerror) { /* Start T3411 timer */ - T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL); + emm_timers->T3411.id = nas_timer_start(emm_timers->T3411.sec, _emm_attach_t3411_handler, NULL); LOG_TRACE(INFO, "EMM-PROC - Timer T3411 (%d) expires in %ld seconds", - T3411.id, T3411.sec); + emm_timers->T3411.id, emm_timers->T3411.sec); } LOG_FUNC_RETURN(rc); @@ -855,16 +849,16 @@ int emm_proc_attach_failure(int is_initial, void *args) int emm_proc_attach_release(void *args) { LOG_FUNC_IN; - + nas_user_t *user=args; emm_sap_t emm_sap; int rc; LOG_TRACE(WARNING, "EMM-PROC - NAS signalling connection released"); /* Execute abnormal case attach procedure */ - _emm_attach_abnormal_cases_bcd(&emm_sap); + _emm_attach_abnormal_cases_bcd(user, &emm_sap); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -883,7 +877,7 @@ int emm_proc_attach_release(void *args) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_attach_restart(void) +int emm_proc_attach_restart(nas_user_t *user) { LOG_FUNC_IN; @@ -896,8 +890,8 @@ int emm_proc_attach_restart(void) * Notify EMM that the attach procedure has to be restarted */ emm_sap.primitive = EMMREG_ATTACH_INIT; - emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; - rc = emm_sap_send(&emm_sap); + emm_sap.u.emm_reg.u.attach.is_emergency = user->emm_data->is_emergency; + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -913,17 +907,17 @@ int emm_proc_attach_restart(void) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_attach_set_emergency(void) +int emm_proc_attach_set_emergency(emm_data_t *emm_data) { LOG_FUNC_IN; LOG_TRACE(WARNING, "EMM-PROC - UE is now attached to the network for " "emergency bearer services only"); - _emm_data.is_emergency = TRUE; + emm_data->is_emergency = TRUE; LOG_FUNC_RETURN(RETURNok); } @@ -940,26 +934,27 @@ int emm_proc_attach_set_emergency(void) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_attach_set_detach(void) +int emm_proc_attach_set_detach(void *nas_user) { LOG_FUNC_IN; + nas_user_t *user=nas_user; int rc; LOG_TRACE(WARNING, "EMM-PROC - UE is now locally detached from the network"); /* Reset the network attachment indicator */ - _emm_data.is_attached = FALSE; + user->emm_data->is_attached = FALSE; /* * Notify that the UE is locally detached from the network */ emm_sap_t emm_sap; emm_sap.primitive = EMMREG_DETACH_CNF; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -995,25 +990,27 @@ int emm_proc_attach_set_detach(void) ** Others: T3410 ** ** ** ***************************************************************************/ -void *_emm_attach_t3410_handler(void *args) +void *emm_attach_t3410_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; int rc; LOG_TRACE(WARNING, "EMM-PROC - T3410 timer expired"); /* Stop T3410 timer */ - T3410.id = nas_timer_stop(T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); /* Execute abnormal case attach procedure */ - _emm_attach_abnormal_cases_bcd(&emm_sap); + _emm_attach_abnormal_cases_bcd(user, &emm_sap); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Locally release the NAS signalling connection */ - _emm_data.ecm_status = ECM_IDLE; + user->emm_data->ecm_status = ECM_IDLE; } LOG_FUNC_RETURN(NULL); @@ -1041,20 +1038,22 @@ static void *_emm_attach_t3411_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; LOG_TRACE(WARNING, "EMM-PROC - T3411 timer expired"); /* Stop T3411 timer */ - T3411.id = nas_timer_stop(T3411.id); + emm_timers->T3411.id = nas_timer_stop(emm_timers->T3411.id); /* * Notify EMM that timer T3411 expired and attach procedure has to be * restarted */ emm_sap.primitive = EMMREG_ATTACH_INIT; - emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; + emm_sap.u.emm_reg.u.attach.is_emergency = user->emm_data->is_emergency; - (void) emm_sap_send(&emm_sap); + (void) emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(NULL); } @@ -1078,29 +1077,31 @@ static void *_emm_attach_t3411_handler(void *args) ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_attach_data, T3402 ** ** ** ***************************************************************************/ static void *_emm_attach_t3402_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user = args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; + emm_attach_data_t *emm_attach_data = user->emm_data->emm_attach_data; emm_sap_t emm_sap; LOG_TRACE(WARNING, "EMM-PROC - T3402 timer expired"); /* Stop T3402 timer */ - T3402.id = nas_timer_stop(T3402.id); + emm_timers->T3402.id = nas_timer_stop(emm_timers->T3402.id); /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; + emm_attach_data->attempt_count = 0; /* * Notify EMM that timer T3402 expired and attach procedure has to be * restarted */ emm_sap.primitive = EMMREG_ATTACH_INIT; - emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; + emm_sap.u.emm_reg.u.attach.is_emergency = user->emm_data->is_emergency; - (void) emm_sap_send(&emm_sap); + (void) emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(NULL); } @@ -1128,30 +1129,30 @@ static void *_emm_attach_t3402_handler(void *args) ** ** ** Outputs: emm_sap: EMM service access point ** ** Return: None ** - ** Others: _emm_data, _emm_attach_data, T3402, T3410, ** ** T3411 ** ** ** ***************************************************************************/ -static void _emm_attach_abnormal_cases_bcd(emm_sap_t *emm_sap) +static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *emm_sap) { LOG_FUNC_IN; - + emm_timers_t *emm_timers = user->emm_data->emm_timers; + emm_attach_data_t *emm_attach_data = user->emm_data->emm_attach_data; LOG_TRACE(WARNING, "EMM-PROC - Abnormal case, attach counter = %d", - _emm_attach_data.attempt_count); + emm_attach_data->attempt_count); /* Stop timer T3410 */ - if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); } - if (_emm_attach_data.attempt_count < EMM_ATTACH_COUNTER_MAX) { + if (emm_attach_data->attempt_count < EMM_ATTACH_COUNTER_MAX) { /* Increment the attach attempt counter */ - _emm_attach_data.attempt_count += 1; + emm_attach_data->attempt_count += 1; /* Start T3411 timer */ - T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL); + emm_timers->T3411.id = nas_timer_start(emm_timers->T3411.sec, _emm_attach_t3411_handler, NULL); LOG_TRACE(INFO, "EMM-PROC - Timer T3411 (%d) expires in %ld seconds", - T3411.id, T3411.sec); + emm_timers->T3411.id, emm_timers->T3411.sec); /* * Notify EMM that the attempt to attach for EPS services failed and * the attach attempt counter didn't reach its maximum value; network @@ -1160,26 +1161,26 @@ static void _emm_attach_abnormal_cases_bcd(emm_sap_t *emm_sap) emm_sap->primitive = EMMREG_ATTACH_FAILED; } else { /* Delete the GUTI */ - _emm_data.guti = NULL; + user->emm_data->guti = NULL; /* Delete the TAI list */ - _emm_data.ltai.n_tais = 0; + user->emm_data->ltai.n_tais = 0; /* Delete the last visited registered TAI */ - _emm_data.tai = NULL; + user->emm_data->tai = NULL; /* Delete the list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; + user->emm_data->nvdata.eplmn.n_plmns = 0; /* Delete the eKSI */ - if (_emm_data.security) { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + if (user->emm_data->security) { + user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE; } /* Set the EPS update status to EU2 NOT UPDATED */ - _emm_data.status = EU2_NOT_UPDATED; + user->emm_data->status = EU2_NOT_UPDATED; /* Start T3402 timer */ - T3402.id = nas_timer_start(T3402.sec, _emm_attach_t3402_handler, NULL); + emm_timers->T3402.id = nas_timer_start(emm_timers->T3402.sec, _emm_attach_t3402_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3402 (%d) expires in %ld seconds", - T3402.id, T3402.sec); + emm_timers->T3402.id, emm_timers->T3402.sec); /* * Notify EMM that the attempt to attach for EPS services failed and * the attach attempt counter reached its maximum value. diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index 9022acbdac8d1a3cc4e6f9602dacb2572b79a323..e49bdd2db7e5e36aa52835dd58b8f477bd3317a9 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -59,26 +59,21 @@ Description Defines the authentication EMM procedure executed by the #include "nas_timer.h" #include "emmData.h" +#include "emm_timers.h" #include "emm_sap.h" #include "emm_cause.h" +#include "emm_timers.h" #include "usim_api.h" #include "secu_defs.h" +#include "Authentication.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -/* - * Retransmission timer handlers - */ -extern void *_emm_attach_t3410_handler(void *); -extern void *_emm_service_t3417_handler(void *); -extern void *_emm_detach_t3421_handler(void *); -extern void *_emm_tau_t3430_handler(void *); - extern uint8_t usim_test; /****************************************************************************/ @@ -97,34 +92,15 @@ static void *_authentication_t3416_handler(void *); static void *_authentication_t3418_handler(void *); static void *_authentication_t3420_handler(void *); -/* - * Internal data used for authentication procedure - */ -static struct { - uint8_t rand[AUTH_RAND_SIZE]; /* Random challenge number */ - uint8_t res[AUTH_RES_SIZE]; /* Authentication response */ - uint8_t ck[AUTH_CK_SIZE]; /* Ciphering key */ - uint8_t ik[AUTH_IK_SIZE]; /* Integrity key */ -#define AUTHENTICATION_T3410 0x01 -#define AUTHENTICATION_T3417 0x02 -#define AUTHENTICATION_T3421 0x04 -#define AUTHENTICATION_T3430 0x08 - unsigned char timers; /* Timer restart bitmap */ -#define AUTHENTICATION_COUNTER_MAX 3 - unsigned char mac_count:2; /* MAC failure counter (#20) */ - unsigned char umts_count:2; /* UMTS challenge failure counter (#26) */ - unsigned char sync_count:2; /* Sync failure counter (#21) */ -} _authentication_data; - /* * Abnormal case authentication procedure */ -static int _authentication_abnormal_cases_cde(int emm_cause, +static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, const OctetString *auts); -static int _authentication_abnormal_case_f(void); +static int _authentication_abnormal_case_f(nas_user_t *user); -static int _authentication_stop_timers(void); -static int _authentication_start_timers(void); +static int _authentication_stop_timers(nas_user_t *user); +static int _authentication_start_timers(nas_user_t *user); static int _authentication_kasme(const OctetString *autn, const OctetString *ck, const OctetString *ik, const plmn_t *plmn, OctetString *kasme); @@ -163,21 +139,21 @@ static int _authentication_kasme(const OctetString *autn, ** ksi: The NAS ket sey identifier ** ** rand: Authentication parameter RAND ** ** autn: Authentication parameter AUTN ** - ** Others: _emm_data, _authentication_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _authentication_data, T3416, ** ** T3418, T3420 ** ** ** ***************************************************************************/ -int emm_proc_authentication_request(int native_ksi, int ksi, +int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, const OctetString *rand, const OctetString *autn) { LOG_FUNC_IN; int rc = RETURNerror; + authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - Authentication requested ksi type = %s, ksi = %d", native_ksi ? "native" : "mapped", ksi); @@ -185,29 +161,29 @@ int emm_proc_authentication_request(int native_ksi, int ksi, * The UE shall proceed with an EPS authentication challenge only if a * USIM is present */ - if (!_emm_data.usim_is_valid) { + if (!user->emm_data->usim_is_valid) { LOG_TRACE(WARNING, "EMM-PROC - USIM is not present or not valid"); LOG_FUNC_RETURN (RETURNerror); } /* Stop timer T3418, if running */ - if (T3418.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3418 (%d)", T3418.id); - T3418.id = nas_timer_stop(T3418.id); + if (emm_timers->T3418.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3418 (%d)", emm_timers->T3418.id); + emm_timers->T3418.id = nas_timer_stop(emm_timers->T3418.id); } /* Stop timer T3420, if running */ - if (T3420.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3420 (%d)", T3420.id); - T3420.id = nas_timer_stop(T3420.id); + if (emm_timers->T3420.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3420 (%d)", emm_timers->T3420.id); + emm_timers->T3420.id = nas_timer_stop(emm_timers->T3420.id); } /* Setup security keys */ - OctetString ck = {AUTH_CK_SIZE, _authentication_data.ck}; - OctetString ik = {AUTH_IK_SIZE, _authentication_data.ik}; - OctetString res = {AUTH_RES_SIZE, _authentication_data.res}; + OctetString ck = {AUTH_CK_SIZE, authentication_data->ck}; + OctetString ik = {AUTH_IK_SIZE, authentication_data->ik}; + OctetString res = {AUTH_RES_SIZE, authentication_data->res}; - if (memcmp(_authentication_data.rand, rand->value, AUTH_CK_SIZE) != 0) { + if (memcmp(authentication_data->rand, rand->value, AUTH_CK_SIZE) != 0) { /* * There is no valid stored RAND in the ME or the stored RAND is * different from the new received value in the AUTHENTICATION @@ -237,11 +213,11 @@ int emm_proc_authentication_request(int native_ksi, int ksi, */ if(usim_test == 0) { - rc = usim_api_authenticate(rand, autn, &auts, &res, &ck, &ik); + rc = usim_api_authenticate(&user->usim_data, rand, autn, &auts, &res, &ck, &ik); } else { - rc = usim_api_authenticate_test(rand, autn, &auts, &res, &ck, &ik); // XOR algo for autentication on usim test mode + rc = usim_api_authenticate_test(&user->usim_data, rand, autn, &auts, &res, &ck, &ik); } } @@ -254,24 +230,24 @@ int emm_proc_authentication_request(int native_ksi, int ksi, (sbit == 0) ? "Non-EPS authentication unacceptable" : "MAC code failure"); /* Delete any previously stored RAND and RES and stop timer T3416 */ - (void) emm_proc_authentication_delete(); + emm_proc_authentication_delete(user); /* Proceed authentication abnormal cases procedure */ if (auts.length > 0) { /* 3GPP TS 24.301, section 5.4.2.6, case e * SQN failure */ rc = _authentication_abnormal_cases_cde( - EMM_CAUSE_SYNCH_FAILURE, &auts); + user, EMM_CAUSE_SYNCH_FAILURE, &auts); } else if (sbit == 0) { /* 3GPP TS 24.301, section 5.4.2.6, case d * Non-EPS authentication unacceptable */ rc = _authentication_abnormal_cases_cde( - EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE, NULL); + user, EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE, NULL); } else { /* 3GPP TS 24.301, section 5.4.2.6, case c * MAC code failure */ rc = _authentication_abnormal_cases_cde( - EMM_CAUSE_MAC_FAILURE, NULL); + user, EMM_CAUSE_MAC_FAILURE, NULL); } /* Free the AUTS parameter */ @@ -284,18 +260,18 @@ int emm_proc_authentication_request(int native_ksi, int ksi, /* Store the new RAND in the volatile memory */ if (rand->length <= AUTH_RAND_SIZE) { - memcpy(_authentication_data.rand, rand->value, rand->length); + memcpy(authentication_data->rand, rand->value, rand->length); } /* Start, or reset and restart timer T3416 */ - if (T3416.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", T3416.id); - T3416.id = nas_timer_stop(T3416.id); + if (emm_timers->T3416.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", emm_timers->T3416.id); + emm_timers->T3416.id = nas_timer_stop(emm_timers->T3416.id); } - T3416.id = nas_timer_start(T3416.sec, _authentication_t3416_handler, NULL); + emm_timers->T3416.id = nas_timer_start(emm_timers->T3416.sec, _authentication_t3416_handler, NULL); LOG_TRACE(INFO, "EMM-PROC - Timer T3416 (%d) expires in %ld seconds", - T3416.id, T3416.sec); + emm_timers->T3416.id, emm_timers->T3416.sec); } /* @@ -304,7 +280,7 @@ int emm_proc_authentication_request(int native_ksi, int ksi, * the authenticity of the core network */ /* Start any retransmission timers */ - rc = _authentication_start_timers(); + rc = _authentication_start_timers(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - Failed to start retransmission timers"); @@ -313,7 +289,7 @@ int emm_proc_authentication_request(int native_ksi, int ksi, /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); if (rc != RETURNok) { LOG_TRACE(WARNING, @@ -327,46 +303,46 @@ int emm_proc_authentication_request(int native_ksi, int ksi, */ emm_sap_t emm_sap; emm_sap.primitive = EMMAS_SECURITY_RES; - emm_sap.u.emm_as.u.security.guti = _emm_data.guti; - emm_sap.u.emm_as.u.security.ueid = 0; + emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; + emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; emm_sap.u.emm_as.u.security.emm_cause = EMM_CAUSE_SUCCESS; emm_sap.u.emm_as.u.security.res = &res; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + user->emm_data->security, FALSE, TRUE); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Reset the authentication failure counters */ - _authentication_data.mac_count = 0; - _authentication_data.umts_count = 0; - _authentication_data.sync_count = 0; + authentication_data->mac_count = 0; + authentication_data->umts_count = 0; + authentication_data->sync_count = 0; /* Create non-current EPS security context */ - if (_emm_data.non_current == NULL) { - _emm_data.non_current = + if (user->emm_data->non_current == NULL) { + user->emm_data->non_current = (emm_security_context_t *)malloc(sizeof(emm_security_context_t)); } - if (_emm_data.non_current) { - memset(_emm_data.non_current, 0, sizeof(emm_security_context_t)); + if (user->emm_data->non_current) { + memset(user->emm_data->non_current, 0, sizeof(emm_security_context_t)); /* Set the security context type */ if (native_ksi) { - _emm_data.non_current->type = EMM_KSI_NATIVE; + user->emm_data->non_current->type = EMM_KSI_NATIVE; } else { - _emm_data.non_current->type = EMM_KSI_MAPPED; + user->emm_data->non_current->type = EMM_KSI_MAPPED; } /* Set the EPS key set identifier */ - _emm_data.non_current->eksi = ksi; + user->emm_data->non_current->eksi = ksi; /* Derive the Kasme from the authentication challenge using * the PLMN identity of the selected PLMN */ - _emm_data.non_current->kasme.length = AUTH_KASME_SIZE; - _emm_data.non_current->kasme.value = malloc(32); - _authentication_kasme(autn, &ck, &ik, &_emm_data.splmn, - &_emm_data.non_current->kasme); + user->emm_data->non_current->kasme.length = AUTH_KASME_SIZE; + user->emm_data->non_current->kasme.value = malloc(32); + _authentication_kasme(autn, &ck, &ik, &user->emm_data->splmn, + &user->emm_data->non_current->kasme); /* NAS integrity and cyphering keys are not yet available */ } } @@ -392,66 +368,67 @@ int emm_proc_authentication_request(int native_ksi, int ksi, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _authentication_data, T3410, ** ** T3417, T3430 ** ** ** ***************************************************************************/ -int emm_proc_authentication_reject(void) +int emm_proc_authentication_reject(nas_user_t *user) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; + authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - Authentication not accepted by the network"); /* Delete any previously stored RAND and RES and stop timer T3416 */ - (void) emm_proc_authentication_delete(); + (void) emm_proc_authentication_delete(user); /* Set the EPS update status to EU3 ROAMING NOT ALLOWED */ - _emm_data.status = EU3_ROAMING_NOT_ALLOWED; + user->emm_data->status = EU3_ROAMING_NOT_ALLOWED; /* Delete the stored GUTI */ - _emm_data.guti = NULL; + user->emm_data->guti = NULL; /* Delete the TAI list */ - _emm_data.ltai.n_tais = 0; + user->emm_data->ltai.n_tais = 0; /* Delete the last visited registered TAI */ - _emm_data.tai = NULL; + user->emm_data->tai = NULL; /* Delete the eKSI */ - if (_emm_data.security) { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + if (user->emm_data->security) { + user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE; } /* Consider the USIM invalid */ - _emm_data.usim_is_valid = FALSE; + user->emm_data->usim_is_valid = FALSE; /* Stop timer T3410 */ - if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); } /* Stop timer T3417 */ - if (T3417.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", T3417.id); - T3417.id = nas_timer_stop(T3417.id); + if (emm_timers->T3417.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", emm_timers->T3417.id); + emm_timers->T3417.id = nas_timer_stop(emm_timers->T3417.id); } /* Stop timer T3430 */ - if (T3430.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", T3430.id); - T3430.id = nas_timer_stop(T3430.id); + if (emm_timers->T3430.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", emm_timers->T3430.id); + emm_timers->T3430.id = nas_timer_stop(emm_timers->T3430.id); } /* Abort any EMM signalling procedure (prevent the retransmission timers to * be restarted) */ - _authentication_data.timers = 0x00; + authentication_data->timers = 0x00; /* * Notify EMM that authentication is not accepted by the network */ emm_sap.primitive = EMMREG_AUTH_REJ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -475,24 +452,25 @@ int emm_proc_authentication_reject(void) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _authentication_data, T3416 ** ** ** ***************************************************************************/ -int emm_proc_authentication_delete(void) +int emm_proc_authentication_delete(nas_user_t *user) { LOG_FUNC_IN; + authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - Delete authentication data RAND and RES"); /* Stop timer T3416, if running */ - if (T3416.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", T3416.id); - T3416.id = nas_timer_stop(T3416.id); + if (emm_timers->T3416.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", emm_timers->T3416.id); + emm_timers->T3416.id = nas_timer_stop(emm_timers->T3416.id); } /* Delete any previously stored RAND and RES */ - memset(_authentication_data.rand, 0, AUTH_RAND_SIZE); - memset(_authentication_data.res, 0, AUTH_RES_SIZE); + memset(authentication_data->rand, 0, AUTH_RAND_SIZE); + memset(authentication_data->res, 0, AUTH_RES_SIZE); LOG_FUNC_RETURN (RETURNok); } @@ -529,13 +507,15 @@ int emm_proc_authentication_delete(void) static void *_authentication_t3416_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - T3416 timer expired"); /* Stop timer T3416 */ - T3416.id = nas_timer_stop(T3416.id); + emm_timers->T3416.id = nas_timer_stop(emm_timers->T3416.id); /* Delete previouly stored RAND and RES authentication data */ - (void) emm_proc_authentication_delete(); + (void) emm_proc_authentication_delete(user); LOG_FUNC_RETURN (NULL); } @@ -556,7 +536,6 @@ static void *_authentication_t3416_handler(void *args) ** ** ** Outputs: None ** ** Return: None ** - ** Others: _authentication_data, T3418 ** ** ** ***************************************************************************/ static void *_authentication_t3418_handler(void *args) @@ -564,16 +543,19 @@ static void *_authentication_t3418_handler(void *args) LOG_FUNC_IN; int rc; + nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; + authentication_data_t *authentication_data = user->authentication_data; LOG_TRACE(WARNING, "EMM-PROC - T3418 timer expired"); /* Stop timer T3418 */ - T3418.id = nas_timer_stop(T3418.id); + emm_timers->T3418.id = nas_timer_stop(emm_timers->T3418.id); /* Reset the MAC failure and UMTS challenge failure counters */ - _authentication_data.mac_count = 0; - _authentication_data.umts_count = 0; + authentication_data->mac_count = 0; + authentication_data->umts_count = 0; /* 3GPP TS 24.301, section 5.4.2.7, case f */ - rc = _authentication_abnormal_case_f(); + rc = _authentication_abnormal_case_f(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - Failed to proceed abnormal case f"); @@ -597,7 +579,6 @@ static void *_authentication_t3418_handler(void *args) ** ** ** Outputs: None ** ** Return: None ** - ** Others: _authentication_data, T3420 ** ** ** ***************************************************************************/ static void *_authentication_t3420_handler(void *args) @@ -605,15 +586,18 @@ static void *_authentication_t3420_handler(void *args) LOG_FUNC_IN; int rc; + nas_user_t *user=args; + authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - T3420 timer expired"); /* Stop timer T3420 */ - T3420.id = nas_timer_stop(T3420.id); + emm_timers->T3420.id = nas_timer_stop(emm_timers->T3420.id); /* Reset the sync failure counter */ - _authentication_data.sync_count = 0; + authentication_data->sync_count = 0; /* 3GPP TS 24.301, section 5.4.2.7, case f */ - rc = _authentication_abnormal_case_f(); + rc = _authentication_abnormal_case_f(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - Failed to proceed abnormal case f"); @@ -641,20 +625,21 @@ static void *_authentication_t3420_handler(void *args) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _authentication_data, T3418, T3420 ** ** ** ***************************************************************************/ -static int _authentication_abnormal_cases_cde(int emm_cause, +static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, const OctetString *auts) { LOG_FUNC_IN; int rc; + authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - " "Abnormal case, authentication counters c/d/e = %d/%d/%d", - _authentication_data.mac_count, _authentication_data.umts_count, - _authentication_data.sync_count); + authentication_data->mac_count, authentication_data->umts_count, + authentication_data->sync_count); /* * Notify EMM-AS SAP that Authentication Failure message has to be sent @@ -662,15 +647,15 @@ static int _authentication_abnormal_cases_cde(int emm_cause, */ emm_sap_t emm_sap; emm_sap.primitive = EMMAS_SECURITY_RES; - emm_sap.u.emm_as.u.security.guti = _emm_data.guti; - emm_sap.u.emm_as.u.security.ueid = 0; + emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; + emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; emm_sap.u.emm_as.u.security.emm_cause = emm_cause; emm_sap.u.emm_as.u.security.auts = auts; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + user->emm_data->security, FALSE, TRUE); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* @@ -680,34 +665,34 @@ static int _authentication_abnormal_cases_cde(int emm_cause, case EMM_CAUSE_MAC_FAILURE: /* 3GPP TS 24.301, section 5.4.2.6, case c * Update the MAC failure counter */ - _authentication_data.mac_count += 1; + authentication_data->mac_count += 1; /* Start timer T3418 */ - T3418.id = nas_timer_start(T3418.sec, - _authentication_t3418_handler, NULL); + emm_timers->T3418.id = nas_timer_start(emm_timers->T3418.sec, + _authentication_t3418_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " - "%ld seconds", T3418.id, T3418.sec); + "%ld seconds", emm_timers->T3418.id, emm_timers->T3418.sec); break; case EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE: /* 3GPP TS 24.301, section 5.4.2.6, case d * Update the UMTS challenge failure counter */ - _authentication_data.umts_count += 1; + authentication_data->umts_count += 1; /* Start timer T3418 */ - T3418.id = nas_timer_start(T3418.sec, - _authentication_t3418_handler, NULL); + emm_timers->T3418.id = nas_timer_start(emm_timers->T3418.sec, + _authentication_t3418_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " - "%ld seconds", T3418.id, T3418.sec); + "%ld seconds", emm_timers->T3418.id, emm_timers->T3418.sec); break; case EMM_CAUSE_SYNCH_FAILURE: /* 3GPP TS 24.301, section 5.4.2.6, case e * Update the synch failure counter */ - _authentication_data.sync_count += 1; + authentication_data->sync_count += 1; /* Start timer T3420 */ - T3420.id = nas_timer_start(T3420.sec, - _authentication_t3420_handler, NULL); + emm_timers->T3420.id = nas_timer_start(emm_timers->T3420.sec, + _authentication_t3420_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3420 (%d) expires in " - "%ld seconds", T3420.id, T3420.sec); + "%ld seconds", emm_timers->T3420.id, emm_timers->T3420.sec); break; default: @@ -719,7 +704,7 @@ static int _authentication_abnormal_cases_cde(int emm_cause, /* * Stop any retransmission timers that are running */ - rc = _authentication_stop_timers(); + rc = _authentication_stop_timers(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - " @@ -733,17 +718,17 @@ static int _authentication_abnormal_cases_cde(int emm_cause, int failure_counter = 0; if (emm_cause == EMM_CAUSE_MAC_FAILURE) { - failure_counter = _authentication_data.mac_count - + _authentication_data.sync_count; + failure_counter = authentication_data->mac_count + + authentication_data->sync_count; } else if (emm_cause == EMM_CAUSE_SYNCH_FAILURE) { - failure_counter = _authentication_data.mac_count - + _authentication_data.umts_count - + _authentication_data.sync_count; + failure_counter = authentication_data->mac_count + + authentication_data->umts_count + + authentication_data->sync_count; } if (failure_counter >= AUTHENTICATION_COUNTER_MAX) { /* 3GPP TS 24.301, section 5.4.2.6, case f */ - rc = _authentication_abnormal_case_f(); + rc = _authentication_abnormal_case_f(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - " @@ -771,7 +756,7 @@ static int _authentication_abnormal_cases_cde(int emm_cause, ** Others: None ** ** ** ***************************************************************************/ -static int _authentication_abnormal_case_f(void) +static int _authentication_abnormal_case_f(nas_user_t *user) { LOG_FUNC_IN; @@ -785,16 +770,16 @@ static int _authentication_abnormal_case_f(void) */ emm_sap_t emm_sap; emm_sap.primitive = EMMAS_RELEASE_REQ; - emm_sap.u.emm_as.u.release.guti = _emm_data.guti; + emm_sap.u.emm_as.u.release.guti = user->emm_data->guti; emm_sap.u.emm_as.u.release.cause = EMM_AS_CAUSE_AUTHENTICATION; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Start any retransmission timers (e.g. T3410, T3417, T3421 or * T3430), if they were running and stopped when the UE received * the first AUTHENTICATION REQUEST message containing an invalid * MAC or SQN */ - rc = _authentication_start_timers(); + rc = _authentication_start_timers(user); } LOG_FUNC_RETURN (rc); @@ -818,40 +803,41 @@ static int _authentication_abnormal_case_f(void) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _authentication_data, T3410, T3417, T3421, ** ** T3430 ** ** ** ***************************************************************************/ -static int _authentication_stop_timers(void) +static int _authentication_stop_timers(nas_user_t *user) { LOG_FUNC_IN; + authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; /* Stop attach timer */ - if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); - _authentication_data.timers |= AUTHENTICATION_T3410; + if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); + authentication_data->timers |= AUTHENTICATION_T3410; } /* Stop service request timer */ - if (T3417.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", T3417.id); - T3417.id = nas_timer_stop(T3417.id); - _authentication_data.timers |= AUTHENTICATION_T3417; + if (emm_timers->T3417.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", emm_timers->T3417.id); + emm_timers->T3417.id = nas_timer_stop(emm_timers->T3417.id); + authentication_data->timers |= AUTHENTICATION_T3417; } /* Stop detach timer */ - if (T3421.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3421 (%d)", T3421.id); - T3421.id = nas_timer_stop(T3421.id); - _authentication_data.timers |= AUTHENTICATION_T3421; + if (emm_timers->T3421.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3421 (%d)", emm_timers->T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); + authentication_data->timers |= AUTHENTICATION_T3421; } /* Stop tracking area update timer */ - if (T3430.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", T3430.id); - T3430.id = nas_timer_stop(T3430.id); - _authentication_data.timers |= AUTHENTICATION_T3430; + if (emm_timers->T3430.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", emm_timers->T3430.id); + emm_timers->T3430.id = nas_timer_stop(emm_timers->T3430.id); + authentication_data->timers |= AUTHENTICATION_T3430; } LOG_FUNC_RETURN (RETURNok); @@ -869,43 +855,44 @@ static int _authentication_stop_timers(void) ** 3GPP TS 24.301, section 5.4.2.7, case f ** ** ** ** Inputs: None ** - ** Others: _authentication_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3410, T3417, T3421, T3430 ** ** ** ***************************************************************************/ -static int _authentication_start_timers(void) +static int _authentication_start_timers(nas_user_t *user) { LOG_FUNC_IN; + authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; - if (_authentication_data.timers & AUTHENTICATION_T3410) { + if (authentication_data->timers & AUTHENTICATION_T3410) { /* Start attach timer */ - T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL); + emm_timers->T3410.id = nas_timer_start(emm_timers->T3410.sec, emm_attach_t3410_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in " - "%ld seconds", T3410.id, T3410.sec); + "%ld seconds", emm_timers->T3410.id, emm_timers->T3410.sec); } - if (_authentication_data.timers & AUTHENTICATION_T3417) { + if (authentication_data->timers & AUTHENTICATION_T3417) { /* Start service request timer */ - T3417.id = nas_timer_start(T3417.sec, _emm_service_t3417_handler, NULL); + emm_timers->T3417.id = nas_timer_start(emm_timers->T3417.sec, emm_service_t3417_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3417 (%d) expires in " - "%ld seconds", T3417.id, T3417.sec); + "%ld seconds", emm_timers->T3417.id, emm_timers->T3417.sec); } - if (_authentication_data.timers & AUTHENTICATION_T3421) { + if (authentication_data->timers & AUTHENTICATION_T3421) { /* Start detach timer */ - T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL); + emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, emm_detach_t3421_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3421 (%d) expires in " - "%ld seconds", T3421.id, T3421.sec); + "%ld seconds", emm_timers->T3421.id, emm_timers->T3421.sec); } - if (_authentication_data.timers & AUTHENTICATION_T3430) { + if (authentication_data->timers & AUTHENTICATION_T3430) { /* Start tracking area update timer */ - T3430.id = nas_timer_start(T3430.sec, _emm_tau_t3430_handler, NULL); + emm_timers->T3430.id = nas_timer_start(emm_timers->T3430.sec, emm_tau_t3430_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3430 (%d) expires in " - "%ld seconds", T3430.id, T3430.sec); + "%ld seconds", emm_timers->T3430.id, emm_timers->T3430.sec); } LOG_FUNC_RETURN (RETURNok); diff --git a/openair3/NAS/UE/EMM/Authentication.h b/openair3/NAS/UE/EMM/Authentication.h new file mode 100644 index 0000000000000000000000000000000000000000..50b2d990aa5ba8628a19550bc393b8b0a88604c2 --- /dev/null +++ b/openair3/NAS/UE/EMM/Authentication.h @@ -0,0 +1,23 @@ +#ifndef _AUTHENTICATION_H +#define _AUTHENTICATION_H + +/* + * Internal data used for authentication procedure + */ +typedef struct { + uint8_t rand[AUTH_RAND_SIZE]; /* Random challenge number */ + uint8_t res[AUTH_RES_SIZE]; /* Authentication response */ + uint8_t ck[AUTH_CK_SIZE]; /* Ciphering key */ + uint8_t ik[AUTH_IK_SIZE]; /* Integrity key */ +#define AUTHENTICATION_T3410 0x01 +#define AUTHENTICATION_T3417 0x02 +#define AUTHENTICATION_T3421 0x04 +#define AUTHENTICATION_T3430 0x08 + unsigned char timers; /* Timer restart bitmap */ +#define AUTHENTICATION_COUNTER_MAX 3 + unsigned char mac_count:2; /* MAC failure counter (#20) */ + unsigned char umts_count:2; /* UMTS challenge failure counter (#26) */ + unsigned char sync_count:2; /* Sync failure counter (#21) */ +} authentication_data_t; + +#endif diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index 7fd73305246ffddd6568cc148037ada478a40f91..fd2db1b6174ae7a9624f875531eaf8b68a2d07b4 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -49,6 +49,7 @@ Description Defines the detach related EMM procedure executed by the #include "nas_timer.h" #include "emmData.h" +#include "emm_timers.h" #include "emm_sap.h" #include "esm_sap.h" @@ -75,29 +76,11 @@ static const char *_emm_detach_type_str[] = { * Internal data handled by the detach procedure in the UE * -------------------------------------------------------------------------- */ -/* - * Timer handlers - */ -void *_emm_detach_t3421_handler(void *); /* * Abnormal case detach procedures */ -static int _emm_detach_abort(emm_proc_detach_type_t type); - -/* - * Internal data used for detach procedure - */ -static struct { -#define EMM_DETACH_COUNTER_MAX 5 - unsigned int count; /* Counter used to limit the number of - * subsequently detach attempts */ - int switch_off; /* UE switch-off indicator */ - emm_proc_detach_type_t type; /* Type of the detach procedure - * currently in progress */ -} _emm_detach_data = {0, FALSE, EMM_DETACH_TYPE_RESERVED}; - - +static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -124,34 +107,34 @@ static struct { ** Inputs: type: Type of the requested detach ** ** switch_off: Indicates whether the detach is required ** ** because the UE is switched off or not ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_detach_data ** ** ** ***************************************************************************/ -int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) +int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_off) { LOG_FUNC_IN; emm_sap_t emm_sap; emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; int rc; LOG_TRACE(INFO, "EMM-PROC - Initiate EPS detach type = %s (%d)", _emm_detach_type_str[type], type); /* Initialize the detach procedure internal data */ - _emm_detach_data.count = 0; - _emm_detach_data.switch_off = switch_off; - _emm_detach_data.type = type; + emm_detach_data->count = 0; + emm_detach_data->switch_off = switch_off; + emm_detach_data->type = type; /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(emm_proc_detach_request, + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, emm_proc_detach_request, emm_proc_detach_failure, - emm_proc_detach_release, NULL); + emm_proc_detach_release, user); if (rc != RETURNok) { LOG_TRACE(WARNING, "Failed to initialize EMM procedure handler"); @@ -167,17 +150,17 @@ int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) /* Set the switch-off indicator */ emm_as->switch_off = switch_off; /* Set the EPS mobile identity */ - emm_as->guti = _emm_data.guti; - emm_as->ueid = 0; + emm_as->guti = user->emm_data->guti; + emm_as->ueid = user->ueid; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, _emm_data.security, FALSE, TRUE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, TRUE); /* * Notify EMM-AS SAP that Detach Request message has to * be sent to the network */ emm_sap.primitive = EMMAS_DATA_REQ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -202,21 +185,24 @@ int emm_proc_detach_request(void *args) { LOG_FUNC_IN; + nas_user_t *user = args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; emm_sap_t emm_sap; int rc; - if ( !_emm_detach_data.switch_off ) { + if ( !emm_detach_data->switch_off ) { /* Start T3421 timer */ - T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL); + emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, emm_detach_t3421_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld seconds", - T3421.id, T3421.sec); + emm_timers->T3421.id, emm_timers->T3421.sec); } /* * Notify EMM that Detach Request has been sent to the network */ emm_sap.primitive = EMMREG_DETACH_REQ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -243,19 +229,21 @@ int emm_proc_detach_request(void *args) ** Others: T3421 ** ** ** ***************************************************************************/ -int emm_proc_detach_accept(void) +int emm_proc_detach_accept(void* args) { LOG_FUNC_IN; + nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; int rc; LOG_TRACE(INFO, "EMM-PROC - UE initiated detach procedure completion"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + (void) emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Stop timer T3421 */ - T3421.id = nas_timer_stop(T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); /* * Notify ESM that all EPS bearer contexts have to be locally deactivated @@ -263,7 +251,7 @@ int emm_proc_detach_accept(void) esm_sap_t esm_sap; esm_sap.primitive = ESM_EPS_BEARER_CONTEXT_DEACTIVATE_REQ; esm_sap.data.eps_bearer_context_deactivate.ebi = ESM_SAP_ALL_EBI; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); /* * XXX - Upon receiving notification from ESM that all EPS bearer @@ -285,7 +273,6 @@ int emm_proc_detach_accept(void) ** ** ** Inputs: is_initial: Not used ** ** args: Not used ** - ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** @@ -296,23 +283,26 @@ int emm_proc_detach_failure(int is_initial, void *args) { LOG_FUNC_IN; + nas_user_t *user = args; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; int rc; LOG_TRACE(WARNING, "EMM-PROC - Network detach failure"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + (void) emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Stop timer T3421 */ - T3421.id = nas_timer_stop(T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); /* * Notify EMM that detach procedure has to be restarted */ emm_sap.primitive = EMMREG_DETACH_INIT; - emm_sap.u.emm_reg.u.detach.switch_off = _emm_detach_data.switch_off; - rc = emm_sap_send(&emm_sap); + emm_sap.u.emm_reg.u.detach.switch_off = emm_detach_data->switch_off; + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -329,7 +319,6 @@ int emm_proc_detach_failure(int is_initial, void *args) ** The detach procedure shall be aborted. ** ** ** ** Inputs: args: not used ** - ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** @@ -342,8 +331,10 @@ int emm_proc_detach_release(void *args) LOG_TRACE(WARNING, "EMM-PROC - NAS signalling connection released"); + nas_user_t *user = args; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; /* Abort the detach procedure */ - int rc = _emm_detach_abort(_emm_detach_data.type); + int rc = _emm_detach_abort(user, emm_detach_data->type); LOG_FUNC_RETURN(rc); } @@ -368,50 +359,52 @@ int emm_proc_detach_release(void *args) ** 3GPP TS 24.301, section 5.5.2.2.4 case c ** ** On the first four expiries of the timer, the UE shall re- ** ** transmit the DETACH REQUEST message and shall reset and ** - ** restart timer T3421. On the fifth expiry of timer T3421, ** + ** restart timer emm_timers->T3421. On the fifth expiry of timer T3421, ** ** the detach procedure shall be aborted. ** ** ** ** Inputs: args: handler parameters ** - ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: None ** ** Others: None ** ** ** ***************************************************************************/ -void *_emm_detach_t3421_handler(void *args) +void *emm_detach_t3421_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user = args; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; int rc; /* Increment the retransmission counter */ - _emm_detach_data.count += 1; + emm_detach_data->count += 1; LOG_TRACE(WARNING, "EMM-PROC - T3421 timer expired, " - "retransmission counter = %d", _emm_detach_data.count); + "retransmission counter = %d", emm_detach_data->count); - if (_emm_detach_data.count < EMM_DETACH_COUNTER_MAX) { + if (emm_detach_data->count < EMM_DETACH_COUNTER_MAX) { /* Retransmit the Detach Request message */ emm_sap_t emm_sap; emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data; /* Stop timer T3421 */ - T3421.id = nas_timer_stop(T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); /* Setup NAS information message to transfer */ emm_as->NASinfo = EMM_AS_NAS_INFO_DETACH; emm_as->NASmsg.length = 0; emm_as->NASmsg.value = NULL; /* Set the detach type */ - emm_as->type = _emm_detach_data.type; + emm_as->type = emm_detach_data->type; /* Set the switch-off indicator */ - emm_as->switch_off = _emm_detach_data.switch_off; + emm_as->switch_off = emm_detach_data->switch_off; /* Set the EPS mobile identity */ - emm_as->guti = _emm_data.guti; - emm_as->ueid = 0; + emm_as->guti = user->emm_data->guti; + emm_as->ueid = user->ueid; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, _emm_data.security, + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, TRUE); /* @@ -419,17 +412,17 @@ void *_emm_detach_t3421_handler(void *args) * be sent to the network */ emm_sap.primitive = EMMAS_DATA_REQ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Start T3421 timer */ - T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL); + emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, emm_detach_t3421_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld " - "seconds", T3421.id, T3421.sec); + "seconds", emm_timers->T3421.id, emm_timers->T3421.sec); } } else { /* Abort the detach procedure */ - rc = _emm_detach_abort(_emm_detach_data.type); + rc = _emm_detach_abort(user, emm_detach_data->type); } LOG_FUNC_RETURN(NULL); @@ -448,34 +441,34 @@ void *_emm_detach_t3421_handler(void *args) ** Description: Aborts the detach procedure ** ** ** ** Inputs: type: not used ** - ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3421 ** ** ** ***************************************************************************/ -static int _emm_detach_abort(emm_proc_detach_type_t type) +static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type) { LOG_FUNC_IN; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; int rc ; LOG_TRACE(WARNING, "EMM-PROC - Abort the detach procedure"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Stop timer T3421 */ - T3421.id = nas_timer_stop(T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); /* * Notify EMM that detach procedure failed */ emm_sap.primitive = EMMREG_DETACH_FAILED; emm_sap.u.emm_reg.u.detach.type = type; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/EmmStatusHdl.c b/openair3/NAS/UE/EMM/EmmStatusHdl.c index c95441d37065e316a7869185860c98be8babfe48..89dd50207f05b80d454de9899d54434f255d6499 100644 --- a/openair3/NAS/UE/EMM/EmmStatusHdl.c +++ b/openair3/NAS/UE/EMM/EmmStatusHdl.c @@ -115,7 +115,7 @@ int emm_proc_status_ind(unsigned int ueid, int emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_status(unsigned int ueid, int emm_cause) +int emm_proc_status(nas_user_t *user, int emm_cause) { LOG_FUNC_IN; @@ -132,15 +132,15 @@ int emm_proc_status(unsigned int ueid, int emm_cause) */ emm_sap.primitive = EMMAS_STATUS_IND; emm_sap.u.emm_as.u.status.emm_cause = emm_cause; - emm_sap.u.emm_as.u.status.ueid = ueid; + emm_sap.u.emm_as.u.status.ueid = user->ueid; - emm_sap.u.emm_as.u.status.guti = _emm_data.guti; - sctx = _emm_data.security; + emm_sap.u.emm_as.u.status.guti = user->emm_data->guti; + sctx = user->emm_data->security; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.status.sctx, sctx, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/Identification.c b/openair3/NAS/UE/EMM/Identification.c index a9ceb7a43bd522669c23ede0ab31fe74f8a8f871..7cf2e765c61322a185618566632227270f083e6f 100644 --- a/openair3/NAS/UE/EMM/Identification.c +++ b/openair3/NAS/UE/EMM/Identification.c @@ -49,6 +49,7 @@ Description Defines the identification EMM procedure executed by the #include "emm_sap.h" #include "msc.h" +#include "user_defs.h" #include <stdlib.h> // malloc, free #include <string.h> // memcpy @@ -102,7 +103,7 @@ static const char *_emm_identity_type_str[] = { ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_identification_request(emm_proc_identity_type_t type) +int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t type) { LOG_FUNC_IN; @@ -114,7 +115,7 @@ int emm_proc_identification_request(emm_proc_identity_type_t type) /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); if (rc != RETURNok) { LOG_TRACE(WARNING, @@ -129,8 +130,8 @@ int emm_proc_identification_request(emm_proc_identity_type_t type) imsi_t modified_imsi; /* International Mobile Subscriber Identity is requested */ - if (_emm_data.imsi) { - memcpy (&modified_imsi, _emm_data.imsi, sizeof (modified_imsi)); + if (user->emm_data->imsi) { + memcpy (&modified_imsi, user->emm_data->imsi, sizeof (modified_imsi)); /* LW: Eventually replace the 0xF value set in MNC digit 3 by a 0 to avoid IMSI to be truncated before reaching HSS */ if (modified_imsi.u.num.digit6 == 0xF) { @@ -166,9 +167,9 @@ int emm_proc_identification_request(emm_proc_identity_type_t type) case EMM_IDENT_TYPE_IMEI: /* International Mobile Equipment Identity is requested */ - if (_emm_data.imei) { + if (user->emm_data->imei) { emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_IMEI; - emm_sap.u.emm_as.u.security.imei = _emm_data.imei; + emm_sap.u.emm_as.u.security.imei = user->emm_data->imei; } break; @@ -176,9 +177,9 @@ int emm_proc_identification_request(emm_proc_identity_type_t type) case EMM_IDENT_TYPE_TMSI: /* Temporary Mobile Subscriber Identity is requested */ - if (_emm_data.guti) { + if (user->emm_data->guti) { emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_TMSI; - emm_sap.u.emm_as.u.security.tmsi = _emm_data.guti->m_tmsi; + emm_sap.u.emm_as.u.security.tmsi = user->emm_data->guti->m_tmsi; } break; @@ -193,13 +194,13 @@ int emm_proc_identification_request(emm_proc_identity_type_t type) * to the MME */ emm_sap.primitive = EMMAS_SECURITY_RES; - emm_sap.u.emm_as.u.security.guti = _emm_data.guti; - emm_sap.u.emm_as.u.security.ueid = 0; + emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; + emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_IDENT; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + user->emm_data->security, FALSE, TRUE); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index a5a2c3070894305392cc2ef0b760f49837d1f9b6..159a3b2a2ceba18bd0e76c2d32d1494f72b36a29 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -59,6 +59,7 @@ Description Defines EMM procedures executed by the Non-Access Stratum #include "emm_proc.h" #include "nas_log.h" +#include "utils.h" #include "emm_sap.h" @@ -78,56 +79,8 @@ Description Defines EMM procedures executed by the Non-Access Stratum /****************************************************************************/ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn); -static int _IldlMode_get_opnn_id(const plmn_t *plmn); -static int _IdleMode_get_suitable_cell(int index); - -/* - * A list of PLMN identities in priority order is maintained locally - * to perform the PLMN selection procedure. - * - * In automatic mode of operation, this list is used for PLMN selection when - * the UE is switched on, or upon recovery from lack of coverage, or when the - * user requests the UE to initiate PLMN reselection, and registration. - * In manual mode of operation, this list is displayed to the user that may - * select an available PLMN and initiate registration. - * - * The list may contain PLMN identifiers in the following order: - * - The last registered PLMN or each equivalent PLMN present in the list of - * "equivalent PLMNs" (EPLMN_MAX), when UE is switched on or following - * recovery from lack of coverage; - * - The highest priority PLMN in the list of "equivalent HPLMNs" or the - * HPLMN derived from the IMSI (1) - * - Each PLMN/access technology combination in the "User Controlled PLMN - * Selector with Access Technology" (PLMN_MAX) - * - Each PLMN/access technology combination in the "Operator Controlled PLMN - * Selector with Access Technology" (OPLMN_MAX) - * - Other PLMN/access technology combinations with received high quality - * signal in random order (TODO) - * - Other PLMN/access technology combinations in order of decreasing signal - * quality (TODO) - * - The last selected PLMN again (1) - */ -static struct { - int n_plmns; -#define EMM_PLMN_LIST_SIZE (EMM_DATA_EPLMN_MAX + EMM_DATA_PLMN_MAX + \ - EMM_DATA_OPLMN_MAX + 2) - plmn_t *plmn[EMM_PLMN_LIST_SIZE]; - int index; /* Index of the PLMN for which selection is ongoing */ - int hplmn; /* Index of the home PLMN or the highest priority - * equivalent home PLMN */ - int fplmn; /* Index of the first forbidden PLMN */ - int splmn; /* Index of the currently selected PLMN */ - int rplmn; /* Index of the currently registered PLMN */ - struct plmn_param_t { - char fullname[NET_FORMAT_LONG_SIZE+1]; /* PLMN full identifier */ - char shortname[NET_FORMAT_SHORT_SIZE+1]; /* PLMN short identifier */ - char num[NET_FORMAT_NUM_SIZE+1]; /* PLMN numeric identifier */ - int stat; /* Indication of the PLMN availability */ - int tac; /* Location/Tracking Area Code */ - int ci; /* Serving cell identifier */ - int rat; /* Radio Access Technology supported by the serving cell */ - } param[EMM_PLMN_LIST_SIZE]; -} _emm_plmn_list; +static int _IldlMode_get_opnn_id(emm_data_t *emm_data, const plmn_t *plmn); +static int _IdleMode_get_suitable_cell(nas_user_t *user, int index); /* Callback executed whenever a network indication is received */ static IdleMode_callback_t _emm_indication_notify; @@ -152,21 +105,23 @@ static IdleMode_callback_t _emm_indication_notify; ** Others: _emm_plmn_list, _emm_indication_notify ** ** ** ***************************************************************************/ -void IdleMode_initialize(IdleMode_callback_t cb) +void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb) { + emm_plmn_list_t *emm_plmn_list = calloc_or_fail( sizeof(emm_plmn_list_t)); + user->emm_plmn_list = emm_plmn_list; /* Initialize the list of available PLMNs */ - _emm_plmn_list.n_plmns = 0; - _emm_plmn_list.index = 0; - _emm_plmn_list.hplmn = -1; - _emm_plmn_list.fplmn = -1; - _emm_plmn_list.splmn = -1; - _emm_plmn_list.rplmn = -1; + emm_plmn_list->n_plmns = 0; + emm_plmn_list->index = 0; + emm_plmn_list->hplmn = -1; + emm_plmn_list->fplmn = -1; + emm_plmn_list->splmn = -1; + emm_plmn_list->rplmn = -1; /* Initialize the network notification handler */ _emm_indication_notify = *cb; /* Initialize EMM Service Access Point */ - emm_sap_initialize(); + emm_sap_initialize(user); } /* @@ -190,9 +145,9 @@ void IdleMode_initialize(IdleMode_callback_t cb) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_nb_plmns(void) +int IdleMode_get_nb_plmns(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.n_plmns; + return emm_plmn_list->n_plmns; } /**************************************************************************** @@ -211,9 +166,9 @@ int IdleMode_get_nb_plmns(void) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_hplmn_index(void) +int IdleMode_get_hplmn_index(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.hplmn; + return emm_plmn_list->hplmn; } /**************************************************************************** @@ -232,9 +187,9 @@ int IdleMode_get_hplmn_index(void) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_rplmn_index(void) +int IdleMode_get_rplmn_index(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.rplmn; + return emm_plmn_list->rplmn; } /**************************************************************************** @@ -245,16 +200,15 @@ int IdleMode_get_rplmn_index(void) ** available PLMNs. ** ** ** ** Inputs: None ** - ** Others: _emm_plmn_list ** ** ** ** Outputs: None ** ** Return: The index of the selected PLMN in the list ** ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_splmn_index(void) +int IdleMode_get_splmn_index(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.splmn; + return emm_plmn_list->splmn; } /**************************************************************************** @@ -265,38 +219,36 @@ int IdleMode_get_splmn_index(void) ** tors present in the network ** ** ** ** Inputs: i: Index of the first operator to update ** - ** Others: _emm_plmn_list ** ** ** ** Outputs: None ** ** Return: The size of the list in bytes ** - ** Others: _emm_data.plist ** ** ** ***************************************************************************/ -int IdleMode_update_plmn_list(int i) +int IdleMode_update_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int i) { int offset = 0; int n = 1; - while ( (i < _emm_plmn_list.n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) { - struct plmn_param_t *plmn = &(_emm_plmn_list.param[i++]); + while ( (i < emm_plmn_list->n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) { + struct plmn_param_t *plmn = &(emm_plmn_list->param[i++]); if (n++ > 1) { - offset += snprintf(_emm_data.plist.buffer + offset, + offset += snprintf(emm_data->plist.buffer + offset, EMM_DATA_BUFFER_SIZE - offset, ","); } - offset += snprintf(_emm_data.plist.buffer + offset, + offset += snprintf(emm_data->plist.buffer + offset, EMM_DATA_BUFFER_SIZE - offset, "(%d,%s,%s,%s", plmn->stat, plmn->fullname, plmn->shortname, plmn->num); if (plmn->rat != NET_ACCESS_UNAVAILABLE) { - offset += snprintf(_emm_data.plist.buffer + offset, + offset += snprintf(emm_data->plist.buffer + offset, EMM_DATA_BUFFER_SIZE - offset, ",%d", plmn->rat); } - offset += snprintf(_emm_data.plist.buffer + offset, + offset += snprintf(emm_data->plist.buffer + offset, EMM_DATA_BUFFER_SIZE - offset, ")"); } @@ -320,13 +272,13 @@ int IdleMode_update_plmn_list(int i) ** Others: None ** ** ** ***************************************************************************/ -const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_fullname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len) { - if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].fullname); - return _emm_plmn_list.param[index].fullname; + if (index < emm_plmn_list->n_plmns) { + assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) ); + *len = strlen(emm_plmn_list->param[index].fullname); + return emm_plmn_list->param[index].fullname; } return NULL; @@ -349,13 +301,13 @@ const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, ** Others: None ** ** ** ***************************************************************************/ -const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_shortname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len) { - if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].shortname); - return _emm_plmn_list.param[index].shortname; + if (index < emm_plmn_list->n_plmns) { + assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) ); + *len = strlen(emm_plmn_list->param[index].shortname); + return emm_plmn_list->param[index].shortname; } return NULL; @@ -379,12 +331,12 @@ const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, ** Others: None ** ** ** ***************************************************************************/ -const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len) +const char *IdleMode_get_plmn_id(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len) { - if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].num); - return _emm_plmn_list.param[index].num; + if (index < emm_plmn_list->n_plmns) { + assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) ); + *len = strlen(emm_plmn_list->param[index].num); + return emm_plmn_list->param[index].num; } return NULL; @@ -406,13 +358,13 @@ const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_fullname_index(const char *plmn) +int IdleMode_get_plmn_fullname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn) { int index; /* Get the index of the PLMN identifier with specified full name */ - for (index = 0; index < _emm_plmn_list.n_plmns; index++) { - if ( strncmp(plmn, _emm_plmn_list.param[index].fullname, + for (index = 0; index < emm_plmn_list->n_plmns; index++) { + if ( strncmp(plmn, emm_plmn_list->param[index].fullname, NET_FORMAT_LONG_SIZE) != 0 ) { continue; } @@ -439,13 +391,13 @@ int IdleMode_get_plmn_fullname_index(const char *plmn) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_shortname_index(const char *plmn) +int IdleMode_get_plmn_shortname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn) { int index; /* Get the index of the PLMN identifier with specified short name */ - for (index = 0; index < _emm_plmn_list.n_plmns; index++) { - if ( !strncmp(plmn, _emm_plmn_list.param[index].shortname, + for (index = 0; index < emm_plmn_list->n_plmns; index++) { + if ( !strncmp(plmn, emm_plmn_list->param[index].shortname, NET_FORMAT_SHORT_SIZE) ) { continue; } @@ -472,13 +424,13 @@ int IdleMode_get_plmn_shortname_index(const char *plmn) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_id_index(const char *plmn) +int IdleMode_get_plmn_id_index(emm_plmn_list_t *emm_plmn_list, const char *plmn) { int index; /* Get the index of the PLMN identifier with specified numeric identifier */ - for (index = 0; index < _emm_plmn_list.n_plmns; index++) { - if ( !strncmp(plmn, _emm_plmn_list.param[index].num, + for (index = 0; index < emm_plmn_list->n_plmns; index++) { + if ( !strncmp(plmn, emm_plmn_list->param[index].num, NET_FORMAT_LONG_SIZE) ) { continue; } @@ -503,66 +455,67 @@ int IdleMode_get_plmn_id_index(const char *plmn) ** to PLMN selection procedure. ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: _emm_plmn_list ** ** ** ***************************************************************************/ -int emm_proc_initialize(void) +int emm_proc_initialize(nas_user_t *user) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; int i; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; - if (!_emm_data.usim_is_valid) { + if (!user->emm_data->usim_is_valid) { /* The USIM application is not present or not valid */ LOG_TRACE(WARNING, "EMM-IDLE - USIM is not valid"); emm_sap.primitive = EMMREG_NO_IMSI; } else { /* The highest priority is given to either the "equivalent PLMNs" * if available, or the last registered PLMN */ - if (_emm_data.nvdata.eplmn.n_plmns > 0) { - for (i=0; i < _emm_data.nvdata.eplmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.nvdata.eplmn.plmn[i]; + if (user->emm_data->nvdata.eplmn.n_plmns > 0) { + for (i=0; i < user->emm_data->nvdata.eplmn.n_plmns; i++) { + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = + &user->emm_data->nvdata.eplmn.plmn[i]; } - } else if ( PLMN_IS_VALID(_emm_data.nvdata.rplmn) ) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.nvdata.rplmn; + } else if ( PLMN_IS_VALID(user->emm_data->nvdata.rplmn) ) { + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = + &user->emm_data->nvdata.rplmn; } /* Update the index of the HPLMN or EHPLM of highest priority. * When switched on, the UE will try to automatically register * to each previous PLMN within the ordered list of available * PLMNs regardless of the network selection mode of operation */ - _emm_plmn_list.hplmn = _emm_plmn_list.n_plmns - 1; - // LG_emm_plmn_list.hplmn = _emm_plmn_list.n_plmns; + emm_plmn_list->hplmn = emm_plmn_list->n_plmns - 1; + // LGemm_plmn_list->hplmn = emm_plmn_list->n_plmns; /* Add the highest priority PLMN in the list of "equivalent HPLMNs" if present and not empty, or the HPLMN derived from the IMSI */ - if (_emm_data.ehplmn.n_plmns > 0) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.ehplmn.plmn[0]; + if (user->emm_data->ehplmn.n_plmns > 0) { + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = + &user->emm_data->ehplmn.plmn[0]; } else { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = &_emm_data.hplmn; + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->hplmn; } /* Each PLMN/access technology combination in the "User * Controlled PLMN Selector with Access Technology" */ - for (i=0; i < _emm_data.plmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.plmn.plmn[i]; + for (i=0; i < user->emm_data->plmn.n_plmns; i++) { + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = + &user->emm_data->plmn.plmn[i]; } /* Each PLMN/access technology combination in the "Operator * Controlled PLMN Selector with Access Technology" */ - for (i=0; i < _emm_data.oplmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.oplmn.plmn[i]; + for (i=0; i < user->emm_data->oplmn.n_plmns; i++) { + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = + &user->emm_data->oplmn.plmn[i]; } /* Other PLMN/access technology combinations with received @@ -574,21 +527,21 @@ int emm_proc_initialize(void) /* TODO: Schedule periodic network selection attemps (hpplmn timer) */ /* Initialize the PLMNs' parameters */ - for (i=0; i < _emm_plmn_list.n_plmns; i++) { - struct plmn_param_t *plmn = &(_emm_plmn_list.param[i]); - int id = _IldlMode_get_opnn_id(_emm_plmn_list.plmn[i]); + for (i=0; i < emm_plmn_list->n_plmns; i++) { + struct plmn_param_t *plmn = &(emm_plmn_list->param[i]); + int id = _IldlMode_get_opnn_id(user->emm_data, emm_plmn_list->plmn[i]); if (id < 0) { plmn->fullname[0] = '\0'; plmn->shortname[0] = '\0'; } else { - strncpy(plmn->fullname, _emm_data.opnn[id].fullname, + strncpy(plmn->fullname, user->emm_data->opnn[id].fullname, NET_FORMAT_LONG_SIZE); - strncpy(plmn->shortname, _emm_data.opnn[id].shortname, + strncpy(plmn->shortname, user->emm_data->opnn[id].shortname, NET_FORMAT_SHORT_SIZE); } - (void)_IdleMode_plmn_str(plmn->num, _emm_plmn_list.plmn[i]); + (void)_IdleMode_plmn_str(plmn->num, emm_plmn_list->plmn[i]); plmn->stat = NET_OPER_UNKNOWN; plmn->tac = 0; plmn->ci = 0; @@ -596,14 +549,14 @@ int emm_proc_initialize(void) } LOG_TRACE(INFO, "EMM-IDLE - %d PLMNs available for network selection", - _emm_plmn_list.n_plmns); + emm_plmn_list->n_plmns); /* Notify EMM that PLMN selection procedure has to be executed */ emm_sap.primitive = EMMREG_REGISTER_REQ; emm_sap.u.emm_reg.u.regist.index = 0; } - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); @@ -627,35 +580,38 @@ int emm_proc_initialize(void) ** mode. ** ** ** ** Inputs: None ** - ** Others: _emm_plmn_list, _emm_data ** + ** Others: _emm_plmn_list, user->emm_data-> ** ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_plmn_list.index ** + ** Others: emm_plmn_list->index ** ** ** ***************************************************************************/ -int emm_proc_plmn_selection(int index) +int emm_proc_plmn_selection(nas_user_t *user, int index) { LOG_FUNC_IN; + emm_data_t *emm_data = user->emm_data; + user_api_id_t *user_api_id = user->user_api_id; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; int rc = RETURNok; - if (_emm_data.plmn_mode != EMM_DATA_PLMN_AUTO) { + if (emm_data->plmn_mode != EMM_DATA_PLMN_AUTO) { /* * Manual or manual/automatic mode of operation * -------------------------------------------- */ - if (index >= _emm_plmn_list.hplmn) { + if (index >= emm_plmn_list->hplmn) { /* * Selection of the last registered or equivalent PLMNs failed */ - if (_emm_data.plmn_index < 0) { + if (emm_data->plmn_index < 0) { /* * The user did not select any PLMN yet; display the ordered * list of available PLMNs to the user */ index = -1; - rc = emm_proc_network_notify(_emm_plmn_list.hplmn); + rc = emm_proc_network_notify(emm_plmn_list, user_api_id, emm_data, emm_plmn_list->hplmn); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify " @@ -665,7 +621,7 @@ int emm_proc_plmn_selection(int index) /* * Try to register to the PLMN manually selected by the user */ - index = _emm_data.plmn_index; + index = emm_data->plmn_index; } } } @@ -678,8 +634,8 @@ int emm_proc_plmn_selection(int index) * or any other PLMN in the ordered list of available PLMNs in * automatic mode. */ - _emm_plmn_list.index = index; - rc = _IdleMode_get_suitable_cell(index); + emm_plmn_list->index = index; + rc = _IdleMode_get_suitable_cell(user, index); } LOG_FUNC_RETURN (rc); @@ -714,47 +670,48 @@ int emm_proc_plmn_selection(int index) ** ci: The identifier of the cell ** ** rat: The radio access technology supported by ** ** the cell ** - ** Others: _emm_plmn_list, _emm_data ** ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_plmn_list, _emm_data ** ** ** ***************************************************************************/ -int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) +int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc = RETURNerror; - int index = _emm_plmn_list.index; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; + user_api_id_t *user_api_id = user->user_api_id; + int index = emm_plmn_list->index; int select_next_plmn = FALSE; LOG_TRACE(INFO, "EMM-IDLE - %s cell found for PLMN %d in %s mode", (found)? "One" : "No", index, - (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : "Automatic/manual"); if (found) { int is_forbidden = FALSE; /* Select the PLMN of which a suitable cell has been found */ - _emm_data.splmn = *_emm_plmn_list.plmn[index]; + emm_data->splmn = *emm_plmn_list->plmn[index]; /* Update the selected PLMN's parameters */ - _emm_plmn_list.param[index].tac = tac; - _emm_plmn_list.param[index].ci = ci; - _emm_plmn_list.param[index].rat = rat; + emm_plmn_list->param[index].tac = tac; + emm_plmn_list->param[index].ci = ci; + emm_plmn_list->param[index].rat = rat; /* Update the location data and notify EMM that data have changed */ - rc = emm_proc_location_notify(tac, ci , rat); + rc = emm_proc_location_notify(user_api_id, emm_data, tac, ci , rat); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify location update"); } - if (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO) { + if (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { /* * Automatic mode of operation * --------------------------- @@ -762,17 +719,17 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) int i; /* Check if the selected PLMN is in the forbidden list */ - for (i = 0; i < _emm_data.fplmn.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(_emm_data.splmn, _emm_data.fplmn.plmn[i])) { + for (i = 0; i < emm_data->fplmn.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(emm_data->splmn, emm_data->fplmn.plmn[i])) { is_forbidden = TRUE; break; } } if (!is_forbidden) { - for (i = 0; i < _emm_data.fplmn_gprs.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(_emm_data.splmn, - _emm_data.fplmn_gprs.plmn[i])) { + for (i = 0; i < emm_data->fplmn_gprs.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(emm_data->splmn, + emm_data->fplmn_gprs.plmn[i])) { is_forbidden = TRUE; break; } @@ -782,12 +739,12 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) /* Check if the selected PLMN belongs to a forbidden * tracking area */ tai_t tai; - tai.plmn = _emm_data.splmn; + tai.plmn = emm_data->splmn; tai.tac = tac; if (!is_forbidden) { - for (i = 0; i < _emm_data.ftai.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, _emm_data.ftai.tai[i])) { + for (i = 0; i < emm_data->ftai.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, emm_data->ftai.tai[i])) { is_forbidden = TRUE; break; } @@ -795,8 +752,8 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) } if (!is_forbidden) { - for (i = 0; i < _emm_data.ftai_roaming.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, _emm_data.ftai_roaming.tai[i])) { + for (i = 0; i < emm_data->ftai_roaming.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, emm_data->ftai_roaming.tai[i])) { is_forbidden = TRUE; break; } @@ -810,25 +767,25 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this acceptable cell for limited services"); /* Save the index of the first forbidden PLMN */ - if (_emm_plmn_list.fplmn < 0) { - _emm_plmn_list.fplmn = index; + if (emm_plmn_list->fplmn < 0) { + emm_plmn_list->fplmn = index; } - _emm_plmn_list.param[index].stat = NET_OPER_FORBIDDEN; + emm_plmn_list->param[index].stat = NET_OPER_FORBIDDEN; } else { /* A suitable cell has been found and the PLMN or tracking area * is not in the forbidden list */ LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this suitable cell for normal services"); - _emm_plmn_list.fplmn = -1; - _emm_plmn_list.param[index].stat = NET_OPER_CURRENT; + emm_plmn_list->fplmn = -1; + emm_plmn_list->param[index].stat = NET_OPER_CURRENT; emm_sap.primitive = EMMREG_REGISTER_CNF; } /* Duplicate the new selected PLMN at the end of the ordered list */ - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns] = &_emm_data.splmn; + emm_plmn_list->plmn[emm_plmn_list->n_plmns] = &emm_data->splmn; } - else if (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO) { + else if (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { /* * Automatic mode of operation * --------------------------- @@ -839,12 +796,12 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) select_next_plmn = TRUE; /* Bypass the previously selected PLMN */ - if (index == _emm_plmn_list.splmn) { + if (index == emm_plmn_list->splmn) { index += 1; } } - else if (_emm_data.plmn_index < 0) { + else if (emm_data->plmn_index < 0) { /* * Manual or manual/automatic mode of operation * -------------------------------------------- @@ -855,7 +812,7 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) select_next_plmn = TRUE; } - else if (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL) { + else if (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL) { /* * Manual mode of operation * ------------------------ @@ -871,8 +828,8 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) * Attempt to find a suitable cell of the PLMN selected by the user * failed; Try to automatically select another PLMN */ - _emm_data.plmn_mode = EMM_DATA_PLMN_AUTO; - index = _emm_plmn_list.hplmn; + emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; + index = emm_plmn_list->hplmn; select_next_plmn = TRUE; } @@ -880,17 +837,17 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) * Force an attempt to register to the next PLMN */ if (select_next_plmn) { - int last_plmn_index = _emm_plmn_list.n_plmns; + int last_plmn_index = emm_plmn_list->n_plmns; - if (_emm_plmn_list.splmn != -1) { + if (emm_plmn_list->splmn != -1) { /* The last attempt was to register the previously selected PLMN */ last_plmn_index += 1; } if (index < last_plmn_index) { /* Try to select the next PLMN in the list of available PLMNs */ - _emm_plmn_list.index = index; - rc = emm_proc_plmn_selection(index); + emm_plmn_list->index = index; + rc = emm_proc_plmn_selection(user, index); } else { /* No suitable cell of any PLMN within the ordered list * of available PLMNs has been found */ @@ -903,46 +860,43 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) * Or terminate the PLMN selection procedure */ if (!select_next_plmn) { - /* TODO: be sure of this fix */ - LOG_TRACE(WARNING, "%s:%d:%s: be sure!!\n", __FILE__, __LINE__, __FUNCTION__); - //if (!(_emm_plmn_list.fplmn) < 0) { // FIXME this comparison makes no sense (bool < 0) - if (!(_emm_plmn_list.fplmn < 0)) { // FIXME this comparison makes no sense (bool < 0) + if (emm_plmn_list->fplmn >= 0) { /* There were one or more PLMNs which were available and allowable, * but an LR failure made registration on those PLMNs unsuccessful * or an entry in any of the forbidden area lists prevented a * registration attempt; select the first such PLMN and enters a * limited service state. */ - index = _emm_plmn_list.fplmn; - _emm_plmn_list.fplmn = -1; + index = emm_plmn_list->fplmn; + emm_plmn_list->fplmn = -1; emm_sap.primitive = EMMREG_REGISTER_REJ; } /* Update the availability indicator of the previously selected PLMN */ - if (_emm_plmn_list.splmn != -1) { - _emm_plmn_list.param[_emm_plmn_list.splmn].stat = NET_OPER_UNKNOWN; + if (emm_plmn_list->splmn != -1) { + emm_plmn_list->param[emm_plmn_list->splmn].stat = NET_OPER_UNKNOWN; } /* Update the index of the new selected PLMN */ if (emm_sap.primitive != EMMREG_NO_CELL) { - _emm_plmn_list.splmn = index; + emm_plmn_list->splmn = index; } else { - _emm_plmn_list.splmn = -1; + emm_plmn_list->splmn = -1; } /* * Notify EMM that PLMN selection procedure has completed */ - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); - if (_emm_plmn_list.splmn != -1) { - if (_emm_plmn_list.splmn == _emm_plmn_list.rplmn) { + if (emm_plmn_list->splmn != -1) { + if (emm_plmn_list->splmn == emm_plmn_list->rplmn) { /* The selected PLMN is the registered PLMN */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is the registered PLMN"); - _emm_data.is_rplmn = TRUE; - } else if (_emm_plmn_list.splmn < _emm_plmn_list.hplmn) { + emm_data->is_rplmn = TRUE; + } else if (emm_plmn_list->splmn < emm_plmn_list->hplmn) { /* The selected PLMN is in the list of equivalent PLMNs */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is in the list of equivalent PLMNs"); - _emm_data.is_eplmn = TRUE; + emm_data->is_eplmn = TRUE; } /* @@ -950,7 +904,7 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) * to register the presence of the UE to the selected PLMN */ emm_sap.primitive = EMMREG_ATTACH_INIT; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } } @@ -976,20 +930,20 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_registration_notify(Stat_t status) +int emm_proc_registration_notify(user_api_id_t *user_api_id, emm_data_t *emm_data, Stat_t status) { LOG_FUNC_IN; int rc = RETURNok; /* Update the network registration status */ - if (_emm_data.stat != status) { - _emm_data.stat = status; + if (emm_data->stat != status) { + emm_data->stat = status; /* Notify EMM that data has changed */ - rc = (*_emm_indication_notify)(1); + rc = (*_emm_indication_notify)(user_api_id, emm_data, 1); } LOG_FUNC_RETURN (rc); @@ -1010,24 +964,24 @@ int emm_proc_registration_notify(Stat_t status) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat) +int emm_proc_location_notify(user_api_id_t *user_api_id, emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat) { LOG_FUNC_IN; int rc = RETURNok; /* Update the location information */ - if ( (_emm_data.tac != tac) || - (_emm_data.ci != ci) || - (_emm_data.rat != rat) ) { - _emm_data.tac = tac; - _emm_data.ci = ci; - _emm_data.rat = rat; + if ( (emm_data->tac != tac) || + (emm_data->ci != ci) || + (emm_data->rat != rat) ) { + emm_data->tac = tac; + emm_data->ci = ci; + emm_data->rat = rat; /* Notify EMM that data has changed */ - rc = (*_emm_indication_notify)(0); + rc = (*_emm_indication_notify)(user_api_id, emm_data, 0); } LOG_FUNC_RETURN (rc); @@ -1047,17 +1001,17 @@ int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_network_notify(int index) +int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, user_api_id_t *user_api_id, emm_data_t *emm_data, int index) { LOG_FUNC_IN; /* Update the list of operators present in the network */ - int size = IdleMode_update_plmn_list(index); + int size = IdleMode_update_plmn_list(emm_plmn_list, emm_data, index); /* Notify EMM that data has changed */ - int rc = (*_emm_indication_notify)(size); + int rc = (*_emm_indication_notify)(user_api_id, emm_data, size); LOG_FUNC_RETURN (rc); } @@ -1126,7 +1080,6 @@ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn) ** tor network name records ** ** ** ** Inputs: plmn: The PLMN identifier ** - ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: The index of the PLMN if found in the list ** @@ -1135,32 +1088,32 @@ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn) ** Others: None ** ** ** ***************************************************************************/ -static int _IldlMode_get_opnn_id(const plmn_t *plmn) +static int _IldlMode_get_opnn_id(emm_data_t *emm_data, const plmn_t *plmn) { int i; - for (i = 0; i < _emm_data.n_opnns; i++) { - if (plmn->MCCdigit1 != _emm_data.opnn[i].plmn->MCCdigit1) { + for (i = 0; i < emm_data->n_opnns; i++) { + if (plmn->MCCdigit1 != emm_data->opnn[i].plmn->MCCdigit1) { continue; } - if (plmn->MCCdigit2 != _emm_data.opnn[i].plmn->MCCdigit2) { + if (plmn->MCCdigit2 != emm_data->opnn[i].plmn->MCCdigit2) { continue; } - if (plmn->MCCdigit3 != _emm_data.opnn[i].plmn->MCCdigit3) { + if (plmn->MCCdigit3 != emm_data->opnn[i].plmn->MCCdigit3) { continue; } - if (plmn->MNCdigit1 != _emm_data.opnn[i].plmn->MNCdigit1) { + if (plmn->MNCdigit1 != emm_data->opnn[i].plmn->MNCdigit1) { continue; } - if (plmn->MNCdigit2 != _emm_data.opnn[i].plmn->MNCdigit2) { + if (plmn->MNCdigit2 != emm_data->opnn[i].plmn->MNCdigit2) { continue; } - if (plmn->MNCdigit3 != _emm_data.opnn[i].plmn->MNCdigit3) { + if (plmn->MNCdigit3 != emm_data->opnn[i].plmn->MNCdigit3) { continue; } @@ -1181,22 +1134,23 @@ static int _IldlMode_get_opnn_id(const plmn_t *plmn) ** ** ** Inputs: index: Index of the selected PLMN in the ordered ** ** list of available PLMNs ** - ** Others: _emm_plmn_list.plmn ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ -static int _IdleMode_get_suitable_cell(int index) +static int _IdleMode_get_suitable_cell(nas_user_t *user, int index) { emm_sap_t emm_sap; - const plmn_t *plmn = _emm_plmn_list.plmn[index]; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; + const plmn_t *plmn = emm_plmn_list->plmn[index]; LOG_TRACE(INFO, "EMM-IDLE - Trying to search a suitable cell " "of PLMN %d in %s mode", index, - (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : "Automatic/manual"); /* * Notify EMM-AS SAP that cell information related to the given @@ -1206,12 +1160,12 @@ static int _IdleMode_get_suitable_cell(int index) emm_sap.u.emm_as.u.cell_info.plmnIDs.n_plmns = 1; emm_sap.u.emm_as.u.cell_info.plmnIDs.plmn[0] = *plmn; - if (_emm_data.plmn_rat != NET_ACCESS_UNAVAILABLE) { - emm_sap.u.emm_as.u.cell_info.rat = (1 << _emm_data.plmn_rat); + if (emm_data->plmn_rat != NET_ACCESS_UNAVAILABLE) { + emm_sap.u.emm_as.u.cell_info.rat = (1 << emm_data->plmn_rat); } else { emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE; } - return emm_sap_send(&emm_sap); + return emm_sap_send(user, &emm_sap); } diff --git a/openair3/NAS/UE/EMM/IdleMode.h b/openair3/NAS/UE/EMM/IdleMode.h index f75d149e911c049cab88a17bd7b991c216a2d4f3..e80b4f91344931edd7117917a33ed5d38150f068 100644 --- a/openair3/NAS/UE/EMM/IdleMode.h +++ b/openair3/NAS/UE/EMM/IdleMode.h @@ -41,6 +41,7 @@ Description Defines the functions used to get information from the list #define __IDLEMODE_H__ #include "commonDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -50,7 +51,7 @@ Description Defines the functions used to get information from the list /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ -typedef int (*IdleMode_callback_t) (int); +typedef int (*IdleMode_callback_t) (user_api_id_t *user_api_id, emm_data_t *emm_data, int); /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ @@ -60,23 +61,23 @@ typedef int (*IdleMode_callback_t) (int); /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void IdleMode_initialize(IdleMode_callback_t cb); +void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb); -int IdleMode_get_nb_plmns(void); -int IdleMode_get_hplmn_index(void); -int IdleMode_get_rplmn_index(void); -int IdleMode_get_splmn_index(void); +int IdleMode_get_nb_plmns(emm_plmn_list_t *emm_plmn_list); +int IdleMode_get_hplmn_index(emm_plmn_list_t *emm_plmn_list); +int IdleMode_get_rplmn_index(emm_plmn_list_t *emm_plmn_list); +int IdleMode_get_splmn_index(emm_plmn_list_t *emm_plmn_list); -int IdleMode_update_plmn_list(int index); +int IdleMode_update_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int i); -const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_fullname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len); -const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_shortname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len); -const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len); +const char *IdleMode_get_plmn_id(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len); -int IdleMode_get_plmn_fullname_index(const char *plmn); -int IdleMode_get_plmn_shortname_index(const char *plmn); -int IdleMode_get_plmn_id_index(const char *plmn); +int IdleMode_get_plmn_fullname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn); +int IdleMode_get_plmn_shortname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn); +int IdleMode_get_plmn_id_index(emm_plmn_list_t *emm_plmn_list, const char *plmn); #endif /* __IDLEMODE_H__*/ diff --git a/openair3/NAS/UE/EMM/IdleMode_defs.h b/openair3/NAS/UE/EMM/IdleMode_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..8ef6c8e86d407ec9813537f8c88745438a51fa94 --- /dev/null +++ b/openair3/NAS/UE/EMM/IdleMode_defs.h @@ -0,0 +1,52 @@ +#ifndef _IDLEMODE_DEFS_H +#define _IDLEMODE_DEFS_H + +/* + * A list of PLMN identities in priority order is maintained locally + * to perform the PLMN selection procedure. + * + * In automatic mode of operation, this list is used for PLMN selection when + * the UE is switched on, or upon recovery from lack of coverage, or when the + * user requests the UE to initiate PLMN reselection, and registration. + * In manual mode of operation, this list is displayed to the user that may + * select an available PLMN and initiate registration. + * + * The list may contain PLMN identifiers in the following order: + * - The last registered PLMN or each equivalent PLMN present in the list of + * "equivalent PLMNs" (EPLMN_MAX), when UE is switched on or following + * recovery from lack of coverage; + * - The highest priority PLMN in the list of "equivalent HPLMNs" or the + * HPLMN derived from the IMSI (1) + * - Each PLMN/access technology combination in the "User Controlled PLMN + * Selector with Access Technology" (PLMN_MAX) + * - Each PLMN/access technology combination in the "Operator Controlled PLMN + * Selector with Access Technology" (OPLMN_MAX) + * - Other PLMN/access technology combinations with received high quality + * signal in random order (TODO) + * - Other PLMN/access technology combinations in order of decreasing signal + * quality (TODO) + * - The last selected PLMN again (1) + */ +typedef struct { + int n_plmns; +#define EMM_PLMN_LIST_SIZE (EMM_DATA_EPLMN_MAX + EMM_DATA_PLMN_MAX + \ + EMM_DATA_OPLMN_MAX + 2) + plmn_t *plmn[EMM_PLMN_LIST_SIZE]; + int index; /* Index of the PLMN for which selection is ongoing */ + int hplmn; /* Index of the home PLMN or the highest priority + * equivalent home PLMN */ + int fplmn; /* Index of the first forbidden PLMN */ + int splmn; /* Index of the currently selected PLMN */ + int rplmn; /* Index of the currently registered PLMN */ + struct plmn_param_t { + char fullname[NET_FORMAT_LONG_SIZE+1]; /* PLMN full identifier */ + char shortname[NET_FORMAT_SHORT_SIZE+1]; /* PLMN short identifier */ + char num[NET_FORMAT_NUM_SIZE+1]; /* PLMN numeric identifier */ + int stat; /* Indication of the PLMN availability */ + int tac; /* Location/Tracking Area Code */ + int ci; /* Serving cell identifier */ + int rat; /* Radio Access Technology supported by the serving cell */ + } param[EMM_PLMN_LIST_SIZE]; +} emm_plmn_list_t; + +#endif diff --git a/openair3/NAS/UE/EMM/LowerLayer.c b/openair3/NAS/UE/EMM/LowerLayer.c index f0f7a3c5b6a42d84b1eb6d6d8257d01628e2fb6a..b5555b2c2fa13b68a0180b3ede87474666662869 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.c +++ b/openair3/NAS/UE/EMM/LowerLayer.c @@ -60,17 +60,6 @@ Description Defines EMM procedures executed by the Non-Access Stratum /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -/* - * Data structure used to handle EMM procedures executed by the UE upon - * receiving lower layer notifications - */ -static struct { - lowerlayer_success_callback_t success; /* Successful data delivery */ - lowerlayer_failure_callback_t failure; /* Lower layer failure */ - lowerlayer_release_callback_t release; /* NAS signalling release */ - void *args; /* EMM procedure argument parameters */ -} _lowerlayer_data; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -88,7 +77,6 @@ static struct { ** Description: Notify the EPS Mobility Management entity that data have ** ** been successfully delivered to the network ** ** ** - ** Inputs: ueid: UE lower layer identifier ** ** Others: None ** ** ** ** Outputs: None ** @@ -96,7 +84,7 @@ static struct { ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_success(unsigned int ueid) +int lowerlayer_success(nas_user_t *user) { LOG_FUNC_IN; @@ -104,8 +92,8 @@ int lowerlayer_success(unsigned int ueid) int rc; emm_sap.primitive = EMMREG_LOWERLAYER_SUCCESS; - emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); + emm_sap.u.emm_reg.ueid = user->ueid; + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -117,7 +105,6 @@ int lowerlayer_success(unsigned int ueid) ** Description: Notify the EPS Mobility Management entity that lower la- ** ** yers failed to deliver data to the network ** ** ** - ** Inputs: ueid: UE lower layer identifier ** ** Others: None ** ** ** ** Outputs: None ** @@ -125,7 +112,7 @@ int lowerlayer_success(unsigned int ueid) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_failure(unsigned int ueid) +int lowerlayer_failure(nas_user_t *user) { LOG_FUNC_IN; @@ -133,8 +120,8 @@ int lowerlayer_failure(unsigned int ueid) int rc; emm_sap.primitive = EMMREG_LOWERLAYER_FAILURE; - emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); + emm_sap.u.emm_reg.ueid = user->ueid; + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -155,12 +142,12 @@ int lowerlayer_failure(unsigned int ueid) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_establish(void) +int lowerlayer_establish(nas_user_t *user) { LOG_FUNC_IN; /* Update the EPS Connection Management status */ - _emm_data.ecm_status = ECM_CONNECTED; + user->emm_data->ecm_status = ECM_CONNECTED; LOG_FUNC_RETURN (RETURNok); } @@ -180,7 +167,7 @@ int lowerlayer_establish(void) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_release(int cause) +int lowerlayer_release(nas_user_t *user, int cause) { LOG_FUNC_IN; @@ -188,11 +175,11 @@ int lowerlayer_release(int cause) int rc; /* Update the EPS Connection Management status */ - _emm_data.ecm_status = ECM_IDLE; + user->emm_data->ecm_status = ECM_IDLE; emm_sap.primitive = EMMREG_LOWERLAYER_RELEASE; - emm_sap.u.emm_reg.ueid = 0; - rc = emm_sap_send(&emm_sap); + emm_sap.u.emm_reg.ueid = user->ueid; + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -204,7 +191,6 @@ int lowerlayer_release(int cause) ** Description: Notify the EPS Session Management entity that data have ** ** been received from lower layers ** ** ** - ** Inputs: ueid: UE lower layer identifier ** ** data: Data transfered from lower layers ** ** Others: None ** ** ** @@ -213,7 +199,7 @@ int lowerlayer_release(int cause) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_data_ind(unsigned int ueid, const OctetString *data) +int lowerlayer_data_ind(nas_user_t *user, const OctetString *data) { esm_sap_t esm_sap; int rc; @@ -223,10 +209,10 @@ int lowerlayer_data_ind(unsigned int ueid, const OctetString *data) esm_sap.primitive = ESM_UNITDATA_IND; esm_sap.is_standalone = TRUE; - esm_sap.ueid = ueid; + esm_sap.ueid = user->ueid; esm_sap.recv = data; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); LOG_FUNC_RETURN (rc); } @@ -238,7 +224,6 @@ int lowerlayer_data_ind(unsigned int ueid, const OctetString *data) ** Description: Notify the EPS Mobility Management entity that data have ** ** to be transfered to lower layers ** ** ** - ** Inputs: ueid: UE lower layer identifier ** ** data: Data to be transfered to lower layers ** ** Others: None ** ** ** @@ -247,7 +232,7 @@ int lowerlayer_data_ind(unsigned int ueid, const OctetString *data) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_data_req(unsigned int ueid, const OctetString *data) +int lowerlayer_data_req(nas_user_t *user, const OctetString *data) { LOG_FUNC_IN; @@ -257,16 +242,16 @@ int lowerlayer_data_req(unsigned int ueid, const OctetString *data) //struct emm_data_context_s *ctx = NULL; emm_sap.primitive = EMMAS_DATA_REQ; - emm_sap.u.emm_as.u.data.guti = _emm_data.guti; - emm_sap.u.emm_as.u.data.ueid = 0; - sctx = _emm_data.security; + emm_sap.u.emm_as.u.data.guti = user->emm_data->guti; + emm_sap.u.emm_as.u.data.ueid = user->ueid; + sctx = user->emm_data->security; emm_sap.u.emm_as.u.data.NASinfo = 0; emm_sap.u.emm_as.u.data.NASmsg.length = data->length; emm_sap.u.emm_as.u.data.NASmsg.value = data->value; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, sctx, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -297,17 +282,17 @@ int lowerlayer_data_req(unsigned int ueid, const OctetString *data) ** Others: _lowerlayer_data ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_initialize(lowerlayer_success_callback_t success, +int emm_proc_lowerlayer_initialize(lowerlayer_data_t *lowerlayer_data, lowerlayer_success_callback_t success, lowerlayer_failure_callback_t failure, lowerlayer_release_callback_t release, void *args) { LOG_FUNC_IN; - _lowerlayer_data.success = success; - _lowerlayer_data.failure = failure; - _lowerlayer_data.release = release; - _lowerlayer_data.args = args; + lowerlayer_data->success = success; + lowerlayer_data->failure = failure; + lowerlayer_data->release = release; + lowerlayer_data->args = args; LOG_FUNC_RETURN (RETURNok); } @@ -328,17 +313,17 @@ int emm_proc_lowerlayer_initialize(lowerlayer_success_callback_t success, ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_success(void) +int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data) { LOG_FUNC_IN; int rc = RETURNok; - lowerlayer_success_callback_t emm_callback = _lowerlayer_data.success; + lowerlayer_success_callback_t emm_callback = lowerlayer_data->success; if (emm_callback) { - rc = (*emm_callback)(_lowerlayer_data.args); - _lowerlayer_data.success = NULL; + rc = (*emm_callback)(lowerlayer_data->args); + lowerlayer_data->success = NULL; } LOG_FUNC_RETURN (rc); @@ -360,17 +345,17 @@ int emm_proc_lowerlayer_success(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_failure(int is_initial) +int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, int is_initial) { LOG_FUNC_IN; int rc = RETURNok; - lowerlayer_failure_callback_t emm_callback = _lowerlayer_data.failure; + lowerlayer_failure_callback_t emm_callback = lowerlayer_data->failure; if (emm_callback) { - rc = (*emm_callback)(is_initial, _lowerlayer_data.args); - _lowerlayer_data.failure = NULL; + rc = (*emm_callback)(is_initial, lowerlayer_data->args); + lowerlayer_data->failure = NULL; } LOG_FUNC_RETURN (rc); @@ -391,17 +376,17 @@ int emm_proc_lowerlayer_failure(int is_initial) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_release(void) +int emm_proc_lowerlayer_release(lowerlayer_data_t *lowerlayer_data) { LOG_FUNC_IN; int rc = RETURNok; - lowerlayer_release_callback_t emm_callback = _lowerlayer_data.release; + lowerlayer_release_callback_t emm_callback = lowerlayer_data->release; if (emm_callback) { - rc = (*emm_callback)(_lowerlayer_data.args); - _lowerlayer_data.release = NULL; + rc = (*emm_callback)(lowerlayer_data->args); + lowerlayer_data->release = NULL; } LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/LowerLayer.h b/openair3/NAS/UE/EMM/LowerLayer.h index 396de203d3da340565542069053262d16595d088..00e271feaa7e9c0dd3e3426401b6dd75c589f5e7 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.h +++ b/openair3/NAS/UE/EMM/LowerLayer.h @@ -43,33 +43,17 @@ Description Defines EMM procedures executed by the Non-Access Stratum #define __LOWERLAYER_H__ #include "OctetString.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ -/* - * Type of EMM procedure callback function executed whenever data are - * successfully delivered to the network - */ -typedef int (*lowerlayer_success_callback_t)(void *); - -/* - * Type of EMM procedure callback function executed when data are not - * delivered to the network because a lower layer failure occurred - */ -typedef int (*lowerlayer_failure_callback_t)(int, void *); - -/* - * Type of EMM procedure callback function executed when NAS signalling - * connection is released - */ -typedef int (*lowerlayer_release_callback_t)(void *); - /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ + /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -78,12 +62,26 @@ typedef int (*lowerlayer_release_callback_t)(void *); /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int lowerlayer_success(unsigned int ueid); -int lowerlayer_failure(unsigned int ueid); -int lowerlayer_establish(void); -int lowerlayer_release(int cause); - -int lowerlayer_data_ind(unsigned int ueid, const OctetString *data); -int lowerlayer_data_req(unsigned int ueid, const OctetString *data); +/* + *--------------------------------------------------------------------------- + * Lower layer procedure + *--------------------------------------------------------------------------- + */ +int emm_proc_lowerlayer_initialize(lowerlayer_data_t *lowerlayer_data, lowerlayer_success_callback_t success, + lowerlayer_failure_callback_t failure, + lowerlayer_release_callback_t release, + void *args); +int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data); +int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, int is_initial); +int emm_proc_lowerlayer_release(lowerlayer_data_t *lowerlayer_data); + + +int lowerlayer_success(nas_user_t *user); +int lowerlayer_failure(nas_user_t *user); +int lowerlayer_establish(nas_user_t *user); +int lowerlayer_release(nas_user_t *user, int cause); + +int lowerlayer_data_ind(nas_user_t *user, const OctetString *data); +int lowerlayer_data_req(nas_user_t *user, const OctetString *data); #endif /* __LOWERLAYER_H__*/ diff --git a/openair3/NAS/UE/EMM/LowerLayer_defs.h b/openair3/NAS/UE/EMM/LowerLayer_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..6035d4ed12db9111ef0bd75e7f81a550c4e58018 --- /dev/null +++ b/openair3/NAS/UE/EMM/LowerLayer_defs.h @@ -0,0 +1,33 @@ +#ifndef _LOWER_LAYER_DEFS_H +#define _LOWER_LAYER_DEFS_H + +/* + * Type of EMM procedure callback function executed whenever data are + * successfully delivered to the network + */ +typedef int (*lowerlayer_success_callback_t)(void *); + +/* + * Type of EMM procedure callback function executed when data are not + * delivered to the network because a lower layer failure occurred + */ +typedef int (*lowerlayer_failure_callback_t)(int, void *); + +/* + * Type of EMM procedure callback function executed when NAS signalling + * connection is released + */ +typedef int (*lowerlayer_release_callback_t)(void *); + +/* + * Data structure used to handle EMM procedures executed by the UE upon + * receiving lower layer notifications + */ +typedef struct { + lowerlayer_success_callback_t success; /* Successful data delivery */ + lowerlayer_failure_callback_t failure; /* Lower layer failure */ + lowerlayer_release_callback_t release; /* NAS signalling release */ + void *args; /* EMM procedure argument parameters */ +} lowerlayer_data_t; + +#endif diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c index 801de96145d1ec4ec58271e0a5d13888086ba322..a2a93c4d780a68e36c6b97ee3a7c3eb0ee64d8b5 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c @@ -54,6 +54,7 @@ Description Implements the EPS Mobility Management procedures executed #include "nas_log.h" #include "emm_proc.h" +#include "user_defs.h" #include <assert.h> @@ -86,17 +87,17 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregistered(const emm_reg_t *evt) +int EmmDeregistered(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED); /* Delete the authentication data RAND and RES */ - rc = emm_proc_authentication_delete(); + rc = emm_proc_authentication_delete(user); if (rc != RETURNok) { LOG_FUNC_RETURN (rc); @@ -116,7 +117,7 @@ int EmmDeregistered(const emm_reg_t *evt) /* * The UE was powered on without a valid USIM application present */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_NO_IMSI); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NO_IMSI); break; case _EMMREG_REGISTER_REQ: @@ -124,11 +125,11 @@ int EmmDeregistered(const emm_reg_t *evt) * The default EMM primary substate when the UE is switched on * with valid USIM application shall be PLMN-SEARCH */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* Process the network registration request */ - rc = emm_fsm_process(evt); + rc = emm_fsm_process(user, evt); } break; @@ -142,14 +143,14 @@ int EmmDeregistered(const emm_reg_t *evt) /* Move to the corresponding initial EMM state */ if (evt->u.attach.is_emergency) { - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); } else { - rc = emm_fsm_set_status(EMM_DEREGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NORMAL_SERVICE); } if (rc != RETURNerror) { /* Restart the attach procedure */ - rc = emm_proc_attach_restart(); + rc = emm_proc_attach_restart(user); } break; diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttachNeeded.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttachNeeded.c index 4f8cbc862bbc08ca30733660d13da0cfd77f7a0f..cbdc470a0b844d996fcef9c23626a5543734ec87 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttachNeeded.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttachNeeded.c @@ -47,6 +47,7 @@ Description Implements the EPS Mobility Management procedures executed #include "emm_fsm.h" #include "commonDef.h" #include "nas_log.h" +#include "user_defs.h" #include <assert.h> @@ -77,11 +78,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredAttachNeeded(const emm_reg_t *evt) +int EmmDeregisteredAttachNeeded(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_ATTACH_NEEDED); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_ATTACH_NEEDED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c index ed1d079930a467611dd9420306d366944330d3fc..7ddfac03db225bfc34cb83c093dcff0f121f911d 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c @@ -79,13 +79,13 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredAttemptingToAttach(const emm_reg_t *evt) +int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); switch (evt->primitive) { case _EMMREG_ATTACH_INIT: @@ -97,14 +97,14 @@ int EmmDeregisteredAttemptingToAttach(const emm_reg_t *evt) /* Move to the corresponding initial EMM state */ if (evt->u.attach.is_emergency) { - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); } else { - rc = emm_fsm_set_status(EMM_DEREGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NORMAL_SERVICE); } if (rc != RETURNerror) { /* Restart the attach procedure */ - rc = emm_proc_attach_restart(); + rc = emm_proc_attach_restart(user); } break; @@ -113,14 +113,14 @@ int EmmDeregisteredAttemptingToAttach(const emm_reg_t *evt) /* * Data successfully delivered to the network */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: /* * Data failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c index 220e666aa7d91a35c5417d42b2ac684d714426ab..d18b66a3162bc876043d649d78804973400aab6b 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c @@ -78,13 +78,13 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredInitiated(const emm_reg_t *evt) +int EmmDeregisteredInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_INITIATED); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_INITIATED); switch (evt->primitive) { @@ -94,7 +94,7 @@ int EmmDeregisteredInitiated(const emm_reg_t *evt) * bearer contexts have been deactivated as UE initiated * detach procedure successfully completed) */ - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); break; case _EMMREG_DETACH_FAILED: @@ -103,9 +103,9 @@ int EmmDeregisteredInitiated(const emm_reg_t *evt) * The detach procedure failed */ if (evt->u.detach.type == EMM_DETACH_TYPE_IMSI) { - rc = emm_fsm_set_status(EMM_REGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_REGISTERED_NORMAL_SERVICE); } else { - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); } break; @@ -123,7 +123,8 @@ int EmmDeregisteredInitiated(const emm_reg_t *evt) * Lower layer failure or release of the NAS signalling connection * before the Detach Accept is received */ - rc = emm_proc_lowerlayer_release(); + // FIXME review + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c index 78d418c69c57653b8727693e7e813b9649f182af..394325441597f64991cedf81764e4408caaae0c9 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c @@ -83,24 +83,24 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredLimitedService(const emm_reg_t *evt) +int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_LIMITED_SERVICE); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_LIMITED_SERVICE); switch (evt->primitive) { case _EMMREG_REGISTER_REQ: /* * The user manually re-selected a PLMN to register to */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* Process the network registration request */ - rc = emm_fsm_process(evt); + rc = emm_fsm_process(user, evt); } break; @@ -109,7 +109,7 @@ int EmmDeregisteredLimitedService(const emm_reg_t *evt) /* * Initiate attach procedure for emergency bearer services */ - rc = emm_proc_attach(EMM_ATTACH_TYPE_EMERGENCY); + rc = emm_proc_attach(user, EMM_ATTACH_TYPE_EMERGENCY); break; case _EMMREG_ATTACH_REQ: @@ -118,7 +118,7 @@ int EmmDeregisteredLimitedService(const emm_reg_t *evt) * (Attach Request message successfully delivered to the network); * enter state EMM-REGISTERED-INITIATED */ - rc = emm_fsm_set_status(EMM_REGISTERED_INITIATED); + rc = emm_fsm_set_status(user, EMM_REGISTERED_INITIATED); break; case _EMMREG_LOWERLAYER_SUCCESS: @@ -126,21 +126,21 @@ int EmmDeregisteredLimitedService(const emm_reg_t *evt) * Initial NAS message has been successfully delivered * to the network */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: /* * Initial NAS message failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(TRUE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, TRUE); break; case _EMMREG_LOWERLAYER_RELEASE: /* * NAS signalling connection has been released */ - rc = emm_proc_lowerlayer_release(); + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c index 9f1f526e83f4dff12002c1c8eef0e8b2862c7494..af9ab5e5be773ccd0090a9986d506139bfe365be 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c @@ -84,13 +84,15 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredNoCellAvailable(const emm_reg_t *evt) +int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc = RETURNerror; + emm_data_t *emm_data = user->emm_data; + user_api_id_t *user_api_id = user->user_api_id; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_NO_CELL_AVAILABLE); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_NO_CELL_AVAILABLE); switch (evt->primitive) { /* TODO: network re-selection is not allowed when in No Cell @@ -101,14 +103,14 @@ int EmmDeregisteredNoCellAvailable(const emm_reg_t *evt) /* * The user manually re-selected a PLMN to register to */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* * Notify EMM that the MT is currently searching an operator * to register to */ - rc = emm_proc_registration_notify(NET_REG_STATE_ON); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_ON); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " @@ -118,7 +120,7 @@ int EmmDeregisteredNoCellAvailable(const emm_reg_t *evt) /* * Perform network re-selection procedure */ - rc = emm_proc_plmn_selection(evt->u.regist.index); + rc = emm_proc_plmn_selection(user, evt->u.regist.index); } break; diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoImsi.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoImsi.c index 059c1f551ba6d955cce108f09285172821e9ea59..0f883c8109d3990939b755bdec22698dbe1013d5 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoImsi.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoImsi.c @@ -78,11 +78,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredNoImsi(const emm_reg_t *evt) +int EmmDeregisteredNoImsi(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_NO_IMSI); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_NO_IMSI); LOG_TRACE(ERROR, "EMM-FSM - USIM is not present or not valid"); diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c index 85f98c4bd7b03e40e093b37d3c86827f1c21fe82..3ec7a96ba8ab416ff73ba3f2ac2bfa332a369a70 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c @@ -84,24 +84,24 @@ extern uint8_t usim_test; ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredNormalService(const emm_reg_t *evt) +int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_NORMAL_SERVICE); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_NORMAL_SERVICE); switch (evt->primitive) { case _EMMREG_REGISTER_REQ: /* * The user manually re-selected a PLMN to register to */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* Process the network registration request */ - rc = emm_fsm_process(evt); + rc = emm_fsm_process(user, evt); } break; @@ -112,11 +112,11 @@ int EmmDeregisteredNormalService(const emm_reg_t *evt) */ if(usim_test == 0) { - rc = emm_proc_attach(EMM_ATTACH_TYPE_EPS); + rc = emm_proc_attach(user, EMM_ATTACH_TYPE_EPS); } else { - rc = emm_proc_attach(EMM_ATTACH_TYPE_IMSI); // CMW500 IMSI initial attach expected + rc = emm_proc_attach(user, EMM_ATTACH_TYPE_IMSI); // CMW500 IMSI initial attach expected } break; @@ -126,7 +126,7 @@ int EmmDeregisteredNormalService(const emm_reg_t *evt) * message successfully delivered to the network); * enter state EMM-REGISTERED-INITIATED */ - rc = emm_fsm_set_status(EMM_REGISTERED_INITIATED); + rc = emm_fsm_set_status(user, EMM_REGISTERED_INITIATED); break; case _EMMREG_LOWERLAYER_SUCCESS: @@ -134,21 +134,21 @@ int EmmDeregisteredNormalService(const emm_reg_t *evt) * Initial NAS message has been successfully delivered * to the network */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: /* * Initial NAS message failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(TRUE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, TRUE); break; case _EMMREG_LOWERLAYER_RELEASE: /* * NAS signalling connection has been released */ - rc = emm_proc_lowerlayer_release(); + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; case _EMMREG_ATTACH_CNF: @@ -157,7 +157,7 @@ int EmmDeregisteredNormalService(const emm_reg_t *evt) * context activated; * enter state EMM-REGISTERED. */ - rc = emm_fsm_set_status(EMM_REGISTERED); + rc = emm_fsm_set_status(user, EMM_REGISTERED); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c index d9865c9b720bf53334fa486b7eedf135c2966a0c..ed41362f2f900563e5776fe2847408cab369b93b 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c @@ -82,27 +82,29 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredPlmnSearch(const emm_reg_t *evt) +int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; + emm_data_t *emm_data = user->emm_data; + user_api_id_t *user_api_id = user->user_api_id; int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_PLMN_SEARCH); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_PLMN_SEARCH); switch (evt->primitive) { case _EMMREG_NO_CELL: /* * No suitable cell of the selected PLMN has been found to camp on */ - rc = emm_proc_registration_notify(NET_REG_STATE_DENIED); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_DENIED); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " "Failed to notify registration update"); } - rc = emm_fsm_set_status(EMM_DEREGISTERED_NO_CELL_AVAILABLE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NO_CELL_AVAILABLE); break; case _EMMREG_REGISTER_REQ: @@ -112,7 +114,7 @@ int EmmDeregisteredPlmnSearch(const emm_reg_t *evt) * may be selected either automatically or manually. * Or the user manually re-selected a PLMN to register to. */ - rc = emm_proc_registration_notify(NET_REG_STATE_ON); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_ON); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " @@ -122,7 +124,7 @@ int EmmDeregisteredPlmnSearch(const emm_reg_t *evt) /* * Perform network selection procedure */ - rc = emm_proc_plmn_selection(evt->u.regist.index); + rc = emm_proc_plmn_selection(user, evt->u.regist.index); break; case _EMMREG_REGISTER_REJ: @@ -130,14 +132,14 @@ int EmmDeregisteredPlmnSearch(const emm_reg_t *evt) * The selected cell is known not to be able to provide normal * service */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); break; case _EMMREG_REGISTER_CNF: /* * A suitable cell of the selected PLMN has been found to camp on */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NORMAL_SERVICE); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmNull.c b/openair3/NAS/UE/EMM/SAP/EmmNull.c index e482281a7184974a9604ec7a0f42d85912eb57dc..7b553f0a765474bc97e405d6c5d591874cdf0a2e 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmNull.c +++ b/openair3/NAS/UE/EMM/SAP/EmmNull.c @@ -46,6 +46,7 @@ Description Implements the EPS Mobility Management procedures executed #include "nas_log.h" #include "emm_proc.h" +#include "user_defs.h" #include <assert.h> @@ -76,16 +77,16 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmNull(const emm_reg_t *evt) +int EmmNull(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc; - assert(emm_fsm_get_status() == EMM_NULL); + assert(emm_fsm_get_status(user) == EMM_NULL); /* Delete the authentication data RAND and RES */ - rc = emm_proc_authentication_delete(); + rc = emm_proc_authentication_delete(user); if (rc != RETURNok) { LOG_FUNC_RETURN (rc); @@ -97,14 +98,14 @@ int EmmNull(const emm_reg_t *evt) * The EPS capability has been enabled in the UE: * Move to the DEREGISTERED state; */ - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); /* * And initialize the EMM procedure call manager in order to * establish an EMM context and make the UE reachable by an MME. */ if (rc != RETURNerror) { - rc = emm_proc_initialize(); + rc = emm_proc_initialize(user); } break; diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c index dcbeee167eb8c3cabaec7fa3c15b369e7905df46..dbc51e51554382af949dee6bd1c6116e334d5186 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c @@ -81,13 +81,13 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegistered(const emm_reg_t *evt) +int EmmRegistered(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_REGISTERED); + assert(emm_fsm_get_status(user) == EMM_REGISTERED); switch (evt->primitive) { @@ -96,7 +96,7 @@ int EmmRegistered(const emm_reg_t *evt) /* * Initiate detach procedure for EPS services */ - rc = emm_proc_detach(EMM_DETACH_TYPE_EPS, evt->u.detach.switch_off); + rc = emm_proc_detach(user, EMM_DETACH_TYPE_EPS, evt->u.detach.switch_off); break; case _EMMREG_DETACH_REQ: @@ -105,7 +105,7 @@ int EmmRegistered(const emm_reg_t *evt) * message successfully delivered to the network); * enter state EMM-DEREGISTERED-INITIATED */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_INITIATED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_INITIATED); break; case _EMMREG_DETACH_CNF: @@ -113,7 +113,7 @@ int EmmRegistered(const emm_reg_t *evt) * The UE implicitly detached from the network (all EPS * bearer contexts may have been deactivated) */ - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); break; case _EMMREG_TAU_REQ: @@ -136,21 +136,21 @@ int EmmRegistered(const emm_reg_t *evt) /* * Data transfer message has been successfully delivered */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: /* * Data transfer message failed to be delivered */ - rc = emm_proc_lowerlayer_failure(FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); break; case _EMMREG_LOWERLAYER_RELEASE: /* * NAS signalling connection has been released */ - rc = emm_proc_lowerlayer_release(); + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c index 59d8f45df9a195a37f35115e5cfef6bac5fe05bd..21654123d1462e3deeba854f5790acc9398e68a4 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c @@ -78,11 +78,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredAttemptingToUpdate(const emm_reg_t *evt) +int EmmRegisteredAttemptingToUpdate(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_ATTEMPTING_TO_UPDATE); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_ATTEMPTING_TO_UPDATE); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c index c522d5ec5cc0c84e31aba3b8c66bd74f2129e378..6855843a25bbe01ba70e58913ada26d0d12983d1 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c @@ -78,11 +78,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredImsiDetachInitiated(const emm_reg_t *evt) +int EmmRegisteredImsiDetachInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_IMSI_DETACH_INITIATED); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_IMSI_DETACH_INITIATED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c index 688b168b5318025aac0b049c7f825731c4bce5c0..d10f0d1053c0c939408600b85fc8c5a2424ce0dc 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c @@ -78,13 +78,15 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredInitiated(const emm_reg_t *evt) +int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc = RETURNerror; + emm_data_t *emm_data = user->emm_data; + user_api_id_t *user_api_id = user->user_api_id; - assert(emm_fsm_get_status() == EMM_REGISTERED_INITIATED); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_INITIATED); switch (evt->primitive) { case _EMMREG_ATTACH_INIT: @@ -96,14 +98,14 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) /* Move to the corresponding initial EMM state */ if (evt->u.attach.is_emergency) { - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); } else { - rc = emm_fsm_set_status(EMM_DEREGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NORMAL_SERVICE); } if (rc != RETURNerror) { /* Restart the attach procedure */ - rc = emm_proc_attach_restart(); + rc = emm_proc_attach_restart(user); } break; @@ -114,7 +116,7 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) * timer T3410 expired). The network attach procedure shall be * restarted when timer T3411 expires. */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); break; case _EMMREG_ATTACH_EXCEEDED: @@ -126,7 +128,7 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) * SEARCH in order to perform a PLMN selection. */ /* TODO: ATTEMPTING-TO-ATTACH or PLMN-SEARCH ??? */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); break; case _EMMREG_ATTACH_CNF: @@ -134,13 +136,13 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) * EPS network attach accepted by the network; * enter state EMM-REGISTERED. */ - rc = emm_fsm_set_status(EMM_REGISTERED); + rc = emm_fsm_set_status(user, EMM_REGISTERED); if (rc != RETURNerror) { /* * Notify EMM that the MT is registered */ - rc = emm_proc_registration_notify(NET_REG_STATE_HN); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_HN); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " @@ -161,13 +163,13 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) * EPS network attach rejected by the network; * enter state EMM-DEREGISTERED. */ - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); if (rc != RETURNerror) { /* * Notify EMM that the MT's registration is denied */ - rc = emm_proc_registration_notify(NET_REG_STATE_DENIED); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_DENIED); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " @@ -181,11 +183,11 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) /* * The UE has to select a new PLMN to register to */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* Process the network registration request */ - rc = emm_fsm_process(evt); + rc = emm_fsm_process(user, evt); } break; @@ -194,7 +196,7 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) /* * The UE failed to register to the network for normal EPS service */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); break; case _EMMREG_NO_IMSI: @@ -202,14 +204,14 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) * The UE failed to register to the network for emergency * bearer services */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_NO_IMSI); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NO_IMSI); break; case _EMMREG_DETACH_INIT: /* * Initiate detach procedure for EPS services */ - rc = emm_proc_detach(EMM_DETACH_TYPE_EPS, evt->u.detach.switch_off); + rc = emm_proc_detach(user, EMM_DETACH_TYPE_EPS, evt->u.detach.switch_off); break; case _EMMREG_DETACH_REQ: @@ -218,7 +220,7 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) * message successfully delivered to the network); * enter state EMM-DEREGISTERED-INITIATED */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_INITIATED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_INITIATED); break; case _EMMREG_LOWERLAYER_SUCCESS: @@ -228,7 +230,7 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) * any message transfered by EMM common procedures requested * by the network. */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: @@ -238,7 +240,7 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) * any message transfered by EMM common procedures requested * by the network. */ - rc = emm_proc_lowerlayer_failure(FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); break; case _EMMREG_LOWERLAYER_RELEASE: @@ -247,7 +249,7 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) * Accept, Attach Reject, or any message transfered by EMM common * procedures requested by the network, is received. */ - rc = emm_proc_lowerlayer_release(); + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredLimitedService.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredLimitedService.c index 280252b8ed671eb1f827d04306dd40a16a08b0b9..b4ea68f689573330e45d844b076f180e2c92f0e8 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredLimitedService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredLimitedService.c @@ -74,11 +74,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredLimitedService(const emm_reg_t *evt) +int EmmRegisteredLimitedService(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_LIMITED_SERVICE); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_LIMITED_SERVICE); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredNoCellAvailable.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredNoCellAvailable.c index a22f3d76c6bbb4483f1254c74f8c7b112838d04c..0328ae81920f9eece5dddc709d377351222b09a9 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredNoCellAvailable.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredNoCellAvailable.c @@ -75,11 +75,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredNoCellAvailable(const emm_reg_t *evt) +int EmmRegisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_NO_CELL_AVAILABLE); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_NO_CELL_AVAILABLE); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredNormalService.c index bc25a1e4be693ac17211e1c9e9c38d66437084d6..8b1c8721f2d6f091645c0db14a19d22611e5b0f9 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredNormalService.c @@ -74,11 +74,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredNormalService(const emm_reg_t *evt) +int EmmRegisteredNormalService(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_NORMAL_SERVICE); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_NORMAL_SERVICE); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredPlmnSearch.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredPlmnSearch.c index 453e39558efc67646f330f6fc017f21ed971a7af..8ee92c4454cce5d18301cb6dbced9b0d8a7aab32 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredPlmnSearch.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredPlmnSearch.c @@ -74,46 +74,13 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredPlmnSearch(const emm_reg_t *evt) +int EmmRegisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_PLMN_SEARCH); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_PLMN_SEARCH); /* TODO */ LOG_FUNC_RETURN (RETURNok); } - -#if 0 -/**************************************************************************** - ** ** - ** Name: EmmRegisteredPlmnSearch_xxx() ** - ** ** - ** Description: Procedure executed when xxx ** - ** while the EMM-SAP is in EMM-REGISTERED.PLMN-SEARCH state. ** - ** ** - ** Inputs: evt: The received EMM-SAP event ** - ** Others: emm_fsm_status ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: emm_fsm_status ** - ** ** - ***************************************************************************/ -int EmmRegisteredPlmnSearch_xxx(const emm_reg_t *evt) -{ - LOG_FUNC_IN; - - assert(emm_fsm_get_status() == EMM_REGISTERED_PLMN_SEARCH); - - /* TODO */ - - LOG_FUNC_RETURN (RETURNok); -} -#endif - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredUpdateNeeded.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredUpdateNeeded.c index 36f35fe351bdaa337e3152cd3d6baefca408bf4f..2a81b488dce0dd9ce5d71ff3609d392a0b2ae413 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredUpdateNeeded.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredUpdateNeeded.c @@ -80,11 +80,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredUpdateNeeded(const emm_reg_t *evt) +int EmmRegisteredUpdateNeeded(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_UPDATE_NEEDED); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_UPDATE_NEEDED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmServiceRequestInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmServiceRequestInitiated.c index a72b2d6003e35431e9df061d79f1cf1362bf9250..b556efb7f44fa02ef98c75eeb0b13b8620b6ada7 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmServiceRequestInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmServiceRequestInitiated.c @@ -76,11 +76,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmServiceRequestInitiated(const emm_reg_t *evt) +int EmmServiceRequestInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_SERVICE_REQUEST_INITIATED); + assert(emm_fsm_get_status(user) == EMM_SERVICE_REQUEST_INITIATED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c index 69699cc117b5c86ef9b4df37ae08a2b931b3b18d..91bb660ee121f4b328a3d38a04d2590910e13244 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c @@ -76,11 +76,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmTrackingAreaUpdatingInitiated(const emm_reg_t *evt) +int EmmTrackingAreaUpdatingInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_TRACKING_AREA_UPDATING_INITIATED); + assert(emm_fsm_get_status(user) == EMM_TRACKING_AREA_UPDATING_INITIATED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 7650f97ee88d0e43911a3adefe67594da0606e5a..d833b5bba08178921e45151d3e2114c096d1bb06 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -53,6 +53,8 @@ Description Defines the EMMAS Service Access Point that provides #include "emm_cause.h" #include "LowerLayer.h" +#include "emm_proc.h" + #include <string.h> // memset #include <stdlib.h> // malloc, free @@ -65,10 +67,6 @@ Description Defines the EMMAS Service Access Point that provides /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -extern int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat); - -extern int emm_proc_status(unsigned int ueid, int emm_cause); - /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -99,19 +97,19 @@ static const char *_emm_as_primitive_str[] = { * Functions executed to process EMM procedures upon receiving * data from the network */ -static int _emm_as_recv(unsigned int ueid, const char *msg, int len, +static int _emm_as_recv(nas_user_t *user, const char *msg, int len, int *emm_cause); -static int _emm_as_establish_cnf(const emm_as_establish_t *msg, int *emm_cause); -static int _emm_as_establish_rej(void); -static int _emm_as_release_ind(const emm_as_release_t *msg); +static int _emm_as_establish_cnf(nas_user_t *user, const emm_as_establish_t *msg, int *emm_cause); +static int _emm_as_establish_rej(nas_user_t *user); +static int _emm_as_release_ind(nas_user_t *user, const emm_as_release_t *msg); static int _emm_as_page_ind(const emm_as_page_t *msg); -static int _emm_as_cell_info_res(const emm_as_cell_info_t *msg); +static int _emm_as_cell_info_res(nas_user_t *user, const emm_as_cell_info_t *msg); static int _emm_as_cell_info_ind(const emm_as_cell_info_t *msg); -static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause); +static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm_cause); /* * Functions executed to send data to the network when requested @@ -133,18 +131,18 @@ static int _emm_as_encrypt( int length, emm_security_context_t *emm_security_context); -static int _emm_as_send(const emm_as_t *msg); +static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg); -static int _emm_as_security_res(const emm_as_security_t *, +static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *, ul_info_transfer_req_t *); -static int _emm_as_establish_req(const emm_as_establish_t *, +static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *, nas_establish_req_t *); static int _emm_as_cell_info_req(const emm_as_cell_info_t *, cell_info_req_t *); -static int _emm_as_data_req(const emm_as_data_t *, ul_info_transfer_req_t *); -static int _emm_as_status_ind(const emm_as_status_t *, ul_info_transfer_req_t *); +static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, ul_info_transfer_req_t *); +static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *, ul_info_transfer_req_t *); static int _emm_as_release_req(const emm_as_release_t *, nas_release_req_t *); /****************************************************************************/ @@ -165,7 +163,7 @@ static int _emm_as_release_req(const emm_as_release_t *, nas_release_req_t *); ** Others: NONE ** ** ** ***************************************************************************/ -void emm_as_initialize(void) +void emm_as_initialize(nas_user_t *user) { LOG_FUNC_IN; @@ -188,7 +186,7 @@ void emm_as_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_as_send(const emm_as_t *msg) +int emm_as_send(nas_user_t *user, const emm_as_t *msg) { LOG_FUNC_IN; @@ -196,28 +194,25 @@ int emm_as_send(const emm_as_t *msg) int emm_cause = EMM_CAUSE_SUCCESS; emm_as_primitive_t primitive = msg->primitive; - uint32_t ueid = 0; - LOG_TRACE(INFO, "EMMAS-SAP - Received primitive %s (%d)", _emm_as_primitive_str[primitive - _EMMAS_START - 1], primitive); switch (primitive) { case _EMMAS_DATA_IND: - rc = _emm_as_data_ind(&msg->u.data, &emm_cause); - ueid = msg->u.data.ueid; + rc = _emm_as_data_ind(user, &msg->u.data, &emm_cause); break; case _EMMAS_ESTABLISH_CNF: - rc = _emm_as_establish_cnf(&msg->u.establish, &emm_cause); + rc = _emm_as_establish_cnf(user, &msg->u.establish, &emm_cause); break; case _EMMAS_ESTABLISH_REJ: - rc = _emm_as_establish_rej(); + rc = _emm_as_establish_rej(user); break; case _EMMAS_RELEASE_IND: - rc = _emm_as_release_ind(&msg->u.release); + rc = _emm_as_release_ind(user, &msg->u.release); break; case _EMMAS_PAGE_IND: @@ -225,7 +220,7 @@ int emm_as_send(const emm_as_t *msg) break; case _EMMAS_CELL_INFO_RES: - rc = _emm_as_cell_info_res(&msg->u.cell_info); + rc = _emm_as_cell_info_res(user, &msg->u.cell_info); break; case _EMMAS_CELL_INFO_IND: @@ -234,7 +229,7 @@ int emm_as_send(const emm_as_t *msg) default: /* Other primitives are forwarded to the Access Stratum */ - rc = _emm_as_send(msg); + rc = _emm_as_send(user, msg); if (rc != RETURNok) { LOG_TRACE(ERROR, "EMMAS-SAP - " @@ -266,7 +261,7 @@ int emm_as_send(const emm_as_t *msg) LOG_TRACE(WARNING, "EMMAS-SAP - Received EMM message is not valid " "(cause=%d)", emm_cause); /* Return an EMM status message */ - rc = emm_proc_status(ueid, emm_cause); + rc = emm_proc_status(user, emm_cause); } if (rc != RETURNok) { @@ -306,7 +301,7 @@ int emm_as_send(const emm_as_t *msg) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_recv(unsigned int ueid, const char *msg, int len, +static int _emm_as_recv(nas_user_t *user, const char *msg, int len, int *emm_cause) { LOG_FUNC_IN; @@ -321,7 +316,7 @@ static int _emm_as_recv(unsigned int ueid, const char *msg, int len, emm_security_context_t *security = NULL; /* Current EPS NAS security context */ - security = _emm_data.security; + security = user->emm_data->security; /* Decode the received message */ decoder_rc = nas_message_decode(msg, &nas_msg, len, security); @@ -338,34 +333,34 @@ static int _emm_as_recv(unsigned int ueid, const char *msg, int len, switch (emm_msg->header.message_type) { case EMM_STATUS: - rc = emm_recv_status(ueid, &emm_msg->emm_status, emm_cause); + rc = emm_recv_status(user->ueid, &emm_msg->emm_status, emm_cause); break; case IDENTITY_REQUEST: - rc = emm_recv_identity_request(&emm_msg->identity_request, + rc = emm_recv_identity_request(user, &emm_msg->identity_request, emm_cause); break; case AUTHENTICATION_REQUEST: - rc = emm_recv_authentication_request( + rc = emm_recv_authentication_request(user, &emm_msg->authentication_request, emm_cause); break; case AUTHENTICATION_REJECT: - rc = emm_recv_authentication_reject( + rc = emm_recv_authentication_reject(user, &emm_msg->authentication_reject, emm_cause); break; case SECURITY_MODE_COMMAND: - rc = emm_recv_security_mode_command( + rc = emm_recv_security_mode_command(user, &emm_msg->security_mode_command, emm_cause); break; case DETACH_ACCEPT: - rc = emm_recv_detach_accept(&emm_msg->detach_accept, emm_cause); + rc = emm_recv_detach_accept(user, &emm_msg->detach_accept, emm_cause); break; @@ -406,7 +401,7 @@ static int _emm_as_recv(unsigned int ueid, const char *msg, int len, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause) +static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm_cause) { LOG_FUNC_IN; @@ -428,7 +423,7 @@ static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause) memset(&header, 0, sizeof(header)); /* Decrypt the received security protected message */ - security = _emm_data.security; + security = user->emm_data->security; int bytes = nas_message_decrypt((char *)(msg->NASmsg.value), plain_msg, &header, @@ -443,23 +438,23 @@ static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause) } else if (header.protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) { /* Process EMM data */ - rc = _emm_as_recv(msg->ueid, plain_msg, bytes, emm_cause); + rc = _emm_as_recv(user, plain_msg, bytes, emm_cause); } else if (header.protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) { const OctetString data = {bytes, (uint8_t *)plain_msg}; /* Foward ESM data to EPS session management */ - rc = lowerlayer_data_ind(msg->ueid, &data); + rc = lowerlayer_data_ind(user, &data); } free(plain_msg); } } else { /* Process successfull lower layer transfer indication */ - rc = lowerlayer_success(msg->ueid); + rc = lowerlayer_success(user); } } else { /* Process lower layer transmission failure of NAS message */ - rc = lowerlayer_failure(msg->ueid); + rc = lowerlayer_failure(user); } LOG_FUNC_RETURN (rc); @@ -482,7 +477,7 @@ static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_establish_cnf(const emm_as_establish_t *msg, +static int _emm_as_establish_cnf(nas_user_t *user, const emm_as_establish_t *msg, int *emm_cause) { LOG_FUNC_IN; @@ -494,11 +489,11 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, if (msg->NASmsg.length > 0) { /* The NAS signalling connection is established */ - (void) lowerlayer_establish(); + (void) lowerlayer_establish(user); } else { /* The initial NAS message has been successfully delivered to * lower layers */ - rc = lowerlayer_success(0); + rc = lowerlayer_success(user); LOG_FUNC_RETURN (rc); } @@ -509,7 +504,7 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, decoder_rc = nas_message_decode((char *)(msg->NASmsg.value), &nas_msg, msg->NASmsg.length, - _emm_data.security); + user->emm_data->security); if (decoder_rc < 0) { LOG_TRACE(WARNING, "EMMAS-SAP - Failed to decode initial NAS message" @@ -523,11 +518,11 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, switch (emm_msg->header.message_type) { case ATTACH_ACCEPT: - rc = emm_recv_attach_accept(&emm_msg->attach_accept, emm_cause); + rc = emm_recv_attach_accept(user, &emm_msg->attach_accept, emm_cause); break; case ATTACH_REJECT: - rc = emm_recv_attach_reject(&emm_msg->attach_reject, emm_cause); + rc = emm_recv_attach_reject(user, &emm_msg->attach_reject, emm_cause); break; case DETACH_ACCEPT: @@ -563,7 +558,7 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_establish_rej(void) +static int _emm_as_establish_rej(nas_user_t *user) { LOG_FUNC_IN; @@ -573,7 +568,7 @@ static int _emm_as_establish_rej(void) "failure"); /* Process lower layer transmission failure of initial NAS message */ - rc = lowerlayer_failure(0); + rc = lowerlayer_failure(user); LOG_FUNC_RETURN (rc); } @@ -595,7 +590,7 @@ static int _emm_as_establish_rej(void) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_release_ind(const emm_as_release_t *msg) +static int _emm_as_release_ind(nas_user_t *user, const emm_as_release_t *msg) { LOG_FUNC_IN; @@ -605,7 +600,7 @@ static int _emm_as_release_ind(const emm_as_release_t *msg) "(cause=%d)", msg->cause); /* Process NAS signalling connection release indication */ - rc = lowerlayer_release(msg->cause); + rc = lowerlayer_release(user, msg->cause); LOG_FUNC_RETURN (rc); } @@ -663,7 +658,7 @@ static int _emm_as_page_ind(const emm_as_page_t *msg) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_cell_info_res(const emm_as_cell_info_t *msg) +static int _emm_as_cell_info_res(nas_user_t *user, const emm_as_cell_info_t *msg) { LOG_FUNC_IN; @@ -685,7 +680,7 @@ static int _emm_as_cell_info_res(const emm_as_cell_info_t *msg) } /* Notify EMM that a cell has been found */ - rc = emm_proc_plmn_selection_end(msg->found, msg->tac, msg->cellID, AcT); + rc = emm_proc_plmn_selection_end(user, msg->found, msg->tac, msg->cellID, AcT); LOG_FUNC_RETURN (rc); } @@ -928,7 +923,7 @@ _emm_as_encrypt( ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_send(const emm_as_t *msg) +static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) { LOG_FUNC_IN; @@ -937,13 +932,13 @@ static int _emm_as_send(const emm_as_t *msg) switch (msg->primitive) { case _EMMAS_DATA_REQ: - as_msg.msgID = _emm_as_data_req( + as_msg.msgID = _emm_as_data_req(user->emm_data, &msg->u.data, &as_msg.msg.ul_info_transfer_req); break; case _EMMAS_STATUS_IND: - as_msg.msgID = _emm_as_status_ind( + as_msg.msgID = _emm_as_status_ind(user->emm_data, &msg->u.status, &as_msg.msg.ul_info_transfer_req); break; @@ -956,13 +951,13 @@ static int _emm_as_send(const emm_as_t *msg) case _EMMAS_SECURITY_RES: - as_msg.msgID = _emm_as_security_res( + as_msg.msgID = _emm_as_security_res(user->emm_data, &msg->u.security, &as_msg.msg.ul_info_transfer_req); break; case _EMMAS_ESTABLISH_REQ: - as_msg.msgID = _emm_as_establish_req( + as_msg.msgID = _emm_as_establish_req(user->emm_data, &msg->u.establish, &as_msg.msg.nas_establish_req); break; @@ -996,7 +991,8 @@ static int _emm_as_send(const emm_as_t *msg) case AS_CELL_INFO_REQ: { nas_itti_cell_info_req( as_msg.msg.cell_info_req.plmnID, - as_msg.msg.cell_info_req.rat); + as_msg.msg.cell_info_req.rat, + user->ueid); LOG_FUNC_RETURN (RETURNok); } break; @@ -1008,7 +1004,8 @@ static int _emm_as_send(const emm_as_t *msg) as_msg.msg.nas_establish_req.s_tmsi, as_msg.msg.nas_establish_req.plmnID, as_msg.msg.nas_establish_req.initialNasMsg.data, - as_msg.msg.nas_establish_req.initialNasMsg.length); + as_msg.msg.nas_establish_req.initialNasMsg.length, + user->ueid); LOG_FUNC_RETURN (RETURNok); } break; @@ -1017,7 +1014,8 @@ static int _emm_as_send(const emm_as_t *msg) nas_itti_ul_data_req( as_msg.msg.ul_info_transfer_req.UEid, as_msg.msg.ul_info_transfer_req.nasMsg.data, - as_msg.msg.ul_info_transfer_req.nasMsg.length); + as_msg.msg.ul_info_transfer_req.nasMsg.length, + user->ueid); LOG_FUNC_RETURN (RETURNok); } break; @@ -1026,7 +1024,8 @@ static int _emm_as_send(const emm_as_t *msg) nas_itti_rab_establish_rsp( as_msg.msg.rab_establish_rsp.s_tmsi, as_msg.msg.rab_establish_rsp.rabID, - as_msg.msg.rab_establish_rsp.errCode); + as_msg.msg.rab_establish_rsp.errCode, + user->ueid); LOG_FUNC_RETURN (RETURNok); } break; @@ -1065,7 +1064,7 @@ static int _emm_as_send(const emm_as_t *msg) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_data_req(const emm_as_data_t *msg, +static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, ul_info_transfer_req_t *as_msg) { LOG_FUNC_IN; @@ -1112,7 +1111,7 @@ static int _emm_as_data_req(const emm_as_data_t *msg, int bytes; emm_security_context_t *emm_security_context = NULL; - emm_security_context = _emm_data.security; + emm_security_context = emm_data->security; if (emm_security_context) { @@ -1161,7 +1160,7 @@ static int _emm_as_data_req(const emm_as_data_t *msg, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_status_ind(const emm_as_status_t *msg, +static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *msg, ul_info_transfer_req_t *as_msg) { LOG_FUNC_IN; @@ -1193,7 +1192,7 @@ static int _emm_as_status_ind(const emm_as_status_t *msg, if (size > 0) { emm_security_context_t *emm_security_context = NULL; - emm_security_context = _emm_data.security; + emm_security_context = emm_data->security; if (emm_security_context) { @@ -1275,7 +1274,7 @@ static int _emm_as_release_req(const emm_as_release_t *msg, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_security_res(const emm_as_security_t *msg, +static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *msg, ul_info_transfer_req_t *as_msg) { LOG_FUNC_IN; @@ -1340,7 +1339,7 @@ static int _emm_as_security_res(const emm_as_security_t *msg, int bytes = _emm_as_encode(&as_msg->nasMsg, &nas_msg, size, - _emm_data.security); + emm_data->security); if (bytes > 0) { LOG_FUNC_RETURN (AS_UL_INFO_TRANSFER_REQ); @@ -1369,7 +1368,7 @@ static int _emm_as_security_res(const emm_as_security_t *msg, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_establish_req(const emm_as_establish_t *msg, +static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *msg, nas_establish_req_t *as_msg) { LOG_FUNC_IN; @@ -1433,7 +1432,7 @@ static int _emm_as_establish_req(const emm_as_establish_t *msg, &as_msg->initialNasMsg, &nas_msg, size, - _emm_data.security); + emm_data->security); if (bytes > 0) { LOG_FUNC_RETURN (AS_NAS_ESTABLISH_REQ); diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.h b/openair3/NAS/UE/EMM/SAP/emm_as.h index 04a14cf3cb26f84cd681315bd76e4d3370e9fcc7..726a363d75c859d4ae8381a44e00c29b951f23e3 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.h +++ b/openair3/NAS/UE/EMM/SAP/emm_as.h @@ -41,6 +41,7 @@ Description Defines the EMMAS Service Access Point that provides #define __EMM_AS_H__ #include "emm_asDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -58,8 +59,8 @@ Description Defines the EMMAS Service Access Point that provides /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_as_initialize(void); +void emm_as_initialize(nas_user_t *user); -int emm_as_send(const emm_as_t *msg); +int emm_as_send(nas_user_t *user, const emm_as_t *msg); #endif /* __EMM_AS_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_esm.c b/openair3/NAS/UE/EMM/SAP/emm_esm.c index a12d71d79beca3d6458aaadf49998dcbe213de83..798e682b112c09f7d54ccebcb4b7dc6fec0492a9 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_esm.c +++ b/openair3/NAS/UE/EMM/SAP/emm_esm.c @@ -108,7 +108,7 @@ void emm_esm_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_esm_send(const emm_esm_t *msg) +int emm_esm_send(nas_user_t *user, const emm_esm_t *msg) { LOG_FUNC_IN; @@ -123,7 +123,7 @@ int emm_esm_send(const emm_esm_t *msg) case _EMMESM_ESTABLISH_REQ: /* ESM requests EMM to initiate an attach procedure before * requesting subsequent connectivity to additional PDNs */ - rc = emm_proc_attach_restart(); + rc = emm_proc_attach_restart(user); break; case _EMMESM_ESTABLISH_CNF: @@ -134,11 +134,11 @@ int emm_esm_send(const emm_esm_t *msg) if (msg->u.establish.is_emergency) { /* Consider the UE attached for emergency bearer services * only */ - rc = emm_proc_attach_set_emergency(); + rc = emm_proc_attach_set_emergency(user->emm_data); } } else { /* Consider the UE locally detached from the network */ - rc = emm_proc_attach_set_detach(); + rc = emm_proc_attach_set_detach(user); } break; @@ -149,7 +149,7 @@ int emm_esm_send(const emm_esm_t *msg) case _EMMESM_UNITDATA_REQ: /* ESM requests EMM to transfer ESM data unit to lower layer */ - rc = lowerlayer_data_req(msg->ueid, &msg->u.data.msg); + rc = lowerlayer_data_req(user, &msg->u.data.msg); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/emm_esm.h b/openair3/NAS/UE/EMM/SAP/emm_esm.h index 7a763d4759a3788c5f5808b130e89012fdd6ca70..11aa42213f8f7681e9399104db26980741339149 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_esm.h +++ b/openair3/NAS/UE/EMM/SAP/emm_esm.h @@ -42,6 +42,7 @@ Description Defines the EMMESM Service Access Point that provides #define __EMM_ESM_H__ #include "emm_esmDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -61,6 +62,6 @@ Description Defines the EMMESM Service Access Point that provides void emm_esm_initialize(void); -int emm_esm_send(const emm_esm_t *msg); +int emm_esm_send(nas_user_t *user, const emm_esm_t *msg); #endif /* __EMM_ESM_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_fsm.c b/openair3/NAS/UE/EMM/SAP/emm_fsm.c index a76b101119b11e0551235fa99f115f1420a87fcb..be1517a7ccd21d4c051394ef0be29adac95658fa 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_fsm.c +++ b/openair3/NAS/UE/EMM/SAP/emm_fsm.c @@ -43,6 +43,7 @@ Description Defines the EPS Mobility Management procedures executed at #include "nas_log.h" #include "emmData.h" +#include "user_defs.h" @@ -127,30 +128,30 @@ static const char *_emm_fsm_status_str[EMM_STATE_MAX] = { */ /* Type of the EPS Mobility Management state machine handler */ -typedef int(*emm_fsm_handler_t)(const emm_reg_t *); - -int EmmNull(const emm_reg_t *); -int EmmDeregistered(const emm_reg_t *); -int EmmRegistered(const emm_reg_t *); -int EmmDeregisteredInitiated(const emm_reg_t *); -int EmmDeregisteredNormalService(const emm_reg_t *); -int EmmDeregisteredLimitedService(const emm_reg_t *); -int EmmDeregisteredAttemptingToAttach(const emm_reg_t *); -int EmmDeregisteredPlmnSearch(const emm_reg_t *); -int EmmDeregisteredNoImsi(const emm_reg_t *); -int EmmDeregisteredAttachNeeded(const emm_reg_t *); -int EmmDeregisteredNoCellAvailable(const emm_reg_t *); -int EmmRegisteredInitiated(const emm_reg_t *); -int EmmRegisteredNormalService(const emm_reg_t *); -int EmmRegisteredAttemptingToUpdate(const emm_reg_t *); -int EmmRegisteredLimitedService(const emm_reg_t *); -int EmmRegisteredPlmnSearch(const emm_reg_t *); -int EmmRegisteredUpdateNeeded(const emm_reg_t *); -int EmmRegisteredNoCellAvailable(const emm_reg_t *); -int EmmRegisteredAttemptingToUpdate(const emm_reg_t *); -int EmmRegisteredImsiDetachInitiated(const emm_reg_t *); -int EmmTrackingAreaUpdatingInitiated(const emm_reg_t *); -int EmmServiceRequestInitiated(const emm_reg_t *); +typedef int(*emm_fsm_handler_t)(nas_user_t *user, const emm_reg_t *); + +int EmmNull(nas_user_t *user, const emm_reg_t *); +int EmmDeregistered(nas_user_t *user, const emm_reg_t *); +int EmmRegistered(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredInitiated(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredNoImsi(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredAttachNeeded(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredNormalService(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredAttemptingToUpdate(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredLimitedService(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredPlmnSearch(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredUpdateNeeded(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredAttemptingToUpdate(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredImsiDetachInitiated(nas_user_t *user, const emm_reg_t *); +int EmmTrackingAreaUpdatingInitiated(nas_user_t *user, const emm_reg_t *); +int EmmServiceRequestInitiated(nas_user_t *user, const emm_reg_t *); /* EMM state machine handlers */ @@ -180,14 +181,6 @@ static const emm_fsm_handler_t _emm_fsm_handlers[EMM_STATE_MAX] = { EmmServiceRequestInitiated, }; -/* - * ----------------------------------------------------------------------------- - * Current EPS Mobility Management status - * ----------------------------------------------------------------------------- - */ - -emm_fsm_state_t _emm_fsm_status[EMM_FSM_NB_UE_MAX]; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -206,14 +199,12 @@ emm_fsm_state_t _emm_fsm_status[EMM_FSM_NB_UE_MAX]; ** Others: _emm_fsm_status ** ** ** ***************************************************************************/ -void emm_fsm_initialize(void) +emm_fsm_state_t emm_fsm_initialize() { - //int ueid; LOG_FUNC_IN; - _emm_fsm_status[0] = EMM_NULL; - LOG_FUNC_OUT; + return EMM_NULL; } /**************************************************************************** @@ -231,22 +222,18 @@ void emm_fsm_initialize(void) ** Others: _emm_fsm_status ** ** ** ***************************************************************************/ -int emm_fsm_set_status( +int emm_fsm_set_status(nas_user_t *user, emm_fsm_state_t status) { LOG_FUNC_IN; - unsigned int ueid = 0; - - - - if ( (status < EMM_STATE_MAX) && (ueid < EMM_FSM_NB_UE_MAX) ) { + if ( status < EMM_STATE_MAX ) { LOG_TRACE(INFO, "EMM-FSM - Status changed: %s ===> %s", - _emm_fsm_status_str[_emm_fsm_status[ueid]], + _emm_fsm_status_str[user->emm_fsm_status], _emm_fsm_status_str[status]); - if (status != _emm_fsm_status[ueid]) { - _emm_fsm_status[ueid] = status; + if (status != user->emm_fsm_status) { + user->emm_fsm_status = status; } LOG_FUNC_RETURN (RETURNok); @@ -270,9 +257,9 @@ int emm_fsm_set_status( ** Others: None ** ** ** ***************************************************************************/ -emm_fsm_state_t emm_fsm_get_status(void) +emm_fsm_state_t emm_fsm_get_status(nas_user_t *user) { - return (_emm_fsm_status[0]); + return user->emm_fsm_status; } /**************************************************************************** @@ -289,7 +276,7 @@ emm_fsm_state_t emm_fsm_get_status(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_fsm_process(const emm_reg_t *evt) +int emm_fsm_process(nas_user_t *user, const emm_reg_t *evt) { int rc; emm_fsm_state_t status; @@ -299,7 +286,7 @@ int emm_fsm_process(const emm_reg_t *evt) primitive = evt->primitive; - status = _emm_fsm_status[0]; + status = user->emm_fsm_status; LOG_TRACE(INFO, "EMM-FSM - Received event %s (%d) in state %s", _emm_fsm_event_str[primitive - _EMMREG_START - 1], primitive, @@ -307,7 +294,7 @@ int emm_fsm_process(const emm_reg_t *evt) /* Execute the EMM state machine */ - rc = (_emm_fsm_handlers[status])(evt); + rc = (_emm_fsm_handlers[status])(user, evt); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/SAP/emm_fsm.h b/openair3/NAS/UE/EMM/SAP/emm_fsm.h index ea7d4ed62228cf6875aad3e31ede55437a1c64b2..aba1ef327ca2e8f5f010ece712a501c2600dc625 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_fsm.h +++ b/openair3/NAS/UE/EMM/SAP/emm_fsm.h @@ -41,48 +41,13 @@ Description Defines the EPS Mobility Management procedures executed at #define __EMM_FSM_H__ #include "emm_regDef.h" +#include "emm_fsm_defs.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/* - * States of the EPS Mobility Management sublayer - * ---------------------------------------------- - * The EMM protocol of the UE and the network is described by means of two - * different state machines. - */ -typedef enum { - EMM_INVALID, - EMM_NULL, - EMM_DEREGISTERED, - EMM_REGISTERED, - EMM_DEREGISTERED_INITIATED, - EMM_DEREGISTERED_NORMAL_SERVICE, - EMM_DEREGISTERED_LIMITED_SERVICE, - EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH, - EMM_DEREGISTERED_PLMN_SEARCH, - EMM_DEREGISTERED_NO_IMSI, - EMM_DEREGISTERED_ATTACH_NEEDED, - EMM_DEREGISTERED_NO_CELL_AVAILABLE, - EMM_REGISTERED_INITIATED, - EMM_REGISTERED_NORMAL_SERVICE, - EMM_REGISTERED_ATTEMPTING_TO_UPDATE, - EMM_REGISTERED_LIMITED_SERVICE, - EMM_REGISTERED_PLMN_SEARCH, - EMM_REGISTERED_UPDATE_NEEDED, - EMM_REGISTERED_NO_CELL_AVAILABLE, - EMM_REGISTERED_ATTEMPTING_TO_UPDATE_MM, - EMM_REGISTERED_IMSI_DETACH_INITIATED, - EMM_TRACKING_AREA_UPDATING_INITIATED, - EMM_SERVICE_REQUEST_INITIATED, - EMM_STATE_MAX -} emm_fsm_state_t; - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -91,12 +56,12 @@ typedef enum { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_fsm_initialize(void); +emm_fsm_state_t emm_fsm_initialize(void); -int emm_fsm_set_status(emm_fsm_state_t status); -emm_fsm_state_t emm_fsm_get_status(void); +int emm_fsm_set_status(nas_user_t *user, emm_fsm_state_t status); +emm_fsm_state_t emm_fsm_get_status(nas_user_t *user); -int emm_fsm_process(const emm_reg_t *evt); +int emm_fsm_process(nas_user_t *user, const emm_reg_t *evt); #endif /* __EMM_FSM_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_recv.c b/openair3/NAS/UE/EMM/SAP/emm_recv.c index 0ad41b09d878862b677cc35da535f103baf1cadf..5b7c6d7dda34fe0c057da04071522ceeefffa69f 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_recv.c +++ b/openair3/NAS/UE/EMM/SAP/emm_recv.c @@ -125,7 +125,7 @@ int emm_recv_status(unsigned int ueid, emm_status_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_attach_accept(attach_accept_msg *msg, int *emm_cause) +int emm_recv_attach_accept(nas_user_t *user, attach_accept_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -224,7 +224,7 @@ int emm_recv_attach_accept(attach_accept_msg *msg, int *emm_cause) } /* Execute attach procedure accepted by the network */ - rc = emm_proc_attach_accept(T3412, T3402, T3423, n_tais, tai, pguti, + rc = emm_proc_attach_accept(user, T3412, T3402, T3423, n_tais, tai, pguti, n_eplmns, &eplmn, &msg->esmmessagecontainer.esmmessagecontainercontents); @@ -245,7 +245,7 @@ int emm_recv_attach_accept(attach_accept_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_attach_reject(attach_reject_msg *msg, int *emm_cause) +int emm_recv_attach_reject(nas_user_t *user, attach_reject_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -275,11 +275,11 @@ int emm_recv_attach_reject(attach_reject_msg *msg, int *emm_cause) */ if (msg->presencemask & ATTACH_REJECT_ESM_MESSAGE_CONTAINER_PRESENT) { /* Execute attach procedure rejected by the network */ - rc = emm_proc_attach_reject(msg->emmcause, + rc = emm_proc_attach_reject(user, msg->emmcause, &msg->esmmessagecontainer.esmmessagecontainercontents); } else { /* Execute attach procedure rejected by the network */ - rc = emm_proc_attach_reject(msg->emmcause, NULL); + rc = emm_proc_attach_reject(user, msg->emmcause, NULL); } LOG_FUNC_RETURN (rc); @@ -299,7 +299,7 @@ int emm_recv_attach_reject(attach_reject_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_detach_accept(detach_accept_msg *msg, int *emm_cause) +int emm_recv_detach_accept(nas_user_t *user, detach_accept_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -311,7 +311,7 @@ int emm_recv_detach_accept(detach_accept_msg *msg, int *emm_cause) * Message processing */ /* Execute the UE initiated detach procedure completion by the UE */ - rc = emm_proc_detach_accept(); + rc = emm_proc_detach_accept(user); LOG_FUNC_RETURN (rc); } @@ -330,7 +330,7 @@ int emm_recv_detach_accept(detach_accept_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_identity_request(identity_request_msg *msg, int *emm_cause) +int emm_recv_identity_request(nas_user_t *user, identity_request_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -358,7 +358,7 @@ int emm_recv_identity_request(identity_request_msg *msg, int *emm_cause) } /* Execute the identification procedure initiated by the network */ - rc = emm_proc_identification_request(type); + rc = emm_proc_identification_request(user, type); LOG_FUNC_RETURN (rc); } @@ -377,7 +377,7 @@ int emm_recv_identity_request(identity_request_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_authentication_request(authentication_request_msg *msg, +int emm_recv_authentication_request(nas_user_t *user, authentication_request_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -404,7 +404,7 @@ int emm_recv_authentication_request(authentication_request_msg *msg, * Message processing */ /* Execute the authentication procedure initiated by the network */ - rc = emm_proc_authentication_request( + rc = emm_proc_authentication_request(user, msg->naskeysetidentifierasme.tsc != NAS_KEY_SET_IDENTIFIER_MAPPED, msg->naskeysetidentifierasme.naskeysetidentifier, &msg->authenticationparameterrand.rand, @@ -427,7 +427,7 @@ int emm_recv_authentication_request(authentication_request_msg *msg, ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_authentication_reject(authentication_reject_msg *msg, +int emm_recv_authentication_reject(nas_user_t *user, authentication_reject_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -440,7 +440,7 @@ int emm_recv_authentication_reject(authentication_reject_msg *msg, * Message processing */ /* Execute the authentication procedure not accepted by the network */ - rc = emm_proc_authentication_reject(); + rc = emm_proc_authentication_reject(user); LOG_FUNC_RETURN (rc); } @@ -459,7 +459,7 @@ int emm_recv_authentication_reject(authentication_reject_msg *msg, ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_security_mode_command(security_mode_command_msg *msg, +int emm_recv_security_mode_command(nas_user_t *user, security_mode_command_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -473,7 +473,7 @@ int emm_recv_security_mode_command(security_mode_command_msg *msg, */ /* Execute the security mode control procedure initiated by the network */ LOG_TRACE(INFO,"Execute the security mode control procedure initiated by the network: imeisvrequest %d\n",msg->imeisvrequest); - rc = emm_proc_security_mode_command( + rc = emm_proc_security_mode_command(user, msg->naskeysetidentifier.tsc != NAS_KEY_SET_IDENTIFIER_MAPPED, msg->naskeysetidentifier.naskeysetidentifier, msg->selectednassecurityalgorithms.typeofcipheringalgorithm, diff --git a/openair3/NAS/UE/EMM/SAP/emm_recv.h b/openair3/NAS/UE/EMM/SAP/emm_recv.h index cec52a8c1f4025535403eff57719e0d5a096c834..ead59e3851bcfb44cf5224ac8942f218da24fc82 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_recv.h +++ b/openair3/NAS/UE/EMM/SAP/emm_recv.h @@ -59,7 +59,7 @@ Description Defines functions executed at the EMMAS Service Access #include "EmmInformation.h" #include "DownlinkNasTransport.h" #include "CsServiceNotification.h" - +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ @@ -88,17 +88,17 @@ int emm_recv_status(unsigned int ueid, emm_status_msg *msg, int *emm_cause); * Functions executed by the UE upon receiving EMM message from the network * -------------------------------------------------------------------------- */ -int emm_recv_attach_accept(attach_accept_msg *msg, int *emm_cause); -int emm_recv_attach_reject(attach_reject_msg *msg, int *emm_cause); +int emm_recv_attach_accept(nas_user_t *user, attach_accept_msg *msg, int *emm_cause); +int emm_recv_attach_reject(nas_user_t *user, attach_reject_msg *msg, int *emm_cause); -int emm_recv_detach_accept(detach_accept_msg *msg, int *emm_cause); +int emm_recv_detach_accept(nas_user_t *user, detach_accept_msg *msg, int *emm_cause); -int emm_recv_identity_request(identity_request_msg *msg, int *emm_cause); -int emm_recv_authentication_request(authentication_request_msg *msg, +int emm_recv_identity_request(nas_user_t *user, identity_request_msg *msg, int *emm_cause); +int emm_recv_authentication_request(nas_user_t *user, authentication_request_msg *msg, int *emm_cause); -int emm_recv_authentication_reject(authentication_reject_msg *msg, +int emm_recv_authentication_reject(nas_user_t *user, authentication_reject_msg *msg, int *emm_cause); -int emm_recv_security_mode_command(security_mode_command_msg *msg, +int emm_recv_security_mode_command(nas_user_t *user, security_mode_command_msg *msg, int *emm_cause); #endif /* __EMM_RECV_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_reg.c b/openair3/NAS/UE/EMM/SAP/emm_reg.c index 065b91bd3ba0eda105e9ab0c08be1e827a77a9c2..6cda066b584d89098421139fcf9f6f60d4dd7256 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_reg.c +++ b/openair3/NAS/UE/EMM/SAP/emm_reg.c @@ -73,12 +73,12 @@ Description Defines the EMMREG Service Access Point that provides ** Others: NONE ** ** ** ***************************************************************************/ -void emm_reg_initialize(void) +void emm_reg_initialize(nas_user_t *user) { LOG_FUNC_IN; /* Initialize the EMM state machine */ - emm_fsm_initialize(); + user->emm_fsm_status = emm_fsm_initialize(); LOG_FUNC_OUT; } @@ -97,7 +97,7 @@ void emm_reg_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_reg_send(const emm_reg_t *msg) +int emm_reg_send(nas_user_t *user, const emm_reg_t *msg) { LOG_FUNC_IN; @@ -111,7 +111,7 @@ int emm_reg_send(const emm_reg_t *msg) (void)primitive; /* Execute the EMM procedure */ - rc = emm_fsm_process(msg); + rc = emm_fsm_process(user, msg); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/SAP/emm_reg.h b/openair3/NAS/UE/EMM/SAP/emm_reg.h index 08d28b67db83757d885f4ec97fdea6e48a4cb770..9cd1132c7a333f148625db8049d6847289b8da97 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_reg.h +++ b/openair3/NAS/UE/EMM/SAP/emm_reg.h @@ -42,6 +42,7 @@ Description Defines the EMMREG Service Access Point that provides #define __EMM_REG_H__ #include "emm_regDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -59,8 +60,8 @@ Description Defines the EMMREG Service Access Point that provides /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_reg_initialize(void); +void emm_reg_initialize(nas_user_t *user); -int emm_reg_send(const emm_reg_t *msg); +int emm_reg_send(nas_user_t *user, const emm_reg_t *msg); #endif /* __EMM_REG_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_sap.c b/openair3/NAS/UE/EMM/SAP/emm_sap.c index d8312ee74cb859e95c2905cb50a973ec23dcb839..429518d475c2c47e20ee86f215d38985de6fd6de 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_sap.c +++ b/openair3/NAS/UE/EMM/SAP/emm_sap.c @@ -46,6 +46,7 @@ Description Defines the EMM Service Access Points at which the EPS #include "emm_reg.h" #include "emm_esm.h" #include "emm_as.h" +#include "user_defs.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -73,13 +74,13 @@ Description Defines the EMM Service Access Points at which the EPS ** Others: NONE ** ** ** ***************************************************************************/ -void emm_sap_initialize(void) +void emm_sap_initialize(nas_user_t *user) { LOG_FUNC_IN; - emm_reg_initialize(); + emm_reg_initialize(user); emm_esm_initialize(); - emm_as_initialize(); + emm_as_initialize(user); LOG_FUNC_OUT; } @@ -98,7 +99,7 @@ void emm_sap_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_sap_send(emm_sap_t *msg) +int emm_sap_send(nas_user_t *user, emm_sap_t *msg) { int rc = RETURNerror; @@ -111,17 +112,17 @@ int emm_sap_send(emm_sap_t *msg) (primitive < (emm_primitive_t)EMMREG_PRIMITIVE_MAX) ) { /* Forward to the EMMREG-SAP */ msg->u.emm_reg.primitive = primitive; - rc = emm_reg_send(&msg->u.emm_reg); + rc = emm_reg_send(user, &msg->u.emm_reg); } else if ( (primitive > (emm_primitive_t)EMMESM_PRIMITIVE_MIN) && (primitive < (emm_primitive_t)EMMESM_PRIMITIVE_MAX) ) { /* Forward to the EMMESM-SAP */ msg->u.emm_esm.primitive = primitive; - rc = emm_esm_send(&msg->u.emm_esm); + rc = emm_esm_send(user, &msg->u.emm_esm); } else if ( (primitive > (emm_primitive_t)EMMAS_PRIMITIVE_MIN) && (primitive < (emm_primitive_t)EMMAS_PRIMITIVE_MAX) ) { /* Forward to the EMMAS-SAP */ msg->u.emm_as.primitive = primitive; - rc = emm_as_send(&msg->u.emm_as); + rc = emm_as_send(user, &msg->u.emm_as); } else { LOG_TRACE(WARNING, "EMM-SAP - Out of range primitive (%d)", primitive); diff --git a/openair3/NAS/UE/EMM/SAP/emm_sap.h b/openair3/NAS/UE/EMM/SAP/emm_sap.h index f27e8d4e5832fb797fedb3f992460568d1e0a8b8..b84fd7808b4bf8ae217107041522dd22b2eabf95 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_sap.h +++ b/openair3/NAS/UE/EMM/SAP/emm_sap.h @@ -46,6 +46,7 @@ Description Defines the EMM Service Access Points at which the EPS #include "emm_regDef.h" #include "emm_esmDef.h" #include "emm_asDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -156,8 +157,8 @@ typedef struct emm_sap_s { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_sap_initialize(void); +void emm_sap_initialize(nas_user_t *user); -int emm_sap_send(emm_sap_t *msg); +int emm_sap_send(nas_user_t *user, emm_sap_t *msg); #endif /* __EMM_SAP_H__*/ diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index f27eb7b4afa87a25a76e08beb95f4a2aa6607b9c..0991fb22bb4ff6a8a68aa7aa25e28141c3448229 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -64,6 +64,7 @@ Description Defines the security mode control EMM procedure executed by the # include "assertions.h" #include "secu_defs.h" #include "msc.h" +#include "SecurityModeControl.h" #if defined(NAS_BUILT_IN_UE) #include "nas_itti_messaging.h" @@ -92,13 +93,6 @@ static int _security_knas_int(const OctetString *kasme, OctetString *knas_int, static int _security_kenb(const OctetString *kasme, OctetString *kenb, uint32_t count); -/* - * Internal data used for security mode control procedure - */ -static struct { - OctetString kenb; /* eNodeB security key */ -} _security_data; - static void _security_release(emm_security_context_t *ctx); /* @@ -145,7 +139,7 @@ static void _security_release(emm_security_context_t *ctx); ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_security_mode_command(int native_ksi, int ksi, +int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, int seea, int seia, int reea, int reia, int imeisv_request) { LOG_FUNC_IN; @@ -153,18 +147,19 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, int rc = RETURNerror; int emm_cause = EMM_CAUSE_SUCCESS; int security_context_is_new = FALSE; + security_data_t *security_data = user->security_data; LOG_TRACE(INFO, "EMM-PROC - Security mode control requested (ksi=%d)", ksi); /* Delete any previously stored RAND and RES and stop timer T3416 */ - (void) emm_proc_authentication_delete(); + (void) emm_proc_authentication_delete(user); /* * Check the replayed UE security capabilities */ - uint8_t eea = (0x80 >> _emm_data.security->capability.eps_encryption); - uint8_t eia = (0x80 >> _emm_data.security->capability.eps_integrity); + uint8_t eea = (0x80 >> user->emm_data->security->capability.eps_encryption); + uint8_t eia = (0x80 >> user->emm_data->security->capability.eps_integrity); if ( (reea != eea) || (reia != eia) ) { LOG_TRACE(WARNING, "EMM-PROC - Replayed UE security capabilities " @@ -180,7 +175,7 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, /* * Check the non-current EPS security context */ - else if (_emm_data.non_current == NULL) { + else if (user->emm_data->non_current == NULL) { LOG_TRACE(WARNING, "EMM-PROC - Non-current EPS security context " "is not valid"); emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; @@ -191,53 +186,53 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, else { LOG_TRACE(INFO, "EMM-PROC - Update the non-current EPS security context seea=%u seia=%u", seea, seia); /* Update selected cyphering and integrity algorithms */ - //LG COMENTED _emm_data.non_current->capability.encryption = seea; - //LG COMENTED _emm_data.non_current->capability.integrity = seia; + //LG COMENTED user->emm_data->non_current->capability.encryption = seea; + //LG COMENTED user->emm_data->non_current->capability.integrity = seia; - _emm_data.non_current->selected_algorithms.encryption = seea; - _emm_data.non_current->selected_algorithms.integrity = seia; + user->emm_data->non_current->selected_algorithms.encryption = seea; + user->emm_data->non_current->selected_algorithms.integrity = seia; /* Derive the NAS cyphering key */ - if (_emm_data.non_current->knas_enc.value == NULL) { - _emm_data.non_current->knas_enc.value = + if (user->emm_data->non_current->knas_enc.value == NULL) { + user->emm_data->non_current->knas_enc.value = (uint8_t *)calloc(1,AUTH_KNAS_ENC_SIZE); - _emm_data.non_current->knas_enc.length = AUTH_KNAS_ENC_SIZE; + user->emm_data->non_current->knas_enc.length = AUTH_KNAS_ENC_SIZE; } - if (_emm_data.non_current->knas_enc.value != NULL) { + if (user->emm_data->non_current->knas_enc.value != NULL) { LOG_TRACE(INFO, "EMM-PROC - Update the non-current EPS security context knas_enc"); - rc = _security_knas_enc(&_emm_data.non_current->kasme, - &_emm_data.non_current->knas_enc, seea); + rc = _security_knas_enc(&user->emm_data->non_current->kasme, + &user->emm_data->non_current->knas_enc, seea); } /* Derive the NAS integrity key */ - if (_emm_data.non_current->knas_int.value == NULL) { - _emm_data.non_current->knas_int.value = + if (user->emm_data->non_current->knas_int.value == NULL) { + user->emm_data->non_current->knas_int.value = (uint8_t *)calloc(1,AUTH_KNAS_INT_SIZE); - _emm_data.non_current->knas_int.length = AUTH_KNAS_INT_SIZE; + user->emm_data->non_current->knas_int.length = AUTH_KNAS_INT_SIZE; } - if (_emm_data.non_current->knas_int.value != NULL) { + if (user->emm_data->non_current->knas_int.value != NULL) { if (rc != RETURNerror) { LOG_TRACE(INFO, "EMM-PROC - Update the non-current EPS security context knas_int"); - rc = _security_knas_int(&_emm_data.non_current->kasme, - &_emm_data.non_current->knas_int, seia); + rc = _security_knas_int(&user->emm_data->non_current->kasme, + &user->emm_data->non_current->knas_int, seia); } } /* Derive the eNodeB key */ - if (_security_data.kenb.value == NULL) { - _security_data.kenb.value = (uint8_t *)calloc(1,AUTH_KENB_SIZE); - _security_data.kenb.length = AUTH_KENB_SIZE; + if (security_data->kenb.value == NULL) { + security_data->kenb.value = (uint8_t *)calloc(1,AUTH_KENB_SIZE); + security_data->kenb.length = AUTH_KENB_SIZE; } - if (_security_data.kenb.value != NULL) { + if (security_data->kenb.value != NULL) { if (rc != RETURNerror) { LOG_TRACE(INFO, "EMM-PROC - Update the non-current EPS security context kenb"); - // LG COMMENT rc = _security_kenb(&_emm_data.security->kasme, - rc = _security_kenb(&_emm_data.non_current->kasme, - &_security_data.kenb, - *(uint32_t *)(&_emm_data.non_current->ul_count)); + // LG COMMENT rc = _security_kenb(&user->emm_data->security->kasme, + rc = _security_kenb(&user->emm_data->non_current->kasme, + &security_data->kenb, + *(uint32_t *)(&user->emm_data->non_current->ul_count)); } } @@ -248,13 +243,13 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, LOG_TRACE(INFO, "EMM-PROC - NAS security mode command accepted by the UE"); /* Update the current EPS security context */ - if ( native_ksi && (_emm_data.security->type != EMM_KSI_NATIVE) ) { + if ( native_ksi && (user->emm_data->security->type != EMM_KSI_NATIVE) ) { /* The type of security context flag included in the SECURITY * MODE COMMAND message is set to "native security context" and * the UE has a mapped EPS security context as the current EPS * security context */ - if ( (_emm_data.non_current->type == EMM_KSI_NATIVE) && - (_emm_data.non_current->eksi == ksi) ) { + if ( (user->emm_data->non_current->type == EMM_KSI_NATIVE) && + (user->emm_data->non_current->eksi == ksi) ) { /* The KSI matches the non-current native EPS security * context; the UE shall take the non-current native EPS * security context into use which then becomes the @@ -263,36 +258,37 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, LOG_TRACE(INFO, "EMM-PROC - Update Current security context"); /* Release non-current security context */ - _security_release(_emm_data.security); - _emm_data.security = _emm_data.non_current; + _security_release(user->emm_data->security); + user->emm_data->security = user->emm_data->non_current; /* Reset the uplink NAS COUNT counter */ - _emm_data.security->ul_count.overflow = 0; - _emm_data.security->ul_count.seq_num = 0; + user->emm_data->security->ul_count.overflow = 0; + user->emm_data->security->ul_count.seq_num = 0; /* Set new security context indicator */ security_context_is_new = TRUE; } } - if ( !native_ksi && (_emm_data.security->type != EMM_KSI_NATIVE) ) { + if ( !native_ksi && (user->emm_data->security->type != EMM_KSI_NATIVE) ) { /* The type of security context flag included in the SECURITY * MODE COMMAND message is set to "mapped security context" and * the UE has a mapped EPS security context as the current EPS * security context */ - if (ksi != _emm_data.security->eksi) { + if (ksi != user->emm_data->security->eksi) { /* The KSI does not match the current EPS security context; * the UE shall reset the uplink NAS COUNT counter */ LOG_TRACE(INFO, "EMM-PROC - Reset uplink NAS COUNT counter"); - _emm_data.security->ul_count.overflow = 0; - _emm_data.security->ul_count.seq_num = 0; + user->emm_data->security->ul_count.overflow = 0; + user->emm_data->security->ul_count.seq_num = 0; } } - _emm_data.security->selected_algorithms.encryption = seea; - _emm_data.security->selected_algorithms.integrity = seia; + user->emm_data->security->selected_algorithms.encryption = seea; + user->emm_data->security->selected_algorithms.integrity = seia; #if defined(NAS_BUILT_IN_UE) - nas_itti_kenb_refresh_req(_security_data.kenb.value); + nas_itti_kenb_refresh_req(security_data->kenb.value); #endif + } /* * NAS security mode command not accepted by the UE @@ -302,17 +298,17 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; /* Release security mode control internal data */ - if (_security_data.kenb.value) { - free(_security_data.kenb.value); - _security_data.kenb.value = NULL; - _security_data.kenb.length = 0; + if (security_data->kenb.value) { + free(security_data->kenb.value); + security_data->kenb.value = NULL; + security_data->kenb.length = 0; } } } /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); if (rc != RETURNok) { LOG_TRACE(WARNING, @@ -326,15 +322,15 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, */ emm_sap_t emm_sap; emm_sap.primitive = EMMAS_SECURITY_RES; - emm_sap.u.emm_as.u.security.guti = _emm_data.guti; - emm_sap.u.emm_as.u.security.ueid = 0; + emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; + emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_SMC; emm_sap.u.emm_as.u.security.imeisv_request = imeisv_request; emm_sap.u.emm_as.u.security.emm_cause = emm_cause; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, security_context_is_new, TRUE); - rc = emm_sap_send(&emm_sap); + user->emm_data->security, security_context_is_new, TRUE); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.h b/openair3/NAS/UE/EMM/SecurityModeControl.h new file mode 100644 index 0000000000000000000000000000000000000000..314c168544dc24564371988bf16f1065ef3f54f6 --- /dev/null +++ b/openair3/NAS/UE/EMM/SecurityModeControl.h @@ -0,0 +1,11 @@ +#ifndef _SECURITYMODECONTROL_H +#define _SECURITYMODECONTROL_H + +/* + * Internal data used for security mode control procedure + */ +typedef struct { + OctetString kenb; /* eNodeB security key */ +} security_data_t; + +#endif diff --git a/openair3/NAS/UE/EMM/ServiceRequestHdl.c b/openair3/NAS/UE/EMM/ServiceRequestHdl.c index 349fce7cad19c9cdf358e480156994a10bcb0b91..93e66efdbdb2ae7ad387403fa58f60f08d745204 100644 --- a/openair3/NAS/UE/EMM/ServiceRequestHdl.c +++ b/openair3/NAS/UE/EMM/ServiceRequestHdl.c @@ -67,11 +67,6 @@ Description Defines the service request EMM procedure executed by the * Internal data handled by the service request procedure in the UE * -------------------------------------------------------------------------- */ -/* - * Timer handlers - */ -void *_emm_service_t3417_handler(void *); - /* * -------------------------------------------------------------------------- * Internal data handled by the service request procedure in the MME @@ -109,14 +104,16 @@ void *_emm_service_t3417_handler(void *); ** Others: None ** ** ** ***************************************************************************/ -void *_emm_service_t3417_handler(void *args) +void *emm_service_t3417_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user = args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - T3417 timer expired"); /* Stop timer T3417 */ - T3417.id = nas_timer_stop(T3417.id); + emm_timers->T3417.id = nas_timer_stop(emm_timers->T3417.id); LOG_FUNC_RETURN(NULL); } diff --git a/openair3/NAS/UE/EMM/TrackingAreaUpdate.c b/openair3/NAS/UE/EMM/TrackingAreaUpdate.c index 50a440951b3bb1c8cd69d23d0c92bd2e2ac67bc9..bafddaf31739edf8f07cab807fb92215f91e73e6 100644 --- a/openair3/NAS/UE/EMM/TrackingAreaUpdate.c +++ b/openair3/NAS/UE/EMM/TrackingAreaUpdate.c @@ -67,10 +67,6 @@ Description Defines the tracking area update EMM procedure executed by the * Internal data handled by the tracking area update procedure in the UE * -------------------------------------------------------------------------- */ -/* - * Timer handlers - */ -void *_emm_tau_t3430_handler(void *); /* * -------------------------------------------------------------------------- @@ -110,14 +106,16 @@ void *_emm_tau_t3430_handler(void *); ** Others: None ** ** ** ***************************************************************************/ -void *_emm_tau_t3430_handler(void *args) +void *emm_tau_t3430_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user = args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - T3430 timer expired"); /* Stop timer T3430 */ - T3430.id = nas_timer_stop(T3430.id); + emm_timers->T3430.id = nas_timer_stop(emm_timers->T3430.id); LOG_FUNC_RETURN(NULL); } diff --git a/openair3/NAS/UE/EMM/emmData.h b/openair3/NAS/UE/EMM/emmData.h index df89fb0c8e04937c4d0243b49dca97a2de55d9ed..84e58bb963023f393b3d6333eb743d4753b04455 100644 --- a/openair3/NAS/UE/EMM/emmData.h +++ b/openair3/NAS/UE/EMM/emmData.h @@ -47,6 +47,7 @@ Description Defines internal private data handled by EPS Mobility #include "nas_timer.h" #include "esmData.h" +#include "emm_proc_defs.h" @@ -93,6 +94,29 @@ Description Defines internal private data handled by EPS Mobility /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * Internal data used for attach procedure + */ + +#define EMM_ATTACH_COUNTER_MAX 5 + +typedef struct { + unsigned int attempt_count; /* Counter used to limit the number of + * subsequently rejected attach attempts */ +} emm_attach_data_t; + +/* + * Internal data used for detach procedure + */ +typedef struct { +#define EMM_DETACH_COUNTER_MAX 5 + unsigned int count; /* Counter used to limit the number of + * subsequently detach attempts */ + int switch_off; /* UE switch-off indicator */ + emm_proc_detach_type_t type; /* Type of the detach procedure + * currently in progress */ +} emm_detach_data_t; + /* * -------------------------------------------------------------------------- * EPS NAS security context handled by EPS Mobility Management sublayer in @@ -197,6 +221,20 @@ typedef struct emm_nvdata_s { PLMN_LIST_T(EMM_DATA_EPLMN_MAX) eplmn; } emm_nvdata_t; +typedef struct { + struct nas_timer_t T3402; /* attach failure timer */ + struct nas_timer_t T3410; /* attach timer */ + struct nas_timer_t T3411; /* attach restart timer */ + struct nas_timer_t T3412; /* periodic tracking area update timer */ + struct nas_timer_t T3416; /* EPS authentication challenge timer */ + struct nas_timer_t T3417; /* Service request timer */ + struct nas_timer_t T3418; /* MAC authentication failure timer */ + struct nas_timer_t T3420; /* Synch authentication failure timer */ + struct nas_timer_t T3421; /* Detach timer */ + struct nas_timer_t T3430; /* tracking area update timer */ + struct nas_timer_t T3423; /* E-UTRAN deactivate ISR timer */ +} emm_timers_t; + /* * Structure of the EMM data * ------------------------- @@ -324,7 +362,13 @@ typedef struct emm_data_s { */ emm_security_context_t *security; /* current security context */ emm_security_context_t *non_current; /* non-current security context */ - + /* + * EPS mobility management timers – UE side + * ---------------------------------------- + */ + emm_timers_t *emm_timers; + emm_detach_data_t *emm_detach_data; + emm_attach_data_t *emm_attach_data; } emm_data_t; @@ -333,18 +377,6 @@ typedef struct emm_data_s { /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ -/* - * -------------------------------------------------------------------------- - * EPS mobility management data (used within EMM only) - * -------------------------------------------------------------------------- - */ -emm_data_t _emm_data; - -/* - * -------------------------------------------------------------------------- - * EPS mobility management timers – UE side - * -------------------------------------------------------------------------- - */ #define T3402_DEFAULT_VALUE 720 /* 12 minutes */ #define T3410_DEFAULT_VALUE 15 /* 15 seconds */ #define T3411_DEFAULT_VALUE 10 /* 10 seconds */ @@ -359,19 +391,6 @@ emm_data_t _emm_data; #define T3430_DEFAULT_VALUE 15 /* 15 seconds */ #define T3440_DEFAULT_VALUE 10 /* 10 seconds */ -struct nas_timer_t T3402; /* attach failure timer */ -struct nas_timer_t T3410; /* attach timer */ -struct nas_timer_t T3411; /* attach restart timer */ -struct nas_timer_t T3412; /* periodic tracking area update timer */ -struct nas_timer_t T3416; /* EPS authentication challenge timer */ -struct nas_timer_t T3417; /* Service request timer */ -struct nas_timer_t T3418; /* MAC authentication failure timer */ -struct nas_timer_t T3420; /* Synch authentication failure timer */ -struct nas_timer_t T3421; /* Detach timer */ -struct nas_timer_t T3430; /* tracking area update timer */ - -struct nas_timer_t T3423; /* E-UTRAN deactivate ISR timer */ - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ diff --git a/openair3/NAS/UE/EMM/emm_fsm_defs.h b/openair3/NAS/UE/EMM/emm_fsm_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..4e5b4a8ee67b82030ad0ccdecde2f25ee88ad7de --- /dev/null +++ b/openair3/NAS/UE/EMM/emm_fsm_defs.h @@ -0,0 +1,42 @@ +#ifndef _EMM_FSM_DEFS_H +#define _EMM_FSM_DEFS_H + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +/* + * States of the EPS Mobility Management sublayer + * ---------------------------------------------- + * The EMM protocol of the UE and the network is described by means of two + * different state machines. + */ +typedef enum { + EMM_INVALID, + EMM_NULL, + EMM_DEREGISTERED, + EMM_REGISTERED, + EMM_DEREGISTERED_INITIATED, + EMM_DEREGISTERED_NORMAL_SERVICE, + EMM_DEREGISTERED_LIMITED_SERVICE, + EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH, + EMM_DEREGISTERED_PLMN_SEARCH, + EMM_DEREGISTERED_NO_IMSI, + EMM_DEREGISTERED_ATTACH_NEEDED, + EMM_DEREGISTERED_NO_CELL_AVAILABLE, + EMM_REGISTERED_INITIATED, + EMM_REGISTERED_NORMAL_SERVICE, + EMM_REGISTERED_ATTEMPTING_TO_UPDATE, + EMM_REGISTERED_LIMITED_SERVICE, + EMM_REGISTERED_PLMN_SEARCH, + EMM_REGISTERED_UPDATE_NEEDED, + EMM_REGISTERED_NO_CELL_AVAILABLE, + EMM_REGISTERED_ATTEMPTING_TO_UPDATE_MM, + EMM_REGISTERED_IMSI_DETACH_INITIATED, + EMM_TRACKING_AREA_UPDATING_INITIATED, + EMM_SERVICE_REQUEST_INITIATED, + EMM_STATE_MAX +} emm_fsm_state_t; + + +#endif diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 2eb4d8fa24d6b18c1d7e8f88d01bbfc00961c2ca..c64fd6df2614381083d16a66f8555daf64f0b679 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -39,8 +39,10 @@ Description Defines the EPS Mobility Management procedure call manager, #include "emm_main.h" #include "nas_log.h" +#include "utils.h" #include "emmData.h" #include "MobileIdentity.h" +#include "emm_proc_defs.h" #include "memory.h" #include "usim_api.h" @@ -63,27 +65,58 @@ static int _emm_main_get_imei(imei_t *imei, const char *imei_str); static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2); -static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, +static const char *_emm_main_get_plmn(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, int format, size_t *size); -static int _emm_main_get_plmn_index(const char *plmn, int format); - -/* - * USIM application data - */ -static usim_data_t _usim_data; +static int _emm_main_get_plmn_index(emm_plmn_list_t *emm_plmn_list, const char *plmn, int format); /* * Callback executed whenever a change in the network has to be notified * to the user application */ static emm_indication_callback_t _emm_main_user_callback; -static int _emm_main_callback(int); +static int _emm_main_callback(user_api_id_t *user_api_id, emm_data_t *emm_data, int size); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ + /* + * Initialize EMM timers + */ +void _emm_timers_initialize(emm_timers_t *emm_timers) { + emm_timers->T3410.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3410.sec = T3410_DEFAULT_VALUE; + emm_timers->T3411.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3411.sec = T3411_DEFAULT_VALUE; + emm_timers->T3402.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3402.sec = T3402_DEFAULT_VALUE; + emm_timers->T3416.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3416.sec = T3416_DEFAULT_VALUE; + emm_timers->T3417.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3417.sec = T3417_DEFAULT_VALUE; + emm_timers->T3418.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3418.sec = T3418_DEFAULT_VALUE; + emm_timers->T3420.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3420.sec = T3420_DEFAULT_VALUE; + emm_timers->T3421.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3421.sec = T3421_DEFAULT_VALUE; + emm_timers->T3423.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3423.sec = T3423_DEFAULT_VALUE; + emm_timers->T3430.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3430.sec = T3430_DEFAULT_VALUE; +} + +void _emm_attach_initialize(emm_attach_data_t *emm_attach_data) { + emm_attach_data->attempt_count = 0; +} + +void _emm_detach_initialize(emm_detach_data_t *emm_detach) { + emm_detach->count = 0; + emm_detach->switch_off = FALSE; + emm_detach->type = EMM_DETACH_TYPE_RESERVED; +} + /**************************************************************************** ** ** ** Name: emm_main_initialize() ** @@ -93,76 +126,74 @@ static int _emm_main_callback(int); ** Inputs: cb: The user notification callback ** ** imei: The IMEI read from the UE's non-volatile ** ** memory ** - ** Others: _usim_data ** ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -void emm_main_initialize(emm_indication_callback_t cb, const char *imei) +void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei) { LOG_FUNC_IN; - + user->emm_data = calloc_or_fail(sizeof(emm_data_t)); /* USIM validity indicator */ - _emm_data.usim_is_valid = FALSE; + user->emm_data->usim_is_valid = FALSE; /* The IMEI read from the UE's non-volatile memory */ - _emm_data.imei = (imei_t *)malloc(sizeof(imei_t)); - _emm_data.imei->length = _emm_main_get_imei(_emm_data.imei, imei); + user->emm_data->imei = (imei_t *)malloc(sizeof(imei_t)); + user->emm_data->imei->length = _emm_main_get_imei(user->emm_data->imei, imei); /* The IMSI, valid only if USIM is present */ - _emm_data.imsi = NULL; + user->emm_data->imsi = NULL; /* EPS location information */ - _emm_data.guti = NULL; - _emm_data.tai = NULL; - _emm_data.ltai.n_tais = 0; + user->emm_data->guti = NULL; + user->emm_data->tai = NULL; + user->emm_data->ltai.n_tais = 0; /* EPS Connection Management status */ - _emm_data.ecm_status = ECM_IDLE; + user->emm_data->ecm_status = ECM_IDLE; /* Network selection mode of operation */ - _emm_data.plmn_mode = EMM_DATA_PLMN_AUTO; + user->emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; /* Index of the PLMN manually selected by the user */ - _emm_data.plmn_index = -1; + user->emm_data->plmn_index = -1; /* Selected Radio Access Technology */ - _emm_data.plmn_rat = NET_ACCESS_UNAVAILABLE; + user->emm_data->plmn_rat = NET_ACCESS_UNAVAILABLE; /* Selected PLMN */ - memset(&_emm_data.splmn, 0xFF, sizeof(plmn_t)); - _emm_data.is_rplmn = FALSE; - _emm_data.is_eplmn = FALSE; + memset(&user->emm_data->splmn, 0xFF, sizeof(plmn_t)); + user->emm_data->is_rplmn = FALSE; + user->emm_data->is_eplmn = FALSE; /* Radio Access Technology of the serving cell */ - _emm_data.rat = NET_ACCESS_UNAVAILABLE; + user->emm_data->rat = NET_ACCESS_UNAVAILABLE; /* Network registration status */ - _emm_data.stat = NET_REG_STATE_OFF; - _emm_data.is_attached = FALSE; - _emm_data.is_emergency = FALSE; + user->emm_data->stat = NET_REG_STATE_OFF; + user->emm_data->is_attached = FALSE; + user->emm_data->is_emergency = FALSE; /* Location/Tracking area code */ - _emm_data.tac = 0; // two byte in hexadecimal format + user->emm_data->tac = 0; // two byte in hexadecimal format /* Identifier of the serving cell */ - _emm_data.ci = 0; // four byte in hexadecimal format + user->emm_data->ci = 0; // four byte in hexadecimal format /* List of operators present in the network */ - memset(_emm_data.plist.buffer, 0, EMM_DATA_BUFFER_SIZE + 1); + memset(user->emm_data->plist.buffer, 0, EMM_DATA_BUFFER_SIZE + 1); /* Home PLMN */ - memset(&_emm_data.hplmn, 0xFF, sizeof(plmn_t)); + memset(&user->emm_data->hplmn, 0xFF, sizeof(plmn_t)); /* List of Forbidden PLMNs */ - _emm_data.fplmn.n_plmns = 0; + user->emm_data->fplmn.n_plmns = 0; /* List of Forbidden PLMNs for GPRS service */ - _emm_data.fplmn_gprs.n_plmns = 0; + user->emm_data->fplmn_gprs.n_plmns = 0; /* List of Equivalent HPLMNs */ - _emm_data.ehplmn.n_plmns = 0; + user->emm_data->ehplmn.n_plmns = 0; /* List of user controlled PLMNs */ - _emm_data.plmn.n_plmns = 0; + user->emm_data->plmn.n_plmns = 0; /* List of operator controlled PLMNs */ - _emm_data.oplmn.n_plmns = 0; + user->emm_data->oplmn.n_plmns = 0; /* List of operator network name records */ - _emm_data.n_opnns = 0; + user->emm_data->n_opnns = 0; /* List of Forbidden Tracking Areas */ - _emm_data.ftai.n_tais = 0; + user->emm_data->ftai.n_tais = 0; /* List of Forbidden Tracking Areas for roaming */ - _emm_data.ftai_roaming.n_tais = 0; + user->emm_data->ftai_roaming.n_tais = 0; /* * Get USIM application data */ - _usim_data.usimtestmode = usim_test; - if ( usim_api_read(&_usim_data) != RETURNok ) { + if ( usim_api_read(user->usim_data_store, &user->usim_data) != RETURNok ) { /* The USIM application may not be present or not valid */ LOG_TRACE(WARNING, "EMM-MAIN - Failed to read USIM application data"); } else { @@ -170,138 +201,138 @@ void emm_main_initialize(emm_indication_callback_t cb, const char *imei) /* The USIM application is present and valid */ LOG_TRACE(INFO, "EMM-MAIN - USIM application data successfully read"); - _emm_data.usim_is_valid = TRUE; + user->emm_data->usim_is_valid = TRUE; /* Get the Home PLMN derived from the IMSI */ - _emm_data.hplmn.MCCdigit1 = _usim_data.imsi.u.num.digit1; - _emm_data.hplmn.MCCdigit2 = _usim_data.imsi.u.num.digit2; - _emm_data.hplmn.MCCdigit3 = _usim_data.imsi.u.num.digit3; - _emm_data.hplmn.MNCdigit1 = _usim_data.imsi.u.num.digit4; - _emm_data.hplmn.MNCdigit2 = _usim_data.imsi.u.num.digit5; - _emm_data.hplmn.MNCdigit3 = _usim_data.imsi.u.num.digit6; + user->emm_data->hplmn.MCCdigit1 = user->usim_data.imsi.u.num.digit1; + user->emm_data->hplmn.MCCdigit2 = user->usim_data.imsi.u.num.digit2; + user->emm_data->hplmn.MCCdigit3 = user->usim_data.imsi.u.num.digit3; + user->emm_data->hplmn.MNCdigit1 = user->usim_data.imsi.u.num.digit4; + user->emm_data->hplmn.MNCdigit2 = user->usim_data.imsi.u.num.digit5; + user->emm_data->hplmn.MNCdigit3 = user->usim_data.imsi.u.num.digit6; /* Get the list of forbidden PLMNs */ for (i=0; (i < EMM_DATA_FPLMN_MAX) && (i < USIM_FPLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.fplmn[i]) ) { - _emm_data.fplmn.plmn[i] = _usim_data.fplmn[i]; - _emm_data.fplmn.n_plmns += 1; + if ( PLMN_IS_VALID(user->usim_data.fplmn[i]) ) { + user->emm_data->fplmn.plmn[i] = user->usim_data.fplmn[i]; + user->emm_data->fplmn.n_plmns += 1; } } /* Get the list of Equivalent HPLMNs */ for (i=0; (i < EMM_DATA_EHPLMN_MAX) && (i < USIM_EHPLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.ehplmn[i]) ) { - _emm_data.ehplmn.plmn[i] = _usim_data.ehplmn[i]; - _emm_data.ehplmn.n_plmns += 1; + if ( PLMN_IS_VALID(user->usim_data.ehplmn[i]) ) { + user->emm_data->ehplmn.plmn[i] = user->usim_data.ehplmn[i]; + user->emm_data->ehplmn.n_plmns += 1; } } /* Get the list of User controlled PLMN Selector */ for (i=0; (i < EMM_DATA_PLMN_MAX) && (i < USIM_PLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.plmn[i].plmn) ) { - _emm_data.plmn.plmn[i] = _usim_data.plmn[i].plmn; - _emm_data.userAcT[i] = _usim_data.plmn[i].AcT; - _emm_data.plmn.n_plmns += 1; + if ( PLMN_IS_VALID(user->usim_data.plmn[i].plmn) ) { + user->emm_data->plmn.plmn[i] = user->usim_data.plmn[i].plmn; + user->emm_data->userAcT[i] = user->usim_data.plmn[i].AcT; + user->emm_data->plmn.n_plmns += 1; } } /* Get the list of Operator controlled PLMN Selector */ for (i=0; (i < EMM_DATA_OPLMN_MAX) && (i < USIM_OPLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.oplmn[i].plmn) ) { - _emm_data.oplmn.plmn[i] = _usim_data.oplmn[i].plmn; - _emm_data.operAcT[i] = _usim_data.oplmn[i].AcT; - _emm_data.oplmn.n_plmns += 1; + if ( PLMN_IS_VALID(user->usim_data.oplmn[i].plmn) ) { + user->emm_data->oplmn.plmn[i] = user->usim_data.oplmn[i].plmn; + user->emm_data->operAcT[i] = user->usim_data.oplmn[i].AcT; + user->emm_data->oplmn.n_plmns += 1; } } /* Get the list of Operator network name records */ for (i=0; (i < EMM_DATA_OPNN_MAX) && (i < USIM_OPL_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.opl[i].plmn) ) { - int pnn_id = _usim_data.opl[i].record_id; - _emm_data.opnn[i].plmn = &_usim_data.opl[i].plmn; - _emm_data.opnn[i].fullname = (char *)_usim_data.pnn[pnn_id].fullname.value; - _emm_data.opnn[i].shortname = (char *)_usim_data.pnn[pnn_id].shortname.value; - _emm_data.n_opnns += 1; + if ( PLMN_IS_VALID(user->usim_data.opl[i].plmn) ) { + int pnn_id = user->usim_data.opl[i].record_id; + user->emm_data->opnn[i].plmn = &user->usim_data.opl[i].plmn; + user->emm_data->opnn[i].fullname = (char *)user->usim_data.pnn[pnn_id].fullname.value; + user->emm_data->opnn[i].shortname = (char *)user->usim_data.pnn[pnn_id].shortname.value; + user->emm_data->n_opnns += 1; } } /* TODO: Get the Higher Priority PLMN search period parameter */ /* Get the EPS location information */ - if (PLMN_IS_VALID(_usim_data.epsloci.guti.gummei.plmn)) { - _emm_data.guti = &_usim_data.epsloci.guti; + if (PLMN_IS_VALID(user->usim_data.epsloci.guti.gummei.plmn)) { + user->emm_data->guti = &user->usim_data.epsloci.guti; } - if (TAI_IS_VALID(_usim_data.epsloci.tai)) { - _emm_data.tai = &_usim_data.epsloci.tai; + if (TAI_IS_VALID(user->usim_data.epsloci.tai)) { + user->emm_data->tai = &user->usim_data.epsloci.tai; } - _emm_data.status = _usim_data.epsloci.status; + user->emm_data->status = user->usim_data.epsloci.status; /* Get NAS configuration parameters */ - _emm_data.NAS_SignallingPriority = - _usim_data.nasconfig.NAS_SignallingPriority.value[0]; - _emm_data.NMO_I_Behaviour = _usim_data.nasconfig.NMO_I_Behaviour.value[0]; - _emm_data.AttachWithImsi = _usim_data.nasconfig.AttachWithImsi.value[0]; - _emm_data.MinimumPeriodicSearchTimer = - _usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0]; - _emm_data.ExtendedAccessBarring = - _usim_data.nasconfig.ExtendedAccessBarring.value[0]; - _emm_data.Timer_T3245_Behaviour = - _usim_data.nasconfig.Timer_T3245_Behaviour.value[0]; + user->emm_data->NAS_SignallingPriority = + user->usim_data.nasconfig.NAS_SignallingPriority.value[0]; + user->emm_data->NMO_I_Behaviour = user->usim_data.nasconfig.NMO_I_Behaviour.value[0]; + user->emm_data->AttachWithImsi = user->usim_data.nasconfig.AttachWithImsi.value[0]; + user->emm_data->MinimumPeriodicSearchTimer = + user->usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0]; + user->emm_data->ExtendedAccessBarring = + user->usim_data.nasconfig.ExtendedAccessBarring.value[0]; + user->emm_data->Timer_T3245_Behaviour = + user->usim_data.nasconfig.Timer_T3245_Behaviour.value[0]; /* * Get EPS NAS security context */ /* Create NAS security context */ - _emm_data.security = + user->emm_data->security = (emm_security_context_t *)malloc(sizeof(emm_security_context_t)); - if (_emm_data.security != NULL) { - memset(_emm_data.security, 0, sizeof(emm_security_context_t)); + if (user->emm_data->security != NULL) { + memset(user->emm_data->security, 0, sizeof(emm_security_context_t)); /* Type of security context */ - if (_usim_data.securityctx.KSIasme.value[0] != + if (user->usim_data.securityctx.KSIasme.value[0] != USIM_KSI_NOT_AVAILABLE) { - _emm_data.security->type = EMM_KSI_NATIVE; + user->emm_data->security->type = EMM_KSI_NATIVE; } else { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE; } /* EPS key set identifier */ - _emm_data.security->eksi = _usim_data.securityctx.KSIasme.value[0]; + user->emm_data->security->eksi = user->usim_data.securityctx.KSIasme.value[0]; /* ASME security key */ - _emm_data.security->kasme.length = - _usim_data.securityctx.Kasme.length; - _emm_data.security->kasme.value = - (uint8_t *)malloc(_emm_data.security->kasme.length); - - if (_emm_data.security->kasme.value) { - memcpy(_emm_data.security->kasme.value, - _usim_data.securityctx.Kasme.value, - _emm_data.security->kasme.length); + user->emm_data->security->kasme.length = + user->usim_data.securityctx.Kasme.length; + user->emm_data->security->kasme.value = + (uint8_t *)malloc(user->emm_data->security->kasme.length); + + if (user->emm_data->security->kasme.value) { + memcpy(user->emm_data->security->kasme.value, + user->usim_data.securityctx.Kasme.value, + user->emm_data->security->kasme.length); } /* Downlink count parameter */ - if (_usim_data.securityctx.dlNAScount.length <= sizeof(uint32_t)) { - memcpy(&_emm_data.security->dl_count, - _usim_data.securityctx.dlNAScount.value, - _usim_data.securityctx.dlNAScount.length); + if (user->usim_data.securityctx.dlNAScount.length <= sizeof(uint32_t)) { + memcpy(&user->emm_data->security->dl_count, + user->usim_data.securityctx.dlNAScount.value, + user->usim_data.securityctx.dlNAScount.length); } /* Uplink count parameter */ - if (_usim_data.securityctx.ulNAScount.length <= sizeof(uint32_t)) { - memcpy(&_emm_data.security->ul_count, - _usim_data.securityctx.ulNAScount.value, - _usim_data.securityctx.ulNAScount.length); + if (user->usim_data.securityctx.ulNAScount.length <= sizeof(uint32_t)) { + memcpy(&user->emm_data->security->ul_count, + user->usim_data.securityctx.ulNAScount.value, + user->usim_data.securityctx.ulNAScount.length); } /* Ciphering algorithm */ - _emm_data.security->capability.eps_encryption = - ((_usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf); + user->emm_data->security->capability.eps_encryption = + ((user->usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf); /* Identity protection algorithm */ - _emm_data.security->capability.eps_integrity = - (_usim_data.securityctx.algorithmID.value[0] & 0xf); + user->emm_data->security->capability.eps_integrity = + (user->usim_data.securityctx.algorithmID.value[0] & 0xf); /* NAS integrity and cyphering keys are not available */ } else { LOG_TRACE(WARNING, @@ -311,78 +342,65 @@ void emm_main_initialize(emm_indication_callback_t cb, const char *imei) /* * Get EMM data from the UE's non-volatile memory */ - memset(&_emm_data.nvdata.rplmn, 0xFF, sizeof(plmn_t)); - _emm_data.nvdata.eplmn.n_plmns = 0; - /* Get EMM data pathname */ - char *path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); + memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t)); + user->emm_data->nvdata.eplmn.n_plmns = 0; - if (path == NULL) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); - } else { - /* Get EMM data stored in the non-volatile memory device */ - int rc = memory_read(path, &_emm_data.nvdata, sizeof(emm_nvdata_t)); + /* Get EMM data stored in the non-volatile memory device */ + int rc = memory_read(user->emm_nvdata_store, &user->emm_data->nvdata, sizeof(emm_nvdata_t)); - if (rc != RETURNok) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to read %s", path); - } else { - /* Check the IMSI */ - LOG_TRACE(INFO, "EMM-MAIN - EMM data successfully read"); - _emm_data.imsi = &_usim_data.imsi; - int imsi_ok = _emm_main_imsi_cmp(&_emm_data.nvdata.imsi, - &_usim_data.imsi); - - if (!imsi_ok) { - LOG_TRACE(WARNING, "EMM-MAIN - IMSI checking failed nvram: " - "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x, " - "usim: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", - _emm_data.nvdata.imsi.u.value[0], - _emm_data.nvdata.imsi.u.value[1], - _emm_data.nvdata.imsi.u.value[2], - _emm_data.nvdata.imsi.u.value[3], - _emm_data.nvdata.imsi.u.value[4], - _emm_data.nvdata.imsi.u.value[5], - _emm_data.nvdata.imsi.u.value[6], - _emm_data.nvdata.imsi.u.value[7], - _usim_data.imsi.u.value[0], - _usim_data.imsi.u.value[1], - _usim_data.imsi.u.value[2], - _usim_data.imsi.u.value[3], - _usim_data.imsi.u.value[4], - _usim_data.imsi.u.value[5], - _usim_data.imsi.u.value[6], - _usim_data.imsi.u.value[7]); - memset(&_emm_data.nvdata.rplmn, 0xFF, sizeof(plmn_t)); - _emm_data.nvdata.eplmn.n_plmns = 0; - } - } + if (rc != RETURNok) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to read %s", user->emm_nvdata_store); + exit(EXIT_FAILURE); + } - free(path); + /* Check the IMSI */ + LOG_TRACE(INFO, "EMM-MAIN - EMM data successfully read"); + user->emm_data->imsi = &user->usim_data.imsi; + int imsi_ok = _emm_main_imsi_cmp(&user->emm_data->nvdata.imsi, + &user->usim_data.imsi); + + if (!imsi_ok) { + LOG_TRACE(WARNING, "EMM-MAIN - IMSI checking failed nvram: " + "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x, " + "usim: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", + user->emm_data->nvdata.imsi.u.value[0], + user->emm_data->nvdata.imsi.u.value[1], + user->emm_data->nvdata.imsi.u.value[2], + user->emm_data->nvdata.imsi.u.value[3], + user->emm_data->nvdata.imsi.u.value[4], + user->emm_data->nvdata.imsi.u.value[5], + user->emm_data->nvdata.imsi.u.value[6], + user->emm_data->nvdata.imsi.u.value[7], + user->usim_data.imsi.u.value[0], + user->usim_data.imsi.u.value[1], + user->usim_data.imsi.u.value[2], + user->usim_data.imsi.u.value[3], + user->usim_data.imsi.u.value[4], + user->usim_data.imsi.u.value[5], + user->usim_data.imsi.u.value[6], + user->usim_data.imsi.u.value[7]); + memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t)); + user->emm_data->nvdata.eplmn.n_plmns = 0; } } /* * Initialize EMM timers */ - T3410.id = NAS_TIMER_INACTIVE_ID; - T3410.sec = T3410_DEFAULT_VALUE; - T3411.id = NAS_TIMER_INACTIVE_ID; - T3411.sec = T3411_DEFAULT_VALUE; - T3402.id = NAS_TIMER_INACTIVE_ID; - T3402.sec = T3402_DEFAULT_VALUE; - T3416.id = NAS_TIMER_INACTIVE_ID; - T3416.sec = T3416_DEFAULT_VALUE; - T3417.id = NAS_TIMER_INACTIVE_ID; - T3417.sec = T3417_DEFAULT_VALUE; - T3418.id = NAS_TIMER_INACTIVE_ID; - T3418.sec = T3418_DEFAULT_VALUE; - T3420.id = NAS_TIMER_INACTIVE_ID; - T3420.sec = T3420_DEFAULT_VALUE; - T3421.id = NAS_TIMER_INACTIVE_ID; - T3421.sec = T3421_DEFAULT_VALUE; - T3423.id = NAS_TIMER_INACTIVE_ID; - T3423.sec = T3423_DEFAULT_VALUE; - T3430.id = NAS_TIMER_INACTIVE_ID; - T3430.sec = T3430_DEFAULT_VALUE; + user->emm_data->emm_timers = calloc_or_fail(sizeof(emm_timers_t)); + _emm_timers_initialize(user->emm_data->emm_timers); + + /* + * Initialize Internal data used for detach procedure + */ + user->emm_data->emm_detach_data = calloc_or_fail(sizeof(emm_detach_data_t)); + _emm_detach_initialize(user->emm_data->emm_detach_data); + + /* + * Initialize Internal data used for attach procedure + */ + user->emm_data->emm_attach_data = calloc_or_fail(sizeof(emm_attach_data_t)); + _emm_attach_initialize(user->emm_data->emm_attach_data); /* * Initialize the user notification callback @@ -392,7 +410,7 @@ void emm_main_initialize(emm_indication_callback_t cb, const char *imei) /* * Initialize EMM internal data used for UE in idle mode */ - IdleMode_initialize(&_emm_main_callback); + IdleMode_initialize(user, &_emm_main_callback); LOG_FUNC_OUT; } @@ -412,56 +430,16 @@ void emm_main_initialize(emm_indication_callback_t cb, const char *imei) ** Others: None ** ** ** ***************************************************************************/ -void emm_main_cleanup(void) +void emm_main_cleanup(nas_user_t *user) { LOG_FUNC_IN; - if (_emm_data.usim_is_valid) { - /* - * TODO: Update USIM application data - */ -#if 0 - int i; - - /* Update the list of Forbidden PLMNs */ - for (i=0; (i < _emm_data.fplmn.n_plmns) && (i < USIM_FPLMN_MAX); i++) { - _usim_data.fplmn[i] = _emm_data.fplmn.plmn[i]; - } - - /* Update the list of Equivalent HPLMNs */ - for (i=0; (i < _emm_data.ehplmn.n_plmns) && (i < USIM_EHPLMN_MAX); i++) { - _usim_data.ehplmn[i] = _emm_data.ehplmn.plmn[i]; - } - - /* Update the GUTI */ - if (_emm_data.guti) { - _usim_data.epsloci.guti = *(_emm_data.guti); - } - - /* Update the last visited registered TAI */ - if (_emm_data.tai) { - _usim_data.epsloci.tai = *(_emm_data.tai); - } - - /* Update the EPS location information */ - _usim_data.epsloci.status = _emm_data.status; - - if (_emm_data.security && (_emm_data.security->type == EMM_KSI_NATIVE)) { - /* TODO: Update the EPS security context parameters from the full - * native EPS security context */ - } + emm_data_t *emm_data = user->emm_data; + if (emm_data->usim_is_valid) { /* - * Store USIM application data - * - List of forbidden PLMNs + * TODO: Update USIM application data */ - if ( usim_api_write(&_usim_data) != RETURNok ) { - /* The USIM application may not be present or not valid */ - LOG_TRACE(WARNING, "EMM-MAIN - " - "Failed to write USIM application data"); - } - -#endif } /* @@ -469,26 +447,20 @@ void emm_main_cleanup(void) * - Registered PLMN * - List of equivalent PLMNs */ - char *path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); - - if (path == NULL) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); - } else { - int rc = memory_write(path, &_emm_data.nvdata, sizeof(emm_nvdata_t)); + int rc = memory_write(user->emm_nvdata_store, &emm_data->nvdata, sizeof(emm_nvdata_t)); - if (rc != RETURNok) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to write %s", path); - } + if (rc != RETURNok) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to write %s", user->emm_nvdata_store); } /* Release dynamically allocated memory */ - if (_emm_data.imei) { - free(_emm_data.imei); - _emm_data.imei = NULL; + if (emm_data->imei) { + free(emm_data->imei); + emm_data->imei = NULL; } - if (_emm_data.security) { - emm_security_context_t *security = _emm_data.security; + if (emm_data->security) { + emm_security_context_t *security = emm_data->security; if (security->kasme.value) { free(security->kasme.value); @@ -508,8 +480,8 @@ void emm_main_cleanup(void) security->knas_int.length = 0; } - free(_emm_data.security); - _emm_data.security = NULL; + free(emm_data->security); + emm_data->security = NULL; } LOG_FUNC_OUT; } @@ -521,17 +493,17 @@ void emm_main_cleanup(void) ** Description: Get the International Mobile Subscriber Identity number ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: Pointer to the IMSI ** ** Others: None ** ** ** ***************************************************************************/ -const imsi_t *emm_main_get_imsi(void) +const imsi_t *emm_main_get_imsi(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (&_emm_data.nvdata.imsi); + LOG_FUNC_RETURN (&emm_data->nvdata.imsi); } /**************************************************************************** @@ -541,17 +513,16 @@ const imsi_t *emm_main_get_imsi(void) ** Description: Get the Mobile Subscriber Dialing Number from the USIM ** ** ** ** Inputs: None ** - ** Others: _usim_data ** ** ** ** Outputs: None ** ** Return: Pointer to the subscriber dialing number ** ** Others: None ** ** ** ***************************************************************************/ -const msisdn_t *emm_main_get_msisdn(void) +const msisdn_t *emm_main_get_msisdn(nas_user_t *user) { LOG_FUNC_IN; - LOG_FUNC_RETURN (&_usim_data.msisdn.number); + LOG_FUNC_RETURN (&user->usim_data.msisdn.number); } /**************************************************************************** @@ -572,32 +543,34 @@ const msisdn_t *emm_main_get_msisdn(void) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_main_set_plmn_selection_mode(int mode, int format, +int emm_main_set_plmn_selection_mode(nas_user_t *user, int mode, int format, const network_plmn_t *plmn, int rat) { LOG_FUNC_IN; int index; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; LOG_TRACE(INFO, "EMM-MAIN - PLMN selection: mode=%d, format=%d, plmn=%s, " "rat=%d", mode, format, (const char *)&plmn->id, rat); - _emm_data.plmn_mode = mode; + emm_data->plmn_mode = mode; if (mode != EMM_DATA_PLMN_AUTO) { /* Get the index of the PLMN in the list of available PLMNs */ - index = _emm_main_get_plmn_index((const char *)&plmn->id, format); + index = _emm_main_get_plmn_index(emm_plmn_list, (const char *)&plmn->id, format); if (index < 0) { LOG_TRACE(WARNING, "EMM-MAIN - PLMN %s not available", (const char *)&plmn->id); } else { /* Update the manually selected network selection data */ - _emm_data.plmn_index = index; - _emm_data.plmn_rat = rat; + emm_data->plmn_index = index; + emm_data->plmn_rat = rat; } } else { /* @@ -605,7 +578,7 @@ int emm_main_set_plmn_selection_mode(int mode, int format, * register to when switched on; the equivalent PLMNs list shall not be * applied to the user reselection in Automatic Network Selection Mode. */ - index = IdleMode_get_hplmn_index(); + index = IdleMode_get_hplmn_index(emm_plmn_list); } LOG_FUNC_RETURN (index); @@ -619,17 +592,17 @@ int emm_main_set_plmn_selection_mode(int mode, int format, ** operation ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: The value of the network selection mode ** ** Others: None ** ** ** ***************************************************************************/ -int emm_main_get_plmn_selection_mode(void) +int emm_main_get_plmn_selection_mode(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.plmn_mode); + LOG_FUNC_RETURN (emm_data->plmn_mode); } /**************************************************************************** @@ -639,19 +612,19 @@ int emm_main_get_plmn_selection_mode(void) ** Description: Get the list of available PLMNs ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: plist: Pointer to the list of available PLMNs ** ** Return: The size of the list in bytes ** ** Others: None ** ** ** ***************************************************************************/ -int emm_main_get_plmn_list(const char **plist) +int emm_main_get_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, const char **plist) { LOG_FUNC_IN; - int size = IdleMode_update_plmn_list(0); - *plist = _emm_data.plist.buffer; + int size = IdleMode_update_plmn_list(emm_plmn_list, emm_data, 0); + *plist = emm_data->plist.buffer; LOG_FUNC_RETURN (size); } @@ -664,7 +637,6 @@ int emm_main_get_plmn_list(const char **plist) ** ** ** Inputs: format: The requested format of the string repre- ** ** sentation of the PLMN identifier ** - ** Others: _emm_data ** ** ** ** Outputs: plmn: The selected PLMN identifier coded in the ** ** requested format ** @@ -673,7 +645,7 @@ int emm_main_get_plmn_list(const char **plist) ** Others: None ** ** ** ***************************************************************************/ -const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format) +const char *emm_main_get_selected_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -681,10 +653,10 @@ const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format) /* * Get the identifier of the selected PLMN in the list of available PLMNs */ - int index = IdleMode_get_splmn_index(); + int index = IdleMode_get_splmn_index(emm_plmn_list); if ( !(index < 0) ) { - const char *name = _emm_main_get_plmn(&_emm_data.splmn, index, + const char *name = _emm_main_get_plmn(emm_plmn_list, &emm_data->splmn, index, format, &size); if (size > 0) { @@ -703,7 +675,6 @@ const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format) ** ** ** Inputs: format: The requested format of the string repre- ** ** sentation of the PLMN identifier ** - ** Others: _emm_data ** ** ** ** Outputs: plmn: The registered PLMN identifier coded in ** ** the requested format ** @@ -712,7 +683,7 @@ const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format) ** Others: None ** ** ** ***************************************************************************/ -const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format) +const char *emm_main_get_registered_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -721,10 +692,10 @@ const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format) /* * Get the identifier of the registered PLMN in the list of available PLMNs */ - int index = IdleMode_get_rplmn_index(); + int index = IdleMode_get_rplmn_index(emm_plmn_list); if ( !(index < 0) ) { - const char *name = _emm_main_get_plmn(&_emm_data.nvdata.rplmn, + const char *name = _emm_main_get_plmn(emm_plmn_list, &emm_data->nvdata.rplmn, index, format, &size); if (size > 0) { @@ -744,17 +715,16 @@ const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format) ** registration of the UE ** ** ** ** Inputs: None ** - ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: The current network registration status ** ** Others: None ** ** ** ***************************************************************************/ -Stat_t emm_main_get_plmn_status(void) +Stat_t emm_main_get_plmn_status(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.stat); + LOG_FUNC_RETURN (emm_data->stat); } /**************************************************************************** @@ -765,17 +735,16 @@ Stat_t emm_main_get_plmn_status(void) ** belongs to ** ** ** ** Inputs: None ** - ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: The Location/Tracking area code ** ** Others: None ** ** ** ***************************************************************************/ -tac_t emm_main_get_plmn_tac(void) +tac_t emm_main_get_plmn_tac(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.tac); + LOG_FUNC_RETURN (emm_data->tac); } /**************************************************************************** @@ -785,17 +754,16 @@ tac_t emm_main_get_plmn_tac(void) ** Description: Get the identifier of the serving cell ** ** ** ** Inputs: None ** - ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: The serving cell identifier ** ** Others: None ** ** ** ***************************************************************************/ -ci_t emm_main_get_plmn_ci(void) +ci_t emm_main_get_plmn_ci(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.ci); + LOG_FUNC_RETURN (emm_data->ci); } /**************************************************************************** @@ -806,7 +774,6 @@ ci_t emm_main_get_plmn_ci(void) ** ving cell ** ** ** ** Inputs: None ** - ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: The value of the Radio Access Technology ** @@ -814,10 +781,10 @@ ci_t emm_main_get_plmn_ci(void) ** Others: None ** ** ** ***************************************************************************/ -AcT_t emm_main_get_plmn_rat(void) +AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.rat); + LOG_FUNC_RETURN (emm_data->rat); } /**************************************************************************** @@ -828,7 +795,7 @@ AcT_t emm_main_get_plmn_rat(void) ** network for EPS services or emergency service only ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: TRUE if the UE is currently attached to ** @@ -836,10 +803,10 @@ AcT_t emm_main_get_plmn_rat(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_main_is_attached(void) +int emm_main_is_attached(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.is_attached); + LOG_FUNC_RETURN (emm_data->is_attached); } /**************************************************************************** @@ -850,7 +817,7 @@ int emm_main_is_attached(void) ** network for emergency bearer services ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: TRUE if the UE is currently attached or is ** @@ -859,10 +826,10 @@ int emm_main_is_attached(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_main_is_emergency(void) +int emm_main_is_emergency(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.is_attached && _emm_data.is_emergency); + LOG_FUNC_RETURN (emm_data->is_attached && emm_data->is_emergency); } /****************************************************************************/ @@ -881,21 +848,21 @@ int emm_main_is_emergency(void) ** present in the network. The list has to be ** ** displayed to the user application when ** ** size > 0. ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ -static int _emm_main_callback(int size) +static int _emm_main_callback(user_api_id_t *user_api_id, emm_data_t *emm_data, int size) { LOG_FUNC_IN; /* Forward the notification to the user API */ - int rc = (*_emm_main_user_callback)(_emm_data.stat, _emm_data.tac, - _emm_data.ci, _emm_data.rat, - _emm_data.plist.buffer, size); + int rc = (*_emm_main_user_callback)(user_api_id, emm_data->stat, emm_data->tac, + emm_data->ci, emm_data->rat, + emm_data->plist.buffer, size); LOG_FUNC_RETURN (rc); } @@ -995,24 +962,24 @@ static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2) ** Others: None ** ** ** ***************************************************************************/ -static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, +static const char *_emm_main_get_plmn(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, int format, size_t *size) { if ( PLMN_IS_VALID(*plmn) ) { switch (format) { case NET_FORMAT_LONG: /* Get the long alpha-numeric representation of the PLMN */ - return IdleMode_get_plmn_fullname(plmn, index, size); + return IdleMode_get_plmn_fullname(emm_plmn_list, plmn, index, size); break; case NET_FORMAT_SHORT: /* Get the short alpha-numeric representation of the PLMN */ - return IdleMode_get_plmn_shortname(plmn, index, size); + return IdleMode_get_plmn_shortname(emm_plmn_list, plmn, index, size); break; case NET_FORMAT_NUM: /* Get the numeric representation of the PLMN */ - return IdleMode_get_plmn_id(plmn, index, size); + return IdleMode_get_plmn_id(emm_plmn_list, plmn, index, size); break; default: @@ -1045,24 +1012,24 @@ static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_main_get_plmn_index(const char *plmn, int format) +static int _emm_main_get_plmn_index(emm_plmn_list_t *emm_plmn_list, const char *plmn, int format) { int index = -1; switch (format) { case NET_FORMAT_LONG: /* Get the index of the long alpha-numeric PLMN identifier */ - index = IdleMode_get_plmn_fullname_index(plmn); + index = IdleMode_get_plmn_fullname_index(emm_plmn_list, plmn); break; case NET_FORMAT_SHORT: /* Get the index of the short alpha-numeric PLMN identifier */ - index = IdleMode_get_plmn_shortname_index(plmn); + index = IdleMode_get_plmn_shortname_index(emm_plmn_list, plmn); break; case NET_FORMAT_NUM: /* Get the index of the numeric PLMN identifier */ - index = IdleMode_get_plmn_id_index(plmn); + index = IdleMode_get_plmn_id_index(emm_plmn_list, plmn); break; default: diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index 1ce584210e5c4183e50653b2ac9b527556f16bbd..aa98965b041245bb818efa4a1a5a3be93f972fd4 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -41,6 +41,7 @@ Description Defines the EPS Mobility Management procedure call manager, #include "commonDef.h" #include "networkDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -50,6 +51,15 @@ Description Defines the EPS Mobility Management procedure call manager, /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * User notification callback, executed whenever a change of data with + * respect of network information (e.g. network registration and/or + * location change, new PLMN becomes available) is notified by the + * EPS Mobility Management sublayer + */ +typedef int (*emm_indication_callback_t) (user_api_id_t *user_api_id, Stat_t, tac_t, ci_t, AcT_t, + const char*, size_t); + /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -58,34 +68,34 @@ Description Defines the EPS Mobility Management procedure call manager, /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_main_initialize(emm_indication_callback_t cb, const char *imei); +void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei); -void emm_main_cleanup(void); +void emm_main_cleanup(nas_user_t *user); /* User's getter of UE's identity */ -const imsi_t *emm_main_get_imsi(void); +const imsi_t *emm_main_get_imsi(emm_data_t *emm_data); /* User's getter of the subscriber dialing number */ -const msisdn_t *emm_main_get_msisdn(void); +const msisdn_t *emm_main_get_msisdn(nas_user_t *user); /* User's getter/setter for network selection */ -int emm_main_set_plmn_selection_mode(int mode, int format, +int emm_main_set_plmn_selection_mode(nas_user_t *user, int mode, int format, const network_plmn_t *plmn, int rat); -int emm_main_get_plmn_selection_mode(void); -int emm_main_get_plmn_list(const char **plist); -const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format); +int emm_main_get_plmn_selection_mode(emm_data_t *emm_data); +int emm_main_get_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, const char **plist); +const char *emm_main_get_selected_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network registration */ -Stat_t emm_main_get_plmn_status(void); -tac_t emm_main_get_plmn_tac(void); -ci_t emm_main_get_plmn_ci(void); -AcT_t emm_main_get_plmn_rat(void); -const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format); +Stat_t emm_main_get_plmn_status(emm_data_t *emm_data); +tac_t emm_main_get_plmn_tac(emm_data_t *emm_data); +ci_t emm_main_get_plmn_ci(emm_data_t *emm_data); +AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data); +const char *emm_main_get_registered_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network attachment */ -int emm_main_is_attached(void); -int emm_main_is_emergency(void); +int emm_main_is_attached(emm_data_t *emm_data); +int emm_main_is_emergency(emm_data_t *emm_data); #endif /* __EMM_MAIN_H__*/ diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 60f71f11c200ebd67ef02b90b5088cfa92dbaead..45052573352c3402fb8f2dcb2e0e9a162f75fa6b 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -42,38 +42,12 @@ Description Defines the EPS Mobility Management procedures executed at #include "commonDef.h" #include "OctetString.h" #include "LowerLayer.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ -/* Type of network attachment */ -typedef enum { - EMM_ATTACH_TYPE_EPS = 0, - EMM_ATTACH_TYPE_IMSI, - EMM_ATTACH_TYPE_EMERGENCY, - EMM_ATTACH_TYPE_RESERVED, -} emm_proc_attach_type_t; - -/* Type of network detach */ -typedef enum { - EMM_DETACH_TYPE_EPS = 0, - EMM_DETACH_TYPE_IMSI, - EMM_DETACH_TYPE_EPS_IMSI, - EMM_DETACH_TYPE_REATTACH, - EMM_DETACH_TYPE_NOT_REATTACH, - EMM_DETACH_TYPE_RESERVED, -} emm_proc_detach_type_t; - -/* Type of requested identity */ -typedef enum { - EMM_IDENT_TYPE_NOT_AVAILABLE = 0, - EMM_IDENT_TYPE_IMSI, - EMM_IDENT_TYPE_IMEI, - EMM_IDENT_TYPE_IMEISV, - EMM_IDENT_TYPE_TMSI -} emm_proc_identity_type_t; - /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ @@ -92,48 +66,35 @@ typedef enum { *--------------------------------------------------------------------------- */ int emm_proc_status_ind(unsigned int ueid, int emm_cause); -int emm_proc_status(unsigned int ueid, int emm_cause); - -/* - *--------------------------------------------------------------------------- - * Lower layer procedure - *--------------------------------------------------------------------------- - */ -int emm_proc_lowerlayer_initialize(lowerlayer_success_callback_t success, - lowerlayer_failure_callback_t failure, - lowerlayer_release_callback_t release, - void *args); -int emm_proc_lowerlayer_success(void); -int emm_proc_lowerlayer_failure(int is_initial); -int emm_proc_lowerlayer_release(void); +int emm_proc_status(nas_user_t *user, int emm_cause); /* *--------------------------------------------------------------------------- * UE's Idle mode procedure *--------------------------------------------------------------------------- */ -int emm_proc_initialize(void); -int emm_proc_plmn_selection(int index); -int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat); +int emm_proc_initialize(nas_user_t *user); +int emm_proc_plmn_selection(nas_user_t *user, int index); +int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat); /* * -------------------------------------------------------------------------- * Attach procedure * -------------------------------------------------------------------------- */ -int emm_proc_attach(emm_proc_attach_type_t type); +int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type); int emm_proc_attach_request(void *args); -int emm_proc_attach_accept(long T3412, long T3402, long T3423, int n_tais, +int emm_proc_attach_accept(nas_user_t *user, long T3412, long T3402, long T3423, int n_tais, tai_t *tai, GUTI_t *guti, int n_eplmns, plmn_t *eplmn, const OctetString *esm_msg); -int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg); +int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *esm_msg); int emm_proc_attach_complete(void *args); int emm_proc_attach_failure(int is_initial, void *args); int emm_proc_attach_release(void *args); -int emm_proc_attach_restart(void); +int emm_proc_attach_restart(nas_user_t *user); -int emm_proc_attach_set_emergency(void); -int emm_proc_attach_set_detach(void); +int emm_proc_attach_set_emergency(emm_data_t *emm_data); +int emm_proc_attach_set_detach(void *user); @@ -142,9 +103,9 @@ int emm_proc_attach_set_detach(void); * Detach procedure * -------------------------------------------------------------------------- */ -int emm_proc_detach(emm_proc_detach_type_t type, int switch_off); +int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_off); int emm_proc_detach_request(void *args); -int emm_proc_detach_accept(void); +int emm_proc_detach_accept(void *args); int emm_proc_detach_failure(int is_initial, void *args); int emm_proc_detach_release(void *args); @@ -154,7 +115,7 @@ int emm_proc_detach_release(void *args); * Identification procedure * -------------------------------------------------------------------------- */ -int emm_proc_identification_request(emm_proc_identity_type_t type); +int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t type); /* @@ -162,10 +123,10 @@ int emm_proc_identification_request(emm_proc_identity_type_t type); * Authentication procedure * -------------------------------------------------------------------------- */ -int emm_proc_authentication_request(int native_ksi, int ksi, +int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, const OctetString *rand, const OctetString *autn); -int emm_proc_authentication_reject(void); -int emm_proc_authentication_delete(void); +int emm_proc_authentication_reject(nas_user_t *user); +int emm_proc_authentication_delete(nas_user_t *user); /* @@ -173,16 +134,16 @@ int emm_proc_authentication_delete(void); * Security mode control procedure * -------------------------------------------------------------------------- */ -int emm_proc_security_mode_command(int native_ksi, int ksi, int seea, int seia, - int reea, int reia,int imeisv_request); +int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, int seea, int seia, + int reea, int reia, int imeisv_request); /* *--------------------------------------------------------------------------- * Network indication handlers *--------------------------------------------------------------------------- */ -int emm_proc_registration_notify(Stat_t status); -int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat); -int emm_proc_network_notify(int index); +int emm_proc_registration_notify(user_api_id_t *user_api_id, emm_data_t *emm_data, Stat_t status); +int emm_proc_location_notify(user_api_id_t *user_api_id, emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat); +int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, user_api_id_t *user_api_id, emm_data_t *emm_data, int index); #endif /* __EMM_PROC_H__*/ diff --git a/openair3/NAS/UE/EMM/emm_proc_defs.h b/openair3/NAS/UE/EMM/emm_proc_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..3779626ac0c384bc3c6fa997d6d12aaaf1be0e60 --- /dev/null +++ b/openair3/NAS/UE/EMM/emm_proc_defs.h @@ -0,0 +1,31 @@ +#ifndef _EMM_PROC_DEFS_H +#define _EMM_PROC_DEFS_H + +/* Type of network attachment */ +typedef enum { + EMM_ATTACH_TYPE_EPS = 0, + EMM_ATTACH_TYPE_IMSI, + EMM_ATTACH_TYPE_EMERGENCY, + EMM_ATTACH_TYPE_RESERVED, +} emm_proc_attach_type_t; + +/* Type of network detach */ +typedef enum { + EMM_DETACH_TYPE_EPS = 0, + EMM_DETACH_TYPE_IMSI, + EMM_DETACH_TYPE_EPS_IMSI, + EMM_DETACH_TYPE_REATTACH, + EMM_DETACH_TYPE_NOT_REATTACH, + EMM_DETACH_TYPE_RESERVED, +} emm_proc_detach_type_t; + +/* Type of requested identity */ +typedef enum { + EMM_IDENT_TYPE_NOT_AVAILABLE = 0, + EMM_IDENT_TYPE_IMSI, + EMM_IDENT_TYPE_IMEI, + EMM_IDENT_TYPE_IMEISV, + EMM_IDENT_TYPE_TMSI +} emm_proc_identity_type_t; + +#endif diff --git a/openair3/NAS/UE/EMM/emm_timers.h b/openair3/NAS/UE/EMM/emm_timers.h new file mode 100644 index 0000000000000000000000000000000000000000..abf7c9ff87411aa362e1e4141af4adeab4d0fbd8 --- /dev/null +++ b/openair3/NAS/UE/EMM/emm_timers.h @@ -0,0 +1,14 @@ +#ifndef EMM_TIMERS_H +#define EMM_TIMERS_H + +/* + * Retransmission timer handlers + */ + +void *emm_attach_t3410_handler(void *); +void *emm_service_t3417_handler(void *); +void *emm_detach_t3421_handler(void *); +void *emm_tau_t3430_handler(void *); + + +#endif diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index 21e54fd2d033371dfe99d76bea4b8825a85ffd7a..e2133563324f60c61df629acfeb0304d7211e6f1 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -104,20 +104,20 @@ Description Defines the dedicated EPS bearer context activation ESM ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, +int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int default_ebi, const esm_proc_qos_t *qos, const esm_proc_tft_t *tft, int *esm_cause) { LOG_FUNC_IN; - + esm_data_t *esm_data = user->esm_data; int rc = RETURNerror; LOG_TRACE(INFO, "ESM-PROC - Dedicated EPS bearer context activation " "requested by the network (ebi=%d)", ebi); /* Get the PDN connection the dedicated EPS bearer is linked to */ - int pid = esm_ebr_context_get_pid(default_ebi); + int pid = esm_ebr_context_get_pid(esm_data, default_ebi); if (pid < 0) { /* 3GPP TS 24.301, section 6.4.2.5, abnormal case c @@ -131,7 +131,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, } /* Assign dedicated EPS bearer context */ - int new_ebi = esm_ebr_assign(ebi, pid+1, FALSE); + int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE); if (new_ebi == ESM_EBI_UNASSIGNED) { /* 3GPP TS 24.301, section 6.4.2.5, abnormal cases a and b @@ -141,7 +141,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested dedicated EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -149,13 +149,13 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; } else { /* Assign new dedicated EPS bearer context */ - ebi = esm_ebr_assign(ebi, pid+1, FALSE); + ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE); } } if (ebi != ESM_EBI_UNASSIGNED) { /* Check syntactical errors in packet filters */ - rc = esm_ebr_context_check_tft(pid, ebi, tft, + rc = esm_ebr_context_check_tft(esm_data, pid, ebi, tft, ESM_EBR_CONTEXT_TFT_CREATE); if (rc != RETURNok) { @@ -165,7 +165,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, *esm_cause = ESM_CAUSE_SYNTACTICAL_ERROR_IN_PACKET_FILTER; } else { /* Create new dedicated EPS bearer context */ - default_ebi = esm_ebr_context_create(pid, ebi, FALSE, qos, tft); + default_ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, FALSE, qos, tft); if (default_ebi != ESM_EBI_UNASSIGNED) { /* Dedicated EPS bearer contextx successfully created */ @@ -206,12 +206,14 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, +int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; int rc; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; LOG_TRACE(INFO,"ESM-PROC - Dedicated EPS bearer context activation " "accepted by the UE (ebi=%d)", ebi); @@ -222,14 +224,14 @@ int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Set the EPS bearer context state to ACTIVE */ - rc = esm_ebr_set_status(ebi, ESM_EBR_ACTIVE, ue_triggered); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in ACTIVE state */ @@ -266,7 +268,7 @@ int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, +int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; @@ -276,9 +278,9 @@ int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, LOG_TRACE(WARNING, "ESM-PROC - Dedicated EPS bearer context activation " "not accepted by the UE (ebi=%d)", ebi); - if ( !esm_ebr_is_not_in_use(ebi) ) { + if ( !esm_ebr_is_not_in_use(user->esm_ebr_data, ebi) ) { /* Release EPS bearer data currently in use */ - rc = esm_ebr_release(ebi); + rc = esm_ebr_release(user->esm_ebr_data, ebi); } if (rc != RETURNok) { @@ -290,10 +292,10 @@ int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 82c4e51be8ea82b88d99ac61b536901b0976d12f..a438d65ddb28cac1c76f1240a236f5e163b36e46 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -63,19 +63,6 @@ Description Defines the default EPS bearer context activation ESM /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -/* - * -------------------------------------------------------------------------- - * Internal data handled by the default EPS bearer context activation - * procedure in the UE - * -------------------------------------------------------------------------- - */ -static struct { - int ebi; /* EPS bearer identity of the default EPS bearer associated - * to the PDN connection to be activated */ -} _default_eps_bearer_context_data = {ESM_EBI_UNASSIGNED}; - - - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -101,22 +88,22 @@ static struct { ** Outputs: esm_cause: Cause code returned upon ESM procedure ** ** failure ** ** Return: RETURNok, RETURNerror ** - ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_request(int pid, int ebi, +int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int ebi, const esm_proc_qos_t *qos, int *esm_cause) { LOG_FUNC_IN; - + esm_data_t *esm_data = user->esm_data; + default_eps_bearer_context_data_t *default_eps_bearer_context_data = user->default_eps_bearer_context_data; int rc = RETURNerror; LOG_TRACE(INFO, "ESM-PROC - Default EPS bearer context activation " "requested by the network (ebi=%d)", ebi); /* Assign default EPS bearer context */ - int new_ebi = esm_ebr_assign(ebi, pid+1, TRUE); + int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE); if (new_ebi == ESM_EBI_UNASSIGNED) { /* 3GPP TS 24.301, section 6.4.1.5, abnormal cases a and b @@ -126,7 +113,7 @@ int esm_proc_default_eps_bearer_context_request(int pid, int ebi, int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested default EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -134,17 +121,17 @@ int esm_proc_default_eps_bearer_context_request(int pid, int ebi, *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; } else { /* Assign new default EPS bearer context */ - ebi = esm_ebr_assign(ebi, pid+1, TRUE); + ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE); } } if (ebi != ESM_EBI_UNASSIGNED) { /* Create new default EPS bearer context */ - ebi = esm_ebr_context_create(pid, ebi, TRUE, qos, NULL); + ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, TRUE, qos, NULL); if (ebi != ESM_EBI_UNASSIGNED) { /* Default EPS bearer contextx successfully created */ - _default_eps_bearer_context_data.ebi = ebi; + default_eps_bearer_context_data->ebi = ebi; rc = RETURNok; } else { /* No resource available */ @@ -188,12 +175,14 @@ int esm_proc_default_eps_bearer_context_request(int pid, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi, +int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; int rc = RETURNok; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; LOG_TRACE(INFO,"ESM-PROC - Default EPS bearer context activation " "accepted by the UE (ebi=%d)", ebi); @@ -205,15 +194,15 @@ int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi, * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } if (rc != RETURNerror) { /* Set the EPS bearer context state to ACTIVE */ - rc = esm_ebr_set_status(ebi, ESM_EBR_ACTIVE, ue_triggered); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in ACTIVE state */ @@ -256,7 +245,7 @@ int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, +int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; @@ -266,9 +255,9 @@ int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, LOG_TRACE(WARNING, "ESM-PROC - Default EPS bearer context activation " "not accepted by the UE (ebi=%d)", ebi); - if ( !esm_ebr_is_not_in_use(ebi) ) { + if ( !esm_ebr_is_not_in_use(user->esm_ebr_data, ebi) ) { /* Release EPS bearer data currently in use */ - rc = esm_ebr_release(ebi); + rc = esm_ebr_release(user->esm_ebr_data, ebi); } if (rc != RETURNok) { @@ -280,10 +269,10 @@ int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } else { /* An error is returned to notify EMM that the default EPS bearer * activation procedure initiated as part of the initial attach @@ -310,10 +299,9 @@ int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_complete(void) +int esm_proc_default_eps_bearer_context_complete(default_eps_bearer_context_data_t *default_eps_bearer_context_data) { LOG_FUNC_IN; @@ -321,7 +309,7 @@ int esm_proc_default_eps_bearer_context_complete(void) "ESM-PROC - Default EPS bearer context activation complete"); /* Reset default EPS bearer context internal data */ - _default_eps_bearer_context_data.ebi = ESM_EBI_UNASSIGNED; + default_eps_bearer_context_data->ebi = ESM_EBI_UNASSIGNED; LOG_FUNC_RETURN (RETURNok); } @@ -339,40 +327,29 @@ int esm_proc_default_eps_bearer_context_complete(void) ** ACCEPT message was sent. ** ** ** ** Inputs: None ** - ** Others: _default_eps_bearer_context_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_failure(void) +int esm_proc_default_eps_bearer_context_failure(nas_user_t *user) { LOG_FUNC_IN; + default_eps_bearer_context_data_t *default_eps_bearer_context_data = user->default_eps_bearer_context_data; - int ebi = _default_eps_bearer_context_data.ebi; + int ebi = default_eps_bearer_context_data->ebi; int pid, bid; LOG_TRACE(WARNING, "ESM-PROC - Default EPS bearer context activation failure"); /* Release the default EPS bearer context and enter state INACTIVE */ - int rc = esm_proc_eps_bearer_context_deactivate(TRUE, ebi, &pid, &bid); + int rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, &pid, &bid); if (rc != RETURNerror) { /* Reset default EPS bearer context internal data */ - _default_eps_bearer_context_data.ebi = ESM_EBI_UNASSIGNED; + default_eps_bearer_context_data->ebi = ESM_EBI_UNASSIGNED; } LOG_FUNC_RETURN (rc); } - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/* - * -------------------------------------------------------------------------- - * Timer handlers - * -------------------------------------------------------------------------- - */ diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c index 774c80e97fe453b018e17166801f000e33491083..6ba5e6e1cc2233f16faba458817d6d7ef477ac05 100644 --- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c +++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c @@ -74,7 +74,7 @@ Description Defines the EPS bearer context deactivation ESM procedure * in the UE * -------------------------------------------------------------------------- */ -static int _eps_bearer_release(int ebi, int *pid, int *bid); +static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid); /****************************************************************************/ @@ -102,7 +102,6 @@ static int _eps_bearer_release(int ebi, int *pid, int *bid); ** gnalling between the UE and the MME ** ** ebi: EPS bearer identity of the EPS bearer con- ** ** text to be deactivated ** - ** Others: _esm_data ** ** ** ** Outputs: pid: Identifier of the PDN connection the EPS ** ** bearer belongs to ** @@ -112,25 +111,25 @@ static int _eps_bearer_release(int ebi, int *pid, int *bid); ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, +int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, int is_local, int ebi, int *pid, int *bid) { LOG_FUNC_IN; int rc = RETURNerror; int i; - + esm_data_t *esm_data = user->esm_data; if (is_local) { if (ebi != ESM_SAP_ALL_EBI) { /* Locally release the EPS bearer context */ - rc = _eps_bearer_release(ebi, pid, bid); + rc = _eps_bearer_release(user, ebi, pid, bid); } else { /* Locally release all the EPS bearer contexts */ *bid = 0; for (*pid = 0; *pid < ESM_DATA_PDN_MAX; (*pid)++) { - if (_esm_data.pdn[*pid].data) { - rc = _eps_bearer_release(ESM_EBI_UNASSIGNED, pid, bid); + if (esm_data->pdn[*pid].data) { + rc = _eps_bearer_release(user, ESM_EBI_UNASSIGNED, pid, bid); if (rc != RETURNok) { break; @@ -146,17 +145,17 @@ int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, ebi); if (*pid < ESM_DATA_PDN_MAX) { - if (_esm_data.pdn[*pid].pid != *pid) { + if (esm_data->pdn[*pid].pid != *pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier %d " "is not valid", *pid); - } else if (_esm_data.pdn[*pid].data == NULL) { + } else if (esm_data->pdn[*pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection %d has not been " "allocated", *pid); - } else if (!_esm_data.pdn[*pid].is_active) { + } else if (!esm_data->pdn[*pid].is_active) { LOG_TRACE(WARNING, "ESM-PROC - PDN connection %d is not active", *pid); } else { - esm_pdn_t *pdn = _esm_data.pdn[*pid].data; + esm_pdn_t *pdn = esm_data->pdn[*pid].data; for (i = 0; i < pdn->n_bearers; i++) { if (pdn->bearer[i]->ebi != ebi) { @@ -189,18 +188,19 @@ int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause) +int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, int *esm_cause) { LOG_FUNC_IN; int pid, bid; int rc = RETURNok; + esm_data_t *esm_data = user->esm_data; LOG_TRACE(INFO, "ESM-PROC - EPS bearer context deactivation " "requested by the network (ebi=%d)", ebi); /* Release the EPS bearer context entry */ - if (esm_ebr_context_release(ebi, &pid, &bid) == ESM_EBI_UNASSIGNED) { + if (esm_ebr_context_release(user, ebi, &pid, &bid) == ESM_EBI_UNASSIGNED) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; LOG_FUNC_RETURN (RETURNerror); @@ -222,7 +222,7 @@ int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause) "connection reactivation"); /* Get PDN context parameters */ - rc = esm_main_get_pdn(pid + 1, &esm_sap.data.pdn_connect.pdn_type, + rc = esm_main_get_pdn(esm_data, pid + 1, &esm_sap.data.pdn_connect.pdn_type, &esm_sap.data.pdn_connect.apn, &esm_sap.data.pdn_connect.is_emergency, &active); @@ -243,7 +243,7 @@ int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause) esm_sap.is_standalone = TRUE; esm_sap.data.pdn_connect.is_defined = TRUE; esm_sap.data.pdn_connect.cid = pid + 1; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } } } @@ -275,12 +275,14 @@ int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause) ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, +int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; int rc = RETURNok; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; LOG_TRACE(INFO,"ESM-PROC - EPS bearer context deactivation accepted"); @@ -290,15 +292,15 @@ int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_sap.u.emm_esm.u.data.msg.length = msg->length; emm_sap.u.emm_esm.u.data.msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } if (rc != RETURNerror) { /* Set the EPS bearer context state to INACTIVE */ - rc = esm_ebr_set_status(ebi, ESM_EBR_INACTIVE, ue_triggered); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_INACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in INACTIVE state */ @@ -309,7 +311,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, } /* Release EPS bearer data */ - rc = esm_ebr_release(ebi); + rc = esm_ebr_release(esm_ebr_data, ebi); } LOG_FUNC_RETURN (rc); @@ -352,27 +354,29 @@ int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, ** Others: None ** ** ** ***************************************************************************/ -static int _eps_bearer_release(int ebi, int *pid, int *bid) +static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid) { LOG_FUNC_IN; int rc = RETURNerror; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; /* Release the EPS bearer context entry */ - ebi = esm_ebr_context_release(ebi, pid, bid); + ebi = esm_ebr_context_release(user, ebi, pid, bid); if (ebi == ESM_EBI_UNASSIGNED) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); } else { /* Set the EPS bearer context state to INACTIVE */ - rc = esm_ebr_set_status(ebi, ESM_EBR_INACTIVE, FALSE); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_INACTIVE, FALSE); if (rc != RETURNok) { /* The EPS bearer context was already in INACTIVE state */ LOG_TRACE(WARNING, "ESM-PROC - EBI %d was already INACTIVE", ebi); } else { /* Release EPS bearer data */ - rc = esm_ebr_release(ebi); + rc = esm_ebr_release(esm_ebr_data, ebi); if (rc != RETURNok) { LOG_TRACE(WARNING, diff --git a/openair3/NAS/UE/ESM/EsmStatusHdl.c b/openair3/NAS/UE/ESM/EsmStatusHdl.c index 48e86f4a6062c2ecb12972190f7899a710ab032f..4c8e0aafc1386f089e1a9a0c0f02ebc0df5401aa 100644 --- a/openair3/NAS/UE/ESM/EsmStatusHdl.c +++ b/openair3/NAS/UE/ESM/EsmStatusHdl.c @@ -161,7 +161,7 @@ int esm_proc_status_ind( ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_status(int is_standalone, +int esm_proc_status(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { @@ -176,10 +176,10 @@ int esm_proc_status(int is_standalone, * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_sap.u.emm_esm.u.data.msg.length = msg->length; emm_sap.u.emm_esm.u.data.msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index 2d8718b0a30c6dc0d00c46c453e20307102b3b25..c51d08cdbc289032cddc18d597d95f67da1cd373 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -81,15 +81,15 @@ Description Defines the PDN connectivity ESM procedure executed by the /* * PDN connection handlers */ -static int _pdn_connectivity_create(int pid, const OctetString *apn, +static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, int is_emergency); -static int _pdn_connectivity_update(int pid, const OctetString *apn, +static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, int esm_cause); -static int _pdn_connectivity_delete(int pid); +static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid); -static int _pdn_connectivity_set_pti(int pid, int pti); -static int _pdn_connectivity_find_apn(const OctetString *apn); -static int _pdn_connectivity_find_pdn(const OctetString *apn, +static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti); +static int _pdn_connectivity_find_apn(esm_data_t *esm_data, const OctetString *apn); +static int _pdn_connectivity_find_pdn(esm_data_t * esm_data, const OctetString *apn, esm_proc_pdn_type_t pdn_type); /* @@ -131,10 +131,9 @@ static void *_pdn_connectivity_t3482_handler(void *); ** the new PDN connection or the released PDN ** ** connection ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_data ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity(int cid, int is_to_define, +int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency, unsigned int *pti) @@ -143,15 +142,17 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, int rc = RETURNerror; int pid = cid - 1; + esm_data_t *esm_data = user-> esm_data; + esm_pt_data_t *esm_pt_data = user-> esm_pt_data; if (!is_to_define) { LOG_TRACE(INFO, "ESM-PROC - Undefine PDN connection (cid=%d)", cid); /* Delete the PDN connection entry */ - int pti = _pdn_connectivity_delete(pid); + int pti = _pdn_connectivity_delete(esm_data, pid); if (pti != ESM_PT_UNASSIGNED) { /* Release the procedure transaction data */ - rc = esm_pt_release(pti); + rc = esm_pt_release(esm_pt_data, pti); } LOG_FUNC_RETURN(rc); @@ -159,7 +160,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, LOG_TRACE(INFO, "ESM-PROC - Assign new procedure transaction identity " "(cid=%d)", cid); /* Assign new procedure transaction identity */ - *pti = esm_pt_assign(); + *pti = esm_pt_assign(esm_pt_data); if (*pti == ESM_PT_UNASSIGNED) { LOG_TRACE(WARNING, "ESM-PROC - Failed to assign new procedure " @@ -168,7 +169,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, } /* Update the PDN connection data */ - rc = _pdn_connectivity_set_pti(pid, *pti); + rc = _pdn_connectivity_set_pti(esm_data, pid, *pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to update PDN connection"); @@ -182,14 +183,14 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, (pdn_type == ESM_PDN_TYPE_IPV6)? "IPv6" : "IPv4v6", apn->value, cid); - if (is_emergency && _esm_data.emergency) { + if (is_emergency && esm_data->emergency) { /* The UE shall not request additional PDN connection for * emergency bearer services */ LOG_TRACE(WARNING, "ESM-PROC - PDN connection for emergency bearer " "services is already active"); LOG_FUNC_RETURN (RETURNerror); } else if (pid < ESM_DATA_PDN_MAX) { - if ((pid == _esm_data.pdn[pid].pid) && (_esm_data.pdn[pid].is_active)) { + if ((pid == esm_data->pdn[pid].pid) && (esm_data->pdn[pid].is_active)) { /* PDN connection with the specified identifier is active */ LOG_TRACE(WARNING, "ESM-PROC - PDN connection is active"); LOG_FUNC_RETURN (RETURNerror); @@ -201,15 +202,15 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, if (apn && apn->length > 0) { /* The UE requested subsequent connectivity to additionnal PDNs */ - int pid = _pdn_connectivity_find_apn(apn); + int pid = _pdn_connectivity_find_apn(esm_data, apn); - if ( (pid >= 0) && _esm_data.pdn[pid].is_active ) { + if ( (pid >= 0) && esm_data->pdn[pid].is_active ) { /* An active PDN connection to this APN already exists */ - if ( (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV4V6) && - (_esm_data.pdn[pid].data->type != pdn_type) ) { + if ( (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4V6) && + (esm_data->pdn[pid].data->type != pdn_type) ) { /* The UE is requesting PDN connection for other IP version * than the one already activated */ - if (!_esm_data.pdn[pid].data->addr_realloc) { + if (!esm_data->pdn[pid].data->addr_realloc) { /* The network does not allow PDN connectivity using * IPv4 and IPv6 address versions to the same APN */ if (pdn_type != ESM_PDN_TYPE_IPV4V6) { @@ -220,7 +221,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, } else { LOG_TRACE(WARNING, "ESM-PROC - %s PDN connection to %s " "already exists", - (_esm_data.pdn[pid].data->type != + (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? "IPv6" : "IPv4", apn->value); } @@ -232,8 +233,8 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, * same IP version than the one already activated */ LOG_TRACE(WARNING, "ESM-PROC - %s PDN connection to %s " "already exists", - (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? - (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV6)? + (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? + (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV6)? "IPv4v6" : "IPv6" : "IPv4", apn->value); LOG_FUNC_RETURN (RETURNerror); } @@ -248,7 +249,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, * not already established, or may have been allowed to request PDN * connectivity for other IP version than the one already activated */ - rc = _pdn_connectivity_create(pid, apn, pdn_type, is_emergency); + rc = _pdn_connectivity_create(esm_data, pid, apn, pdn_type, is_emergency); LOG_FUNC_RETURN(rc); } @@ -279,11 +280,11 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_request(int is_standalone, int pti, +int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc = RETURNok; LOG_TRACE(INFO, "ESM-PROC - Initiate PDN connectivity (pti=%d)", pti); @@ -295,21 +296,21 @@ int esm_proc_pdn_connectivity_request(int is_standalone, int pti, * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Start T3482 retransmission timer */ - rc = esm_pt_start_timer(pti, msg, T3482_DEFAULT_VALUE, + rc = esm_pt_start_timer(user, pti, msg, T3482_DEFAULT_VALUE, _pdn_connectivity_t3482_handler); } } if (rc != RETURNerror) { /* Set the procedure transaction state to PENDING */ - rc = esm_pt_set_status(pti, ESM_PT_PENDING); + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_PENDING); if (rc != RETURNok) { /* The procedure transaction was already in PENDING state */ @@ -346,12 +347,13 @@ int esm_proc_pdn_connectivity_request(int is_standalone, int pti, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, +int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, const OctetString *apn, int *esm_cause) { LOG_FUNC_IN; - + esm_data_t *esm_data = user->esm_data; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc; int pid = RETURNerror; char apn_first_char[4]; @@ -369,9 +371,9 @@ int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, esm_data_get_ipv4v6_addr(pdn_addr)); /* Stop T3482 timer if running */ - (void) esm_pt_stop_timer(pti); + esm_pt_stop_timer(esm_pt_data, pti); /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state @@ -391,7 +393,7 @@ int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, */ /* Check whether a PDN connection exists to this APN */ - pid = _pdn_connectivity_find_pdn(apn, pdn_type); + pid = _pdn_connectivity_find_pdn(esm_data, apn, pdn_type); if (pid < 0) { /* No any PDN connection has been defined to establish connectivity @@ -403,7 +405,7 @@ int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, } /* Update the PDN connection */ - rc = _pdn_connectivity_update(pid, apn, pdn_type, pdn_addr, *esm_cause); + rc = _pdn_connectivity_update(esm_data, pid, apn, pdn_type, pdn_addr, *esm_cause); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to update PDN connection " @@ -438,19 +440,19 @@ int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_reject(int pti, int *esm_cause) +int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc; LOG_TRACE(WARNING, "ESM-PROC - PDN connectivity rejected by " "the network (pti=%d), ESM cause = %d", pti, *esm_cause); /* Stop T3482 timer if running */ - (void) esm_pt_stop_timer(pti); + (void) esm_pt_stop_timer(esm_pt_data, pti); /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state */ @@ -458,7 +460,7 @@ int esm_proc_pdn_connectivity_reject(int pti, int *esm_cause) *esm_cause = ESM_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE; } else { /* Release the procedure transaction identity */ - rc = esm_pt_release(pti); + rc = esm_pt_release(user->esm_pt_data, pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); @@ -489,21 +491,21 @@ int esm_proc_pdn_connectivity_reject(int pti, int *esm_cause) ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_complete(void) +int esm_proc_pdn_connectivity_complete(nas_user_t *user) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc = RETURNerror; LOG_TRACE(INFO, "ESM-PROC - PDN connectivity complete"); /* Get the procedure transaction identity assigned to the PDN connection * entry which is still pending in the inactive state */ - int pti = esm_pt_get_pending_pti(ESM_PT_INACTIVE); + int pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_INACTIVE); if (pti != ESM_PT_UNASSIGNED) { /* Release the procedure transaction identity */ - rc = esm_pt_release(pti); + rc = esm_pt_release(esm_pt_data, pti); } LOG_FUNC_RETURN(rc); @@ -530,10 +532,10 @@ int esm_proc_pdn_connectivity_complete(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_failure(int is_pending) +int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc; int pti; @@ -543,7 +545,7 @@ int esm_proc_pdn_connectivity_failure(int is_pending) if (is_pending) { /* Get the procedure transaction identity assigned to the pending PDN * connection entry */ - pti = esm_pt_get_pending_pti(ESM_PT_PENDING); + pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_PENDING); if (pti == ESM_PT_UNASSIGNED) { LOG_TRACE(ERROR, "ESM-PROC - No procedure transaction is PENDING"); @@ -551,15 +553,15 @@ int esm_proc_pdn_connectivity_failure(int is_pending) } /* Set the procedure transaction state to INACTIVE */ - (void) esm_pt_set_status(pti, ESM_PT_INACTIVE); + (void) esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); } else { /* Get the procedure transaction identity assigned to the PDN * connection entry which is still pending in the inactive state */ - pti = esm_pt_get_pending_pti(ESM_PT_INACTIVE); + pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_INACTIVE); } /* Release the procedure transaction identity */ - rc = esm_pt_release(pti); + rc = esm_pt_release(esm_pt_data, pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); @@ -603,6 +605,7 @@ int esm_proc_pdn_connectivity_failure(int is_pending) ** Others: None ** ** ** ***************************************************************************/ +// FIXME static void *_pdn_connectivity_t3482_handler(void *args) { LOG_FUNC_IN; @@ -610,7 +613,9 @@ static void *_pdn_connectivity_t3482_handler(void *args) int rc; /* Get retransmission timer parameters data */ - esm_pt_timer_data_t *data = (esm_pt_timer_data_t *)(args); + esm_pt_timer_data_t *data = args; + nas_user_t *user = data->user; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; /* Increment the retransmission counter */ data->count += 1; @@ -626,19 +631,19 @@ static void *_pdn_connectivity_t3482_handler(void *args) * has to be sent again */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = data->msg.length; emm_esm->msg.value = data->msg.value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Restart the timer T3482 */ - rc = esm_pt_start_timer(data->pti, &data->msg, T3482_DEFAULT_VALUE, + rc = esm_pt_start_timer(user, data->pti, &data->msg, T3482_DEFAULT_VALUE, _pdn_connectivity_t3482_handler); } } else { /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(data->pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(esm_pt_data, data->pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state */ @@ -646,7 +651,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) data->pti); } else { /* Release the transaction identity assigned to this procedure */ - rc = esm_pt_release(data->pti); + rc = esm_pt_release(esm_pt_data, data->pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", @@ -676,14 +681,12 @@ static void *_pdn_connectivity_t3482_handler(void *args) ** pdn_type: PDN type (IPv4, IPv6, IPv4v6) ** ** is_emergency: TRUE if the PDN connection has to be esta- ** ** blished for emergency bearer services ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_data ** ** ** ***************************************************************************/ -static int _pdn_connectivity_create(int pid, const OctetString *apn, +static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, int is_emergency) { @@ -693,14 +696,14 @@ static int _pdn_connectivity_create(int pid, const OctetString *apn, if (pid >= ESM_DATA_PDN_MAX) { return (RETURNerror); - } else if (_esm_data.pdn[pid].is_active) { + } else if (esm_data->pdn[pid].is_active) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); return (RETURNerror); } - if (_esm_data.pdn[pid].data != NULL) { + if (esm_data->pdn[pid].data != NULL) { /* Update existing non-active PDN connection */ - pdn = _esm_data.pdn[pid].data; + pdn = esm_data->pdn[pid].data; } else { /* Create new PDN connection */ pdn = (esm_pdn_t *)malloc(sizeof(esm_pdn_t)); @@ -713,13 +716,13 @@ static int _pdn_connectivity_create(int pid, const OctetString *apn, memset(pdn, 0, sizeof(esm_pdn_t)); /* Increment the number of PDN connections */ - _esm_data.n_pdns += 1; + esm_data->n_pdns += 1; /* Set the PDN connection identifier */ - _esm_data.pdn[pid].pid = pid; + esm_data->pdn[pid].pid = pid; /* Reset the PDN connection active indicator */ - _esm_data.pdn[pid].is_active = FALSE; + esm_data->pdn[pid].is_active = FALSE; /* Setup the PDN connection data */ - _esm_data.pdn[pid].data = pdn; + esm_data->pdn[pid].data = pdn; } /* Update the PDN connection data */ @@ -760,10 +763,9 @@ static int _pdn_connectivity_create(int pid, const OctetString *apn, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_data ** ** ** ***************************************************************************/ -static int _pdn_connectivity_update(int pid, const OctetString *apn, +static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, int esm_cause) @@ -772,21 +774,21 @@ static int _pdn_connectivity_update(int pid, const OctetString *apn, if (pid >= ESM_DATA_PDN_MAX) { return (RETURNerror); - } else if (pid != _esm_data.pdn[pid].pid) { + } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier is not valid"); return (RETURNerror); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection has not been allocated"); return (RETURNerror); - } else if (_esm_data.pdn[pid].is_active) { + } else if (esm_data->pdn[pid].is_active) { LOG_TRACE(WARNING, "ESM-PROC - Active %s PDN connection to %s already " - "exists", (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? - "IPv6" : "IPv4", _esm_data.pdn[pid].data->apn.value); + "exists", (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? + "IPv6" : "IPv4", esm_data->pdn[pid].data->apn.value); return (RETURNerror); } /* Get the PDN connection */ - esm_pdn_t *pdn = _esm_data.pdn[pid].data; + esm_pdn_t *pdn = esm_data->pdn[pid].data; /* Setup the Access Point Name value */ if ( apn && (apn->length > 0) ) { @@ -847,49 +849,47 @@ static int _pdn_connectivity_update(int pid, const OctetString *apn, ** ** ** Inputs: pid: Identifier of the PDN connection to be ** ** released ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The identity of the procedure transaction ** ** assigned to the PDN connection when suc- ** ** cessfully released; ** ** UNASSIGNED value otherwise. ** - ** Others: _esm_data ** ** ** ***************************************************************************/ -static int _pdn_connectivity_delete(int pid) +static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid) { int pti = ESM_PT_UNASSIGNED; if (pid < ESM_DATA_PDN_MAX) { - if (pid != _esm_data.pdn[pid].pid) { + if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier is not valid"); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection has not been allocated"); - } else if (_esm_data.pdn[pid].is_active) { + } else if (esm_data->pdn[pid].is_active) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); } else { /* Get the identity of the procedure transaction that created * the PDN connection */ - pti = _esm_data.pdn[pid].data->pti; + pti = esm_data->pdn[pid].data->pti; } } if (pti != ESM_PT_UNASSIGNED) { /* Decrement the number of PDN connections */ - _esm_data.n_pdns -= 1; + esm_data->n_pdns -= 1; /* Set the PDN connection as available */ - _esm_data.pdn[pid].pid = -1; + esm_data->pdn[pid].pid = -1; /* Release allocated PDN connection data */ - if (_esm_data.pdn[pid].data->apn.length > 0) { - free(_esm_data.pdn[pid].data->apn.value); + if (esm_data->pdn[pid].data->apn.length > 0) { + free(esm_data->pdn[pid].data->apn.value); } - free(_esm_data.pdn[pid].data); - _esm_data.pdn[pid].data = NULL; + free(esm_data->pdn[pid].data); + esm_data->pdn[pid].data = NULL; LOG_TRACE(WARNING, "ESM-PROC - PDN connection %d released", pid); } @@ -910,24 +910,23 @@ static int _pdn_connectivity_delete(int pid) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_data ** ** ** ***************************************************************************/ -static int _pdn_connectivity_set_pti(int pid, int pti) +static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti) { if (pid < ESM_DATA_PDN_MAX) { - if (pid != _esm_data.pdn[pid].pid) { + if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier is not valid"); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection has not been allocated"); - } else if (_esm_data.pdn[pid].is_active) { + } else if (esm_data->pdn[pid].is_active) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); } else { /* Update the identity of the procedure transaction assigned to * the PDN connection */ - _esm_data.pdn[pid].data->pti = pti; + esm_data->pdn[pid].data->pti = pti; return (RETURNok); } } @@ -943,7 +942,6 @@ static int _pdn_connectivity_set_pti(int pid, int pti) ** for the specified APN ** ** ** ** Inputs: apn: Access Point Name of the PDN connection ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The identifier of the PDN connection if ** @@ -951,17 +949,17 @@ static int _pdn_connectivity_set_pti(int pid, int pti) ** Others: None ** ** ** ***************************************************************************/ -static int _pdn_connectivity_find_apn(const OctetString *apn) +static int _pdn_connectivity_find_apn(esm_data_t *esm_data, const OctetString *apn) { int i; for (i = 0; i < ESM_DATA_PDN_MAX; i++) { - if ( (_esm_data.pdn[i].pid != -1) && _esm_data.pdn[i].data ) { - if (_esm_data.pdn[i].data->apn.length != apn->length) { + if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { + if (esm_data->pdn[i].data->apn.length != apn->length) { continue; } - if (memcmp(_esm_data.pdn[i].data->apn.value, + if (memcmp(esm_data->pdn[i].data->apn.value, apn->value, apn->length) != 0) { continue; } @@ -972,7 +970,7 @@ static int _pdn_connectivity_find_apn(const OctetString *apn) } /* Return the identifier of the PDN connection */ - return (_esm_data.pdn[i].pid); + return (esm_data->pdn[i].pid); } /**************************************************************************** @@ -984,7 +982,6 @@ static int _pdn_connectivity_find_apn(const OctetString *apn) ** ** ** Inputs: apn: Access Point Name of the PDN connection ** ** pdn_type: PDN address type ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The identifier of the PDN connection if ** @@ -992,38 +989,38 @@ static int _pdn_connectivity_find_apn(const OctetString *apn) ** Others: None ** ** ** ***************************************************************************/ -static int _pdn_connectivity_find_pdn(const OctetString *apn, +static int _pdn_connectivity_find_pdn(esm_data_t *esm_data, const OctetString *apn, const esm_proc_pdn_type_t pdn_type) { int i; for (i = 0; i < ESM_DATA_PDN_MAX; i++) { - if ( (_esm_data.pdn[i].pid != -1) && _esm_data.pdn[i].data ) { + if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { /* PDN connection established during initial network attachment */ - if (_esm_data.pdn[i].data->apn.length == 0) { + if (esm_data->pdn[i].data->apn.length == 0) { break; } /* Subsequent PDN connection established for the specified APN */ - if (_esm_data.pdn[i].data->apn.length != apn->length) { + if (esm_data->pdn[i].data->apn.length != apn->length) { continue; } - if (memcmp(_esm_data.pdn[i].data->apn.value, + if (memcmp(esm_data->pdn[i].data->apn.value, apn->value, apn->length) != 0) { continue; } - if (_esm_data.pdn[i].data->type == ESM_PDN_TYPE_IPV4V6) { + if (esm_data->pdn[i].data->type == ESM_PDN_TYPE_IPV4V6) { break; } - if (_esm_data.pdn[i].data->type == pdn_type) { + if (esm_data->pdn[i].data->type == pdn_type) { break; } } } /* Return the identifier of the PDN connection */ - return (_esm_data.pdn[i].pid); + return (esm_data->pdn[i].pid); } diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c index 3cb2f563858ad1306ea241ccf8357874dfb5b571..4b5c0f06e5b0bfe14d7cae3613c3393ea7350e5e 100644 --- a/openair3/NAS/UE/ESM/PdnDisconnect.c +++ b/openair3/NAS/UE/ESM/PdnDisconnect.c @@ -73,7 +73,7 @@ Description Defines the PDN disconnect ESM procedure executed by the /* * PDN disconnection handlers */ -static int _pdn_disconnect_get_default_ebi(int pti); +static int _pdn_disconnect_get_default_ebi(esm_data_t *esm_data, int pti); /* * Timer handlers @@ -104,7 +104,6 @@ static void *_pdn_disconnect_t3492_handler(void *); ** tifier ** ** ** ** Inputs: cid: PDN context identifier ** - ** Others: _esm_data ** ** ** ** Outputs: pti: Procedure transaction identity assigned to ** ** the PDN connection to be released ** @@ -114,7 +113,7 @@ static void *_pdn_disconnect_t3492_handler(void *); ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi) +int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, unsigned int *ebi) { LOG_FUNC_IN; @@ -122,21 +121,21 @@ int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi) int pid = cid - 1; if (pid < ESM_DATA_PDN_MAX) { - if (pid != _esm_data.pdn[pid].pid) { + if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-PROC - PDN connection identifier %d is " "not valid", pid); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection %d has not been " "allocated", pid); - } else if (!_esm_data.pdn[pid].is_active) { + } else if (!esm_data->pdn[pid].is_active) { LOG_TRACE(WARNING, "ESM-PROC - PDN connection is not active"); } else { /* Get the procedure transaction identity assigned to the PDN * connection to be released */ - *pti = _esm_data.pdn[pid].data->pti; + *pti = esm_data->pdn[pid].data->pti; /* Get the EPS bearer identity of the default bearer associated * with the PDN to disconnect from */ - *ebi = _esm_data.pdn[pid].data->bearer[0]->ebi; + *ebi = esm_data->pdn[pid].data->bearer[0]->ebi; rc = RETURNok; } } @@ -168,13 +167,13 @@ int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi) ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect_request(int is_standalone, int pti, +int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue) { LOG_FUNC_IN; int rc = RETURNok; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; LOG_TRACE(INFO, "ESM-PROC - Initiate PDN disconnection (pti=%d)", pti); if (is_standalone) { @@ -184,21 +183,21 @@ int esm_proc_pdn_disconnect_request(int is_standalone, int pti, * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Start T3482 retransmission timer */ - rc = esm_pt_start_timer(pti, msg, T3492_DEFAULT_VALUE, + rc = esm_pt_start_timer(user, pti, msg, T3492_DEFAULT_VALUE, _pdn_disconnect_t3492_handler); } } if (rc != RETURNerror) { /* Set the procedure transaction state to PENDING */ - rc = esm_pt_set_status(pti, ESM_PT_PENDING); + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_PENDING); if (rc != RETURNok) { /* The procedure transaction was already in PENDING state */ @@ -232,7 +231,7 @@ int esm_proc_pdn_disconnect_request(int is_standalone, int pti, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) +int esm_proc_pdn_disconnect_accept(esm_pt_data_t *esm_pt_data, int pti, int *esm_cause) { LOG_FUNC_IN; @@ -240,9 +239,9 @@ int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) "(pti=%d)", pti); /* Stop T3492 timer if running */ - (void) esm_pt_stop_timer(pti); + (void) esm_pt_stop_timer(esm_pt_data, pti); /* Set the procedure transaction state to INACTIVE */ - int rc = esm_pt_set_status(pti, ESM_PT_INACTIVE); + int rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state */ @@ -251,7 +250,7 @@ int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) } else { /* Immediately release the transaction identity assigned to this * procedure */ - rc = esm_pt_release(pti); + rc = esm_pt_release(esm_pt_data, pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); @@ -284,19 +283,19 @@ int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause) +int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause) { LOG_FUNC_IN; - + esm_data_t *esm_data = user->esm_data; int rc; LOG_TRACE(WARNING, "ESM-PROC - PDN disconnection rejected by the network " "(pti=%d), ESM cause = %d", pti, *esm_cause); /* Stop T3492 timer if running */ - (void) esm_pt_stop_timer(pti); + (void) esm_pt_stop_timer(user->esm_pt_data, pti); /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(user->esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state @@ -305,7 +304,7 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause) *esm_cause = ESM_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE; } else { /* Release the transaction identity assigned to this procedure */ - rc = esm_pt_release(pti); + rc = esm_pt_release(user->esm_pt_data, pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); @@ -313,7 +312,7 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause) } else if (*esm_cause != ESM_CAUSE_LAST_PDN_DISCONNECTION_NOT_ALLOWED) { /* Get the identity of the default EPS bearer context allocated to * the PDN connection entry assigned to this procedure transaction */ - int ebi = _pdn_disconnect_get_default_ebi(pti); + int ebi = _pdn_disconnect_get_default_ebi(esm_data, pti); if (ebi < 0) { LOG_TRACE(ERROR, "ESM-PROC - No default EPS bearer found"); @@ -331,7 +330,7 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause) esm_sap.recv = NULL; esm_sap.send.length = 0; esm_sap.data.eps_bearer_context_deactivate.ebi = ebi; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); if (rc != RETURNok) { *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; @@ -382,7 +381,8 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause) static void *_pdn_disconnect_t3492_handler(void *args) { LOG_FUNC_IN; - + nas_user_t *user = args; + esm_data_t *esm_data = user->esm_data;; int rc; /* Get retransmission timer parameters data */ @@ -402,19 +402,19 @@ static void *_pdn_disconnect_t3492_handler(void *args) * has to be sent again */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = data->msg.length; emm_esm->msg.value = data->msg.value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Restart the timer T3492 */ - rc = esm_pt_start_timer(data->pti, &data->msg, T3492_DEFAULT_VALUE, + rc = esm_pt_start_timer(user, data->pti, &data->msg, T3492_DEFAULT_VALUE, _pdn_disconnect_t3492_handler); } } else { /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(data->pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(user->esm_pt_data, data->pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state */ @@ -422,7 +422,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) data->pti); } else { /* Release the transaction identity assigned to this procedure */ - rc = esm_pt_release(data->pti); + rc = esm_pt_release(user->esm_pt_data, data->pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", @@ -431,7 +431,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) /* Get the identity of the default EPS bearer context * allocated to the PDN connection entry assigned to * this procedure transaction */ - int ebi = _pdn_disconnect_get_default_ebi(data->pti); + int ebi = _pdn_disconnect_get_default_ebi(esm_data, data->pti); if (ebi < 0) { LOG_TRACE(ERROR, "ESM-PROC - No default EPS bearer found"); @@ -448,7 +448,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) esm_sap.recv = NULL; esm_sap.send.length = 0; esm_sap.data.eps_bearer_context_deactivate.ebi = ebi; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } } } @@ -471,7 +471,6 @@ static void *_pdn_disconnect_t3492_handler(void *args) ** ven procedure transaction identity has been assigned ** ** ** ** Inputs: pti: The procedure transaction identity ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The EPS bearer identity of the default EPS ** @@ -479,22 +478,22 @@ static void *_pdn_disconnect_t3492_handler(void *args) ** Others: None ** ** ** ***************************************************************************/ -static int _pdn_disconnect_get_default_ebi(int pti) +static int _pdn_disconnect_get_default_ebi(esm_data_t *esm_data, int pti) { int ebi = -1; int i; for (i = 0; i < ESM_DATA_PDN_MAX; i++) { - if ( (_esm_data.pdn[i].pid != -1) && _esm_data.pdn[i].data ) { - if (_esm_data.pdn[i].data->pti != pti) { + if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { + if (esm_data->pdn[i].data->pti != pti) { continue; } /* PDN entry found */ - if (_esm_data.pdn[i].data->bearer[0] != NULL) { + if (esm_data->pdn[i].data->bearer[0] != NULL) { /* Get the EPS bearer identity of the default EPS bearer * context associated to the PDN connection */ - ebi = _esm_data.pdn[i].data->bearer[0]->ebi; + ebi = esm_data->pdn[i].data->bearer[0]->ebi; } break; diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.c b/openair3/NAS/UE/ESM/SAP/esm_recv.c index 243d619896732ca14f4635ba00729d9a362186c5..03a421558113c48500f8d5893fcfb21e842970ec 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_recv.c +++ b/openair3/NAS/UE/ESM/SAP/esm_recv.c @@ -74,7 +74,7 @@ Description Defines functions executed at the ESM Service Access ** ** ** Description: Processes ESM status message ** ** ** - ** Inputs: ueid: UE local identifier ** + ** Inputs: ** ** pti: Procedure transaction identity ** ** ebi: EPS bearer identity ** ** msg: The received ESM message ** @@ -135,7 +135,7 @@ int esm_recv_status(int pti, int ebi, const esm_status_msg *msg) ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_pdn_connectivity_reject(int pti, int ebi, +int esm_recv_pdn_connectivity_reject(nas_user_t *user, int pti, int ebi, const pdn_connectivity_reject_msg *msg) { LOG_FUNC_IN; @@ -154,7 +154,7 @@ int esm_recv_pdn_connectivity_reject(int pti, int ebi, */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( esm_pt_is_not_in_use(pti) ) { + } else if ( esm_pt_is_not_in_use(user->esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case a * Assigned value that does not match any PTI in use */ @@ -164,7 +164,7 @@ int esm_recv_pdn_connectivity_reject(int pti, int ebi, /* * EPS bearer identity checking */ - else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) { + else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case a * Assigned or reserved EPS bearer identity value */ LOG_TRACE(WARNING, "ESM-SAP - Invalid EPS bearer identity (ebi=%d)", @@ -179,7 +179,7 @@ int esm_recv_pdn_connectivity_reject(int pti, int ebi, esm_cause = msg->esmcause; /* Execute the PDN connectivity procedure not accepted by the network */ - int rc = esm_proc_pdn_connectivity_reject(pti, &esm_cause); + int rc = esm_proc_pdn_connectivity_reject(user, pti, &esm_cause); if (rc != RETURNerror) { esm_cause = ESM_CAUSE_SUCCESS; @@ -206,7 +206,7 @@ int esm_recv_pdn_connectivity_reject(int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_pdn_disconnect_reject(int pti, int ebi, +int esm_recv_pdn_disconnect_reject(nas_user_t *user, int pti, int ebi, const pdn_disconnect_reject_msg *msg) { LOG_FUNC_IN; @@ -225,7 +225,7 @@ int esm_recv_pdn_disconnect_reject(int pti, int ebi, */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( esm_pt_is_not_in_use(pti) ) { + } else if ( esm_pt_is_not_in_use(user->esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case b * Assigned value that does not match any PTI in use */ @@ -235,7 +235,7 @@ int esm_recv_pdn_disconnect_reject(int pti, int ebi, /* * EPS bearer identity checking */ - else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) { + else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case b * Assigned or reserved EPS bearer identity value */ LOG_TRACE(WARNING, "ESM-SAP - Invalid EPS bearer identity (ebi=%d)", @@ -250,7 +250,7 @@ int esm_recv_pdn_disconnect_reject(int pti, int ebi, esm_cause = msg->esmcause; /* Execute the PDN disconnect procedure not accepted by the network */ - int rc = esm_proc_pdn_disconnect_reject(pti, &esm_cause); + int rc = esm_proc_pdn_disconnect_reject(user, pti, &esm_cause); if (rc != RETURNerror) { esm_cause = ESM_CAUSE_SUCCESS; @@ -278,12 +278,13 @@ int esm_recv_pdn_disconnect_reject(int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, +int esm_recv_activate_default_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const activate_default_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; int esm_cause = ESM_CAUSE_SUCCESS; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; LOG_TRACE(INFO, "ESM-SAP - Received Activate Default EPS Bearer Context " "Request message (pti=%d, ebi=%d)", pti, ebi); @@ -297,7 +298,7 @@ int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( esm_pt_is_not_in_use(pti) ) { + } else if ( esm_pt_is_not_in_use(esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case g * Assigned value that does not match any PTI in use */ @@ -307,7 +308,7 @@ int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, /* * EPS bearer identity checking */ - else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) { + else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case g * Reserved or unassigned EPS bearer identity value */ @@ -369,14 +370,14 @@ int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, } /* Execute the PDN connectivity procedure accepted by the network */ - int pid = esm_proc_pdn_connectivity_accept(pti, pdn_type, + int pid = esm_proc_pdn_connectivity_accept(user, pti, pdn_type, &msg->pdnaddress.pdnaddressinformation, &msg->accesspointname.accesspointnamevalue, &esm_cause); if (pid != RETURNerror) { /* Create local default EPS bearer context */ - int rc = esm_proc_default_eps_bearer_context_request(pid, ebi, &qos, + int rc = esm_proc_default_eps_bearer_context_request(user, pid, ebi, &qos, &esm_cause); if (rc != RETURNerror) { @@ -406,7 +407,7 @@ int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, +int esm_recv_activate_dedicated_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const activate_dedicated_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; @@ -414,6 +415,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, int esm_cause = ESM_CAUSE_SUCCESS; int i; int j; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; LOG_TRACE(INFO, "ESM-SAP - Received Activate Dedicated EPS Bearer " "Context Request message (pti=%d, ebi=%d)", pti, ebi); @@ -427,7 +429,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( (pti != ESM_PT_UNASSIGNED) && esm_pt_is_not_in_use(pti) ) { + } else if ( (pti != ESM_PT_UNASSIGNED) && esm_pt_is_not_in_use(esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case i * Assigned value that does not match any PTI in use */ @@ -437,7 +439,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, /* * EPS bearer identity checking */ - else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) { + else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case h * Reserved or unassigned EPS bearer identity value */ @@ -580,7 +582,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, } /* Execute the dedicated EPS bearer context activation procedure */ - int rc = esm_proc_dedicated_eps_bearer_context_request(ebi, + int rc = esm_proc_dedicated_eps_bearer_context_request(user, ebi, msg->linkedepsbeareridentity, &qos, &tft, &esm_cause); @@ -614,13 +616,14 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi, +int esm_recv_deactivate_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const deactivate_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; int rc = RETURNok; int esm_cause; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; LOG_TRACE(INFO, "ESM-SAP - Received Deactivate EPS Bearer Context " "Request message (pti=%d, ebi=%d)", pti, ebi); @@ -634,7 +637,7 @@ int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi, */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( esm_pt_is_not_in_use(pti) ) { + } else if ( esm_pt_is_not_in_use(esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case m * Assigned value does not match any PTI in use */ @@ -644,8 +647,8 @@ int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi, /* * EPS bearer identity checking */ - else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) || - esm_ebr_is_not_in_use(ebi) ) { + else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) || + esm_ebr_is_not_in_use(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case j * Reserved or unassigned EPS bearer identity value or, * assigned value that does not match an existing EPS bearer context @@ -665,12 +668,12 @@ int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi, /* Execute the PDN disconnect procedure accepted by the network */ if (pti != ESM_PT_UNASSIGNED) { - rc = esm_proc_pdn_disconnect_accept(pti, &esm_cause); + rc = esm_proc_pdn_disconnect_accept(esm_pt_data, pti, &esm_cause); } if (rc != RETURNerror) { /* Execute the EPS bearer context deactivation procedure */ - rc = esm_proc_eps_bearer_context_deactivate_request(ebi, &esm_cause); + rc = esm_proc_eps_bearer_context_deactivate_request(user, ebi, &esm_cause); if (rc != RETURNerror) { esm_cause = ESM_CAUSE_SUCCESS; diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.h b/openair3/NAS/UE/ESM/SAP/esm_recv.h index db65230e1e3ec546efa5c0238488690b2c8b6b3e..ae36d650e3c37310e90b517934011e0f07e46dc7 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_recv.h +++ b/openair3/NAS/UE/ESM/SAP/esm_recv.h @@ -42,6 +42,7 @@ Description Defines functions executed at the ESM Service Access #include "EsmStatus.h" #include "emmData.h" +#include "user_defs.h" #include "PdnConnectivityReject.h" #include "PdnDisconnectReject.h" @@ -88,23 +89,23 @@ int esm_recv_status(int pti, int ebi, const esm_status_msg *msg); * Transaction related messages * ---------------------------- */ -int esm_recv_pdn_connectivity_reject(int pti, int ebi, +int esm_recv_pdn_connectivity_reject(nas_user_t *user, int pti, int ebi, const pdn_connectivity_reject_msg *msg); -int esm_recv_pdn_disconnect_reject(int pti, int ebi, +int esm_recv_pdn_disconnect_reject(nas_user_t *user, int pti, int ebi, const pdn_disconnect_reject_msg *msg); /* * Messages related to EPS bearer contexts * --------------------------------------- */ -int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, +int esm_recv_activate_default_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const activate_default_eps_bearer_context_request_msg *msg); -int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, +int esm_recv_activate_dedicated_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const activate_dedicated_eps_bearer_context_request_msg *msg); -int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi, +int esm_recv_deactivate_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const deactivate_eps_bearer_context_request_msg *msg); diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c index 5ead95d5b416ab5cf290e65dbcb2dc6b02713690..7ff1e57380bbb20b1dfb8b444593edd202809e87 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.c +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c @@ -63,9 +63,9 @@ Description Defines the ESM Service Access Points at which the EPS /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -static int _esm_sap_recv(int msg_type, int is_standalone, +static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err); -static int _esm_sap_send(int msg_type, int is_standalone, int pti, int ebi, +static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, int pti, int ebi, const esm_sap_data_t *data, OctetString *rsp); @@ -95,12 +95,6 @@ static const char *_esm_sap_primitive_str[] = { "ESM_UNITDATA_IND", }; -/* - * Buffer used to encode ESM messages before being returned to the EPS - * Mobility Management sublayer in order to be sent onto the network - */ -#define ESM_SAP_BUFFER_SIZE 4096 -static char _esm_sap_buffer[ESM_SAP_BUFFER_SIZE]; /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -144,9 +138,11 @@ void esm_sap_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_sap_send(esm_sap_t *msg) +int esm_sap_send(nas_user_t *user, esm_sap_t *msg) { LOG_FUNC_IN; + esm_data_t *esm_data = user->esm_data; + msg->send.value = esm_data->send_buffer; int rc = RETURNerror; int pid; @@ -172,7 +168,7 @@ int esm_sap_send(esm_sap_t *msg) } /* Define new PDN context */ - rc = esm_proc_pdn_connectivity(pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, TRUE, pdn_connect->pdn_type, &apn, pdn_connect->is_emergency, NULL); @@ -184,13 +180,13 @@ int esm_sap_send(esm_sap_t *msg) if (pdn_connect->is_defined) { unsigned int pti; /* Assign new procedure transaction identity */ - rc = esm_proc_pdn_connectivity(pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, TRUE, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, &pti); if (rc != RETURNerror) { /* Send PDN connectivity request */ - rc = _esm_sap_send(PDN_CONNECTIVITY_REQUEST, + rc = _esm_sap_send(user, PDN_CONNECTIVITY_REQUEST, msg->is_standalone, pti, EPS_BEARER_IDENTITY_UNASSIGNED, &msg->data, &msg->send); @@ -206,16 +202,16 @@ int esm_sap_send(esm_sap_t *msg) if ( msg->is_standalone && pdn_connect->is_defined ) { /* Undefine the specified PDN context */ - rc = esm_proc_pdn_connectivity(pdn_connect->cid, FALSE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, FALSE, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, NULL); } else if (msg->recv != NULL) { /* The UE received a PDN connectivity reject message */ - rc = _esm_sap_recv(PDN_CONNECTIVITY_REJECT, msg->is_standalone, + rc = _esm_sap_recv(user, PDN_CONNECTIVITY_REJECT, msg->is_standalone, msg->recv, &msg->send, &msg->err); } else { /* The PDN connectivity procedure locally failed */ - rc = esm_proc_pdn_connectivity_failure(TRUE); + rc = esm_proc_pdn_connectivity_failure(user, TRUE); } } break; @@ -226,12 +222,12 @@ int esm_sap_send(esm_sap_t *msg) /* Get the procedure transaction identity and the EPS bearer * identity of the default bearer assigned to the PDN to * disconnect from */ - rc = esm_proc_pdn_disconnect(msg->data.pdn_disconnect.cid, + rc = esm_proc_pdn_disconnect(esm_data, msg->data.pdn_disconnect.cid, &pti, &ebi); if (rc != RETURNerror) { /* Send PDN disconnect request */ - rc = _esm_sap_send(PDN_DISCONNECT_REQUEST, TRUE, pti, ebi, + rc = _esm_sap_send(user, PDN_DISCONNECT_REQUEST, TRUE, pti, ebi, &msg->data, &msg->send); } } @@ -254,7 +250,7 @@ int esm_sap_send(esm_sap_t *msg) case ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ: /* The UE received activate default ESP bearer context request */ - rc = _esm_sap_recv(ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST, + rc = _esm_sap_recv(user, ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST, msg->is_standalone, msg->recv, &msg->send, &msg->err); break; @@ -264,10 +260,10 @@ int esm_sap_send(esm_sap_t *msg) * The activate default ESP bearer context accept message * has been successfully delivered to the other side */ - rc = esm_proc_default_eps_bearer_context_complete(); + rc = esm_proc_default_eps_bearer_context_complete(user->default_eps_bearer_context_data); if (rc != RETURNerror) { - rc = esm_proc_pdn_connectivity_complete(); + rc = esm_proc_pdn_connectivity_complete(user); } break; @@ -276,10 +272,10 @@ int esm_sap_send(esm_sap_t *msg) /* * Default ESP bearer context activation procedure locally failed */ - rc = esm_proc_default_eps_bearer_context_failure(); + rc = esm_proc_default_eps_bearer_context_failure(user); if (rc != RETURNerror) { - rc = esm_proc_pdn_connectivity_failure(FALSE); + rc = esm_proc_pdn_connectivity_failure(user, FALSE); } break; @@ -307,7 +303,7 @@ int esm_sap_send(esm_sap_t *msg) /* * Locally deactivate EPS bearer context */ - rc = esm_proc_eps_bearer_context_deactivate(TRUE, + rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, msg->data.eps_bearer_context_deactivate.ebi, &pid, &bid); } break; @@ -316,7 +312,7 @@ int esm_sap_send(esm_sap_t *msg) break; case ESM_UNITDATA_IND: - rc = _esm_sap_recv(-1, msg->is_standalone, msg->recv, + rc = _esm_sap_recv(user, -1, msg->is_standalone, msg->recv, &msg->send, &msg->err); break; @@ -358,10 +354,9 @@ int esm_sap_send(esm_sap_t *msg) ** turned upon ESM procedure completion ** ** err: Error code of the ESM procedure ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_sap_buffer ** ** ** ***************************************************************************/ -static int _esm_sap_recv(int msg_type, int is_standalone, +static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err) { @@ -439,7 +434,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, * received from the MME */ esm_cause = esm_recv_activate_default_eps_bearer_context_request( - pti, ebi, + user, pti, ebi, &esm_msg.activate_default_eps_bearer_context_request); if ( (esm_cause == ESM_CAUSE_SUCCESS) || @@ -477,7 +472,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, * received from the MME */ esm_cause = esm_recv_activate_dedicated_eps_bearer_context_request( - pti, ebi, + user, pti, ebi, &esm_msg.activate_dedicated_eps_bearer_context_request); if ( (esm_cause == ESM_CAUSE_SUCCESS) || @@ -517,7 +512,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, * Process deactivate EPS bearer context request message * received from the MME */ - esm_cause = esm_recv_deactivate_eps_bearer_context_request(pti, ebi, + esm_cause = esm_recv_deactivate_eps_bearer_context_request(user, pti, ebi, &esm_msg.deactivate_eps_bearer_context_request); if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) || @@ -553,7 +548,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, /* * Process PDN connectivity reject message received from the MME */ - esm_cause = esm_recv_pdn_connectivity_reject(pti, ebi, + esm_cause = esm_recv_pdn_connectivity_reject(user, pti, ebi, &esm_msg.pdn_connectivity_reject); if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) || @@ -576,7 +571,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, /* * Process PDN disconnect reject message received from the MME */ - esm_cause = esm_recv_pdn_disconnect_reject(pti, ebi, + esm_cause = esm_recv_pdn_disconnect_reject(user, pti, ebi, &esm_msg.pdn_disconnect_reject); if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) || @@ -641,16 +636,13 @@ static int _esm_sap_recv(int msg_type, int is_standalone, if ( (rc != RETURNerror) && (esm_procedure != NULL) ) { /* Encode the returned ESM response message */ - int size = esm_msg_encode(&esm_msg, (uint8_t *)_esm_sap_buffer, + int size = esm_msg_encode(&esm_msg, rsp->value, ESM_SAP_BUFFER_SIZE); - if (size > 0) { - rsp->length = size; - rsp->value = (uint8_t *)(_esm_sap_buffer); - } + rsp->length = size; /* Complete the relevant ESM procedure */ - rc = (*esm_procedure)(is_standalone, ebi, rsp, triggered_by_ue); + rc = (*esm_procedure)(user, is_standalone, ebi, rsp, triggered_by_ue); if (is_discarded) { /* Return indication that received message has been discarded */ @@ -690,10 +682,9 @@ static int _esm_sap_recv(int msg_type, int is_standalone, ** Outputs: rsp: The encoded ESM response message to be re- ** ** turned upon ESM procedure completion ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_sap_buffer ** ** ** ***************************************************************************/ -static int _esm_sap_send(int msg_type, int is_standalone, +static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, int pti, int ebi, const esm_sap_data_t *data, OctetString *rsp) { @@ -771,18 +762,15 @@ static int _esm_sap_send(int msg_type, int is_standalone, if (rc != RETURNerror) { /* Encode the returned ESM response message */ - int size = esm_msg_encode(&esm_msg, (uint8_t *)_esm_sap_buffer, + int size = esm_msg_encode(&esm_msg, rsp->value, ESM_SAP_BUFFER_SIZE); - if (size > 0) { - rsp->length = size; - rsp->value = (uint8_t *)(_esm_sap_buffer); - } - + rsp->length = size; /* Execute the relevant ESM procedure */ if (esm_procedure) { - rc = (*esm_procedure)(is_standalone, pti, rsp, sent_by_ue); + rc = (*esm_procedure)(user, is_standalone, pti, rsp, sent_by_ue); } + } LOG_FUNC_RETURN(rc); diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.h b/openair3/NAS/UE/ESM/SAP/esm_sap.h index 7364a4b6610961099706a2e49141efed1de5f629..b464e18900a330bdaf05bb6b6998da2d69e164b9 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.h +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.h @@ -41,6 +41,7 @@ Description Defines the ESM Service Access Points at which the EPS #define __ESM_SAP_H__ #include "esm_sapDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -60,6 +61,6 @@ Description Defines the ESM Service Access Points at which the EPS void esm_sap_initialize(void); -int esm_sap_send(esm_sap_t *msg); +int esm_sap_send(nas_user_t *user, esm_sap_t *msg); #endif /* __ESM_SAP_H__*/ diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index 4a498b5d2e979ddcdd79fdd50f44f4b3b12396fd..02bc0dd93073e80601dae5dd028c86b9017efab6 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -52,11 +52,23 @@ Description Defines internal private data handled by EPS Session /* Total number of active EPS bearers */ #define ESM_DATA_EPS_BEARER_TOTAL 11 +#define ESM_SAP_BUFFER_SIZE 4096 /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * -------------------------------------------------------------------------- + * Internal data handled by the default EPS bearer context activation + * procedure in the UE + * -------------------------------------------------------------------------- + */ +typedef struct { + int ebi; /* EPS bearer identity of the default EPS bearer associated + * to the PDN connection to be activated */ +} default_eps_bearer_context_data_t; + /* * Minimal and maximal value of an EPS bearer identity: * The EPS Bearer Identity (EBI) identifies a message flow @@ -72,8 +84,6 @@ typedef enum { ESM_EBR_STATE_MAX } esm_ebr_state; - - /* * ----------------------- * EPS bearer context data @@ -172,6 +182,7 @@ typedef struct esm_data_context_s { } pdn[ESM_DATA_PDN_MAX+1]; esm_ebr_data_t ebr; + uint8_t send_buffer[ESM_SAP_BUFFER_SIZE]; } esm_data_context_t; /* @@ -185,21 +196,15 @@ typedef struct esm_data_context_s { */ typedef esm_data_context_t esm_data_t; - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ -/* - * ESM internal data (used within ESM only) - * ---------------------------------------- - */ -esm_data_t _esm_data; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ +// FIXME prototype and buffer allocation extern char ip_addr_str[100]; extern char *esm_data_get_ipv4_addr(const OctetString *ip_addr); diff --git a/openair3/NAS/UE/ESM/esm_ebr.c b/openair3/NAS/UE/ESM/esm_ebr.c index 878f06c18439ce46f63aed921f434a7410195cff..330da2fb23660d2182b70a4faf7a103b1c2fe961 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.c +++ b/openair3/NAS/UE/ESM/esm_ebr.c @@ -44,15 +44,13 @@ Description Defines functions used to handle state of EPS bearer contexts #include "esm_ebr.h" #include "commonDef.h" #include "nas_log.h" +#include "utils.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -#define ESM_EBR_NB_UE_MAX 1 - - /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -63,16 +61,6 @@ static const char *_esm_ebr_state_str[ESM_EBR_STATE_MAX] = { "BEARER CONTEXT ACTIVE", }; -/* - * ---------------------------------- - * List of EPS bearer contexts per UE - * ---------------------------------- - */ - -#if !defined(NAS_BUILT_IN_EPC) -static esm_ebr_data_t _esm_ebr_data[ESM_EBR_NB_UE_MAX]; -#endif - /* * ---------------------- * User notification data @@ -102,7 +90,7 @@ static const network_pdn_state_t _esm_ebr_pdn_state[2][2][2] = { /* Returns the index of the next available entry in the list of EPS bearer * context data */ -static int _esm_ebr_get_available_entry(unsigned int ueid); +static int _esm_ebr_get_available_entry(esm_ebr_data_t *esm_ebr_data); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -119,41 +107,46 @@ static int _esm_ebr_get_available_entry(unsigned int ueid); ** ** ** Outputs: None ** ** Return: None ** - ** Others: _esm_ebr_data ** ** ** ***************************************************************************/ -void esm_ebr_initialize( - esm_indication_callback_t cb -) + +esm_ebr_data_t *esm_ebr_initialize(void) { -#if !defined(NAS_BUILT_IN_EPC) - int ueid, i; LOG_FUNC_IN; - for (ueid = 0; ueid < ESM_EBR_NB_UE_MAX; ueid++) { - _esm_ebr_data[ueid].index = 0; + int i; + esm_ebr_data_t *esm_ebr_data = calloc_or_fail(sizeof(esm_ebr_data_t)); - /* Initialize EPS bearer context data */ - for (i = 0; i < ESM_EBR_DATA_SIZE + 1; i++) { - _esm_ebr_data[ueid].context[i] = NULL; - } + esm_ebr_data->index = 0; + + /* Initialize EPS bearer context data */ + for (i = 0; i < ESM_EBR_DATA_SIZE + 1; i++) { + esm_ebr_data->context[i] = NULL; } + LOG_FUNC_OUT; + return esm_ebr_data; +} + +void esm_ebr_register_callback(esm_indication_callback_t cb) +{ + + LOG_FUNC_IN; + /* Initialize the user notification callback */ _esm_ebr_callback = *cb; LOG_FUNC_OUT; -#endif } + /**************************************************************************** ** ** ** Name: esm_ebr_assign() ** ** ** ** Description: Assigns a new EPS bearer context ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** ** ebi: Identity of the new EPS bearer context ** ** cid: Identifier of the PDN context the EPS bea- ** ** rer context is associated to ** @@ -165,18 +158,16 @@ void esm_ebr_initialize( ** Return: The identity of the new EPS bearer context ** ** if successfully assigned; ** ** the not assigned EBI (0) otherwise. ** - ** Others: _esm_ebr_data ** ** ** ***************************************************************************/ -int esm_ebr_assign(int ebi, int cid, int default_ebr) +int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr) { esm_ebr_context_t *ebr_ctx = NULL; - unsigned int ueid = 0; int i; LOG_FUNC_IN; - ebr_ctx = _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]; + ebr_ctx = esm_ebr_data->context[ebi - ESM_EBI_MIN]; if (ebi != ESM_EBI_UNASSIGNED) { @@ -192,7 +183,7 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr) i = ebi - ESM_EBI_MIN; } else { /* Search for an available EPS bearer identity */ - i = _esm_ebr_get_available_entry(ueid); + i = _esm_ebr_get_available_entry(esm_ebr_data); if (i < 0) { LOG_FUNC_RETURN(ESM_EBI_UNASSIGNED); @@ -211,10 +202,10 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr) } - _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN] = ebr_ctx; + esm_ebr_data->context[ebi - ESM_EBI_MIN] = ebr_ctx; /* Store the index of the next available EPS bearer identity */ - _esm_ebr_data[ueid].index = i + 1; + esm_ebr_data->index = i + 1; /* Set the EPS bearer identity */ ebr_ctx->ebi = ebi; @@ -235,7 +226,7 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr) ** ** ** Description: Release the given EPS bearer identity ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** + ** Inputs: ** ** ebi: The identity of the EPS bearer context to ** ** be released ** ** Others: None ** @@ -244,13 +235,11 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr) ** Return: RETURNok if the EPS bearer context has ** ** been successfully released; ** ** RETURNerror otherwise. ** - ** Others: _esm_ebr_data ** ** ** ***************************************************************************/ -int esm_ebr_release( +int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, int ebi) { - unsigned int ueid = 0; esm_ebr_context_t *ebr_ctx; LOG_FUNC_IN; @@ -260,7 +249,7 @@ int esm_ebr_release( } /* Get EPS bearer context data */ - ebr_ctx = _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]; + ebr_ctx = esm_ebr_data->context[ebi - ESM_EBI_MIN]; if ( (ebr_ctx == NULL) || (ebr_ctx->ebi != ebi) ) { /* EPS bearer context not assigned */ @@ -290,7 +279,6 @@ int esm_ebr_release( ** Description: Set the status of the specified EPS bearer context to the ** ** given state ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** ** ebi: The identity of the EPS bearer ** ** status: The new EPS bearer context status ** ** ue_requested: TRUE/FALSE if the modification of the EPS ** @@ -300,10 +288,9 @@ int esm_ebr_release( ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_ebr_data ** ** ** ***************************************************************************/ -int esm_ebr_set_status( +int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested) { esm_ebr_context_t *ebr_ctx; @@ -311,19 +298,13 @@ int esm_ebr_set_status( LOG_FUNC_IN; - unsigned int ueid = 0; - - if (ueid >= ESM_EBR_NB_UE_MAX) { - LOG_FUNC_RETURN (RETURNerror); - } - if ( (ebi < ESM_EBI_MIN) || (ebi > ESM_EBI_MAX) ) { LOG_FUNC_RETURN (RETURNerror); } /* Get EPS bearer context data */ - ebr_ctx = _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]; + ebr_ctx = esm_ebr_data->context[ebi - ESM_EBI_MIN]; if ( (ebr_ctx == NULL) || (ebr_ctx->ebi != ebi) ) { /* EPS bearer context not assigned */ @@ -344,7 +325,7 @@ int esm_ebr_set_status( /* * Notify the user that the state of the EPS bearer has changed */ - (*_esm_ebr_callback)(ebr_ctx->cid, + (*_esm_ebr_callback)(user_api_id, ebr_ctx->cid, _esm_ebr_pdn_state[ue_requested][ebr_ctx->is_default_ebr][status]); LOG_FUNC_RETURN (RETURNok); } @@ -360,9 +341,7 @@ int esm_ebr_set_status( ** Description: Get the current status value of the specified EPS bearer ** ** context ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** ** ebi: The identity of the EPS bearer ** - ** Others: _esm_ebr_data ** ** ** ** Outputs: None ** ** Return: The current value of the EPS bearer con- ** @@ -371,26 +350,25 @@ int esm_ebr_set_status( ** ** ***************************************************************************/ -esm_ebr_state esm_ebr_get_status( +esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, int ebi) { - unsigned int ueid = 0; if ( (ebi < ESM_EBI_MIN) || (ebi > ESM_EBI_MAX) ) { return (ESM_EBR_INACTIVE); } - if (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN] == NULL) { + if (esm_ebr_data->context[ebi - ESM_EBI_MIN] == NULL) { /* EPS bearer context not allocated */ return (ESM_EBR_INACTIVE); } - if (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]->ebi != ebi) { + if (esm_ebr_data->context[ebi - ESM_EBI_MIN]->ebi != ebi) { /* EPS bearer context not assigned */ return (ESM_EBR_INACTIVE); } - return (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]->status); + return (esm_ebr_data->context[ebi - ESM_EBI_MIN]->status); } /**************************************************************************** @@ -408,7 +386,7 @@ esm_ebr_state esm_ebr_get_status( ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_is_reserved(int ebi) +int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi) { return ( (ebi != ESM_EBI_UNASSIGNED) && (ebi < ESM_EBI_MIN) ); } @@ -420,23 +398,20 @@ int esm_ebr_is_reserved(int ebi) ** Description: Check whether the given EPS bearer identity does not ** ** match an assigned EBI value currently in use ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** ** ebi: The identity of the EPS bearer ** - ** Others: _esm_ebr_data ** ** ** ** Outputs: None ** ** Return: TRUE, FALSE ** ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_is_not_in_use( +int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi) { - unsigned int ueid = 0; return ( (ebi == ESM_EBI_UNASSIGNED) || - (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN] == NULL) || - (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]->ebi) != ebi); + (esm_ebr_data->context[ebi - ESM_EBI_MIN] == NULL) || + (esm_ebr_data->context[ebi - ESM_EBI_MIN]->ebi) != ebi); } /****************************************************************************/ @@ -450,8 +425,6 @@ int esm_ebr_is_not_in_use( ** Description: Returns the index of the next available entry in the list ** ** of EPS bearer context data ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** - ** Others: _esm_ebr_data ** ** ** ** Outputs: None ** ** Return: The index of the next available EPS bearer ** @@ -460,20 +433,20 @@ int esm_ebr_is_not_in_use( ** Others: None ** ** ** ***************************************************************************/ -static int _esm_ebr_get_available_entry(unsigned int ueid) +static int _esm_ebr_get_available_entry(esm_ebr_data_t *esm_ebr_data) { int i; - for (i = _esm_ebr_data[ueid].index; i < ESM_EBR_DATA_SIZE; i++) { - if (_esm_ebr_data[ueid].context[i] != NULL) { + for (i = esm_ebr_data->index; i < ESM_EBR_DATA_SIZE; i++) { + if (esm_ebr_data->context[i] != NULL) { continue; } return i; } - for (i = 0; i < _esm_ebr_data[ueid].index; i++) { - if (_esm_ebr_data[ueid].context[i] != NULL) { + for (i = 0; i < esm_ebr_data->index; i++) { + if (esm_ebr_data->context[i] != NULL) { continue; } diff --git a/openair3/NAS/UE/ESM/esm_ebr.h b/openair3/NAS/UE/ESM/esm_ebr.h index dd586319564a15e986e708cb54fe5a942a22a39f..8e1eaee1a4291dd76fcf66c37d4201efd419e9e9 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.h +++ b/openair3/NAS/UE/ESM/esm_ebr.h @@ -42,8 +42,10 @@ Description Defines functions used to handle state of EPS bearer contexts #include "OctetString.h" #include "networkDef.h" +#include "esmData.h" #include "nas_timer.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -56,6 +58,13 @@ Description Defines functions used to handle state of EPS bearer contexts /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * User notification callback, executed whenever a change of status with + * respect of PDN connection or EPS bearer context is notified by the EPS + * Session Management sublayer + */ +typedef int (*esm_indication_callback_t) (user_api_id_t *user_api_id, int, network_pdn_state_t); + /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -64,15 +73,17 @@ Description Defines functions used to handle state of EPS bearer contexts /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int esm_ebr_is_reserved(int ebi); +void esm_ebr_register_callback(esm_indication_callback_t cb); + +int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi); -void esm_ebr_initialize(esm_indication_callback_t cb); -int esm_ebr_assign(int ebi, int cid, int default_ebr); -int esm_ebr_release(int ebi); +esm_ebr_data_t *esm_ebr_initialize(void); +int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr); +int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, int ebi); -int esm_ebr_set_status(int ebi, esm_ebr_state status, int ue_requested); -esm_ebr_state esm_ebr_get_status(int ebi); +int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested); +esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, int ebi); -int esm_ebr_is_not_in_use(int ebi); +int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi); #endif /* __ESM_EBR_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index cca1e06913db2da5c436408e13681467c132bd00..bfa4a04cc82dd9d73946ac67702897fe2dce8a51 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -82,36 +82,33 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, ** Description: Creates a new EPS bearer context to the PDN with the spe- ** ** cified PDN connection identifier ** ** ** - ** Inputs: ueid: UE identifier ** + ** Inputs: ** ** pid: PDN connection identifier ** ** ebi: EPS bearer identity ** ** is_default: TRUE if the new bearer is a default EPS ** ** bearer context ** ** esm_qos: EPS bearer level QoS parameters ** ** tft: Traffic flow template parameters ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The EPS bearer identity of the default EPS ** ** bearer associated to the new EPS bearer ** ** context if successfully created; ** ** UNASSIGN EPS bearer value otherwise. ** - ** Others: _esm_data ** ** ** ***************************************************************************/ int esm_ebr_context_create( - + esm_data_t *esm_data, int ueid, int pid, int ebi, int is_default, const network_qos_t *qos, const network_tft_t *tft) { int bid = 0; esm_data_context_t *esm_ctx = NULL; esm_pdn_t *pdn = NULL; - //unsigned int ueid = 0; LOG_FUNC_IN; - esm_ctx = &_esm_data; + esm_ctx = esm_data; bid = ESM_DATA_EPS_BEARER_MAX; @@ -209,7 +206,7 @@ int esm_ebr_context_create( char *netmask = NULL; char broadcast[INET_ADDRSTRLEN]; struct in_addr in_addr; - char command_line[128]; + char command_line[500]; int res; switch (pdn->type) { @@ -275,11 +272,17 @@ int esm_ebr_context_create( } res = sprintf(command_line, - "ifconfig oip1 %s netmask %s broadcast %s", - ipv4_addr, netmask, broadcast); - (void)res; /* avoid gcc warning "set but not used" */ - // AssertFatal((res > 0) && (res < 128), - // "error in system command line"); + "ifconfig oip%d %s netmask %s broadcast %s up && " + "ip rule add from %s/32 table %d && " + "ip rule add to %s/32 table %d && " + "ip route add default dev oip%d table %d", + ueid + 1, ipv4_addr, netmask, broadcast, + ipv4_addr, ueid + 201, + ipv4_addr, ueid + 201, + ueid + 1, ueid + 201); + if ( res<0 ) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string"); + } LOG_TRACE(INFO, "ESM-PROC - executing %s ", command_line); @@ -316,9 +319,8 @@ int esm_ebr_context_create( ** Description: Releases EPS bearer context entry previously allocated ** ** to the EPS bearer with the specified EPS bearer identity ** ** ** - ** Inputs: ueid: UE identifier ** + ** Inputs: ** ** ebi: EPS bearer identity ** - ** Others: _esm_data ** ** ** ** Outputs: pid: Identifier of the PDN connection entry the ** ** EPS bearer context belongs to ** @@ -327,22 +329,20 @@ int esm_ebr_context_create( ** Return: The EPS bearer identity associated to the ** ** EPS bearer context if successfully relea- ** ** sed; UNASSIGN EPS bearer value otherwise. ** - ** Others: _esm_data ** ** ** ***************************************************************************/ -int esm_ebr_context_release( - +int esm_ebr_context_release(nas_user_t *user, int ebi, int *pid, int *bid) { int found = FALSE; esm_pdn_t *pdn = NULL; esm_data_context_t *esm_ctx; - - //unsigned int ueid = 0; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; LOG_FUNC_IN; - esm_ctx = &_esm_data; + esm_ctx = user->esm_data; if (ebi != ESM_EBI_UNASSIGNED) { /* @@ -456,11 +456,11 @@ int esm_ebr_context_release( } /* Set the EPS bearer context state to INACTIVE */ - (void) esm_ebr_set_status(pdn->bearer[i]->ebi, + esm_ebr_set_status(user_api_id, esm_ebr_data, pdn->bearer[i]->ebi, ESM_EBR_INACTIVE, TRUE); /* Release EPS bearer data */ - (void) esm_ebr_release(pdn->bearer[i]->ebi); + esm_ebr_release(esm_ebr_data, pdn->bearer[i]->ebi); // esm_ebr_release() /* Release dedicated EPS bearer data */ @@ -492,7 +492,7 @@ int esm_ebr_context_release( emm_sap_t emm_sap; emm_sap.primitive = EMMESM_ESTABLISH_CNF; emm_sap.u.emm_esm.u.establish.is_attached = FALSE; - (void) emm_sap_send(&emm_sap); + (void) emm_sap_send(user, &emm_sap); } /* 3GPP TS 24.301, section 6.4.4.3, 6.4.4.6 * If due to the EPS bearer context deactivation only the PDN @@ -505,7 +505,7 @@ int esm_ebr_context_release( emm_sap.primitive = EMMESM_ESTABLISH_CNF; emm_sap.u.emm_esm.u.establish.is_attached = TRUE; emm_sap.u.emm_esm.u.establish.is_emergency = TRUE; - (void) emm_sap_send(&emm_sap); + (void) emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (ebi); @@ -524,7 +524,6 @@ int esm_ebr_context_release( ** ** ** Inputs: ebi: The EPS bearer identity of the default EPS ** ** bearer context ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The identifier of the PDN connection entry ** @@ -533,22 +532,22 @@ int esm_ebr_context_release( ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_context_get_pid(int ebi) +int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi) { LOG_FUNC_IN; int pid; for (pid = 0; pid < ESM_DATA_PDN_MAX; pid++) { - if (_esm_data.pdn[pid].data == NULL) { + if (esm_data->pdn[pid].data == NULL) { continue; } - if (_esm_data.pdn[pid].data->bearer[0] == NULL) { + if (esm_data->pdn[pid].data->bearer[0] == NULL) { continue; } - if (_esm_data.pdn[pid].data->bearer[0]->ebi == ebi) { + if (esm_data->pdn[pid].data->bearer[0]->ebi == ebi) { break; } } @@ -576,14 +575,13 @@ int esm_ebr_context_get_pid(int ebi) ** tft: The traffic flow template (set of packet ** ** filters) to be checked ** ** operation: Traffic flow template operation ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_context_check_tft(int pid, int ebi, +int esm_ebr_context_check_tft(esm_data_t *esm_data, int pid, int ebi, const network_tft_t *tft, esm_ebr_context_tft_t operation) { @@ -593,14 +591,14 @@ int esm_ebr_context_check_tft(int pid, int ebi, int i; if (pid < ESM_DATA_PDN_MAX) { - if (pid != _esm_data.pdn[pid].pid) { + if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier %d " "is not valid", pid); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection %d has not been " "allocated", pid); } else if (operation == ESM_EBR_CONTEXT_TFT_CREATE) { - esm_pdn_t *pdn = _esm_data.pdn[pid].data; + esm_pdn_t *pdn = esm_data->pdn[pid].data; /* For each EPS bearer context associated to the PDN connection */ for (i = 0; i < pdn->n_bearers; i++) { diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.h b/openair3/NAS/UE/ESM/esm_ebr_context.h index 95d7b081d884402da2b6ddff5ec5364e8a8d696c..a0016555a30233a9d5a3718dacae227b6e369692 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.h +++ b/openair3/NAS/UE/ESM/esm_ebr_context.h @@ -39,6 +39,7 @@ Description Defines functions used to handle EPS bearer contexts. #define __ESM_EBR_CONTEXT_H__ #include "networkDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -65,14 +66,14 @@ typedef enum { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int esm_ebr_context_create(int pid, int ebi, int is_default, +int esm_ebr_context_create(esm_data_t *esm_data, int ueid, int pid, int ebi, int is_default, const network_qos_t *qos, const network_tft_t *tft); -int esm_ebr_context_release(int ebi, int *pid, int *bid); +int esm_ebr_context_release(nas_user_t *user, int ebi, int *pid, int *bid); -int esm_ebr_context_get_pid(int ebi); +int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi); -int esm_ebr_context_check_tft(int pid, int ebi, const network_tft_t *tft, +int esm_ebr_context_check_tft(esm_data_t *esm_data, int pid, int ebi, const network_tft_t *tft, esm_ebr_context_tft_t operation); diff --git a/openair3/NAS/UE/ESM/esm_ip.c b/openair3/NAS/UE/ESM/esm_ip.c index f21305a1a0ca9c1862b4cec94fb0ac879d58f392..2638221a8f9cb1a86826bb8201a3e0b40a967c42 100644 --- a/openair3/NAS/UE/ESM/esm_ip.c +++ b/openair3/NAS/UE/ESM/esm_ip.c @@ -22,8 +22,10 @@ #include "emmData.h" #include "esmData.h" +// FIXME don't work for reentrant calls char ip_addr_str[100]; +// FIXME can't be extern and inline at same time ! inline char *esm_data_get_ipv4_addr(const OctetString *ip_addr) { if (ip_addr->length > 0) { diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index 74af9935aaaf0210088e900a514ae0daf691d61c..6c110abb52ea34f708e278198a6e37a5b577f118 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -40,11 +40,13 @@ Description Defines the EPS Session Management procedure call manager, #include "esm_main.h" #include "commonDef.h" #include "nas_log.h" +#include "utils.h" #include "emmData.h" #include "esmData.h" #include "esm_pt.h" #include "esm_ebr.h" +#include "user_defs.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -69,35 +71,46 @@ Description Defines the EPS Session Management procedure call manager, ** ** ** Outputs: None ** ** Return: None ** - ** Others: _esm_data ** ** ** ***************************************************************************/ -void esm_main_initialize(esm_indication_callback_t cb) +void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb) { LOG_FUNC_IN; int i; + esm_data_t *esm_data = calloc_or_fail(sizeof(esm_data_t)); + user->esm_data = esm_data; + + default_eps_bearer_context_data_t *default_eps_bearer_context = calloc(1, sizeof(default_eps_bearer_context_data_t)); + if ( default_eps_bearer_context == NULL ) { + LOG_TRACE(ERROR, "ESM-MAIN - Can't malloc default_eps_bearer_context"); + exit(EXIT_FAILURE); + } + default_eps_bearer_context->ebi = ESM_EBI_UNASSIGNED; + user->default_eps_bearer_context_data = default_eps_bearer_context; /* Total number of active EPS bearer contexts */ - _esm_data.n_ebrs = 0; + esm_data->n_ebrs = 0; /* List of active PDN connections */ - _esm_data.n_pdns = 0; + esm_data->n_pdns = 0; for (i = 0; i < ESM_DATA_PDN_MAX + 1; i++) { - _esm_data.pdn[i].pid = -1; - _esm_data.pdn[i].is_active = FALSE; - _esm_data.pdn[i].data = NULL; + esm_data->pdn[i].pid = -1; + esm_data->pdn[i].is_active = FALSE; + esm_data->pdn[i].data = NULL; } /* Emergency bearer services indicator */ - _esm_data.emergency = FALSE; + esm_data->emergency = FALSE; /* Initialize the procedure transaction identity manager */ - esm_pt_initialize(); - /* Initialize the EPS bearer context manager */ - esm_ebr_initialize(cb); + user->esm_pt_data = esm_pt_initialize(); + /* Initialize the EPS bearer context manager */ + user->esm_ebr_data = esm_ebr_initialize(); + // FIXME only one callback for all user or many for many ? + esm_ebr_register_callback(cb); LOG_FUNC_OUT; } @@ -116,7 +129,7 @@ void esm_main_initialize(esm_indication_callback_t cb) ** Others: None ** ** ** ***************************************************************************/ -void esm_main_cleanup(void) +void esm_main_cleanup(esm_data_t *esm_data) { LOG_FUNC_IN; @@ -127,8 +140,8 @@ void esm_main_cleanup(void) /* De-activate EPS bearers and clean up PDN connections */ for (pid = 0; pid < ESM_DATA_PDN_MAX; pid++) { - if (_esm_data.pdn[pid].data) { - esm_pdn_t *pdn = _esm_data.pdn[pid].data; + if (esm_data->pdn[pid].data) { + esm_pdn_t *pdn = esm_data->pdn[pid].data; if (pdn->apn.length > 0) { free(pdn->apn.value); @@ -152,7 +165,7 @@ void esm_main_cleanup(void) } /* Release the PDN connection */ - free(_esm_data.pdn[pid].data); + free(esm_data->pdn[pid].data); } } } @@ -168,7 +181,6 @@ void esm_main_cleanup(void) ** a defined state at the same time ** ** ** ** Inputs: None ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The maximum number of PDN connections that ** @@ -176,7 +188,7 @@ void esm_main_cleanup(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_nb_pdns_max(void) +int esm_main_get_nb_pdns_max(esm_data_t *esm_data) { LOG_FUNC_IN; @@ -190,18 +202,17 @@ int esm_main_get_nb_pdns_max(void) ** Description: Get the number of active PDN connections ** ** ** ** Inputs: None ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The number of active PDN connections ** ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_nb_pdns(void) +int esm_main_get_nb_pdns(esm_data_t *esm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_esm_data.n_pdns); + LOG_FUNC_RETURN (esm_data->n_pdns); } /**************************************************************************** @@ -212,7 +223,6 @@ int esm_main_get_nb_pdns(void) ** vices is established ** ** ** ** Inputs: None ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: TRUE if a PDN connection for emergency ** @@ -220,11 +230,11 @@ int esm_main_get_nb_pdns(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_main_has_emergency(void) +int esm_main_has_emergency(esm_data_t *esm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_esm_data.emergency); + LOG_FUNC_RETURN (esm_data->emergency); } /**************************************************************************** @@ -234,7 +244,6 @@ int esm_main_has_emergency(void) ** Description: Get the status of the specified PDN connection ** ** ** ** Inputs: cid: PDN connection identifier ** - ** Others: _esm_data ** ** ** ** Outputs: state: TRUE if the current state of the PDN con- ** ** nection is ACTIVE; FALSE otherwise. ** @@ -245,28 +254,30 @@ int esm_main_has_emergency(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_pdn_status(int cid, int *state) +int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) { LOG_FUNC_IN; unsigned int pid = cid - 1; + esm_data_t *esm_data = user->esm_data; + esm_ebr_data_t *esm_ebr_data = user-> esm_ebr_data; if (pid >= ESM_DATA_PDN_MAX) { return (FALSE); - } else if (pid != _esm_data.pdn[pid].pid) { + } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid); return (FALSE); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated", cid); return (FALSE); } - if (_esm_data.pdn[pid].data->bearer[0] != NULL) { + if (esm_data->pdn[pid].data->bearer[0] != NULL) { /* The status of a PDN connection is the status of the default EPS bearer * that has been assigned to this PDN connection at activation time */ - int ebi = _esm_data.pdn[pid].data->bearer[0]->ebi; - *state = (esm_ebr_get_status(ebi) == ESM_EBR_ACTIVE); + int ebi = esm_data->pdn[pid].data->bearer[0]->ebi; + *state = (esm_ebr_get_status(esm_ebr_data, ebi) == ESM_EBR_ACTIVE); } /* The PDN connection has not been activated yet */ @@ -280,7 +291,6 @@ int esm_main_get_pdn_status(int cid, int *state) ** Description: Get parameters defined for the specified PDN connection ** ** ** ** Inputs: cid: PDN connection identifier ** - ** Others: _esm_data ** ** ** ** Outputs: type: PDN connection type (IPv4, IPv6, IPv4v6) ** ** apn: Access Point logical Name in used ** @@ -290,7 +300,7 @@ int esm_main_get_pdn_status(int cid, int *state) ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_pdn(int cid, int *type, const char **apn, +int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, int *is_emergency, int *is_active) { LOG_FUNC_IN; @@ -299,29 +309,29 @@ int esm_main_get_pdn(int cid, int *type, const char **apn, if (pid >= ESM_DATA_PDN_MAX) { return (RETURNerror); - } else if (pid != _esm_data.pdn[pid].pid) { + } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid); return (RETURNerror); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated", cid); return (RETURNerror); } /* Get the PDN type */ - *type = _esm_data.pdn[pid].data->type; + *type = esm_data->pdn[pid].data->type; /* Get the Access Point Name */ - if (_esm_data.pdn[pid].data->apn.length > 0) { - *apn = (char *)(_esm_data.pdn[pid].data->apn.value); + if (esm_data->pdn[pid].data->apn.length > 0) { + *apn = (char *)(esm_data->pdn[pid].data->apn.value); } else { *apn = NULL; } /* Get the emergency bearer services indicator */ - *is_emergency = _esm_data.pdn[pid].data->is_emergency; + *is_emergency = esm_data->pdn[pid].data->is_emergency; /* Get the active PDN connection indicator */ - *is_active = _esm_data.pdn[pid].is_active; + *is_active = esm_data->pdn[pid].is_active; LOG_FUNC_RETURN (RETURNok); } @@ -334,7 +344,6 @@ int esm_main_get_pdn(int cid, int *type, const char **apn, ** tion ** ** ** ** Inputs: cid: PDN connection identifier ** - ** Others: _esm_data ** ** ** ** Outputs: ipv4adddr: IPv4 address ** ** ipv6adddr: IPv6 address ** @@ -342,7 +351,7 @@ int esm_main_get_pdn(int cid, int *type, const char **apn, ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr) +int esm_main_get_pdn_addr(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr) { LOG_FUNC_IN; @@ -350,35 +359,30 @@ int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr) if (pid >= ESM_DATA_PDN_MAX) { return (RETURNerror); - } else if (pid != _esm_data.pdn[pid].pid) { + } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid); return (RETURNerror); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated", cid); return (RETURNerror); - } else if (!_esm_data.pdn[pid].is_active) { + } else if (!esm_data->pdn[pid].is_active) { /* No any IP address has been assigned to this PDN connection */ return (RETURNok); } - if (_esm_data.pdn[pid].data->type == NET_PDN_TYPE_IPV4) { + if (esm_data->pdn[pid].data->type == NET_PDN_TYPE_IPV4) { /* Get IPv4 address */ - *ipv4addr = _esm_data.pdn[pid].data->ip_addr; - } else if (_esm_data.pdn[pid].data->type == NET_PDN_TYPE_IPV6) { + *ipv4addr = esm_data->pdn[pid].data->ip_addr; + } else if (esm_data->pdn[pid].data->type == NET_PDN_TYPE_IPV6) { /* Get IPv6 address */ - *ipv6addr = _esm_data.pdn[pid].data->ip_addr; + *ipv6addr = esm_data->pdn[pid].data->ip_addr; } else { /* IPv4v6 dual-stack terminal */ - *ipv4addr = _esm_data.pdn[pid].data->ip_addr; - *ipv6addr = _esm_data.pdn[pid].data->ip_addr+ESM_DATA_IPV4_ADDRESS_SIZE; + *ipv4addr = esm_data->pdn[pid].data->ip_addr; + *ipv6addr = esm_data->pdn[pid].data->ip_addr+ESM_DATA_IPV4_ADDRESS_SIZE; } LOG_FUNC_RETURN (RETURNok); } - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - diff --git a/openair3/NAS/UE/ESM/esm_main.h b/openair3/NAS/UE/ESM/esm_main.h index d7346fdb0898c491595485e90e32137ecbf430b3..42381c8d5b15b89d97ab2d008289dd40f5768a9b 100644 --- a/openair3/NAS/UE/ESM/esm_main.h +++ b/openair3/NAS/UE/ESM/esm_main.h @@ -41,6 +41,9 @@ Description Defines the EPS Session Management procedure call manager, #define __ESM_MAIN_H__ #include "networkDef.h" +#include "esm_ebr.h" +#include "esmData.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -58,19 +61,19 @@ Description Defines the EPS Session Management procedure call manager, /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void esm_main_initialize(esm_indication_callback_t cb); +void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb); -void esm_main_cleanup(void); +void esm_main_cleanup(esm_data_t *esm_data); /* User's getter for PDN connections and EPS bearer contexts */ -int esm_main_get_nb_pdns_max(void); -int esm_main_get_nb_pdns(void); -int esm_main_has_emergency(void); -int esm_main_get_pdn_status(int cid, int *state); -int esm_main_get_pdn(int cid, int *type, const char **apn, int *is_emergency, +int esm_main_get_nb_pdns_max(esm_data_t *esm_data); +int esm_main_get_nb_pdns(esm_data_t *esm_data); +int esm_main_has_emergency(esm_data_t *esm_data); +int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state); +int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, int *is_emergency, int *is_active); -int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr); +int esm_main_get_pdn_addr(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr); #endif /* __ESM_MAIN_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_proc.h b/openair3/NAS/UE/ESM/esm_proc.h index edbd926309380549b597c63a8dc2241b9de27430..3d7260b83b7400c8a8d140dc648c7937fa9c6194 100644 --- a/openair3/NAS/UE/ESM/esm_proc.h +++ b/openair3/NAS/UE/ESM/esm_proc.h @@ -43,6 +43,7 @@ Description Defines the EPS Session Management procedures executed at #include "OctetString.h" #include "emmData.h" #include "ProtocolConfigurationOptions.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -78,7 +79,7 @@ typedef enum { * Type of the ESM procedure callback executed when requested by the UE * or initiated by the network */ -typedef int (*esm_proc_procedure_t) (int, int, OctetString *, int); +typedef int (*esm_proc_procedure_t) (nas_user_t *user, int, int, OctetString *, int); /* EPS bearer level QoS parameters */ typedef network_qos_t esm_proc_qos_t; @@ -112,7 +113,7 @@ typedef struct { * -------------------------------------------------------------------------- */ int esm_proc_status_ind(int pti, int ebi, int *esm_cause); -int esm_proc_status(int is_standalone, int pti, OctetString *msg, +int esm_proc_status(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue); @@ -121,16 +122,16 @@ int esm_proc_status(int is_standalone, int pti, OctetString *msg, * PDN connectivity procedure * -------------------------------------------------------------------------- */ -int esm_proc_pdn_connectivity(int cid, int to_define, +int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int to_define, esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency, unsigned int *pti); -int esm_proc_pdn_connectivity_request(int is_standalone, int pti, +int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue); -int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, +int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_address, const OctetString *apn, int *esm_cause); -int esm_proc_pdn_connectivity_reject(int pti, int *esm_cause); -int esm_proc_pdn_connectivity_complete(void); -int esm_proc_pdn_connectivity_failure(int is_pending); +int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause); +int esm_proc_pdn_connectivity_complete(nas_user_t *user); +int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending); /* @@ -138,12 +139,12 @@ int esm_proc_pdn_connectivity_failure(int is_pending); * PDN disconnect procedure * -------------------------------------------------------------------------- */ -int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi); -int esm_proc_pdn_disconnect_request(int is_standalone, int pti, +int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, unsigned int *ebi); +int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue); -int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause); -int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause); +int esm_proc_pdn_disconnect_accept(esm_pt_data_t *esm_pt_data, int pti, int *esm_cause); +int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause); /* * -------------------------------------------------------------------------- @@ -151,14 +152,14 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause); * -------------------------------------------------------------------------- */ -int esm_proc_default_eps_bearer_context_request(int pid, int ebi, +int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int ebi, const esm_proc_qos_t *esm_qos, int *esm_cause); -int esm_proc_default_eps_bearer_context_complete(void); -int esm_proc_default_eps_bearer_context_failure(void); +int esm_proc_default_eps_bearer_context_complete(default_eps_bearer_context_data_t *default_eps_bearer_context_data); +int esm_proc_default_eps_bearer_context_failure(nas_user_t *user); -int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi, +int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); -int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, +int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); /* @@ -167,12 +168,12 @@ int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, * -------------------------------------------------------------------------- */ -int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, +int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int default_ebi, const esm_proc_qos_t *qos, const esm_proc_tft_t *tft, int *esm_cause); -int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, +int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); -int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, +int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); /* @@ -181,11 +182,11 @@ int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, * -------------------------------------------------------------------------- */ -int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, int *pid, +int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, int is_local, int ebi, int *pid, int *bid); -int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause); +int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, int *esm_cause); -int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, +int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); #endif /* __ESM_PROC_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_pt.c b/openair3/NAS/UE/ESM/esm_pt.c index 8e819fbd0bb6a956931a0a42785d86fcb8f784f0..9f8e948954ba7537e2abf6ada2303ef8e046ebc3 100644 --- a/openair3/NAS/UE/ESM/esm_pt.c +++ b/openair3/NAS/UE/ESM/esm_pt.c @@ -37,9 +37,12 @@ Description Defines functions used to handle ESM procedure transactions. *****************************************************************************/ #include "esm_pt.h" +#include "esm_pt_defs.h" +#include "user_defs.h" #include "commonDef.h" #include "nas_log.h" +#include "utils.h" #include <stdlib.h> // malloc, free #include <string.h> // memcpy @@ -48,14 +51,6 @@ Description Defines functions used to handle ESM procedure transactions. /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -/* - * Minimal and maximal value of a procedure transaction identity: - * The Procedure Transaction Identity (PTI) identifies bi-directional - * messages flows - */ -#define ESM_PTI_MIN (PROCEDURE_TRANSACTION_IDENTITY_FIRST) -#define ESM_PTI_MAX (PROCEDURE_TRANSACTION_IDENTITY_LAST) - /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -66,33 +61,9 @@ static const char *_esm_pt_state_str[ESM_PT_STATE_MAX] = { "PROCEDURE TRANSACTION PENDING" }; -/* - * -------------------------- - * Procedure transaction data - * -------------------------- - */ -typedef struct { - unsigned char pti; /* Procedure transaction identity */ - esm_pt_state status; /* Procedure transaction status */ - struct nas_timer_t timer; /* Retransmission timer */ - esm_pt_timer_data_t *args; /* Retransmission timer parameters data */ -} esm_pt_context_t; - -/* - * ------------------------------ - * List of procedure transactions - * ------------------------------ - */ -static struct { - unsigned char index; /* Index of the next procedure transaction - * identity to be used */ -#define ESM_PT_DATA_SIZE (ESM_PTI_MAX - ESM_PTI_MIN + 1) - esm_pt_context_t *context[ESM_PT_DATA_SIZE + 1]; -} _esm_pt_data; - /* Return the index of the next available entry in the list of procedure * transaction data */ -static int _esm_pt_get_available_entry(void); +static int _esm_pt_get_available_entry(esm_pt_data_t *esm_pt_data); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -109,22 +80,22 @@ static int _esm_pt_get_available_entry(void); ** ** ** Outputs: None ** ** Return: None ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -void esm_pt_initialize(void) +esm_pt_data_t *esm_pt_initialize(void) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = calloc_or_fail(sizeof(esm_pt_data_t)); int i; - _esm_pt_data.index = 0; + esm_pt_data->index = 0; for (i = 0; i < ESM_PT_DATA_SIZE + 1; i++) { - _esm_pt_data.context[i] = NULL; + esm_pt_data->context[i] = NULL; } LOG_FUNC_OUT; + return esm_pt_data; } /**************************************************************************** @@ -140,43 +111,42 @@ void esm_pt_initialize(void) ** Return: The identity of the new procedure transac- ** ** tion when successfully assigned; ** ** the unassigned PTI (0) otherwise. ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_assign(void) +int esm_pt_assign(esm_pt_data_t *esm_pt_data) { LOG_FUNC_IN; /* Search for an available procedure transaction identity */ - int i = _esm_pt_get_available_entry(); + int i = _esm_pt_get_available_entry(esm_pt_data); if (i < 0) { LOG_FUNC_RETURN (ESM_PT_UNASSIGNED); } /* Assign new procedure transaction */ - _esm_pt_data.context[i] = + esm_pt_data->context[i] = (esm_pt_context_t *)malloc(sizeof(esm_pt_context_t)); - if (_esm_pt_data.context[i] == NULL) { + if (esm_pt_data->context[i] == NULL) { LOG_FUNC_RETURN (ESM_PT_UNASSIGNED); } /* Store the index of the next available procedure transaction identity */ - _esm_pt_data.index = i + 1; + esm_pt_data->index = i + 1; /* An available procedure transaction identity is found */ - _esm_pt_data.context[i]->pti = i + ESM_PTI_MIN; + esm_pt_data->context[i]->pti = i + ESM_PTI_MIN; /* Set the procedure transaction status to INACTIVE */ - _esm_pt_data.context[i]->status = ESM_PT_INACTIVE; + esm_pt_data->context[i]->status = ESM_PT_INACTIVE; /* Disable the retransmission timer */ - _esm_pt_data.context[i]->timer.id = NAS_TIMER_INACTIVE_ID; + esm_pt_data->context[i]->timer.id = NAS_TIMER_INACTIVE_ID; /* Setup retransmission timer parameters */ - _esm_pt_data.context[i]->args = NULL; + esm_pt_data->context[i]->args = NULL; LOG_TRACE(INFO, "ESM-FSM - Procedure transaction identity %d assigned", - _esm_pt_data.context[i]->pti); - LOG_FUNC_RETURN (_esm_pt_data.context[i]->pti); + esm_pt_data->context[i]->pti); + LOG_FUNC_RETURN (esm_pt_data->context[i]->pti); } /**************************************************************************** @@ -193,10 +163,9 @@ int esm_pt_assign(void) ** Return: RETURNok if the procedure transaction iden-** ** tity has been successfully released; ** ** RETURNerror otherwise. ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_release(int pti) +int esm_pt_release(esm_pt_data_t *esm_pt_data, int pti) { LOG_FUNC_IN; @@ -205,7 +174,7 @@ int esm_pt_release(int pti) } /* Get procedure transaction data */ - esm_pt_context_t *ctx = _esm_pt_data.context[pti - ESM_PTI_MIN]; + esm_pt_context_t *ctx = esm_pt_data->context[pti - ESM_PTI_MIN]; if ( (ctx == NULL) || (ctx->pti != pti) ) { /* Procedure transaction not assigned */ @@ -236,8 +205,8 @@ int esm_pt_release(int pti) } /* Release transaction procedure data */ - free(_esm_pt_data.context[pti - ESM_PTI_MIN]); - _esm_pt_data.context[pti - ESM_PTI_MIN] = NULL; + free(esm_pt_data->context[pti - ESM_PTI_MIN]); + esm_pt_data->context[pti - ESM_PTI_MIN] = NULL; LOG_TRACE(INFO, "ESM-FSM - Procedure transaction %d released", pti); @@ -261,20 +230,20 @@ int esm_pt_release(int pti) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_start_timer(int pti, const OctetString *msg, +int esm_pt_start_timer(nas_user_t *user, int pti, const OctetString *msg, long sec, nas_timer_callback_t cb) { LOG_FUNC_IN; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; if ( (pti < ESM_PTI_MIN) || (pti > ESM_PTI_MAX) ) { LOG_FUNC_RETURN (RETURNerror); } /* Get procedure transaction data */ - esm_pt_context_t *ctx = _esm_pt_data.context[pti - ESM_PTI_MIN]; + esm_pt_context_t *ctx = esm_pt_data->context[pti - ESM_PTI_MIN]; if ( (ctx == NULL) || (ctx->pti != pti) ) { /* Procedure transaction not assigned */ @@ -291,6 +260,7 @@ int esm_pt_start_timer(int pti, const OctetString *msg, ctx->args = (esm_pt_timer_data_t *)malloc(sizeof(esm_pt_timer_data_t)); if (ctx->args) { + ctx->args->user = user; /* Set the EPS bearer identity */ ctx->args->pti = pti; /* Reset the retransmission counter */ @@ -332,10 +302,9 @@ int esm_pt_start_timer(int pti, const OctetString *msg, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_stop_timer(int pti) +int esm_pt_stop_timer(esm_pt_data_t *esm_pt_data, int pti) { LOG_FUNC_IN; @@ -344,7 +313,7 @@ int esm_pt_stop_timer(int pti) } /* Get procedure transaction data */ - esm_pt_context_t *ctx = _esm_pt_data.context[pti - ESM_PTI_MIN]; + esm_pt_context_t *ctx = esm_pt_data->context[pti - ESM_PTI_MIN]; if ( (ctx == NULL) || (ctx->pti != pti) ) { /* Procedure transaction not assigned */ @@ -384,10 +353,9 @@ int esm_pt_stop_timer(int pti) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_set_status(int pti, esm_pt_state status) +int esm_pt_set_status(esm_pt_data_t *esm_pt_data, int pti, esm_pt_state status) { LOG_FUNC_IN; @@ -398,7 +366,7 @@ int esm_pt_set_status(int pti, esm_pt_state status) } /* Get procedure transaction data */ - esm_pt_context_t *ctx = _esm_pt_data.context[pti - ESM_PTI_MIN]; + esm_pt_context_t *ctx = esm_pt_data->context[pti - ESM_PTI_MIN]; if ( (ctx == NULL) || (ctx->pti != pti) ) { /* Procedure transaction not assigned */ @@ -431,7 +399,6 @@ int esm_pt_set_status(int pti, esm_pt_state status) ** transaction ** ** ** ** Inputs: pti: The identity of the procedure transaction ** - ** Others: _esm_pt_data ** ** ** ** Outputs: None ** ** Return: The current value of the ESM procedure ** @@ -439,23 +406,23 @@ int esm_pt_set_status(int pti, esm_pt_state status) ** Others: None ** ** ** ***************************************************************************/ -esm_pt_state esm_pt_get_status(int pti) +esm_pt_state esm_pt_get_status(esm_pt_data_t *esm_pt_data, int pti) { if ( (pti < ESM_PTI_MIN) || (pti > ESM_PTI_MAX) ) { return (ESM_PT_INACTIVE); } - if (_esm_pt_data.context[pti - ESM_PTI_MIN] == NULL) { + if (esm_pt_data->context[pti - ESM_PTI_MIN] == NULL) { /* Procedure transaction not allocated */ return (ESM_PT_INACTIVE); } - if (_esm_pt_data.context[pti - ESM_PTI_MIN]->pti != pti) { + if (esm_pt_data->context[pti - ESM_PTI_MIN]->pti != pti) { /* Procedure transaction not assigned */ return (ESM_PT_INACTIVE); } - return (_esm_pt_data.context[pti - ESM_PTI_MIN]->status); + return (esm_pt_data->context[pti - ESM_PTI_MIN]->status); } /**************************************************************************** @@ -467,7 +434,6 @@ esm_pt_state esm_pt_get_status(int pti) ** given state ** ** ** ** Inputs: status: The PDN connection status ** - ** Others: _esm_pt_data ** ** ** ** Outputs: None ** ** Return: The procedure transaction identity of the ** @@ -476,18 +442,18 @@ esm_pt_state esm_pt_get_status(int pti) ** Others: None ** ** ** ***************************************************************************/ -int esm_pt_get_pending_pti(esm_pt_state status) +int esm_pt_get_pending_pti(esm_pt_data_t *esm_pt_data, esm_pt_state status) { LOG_FUNC_IN; int i; for (i = 0; i < ESM_PT_DATA_SIZE; i++) { - if (_esm_pt_data.context[i] == NULL) { + if (esm_pt_data->context[i] == NULL) { continue; } - if (_esm_pt_data.context[i]->status != status) { + if (esm_pt_data->context[i]->status != status) { continue; } @@ -496,7 +462,7 @@ int esm_pt_get_pending_pti(esm_pt_state status) } if (i < ESM_PT_DATA_SIZE) { - LOG_FUNC_RETURN (_esm_pt_data.context[i]->pti); + LOG_FUNC_RETURN (esm_pt_data->context[i]->pti); } /* PDN connection entry not found */ @@ -511,18 +477,17 @@ int esm_pt_get_pending_pti(esm_pt_state status) ** does not match an assigned PTI value currently in use ** ** ** ** Inputs: pti: The identity of the procedure transaction ** - ** Others: _esm_pt_data ** ** ** ** Outputs: None ** ** Return: TRUE, FALSE ** ** Others: None ** ** ** ***************************************************************************/ -int esm_pt_is_not_in_use(int pti) +int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti) { return ( (pti == ESM_PT_UNASSIGNED) || - (_esm_pt_data.context[pti - ESM_PTI_MIN] == NULL) || - (_esm_pt_data.context[pti - ESM_PTI_MIN]->pti) != pti); + (esm_pt_data->context[pti - ESM_PTI_MIN] == NULL) || + (esm_pt_data->context[pti - ESM_PTI_MIN]->pti) != pti); } /**************************************************************************** @@ -557,7 +522,6 @@ int esm_pt_is_reserved(int pti) ** of procedure transaction data ** ** ** ** Inputs: None ** - ** Others: _esm_pt_data ** ** ** ** Outputs: None ** ** Return: The index of the next available procedure ** @@ -566,20 +530,20 @@ int esm_pt_is_reserved(int pti) ** Others: None ** ** ** ***************************************************************************/ -static int _esm_pt_get_available_entry(void) +static int _esm_pt_get_available_entry(esm_pt_data_t *esm_pt_data) { int i; - for (i = _esm_pt_data.index; i < ESM_PT_DATA_SIZE; i++) { - if (_esm_pt_data.context[i] != NULL) { + for (i = esm_pt_data->index; i < ESM_PT_DATA_SIZE; i++) { + if (esm_pt_data->context[i] != NULL) { continue; } return i; } - for (i = 0; i < _esm_pt_data.index; i++) { - if (_esm_pt_data.context[i] != NULL) { + for (i = 0; i < esm_pt_data->index; i++) { + if (esm_pt_data->context[i] != NULL) { continue; } diff --git a/openair3/NAS/UE/ESM/esm_pt.h b/openair3/NAS/UE/ESM/esm_pt.h index 7cc0c54780646403ae3c33fc3dbb23e898bd31b9..8b8693efdaf6bb6d78130e8b4c817a383af27640 100644 --- a/openair3/NAS/UE/ESM/esm_pt.h +++ b/openair3/NAS/UE/ESM/esm_pt.h @@ -40,6 +40,8 @@ Description Defines functions used to handle ESM procedure transactions. #include "OctetString.h" #include "nas_timer.h" +#include "user_defs.h" +#include "esm_pt_defs.h" #include "ProcedureTransactionIdentity.h" @@ -54,21 +56,6 @@ Description Defines functions used to handle ESM procedure transactions. /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ -/* Procedure transaction states */ -typedef enum { - ESM_PT_INACTIVE, /* No procedure transaction exists */ - ESM_PT_PENDING, /* The UE has initiated a procedure transaction - * towards the network */ - ESM_PT_STATE_MAX -} esm_pt_state; - -/* ESM message timer retransmission data */ -typedef struct { - unsigned char pti; /* Procedure transaction identity */ - unsigned int count; /* Retransmission counter */ - OctetString msg; /* Encoded ESM message to re-transmit */ -} esm_pt_timer_data_t; - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -79,19 +66,19 @@ typedef struct { int esm_pt_is_reserved(int pti); -void esm_pt_initialize(void); +esm_pt_data_t *esm_pt_initialize(void); -int esm_pt_assign(void); -int esm_pt_release(int pti); +int esm_pt_assign(esm_pt_data_t *esm_pt_data); +int esm_pt_release(esm_pt_data_t *esm_pt_data, int pti); -int esm_pt_start_timer(int pti, const OctetString *msg, long sec, +int esm_pt_start_timer(nas_user_t *user, int pti, const OctetString *msg, long sec, nas_timer_callback_t cb); -int esm_pt_stop_timer(int pti); +int esm_pt_stop_timer(esm_pt_data_t *esm_pt_data, int pti); -int esm_pt_set_status(int pti, esm_pt_state status); -esm_pt_state esm_pt_get_status(int pti); -int esm_pt_get_pending_pti(esm_pt_state status); +int esm_pt_set_status(esm_pt_data_t *esm_pt_data, int pti, esm_pt_state status); +esm_pt_state esm_pt_get_status(esm_pt_data_t *esm_pt_data, int pti); +int esm_pt_get_pending_pti(esm_pt_data_t *esm_pt_data, esm_pt_state status); -int esm_pt_is_not_in_use(int pti); +int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti); #endif /* __ESM_PT_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_pt_defs.h b/openair3/NAS/UE/ESM/esm_pt_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..36cc52dda92da2a52d15f1b7d4b3bf3b5b8af6a3 --- /dev/null +++ b/openair3/NAS/UE/ESM/esm_pt_defs.h @@ -0,0 +1,63 @@ +#ifndef _ESM_PT_DEFS_H +#define _ESM_PT_DEFS_H + +#include "UTIL/nas_timer.h" +#include "IES/ProcedureTransactionIdentity.h" + +/****************************************************************************/ +/********************* G L O B A L C O N S T A N T S *******************/ +/****************************************************************************/ + +/* + * Minimal and maximal value of a procedure transaction identity: + * The Procedure Transaction Identity (PTI) identifies bi-directional + * messages flows + */ +#define ESM_PTI_MIN (PROCEDURE_TRANSACTION_IDENTITY_FIRST) +#define ESM_PTI_MAX (PROCEDURE_TRANSACTION_IDENTITY_LAST) + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +/* Procedure transaction states */ +typedef enum { + ESM_PT_INACTIVE, /* No procedure transaction exists */ + ESM_PT_PENDING, /* The UE has initiated a procedure transaction + * towards the network */ + ESM_PT_STATE_MAX +} esm_pt_state; + +/* ESM message timer retransmission data */ +typedef struct { + unsigned char pti; /* Procedure transaction identity */ + unsigned int count; /* Retransmission counter */ + OctetString msg; /* Encoded ESM message to re-transmit */ + void *user; /* user reference - void to avoid cyclic dependency */ +} esm_pt_timer_data_t; + +/* + * -------------------------- + * Procedure transaction data + * -------------------------- + */ +typedef struct { + unsigned char pti; /* Procedure transaction identity */ + esm_pt_state status; /* Procedure transaction status */ + struct nas_timer_t timer; /* Retransmission timer */ + esm_pt_timer_data_t *args; /* Retransmission timer parameters data */ +} esm_pt_context_t; + +/* + * ------------------------------ + * List of procedure transactions + * ------------------------------ + */ +typedef struct { + unsigned char index; /* Index of the next procedure transaction + * identity to be used */ +#define ESM_PT_DATA_SIZE (ESM_PTI_MAX - ESM_PTI_MIN + 1) + esm_pt_context_t *context[ESM_PT_DATA_SIZE + 1]; +} esm_pt_data_t; + +#endif diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index 20af58dac67563576cb9c9f425a7bd63987033ec..72035da6c8c0fb687a4381a1ef332807463b05d5 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -46,6 +46,7 @@ #include "nas_user.h" #include "nas_network.h" #include "nas_parser.h" +#include "user_defs.h" #include <stdlib.h> // exit #include <poll.h> // poll @@ -69,9 +70,12 @@ static void *_nas_network_mngr(void *); static int _nas_set_signal_handler(int signal, void (handler)(int)); static void _nas_signal_handler(int signal); -static void _nas_clean(int usr_fd, int net_fd); +static void _nas_clean(user_api_id_t *user_api_id, int net_fd); uint8_t usim_test = 0; +// FIXME user must be set up with right itti message instance +// FIXME allocate user and initialize its fields +nas_user_t *user = NULL; /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -80,6 +84,8 @@ uint8_t usim_test = 0; /****************************************************************************/ int main(int argc, const char *argv[]) { + // FIXME allocate and put it in user + user_api_id_t *user_api_id = NULL; /* * Get the command line options */ @@ -108,19 +114,19 @@ int main(int argc, const char *argv[]) /* * Initialize the User interface */ - if (user_api_initialize (uhost, uport, devpath, devparams) != RETURNok) { + if (user_api_initialize (user_api_id, uhost, uport, devpath, devparams) != RETURNok) { LOG_TRACE (ERROR, "UE-MAIN - user_api_initialize() failed"); exit (EXIT_FAILURE); } - int user_fd = user_api_get_fd (); + int user_fd = user_api_get_fd (user_api_id); /* * Initialize the Network interface */ if (network_api_initialize (nhost, nport) != RETURNok) { LOG_TRACE (ERROR, "UE-MAIN - network_api_initialize() failed"); - user_api_close (user_fd); + user_api_close (user_api_id); exit (EXIT_FAILURE); } @@ -129,7 +135,7 @@ int main(int argc, const char *argv[]) /* * Initialize the NAS contexts */ - nas_user_initialize (&user_api_emm_callback, &user_api_esm_callback, + nas_user_initialize (user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); nas_network_initialize (); @@ -157,7 +163,7 @@ int main(int argc, const char *argv[]) if (pthread_create (&user_mngr, &attr, _nas_user_mngr, &user_fd) != 0) { LOG_TRACE (ERROR, "UE-MAIN - " "Failed to create the user management thread"); - user_api_close (user_fd); + user_api_close (user_api_id); network_api_close (network_fd); exit (EXIT_FAILURE); } @@ -171,7 +177,7 @@ int main(int argc, const char *argv[]) &network_fd) != 0) { LOG_TRACE (ERROR, "UE-MAIN - " "Failed to create the network management thread"); - user_api_close (user_fd); + user_api_close (user_api_id); network_api_close (network_fd); exit (EXIT_FAILURE); } @@ -184,12 +190,12 @@ int main(int argc, const char *argv[]) */ while ((user_fd != -1) && (network_fd != -1)) { poll (NULL, 0, NAS_SLEEP_TIMEOUT); - user_fd = user_api_get_fd (); + user_fd = user_api_get_fd (user_api_id); network_fd = network_api_get_fd (); } /* Termination cleanup */ - _nas_clean (user_fd, network_fd); + _nas_clean (user_api_id, network_fd); LOG_TRACE (WARNING, "UE-MAIN - NAS main process exited"); @@ -226,11 +232,11 @@ static void *_nas_user_mngr(void *args) /* User receiving loop */ while (!exit_loop) { - exit_loop = nas_user_receive_and_process(fd, NULL); + exit_loop = nas_user_receive_and_process(user, NULL); } /* Close the connection to the user application layer */ - user_api_close (*fd); + user_api_close (user->user_api_id); LOG_TRACE (WARNING, "UE-MAIN - " "The user connection endpoint manager exited"); @@ -291,7 +297,7 @@ static void *_nas_network_mngr(void *args) } /* Process the network data message */ - ret_code = nas_network_process_data (network_message_id, + ret_code = nas_network_process_data (user, network_message_id, network_api_get_data ()); if (ret_code != RETURNok) { @@ -379,7 +385,8 @@ static void _nas_signal_handler(int signal) LOG_FUNC_IN; LOG_TRACE (WARNING, "UE-MAIN - Signal %d received", signal); - _nas_clean (user_api_get_fd (), network_api_get_fd ()); + // FIXME acces to global + _nas_clean (user->user_api_id, network_api_get_fd ()); exit (EXIT_SUCCESS); LOG_FUNC_OUT @@ -400,17 +407,19 @@ static void _nas_signal_handler(int signal) ** Others: None ** ** ** ***************************************************************************/ -static void _nas_clean(int usr_fd, int net_fd) +static void _nas_clean(user_api_id_t *user_api_id, int net_fd) { LOG_FUNC_IN; LOG_TRACE (INFO, "UE-MAIN - Perform EMM and ESM cleanup"); - nas_network_cleanup (); + // FIXME nas_network_cleanup depends on nas_user_t + // Why this program should interfere like that with oaisim ? + //nas_network_cleanup (); LOG_TRACE (INFO, "UE-MAIN - " "Closing user connection %d and network connection %d", - usr_fd, net_fd); - user_api_close (usr_fd); + user_api_get_fd (user_api_id), net_fd); + user_api_close (user_api_id); network_api_close (net_fd); LOG_FUNC_OUT diff --git a/openair3/NAS/UE/nas_itti_messaging.c b/openair3/NAS/UE/nas_itti_messaging.c index 7667ad50a438b95892355a31c86b98b39c5f6e71..b6b2126dfb4800863a44473ac6dddb157416cd2b 100644 --- a/openair3/NAS/UE/nas_itti_messaging.c +++ b/openair3/NAS/UE/nas_itti_messaging.c @@ -213,7 +213,7 @@ int nas_itti_kenb_refresh_req(const Byte_t kenb[32]) return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); } -int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat) +int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id) { MessageDef *message_p; @@ -230,10 +230,10 @@ int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat) plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3, plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3); - return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); + return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p); } -int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data, uint32_t length) +int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data, uint32_t length, int user_id) { MessageDef *message_p; @@ -255,10 +255,10 @@ int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3, plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3); - return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); + return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p); } -int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length) +int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length, int user_id) { MessageDef *message_p; @@ -268,10 +268,10 @@ int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = data; NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = length; - return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); + return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p); } -int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode) +int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode, int user_id) { MessageDef *message_p; @@ -287,5 +287,5 @@ int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, NULL,0, "0 NAS_RAB_ESTABLI_RSP MME code %u m-TMSI %u rb id %u status %u", s_tmsi.MMEcode, s_tmsi.m_tmsi,rabID, errCode ); - return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); + return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p); } diff --git a/openair3/NAS/UE/nas_itti_messaging.h b/openair3/NAS/UE/nas_itti_messaging.h index 22c09f109b3be64977db004b3d12579f5ff2b688..f4f1f184143cc7e64f54293f04e9bb731da07b12 100644 --- a/openair3/NAS/UE/nas_itti_messaging.h +++ b/openair3/NAS/UE/nas_itti_messaging.h @@ -50,12 +50,12 @@ int nas_itti_protected_msg( int nas_itti_kenb_refresh_req(const Byte_t kenb[32]); -int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat); +int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id); -int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data_pP, uint32_t lengthP); +int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data_pP, uint32_t lengthP, int user_id); -int nas_itti_ul_data_req(const uint32_t ue_idP, void *const data_pP, const uint32_t lengthP); +int nas_itti_ul_data_req(const uint32_t ue_idP, void *const data_pP, const uint32_t lengthP, int user_id); -int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode); +int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode, int user_id); # endif #endif /* NAS_ITTI_MESSAGING_H_ */ diff --git a/openair3/NAS/UE/nas_network.c b/openair3/NAS/UE/nas_network.c index f3ee3d2955c5ed67dab2b9ba020cdb4873544edf..6ca4a34c7ffaa13b85d9cabe8dd4f160f84fa72c 100644 --- a/openair3/NAS/UE/nas_network.c +++ b/openair3/NAS/UE/nas_network.c @@ -43,6 +43,7 @@ Description NAS procedure functions triggered by the network #include "as_message.h" #include "nas_proc.h" +#include "user_defs.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -91,11 +92,11 @@ void nas_network_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -void nas_network_cleanup(void) +void nas_network_cleanup(nas_user_t *user) { LOG_FUNC_IN; - nas_proc_cleanup(); + nas_proc_cleanup(user); LOG_FUNC_OUT; } @@ -118,7 +119,7 @@ void nas_network_cleanup(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_network_process_data(int msg_id, const void *data) +int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) { LOG_FUNC_IN; @@ -142,7 +143,7 @@ int nas_network_process_data(int msg_id, const void *data) /* Received cell information confirm */ const cell_info_cnf_t *info = &msg->msg.cell_info_cnf; int cell_found = (info->errCode == AS_SUCCESS); - rc = nas_proc_cell_info(cell_found, info->tac, + rc = nas_proc_cell_info(user, cell_found, info->tac, info->cellID, info->rat, info->rsrp, info->rsrq); break; @@ -160,12 +161,12 @@ int nas_network_process_data(int msg_id, const void *data) if ( (confirm->errCode == AS_SUCCESS) || (confirm->errCode == AS_TERMINATED_NAS) ) { - rc = nas_proc_establish_cnf(confirm->nasMsg.data, + rc = nas_proc_establish_cnf(user, confirm->nasMsg.data, confirm->nasMsg.length); } else { LOG_TRACE(WARNING, "NET-MAIN - " "Initial NAS message not delivered"); - rc = nas_proc_establish_rej(); + rc = nas_proc_establish_rej(user); } break; @@ -173,7 +174,7 @@ int nas_network_process_data(int msg_id, const void *data) case AS_NAS_RELEASE_IND: /* Received NAS signalling connection releaase indication */ - rc = nas_proc_release_ind(msg->msg.nas_release_ind.cause); + rc = nas_proc_release_ind(user, msg->msg.nas_release_ind.cause); break; case AS_UL_INFO_TRANSFER_CNF: @@ -182,9 +183,9 @@ int nas_network_process_data(int msg_id, const void *data) if (msg->msg.ul_info_transfer_cnf.errCode != AS_SUCCESS) { LOG_TRACE(WARNING, "NET-MAIN - " "Uplink NAS message not delivered"); - rc = nas_proc_ul_transfer_rej(); + rc = nas_proc_ul_transfer_rej(user); } else { - rc = nas_proc_ul_transfer_cnf(); + rc = nas_proc_ul_transfer_cnf(user); } break; @@ -192,7 +193,7 @@ int nas_network_process_data(int msg_id, const void *data) case AS_DL_INFO_TRANSFER_IND: { const dl_info_transfer_ind_t *info = &msg->msg.dl_info_transfer_ind; /* Received downlink data transfer indication */ - rc = nas_proc_dl_transfer_ind(info->nasMsg.data, + rc = nas_proc_dl_transfer_ind(user, info->nasMsg.data, info->nasMsg.length); break; } diff --git a/openair3/NAS/UE/nas_network.h b/openair3/NAS/UE/nas_network.h index 363f63c5ab16d2d4f3fe851b0b4dfe8d9c5f0206..fb05c8dd2a044b1c84a1ceb6c3891aa789960d60 100644 --- a/openair3/NAS/UE/nas_network.h +++ b/openair3/NAS/UE/nas_network.h @@ -40,6 +40,8 @@ Description NAS procedure functions triggered by the network #ifndef __NAS_NETWORK_H__ #define __NAS_NETWORK_H__ +#include "user_defs.h" + /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ @@ -59,9 +61,9 @@ Description NAS procedure functions triggered by the network void nas_network_initialize(void); -void nas_network_cleanup(void); +void nas_network_cleanup(nas_user_t *user); -int nas_network_process_data(int command_id, const void *data); +int nas_network_process_data(nas_user_t *user, int command_id, const void *data); const void *nas_network_get_data(void); diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 79b66269955616bb74db6659ac7bc5df75c33484..97ecea8e5a7b4ca09b8eeb9653e7797ce021d73f 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -38,6 +38,8 @@ Description NAS procedure call manager #include "nas_proc.h" #include "nas_log.h" +#include "nas_user.h" +#include "utils.h" #include "emm_main.h" #include "emm_sap.h" @@ -62,20 +64,9 @@ Description NAS procedure call manager #define NAS_PROC_RSRQ_UNKNOWN 255 #define NAS_PROC_RSRP_UNKNOWN 255 -/* - * Local NAS data - */ -static struct { - /* EPS capibility status */ - int EPS_capability_status; - /* Reference signal received quality */ - int rsrq; - /* Reference signal received power */ - int rsrp; -} _nas_proc_data; - -static int _nas_proc_activate(int cid, int apply_to_all); -static int _nas_proc_deactivate(int cid, int apply_to_all); + +static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all); +static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -97,21 +88,24 @@ static int _nas_proc_deactivate(int cid, int apply_to_all); ** Others: _nas_proc_data ** ** ** ***************************************************************************/ -void nas_proc_initialize(emm_indication_callback_t emm_cb, +void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *imei) { LOG_FUNC_IN; /* Initialize local NAS data */ - _nas_proc_data.EPS_capability_status = FALSE; - _nas_proc_data.rsrq = NAS_PROC_RSRQ_UNKNOWN; - _nas_proc_data.rsrp = NAS_PROC_RSRP_UNKNOWN; + user->proc.EPS_capability_status = FALSE; + user->proc.rsrq = NAS_PROC_RSRQ_UNKNOWN; + user->proc.rsrp = NAS_PROC_RSRP_UNKNOWN; + + user->authentication_data = calloc_or_fail(sizeof(authentication_data_t)); + user->security_data = calloc_or_fail( sizeof(security_data_t)); /* Initialize the EMM procedure manager */ - emm_main_initialize(emm_cb, imei); + emm_main_initialize(user, emm_cb, imei); /* Initialize the ESM procedure manager */ - esm_main_initialize(esm_cb); + esm_main_initialize(user, esm_cb); LOG_FUNC_OUT; } @@ -131,12 +125,12 @@ void nas_proc_initialize(emm_indication_callback_t emm_cb, ** Others: None ** ** ** ***************************************************************************/ -void nas_proc_cleanup(void) +void nas_proc_cleanup(nas_user_t *user) { LOG_FUNC_IN; /* Detach the UE from the EPS network */ - int rc = nas_proc_detach(TRUE); + int rc = nas_proc_detach(user, TRUE); if (rc != RETURNok) { LOG_TRACE(ERROR, "NAS-PROC - Failed to detach from the network"); @@ -144,10 +138,10 @@ void nas_proc_cleanup(void) /* Perform the EPS Mobility Manager's clean up procedure */ - emm_main_cleanup(); + emm_main_cleanup(user); /* Perform the EPS Session Manager's clean up procedure */ - esm_main_cleanup(); + esm_main_cleanup(user->esm_data); LOG_FUNC_OUT; } @@ -172,7 +166,7 @@ void nas_proc_cleanup(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_enable_s1_mode(void) +int nas_proc_enable_s1_mode(nas_user_t *user) { LOG_FUNC_IN; @@ -183,9 +177,9 @@ int nas_proc_enable_s1_mode(void) * Notify the EMM procedure call manager that EPS capability * of the UE is enabled */ - _nas_proc_data.EPS_capability_status = TRUE; + user->proc.EPS_capability_status = TRUE; emm_sap.primitive = EMMREG_S1_ENABLED; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -205,7 +199,7 @@ int nas_proc_enable_s1_mode(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_disable_s1_mode(void) +int nas_proc_disable_s1_mode(nas_user_t *user) { LOG_FUNC_IN; @@ -216,9 +210,9 @@ int nas_proc_disable_s1_mode(void) * Notify the EMM procedure call manager that EPS capability * of the UE is disabled */ - _nas_proc_data.EPS_capability_status = FALSE; + user->proc.EPS_capability_status = FALSE; emm_sap.primitive = EMMREG_S1_DISABLED; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -238,11 +232,11 @@ int nas_proc_disable_s1_mode(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_eps(int *stat) +int nas_proc_get_eps(nas_user_t *user, int *stat) { LOG_FUNC_IN; - *stat = _nas_proc_data.EPS_capability_status; + *stat = user->proc.EPS_capability_status; LOG_FUNC_RETURN (RETURNok); } @@ -261,11 +255,11 @@ int nas_proc_get_eps(int *stat) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_imsi(char *imsi_str) +int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str) { LOG_FUNC_IN; - const imsi_t *imsi = emm_main_get_imsi(); + const imsi_t *imsi = emm_main_get_imsi(emm_data); if (imsi != NULL) { int offset = 0; @@ -309,11 +303,11 @@ int nas_proc_get_imsi(char *imsi_str) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi) +int nas_proc_get_msisdn(nas_user_t *user, char *msisdn_str, int *ton_npi) { LOG_FUNC_IN; - const msisdn_t *msisdn = emm_main_get_msisdn(); + const msisdn_t *msisdn = emm_main_get_msisdn(user); if (msisdn != NULL) { union { @@ -358,12 +352,12 @@ int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_signal_quality(int *rsrq, int *rsrp) +int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp) { LOG_FUNC_IN; - *rsrq = _nas_proc_data.rsrq; - *rsrp = _nas_proc_data.rsrp; + *rsrq = user->proc.rsrq; + *rsrp = user->proc.rsrp; LOG_FUNC_RETURN (RETURNok); } @@ -387,7 +381,7 @@ int nas_proc_get_signal_quality(int *rsrq, int *rsrp) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT) +int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn_t *oper, int AcT) { LOG_FUNC_IN; @@ -396,7 +390,7 @@ int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT) /* * Set the PLMN selection mode of operation */ - int index = emm_main_set_plmn_selection_mode(mode, format, oper, AcT); + int index = emm_main_set_plmn_selection_mode(user, mode, format, oper, AcT); if ( !(index < 0) ) { /* @@ -406,7 +400,7 @@ int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT) emm_sap_t emm_sap; emm_sap.primitive = EMMREG_REGISTER_REQ; emm_sap.u.emm_reg.u.regist.index = index; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); @@ -426,7 +420,7 @@ int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_deregister(void) +int nas_proc_deregister(nas_user_t *user) { LOG_FUNC_IN; @@ -456,22 +450,22 @@ int nas_proc_deregister(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_reg_data(int *mode, int *selected, int format, +int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format, network_plmn_t *oper, int *AcT) { LOG_FUNC_IN; /* Get the PLMN selection mode of operation */ - *mode = emm_main_get_plmn_selection_mode(); + *mode = emm_main_get_plmn_selection_mode(user->emm_data); /* Get the currently selected operator */ - const char *oper_name = emm_main_get_selected_plmn(oper, format); + const char *oper_name = emm_main_get_selected_plmn(user->emm_plmn_list, user->emm_data, oper, format); if (oper_name != NULL) { /* An operator is currently selected */ *selected = TRUE; /* Get the supported Radio Access Technology */ - *AcT = emm_main_get_plmn_rat(); + *AcT = emm_main_get_plmn_rat(user->emm_data); } else { /* No any operator is selected */ *selected = FALSE; @@ -495,11 +489,11 @@ int nas_proc_get_reg_data(int *mode, int *selected, int format, ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_oper_list(const char **oper_list) +int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list) { LOG_FUNC_IN; - int size = emm_main_get_plmn_list(oper_list); + int size = emm_main_get_plmn_list(user->emm_plmn_list, user->emm_data, oper_list); LOG_FUNC_RETURN (size); } @@ -520,11 +514,11 @@ int nas_proc_get_oper_list(const char **oper_list) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_reg_status(int *stat) +int nas_proc_get_reg_status(nas_user_t *user, int *stat) { LOG_FUNC_IN; - *stat = emm_main_get_plmn_status(); + *stat = emm_main_get_plmn_status(user->emm_data); LOG_FUNC_RETURN (RETURNok); } @@ -548,13 +542,13 @@ int nas_proc_get_reg_status(int *stat) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_loc_info(char *tac, char *ci, int *AcT) +int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT) { LOG_FUNC_IN; - sprintf(tac, "%.4x", emm_main_get_plmn_tac()); // two byte - sprintf(ci, "%.8x", emm_main_get_plmn_ci()); // four byte - *AcT = emm_main_get_plmn_rat(); // E-UTRAN + sprintf(tac, "%.4x", emm_main_get_plmn_tac(user->emm_data)); // two byte + sprintf(ci, "%.8x", emm_main_get_plmn_ci(user->emm_data)); // four byte + *AcT = emm_main_get_plmn_rat(user->emm_data); // E-UTRAN LOG_FUNC_RETURN (RETURNok); } @@ -573,18 +567,18 @@ int nas_proc_get_loc_info(char *tac, char *ci, int *AcT) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_detach(int switch_off) +int nas_proc_detach(nas_user_t *user, int switch_off) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc = RETURNok; - if ( emm_main_is_attached() ) { + if ( emm_main_is_attached(user->emm_data) ) { /* Initiate an Detach procedure */ emm_sap.primitive = EMMREG_DETACH_INIT; emm_sap.u.emm_reg.u.detach.switch_off = switch_off; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); @@ -604,18 +598,18 @@ int nas_proc_detach(int switch_off) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_attach(void) +int nas_proc_attach(nas_user_t *user) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc = RETURNok; - if ( !emm_main_is_attached() ) { + if ( !emm_main_is_attached(user->emm_data) ) { /* Initiate an Attach procedure */ emm_sap.primitive = EMMREG_ATTACH_INIT; emm_sap.u.emm_reg.u.attach.is_emergency = FALSE; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); @@ -636,11 +630,11 @@ int nas_proc_attach(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_attach_status(void) +int nas_proc_get_attach_status(nas_user_t *user) { LOG_FUNC_IN; - int is_attached = emm_main_is_attached(); + int is_attached = emm_main_is_attached(user->emm_data); LOG_FUNC_RETURN (is_attached); } @@ -659,11 +653,11 @@ int nas_proc_get_attach_status(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_range(void) +int nas_proc_get_pdn_range(esm_data_t *esm_data) { LOG_FUNC_IN; - int max_pdn_id = esm_main_get_nb_pdns_max(); + int max_pdn_id = esm_main_get_nb_pdns_max(esm_data); LOG_FUNC_RETURN (max_pdn_id); } @@ -684,7 +678,7 @@ int nas_proc_get_pdn_range(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_status(int *cids, int *states, int n_pdn_max) +int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max) { LOG_FUNC_IN; @@ -692,13 +686,13 @@ int nas_proc_get_pdn_status(int *cids, int *states, int n_pdn_max) int n_defined_pdn = 0; /* Get the maximum number of supported PDN contexts */ - int n_pdn = esm_main_get_nb_pdns_max(); + int n_pdn = esm_main_get_nb_pdns_max(user->esm_data); /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { /* Get the status of this PDN */ int state = FALSE; - int is_defined = esm_main_get_pdn_status(cid, &state); + int is_defined = esm_main_get_pdn_status(user, cid, &state); if (is_defined != FALSE) { /* This PDN has been defined */ @@ -728,7 +722,7 @@ int nas_proc_get_pdn_status(int *cids, int *states, int n_pdn_max) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_param(int *cids, int *types, const char **apns, +int nas_proc_get_pdn_param(esm_data_t *esm_data, int *cids, int *types, const char **apns, int n_pdn_max) { LOG_FUNC_IN; @@ -737,13 +731,13 @@ int nas_proc_get_pdn_param(int *cids, int *types, const char **apns, int n_defined_pdn = 0; /* Get the maximum number of supported PDN contexts */ - int n_pdn = esm_main_get_nb_pdns_max(); + int n_pdn = esm_main_get_nb_pdns_max(esm_data); /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { int emergency, active; /* Get PDN connection parameters */ - int rc = esm_main_get_pdn(cid, types, apns, &emergency, &active); + int rc = esm_main_get_pdn(esm_data, cid, types, apns, &emergency, &active); if (rc != RETURNerror) { /* This PDN has been defined */ @@ -780,7 +774,7 @@ int nas_proc_get_pdn_param(int *cids, int *types, const char **apns, ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_addr(int cid, int *cids, const char **addr1, +int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **addr1, const char **addr2, int n_pdn_max) { LOG_FUNC_IN; @@ -790,7 +784,7 @@ int nas_proc_get_pdn_addr(int cid, int *cids, const char **addr1, if (cid > 0) { /* Get addresses assigned to the specified PDN */ - rc = esm_main_get_pdn_addr(cid, addr1, addr2); + rc = esm_main_get_pdn_addr(user->esm_data, cid, addr1, addr2); if (rc != RETURNerror) { *cids = cid; @@ -798,12 +792,12 @@ int nas_proc_get_pdn_addr(int cid, int *cids, const char **addr1, } } else if (cid < 0) { /* Get the maximum number of supported PDN contexts */ - int n_pdn = esm_main_get_nb_pdns_max(); + int n_pdn = esm_main_get_nb_pdns_max(user->esm_data); /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { /* Get PDN connection addresses */ - rc = esm_main_get_pdn_addr(cid, addr1, addr2); + rc = esm_main_get_pdn_addr(user->esm_data, cid, addr1, addr2); if (rc != RETURNerror) { /* This PDN has been defined */ @@ -843,7 +837,7 @@ int nas_proc_get_pdn_addr(int cid, int *cids, const char **addr1, ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_set_pdn(int cid, int type, const char *apn, int ipv4_addr, +int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int ipv4_addr, int emergency, int p_cscf, int im_cn_signal) { LOG_FUNC_IN; @@ -862,7 +856,7 @@ int nas_proc_set_pdn(int cid, int type, const char *apn, int ipv4_addr, * Notify ESM that a new PDN context has to be defined for * the specified APN */ - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); LOG_FUNC_RETURN (rc); } @@ -881,7 +875,7 @@ int nas_proc_set_pdn(int cid, int type, const char *apn, int ipv4_addr, ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_reset_pdn(int cid) +int nas_proc_reset_pdn(nas_user_t *user, int cid) { LOG_FUNC_IN; @@ -895,7 +889,7 @@ int nas_proc_reset_pdn(int cid) /* * Notify ESM that the specified PDN context has to be undefined */ - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); LOG_FUNC_RETURN (rc); } @@ -915,7 +909,7 @@ int nas_proc_reset_pdn(int cid) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_deactivate_pdn(int cid) +int nas_proc_deactivate_pdn(nas_user_t *user, int cid) { LOG_FUNC_IN; @@ -923,15 +917,15 @@ int nas_proc_deactivate_pdn(int cid) if (cid > 0) { /* Deactivate only the specified PDN context */ - rc = _nas_proc_deactivate(cid, FALSE); + rc = _nas_proc_deactivate(user, cid, FALSE); } else { /* Do not deactivate the PDN connection established during initial * network attachment (identifier 1) */ cid = 2; /* Deactivate all active PDN contexts */ - while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max()+1)) { - rc = _nas_proc_deactivate(cid++, TRUE); + while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(user->esm_data)+1)) { + rc = _nas_proc_deactivate(user, cid++, TRUE); } } @@ -954,20 +948,20 @@ int nas_proc_deactivate_pdn(int cid) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_activate_pdn(int cid) +int nas_proc_activate_pdn(nas_user_t *user, int cid) { LOG_FUNC_IN; int rc = RETURNok; - if ( !emm_main_is_attached() ) { + if ( !emm_main_is_attached(user->emm_data) ) { /* * If the UE is not attached to the network, perform EPS attach * procedure prior to attempt to request any PDN connectivity */ LOG_TRACE(WARNING, "NAS-PROC - UE is not attached to the network"); - rc = nas_proc_attach(); - } else if (emm_main_is_emergency()) { + rc = nas_proc_attach(user); + } else if (emm_main_is_emergency(user->emm_data)) { /* The UE is attached for emergency bearer services; It shall not * request a PDN connection to any other PDN */ LOG_TRACE(WARNING,"NAS-PROC - Attached for emergency bearer services"); @@ -977,13 +971,13 @@ int nas_proc_activate_pdn(int cid) if (rc != RETURNerror) { if (cid > 0) { /* Activate only the specified PDN context */ - rc = _nas_proc_activate(cid, FALSE); + rc = _nas_proc_activate(user, cid, FALSE); } else { cid = 1; /* Activate all defined PDN contexts */ - while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max()+1)) { - rc = _nas_proc_activate(cid++, TRUE); + while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(user->esm_data)+1)) { + rc = _nas_proc_activate(user, cid++, TRUE); } } } @@ -1021,7 +1015,7 @@ int nas_proc_activate_pdn(int cid) ** Others: _nas_proc_data ** ** ** ***************************************************************************/ -int nas_proc_cell_info(int found, tac_t tac, ci_t ci, AcT_t AcT, +int nas_proc_cell_info(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t AcT, uint8_t rsrq, uint8_t rsrp) { LOG_FUNC_IN; @@ -1030,8 +1024,8 @@ int nas_proc_cell_info(int found, tac_t tac, ci_t ci, AcT_t AcT, int rc; /* Store LTE signal strength/quality measurement data */ - _nas_proc_data.rsrq = rsrq; - _nas_proc_data.rsrp = rsrp; + user->proc.rsrq = rsrq; + user->proc.rsrp = rsrp; /* * Notify the EMM procedure call manager that cell information @@ -1044,7 +1038,7 @@ int nas_proc_cell_info(int found, tac_t tac, ci_t ci, AcT_t AcT, emm_sap.u.emm_as.u.cell_info.tac = tac; emm_sap.u.emm_as.u.cell_info.cellID = ci; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1066,7 +1060,7 @@ int nas_proc_cell_info(int found, tac_t tac, ci_t ci, AcT_t AcT, ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_establish_cnf(const Byte_t *data, uint32_t len) +int nas_proc_establish_cnf(nas_user_t *user, const Byte_t *data, uint32_t len) { LOG_FUNC_IN; @@ -1081,7 +1075,7 @@ int nas_proc_establish_cnf(const Byte_t *data, uint32_t len) emm_sap.primitive = EMMAS_ESTABLISH_CNF; emm_sap.u.emm_as.u.establish.NASmsg.length = len; emm_sap.u.emm_as.u.establish.NASmsg.value = (uint8_t *)data; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1103,7 +1097,7 @@ int nas_proc_establish_cnf(const Byte_t *data, uint32_t len) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_establish_rej(void) +int nas_proc_establish_rej(nas_user_t *user) { LOG_FUNC_IN; @@ -1116,7 +1110,7 @@ int nas_proc_establish_rej(void) * from lower layers */ emm_sap.primitive = EMMAS_ESTABLISH_REJ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1136,7 +1130,7 @@ int nas_proc_establish_rej(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_release_ind(int cause) +int nas_proc_release_ind(nas_user_t *user, int cause) { LOG_FUNC_IN; @@ -1149,7 +1143,7 @@ int nas_proc_release_ind(int cause) */ emm_sap.primitive = EMMAS_RELEASE_IND; emm_sap.u.emm_as.u.release.cause = cause; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1170,7 +1164,7 @@ int nas_proc_release_ind(int cause) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_ul_transfer_cnf(void) +int nas_proc_ul_transfer_cnf(nas_user_t *user) { LOG_FUNC_IN; @@ -1183,10 +1177,10 @@ int nas_proc_ul_transfer_cnf(void) * receiver side */ emm_sap.primitive = EMMAS_DATA_IND; - emm_sap.u.emm_as.u.data.ueid = 0; + emm_sap.u.emm_as.u.data.ueid = user->ueid; emm_sap.u.emm_as.u.data.delivered = TRUE; emm_sap.u.emm_as.u.data.NASmsg.length = 0; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1207,7 +1201,7 @@ int nas_proc_ul_transfer_cnf(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_ul_transfer_rej(void) +int nas_proc_ul_transfer_rej(nas_user_t *user) { LOG_FUNC_IN; @@ -1220,10 +1214,10 @@ int nas_proc_ul_transfer_rej(void) * from lower layers */ emm_sap.primitive = EMMAS_DATA_IND; - emm_sap.u.emm_as.u.data.ueid = 0; + emm_sap.u.emm_as.u.data.ueid = user->ueid; emm_sap.u.emm_as.u.data.delivered = FALSE; emm_sap.u.emm_as.u.data.NASmsg.length = 0; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1244,7 +1238,7 @@ int nas_proc_ul_transfer_rej(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_dl_transfer_ind(const Byte_t *data, uint32_t len) +int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) { LOG_FUNC_IN; @@ -1257,11 +1251,11 @@ int nas_proc_dl_transfer_ind(const Byte_t *data, uint32_t len) * indication has been received from the Access-Stratum sublayer */ emm_sap.primitive = EMMAS_DATA_IND; - emm_sap.u.emm_as.u.data.ueid = 0; + emm_sap.u.emm_as.u.data.ueid = user->ueid; emm_sap.u.emm_as.u.data.delivered = TRUE; emm_sap.u.emm_as.u.data.NASmsg.length = len; emm_sap.u.emm_as.u.data.NASmsg.value = (uint8_t *)data; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); @@ -1291,7 +1285,7 @@ int nas_proc_dl_transfer_ind(const Byte_t *data, uint32_t len) ** Others: None ** ** ** ***************************************************************************/ -static int _nas_proc_activate(int cid, int apply_to_all) +static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) { LOG_FUNC_IN; @@ -1301,7 +1295,7 @@ static int _nas_proc_activate(int cid, int apply_to_all) esm_sap_t esm_sap; /* Get PDN context parameters */ - rc = esm_main_get_pdn(cid, &esm_sap.data.pdn_connect.pdn_type, + rc = esm_main_get_pdn(user->esm_data, cid, &esm_sap.data.pdn_connect.pdn_type, &esm_sap.data.pdn_connect.apn, &esm_sap.data.pdn_connect.is_emergency, &active); @@ -1323,7 +1317,7 @@ static int _nas_proc_activate(int cid, int apply_to_all) } if (esm_sap.data.pdn_connect.is_emergency) { - if (esm_main_has_emergency()) { + if (esm_main_has_emergency(user->esm_data)) { /* There is already a PDN connection for emergency * bearer services established; the UE shall not * request an additional PDN connection for emer- @@ -1342,7 +1336,7 @@ static int _nas_proc_activate(int cid, int apply_to_all) esm_sap.is_standalone = TRUE; esm_sap.data.pdn_connect.is_defined = TRUE; esm_sap.data.pdn_connect.cid = cid; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); LOG_FUNC_RETURN (rc); } @@ -1364,7 +1358,7 @@ static int _nas_proc_activate(int cid, int apply_to_all) ** Others: None ** ** ** ***************************************************************************/ -static int _nas_proc_deactivate(int cid, int apply_to_all) +static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all) { LOG_FUNC_IN; @@ -1375,7 +1369,7 @@ static int _nas_proc_deactivate(int cid, int apply_to_all) int active = FALSE; /* Get PDN context parameters */ - rc = esm_main_get_pdn(cid, &pdn_type, &apn, &emergency, &active); + rc = esm_main_get_pdn(user->esm_data, cid, &pdn_type, &apn, &emergency, &active); if (rc != RETURNok) { /* No any context is defined for the specified PDN */ @@ -1393,7 +1387,7 @@ static int _nas_proc_deactivate(int cid, int apply_to_all) LOG_FUNC_RETURN (RETURNok); } - if (esm_main_get_nb_pdns() > 1) { + if (esm_main_get_nb_pdns(user->esm_data) > 1) { /* * Notify ESM that all EPS bearers towards the specified PDN * has to be released @@ -1401,7 +1395,7 @@ static int _nas_proc_deactivate(int cid, int apply_to_all) esm_sap_t esm_sap; esm_sap.primitive = ESM_PDN_DISCONNECT_REQ; esm_sap.data.pdn_disconnect.cid = cid; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } else { /* For EPS, if an attempt is made to disconnect the last PDN * connection, then the MT responds with an error */ diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index 4514983df88d28f981c435469475fe83f9119028..bf8dec9e58a19e81986a3d0eb4f598ea9ae5ea47 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -40,6 +40,10 @@ Description NAS procedure call manager #include "commonDef.h" #include "networkDef.h" +#include "user_defs.h" +#include "emm_main.h" +#include "esm_ebr.h" +#include "esmData.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -57,10 +61,10 @@ Description NAS procedure call manager /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void nas_proc_initialize(emm_indication_callback_t emm_cb, +void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *imei); -void nas_proc_cleanup(void); +void nas_proc_cleanup(nas_user_t *user); /* * -------------------------------------------------------------------------- @@ -68,39 +72,39 @@ void nas_proc_cleanup(void); * -------------------------------------------------------------------------- */ -int nas_proc_enable_s1_mode(void); -int nas_proc_disable_s1_mode(void); -int nas_proc_get_eps(int *stat); +int nas_proc_enable_s1_mode(nas_user_t *user); +int nas_proc_disable_s1_mode(nas_user_t *user); +int nas_proc_get_eps(nas_user_t *user, int *stat); -int nas_proc_get_imsi(char *imsi_str); -int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi); +int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str); +int nas_proc_get_msisdn(nas_user_t *user, char *msisdn_str, int *ton_npi); -int nas_proc_get_signal_quality(int *rsrq, int *rsrp); +int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp); -int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT); -int nas_proc_deregister(void); -int nas_proc_get_reg_data(int *mode, int *selected, int format, +int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn_t *oper, int AcT); +int nas_proc_deregister(nas_user_t *user); +int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format, network_plmn_t *oper, int *AcT); -int nas_proc_get_oper_list(const char **oper_list); +int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list); -int nas_proc_get_reg_status(int *stat); -int nas_proc_get_loc_info(char *tac, char *ci, int *AcT); +int nas_proc_get_reg_status(nas_user_t *user, int *stat); +int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT); -int nas_proc_detach(int switch_off); -int nas_proc_attach(void); -int nas_proc_get_attach_status(void); +int nas_proc_detach(nas_user_t *user, int switch_off); +int nas_proc_attach(nas_user_t *user); +int nas_proc_get_attach_status(nas_user_t *user); -int nas_proc_reset_pdn(int cid); -int nas_proc_set_pdn(int cid, int type, const char *apn, int ipv4_addr, +int nas_proc_reset_pdn(nas_user_t *user, int cid); +int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int ipv4_addr, int emergency, int p_cscf, int im_cn_signal); -int nas_proc_get_pdn_range(void); -int nas_proc_get_pdn_status(int *cids, int *states, int n_pdn_max); -int nas_proc_get_pdn_param(int *cids, int *types, const char **apns, +int nas_proc_get_pdn_range(esm_data_t *esm_data); +int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max); +int nas_proc_get_pdn_param(esm_data_t *esm_data, int *cids, int *types, const char **apns, int n_pdn_max); -int nas_proc_get_pdn_addr(int cid, int *cids, const char **addr1, +int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **addr1, const char **addr2, int n_addr_max); -int nas_proc_deactivate_pdn(int cid); -int nas_proc_activate_pdn(int cid); +int nas_proc_deactivate_pdn(nas_user_t *user, int cid); +int nas_proc_activate_pdn(nas_user_t *user, int cid); /* * -------------------------------------------------------------------------- @@ -108,17 +112,17 @@ int nas_proc_activate_pdn(int cid); * -------------------------------------------------------------------------- */ -int nas_proc_cell_info(int found, tac_t tac, ci_t ci, AcT_t rat, uint8_t rsrp, +int nas_proc_cell_info(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat, uint8_t rsrp, uint8_t rsrq); -int nas_proc_establish_cnf(const Byte_t *data, uint32_t len); -int nas_proc_establish_rej(void); +int nas_proc_establish_cnf(nas_user_t *user, const Byte_t *data, uint32_t len); +int nas_proc_establish_rej(nas_user_t *user); -int nas_proc_release_ind(int cause); +int nas_proc_release_ind(nas_user_t *user, int cause); -int nas_proc_ul_transfer_cnf(void); -int nas_proc_ul_transfer_rej(void); -int nas_proc_dl_transfer_ind(const Byte_t *data, uint32_t len); +int nas_proc_ul_transfer_cnf(nas_user_t *user); +int nas_proc_ul_transfer_rej(nas_user_t *user); +int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len); diff --git a/openair3/NAS/UE/nas_proc_defs.h b/openair3/NAS/UE/nas_proc_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..1ce2bfd929df7734eafd738df34787c388b263f6 --- /dev/null +++ b/openair3/NAS/UE/nas_proc_defs.h @@ -0,0 +1,43 @@ +#ifndef _NAS_PROC_DEFS_H +#define _NAS_PROC_DEFS_H + +/* + * Local NAS data + */ +typedef struct { + /* EPS capibility status */ + int EPS_capability_status; + /* Reference signal received quality */ + int rsrq; + /* Reference signal received power */ + int rsrp; +} proc_data_t; + +/* + * MT SIM pending status (see ETSI TS 127 007 V10.6.0, Note 2) + * Commands which interact with MT that are accepted when MT is pending SIM PIN, + * SIM PUK, or PH-SIM are: +CGMI, +CGMM, +CGMR, +CGSN, D112; (emergency call), + * +CPAS, +CFUN, +CPIN, +CPINR, +CDIS (read and test command only), and +CIND + * (read and test command only). +*/ +typedef enum { + NAS_USER_READY, /* MT is not pending for any password */ + NAS_USER_SIM_PIN, /* MT is waiting SIM PIN to be given */ + NAS_USER_SIM_PUK, /* MT is waiting SIM PUK to be given */ + NAS_USER_PH_SIM_PIN /* MT is waiting phone-to-SIM card + * password to be given */ +} nas_user_sim_status; + +/* + * The local UE context + */ +typedef struct { + /* Firmware version number */ + const char *version; + /* SIM pending status */ + nas_user_sim_status sim_status; + /* Level of functionality */ + int fun; +} nas_user_context_t; + +#endif diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 9d097fc3897030e8491271e7cf89e472c4c95e2f..2a42b38a7248a3bfe24eea3bae51b9d958b76a4d 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -19,26 +19,32 @@ * contact@openairinterface.org */ +#include "utils.h" #if defined(ENABLE_ITTI) # include "assertions.h" # include "intertask_interface.h" # include "nas_ue_task.h" # include "UTIL/LOG/log.h" -# include "nas_user.h" +# include "user_defs.h" # include "user_api.h" # include "nas_parser.h" # include "nas_proc.h" # include "msc.h" +# include "memory.h" +#include "nas_user.h" + +// FIXME make command line option for NAS_UE_AUTOSTART # define NAS_UE_AUTOSTART 1 +// FIXME review these externs extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; -static int user_fd; +char *make_port_str_from_ueid(const char *base_port_str, int ueid); -static int nas_ue_process_events(struct epoll_event *events, int nb_events) +static int nas_ue_process_events(nas_user_container_t *users, struct epoll_event *events, int nb_events) { int event; int exit_loop = FALSE; @@ -48,8 +54,9 @@ static int nas_ue_process_events(struct epoll_event *events, int nb_events) for (event = 0; event < nb_events; event++) { if (events[event].events != 0) { /* If the event has not been yet been processed (not an itti message) */ - if (events[event].data.fd == user_fd) { - exit_loop = nas_user_receive_and_process(&user_fd, NULL); + nas_user_t *user = find_user_from_fd(users, events[event].data.fd); + if ( user != NULL ) { + exit_loop = nas_user_receive_and_process(user, NULL); } else { LOG_E(NAS, "[UE] Received an event from an unknown fd %d!\n", events[event].data.fd); } @@ -59,6 +66,24 @@ static int nas_ue_process_events(struct epoll_event *events, int nb_events) return (exit_loop); } +// Initialize user api id and port number +void nas_user_api_id_initialize(nas_user_t *user) { + user_api_id_t *user_api_id = calloc_or_fail(sizeof(user_api_id_t)); + user->user_api_id = user_api_id; + char *port = make_port_str_from_ueid(NAS_PARSER_DEFAULT_USER_PORT_NUMBER, user->ueid); + if ( port == NULL ) { + LOG_E(NAS, "[UE %d] can't get port from ueid %d !", user->ueid); + exit (EXIT_FAILURE); + } + if (user_api_initialize (user_api_id, NAS_PARSER_DEFAULT_USER_HOSTNAME, port, NULL, + NULL) != RETURNok) { + LOG_E(NAS, "[UE %d] user interface initialization failed!", user->ueid); + exit (EXIT_FAILURE); + } + free(port); + itti_subscribe_event_fd (TASK_NAS_UE, user_api_get_fd(user_api_id)); +} + void *nas_ue_task(void *args_p) { int nb_events; @@ -68,25 +93,45 @@ void *nas_ue_task(void *args_p) instance_t instance; unsigned int Mod_id; int result; + nas_user_container_t *users=args_p; itti_mark_task_ready (TASK_NAS_UE); MSC_START_USE(); /* Initialize UE NAS (EURECOM-NAS) */ + for (int i=0; i < users->count; i++) { - /* Initialize user interface (to exchange AT commands with user process) */ - { - if (user_api_initialize (NAS_PARSER_DEFAULT_USER_HOSTNAME, NAS_PARSER_DEFAULT_USER_PORT_NUMBER, NULL, - NULL) != RETURNok) { - LOG_E(NAS, "[UE] user interface initialization failed!"); - exit (EXIT_FAILURE); - } + nas_user_t *user = &users->item[i]; + user->ueid=i; + + /* Get USIM data application 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 ) { + LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid, user->ueid); + exit(EXIT_FAILURE); + } + + /* Get UE's data pathname */ + user->user_nvdata_store = memory_get_path_from_ueid(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME, user->ueid); + if ( user->user_nvdata_store == NULL ) { + LOG_E(NAS, "[UE %d] - Failed to get USIM nvdata filename", user->ueid); + exit(EXIT_FAILURE); + } - user_fd = user_api_get_fd (); - itti_subscribe_event_fd (TASK_NAS_UE, user_fd); + /* Get EMM data pathname */ + user->emm_nvdata_store = memory_get_path_from_ueid(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME, user->ueid); + if ( user->emm_nvdata_store == NULL ) { + LOG_E(NAS, "[UE %d] - Failed to get EMM nvdata filename", user->ueid); + exit(EXIT_FAILURE); } + /* Initialize user interface (to exchange AT commands with user process) */ + nas_user_api_id_initialize(user); + /* allocate needed structures */ + user->user_at_commands = calloc_or_fail(sizeof(user_at_commands_t)); + user->at_response = calloc_or_fail(sizeof(at_response_t)); + user->lowerlayer_data = calloc_or_fail(sizeof(lowerlayer_data_t)); /* Initialize NAS user */ - nas_user_initialize (&user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); + nas_user_initialize (user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); } /* Set UE activation state */ @@ -105,6 +150,12 @@ void *nas_ue_task(void *args_p) msg_name = ITTI_MSG_NAME (msg_p); instance = ITTI_MSG_INSTANCE (msg_p); Mod_id = instance - NB_eNB_INST; + if (instance == INSTANCE_DEFAULT) { + printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n", + __FILE__, __LINE__); + abort(); + } + nas_user_t *user = &users->item[Mod_id]; switch (ITTI_MSG_ID(msg_p)) { case INITIALIZE_MESSAGE: @@ -114,7 +165,7 @@ void *nas_ue_task(void *args_p) /* Send an activate modem command to NAS like UserProcess should do it */ char *user_data = "at+cfun=1\r"; - nas_user_receive_and_process (&user_fd, user_data); + nas_user_receive_and_process (user, user_data); } #endif break; @@ -134,7 +185,7 @@ void *nas_ue_task(void *args_p) { int cell_found = (NAS_CELL_SELECTION_CNF (msg_p).errCode == AS_SUCCESS); - nas_proc_cell_info (cell_found, NAS_CELL_SELECTION_CNF (msg_p).tac, + nas_proc_cell_info (user, cell_found, NAS_CELL_SELECTION_CNF (msg_p).tac, NAS_CELL_SELECTION_CNF (msg_p).cellID, NAS_CELL_SELECTION_CNF (msg_p).rat, NAS_CELL_SELECTION_CNF (msg_p).rsrq, NAS_CELL_SELECTION_CNF (msg_p).rsrp); } @@ -160,7 +211,7 @@ void *nas_ue_task(void *args_p) if ((NAS_CONN_ESTABLI_CNF (msg_p).errCode == AS_SUCCESS) || (NAS_CONN_ESTABLI_CNF (msg_p).errCode == AS_TERMINATED_NAS)) { - nas_proc_establish_cnf(NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.data, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length); + nas_proc_establish_cnf(user, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.data, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length); /* TODO checks if NAS will free the nas message, better to do it there anyway! */ // result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data); @@ -173,7 +224,7 @@ void *nas_ue_task(void *args_p) LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, msg_name, NAS_CONN_RELEASE_IND (msg_p).cause); - nas_proc_release_ind (NAS_CONN_RELEASE_IND (msg_p).cause); + nas_proc_release_ind (user, NAS_CONN_RELEASE_IND (msg_p).cause); break; case NAS_UPLINK_DATA_CNF: @@ -181,9 +232,9 @@ void *nas_ue_task(void *args_p) NAS_UPLINK_DATA_CNF (msg_p).UEid, NAS_UPLINK_DATA_CNF (msg_p).errCode); if (NAS_UPLINK_DATA_CNF (msg_p).errCode == AS_SUCCESS) { - nas_proc_ul_transfer_cnf (); + nas_proc_ul_transfer_cnf (user); } else { - nas_proc_ul_transfer_rej (); + nas_proc_ul_transfer_rej (user); } break; @@ -192,7 +243,7 @@ void *nas_ue_task(void *args_p) LOG_I(NAS, "[UE %d] Received %s: UEid %u, length %u\n", Mod_id, msg_name, NAS_DOWNLINK_DATA_IND (msg_p).UEid, NAS_DOWNLINK_DATA_IND (msg_p).nasMsg.length); - nas_proc_dl_transfer_ind (NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length); + nas_proc_dl_transfer_ind (user, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length); if (0) { /* TODO checks if NAS will free the nas message, better to do it there anyway! */ @@ -215,10 +266,41 @@ void *nas_ue_task(void *args_p) nb_events = itti_get_events(TASK_NAS_UE, &events); if ((nb_events > 0) && (events != NULL)) { - if (nas_ue_process_events(events, nb_events) == TRUE) { + if (nas_ue_process_events(users, events, nb_events) == TRUE) { LOG_E(NAS, "[UE] Received exit loop\n"); } } } + + free(users); + return NULL; +} + +nas_user_t *find_user_from_fd(nas_user_container_t *users, int fd) { + for (int i=0; i<users->count; i++) { + nas_user_t *user = &users->item[i]; + if (fd == user_api_get_fd(user->user_api_id)) { + return user; + } + } + return NULL; +} + +char *make_port_str_from_ueid(const char *base_port_str, int ueid) { + int port; + int base_port; + char *endptr = NULL; + + base_port = strtol(base_port_str, &endptr, 10); + if ( base_port_str == endptr ) { + return NULL; + } + + port = base_port + ueid; + if ( port<1 || port > 65535 ) { + return NULL; + } + + return itoa(port); } #endif diff --git a/openair2/NAS/nas_ue_task.h b/openair3/NAS/UE/nas_ue_task.h similarity index 80% rename from openair2/NAS/nas_ue_task.h rename to openair3/NAS/UE/nas_ue_task.h index bc580726810cdf702db9f50435bb4dc09085b736..90ef26bd80ffbab5fdd6eac4d00938a8e4fcf706 100644 --- a/openair2/NAS/nas_ue_task.h +++ b/openair3/NAS/UE/nas_ue_task.h @@ -22,6 +22,17 @@ #ifndef NAS_UE_TASK_H_ #define NAS_UE_TASK_H_ +#include "openairinterface5g_limits.h" +#include "user_defs.h" + +// XXX simple array container for multiple users +typedef struct { + size_t count; + nas_user_t item[NUMBER_OF_UE_MAX]; +} nas_user_container_t; + +nas_user_t *find_user_from_fd(nas_user_container_t *users, int fd); + # if defined(ENABLE_ITTI) void *nas_ue_task(void *args_p); # endif diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 7616a48c0528045c02730c3f0560e532cd370a4e..3108858d06f539c4661c0fe27975dec90ff8e3fe 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -37,8 +37,7 @@ Description NAS procedure functions triggered by the user *****************************************************************************/ -#include "nas_user.h" -#include "userDef.h" +#include "user_defs.h" #include "nas_log.h" #include "memory.h" @@ -47,6 +46,8 @@ Description NAS procedure functions triggered by the user #include "at_error.h" #include "user_indication.h" #include "nas_proc.h" +#include "nas_user.h" +#include "utils.h" #include "user_api.h" #include <string.h> // memset, strncpy, strncmp @@ -65,30 +66,30 @@ Description NAS procedure functions triggered by the user * Functions executed upon receiving AT command from the user * --------------------------------------------------------------------- */ -static int _nas_user_proc_cgsn (const at_command_t *data); -static int _nas_user_proc_cgmi (const at_command_t *data); -static int _nas_user_proc_cgmm (const at_command_t *data); -static int _nas_user_proc_cgmr (const at_command_t *data); -static int _nas_user_proc_cimi (const at_command_t *data); -static int _nas_user_proc_cfun (const at_command_t *data); -static int _nas_user_proc_cpin (const at_command_t *data); -static int _nas_user_proc_csq (const at_command_t *data); -static int _nas_user_proc_cesq (const at_command_t *data); -static int _nas_user_proc_cops (const at_command_t *data); -static int _nas_user_proc_cgatt (const at_command_t *data); -static int _nas_user_proc_creg (const at_command_t *data); -static int _nas_user_proc_cgreg (const at_command_t *data); -static int _nas_user_proc_cereg (const at_command_t *data); -static int _nas_user_proc_cgdcont (const at_command_t *data); -static int _nas_user_proc_cgact (const at_command_t *data); -static int _nas_user_proc_cmee (const at_command_t *data); -static int _nas_user_proc_clck (const at_command_t *data); -static int _nas_user_proc_cgpaddr (const at_command_t *data); -static int _nas_user_proc_cnum (const at_command_t *data); -static int _nas_user_proc_clac (const at_command_t *data); +static int _nas_user_proc_cgsn (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgmi (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgmm (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgmr (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cimi (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cfun (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cpin (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_csq (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cesq (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cops (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgatt (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_creg (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgreg (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cereg (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgdcont (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgact (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cmee (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_clck (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgpaddr (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cnum (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_clac (nas_user_t *user, const at_command_t *data); /* NAS procedures applicable to AT commands */ -typedef int (*_nas_user_procedure_t) (const at_command_t *); +typedef int (*_nas_user_procedure_t) (nas_user_t *, const at_command_t *); static _nas_user_procedure_t _nas_user_procedure[AT_COMMAND_ID_MAX] = { NULL, @@ -115,31 +116,12 @@ static _nas_user_procedure_t _nas_user_procedure[AT_COMMAND_ID_MAX] = { _nas_user_proc_cgpaddr, /* CGPADDR */ }; -/* - * Internal representation of data structure returned to the user - * as the result of NAS procedure function call - */ -static at_response_t _nas_user_data = {}; - /* * --------------------------------------------------------------------- * Local UE context * --------------------------------------------------------------------- */ -/* - * MT SIM pending status (see ETSI TS 127 007 V10.6.0, Note 2) - * Commands which interact with MT that are accepted when MT is pending SIM PIN, - * SIM PUK, or PH-SIM are: +CGMI, +CGMM, +CGMR, +CGSN, D112; (emergency call), - * +CPAS, +CFUN, +CPIN, +CPINR, +CDIS (read and test command only), and +CIND - * (read and test command only). -*/ -typedef enum { - NAS_USER_READY, /* MT is not pending for any password */ - NAS_USER_SIM_PIN, /* MT is waiting SIM PIN to be given */ - NAS_USER_SIM_PUK, /* MT is waiting SIM PUK to be given */ - NAS_USER_PH_SIM_PIN /* MT is waiting phone-to-SIM card - * password to be given */ -} nas_user_sim_status; + static const char *_nas_user_sim_status_str[] = { "READY", "SIM PIN", @@ -147,29 +129,16 @@ static const char *_nas_user_sim_status_str[] = { "PH-SIM PIN" }; -/* - * The local UE context - */ -static struct { - /* Firmware version number */ - const char *version; - /* SIM pending status */ - nas_user_sim_status sim_status; - /* Level of functionality */ - int fun; -} _nas_user_context; - -/* - * --------------------------------------------------------------------- - * UE parameters stored in the UE's non-volatile memory device - * --------------------------------------------------------------------- - */ -static user_nvdata_t _nas_user_nvdata; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ +void _nas_user_context_initialize(nas_user_context_t *nas_user_context, const char *version) { + nas_user_context->version = version; + nas_user_context->sim_status = NAS_USER_SIM_PIN; + nas_user_context->fun = AT_CFUN_FUN_DEFAULT; +} + /**************************************************************************** ** ** ** Name: nas_user_initialize() ** @@ -183,38 +152,26 @@ static user_nvdata_t _nas_user_nvdata; ** ** ** Outputs: None ** ** Return: None ** - ** Others: _nas_user_nvdata, _nas_user_context ** ** ** ***************************************************************************/ -void nas_user_initialize(emm_indication_callback_t emm_cb, +void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *version) { LOG_FUNC_IN; - /* Get UE's data pathname */ - char *path = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME); - - if (path == NULL) { - LOG_TRACE(ERROR, "USR-MAIN - Failed to get UE's data pathname"); - } + user->nas_user_nvdata = calloc_or_fail(sizeof(user_nvdata_t)); /* Get UE data stored in the non-volatile memory device */ - else { - int rc = memory_read(path, &_nas_user_nvdata, sizeof(user_nvdata_t)); - - if (rc != RETURNok) { - LOG_TRACE(ERROR, "USR-MAIN - Failed to read %s", path); - } - - free(path); + int rc = memory_read(user->user_nvdata_store, user->nas_user_nvdata, sizeof(user_nvdata_t)); + if (rc != RETURNok) { + LOG_TRACE(ERROR, "USR-MAIN - Failed to read %s", user->nas_user_nvdata); } - _nas_user_context.version = version; - _nas_user_context.sim_status = NAS_USER_SIM_PIN; - _nas_user_context.fun = AT_CFUN_FUN_DEFAULT; + user->nas_user_context = calloc_or_fail(sizeof(nas_user_context_t)); + _nas_user_context_initialize(user->nas_user_context, version); /* Initialize the internal NAS processing data */ - nas_proc_initialize(emm_cb, esm_cb, _nas_user_nvdata.IMEI); + nas_proc_initialize(user, emm_cb, esm_cb, user->nas_user_nvdata->IMEI); LOG_FUNC_OUT; } @@ -232,7 +189,7 @@ void nas_user_initialize(emm_indication_callback_t emm_cb, ** Outputs: Return: FALSE, TRUE ** ** ** ***************************************************************************/ -int nas_user_receive_and_process(int *fd, char *message) +int nas_user_receive_and_process(nas_user_t *user, char *message) { LOG_FUNC_IN; @@ -240,13 +197,14 @@ int nas_user_receive_and_process(int *fd, char *message) int nb_command; int bytes; int i; + user_api_id_t *user_api_id = user->user_api_id; if (message != NULL) { /* Set the message in receive buffer (Use to simulate reception of data from UserProcess) */ - bytes = user_api_set_data(message); + bytes = user_api_set_data(user_api_id, message); } else { /* Read the user data message */ - bytes = user_api_read_data (*fd); + bytes = user_api_read_data (user_api_id); if (bytes == RETURNerror) { /* Failed to read data from the user application layer; @@ -263,11 +221,11 @@ int nas_user_receive_and_process(int *fd, char *message) } /* Decode the user data message */ - nb_command = user_api_decode_data (bytes); + nb_command = user_api_decode_data (user_api_id, user->user_at_commands, bytes); for (i = 0; i < nb_command; i++) { /* Get the user data to be processed */ - const void *data = user_api_get_data (i); + const void *data = user_api_get_data (user->user_at_commands, i); if (data == NULL) { /* Failed to get user data at the given index; @@ -279,7 +237,7 @@ int nas_user_receive_and_process(int *fd, char *message) } /* Process the user data message */ - ret_code = nas_user_process_data (data); + ret_code = nas_user_process_data (user, data); if (ret_code != RETURNok) { /* The user data message has not been successfully @@ -293,7 +251,7 @@ int nas_user_receive_and_process(int *fd, char *message) /* Send response to UserProcess (If not in simulated reception) */ if (message == NULL) { /* Encode the user data message */ - bytes = user_api_encode_data (nas_user_get_data (), i == nb_command - 1); + bytes = user_api_encode_data (user->user_api_id, nas_user_get_data (user), i == nb_command - 1); if (bytes == RETURNerror) { /* Failed to encode the user data message; @@ -302,7 +260,7 @@ int nas_user_receive_and_process(int *fd, char *message) } /* Send the data message to the user */ - bytes = user_api_send_data (*fd, bytes); + bytes = user_api_send_data (user_api_id, bytes); if (bytes == RETURNerror) { /* Failed to send data to the user application layer; @@ -331,12 +289,12 @@ int nas_user_receive_and_process(int *fd, char *message) ** Outputs: None ** ** Return: RETURNok if the command has been success- ** ** fully executed; RETURNerror otherwise ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -int nas_user_process_data(const void *data) +int nas_user_process_data(nas_user_t *user, const void *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNerror; @@ -355,18 +313,18 @@ int nas_user_process_data(const void *data) nas_procedure = _nas_user_procedure[user_data->id]; if (nas_procedure != NULL) { - ret_code = (*nas_procedure)(user_data); + ret_code = (*nas_procedure)(user, user_data); } else { /* AT command related to result format only */ - _nas_user_data.id = user_data->id; - _nas_user_data.type = user_data->type; - _nas_user_data.mask = user_data->mask; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = user_data->id; + at_response->type = user_data->type; + at_response->mask = user_data->mask; + at_response->cause_code = AT_ERROR_SUCCESS; ret_code = RETURNok; } } else { LOG_TRACE(ERROR, "USR-MAIN - Data to be processed is null"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } LOG_FUNC_RETURN (ret_code); @@ -389,10 +347,10 @@ int nas_user_process_data(const void *data) ** Others: None ** ** ** ***************************************************************************/ -const void *nas_user_get_data(void) +const void *nas_user_get_data(nas_user_t *user) { LOG_FUNC_IN; - LOG_FUNC_RETURN ((void *) &_nas_user_data); + LOG_FUNC_RETURN ((void *) user->at_response); } /****************************************************************************/ @@ -411,30 +369,29 @@ const void *nas_user_get_data(void) ** ning the IMEI. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_nvdata ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgsn(const at_command_t *data) +static int _nas_user_proc_cgsn(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgsn_resp_t *cgsn = &_nas_user_data.response.cgsn; + at_cgsn_resp_t *cgsn = &at_response->response.cgsn; memset(cgsn, 0, sizeof(at_cgsn_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGSN_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGSN_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: /* Get the Product Serial Number Identification (IMEI) */ - strncpy(cgsn->sn, _nas_user_nvdata.IMEI, + strncpy(cgsn->sn, user->nas_user_nvdata->IMEI, AT_RESPONSE_INFO_TEXT_SIZE); break; @@ -445,7 +402,7 @@ static int _nas_user_proc_cgsn(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGSN command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -463,30 +420,29 @@ static int _nas_user_proc_cgsn(const at_command_t *data) ** le Equipment to which it is connected to. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_nvdata ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgmi(const at_command_t *data) +static int _nas_user_proc_cgmi(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgmi_resp_t *cgmi = &_nas_user_data.response.cgmi; + at_cgmi_resp_t *cgmi = &at_response->response.cgmi; memset(cgmi, 0, sizeof(at_cgmi_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGMI_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGMI_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: /* Get the Manufacturer identifier */ - strncpy(cgmi->manufacturer, _nas_user_nvdata.manufacturer, + strncpy(cgmi->manufacturer, user->nas_user_nvdata->manufacturer, AT_RESPONSE_INFO_TEXT_SIZE); break; @@ -497,7 +453,7 @@ static int _nas_user_proc_cgmi(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGMI command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -515,30 +471,29 @@ static int _nas_user_proc_cgmi(const at_command_t *data) ** Equipment to which it is connected to. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_nvdata ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgmm(const at_command_t *data) +static int _nas_user_proc_cgmm(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgmm_resp_t *cgmm = &_nas_user_data.response.cgmm; + at_cgmm_resp_t *cgmm = &at_response->response.cgmm; memset(cgmm, 0, sizeof(at_cgmm_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGMM_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGMM_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: /* Get the Model identifier */ - strncpy(cgmm->model, _nas_user_nvdata.model, + strncpy(cgmm->model, user->nas_user_nvdata->model, AT_RESPONSE_INFO_TEXT_SIZE); break; @@ -549,7 +504,7 @@ static int _nas_user_proc_cgmm(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGMM command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -568,30 +523,30 @@ static int _nas_user_proc_cgmm(const at_command_t *data) ** Equipment to which it is connected to. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgmr(const at_command_t *data) +static int _nas_user_proc_cgmr(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgmr_resp_t *cgmr = &_nas_user_data.response.cgmr; + at_cgmr_resp_t *cgmr = &at_response->response.cgmr; memset(cgmr, 0, sizeof(at_cgmr_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGMR_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGMR_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: /* Get the revision identifier */ - strncpy(cgmr->revision, _nas_user_context.version, + strncpy(cgmr->revision, nas_user_context->version, AT_RESPONSE_INFO_TEXT_SIZE); break; @@ -602,7 +557,7 @@ static int _nas_user_proc_cgmr(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGMR command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -624,39 +579,39 @@ static int _nas_user_proc_cgmr(const at_command_t *data) ** ning the IMSI. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_nvdata ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cimi(const at_command_t *data) +static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cimi_resp_t *cimi = &_nas_user_data.response.cimi; + at_cimi_resp_t *cimi = &at_response->response.cimi; memset(cimi, 0, sizeof(at_cimi_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CIMI_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CIMI_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } /* Get the International Mobile Subscriber Identity (IMSI) */ - ret_code = nas_proc_get_imsi(cimi->IMSI); + ret_code = nas_proc_get_imsi(user->emm_data, cimi->IMSI); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get IMSI number"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -668,7 +623,7 @@ static int _nas_user_proc_cimi(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CIMI command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -685,27 +640,27 @@ static int _nas_user_proc_cimi(const at_command_t *data) ** to different power consumption states. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cfun(const at_command_t *data) +static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cfun_resp_t *cfun = &_nas_user_data.response.cfun; + at_cfun_resp_t *cfun = &at_response->response.cfun; memset(cfun, 0, sizeof(at_cfun_resp_t)); int fun = AT_CFUN_FUN_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CFUN_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CFUN_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: @@ -721,7 +676,7 @@ static int _nas_user_proc_cfun(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <rst> parameter is not valid" " (%d)", data->command.cfun.rst); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -734,7 +689,7 @@ static int _nas_user_proc_cfun(const at_command_t *data) * is not valid; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <fun> parameter is not valid" " (%d)", data->command.cfun.fun); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -751,7 +706,7 @@ static int _nas_user_proc_cfun(const at_command_t *data) case AT_CFUN_FULL: /* Notify the NAS procedure call manager that the UE is * operational */ - ret_code = nas_proc_enable_s1_mode(); + ret_code = nas_proc_enable_s1_mode(user); break; default: @@ -761,14 +716,14 @@ static int _nas_user_proc_cfun(const at_command_t *data) if (ret_code != RETURNerror) { /* Update the functionality level */ - _nas_user_context.fun = fun; + nas_user_context->fun = fun; } break; case AT_COMMAND_GET: /* Get the MT's functionality level */ - cfun->fun = _nas_user_context.fun; + cfun->fun = nas_user_context->fun; break; case AT_COMMAND_TST: @@ -780,7 +735,7 @@ static int _nas_user_proc_cfun(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CFUN command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -798,25 +753,25 @@ static int _nas_user_proc_cfun(const at_command_t *data) ** can be operated. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_context, _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cpin(const at_command_t *data) +static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cpin_resp_t *cpin = &_nas_user_data.response.cpin; + at_cpin_resp_t *cpin = &at_response->response.cpin; memset(cpin, 0, sizeof(at_cpin_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CPIN_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CPIN_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: @@ -825,24 +780,24 @@ static int _nas_user_proc_cpin(const at_command_t *data) * Set command sends to the MT a password which is necessary * before it can be operated */ - if (_nas_user_context.sim_status == NAS_USER_SIM_PIN) { + if (nas_user_context->sim_status == NAS_USER_SIM_PIN) { /* The MT is waiting for PIN password; check the PIN code */ - if (strncmp(_nas_user_nvdata.PIN, + if (strncmp(user->nas_user_nvdata->PIN, data->command.cpin.pin, USER_PIN_SIZE) != 0) { /* The PIN code is NOT matching; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - PIN code is not correct " "(%s)", data->command.cpin.pin); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PASSWD; + at_response->cause_code = AT_ERROR_INCORRECT_PASSWD; ret_code = RETURNerror; } else { /* The PIN code is matching; update the user's PIN * pending status */ - _nas_user_context.sim_status = NAS_USER_READY; + nas_user_context->sim_status = NAS_USER_READY; } } else { /* The MT is NOT waiting for PIN password; * return an error message */ - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_ALLOWED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_ALLOWED; ret_code = RETURNerror; } @@ -854,7 +809,7 @@ static int _nas_user_proc_cpin(const at_command_t *data) * whether some password is required or not. */ strncpy(cpin->code, - _nas_user_sim_status_str[_nas_user_context.sim_status], + _nas_user_sim_status_str[nas_user_context->sim_status], AT_CPIN_RESP_SIZE); break; @@ -866,7 +821,7 @@ static int _nas_user_proc_cpin(const at_command_t *data) /* Other types of AT CPIN command are not valid */ LOG_TRACE(ERROR, "USR-MAIN - AT+CPIN command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -884,30 +839,30 @@ static int _nas_user_proc_cpin(const at_command_t *data) ** Equipment. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_csq(const at_command_t *data) +static int _nas_user_proc_csq(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_csq_resp_t *csq = &_nas_user_data.response.csq; + at_csq_resp_t *csq = &at_response->response.csq; memset(csq, 0, sizeof(at_csq_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CSQ_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CSQ_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -928,7 +883,7 @@ static int _nas_user_proc_csq(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CSQ command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -945,30 +900,30 @@ static int _nas_user_proc_csq(const at_command_t *data) ** meters. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cesq(const at_command_t *data) +static int _nas_user_proc_cesq(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cesq_resp_t *cesq = &_nas_user_data.response.cesq; + at_cesq_resp_t *cesq = &at_response->response.cesq; memset(cesq, 0, sizeof(at_cesq_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CESQ_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CESQ_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -979,7 +934,7 @@ static int _nas_user_proc_cesq(const at_command_t *data) cesq->ber = AT_CESQ_BER_UNKNOWN; cesq->rscp = AT_CESQ_RSCP_UNKNOWN; cesq->ecno = AT_CESQ_ECNO_UNKNOWN; - ret_code = nas_proc_get_signal_quality(&cesq->rsrq, &cesq->rsrp); + ret_code = nas_proc_get_signal_quality(user, &cesq->rsrq, &cesq->rsrp); break; case AT_COMMAND_TST: @@ -991,7 +946,7 @@ static int _nas_user_proc_cesq(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CESQ command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1010,19 +965,19 @@ static int _nas_user_proc_cesq(const at_command_t *data) ** slot. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cops(const at_command_t *data) +static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cops_resp_t *cops = &_nas_user_data.response.cops; + at_cops_resp_t *cops = &at_response->response.cops; memset(cops, 0, sizeof(at_cops_resp_t)); static int read_format = AT_COPS_FORMAT_DEFAULT; @@ -1035,15 +990,15 @@ static int _nas_user_proc_cops(const at_command_t *data) int oper_is_selected; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1079,7 +1034,7 @@ static int _nas_user_proc_cops(const at_command_t *data) /* <oper> field shall be present */ if ( !(data->mask & AT_COPS_OPER_MASK) ) { LOG_TRACE(ERROR, "USR-MAIN - <oper> parameter is not present"); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1087,7 +1042,7 @@ static int _nas_user_proc_cops(const at_command_t *data) /* <format> field shall be present */ if ( !(data->mask & AT_COPS_FORMAT_MASK) ) { LOG_TRACE(ERROR, "USR-MAIN - <format> parameter is not present"); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1098,7 +1053,7 @@ static int _nas_user_proc_cops(const at_command_t *data) /* The value of <format> field is not valid */ LOG_TRACE(ERROR, "USR-MAIN - <format> parameter is not valid (%d)", data->command.cops.format); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1112,7 +1067,7 @@ static int _nas_user_proc_cops(const at_command_t *data) /* The value of <AcT> field is not valid */ LOG_TRACE(ERROR, "USR-MAIN - <AcT> parameter is not valid (%d)", data->command.cops.AcT); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1140,7 +1095,7 @@ static int _nas_user_proc_cops(const at_command_t *data) /* The value of <format> field is not valid */ LOG_TRACE(ERROR, "USR-MAIN - <format> parameter is not valid (%d)", data->command.cops.format); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1156,7 +1111,7 @@ static int _nas_user_proc_cops(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - <mode> parameter is not supported (%d)", mode); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1168,22 +1123,22 @@ static int _nas_user_proc_cops(const at_command_t *data) if (ret_code != RETURNerror) { if (mode == AT_COPS_DEREG) { /* Force an attempt to deregister from the network */ - ret_code = nas_proc_deregister(); + ret_code = nas_proc_deregister(user); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Network deregistration failed"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; break; } } else if (mode != AT_COPS_FORMAT) { /* Force an attempt to automatically/manualy select * and register the GSM/UMTS/EPS network operator */ - ret_code = nas_proc_register(mode, format, + ret_code = nas_proc_register(user, mode, format, &data->command.cops.plmn, AcT); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Network registration failed (<mode>=%d)", mode); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; break; } } @@ -1198,14 +1153,14 @@ static int _nas_user_proc_cops(const at_command_t *data) */ /* Get the current network registration data */ - ret_code = nas_proc_get_reg_data(&mode, + ret_code = nas_proc_get_reg_data(user, &mode, &oper_is_selected, read_format, &cops->get.plmn, &cops->get.AcT); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration data (<mode>=%d)", mode); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; break; } @@ -1221,11 +1176,11 @@ static int _nas_user_proc_cops(const at_command_t *data) /* Set optional parameter bitmask */ if (oper_is_selected) { cops->get.format = read_format; - _nas_user_data.mask |= (AT_COPS_RESP_FORMAT_MASK | + at_response->mask |= (AT_COPS_RESP_FORMAT_MASK | AT_COPS_RESP_OPER_MASK); if (cops->get.AcT != NET_ACCESS_UNAVAILABLE) { - _nas_user_data.mask |= AT_COPS_RESP_ACT_MASK; + at_response->mask |= AT_COPS_RESP_ACT_MASK; } } @@ -1236,13 +1191,13 @@ static int _nas_user_proc_cops(const at_command_t *data) * Test command returns a set of parameters, each representing * an operator present in the network. */ - cops->tst.size = nas_proc_get_oper_list(&cops->tst.data); + cops->tst.size = nas_proc_get_oper_list(user, &cops->tst.data); break; default: LOG_TRACE(ERROR, "USR-MAIN - AT+COPS command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1259,30 +1214,30 @@ static int _nas_user_proc_cops(const at_command_t *data) ** or detach the MT from, the EPS service. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgatt(const at_command_t *data) +static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgatt_resp_t *cgatt = &_nas_user_data.response.cgatt; + at_cgatt_resp_t *cgatt = &at_response->response.cgatt; memset(cgatt, 0, sizeof(at_cgatt_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGATT_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGATT_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1297,7 +1252,7 @@ static int _nas_user_proc_cgatt(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <state> parameter is not valid (%d)", data->command.cgatt.state); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1308,16 +1263,16 @@ static int _nas_user_proc_cgatt(const at_command_t *data) ret_code = RETURNerror; if (data->command.cgatt.state == AT_CGATT_ATTACHED) { - ret_code = nas_proc_attach(); + ret_code = nas_proc_attach(user); } else if (data->command.cgatt.state == AT_CGATT_DETACHED) { - ret_code = nas_proc_detach(FALSE); + ret_code = nas_proc_detach(user, FALSE); } if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to attach/detach " "to/from EPS service (<state>=%d)", data->command.cgatt.state); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } } @@ -1328,7 +1283,7 @@ static int _nas_user_proc_cgatt(const at_command_t *data) /* * Read command returns the current EPS service state. */ - if (nas_proc_get_attach_status() != TRUE) { + if (nas_proc_get_attach_status(user) != TRUE) { cgatt->state = AT_CGATT_DETACHED; } else { cgatt->state = AT_CGATT_ATTACHED; @@ -1346,7 +1301,7 @@ static int _nas_user_proc_cgatt(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGATT command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1364,32 +1319,32 @@ static int _nas_user_proc_cgatt(const at_command_t *data) ** location information in GERA/UTRA/E-UTRA Network. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_creg(const at_command_t *data) +static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_creg_resp_t *creg = &_nas_user_data.response.creg; + at_creg_resp_t *creg = &at_response->response.creg; memset(creg, 0, sizeof(at_creg_resp_t)); static int n = AT_CREG_N_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1406,7 +1361,7 @@ static int _nas_user_proc_creg(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <n> parameter is not valid" " (%d)", data->command.creg.n); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1432,7 +1387,7 @@ static int _nas_user_proc_creg(const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to disable logging of network notification"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1447,7 +1402,7 @@ static int _nas_user_proc_creg(const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to enable logging of registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1474,11 +1429,11 @@ static int _nas_user_proc_creg(const at_command_t *data) case AT_CREG_OFF: case AT_CREG_ON: /* Get network registration status */ - ret_code = nas_proc_get_reg_status(&creg->stat); + ret_code = nas_proc_get_reg_status(user, &creg->stat); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1495,7 +1450,7 @@ static int _nas_user_proc_creg(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CREG command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1513,32 +1468,32 @@ static int _nas_user_proc_creg(const at_command_t *data) ** information in GERA/UTRA Network. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgreg(const at_command_t *data) +static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgreg_resp_t *cgreg = &_nas_user_data.response.cgreg; + at_cgreg_resp_t *cgreg = &at_response->response.cgreg; memset(cgreg, 0, sizeof(at_cgreg_resp_t)); static int n = AT_CGREG_N_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1555,7 +1510,7 @@ static int _nas_user_proc_cgreg(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <n> parameter is not valid" " (%d)", data->command.cgreg.n); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1581,7 +1536,7 @@ static int _nas_user_proc_cgreg(const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to disable logging of network notification"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1596,7 +1551,7 @@ static int _nas_user_proc_cgreg(const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to enable logging of registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1623,11 +1578,11 @@ static int _nas_user_proc_cgreg(const at_command_t *data) case AT_CGREG_OFF: case AT_CGREG_ON: /* Get network registration status */ - ret_code = nas_proc_get_reg_status(&cgreg->stat); + ret_code = nas_proc_get_reg_status(user, &cgreg->stat); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1644,7 +1599,7 @@ static int _nas_user_proc_cgreg(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGREG command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1662,32 +1617,32 @@ static int _nas_user_proc_cgreg(const at_command_t *data) ** information in E-UTRA Network. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cereg(const at_command_t *data) +static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cereg_resp_t *cereg = &_nas_user_data.response.cereg; + at_cereg_resp_t *cereg = &at_response->response.cereg; memset(cereg, 0, sizeof(at_cereg_resp_t)); static int n = AT_CEREG_N_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1704,7 +1659,7 @@ static int _nas_user_proc_cereg(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <n> parameter is not valid" " (%d)", data->command.cereg.n); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1730,7 +1685,7 @@ static int _nas_user_proc_cereg(const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to disable logging of network notification"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1741,7 +1696,7 @@ static int _nas_user_proc_cereg(const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to enable logging of location information"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1753,7 +1708,7 @@ static int _nas_user_proc_cereg(const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to enable logging of registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1776,21 +1731,21 @@ static int _nas_user_proc_cereg(const at_command_t *data) switch (n) { case AT_CEREG_BOTH: /* Get EPS location information */ - ret_code = nas_proc_get_loc_info(cereg->tac, cereg->ci, + ret_code = nas_proc_get_loc_info(user, cereg->tac, cereg->ci, &cereg->AcT); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get location information"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; break; } if (cereg->tac[0] != 0) { - _nas_user_data.mask |= (AT_CEREG_RESP_TAC_MASK | + at_response->mask |= (AT_CEREG_RESP_TAC_MASK | AT_CEREG_RESP_CI_MASK); if (cereg->AcT != NET_ACCESS_UNAVAILABLE) { - _nas_user_data.mask |= (AT_CEREG_RESP_ACT_MASK); + at_response->mask |= (AT_CEREG_RESP_ACT_MASK); } } @@ -1799,11 +1754,11 @@ static int _nas_user_proc_cereg(const at_command_t *data) case AT_CEREG_OFF: case AT_CEREG_ON: /* Get network registration status */ - ret_code = nas_proc_get_reg_status(&cereg->stat); + ret_code = nas_proc_get_reg_status(user, &cereg->stat); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1820,7 +1775,7 @@ static int _nas_user_proc_cereg(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CEREG command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1843,19 +1798,19 @@ static int _nas_user_proc_cereg(const at_command_t *data) ** fault bearer and traffic flows in EPS. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgdcont(const at_command_t *data) +static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgdcont_get_t *cgdcont = &_nas_user_data.response.cgdcont.get; + at_cgdcont_get_t *cgdcont = &at_response->response.cgdcont.get; memset(cgdcont, 0, sizeof(at_cgdcont_resp_t)); int cid = AT_CGDCONT_CID_DEFAULT; @@ -1867,15 +1822,15 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) int im_cn_signalling = AT_CGDCONT_IM_CM_DEFAULT; int reset_pdn = TRUE; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1889,7 +1844,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <cid> parameter is not valid" " (%d)", data->command.cgdcont.cid); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1909,7 +1864,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <PDN_type> parameter is not " "valid (%s)", data->command.cgdcont.PDP_type); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1928,7 +1883,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) * not valid; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <d_comp> parameter is not " "valid (%d)", data->command.cgdcont.d_comp); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1943,7 +1898,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) * not valid; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <h_comp> parameter is not " "valid (%d)", data->command.cgdcont.h_comp); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1959,7 +1914,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) LOG_TRACE(ERROR, "USR-MAIN - <IPv4AddrAlloc> parameter " "is not valid (%d)", data->command.cgdcont.IPv4AddrAlloc); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1975,7 +1930,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) LOG_TRACE(ERROR, "USR-MAIN - <emergency indication> " "parameter is not valid (%d)", data->command.cgdcont.emergency_indication); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1991,7 +1946,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) LOG_TRACE(ERROR, "USR-MAIN - <P-CSCF_discovery> " "parameter is not valid (%d)", data->command.cgdcont.P_CSCF_discovery); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2008,7 +1963,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) LOG_TRACE(ERROR, "USR-MAIN - <IM_CN_Signalling_Flag_Ind> " "parameter is not valid (%d)", data->command.cgdcont.IM_CN_Signalling_Flag_Ind); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2022,10 +1977,10 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) if (reset_pdn) { /* A special form of the set command, +CGDCONT=<cid> causes * the values for context number <cid> to become undefined */ - ret_code = nas_proc_reset_pdn(cid); + ret_code = nas_proc_reset_pdn(user, cid); } else { /* Define a new PDN connection */ - ret_code = nas_proc_set_pdn(cid, pdn_type, apn, + ret_code = nas_proc_set_pdn(user, cid, pdn_type, apn, ipv4_addr_allocation, emergency, p_cscf, im_cn_signalling); } @@ -2033,7 +1988,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to setup PDN connection " "(<cid>=%d)", data->command.cgdcont.cid); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2043,14 +1998,14 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) * Read command returns the current settings for each * defined PDN connection/default EPS bearer context */ - cgdcont->n_pdns = nas_proc_get_pdn_param(cgdcont->cid, + cgdcont->n_pdns = nas_proc_get_pdn_param(user->esm_data, cgdcont->cid, cgdcont->PDP_type, cgdcont->APN, AT_CGDCONT_RESP_SIZE); if (cgdcont->n_pdns == 0) { LOG_TRACE(ERROR, "USR-MAIN - No any PDN context is defined"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2061,15 +2016,15 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) */ { /* Get the maximum value of a PDN context identifier */ - int cid_max = nas_proc_get_pdn_range(); + int cid_max = nas_proc_get_pdn_range(user->esm_data); if (cid_max > AT_CGDCONT_RESP_SIZE) { /* The range is defined by the user interface */ - _nas_user_data.response.cgdcont.tst.n_cid = + at_response->response.cgdcont.tst.n_cid = AT_CGDCONT_RESP_SIZE; } else { /* The range is defined by the ESM sublayer application */ - _nas_user_data.response.cgdcont.tst.n_cid = cid_max; + at_response->response.cgdcont.tst.n_cid = cid_max; } } break; @@ -2077,7 +2032,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGDCONT command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2095,33 +2050,33 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) ** for E-UTRAN ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgact(const at_command_t *data) +static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgact_resp_t *cgact = &_nas_user_data.response.cgact; + at_cgact_resp_t *cgact = &at_response->response.cgact; memset(cgact, 0, sizeof(at_cgact_resp_t)); int cid = -1; int state = AT_CGACT_STATE_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGACT_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGACT_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -2136,7 +2091,7 @@ static int _nas_user_proc_cgact(const at_command_t *data) * not valid; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <state> parameter is " "not valid (%d)", data->command.cgact.state); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2150,7 +2105,7 @@ static int _nas_user_proc_cgact(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <cid> parameter is " "not valid (%d)", data->command.cgact.cid); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2164,9 +2119,9 @@ static int _nas_user_proc_cgact(const at_command_t *data) ret_code = RETURNerror; if (state == AT_CGACT_DEACTIVATED) { - ret_code = nas_proc_deactivate_pdn(cid); + ret_code = nas_proc_deactivate_pdn(user, cid); } else if (state == AT_CGACT_ACTIVATED) { - ret_code = nas_proc_activate_pdn(cid); + ret_code = nas_proc_activate_pdn(user, cid); } if (ret_code != RETURNok) { @@ -2174,7 +2129,7 @@ static int _nas_user_proc_cgact(const at_command_t *data) "(<state>=%d,<cid>=%d)", (state != AT_CGACT_ACTIVATED)? "deactivate" : "activate", state, cid); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2184,12 +2139,12 @@ static int _nas_user_proc_cgact(const at_command_t *data) * The read command returns the current activation states for * all the defined PDN/EPS bearer contexts */ - cgact->n_pdns = nas_proc_get_pdn_status(cgact->cid, cgact->state, + cgact->n_pdns = nas_proc_get_pdn_status(user, cgact->cid, cgact->state, AT_CGACT_RESP_SIZE); if (cgact->n_pdns == 0) { LOG_TRACE(ERROR, "USR-MAIN - No any PDN context is defined"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2204,7 +2159,7 @@ static int _nas_user_proc_cgact(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGACT command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2226,23 +2181,23 @@ static int _nas_user_proc_cgact(const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cmee(const at_command_t *data) +static int _nas_user_proc_cmee(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; int ret_code = RETURNok; - at_cmee_resp_t *cmee = &_nas_user_data.response.cmee; + at_response_t *at_response = user->at_response; + at_cmee_resp_t *cmee = &at_response->response.cmee; memset(cmee, 0, sizeof(at_cmee_resp_t)); int n = AT_CMEE_N_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CMEE_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CMEE_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: /* ATV0, ATV1 response format commands */ @@ -2260,7 +2215,7 @@ static int _nas_user_proc_cmee(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <n> parameter is not valid" " (%d)", data->command.cmee.n); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2304,7 +2259,7 @@ static int _nas_user_proc_cmee(const at_command_t *data) if (cmee->n == RETURNerror) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get format of the final result code"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2318,7 +2273,7 @@ static int _nas_user_proc_cmee(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CMEE command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2339,21 +2294,21 @@ static int _nas_user_proc_cmee(const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_clck(const at_command_t *data) +static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_clck_resp_t *clck = &_nas_user_data.response.clck; + at_clck_resp_t *clck = &at_response->response.clck; memset(clck, 0, sizeof(at_clck_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CLCK_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CLCK_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: @@ -2369,7 +2324,7 @@ static int _nas_user_proc_clck(const at_command_t *data) /* Facilities other than SIM is not supported */ LOG_TRACE(ERROR, "USR-MAIN - Facility is not supported (%s)", data->command.clck.fac); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2377,12 +2332,12 @@ static int _nas_user_proc_clck(const at_command_t *data) /* Check password parameter */ if (data->mask & AT_CLCK_PASSWD_MASK) { /* Check the PIN code */ - if (strncmp(_nas_user_nvdata.PIN, + if (strncmp(user->nas_user_nvdata->PIN, data->command.clck.passwd, USER_PIN_SIZE) != 0) { /* The PIN code is NOT matching; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - Password is not correct " "(%s)", data->command.clck.passwd); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PASSWD; + at_response->cause_code = AT_ERROR_INCORRECT_PASSWD; ret_code = RETURNerror; break; } @@ -2397,14 +2352,14 @@ static int _nas_user_proc_clck(const at_command_t *data) /* unlock requires password */ LOG_TRACE(ERROR, "USR-MAIN - unlock mode of operation " "requires a password"); - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; ret_code = RETURNerror; break; } LOG_TRACE(ERROR, "USR-MAIN - unlock mode of operation " "is not supported"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; @@ -2415,14 +2370,14 @@ static int _nas_user_proc_clck(const at_command_t *data) /* unlock requires password */ LOG_TRACE(ERROR, "USR-MAIN - lock mode of operation " "requires a password"); - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; ret_code = RETURNerror; break; } LOG_TRACE(ERROR, "USR-MAIN - lock mode of operation " "is not supported"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; @@ -2434,7 +2389,7 @@ static int _nas_user_proc_clck(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - <mode> parameter is not valid" " (%d)", data->command.clck.mode); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2450,7 +2405,7 @@ static int _nas_user_proc_clck(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CLCK command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2467,32 +2422,32 @@ static int _nas_user_proc_clck(const at_command_t *data) ** for the specified context identifiers ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgpaddr(const at_command_t *data) +static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgpaddr_resp_t *cgpaddr = &_nas_user_data.response.cgpaddr; + at_cgpaddr_resp_t *cgpaddr = &at_response->response.cgpaddr; memset(cgpaddr, 0, sizeof(at_cgpaddr_resp_t)); int cid = -1; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGPADDR_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGPADDR_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -2506,7 +2461,7 @@ static int _nas_user_proc_cgpaddr(const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - <cid> parameter is " "not valid (%d)", data->command.cgpaddr.cid); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2517,14 +2472,14 @@ static int _nas_user_proc_cgpaddr(const at_command_t *data) /* * Get the PDP addresses */ - cgpaddr->n_pdns = nas_proc_get_pdn_addr(cid, cgpaddr->cid, + cgpaddr->n_pdns = nas_proc_get_pdn_addr(user, cid, cgpaddr->cid, cgpaddr->PDP_addr_1, cgpaddr->PDP_addr_2, AT_CGPADDR_RESP_SIZE); if (cgpaddr->n_pdns == 0) { LOG_TRACE(ERROR, "USR-MAIN - No any PDN context is defined"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2533,7 +2488,7 @@ static int _nas_user_proc_cgpaddr(const at_command_t *data) /* * The test command returns a list of defined <cid>s. */ - cgpaddr->n_pdns = nas_proc_get_pdn_addr(cid, cgpaddr->cid, + cgpaddr->n_pdns = nas_proc_get_pdn_addr(user, cid, cgpaddr->cid, cgpaddr->PDP_addr_1, cgpaddr->PDP_addr_2, AT_CGPADDR_RESP_SIZE); @@ -2542,7 +2497,7 @@ static int _nas_user_proc_cgpaddr(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGPADDR command type %d is " "not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2559,39 +2514,39 @@ static int _nas_user_proc_cgpaddr(const at_command_t *data) ** subscriber. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cnum(const at_command_t *data) +static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cnum_resp_t *cnum = &_nas_user_data.response.cnum; + at_cnum_resp_t *cnum = &at_response->response.cnum; memset(cnum, 0, sizeof(at_cnum_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CNUM_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CNUM_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: - if (_nas_user_context.sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + if (nas_user_context->sim_status != NAS_USER_READY) { + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } /* Get the International Mobile Subscriber Identity (IMSI) */ - ret_code = nas_proc_get_msisdn(cnum->number, &cnum->type); + ret_code = nas_proc_get_msisdn(user, cnum->number, &cnum->type); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get MS dialing number"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2603,7 +2558,7 @@ static int _nas_user_proc_cnum(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CNUM command type %d is " "not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2620,25 +2575,23 @@ static int _nas_user_proc_cnum(const at_command_t *data) ** are available for the user. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_clac(const at_command_t *data) +static int _nas_user_proc_clac(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; - + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_clac_resp_t *clac = &_nas_user_data.response.clac; + at_clac_resp_t *clac = &at_response->response.clac; memset(clac, 0, sizeof(at_clac_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CLAC_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CLAC_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: @@ -2648,7 +2601,7 @@ static int _nas_user_proc_clac(const at_command_t *data) if (clac->n_acs == 0) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get the list of " "supported AT commands"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2660,7 +2613,7 @@ static int _nas_user_proc_clac(const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CLAC command type %d is " "not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } diff --git a/openair3/NAS/UE/nas_user.h b/openair3/NAS/UE/nas_user.h index 93b1cc8961bb574581f13fc3289d541478a95cbb..eb7f94a671a0569b988d149fb2ff01fa6fa98235 100644 --- a/openair3/NAS/UE/nas_user.h +++ b/openair3/NAS/UE/nas_user.h @@ -40,6 +40,9 @@ Description NAS procedure functions triggered by the user #include "commonDef.h" #include "networkDef.h" +#include "emm_main.h" +#include "esm_ebr.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -57,13 +60,13 @@ Description NAS procedure functions triggered by the user /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void nas_user_initialize(emm_indication_callback_t emm_cb, +void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *version); -int nas_user_receive_and_process(int * fd, char *message); +int nas_user_receive_and_process(nas_user_t *user, char *message); -int nas_user_process_data(const void *data); +int nas_user_process_data(nas_user_t *user, const void *data); -const void *nas_user_get_data(void); +const void *nas_user_get_data(nas_user_t *nas_user); #endif /* __NAS_USER_H__*/ diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..c27cf1320ee1708e0f9d9e03760f6030e2e18728 --- /dev/null +++ b/openair3/NAS/UE/user_defs.h @@ -0,0 +1,84 @@ +/* + * 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 user_defs.h + +Version 0.1 + +Date 2016/07/01 + +Product NAS stack + +Subsystem NAS main process + +Author Frederic Leroy + +Description NAS type definition to manage a user equipment + +*****************************************************************************/ +#ifndef __USER_DEFS_H__ +#define __USER_DEFS_H__ + +#include "nas_proc_defs.h" +#include "esmData.h" +#include "esm_pt_defs.h" +#include "EMM/emm_fsm_defs.h" +#include "EMM/emmData.h" +#include "EMM/Authentication.h" +#include "EMM/IdleMode_defs.h" +#include "EMM/LowerLayer_defs.h" +#include "API/USIM/usim_api.h" +#include "API/USER/user_api_defs.h" +#include "SecurityModeControl.h" +#include "userDef.h" +#include "at_response.h" + +typedef struct { + int ueid; /* UE lower layer identifier */ + proc_data_t proc; + // Eps Session Management + esm_data_t *esm_data; // ESM internal data (used within ESM only) + esm_pt_data_t *esm_pt_data; + esm_ebr_data_t *esm_ebr_data; // EPS bearer contexts + default_eps_bearer_context_data_t *default_eps_bearer_context_data; + // Eps Mobility Management + emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status + emm_data_t *emm_data; // EPS mobility management data + const char *emm_nvdata_store; + emm_plmn_list_t *emm_plmn_list; // list of PLMN identities + authentication_data_t *authentication_data; + security_data_t *security_data; //Internal data used for security mode control procedure + // Hardware persistent storage + usim_data_t usim_data; // USIM application data + const char *usim_data_store; // USIM application data filename + user_nvdata_t *nas_user_nvdata; //UE parameters stored in the UE's non-volatile memory device + const char *user_nvdata_store; //UE parameters stored in the UE's non-volatile memory device + // + nas_user_context_t *nas_user_context; + at_response_t *at_response; // data structure returned to the user as the result of NAS procedure function call + // + user_at_commands_t *user_at_commands; //decoded data received from the user application layer + user_api_id_t *user_api_id; + lowerlayer_data_t *lowerlayer_data; +} nas_user_t; + +#endif diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 9a1a14baebf4669d00937ba795a77c10695ac3dd..c28b9e839c4377755498fc5a1a87e5cef27b78b2 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -85,7 +85,10 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) # if defined(NAS_BUILT_IN_UE) if (ue_nb > 0) { - if (itti_create_task (TASK_NAS_UE, nas_ue_task, NULL) < 0) { + nas_user_container_t *users = calloc(1, sizeof(*users)); + if (users == NULL) abort(); + users->count = ue_nb; + if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) { LOG_E(NAS, "Create task for NAS UE failed\n"); return -1; } diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h new file mode 100644 index 0000000000000000000000000000000000000000..d9590873e82f47ed935c49eb1deb5f8a409f8e74 --- /dev/null +++ b/targets/COMMON/openairinterface5g_limits.h @@ -0,0 +1,25 @@ +#ifndef OPENAIRINTERFACE5G_LIMITS_H_ +#define OPENAIRINTERFACE5G_LIMITS_H_ + +#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) + #define NUMBER_OF_eNB_MAX 1 + #define NUMBER_OF_UE_MAX 16 + #define NUMBER_OF_CONNECTED_eNB_MAX 3 +#else + #define NUMBER_OF_eNB_MAX 7 + #define NUMBER_OF_UE_MAX 20 + #define NUMBER_OF_CONNECTED_eNB_MAX 3 + + #if STANDALONE==1 + #define NUMBER_OF_eNB_MAX 3 + #define NUMBER_OF_UE_MAX 3 + #endif + + #if LARGE_SCALE + #define NUMBER_OF_eNB_MAX 2 + #define NUMBER_OF_UE_MAX 120 + #define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory + #endif +#endif + +#endif diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/start_enb_and_ue_virt.bash b/targets/PROJECTS/GENERIC-LTE-EPC/start_enb_and_ue_virt.bash index 5339af13e490f9f94aff25a537ff68ee1a92ff5f..6ea2d5bb0afe0efc6d64bc08b06b5e1c503b45bc 100755 --- a/targets/PROJECTS/GENERIC-LTE-EPC/start_enb_and_ue_virt.bash +++ b/targets/PROJECTS/GENERIC-LTE-EPC/start_enb_and_ue_virt.bash @@ -125,18 +125,18 @@ if [ ! -f $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data ] || [ ! -f $OPENAIR3_DIR/NA fi echo_success "make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS -f Makefile PROCESS=UE all" make -f Makefile --debug=b --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS PROCESS=UE all - rm .ue.nvram - rm .usim.nvram + rm .ue.nvram0 + rm .usim.nvram0 touch /tmp/nas_cleaned fi -if [ ! -f .ue.nvram ]; then - echo_success "generate .ue_emm.nvram .ue.nvram" +if [ ! -f .ue.nvram0 ]; then + echo_success "generate .ue_emm.nvram0 .ue.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --gen fi -if [ ! -f .usim.nvram ]; then - echo_success "generate .usim.nvram" +if [ ! -f .usim.nvram0 ]; then + echo_success "generate .usim.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data --gen fi $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --print diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/start_ue.bash b/targets/PROJECTS/GENERIC-LTE-EPC/start_ue.bash index e6d96602e270b5fb3d46ceddcd0291c1916df82c..ff16e27982a0e42954149bab6d3dbbf938bbf1f2 100755 --- a/targets/PROJECTS/GENERIC-LTE-EPC/start_ue.bash +++ b/targets/PROJECTS/GENERIC-LTE-EPC/start_ue.bash @@ -68,20 +68,20 @@ export NVRAM_DIR=$THIS_SCRIPT_PATH if [ ! -f $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data ]; then make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS veryveryclean make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS PROCESS=UE - rm .ue.nvram + rm .ue.nvram0 fi if [ ! -f $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data ]; then make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS veryveryclean make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS PROCESS=UE - rm .usim.nvram + rm .usim.nvram0 fi -if [ ! -f .ue.nvram ]; then - # generate .ue_emm.nvram .ue.nvram +if [ ! -f .ue.nvram0 ]; then + # generate .ue_emm.nvram0 .ue.nvram0 $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --gen fi -if [ ! -f .usim.nvram ]; then - # generate .usim.nvram +if [ ! -f .usim.nvram0 ]; then + # generate .usim.nvram0 $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data --gen fi $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --print diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index b37d5bc1c4cb11ee5e034114a09983e23b34c285..68b8050735e842e92165287656d675b6aea126ae 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -289,6 +289,11 @@ char uecap_xer[1024],uecap_xer_in=0; int oaisim_flag=0; +/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed + * this is very hackish - find a proper solution + */ +uint8_t abstraction_flag=0; + /*---------------------BMC: timespec helpers -----------------------------*/ struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 5c821a4176c2f98277566dd4b4cdf2d993b4377b..3745c61a9e95ae137eac2cd75d7502064ca40eb0 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -190,26 +190,28 @@ void init_UE(int nb_inst) { } UE->rfdevice.host_type = BBU_HOST; // UE->rfdevice.type = NONE_DEV; - error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, NULL); + error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, UE); if (error_code!= 0) { LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); return; } else { + char name[128]; + sprintf(name, "main UE %d", inst); LOG_D(HW, "[lte-softmodem.c] Allocate UE_thread successful\n" ); - pthread_setname_np( UE->proc.pthread_ue, "main UE" ); + pthread_setname_np(UE->proc.pthread_ue, name); } } printf("UE threads created\n"); -#ifdef USE_MME - +#if 0 +#if defined(ENABLE_USE_MME) + extern volatile int start_UE; while (start_UE == 0) { sleep(1); } - #endif - +#endif } /*! @@ -611,6 +613,14 @@ static void *UE_thread_synch(void *arg) } +/* this structure is used to pass both UE phy vars and + * proc to the function UE_thread_rxn_txnp4 + */ +struct rx_tx_thread_data { + PHY_VARS_UE *UE; + UE_rxtx_proc_t *proc; +}; + /*! * \brief This is the UE thread for RX subframe n and TX subframe n+4. @@ -623,9 +633,10 @@ static void *UE_thread_synch(void *arg) static void *UE_thread_rxn_txnp4(void *arg) { static int UE_thread_rxtx_retval; - UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; + struct rx_tx_thread_data *rtd = arg; + UE_rxtx_proc_t *proc = rtd->proc; + PHY_VARS_UE *UE = rtd->UE; int ret; - PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; proc->instance_cnt_rxtx=-1; @@ -861,6 +872,7 @@ static void *UE_thread_rxn_txnp4(void *arg) } // thread finished + free(arg); return &UE_thread_rxtx_retval; } @@ -885,7 +897,7 @@ static void *UE_thread_rxn_txnp4(void *arg) void *UE_thread(void *arg) { static int UE_thread_retval; - PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; + PHY_VARS_UE *UE = arg; //PHY_vars_UE_g[0][0]; // int tx_enabled = 0; uint32_t rxs=0,txs=0; int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); @@ -948,7 +960,7 @@ void *UE_thread(void *arg) { #ifdef NAS_UE message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); + itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); #endif while (!oai_exit) { @@ -1693,8 +1705,10 @@ void *UE_thread_old(void *arg) */ void init_UE_threads(int inst) { + struct rx_tx_thread_data *rtd; + char name[128]; PHY_VARS_UE *UE; - + UE = PHY_vars_UE_g[inst][0]; pthread_attr_init (&UE->proc.attr_ue); @@ -1717,12 +1731,23 @@ void init_UE_threads(int inst) pthread_cond_init(&UE->proc.proc_rxtx[0].cond_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[1].cond_rxtx,NULL); pthread_cond_init(&UE->proc.cond_synch,NULL); - pthread_create(&UE->proc.proc_rxtx[0].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[0]); - pthread_setname_np( UE->proc.proc_rxtx[0].pthread_rxtx, "rxn_txnp4_even" ); - pthread_create(&UE->proc.proc_rxtx[1].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[1]); - pthread_setname_np( UE->proc.proc_rxtx[1].pthread_rxtx, "rxn_txnp4_odd" ); + rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = PHY_vars_UE_g[inst][UE->proc.proc_rxtx[0].CC_id]; + rtd->proc = &UE->proc.proc_rxtx[0]; + pthread_create(&UE->proc.proc_rxtx[0].pthread_rxtx,NULL,UE_thread_rxn_txnp4,rtd);//(void*)&UE->proc.proc_rxtx[0]); + sprintf(name, "rxn_txnp4_even UE %d", inst); + pthread_setname_np(UE->proc.proc_rxtx[0].pthread_rxtx, name); + rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = PHY_vars_UE_g[inst][UE->proc.proc_rxtx[1].CC_id]; + rtd->proc = &UE->proc.proc_rxtx[1]; + pthread_create(&UE->proc.proc_rxtx[1].pthread_rxtx,NULL,UE_thread_rxn_txnp4,rtd);//(void*)&UE->proc.proc_rxtx[1]); + sprintf(name, "rxn_txnp4_odd UE %d", inst); + pthread_setname_np(UE->proc.proc_rxtx[1].pthread_rxtx, name); pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); - pthread_setname_np( UE->proc.pthread_synch, "UE_thread_synch" ); + sprintf(name, "UE_thread_synch UE %d", inst); + pthread_setname_np(UE->proc.pthread_synch, name); } diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index 370e50d145257253df3662f8e2dc80f0177a2799..aff1f789eeefe8486457c3b44a2344fdc1320e3e 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -327,8 +327,8 @@ void do_DL_sig(channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_N eNB_output_mask[UE_id]=0; - double *r_re_p[2] = {r_re_DL[eNB_id][0],r_re_DL[eNB_id][1]}; - double *r_im_p[2] = {r_im_DL[eNB_id][0],r_im_DL[eNB_id][1]}; + double *r_re_p[2] = {r_re_DL[UE_id][0],r_re_DL[UE_id][1]}; + double *r_im_p[2] = {r_im_DL[UE_id][0],r_im_DL[UE_id][1]}; #ifdef DEBUG_SIM rx_pwr = signal_energy_fp(r_re_p,r_im_p,nb_antennas_rx,frame_parms->ofdm_symbol_size,sf_offset)/(12.0*frame_parms->N_RB_DL); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 71bfce44cb1a1ce2ef54927491d10c07ac8e6ed1..02ccefed26989acb363e02440c9ab0e88c54c8f9 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -457,7 +457,8 @@ l2l1_task_state_t l2l1_state = L2L1_WAITTING; extern openair0_timestamp current_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs]; extern openair0_timestamp current_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs]; - +extern openair0_timestamp last_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs]; +extern openair0_timestamp last_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs]; /*------------------------------------------------------------------------------*/ void * @@ -590,6 +591,7 @@ l2l1_task (void *args_p) switch (ITTI_MSG_ID(message_p)) { case INITIALIZE_MESSAGE: l2l1_state = L2L1_RUNNING; + start_eNB = 1; break; case ACTIVATE_MESSAGE: @@ -733,57 +735,43 @@ l2l1_task (void *args_p) clear_eNB_transport_info (oai_emulation.info.nb_enb_local); - CC_id=0; int all_done=0; while (all_done==0) { - pthread_mutex_lock(&subframe_mutex); - int subframe_eNB_mask_local = subframe_eNB_mask; - int subframe_UE_mask_local = subframe_UE_mask; - pthread_mutex_unlock(&subframe_mutex); - LOG_D(EMU,"Frame %d, Subframe %d: Checking masks %x,%x\n",frame,sf,subframe_eNB_mask,subframe_UE_mask); - if ((subframe_eNB_mask_local == ((1<<NB_eNB_INST)-1)) && - (subframe_UE_mask_local == ((1<<NB_UE_INST)-1))) - all_done=1; - else - usleep(1500); + int i; + all_done = 1; + for (i = oai_emulation.info.first_enb_local; + i < oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local; + i++) + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) + if (last_eNB_rx_timestamp[i][CC_id] != current_eNB_rx_timestamp[i][CC_id]) { + all_done = 0; + break; + } + if (all_done == 1) + for (i = 0; i < NB_UE_INST; i++) + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) + if (last_UE_rx_timestamp[i][CC_id] != current_UE_rx_timestamp[i][CC_id]) { + all_done = 0; + break; + } + if (all_done == 0) + usleep(500); } - //clear subframe masks for next round - pthread_mutex_lock(&subframe_mutex); - subframe_eNB_mask=0; - subframe_UE_mask=0; - pthread_mutex_unlock(&subframe_mutex); - // increment timestamps for (eNB_inst = oai_emulation.info.first_enb_local; (eNB_inst < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local)); eNB_inst++) { - - current_eNB_rx_timestamp[eNB_inst][CC_id] += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) + current_eNB_rx_timestamp[eNB_inst][CC_id] += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti; } for (UE_inst = 0; UE_inst<NB_UE_INST;UE_inst++) { - current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) + current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti; } - - if (oai_emulation.info.cli_start_enb[eNB_inst] != 0) { - T(T_ENB_MASTER_TICK, T_INT(eNB_inst), T_INT(frame % 1024), T_INT(slot/2)); - /* - LOG_D(EMU, - "PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d) TDD %d/%d Nid_cell %d\n", - eNB_inst, - frame%MAX_FRAME_NUMBER, - 2*sf, - PHY_vars_eNB_g[eNB_inst][0]->proc[slot >> 1].subframe_tx, - PHY_vars_eNB_g[eNB_inst][0]->proc[slot >> 1].subframe_rx, - PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.frame_type, - PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.tdd_config, - PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.Nid_cell); - */ - } - for (eNB_inst = oai_emulation.info.first_enb_local; (eNB_inst < (oai_emulation.info.first_enb_local @@ -791,7 +779,6 @@ l2l1_task (void *args_p) eNB_inst++) { if (oai_emulation.info.cli_start_enb[eNB_inst] != 0) { - T(T_ENB_MASTER_TICK, T_INT(eNB_inst), T_INT(frame % 1024), T_INT(sf)); /* LOG_D(EMU, "PHY procedures eNB %d for frame %d, subframe %d TDD %d/%d Nid_cell %d\n", @@ -1223,6 +1210,12 @@ main (int argc, char **argv) //Default values if not changed by the user in get_simulation_options(); pdcp_period = 1; omg_period = 1; + //Clean ip rule table + for(int i =0; i<NUMBER_OF_UE_MAX; i++){ + char command_line[100]; + sprintf(command_line, "while ip rule del table %d; do true; done",i+201); + system(command_line); + } // start thread for log gen log_thread_init (); @@ -1350,9 +1343,9 @@ main (int argc, char **argv) #if defined(ENABLE_ITTI) + // Handle signals until all tasks are terminated itti_wait_tasks_end(); - #else if (oai_emulation.info.nb_enb_local > 0) { diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index e500c15a3c1d9035ed43e8fcceadafab47320052..c47dc10caf11d95cfa71addff2b4de91f6ad2500 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1036,13 +1036,15 @@ int UE_trx_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { extern pthread_mutex_t subframe_mutex; extern int subframe_eNB_mask,subframe_UE_mask; -int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - +int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) +{ + int ret = nsamps; int eNB_id = device->Mod_id; int CC_id = device->CC_id; int subframe; - int sample_count=0; + int read_samples, max_samples; + openair0_timestamp last = last_eNB_rx_timestamp[eNB_id][CC_id]; *ptimestamp = last_eNB_rx_timestamp[eNB_id][CC_id]; @@ -1052,49 +1054,55 @@ int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void * (*ptimestamp/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10); // if we're at a subframe boundary generate UL signals for this eNB - while (sample_count<nsamps) { - while (current_eNB_rx_timestamp[eNB_id][CC_id]< - (nsamps+last_eNB_rx_timestamp[eNB_id][CC_id])) { - // LOG_D(EMU,"eNB: current TS %llu, last TS %llu, sleeping\n",current_eNB_rx_timestamp[eNB_id][CC_id],last_eNB_rx_timestamp[eNB_id][CC_id]); + while (nsamps) { + while (current_eNB_rx_timestamp[eNB_id][CC_id] == last) { + LOG_D(EMU,"eNB: current TS %llu, last TS %llu, sleeping\n",current_eNB_rx_timestamp[eNB_id][CC_id],last_eNB_rx_timestamp[eNB_id][CC_id]); usleep(500); } - // tell top-level we are busy - pthread_mutex_lock(&subframe_mutex); - subframe_eNB_mask|=(1<<eNB_id); - pthread_mutex_unlock(&subframe_mutex); - - subframe = (last_eNB_rx_timestamp[eNB_id][CC_id]/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10; - LOG_D(EMU,"eNB_trx_read generating UL subframe %d (Ts %llu, current TS %llu)\n", - subframe,(unsigned long long)*ptimestamp, - (unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id]); - - do_UL_sig(UE2eNB, - enb_data, - ue_data, - subframe, - 0, // abstraction_flag - &PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms, - 0, // frame is only used for abstraction - eNB_id, - CC_id); - - last_eNB_rx_timestamp[eNB_id][CC_id] += PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti; - sample_count += PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti; - } + read_samples = nsamps; + max_samples = current_eNB_rx_timestamp[eNB_id][CC_id]-last; + if (read_samples > max_samples) + read_samples = max_samples; + last += read_samples; + nsamps -= read_samples; + if (current_eNB_rx_timestamp[eNB_id][CC_id] == last) { + subframe = (last/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10; + //subframe = (subframe+9) % 10; - return(nsamps); -} + LOG_D(PHY,"eNB_trx_read generating UL subframe %d (Ts %llu, current TS %llu)\n", + subframe,(unsigned long long)*ptimestamp, + (unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id]); + + do_UL_sig(UE2eNB, + enb_data, + ue_data, + subframe, + 0, // abstraction_flag + &PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms, + 0, // frame is only used for abstraction + eNB_id, + CC_id); + + last_eNB_rx_timestamp[eNB_id][CC_id] = last; + } + } + + last_eNB_rx_timestamp[eNB_id][CC_id] = last; -int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { + return ret; +} +int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) +{ + int ret = nsamps; int UE_id = device->Mod_id; int CC_id = device->CC_id; int subframe; - int sample_count=0; - int read_size; + int read_samples, max_samples; + openair0_timestamp last = last_UE_rx_timestamp[UE_id][CC_id]; *ptimestamp = last_UE_rx_timestamp[UE_id][CC_id]; @@ -1103,55 +1111,59 @@ int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** (unsigned long long)last_UE_rx_timestamp[UE_id][CC_id], cc); - if (nsamps < PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti) - read_size = nsamps; - else - read_size = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti; - - while (sample_count<nsamps) { - while (current_UE_rx_timestamp[UE_id][CC_id] < - (last_UE_rx_timestamp[UE_id][CC_id]+read_size)) { - //LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); + while (nsamps) { + /* wait for all processing to be finished */ + while (1) { + PHY_VARS_UE *UE = PHY_vars_UE_g[UE_id][0]; + int ready = 1; + int i; + for (i = 0; i < 2; i++) + if (UE->proc.proc_rxtx[i].instance_cnt_rxtx >= 0) ready = 0; + if (UE->proc.instance_cnt_synch >= 0) ready = 0; + if (ready) break; + usleep(500); + } + while (current_UE_rx_timestamp[UE_id][CC_id] == last) { + LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); usleep(500); } // LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); - // tell top-level we are busy - pthread_mutex_lock(&subframe_mutex); - subframe_UE_mask|=(1<<UE_id); - pthread_mutex_unlock(&subframe_mutex); - - - // otherwise we have one subframe here so generate the received signal - subframe = (last_UE_rx_timestamp[UE_id][CC_id]/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10; - if ((last_UE_rx_timestamp[UE_id][CC_id]%PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti) > 0) - subframe++; - - last_UE_rx_timestamp[UE_id][CC_id] += read_size; - sample_count += read_size; - - if (subframe > 9) - return(nsamps); - - LOG_D(PHY,"UE_trx_read generating DL subframe %d (Ts %llu, current TS %llu)\n", - subframe,(unsigned long long)*ptimestamp, - (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id]); - do_DL_sig(eNB2UE, - enb_data, - ue_data, - subframe, - 0, //abstraction_flag, - &PHY_vars_UE_g[UE_id][CC_id]->frame_parms, - UE_id, - CC_id); - - + read_samples = nsamps; + max_samples = current_UE_rx_timestamp[UE_id][CC_id]-last; + if (read_samples > max_samples) + read_samples = max_samples; + + last += read_samples; + nsamps -= read_samples; + + if (current_UE_rx_timestamp[UE_id][CC_id] == last) { + // we have one subframe here so generate the received signal + subframe = (last/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10; + //subframe = (subframe+9) % 10; + + LOG_D(PHY,"UE_trx_read generating DL subframe %d (Ts %llu, current TS %llu)\n", + subframe,(unsigned long long)*ptimestamp, + (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id]); + + do_DL_sig(eNB2UE, + enb_data, + ue_data, + subframe, + 0, //abstraction_flag, + &PHY_vars_UE_g[UE_id][CC_id]->frame_parms, + UE_id, + CC_id); + + last_UE_rx_timestamp[UE_id][CC_id] = last; + } } + last_UE_rx_timestamp[UE_id][CC_id] = last; - return(nsamps); + return ret; } int eNB_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { diff --git a/targets/build_helper.bash b/targets/build_helper.bash index 163be3ba53504b764e21aebcccab1f76e5923246..f161275c65d09c1d9a7a5585ceed4326ead50460 100755 --- a/targets/build_helper.bash +++ b/targets/build_helper.bash @@ -852,8 +852,8 @@ compile_nas_tools() { fi echo_success "make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS/tools all" make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS/tools all - rm .ue.nvram - rm .usim.nvram + rm .ue.nvram0 + rm .usim.nvram0 touch /tmp/nas_cleaned } @@ -1027,13 +1027,13 @@ install_oaisim() { install_nas_tools() { cd $OPENAIR_TARGETS/bin - if [ ! -f .ue.nvram ]; then - echo_success "generate .ue_emm.nvram .ue.nvram" + if [ ! -f .ue.nvram0 ]; then + echo_success "generate .ue_emm.nvram0 .ue.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --gen fi - if [ ! -f .usim.nvram ]; then - echo_success "generate .usim.nvram" + if [ ! -f .usim.nvram0 ]; then + echo_success "generate .usim.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data --gen fi $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --print diff --git a/targets/build_oai.bash b/targets/build_oai.bash index 1303ef9e7e9cba90e231bb3e9203982fe3f2ded7..7a6a179bebc431acb4158b218cee4bcbd8d724ec 100755 --- a/targets/build_oai.bash +++ b/targets/build_oai.bash @@ -756,13 +756,13 @@ if [ $RUN -ne 0 ]; then install_nasmesh else # prepare NAS for UE - if [ ! -f .ue.nvram ]; then - echo_success "generate .ue_emm.nvram .ue.nvram" + if [ ! -f .ue.nvram0 ]; then + echo_success "generate .ue_emm.nvram0 .ue.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --gen fi - if [ ! -f .usim.nvram ]; then - echo_success "generate .usim.nvram" + if [ ! -f .usim.nvram0 ]; then + echo_success "generate .usim.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data --gen fi $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --print