srsRAN/srsue/hdr/stack/upper/rrctl.h

261 lines
6.8 KiB
C++

/*
* 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