e2ap, ric: add support for ric reset request and response

master
Brendan 2 years ago committed by Justin Tallon
parent a599234bf7
commit e52203f739

@ -47,6 +47,11 @@ public:
e2_ap_pdu_c generate_subscription_response();
int generate_subscription_failure();
int generate_indication();
e2_ap_pdu_c generate_reset_request();
e2_ap_pdu_c generate_reset_response();
int process_reset_request(reset_request_s reset_request);
int process_reset_response(reset_resp_s reset_response);
int get_reset_id();
bool has_setup_response() { return setup_response_received; }
private:
@ -60,6 +65,10 @@ private:
global_ric_id_t global_ric_id = {};
std::map<uint32_t, RANfunction_description> ran_functions;
srsenb::e2_interface_metrics* gnb_metrics = nullptr;
bool reset_response_received = false;
int reset_transaction_id = 1;
cause_c reset_cause = cause_c();
int reset_id = 1;
};
#endif /* RIC_E2AP_H */

@ -22,17 +22,26 @@
#include "srsran/srsran.h"
static const int e2ap_ppid = 70;
static const int e2ap_port = 36422;
enum e2_msg_type_t { E2_SETUP_REQUEST, E2_SUB_RESPONSE, E2_INDICATION };
enum e2_msg_type_t { E2_SETUP_REQUEST, E2_SUB_RESPONSE, E2_INDICATION, E2_RESET, E2_RESET_RESPONSE };
namespace srsenb {
class ric_client : public srsran::thread
{
public:
ric_client(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics);
// Initiate and Stop
bool init();
void stop();
void run_thread();
// Send messages to RIC
bool send_sctp(srsran::unique_byte_buffer_t& buf);
bool send_e2_msg(e2_msg_type_t msg_type);
bool send_reset_response();
// Handle messages received from RIC
bool
handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags);
bool handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg);
@ -40,6 +49,8 @@ public:
bool handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome);
bool handle_e2_setup_response(e2setup_resp_s setup_response);
bool handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request);
bool handle_reset_response(reset_resp_s& reset_response);
bool handle_reset_request(reset_request_s& reset_request);
private:
e2ap e2ap_;

@ -16,9 +16,13 @@ e2_ap_pdu_c e2ap::generate_setup_request()
e2setup_request_s& setup = initmsg.value.e2setup_request();
setup->transaction_id.crit = asn1::crit_opts::reject;
<<<<<<< HEAD
setup->transaction_id.value.value = setup_procedure_transaction_id;
setup->global_e2node_id.crit = asn1::crit_opts::reject;
auto& gnb_ = setup->global_e2node_id.value.set_gnb();
=======
setup->transaction_id.value.value = transaction_id;
>>>>>>> 456170567 (e2ap, ric: add support for ric reset request and response)
gnb_.global_g_nb_id.plmn_id.from_number(plmn_id);
gnb_.global_g_nb_id.gnb_id.gnb_id().from_number(gnb_id);
@ -115,3 +119,49 @@ int e2ap::process_subscription_request(ricsubscription_request_s subscription_re
// TODO process subscription request
return 0;
}
e2_ap_pdu_c e2ap::generate_reset_request()
{
using namespace asn1::e2ap;
e2_ap_pdu_c pdu;
init_msg_s& request = pdu.set_init_msg();
request.load_info_obj(ASN1_E2AP_ID_RESET);
reset_request_s& reset_request = request.value.reset_request();
reset_request->transaction_id.crit = asn1::crit_opts::reject;
reset_request->transaction_id.value.value = reset_transaction_id;
reset_request->cause.crit = asn1::crit_opts::ignore;
reset_request->cause.value.set_misc();
return pdu;
}
e2_ap_pdu_c e2ap::generate_reset_response()
{
e2_ap_pdu_c pdu;
successful_outcome_s& response = pdu.set_successful_outcome();
response.load_info_obj(ASN1_E2AP_ID_RESET);
reset_resp_s& reset_response = response.value.reset_resp();
reset_response->transaction_id.crit = asn1::crit_opts::reject;
reset_response->transaction_id.value.value = reset_transaction_id;
return pdu;
}
int e2ap::process_reset_request(reset_request_s reset_request)
{
reset_id = reset_request->transaction_id.value;
// TO DO: Parse and store the cause for future extension of the ric client
return 0;
}
int e2ap::process_reset_response(reset_resp_s reset_response)
{
// TO DO process reset response from RIC
reset_response_received = true;
return 0;
}
int e2ap::get_reset_id()
{
return reset_id;
}

@ -20,6 +20,7 @@ ric_client::ric_client(srslog::basic_logger& logger, e2_interface_metrics* _gnb_
{
gnb_metrics = _gnb_metrics;
}
bool ric_client::init()
{
printf("RIC_CLIENT: Init\n");
@ -35,7 +36,6 @@ bool ric_client::init()
}
// Bind socket
if (not ric_socket.bind_addr("172.17.0.3", 36422)) {
ric_socket.close();
return false;
@ -59,13 +59,17 @@ bool ric_client::init()
start(0);
return SRSRAN_SUCCESS;
}
void ric_client::stop()
{
running = false;
wait_thread_finish();
}
void ric_client::run_thread()
{
using namespace asn1::e2ap;
while (running) {
if (!e2ap_.has_setup_response()) {
send_e2_msg(E2_SETUP_REQUEST);
@ -73,9 +77,9 @@ void ric_client::run_thread()
}
sleep(1);
task_sched.run_next_task();
sleep(5);
}
}
bool ric_client::send_sctp(srsran::unique_byte_buffer_t& buf)
{
ssize_t ret;
@ -98,6 +102,7 @@ bool ric_client::send_sctp(srsran::unique_byte_buffer_t& buf)
bool ric_client::send_e2_msg(e2_msg_type_t msg_type)
{
std::string message_name;
srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer();
if (buf == nullptr) {
// logger.error("Fatal Error: Couldn't allocate buffer for %s.", procedure_name);
@ -107,13 +112,23 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type)
switch (msg_type) {
case e2_msg_type_t::E2_SETUP_REQUEST:
send_pdu = e2ap_.generate_setup_request();
message_name = "E2 SETUP REQUEST";
break;
case e2_msg_type_t::E2_SUB_RESPONSE:
send_pdu = e2ap_.generate_subscription_response();
message_name = "E2 SUBSCRIPTION RESPONSE";
break;
case e2_msg_type_t::E2_INDICATION:
// TODO create E2 INDICATION generation
break;
case e2_msg_type_t::E2_RESET:
send_pdu = e2ap_.generate_reset_request();
message_name = "E2 RESET REQUEST";
break;
case e2_msg_type_t::E2_RESET_RESPONSE:
send_pdu = e2ap_.generate_reset_response();
message_name = "E2 RESET RESPONSE";
break;
default:
printf("Unknown E2AP message type\n");
return false;
@ -126,7 +141,7 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type)
buf->N_bytes = bref.distance_bytes();
printf("try to send %d bytes to addr %s \n", buf->N_bytes, inet_ntoa(ric_addr.sin_addr));
if (!send_sctp(buf)) {
logger.error("failed to send e2 setup request");
logger.error("failed to send {}", message_name);
return false;
}
return true;
@ -176,7 +191,7 @@ bool ric_client::handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg)
//handle_e2conn_upd(init_msg.value.e2conn_upd());
} else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::reset_request) {
logger.info("Received E2AP E2 Reset Request");
//handle_reset_request(init_msg.value.reset_request());
handle_reset_request(init_msg.value.reset_request());
} else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::e2_removal_request) {
logger.info("Received E2AP E2 Removal Request");
//handle_e2_removal_request(init_msg.value.e2_removal_request());
@ -209,9 +224,9 @@ bool ric_client::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s&
e2_ap_elem_procs_o::successful_outcome_c::types_opts::ricsubscription_delete_resp) {
logger.info("Received E2AP RIC Subscription Delete Response \n");
// handle_ric_subscription_delete_response(successful_outcome.value.ric_subscription_delete());
} else if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::e2_removal_resp) {
logger.info("Received E2AP RIC Service Status Successful Outcome \n");
// handle_e2_removal_response(successful_outcome.value.e2_removal());
} else if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::reset_resp) {
logger.info("Received E2AP RIC Reset Response \n");
handle_reset_response(successful_outcome.value.reset_resp());
} else {
logger.info("Received E2AP Unknown Successful Outcome \n");
}
@ -221,7 +236,7 @@ bool ric_client::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s&
bool ric_client::handle_e2_setup_response(e2setup_resp_s setup_response)
{
if (e2ap_.process_setup_response(setup_response)) {
logger.error("Failed to process E2 Setup Response");
logger.error("Failed to process E2 Setup Response \n");
return false;
}
return true;
@ -245,3 +260,36 @@ bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_s
// TODO handle RIC subscription request
return true;
}
bool ric_client::handle_reset_request(reset_request_s& reset_request)
{
printf("Received E2AP E2 Reset Request \n");
// call process to handle reset request, if it fails log error and return false, else return true - success
if (e2ap_.process_reset_request(reset_request)) {
logger.error("Failed to process E2 Reset Request \n");
return false;
}
logger.info("Reset transaction with ID = {}", e2ap_.get_reset_id());
// send reset reset response
auto send_reset_resp = [this]() { send_e2_msg(E2_RESET_RESPONSE); };
ric_rece_task_queue.push(send_reset_resp);
return true;
}
bool ric_client::handle_reset_response(reset_resp_s& reset_response)
{
printf("Received E2AP E2 Reset Response \n");
// call process to handle reset reponse, if it fails log error, else return true - success
// all processing of message will be done in process_reset_response (e2ap.cc)
if (e2ap_.process_reset_response(reset_response)) {
logger.error("Failed to process E2 Reset Response \n");
return false;
}
logger.info("Reset Response successfully processed \n");
return true;
}

@ -142,6 +142,7 @@ void test_native_e2ap_subscription_response()
e2ap e2ap_(logger, &dummy_metrics);
pdu = e2ap_.generate_subscription_response();
pdu = e2ap_.generate_subscription_response();
asn1::bit_ref bref(buf->msg, buf->get_tailroom());
if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) {
printf("Failed to pack TX E2 PDU\n");
@ -149,17 +150,58 @@ void test_native_e2ap_subscription_response()
}
asn1::cbit_ref bref2(buf->msg, buf->get_tailroom());
asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2);
TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret);
printf("Unpacked native E2AP PDU (subscription response) %d\n", (int)unpack_ret);
}
void test_native_e2ap_reset_request()
{
srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer();
e2_ap_pdu_c pdu, pdu2;
e2ap e2ap_;
pdu = e2ap_.generate_reset_request();
asn1::bit_ref bref(buf->msg, buf->get_tailroom());
if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) {
printf("Failed to pack TX E2 PDU\n");
return;
}
asn1::cbit_ref bref2(buf->msg, buf->get_tailroom());
asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2);
TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret);
printf("Unpacked native E2AP PDU RESET %d\n", (int)unpack_ret);
}
void test_native_e2ap_reset_response()
{
srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer();
e2_ap_pdu_c pdu, pdu2;
e2ap e2ap_;
pdu = e2ap_.generate_reset_response();
asn1::bit_ref bref(buf->msg, buf->get_tailroom());
if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) {
printf("Failed to pack TX E2 PDU\n");
return;
}
asn1::cbit_ref bref2(buf->msg, buf->get_tailroom());
asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2);
TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret);
printf("Unpacked native E2AP PDU RESET RESPONSE %d\n", (int)unpack_ret);
}
// add tets for set-up request and response
int main()
{
test_reference_e2ap_setup_request();
test_native_e2ap_setup_request();
test_reference_e2ap_subscription_request();
test_native_e2ap_subscription_response();
test_native_e2ap_reset_request();
test_native_e2ap_reset_response();
// call reset test functions here
return 0;
}
Loading…
Cancel
Save