Compare commits

...

22 Commits

Author SHA1 Message Date
Vadim Yanitskiy aaaafe1e53 WIP WIP WIP 2020-11-09 19:00:36 +07:00
Vadim Yanitskiy 836b0ee426 srsue/extnas: implement encryption and signing of NAS messages 2020-11-09 19:00:36 +07:00
Vadim Yanitskiy c8eed1576d srsue/extnas: move EEA/EIA API from 'nas' to 'nas_base'
This way 'nas_ext' would also be able to use it.
2020-11-09 19:00:36 +07:00
Vadim Yanitskiy ea60a4909b srsue/extnas: handle (U)SIM GenAuthResp.Request 2020-11-09 19:00:36 +07:00
Vadim Yanitskiy a3c50af18d srsue/rrctl: make codec::enc_hdr() return proto::msg_hdr 2020-11-09 19:00:30 +07:00
Vadim Yanitskiy 9d9f37fb63 srsue/rrctl: add Security Mode messages for EEA/EIA 2020-11-07 20:59:20 +07:00
Vadim Yanitskiy 96a5acb7a6 srsue/rrctl: add (U)SIM specific protocol extensions 2020-11-07 17:49:19 +07:00
Vadim Yanitskiy 79fe532f7f srsue/rrctl: reserve a range for RRCTL protocol extensions
The idea is to group protocol extensions and have one message
type (with 4 variations: Req/Ind/Cnf/Err) per group.  Similar
to the stack and heap allocation model in Linux, new entries
shall be added to the 'RRCTL_MsgType' list as follows:

  - regular messages - from bottom to the end,
  - extension groups - from the end towards the bottom

The mask '11xxxx'B gives us 16 unique messages, one is reserved.
2020-11-07 05:47:05 +07:00
Vadim Yanitskiy 8768a63ebf srsue/rrctl: add RFU (Reserved for Further Use) message type 2020-11-07 04:53:26 +07:00
Vadim Yanitskiy f480a58de7 srsue/extnas: implement handling of RRCTL parameters 2020-11-07 04:53:25 +07:00
Vadim Yanitskiy 23d4dcf256 srsue/extnas: implement forwarding of paging messages 2020-11-07 04:53:25 +07:00
Vadim Yanitskiy d5ae5d8e4a srsue/extnas: fix handle_rrctl_data(): send missing confirmation 2020-11-07 04:53:04 +07:00
Vadim Yanitskiy 95058ef656 srsue/extnas: implement RRCTL codec and message handling
RRCTL is a simple protocol (inspired by Osmocom's L1CTL) that allows
an external NAS entity to control the RRC layer of srsUE. The most
notable primitives are PLMN search, selection, and PDU transfer.

The protocol assumes traditional master-slave communication, where
one side (an external NAS entity) initiates various processes,
while the other (srsUE) executes them and indicates the outcome.

Each RRCTL message starts with a header that can be defined as follows:

  +-------------------------------+--------------------------+
  | Message type                  | 6 bits                   |
  +-------------------------------+--------------------------+
  | Message sub-type              | 2 bits                   |
  +-------------------------------+--------------------------+
  | Spare (RFU)                   | 8 bits                   |
  +-------------------------------+--------------------------+
  | Payload length                | 2 octets (big endian)    |
  +-------------------------------+--------------------------+
  | Payload (optional)            | (see payload length)     |
  +-------------------------------+--------------------------+

The following message types are defined at the moment:

  - RRCTL_RESET - reset internal state of the external NAS interface
                  (does nothing for now, may be useful in the future);

  - RRCTL_PLMN_SEARCH - initiates PLMN (carrier) search on pre-configured
                        EARFCN (Absolute Radio Freqency Number);

  - RRCTL_PLMN_SELECT - binds the UE to one of the previously detected
                        carriers (see RRCTL_PLMN_SEARCH) defined by a
                        given pair of MCC and MNC;

  - RRCTL_CONN_ESTABLISH - establishes connection to the serving cell
                           (previously selected using RRCTL_PLMN_SELECT)
                           with a given cause and NAS PDU;

  - RRCTL_CONN_RELEASE - releases previously established dedicated connection
                         (currently does nothing because the RRC layer does
                          not expose any API for that);

  - RRCTL_DATA - encapsulates a received (Downlink) or to be transmitted
                 (Uplink) NAS PDU (the former also contains LCID).

Each message type has at least two of the following sub-types:

  - RRCTL_REQ - request (usually comes from an external NAS entity),
                used to initiate some process (e.g. PLMN search);

  - RRCTL_IND - indication that something has happened without a prior
                request (for example, a Downlink NAS PDU was received);

  - RRCTL_CNF - confirmation (positive conslusion) of the requested task;

  - RRCTL_ERR - negative conslusion of the requested task (error).

The protocol definition (enums ans structs) and codec functions are
defined in a separate namespaces: 'rrctl::proto' and 'rrctl::codec'
respectively. The codec functions may throw exceptions of type
'rrctl::codec::error' if something goes wrong.
2020-07-26 04:15:21 +07:00
Vadim Yanitskiy 845f90face srsue/extnas: add a possibility to enable the external NAS interface
The new configuration section '[extnas]' allows to disable the
built-in NAS implementation, and provide the interface (UNIX
domain socket) to an external entity. The interface itself will
be implemented in the follow up commits.
2020-07-26 04:15:21 +07:00
Vadim Yanitskiy fbc9e3554f srsue/extnas: implement a simple UNIX domain socket server
Unfortunately, the existing networking API (common/network_utils.h)
lacks the UNIX domain socket support, and it turned to be easier
to implement a simple, single client server using Boost.Asio.

The server runs in its own thread with a blocking Tx queue, and
calls a user definted callback on receipt of any data from client.
Multiple client connections are not supported and will be rejected.
2020-07-26 04:15:21 +07:00
Vadim Yanitskiy 5e60f29d70 srsue/extnas: introduce draft implementation of 'nas_ext' class
This commit introduces a skeleton class (child of 'nas_base') for
the upcoming implementation of an external NAS interface, as well
as the implementation specific configuration container.
2020-07-26 04:15:21 +07:00
Vadim Yanitskiy 63abfb9130 srsue/extnas: derive abstract 'nas_base' class from 'nas'
This is the first step towards the goal of having an external NAS
interface. The new 'nas_base' class becomes a parent of 'nas',
combining all interfaces and the basic (common) API.

The 'ue_stack_lte' now holds a unique_ptr of type 'srsue::nas_base',
so the underlying NAS implementation (built-in or external) can
be choosen at run-time depending on configuration.

The implementation specific configuration now needs to be passed
to the constructor instead, not to the init() method as was before.
2020-07-26 04:15:21 +07:00
Vadim Yanitskiy 73a8073b8d lib: fix multiple symbol definitions detected by GCC 10 2020-07-26 04:14:27 +07:00
Vadim Yanitskiy 9a0908d36c CMakeLists.txt: disable -Werror due to build failures with GCC 10 2020-07-26 04:12:59 +07:00
Vadim Yanitskiy bb1d2f56e4 srslte/common: constify the argument of byte_buffer_t::append_bytes()
This function does not modify the input buffer. Let's make it
possible to pass 'const uint8_t *' pointers without loosing
the const qualifier and making GCC unhappy.
2020-03-20 18:44:24 +07:00
Vadim Yanitskiy dcb59b3055 srslte/interfaces: mark to_number() of struct plmn_id_t as const
This function does not modify any fields of the structure. Without
the 'const' qualifier it's impossible to call to_number() through
a const pointer of type 'struct plmn_id_t'.
2020-03-20 18:44:24 +07:00
Vadim Yanitskiy d83f7e795f srsue/rrc: fix rrc::new_phy_meas(): properly print EARFCN
A measurement report coming from a PHY worker may contain a negative EARFCN:

  [RRC ] [I] MEAS:  New measurement earfcn=-1, pci=98 (serving), rsrp=-76.5 dBm.

This means that the measurement report is for the current serving
cell, so let's rather print its EARFCN instead of a negative one.
2020-03-20 18:44:24 +07:00
32 changed files with 1593 additions and 105 deletions

View File

@ -12,7 +12,7 @@ jobs:
- name: Build srsLTE on x86
run: |
sudo apt update
sudo apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev colordiff ninja-build valgrind
sudo apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libasio-dev libconfig++-dev libsctp-dev colordiff ninja-build valgrind
mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja && ctest -T memcheck
x86_ubuntu16_build:
name: Build and test on x86 Ubuntu 16.04
@ -25,7 +25,7 @@ jobs:
- name: Build srsLTE on x86
run: |
sudo apt update
sudo apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev colordiff ninja-build valgrind
sudo apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libasio-dev libconfig++-dev libsctp-dev colordiff ninja-build valgrind
mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja && ctest -T memcheck
aarch64_ubuntu18_build:
@ -40,5 +40,5 @@ jobs:
distribution: ubuntu18.04
run: |
apt update
apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev ninja-build
apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libasio-dev libconfig++-dev libsctp-dev ninja-build
ls -l && pwd && mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja

View File

@ -8,6 +8,7 @@ extraction:
- libmbedtls-dev
- libpcsclite-dev
- libboost-program-options-dev
- libasio-dev
- libconfig++-dev
- libsctp-dev
- libuhd-dev

View File

@ -3,7 +3,7 @@ sudo: required
before_script:
- sudo apt-get -qq update
- sudo apt-get install -qq build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev colordiff ninja-build
- sudo apt-get install -qq build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libasio-dev libconfig++-dev libsctp-dev colordiff ninja-build
language: cpp

View File

@ -226,6 +226,7 @@ endif(BUILD_STATIC)
set(BOOST_REQUIRED_COMPONENTS
program_options
system
)
if(UNIX AND EXISTS "/usr/lib64")
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix
@ -448,12 +449,6 @@ if("Ninja" STREQUAL ${CMAKE_GENERATOR})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
endif()
# Add -Werror to C/C++ flags for newer compilers
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9 AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif()
message(STATUS "CMAKE_C_FLAGS is ${CMAKE_C_FLAGS}")
message(STATUS "CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")

View File

@ -114,7 +114,7 @@ Build Instructions
For example, on Ubuntu 17.04, one can install the required libraries with:
```
sudo apt-get install cmake libfftw3-dev libmbedtls-dev libboost-program-options-dev libconfig++-dev libsctp-dev
sudo apt-get install cmake libfftw3-dev libmbedtls-dev libboost-program-options-dev libasio-dev libconfig++-dev libsctp-dev
```
or on Fedora:
```

View File

@ -1,7 +1,7 @@
SET(CPACK_PACKAGE_DESCRIPTION "srsLTE")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LTE library for SDR.")
SET(CPACK_PACKAGE_NAME "srslte")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.6), libgcc1 (>= 1:4.1), libboost-dev (>= 1.35)")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.6), libgcc1 (>= 1:4.1), libboost-dev (>= 1.35) libasio-dev")
SET(CPACK_PACKAGE_CONTACT "Ismael Gomez ")
SET(CPACK_PACKAGE_VENDOR "Software Radio Systems Limited")
@ -45,12 +45,12 @@ ENDIF()
########################################################################
# Setup CPack Debian
########################################################################
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev libasio-dev")
########################################################################
# Setup CPack RPM
########################################################################
SET(CPACK_RPM_PACKAGE_REQUIRES "boost-devel")
SET(CPACK_RPM_PACKAGE_REQUIRES "boost-devel libasio-dev")
########################################################################
# Setup CPack NSIS

1
debian/control vendored
View File

@ -10,6 +10,7 @@ Build-Depends:
libfftw3-dev,
libmbedtls-dev,
libboost-program-options-dev,
libasio-dev,
libconfig++-dev,
libsctp-dev,
libuhd-dev,

View File

@ -172,7 +172,7 @@ public:
#endif
}
void append_bytes(uint8_t* buf, uint32_t size)
void append_bytes(const uint8_t* buf, uint32_t size)
{
memcpy(&msg[N_bytes], buf, size);
N_bytes += size;

View File

@ -83,7 +83,7 @@ struct plmn_id_t {
}
return SRSLTE_SUCCESS;
}
std::pair<uint16_t, uint16_t> to_number()
std::pair<uint16_t, uint16_t> to_number() const
{
uint16_t mcc_num, mnc_num;
srslte::bytes_to_mcc(&mcc[0], &mcc_num);
@ -104,6 +104,34 @@ struct plmn_id_t {
uint8_t* plmn_ptr = (uint8_t*)&s1ap_plmn;
memcpy(&plmn_bytes[0], plmn_ptr + 1, 3);
}
void to_rrctl_bytes(uint8_t *mcc_buf, uint8_t *mnc_buf) const
{
mcc_buf[0] = ((mcc[1] & 0x0f) << 4) | (mcc[0] & 0x0f);
mcc_buf[1] = (0x0f << 4) | (mcc[2] & 0x0f);
mnc_buf[0] = ((mnc[1] & 0x0f) << 4) | (mnc[0] & 0x0f);
if (nof_mnc_digits > 2)
mnc_buf[1] = (0x0f << 4) | (mnc[2] & 0x0f);
else
mnc_buf[1] = 0xff;
}
void from_rrctl_bytes(const uint8_t *mcc_buf, const uint8_t *mnc_buf)
{
mcc[0] = mcc_buf[0] & 0x0f;
mcc[1] = mcc_buf[0] >> 4;
mcc[2] = mcc_buf[1] & 0x0f;
mnc[0] = mnc_buf[0] & 0x0f;
mnc[1] = mnc_buf[0] >> 4;
if (mnc_buf[1] != 0xff) {
nof_mnc_digits = 3;
mnc[2] = mnc_buf[1] & 0x0f;
} else {
nof_mnc_digits = 2;
mnc[2] = 0x00;
}
}
int from_string(const std::string& plmn_str)
{
if (plmn_str.size() < 5 or plmn_str.size() > 6) {

View File

@ -34,12 +34,12 @@ typedef union {
__m64 v;
} decision_t;
union branchtab27 {
static union branchtab27 {
unsigned char c[32];
__m256i v;
} Branchtab37_sse2[3];
int firstGo;
static int firstGo;
/* State info for instance of Viterbi decoder */
struct v37 {
metric_t metrics1; /* path metric buffer 1 */

View File

@ -34,7 +34,7 @@ typedef union {
__m64 v[1];
} decision_t;
union branchtab27 {
static union branchtab27 {
// unsigned char c[32];
//__m128i v[2];
@ -43,7 +43,7 @@ union branchtab27 {
} Branchtab37_sse2[3];
int firstGo;
static int firstGo;
/* State info for instance of Viterbi decoder */
struct v37 {
metric_t metrics1; /* path metric buffer 1 */

View File

@ -29,7 +29,7 @@ typedef union {
__m64 v[1];
} decision_t;
union branchtab27 {
static union branchtab27 {
unsigned char c[32];
__m128i v[2];
} Branchtab37_sse2[3];

View File

@ -71,7 +71,7 @@ typedef struct {
uint32_t num_stream_curruption;
} rf_soapy_handler_t;
cf_t zero_mem[64 * 1024];
static cf_t zero_mem[64 * 1024];
static void log_overflow(rf_soapy_handler_t* h)
{

View File

@ -70,7 +70,7 @@ void suppress_handler(const char* x)
// do nothing
}
cf_t zero_mem[64 * 1024];
static cf_t zero_mem[64 * 1024];
static void log_overflow(rf_uhd_handler_t* h)
{

View File

@ -64,6 +64,7 @@ typedef struct {
usim_args_t usim;
rrc_args_t rrc;
std::string ue_category_str;
nas_ext_args_t nas_ext;
nas_args_t nas;
gw_args_t gw;
} stack_args_t;

View File

@ -37,6 +37,7 @@
#include "srslte/upper/pdcp.h"
#include "srslte/upper/rlc.h"
#include "upper/nas.h"
#include "upper/nas_ext.h"
#include "upper/usim.h"
#include "srslte/common/buffer_pool.h"
@ -153,9 +154,11 @@ private:
srslte::rlc rlc;
srslte::pdcp pdcp;
srsue::rrc rrc;
srsue::nas nas;
std::unique_ptr<usim_base> usim;
// NAS implementation (built-in or external)
std::unique_ptr<srsue::nas_base> nas;
// RAT-specific interfaces
phy_interface_stack_lte* phy = nullptr;
gw_interface_stack* gw = nullptr;

View File

@ -37,11 +37,60 @@ using srslte::byte_buffer_t;
namespace srsue {
class nas : public nas_interface_rrc, public nas_interface_ue, public srslte::timer_callback
class nas_base : public nas_interface_rrc, public nas_interface_ue, public srslte::timer_callback
{
public:
nas(srslte::log* log_, srslte::timer_handler* timers_);
void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& args_);
nas_base(srslte::log* log_, srslte::timer_handler* timers_) :
pool(srslte::byte_buffer_pool::get_instance()), timers(timers_), nas_log(log_){};
virtual void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_) = 0;
virtual void get_metrics(nas_metrics_t* m) = 0;
virtual void stop() = 0;
// PCAP
void start_pcap(srslte::nas_pcap* pcap_);
protected:
srslte::byte_buffer_pool* pool = nullptr;
srslte::timer_handler* timers = nullptr;
srslte::log* nas_log = nullptr;
rrc_interface_nas* rrc = nullptr;
usim_interface_nas* usim = nullptr;
gw_interface_nas* gw = nullptr;
// PCAP
srslte::nas_pcap* pcap = nullptr;
// Security context
uint8_t k_nas_enc[32] = { };
uint8_t k_nas_int[32] = { };
struct nas_sec_ctxt {
uint8_t ksi;
uint8_t k_asme[32];
uint32_t tx_count;
uint32_t rx_count;
uint32_t k_enb_count;
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo;
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo;
LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti;
} ctxt = { };
void integrity_generate(uint8_t* key_128, uint32_t count, uint8_t direction,
uint8_t* msg, uint32_t msg_len, uint8_t* mac);
bool integrity_check(srslte::byte_buffer_t* pdu);
void cipher_encrypt(srslte::byte_buffer_t* pdu);
void cipher_decrypt(srslte::byte_buffer_t* pdu);
void set_k_enb_count(uint32_t count);
uint32_t get_k_enb_count();
};
class nas : public nas_base
{
public:
nas(srslte::log* log_, srslte::timer_handler* timers_, const nas_args_t& cfg_);
void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_);
void stop();
void run_tti(uint32_t tti) final;
@ -53,7 +102,6 @@ public:
bool paging(srslte::s_tmsi_t* ue_identity);
void set_barring(barring_t barring);
void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu);
uint32_t get_k_enb_count();
bool is_attached();
bool get_k_asme(uint8_t* k_asme_, uint32_t n);
uint32_t get_ipv4_addr();
@ -70,16 +118,7 @@ public:
// timer callback
void timer_expired(uint32_t timeout_id);
// PCAP
void start_pcap(srslte::nas_pcap* pcap_);
private:
srslte::byte_buffer_pool* pool = nullptr;
srslte::log* nas_log = nullptr;
rrc_interface_nas* rrc = nullptr;
usim_interface_nas* usim = nullptr;
gw_interface_nas* gw = nullptr;
nas_args_t cfg = {};
emm_state_t state = EMM_STATE_DEREGISTERED;
@ -92,18 +131,6 @@ private:
std::vector<srslte::plmn_id_t> known_plmns;
// Security context
struct nas_sec_ctxt {
uint8_t ksi;
uint8_t k_asme[32];
uint32_t tx_count;
uint32_t rx_count;
uint32_t k_enb_count;
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo;
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo;
LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti;
};
typedef enum { DEFAULT_EPS_BEARER = 0, DEDICATED_EPS_BEARER } eps_bearer_type_t;
typedef struct {
@ -118,7 +145,6 @@ private:
bool have_guti = false;
bool have_ctxt = false;
nas_sec_ctxt ctxt = {};
bool auth_request = false;
uint32_t ip_addr = 0;
@ -129,7 +155,6 @@ private:
uint8_t transaction_id = 0;
// timers
srslte::timer_handler* timers = nullptr;
srslte::timer_handler::unique_timer t3410; // started when attach request is sent, on expiry, start t3411
srslte::timer_handler::unique_timer t3411; // started when attach failed
@ -139,21 +164,9 @@ private:
// Security
bool eia_caps[8] = {};
bool eea_caps[8] = {};
uint8_t k_nas_enc[32] = {};
uint8_t k_nas_int[32] = {};
// PCAP
srslte::nas_pcap* pcap = nullptr;
bool running = false;
void
integrity_generate(uint8_t* key_128, uint32_t count, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* mac);
bool integrity_check(srslte::byte_buffer_t* pdu);
void cipher_encrypt(srslte::byte_buffer_t* pdu);
void cipher_decrypt(srslte::byte_buffer_t* pdu);
void set_k_enb_count(uint32_t count);
bool check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT* caps);
void select_plmn();

View File

@ -38,6 +38,15 @@ public:
std::string eea;
};
class nas_ext_args_t
{
public:
nas_ext_args_t() : enable(false) {}
bool enable;
std::string sock_path;
};
// EMM states (3GPP 24.302 v10.0.0)
typedef enum {
EMM_STATE_NULL = 0,

View File

@ -0,0 +1,104 @@
/*
* Copyright 2020 Software Radio Systems Limited
* Author: Vadim Yanitskiy <axilirator@gmail.com>
* Sponsored by Positive Technologies
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE 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 Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSUE_NAS_EXT_H
#define SRSUE_NAS_EXT_H
#include "srslte/common/buffer_pool.h"
#include "srslte/common/common.h"
#include "srslte/common/log.h"
#include "srslte/common/nas_pcap.h"
#include "srslte/common/security.h"
#include "srslte/common/stack_procedure.h"
#include "srslte/interfaces/ue_interfaces.h"
#include "srsue/hdr/stack/upper/nas.h"
#include "srsue/hdr/stack/upper/nas_common.h"
#include "srsue/hdr/stack/upper/nas_ext.h"
#include "srsue/hdr/stack/upper/nas_extif.h"
#include "srsue/hdr/stack/upper/nas_metrics.h"
#include "srsue/hdr/stack/upper/rrctl.h"
using srslte::byte_buffer_t;
namespace srsue {
class nas_ext : public nas_base
{
public:
nas_ext(srslte::log* log_, srslte::timer_handler* timers_, const nas_ext_args_t& cfg_) :
nas_base::nas_base(log_, timers_), cfg(cfg_){};
void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_);
void get_metrics(nas_metrics_t* m);
void stop();
// RRC interface
void left_rrc_connected();
bool paging(srslte::s_tmsi_t* ue_identity);
void set_barring(barring_t barring);
void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu);
bool is_attached();
bool get_k_asme(uint8_t* k_asme_, uint32_t n);
uint32_t get_ipv4_addr();
bool get_ipv6_addr(uint8_t* ipv6_addr);
void plmn_search_completed(const rrc_interface_nas::found_plmn_t found_plmns[rrc_interface_nas::MAX_FOUND_PLMNS],
int nof_plmns) final;
bool connection_request_completed(bool outcome) final;
void run_tti(uint32_t tti) final;
// UE interface
void start_attach_request(srslte::proc_state_t* result, srslte::establishment_cause_t cause_) final;
bool detach_request(const bool switch_off) final;
// timer callback
void timer_expired(uint32_t timeout_id);
private:
nas_ext_args_t cfg = {};
// Interface to an external NAS entity
std::unique_ptr<nas_extif_base> iface;
// RRCTL message handlers
void handle_rrctl_reset(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
void handle_rrctl_plmn_search(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
void handle_rrctl_plmn_select(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
void handle_rrctl_conn_establish(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
void handle_rrctl_conn_release(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
void handle_rrctl_data(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
void handle_rrctl_param(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
void handle_rrctl_sec_mode(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
void handle_rrctl_ext_usim(const uint8_t* msg, size_t len);
void handle_usim_gen_auth_resp_req(const struct rrctl::proto::ext_usim_msg* msg, size_t len);
void handle_usim_gen_nas_keys_req(const struct rrctl::proto::ext_usim_msg* msg, size_t len);
void rrctl_send_confirm(rrctl::proto::msg_type type);
void rrctl_send_error(rrctl::proto::msg_type type);
};
} // namespace srsue
#endif // SRSUE_NAS_EXT_H

View File

@ -0,0 +1,60 @@
/*
* Copyright 2020 Software Radio Systems Limited
* Author: Vadim Yanitskiy <axilirator@gmail.com>
* Sponsored by Positive Technologies
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE 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 Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSUE_NAS_EXTIF_H
#define SRSUE_NAS_EXTIF_H
#include "srslte/common/common.h"
#include "srslte/common/log.h"
#include "srslte/common/threads.h"
using srslte::byte_buffer_t;
namespace srsue {
// Abstract class for an external interface
class nas_extif_base : public thread
{
public:
using recv_cb_t = std::function<void(const srslte::byte_buffer_t&)>;
nas_extif_base(srslte::log* log_, recv_cb_t recv_cb_) :
nas_log(log_), recv_cb(std::move(recv_cb_)), thread("EXTIF"){};
// Interface for nas_ext
virtual void close(void) = 0;
virtual int write(const srslte::byte_buffer_t& pdu) = 0;
protected:
static const int IFACE_THREAD_PRIO = 65;
virtual void run_thread() = 0;
virtual void stop() = 0;
bool running = false;
srslte::log* nas_log = nullptr;
recv_cb_t recv_cb;
};
} // namespace srsue
#endif // SRSUE_NAS_EXTIF_H

View File

@ -0,0 +1,67 @@
/*
* Copyright 2020 Software Radio Systems Limited
* Author: Vadim Yanitskiy <axilirator@gmail.com>
* Sponsored by Positive Technologies
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE 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 Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSUE_NAS_EXTIF_UNIX_H
#define SRSUE_NAS_EXTIF_UNIX_H
#include <boost/asio.hpp>
#include "srslte/common/block_queue.h"
#include "srslte/common/common.h"
#include "srslte/common/log.h"
#include "srsue/hdr/stack/upper/nas_extif.h"
namespace srsue {
// UNIX domain socket server
class nas_extif_unix : public nas_extif_base
{
public:
nas_extif_unix(srslte::log* log_, recv_cb_t cb_, const std::string& sock_path_);
void close(void);
int write(const srslte::byte_buffer_t& pdu);
protected:
void run_thread(void);
void stop(void);
private:
std::unique_ptr<boost::asio::local::stream_protocol::acceptor> acc;
std::unique_ptr<boost::asio::local::stream_protocol::socket> sock;
boost::asio::io_context io_ctx;
std::string sock_path;
srslte::block_queue<srslte::byte_buffer_t> tx_queue;
bool has_connection;
uint8_t buf[1024];
void handle_write(void);
void handle_read(void);
void accept_conn(void);
};
} // namespace srsue
#endif // SRSUE_NAS_EXTIF_UNIX_H

View File

@ -0,0 +1,260 @@
/*
* Copyright 2020 Software Radio Systems Limited
* Author: Vadim Yanitskiy <axilirator@gmail.com>
* Sponsored by Positive Technologies
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE 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 Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <stdint.h>
#include <asm/byteorder.h>
#include "srslte/common/common.h"
#include "srslte/interfaces/ue_interfaces.h"
namespace rrctl {
namespace proto {
enum msg_type {
RRCTL_RESET = 0x00,
RRCTL_DATA,
RRCTL_PLMN_SEARCH,
RRCTL_PLMN_SELECT,
RRCTL_CONN_ESTABLISH,
RRCTL_CONN_RELEASE,
RRCTL_PAGING,
RRCTL_PARAM,
RRCTL_SEC_MODE,
/* RRCTL protocol extensions (0b11xxxx, up to 15 groups) follow */
/* (U)SIM specific messages (for accessing built-in card reader) */
RRCTL_EXT_USIM = 0x3e, // 0b111110
/* RFU (Reserved for Further Use) */
RRCTL_RESERVED = 0x3f, // 0b111111
};
enum msg_disc {
RRCTL_REQ = 0x00,
RRCTL_IND = 0x01,
RRCTL_CNF = 0x02,
RRCTL_ERR = 0x03,
};
struct msg_hdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t disc:2, type:6;
#elif defined(__BIG_ENDIAN_BITFIELD)
uint8_t type:6, disc:2;
#else
#error "Please fix <asm/byteorder.h>"
#endif
uint8_t rfu; // Reserved
uint16_t len;
uint8_t data[0];
} __attribute__((packed));
struct msg_plmn_search_res {
uint8_t nof_plmns;
struct plmn {
uint8_t mcc[2];
uint8_t mnc[2];
uint16_t tac;
} plmns[16];
} __attribute__((packed));
struct msg_plmn_select_req {
uint8_t mcc[2];
uint8_t mnc[2];
} __attribute__((packed));
struct msg_conn_establish_req {
uint8_t cause;
uint8_t pdu[0];
} __attribute__((packed));
struct msg_data {
uint32_t lcid;
uint8_t pdu[0];
} __attribute__((packed));
struct __mmec_m_tmsi {
uint8_t mmec;
uint32_t m_tmsi;
} __attribute__((packed));
struct msg_paging_ind {
struct __mmec_m_tmsi ueid;
} __attribute__((packed));
enum msg_param_type {
RRCTL_PARAM_UEID = 0x00,
};
struct msg_param_req {
uint8_t type;
uint8_t len;
union {
struct __mmec_m_tmsi ueid;
} u;
} __attribute__((packed));
enum msg_eea_type {
RRCTL_EEA0 = 0x00,
RRCTL_EEA1 = 0x01,
RRCTL_EEA2 = 0x02,
RRCTL_EEA3 = 0x03,
};
enum msg_eia_type {
RRCTL_EIA0 = 0x00,
RRCTL_EIA1 = 0x01,
RRCTL_EIA2 = 0x02,
RRCTL_EIA3 = 0x03,
};
#define SEC_MODE_F_RESET_RX_CTR (1 << 0)
#define SEC_MODE_F_RESET_TX_CTR (1 << 1)
struct msg_sec_mode_req {
#if defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t flags:2, eia:3, eea:3;
#elif defined(__BIG_ENDIAN_BITFIELD)
uint8_t eea:3, eia:3, flags:2;
#else
#error "Please fix <asm/byteorder.h>"
#endif
uint8_t spare[3];
uint8_t k_asme[0]; // optional (32 octets)
} __attribute__((packed));
struct msg {
struct msg_hdr hdr;
union {
struct msg_data data;
struct msg_sec_mode_req;
struct msg_param_req param_req;
struct msg_paging_ind paging_ind;
struct msg_plmn_search_res plmn_search_res;
struct msg_plmn_select_req plmn_select_req;
struct msg_conn_establish_req conn_establish_req;
} u;
} __attribute__((packed));
/* (U)SIM specific message types */
enum ext_usim_msg_type {
EXT_USIM_RAW_APDU = 0x00,
EXT_USIM_READ_FILE = 0x01,
EXT_USIM_UPDATE_FILE = 0x02,
EXT_USIM_GEN_AUTH_RESP = 0x03,
/* RFU (Reserved for Further Use) */
EXT_USIM_RESERVED = 0xff,
};
struct ext_usim_raw_apdu {
uint16_t len;
uint8_t apdu_sw[0];
} __attribute__((packed));
struct ext_usim_read_file_req {
/* TODO: check GSM 11.11 and make sure that this is correct */
uint16_t df; // Dedicated File
uint16_t ef; // Elementary File
} __attribute__((packed));
struct ext_usim_read_file_rsp {
uint16_t len;
uint8_t data[0];
} __attribute__((packed));
struct ext_usim_update_file_req {
/* NOTE: re-using the existing structures here */
struct ext_usim_read_file_req file; // DF & EF
struct ext_usim_read_file_rsp content;
} __attribute__((packed));
struct ext_usim_gen_auth_resp_req {
uint8_t rand[16];
uint8_t autn[16];
uint8_t mcc[2];
uint8_t mnc[2];
} __attribute__((packed));
struct ext_usim_gen_auth_resp_rsp {
uint8_t out_of_sync;
uint8_t res_len;
uint8_t spare[2];
uint8_t k_asme_res[0];
} __attribute__((packed));
struct ext_usim_msg {
uint8_t type;
uint8_t spare[3];
union {
struct ext_usim_raw_apdu raw_apdu;
struct ext_usim_read_file_req read_file_req;
struct ext_usim_read_file_rsp read_file_rsp;
struct ext_usim_update_file_req update_file_req;
struct ext_usim_gen_auth_resp_req gen_auth_resp_req;
struct ext_usim_gen_auth_resp_rsp gen_auth_resp_rsp;
} u;
} __attribute__((packed));
std::string msg_hdr_desc(proto::msg_type type, proto::msg_disc disc, uint16_t len = 0);
} // namespace proto
namespace codec {
class error : public std::runtime_error {
public:
explicit error(const std::string& msg) : std::runtime_error(msg) {};
};
struct proto::msg_hdr* enc_hdr(srslte::byte_buffer_t& buf,
proto::msg_type type,
proto::msg_disc disc,
uint16_t len = 0);
const uint8_t* dec_hdr(const srslte::byte_buffer_t& buf,
proto::msg_type& type,
proto::msg_disc& disc,
uint16_t& len);
void enc_plmn_search_res(srslte::byte_buffer_t& buf,
const srsue::rrc_interface_nas::found_plmn_t* plmns,
size_t nof_plmns);
void dec_plmn_select_req(std::pair<uint16_t, uint16_t>& mcc_mnc,
const uint8_t* payload, size_t len);
void dec_conn_establish_req(srslte::establishment_cause_t& cause,
const uint8_t*& pdu, size_t& pdu_len,
const uint8_t* payload, size_t len);
void enc_data_ind(srslte::byte_buffer_t& buf,
const uint8_t *pdu, size_t pdu_len,
uint32_t lcid);
void enc_paging_ind(srslte::byte_buffer_t& buf,
srslte::s_tmsi_t* ue_identity);
} // namespace codec
} // namespace rrctl

View File

@ -110,6 +110,9 @@ static int parse_args(all_args_t* args, int argc, char* argv[])
("nas.eia", bpo::value<string>(&args->stack.nas.eia)->default_value("1,2,3"), "List of integrity algorithms included in UE capabilities")
("nas.eea", bpo::value<string>(&args->stack.nas.eea)->default_value("0,1,2,3"), "List of ciphering algorithms included in UE capabilities")
("extnas.enable", bpo::value<bool>(&args->stack.nas_ext.enable)->default_value(false), "Disable the built-in NAS implementation, provide external interface")
("extnas.sock_path", bpo::value<string>(&args->stack.nas_ext.sock_path)->default_value("/tmp/ue_extnas.sock"), "UNIX socket path of the external interface")
("pcap.enable", bpo::value<bool>(&args->stack.pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark")
("pcap.filename", bpo::value<string>(&args->stack.pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename")
("pcap.nas_enable", bpo::value<bool>(&args->stack.pcap.nas_enable)->default_value(false), "Enable NAS packet captures for wireshark")

View File

@ -368,8 +368,8 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p
}
phy_meas_t new_meas = {rsrp, rsrq, tti, earfcn, pci};
phy_meas_q.push(new_meas);
rrc_log->info("MEAS: New measurement earfcn=%d, pci=%d (%s), rsrp=%.1f dBm.\n",
earfcn_i,
rrc_log->info("MEAS: New measurement earfcn=%u, pci=%d (%s), rsrp=%.1f dBm.\n",
earfcn,
pci,
pci_i < 0 ? "serving" : "neighbour",
rsrp);

View File

@ -37,7 +37,6 @@ ue_stack_lte::ue_stack_lte() :
mac(&mac_log),
rrc(&rrc_log),
pdcp(&timers, &pdcp_log),
nas(&nas_log, &timers),
thread("STACK"),
pending_tasks(1024),
background_tasks(2)
@ -115,6 +114,16 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_)
asn1::srsasn_log_register_handler(&asn1_log);
asn1::rrc::rrc_log_register_handler(&rrc_log);
// Should we use the built-in NAS implementation
// or provide an external interface (RRCTL)?
if (args.nas_ext.enable) {
std::unique_ptr<srsue::nas_ext> nas_impl(new srsue::nas_ext(&nas_log, &timers, args.nas_ext));
nas = std::move(nas_impl);
} else {
std::unique_ptr<srsue::nas> nas_impl(new srsue::nas(&nas_log, &timers, args.nas));
nas = std::move(nas_impl);
}
// Set up pcap
if (args.pcap.enable) {
mac_pcap.open(args.pcap.filename.c_str());
@ -122,7 +131,7 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_)
}
if (args.pcap.nas_enable) {
nas_pcap.open(args.pcap.nas_filename.c_str());
nas.start_pcap(&nas_pcap);
nas->start_pcap(&nas_pcap);
}
// Init USIM first to allow early exit in case reader couldn't be found
@ -135,8 +144,8 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_)
mac.init(phy, &rlc, &rrc, &timers, this);
rlc.init(&pdcp, &rrc, &timers, 0 /* RB_ID_SRB0 */);
pdcp.init(&rlc, &rrc, gw);
nas.init(usim.get(), &rrc, gw, args.nas);
rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &timers, this, args.rrc);
nas->init(usim.get(), &rrc, gw);
rrc.init(phy, &mac, &rlc, &pdcp, nas.get(), usim.get(), gw, &timers, this, args.rrc);
running = true;
start(STACK_MAIN_THREAD_PRIO);
@ -157,7 +166,7 @@ void ue_stack_lte::stop_impl()
running = false;
usim->stop();
nas.stop();
nas->stop();
rrc.stop();
rlc.stop();
@ -176,7 +185,7 @@ bool ue_stack_lte::switch_on()
{
if (running) {
pending_tasks.try_push(ue_queue_id,
[this]() { nas.start_attach_request(nullptr, srslte::establishment_cause_t::mo_data); });
[this]() { nas->start_attach_request(nullptr, srslte::establishment_cause_t::mo_data); });
return true;
}
return false;
@ -185,7 +194,7 @@ bool ue_stack_lte::switch_on()
bool ue_stack_lte::switch_off()
{
// generate detach request with switch-off flag
nas.detach_request(true);
nas->detach_request(true);
// wait for max. 5s for it to be sent (according to TS 24.301 Sec 25.5.2.2)
const uint32_t RB_ID_SRB1 = 1;
@ -212,14 +221,14 @@ bool ue_stack_lte::enable_data()
bool ue_stack_lte::disable_data()
{
// generate detach request
return nas.detach_request(false);
return nas->detach_request(false);
}
bool ue_stack_lte::get_metrics(stack_metrics_t* metrics)
{
mac.get_metrics(metrics->mac);
rlc.get_metrics(metrics->rlc);
nas.get_metrics(&metrics->nas);
nas->get_metrics(&metrics->nas);
rrc.get_metrics(metrics->rrc);
return (metrics->nas.state == EMM_STATE_REGISTERED && metrics->rrc.state == RRC_STATE_CONNECTED);
}
@ -285,7 +294,7 @@ void ue_stack_lte::run_tti_impl(uint32_t tti)
{
mac.run_tti(tti);
rrc.run_tti(tti);
nas.run_tti(tti);
nas->run_tti(tti);
timers.step_all();
}

View File

@ -18,7 +18,7 @@
# and at http://www.gnu.org/licenses/.
#
set(SOURCES gw.cc nas.cc usim_base.cc usim.cc tft_packet_filter.cc)
set(SOURCES gw.cc nas.cc nas_ext.cc nas_extif.cc rrctl.cc usim_base.cc usim.cc tft_packet_filter.cc)
if(HAVE_PCSC)
list(APPEND SOURCES "pcsc_usim.cc")

View File

@ -224,18 +224,17 @@ proc_outcome_t nas::rrc_connect_proc::react(nas::rrc_connect_proc::connection_re
* NAS
********************************************************************/
nas::nas(srslte::log* log_, srslte::timer_handler* timers_) :
nas_log(log_),
pool(byte_buffer_pool::get_instance()),
nas::nas(srslte::log* log_, srslte::timer_handler* timers_, const nas_args_t& cfg_) :
nas_base::nas_base(log_, timers_),
cfg(cfg_),
plmn_searcher(this),
rrc_connector(this),
timers(timers_),
t3410(timers_->get_unique_timer()),
t3411(timers_->get_unique_timer())
{
}
void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& cfg_)
void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_)
{
usim = usim_;
rrc = rrc_;
@ -248,7 +247,7 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_
}
// parse and sanity check EIA list
std::vector<uint8_t> cap_list = split_string(cfg_.eia);
std::vector<uint8_t> cap_list = split_string(cfg.eia);
if (cap_list.empty()) {
nas_log->error("Empty EIA list. Select at least one EIA algorithm.\n");
}
@ -261,7 +260,7 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_
}
// parse and sanity check EEA list
cap_list = split_string(cfg_.eea);
cap_list = split_string(cfg.eea);
if (cap_list.empty()) {
nas_log->error("Empty EEA list. Select at least one EEA algorithm.\n");
}
@ -273,8 +272,6 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_
}
}
cfg = cfg_;
if ((read_ctxt_file(&ctxt))) {
usim->generate_nas_keys(ctxt.k_asme, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo);
nas_log->debug_hex(k_nas_enc, 32, "NAS encryption key - k_nas_enc");
@ -610,14 +607,14 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu)
}
}
void nas::set_k_enb_count(uint32_t count)
void nas_base::set_k_enb_count(uint32_t count)
{
// UL count for RRC key derivation depends on UL Count of the Attach Request or Service Request.
// On the case of an Authentication Request, the UL count used to generate K_enb must be reset to zero.
ctxt.k_enb_count = count;
}
uint32_t nas::get_k_enb_count()
uint32_t nas_base::get_k_enb_count()
{
return ctxt.k_enb_count;
}
@ -656,7 +653,7 @@ bool nas::get_ipv6_addr(uint8_t* ipv6_addr)
PCAP
*******************************************************************************/
void nas::start_pcap(srslte::nas_pcap* pcap_)
void nas_base::start_pcap(srslte::nas_pcap* pcap_)
{
pcap = pcap_;
}
@ -665,12 +662,12 @@ void nas::start_pcap(srslte::nas_pcap* pcap_)
* Security
******************************************************************************/
void nas::integrity_generate(uint8_t* key_128,
uint32_t count,
uint8_t direction,
uint8_t* msg,
uint32_t msg_len,
uint8_t* mac)
void nas_base::integrity_generate(uint8_t* key_128,
uint32_t count,
uint8_t direction,
uint8_t* msg,
uint32_t msg_len,
uint8_t* mac)
{
switch (ctxt.integ_algo) {
case INTEGRITY_ALGORITHM_ID_EIA0:
@ -710,7 +707,7 @@ void nas::integrity_generate(uint8_t* key_128,
// This function depends to a valid k_nas_int.
// This key is generated in the security mode command.
bool nas::integrity_check(byte_buffer_t* pdu)
bool nas_base::integrity_check(byte_buffer_t* pdu)
{
if (pdu == nullptr) {
nas_log->error("Invalid PDU\n");
@ -758,7 +755,7 @@ bool nas::integrity_check(byte_buffer_t* pdu)
}
}
void nas::cipher_encrypt(byte_buffer_t* pdu)
void nas_base::cipher_encrypt(byte_buffer_t* pdu)
{
byte_buffer_t pdu_tmp;
switch (ctxt.cipher_algo) {