First commit
This commit is contained in:
BIN
setup/xapp-bs-connector/src/.routes.txt.swp
Normal file
BIN
setup/xapp-bs-connector/src/.routes.txt.swp
Normal file
Binary file not shown.
79
setup/xapp-bs-connector/src/Makefile
Executable file
79
setup/xapp-bs-connector/src/Makefile
Executable file
@@ -0,0 +1,79 @@
|
||||
CXX:= g++ --std=c++14 -O2 -L/usr/local/lib
|
||||
CC:= gcc -O2 -L/usr/local/lib
|
||||
|
||||
SRC:=./
|
||||
HWSRC:=./
|
||||
UTILSRC=./xapp-utils
|
||||
MSGSRC:=./xapp-mgmt
|
||||
|
||||
ASNSRC:=../asn1c_defs
|
||||
E2APSRC:=./xapp-asn/e2ap
|
||||
E2SMSRC:=./xapp-asn/e2sm
|
||||
|
||||
####### Logging library and flags
|
||||
CLOGFLAGS:= `pkg-config mdclog --cflags`
|
||||
LOG_LIBS:= `pkg-config mdclog --libs`
|
||||
CURL_LIBS:= `pkg-config libcurl --libs`
|
||||
RNIB_LIBS:= -pthread /usr/local/include/rnib/rnibreader.a
|
||||
######## Keep include dirs separate so we have transparency
|
||||
|
||||
|
||||
BASEFLAGS= -Wall -std=c++14 $(CLOGFLAGS)
|
||||
C_BASEFLAGS= -Wall $(CLOGFLAGS) -DASN_DISABLE_OER_SUPPORT
|
||||
|
||||
XAPPFLAGS= -I./
|
||||
HWFLAGS= -I./
|
||||
UTILFLAGS= -I$(UTILSRC)
|
||||
MSGFLAGS= -I$(MSGSRC)
|
||||
|
||||
ASNFLAGS=-I$(ASNSRC) -DASN_DISABLE_OER_SUPPORT
|
||||
E2APFLAGS = -I$(E2APSRC)
|
||||
E2SMFLAGS = -I$(E2SMSRC)
|
||||
|
||||
########libs
|
||||
|
||||
LIBS= -lsdl -lrmr_si -lpthread -lm $(LOG_LIBS) $(CURL_LIBS) $(RNIB_LIBS)
|
||||
COV_FLAGS= -fprofile-arcs -ftest-coverage
|
||||
|
||||
#######
|
||||
HWXAPP_SRC= hw_xapp_main.cc
|
||||
XAPP_SRC= xapp.cc
|
||||
UTIL_SRC= $(wildcard $(UTILSRC)/*.cc)
|
||||
MSG_SRC= $(wildcard $(MSGSRC)/*.cc)
|
||||
|
||||
E2AP_SRC= $(wildcard $(E2APSRC)/*.cc)
|
||||
E2SM_SRC= $(wildcard $(E2SMSRC)/*.cc)
|
||||
ASN1C_SRC= $(wildcard $(ASNSRC)/*.c)
|
||||
|
||||
##############Objects
|
||||
UTIL_OBJ=${UTIL_SRC:.cc=.o}
|
||||
XAPP_OBJ=${XAPP_SRC:.cc=.o}
|
||||
HWXAPP_OBJ= ${HWXAPP_SRC:.cc=.o}
|
||||
MSG_OBJ= ${MSG_SRC:.cc=.o}
|
||||
|
||||
E2AP_OBJ = $(E2AP_SRC:.cc=.o)
|
||||
E2SM_OBJ = $(E2SM_SRC:.cc=.o)
|
||||
ASN1C_MODULES = $(ASN1C_SRC:.c=.o)
|
||||
|
||||
$(ASN1C_MODULES): export CFLAGS = $(C_BASEFLAGS) $(ASNFLAGS)
|
||||
$(UTIL_OBJ):export CPPFLAGS=$(BASEFLAGS) $(UTILFLAGS) $(E2APFLAGS) $(E2SMFLAGS) $(ASNFLAGS) $(MSGFLAGS)
|
||||
|
||||
$(MSG_OBJ):export CPPFLAGS=$(BASEFLAGS) $(MSGFLAGS) $(ASNFLAGS) $(E2APFLAGS) $(E2SMFLAGS)
|
||||
$(E2AP_OBJ): export CPPFLAGS = $(BASEFLAGS) $(ASNFLAGS) $(E2APFLAGS)
|
||||
$(E2SM_OBJ): export CPPFLAGS = $(BASEFLAGS) $(ASNFLAGS) $(E2SMFLAGS)
|
||||
$(XAPP_OBJ): export CPPFLAGS = $(BASEFLAGS) $(XAPPFLAGS) $(UTILFLAGS) $(MSGFLAGS) $(E2APFLAGS) $(E2SMFLAGS) $(ASNFLAGS)
|
||||
|
||||
$(HWXAPP_OBJ):export CPPFLAGS=$(BASEFLAGS) $(HWFLAGS) $(XAPPFLAGS) $(UTILFLAGS) $(MSGFLAGS) $(E2APFLAGS) $(E2SMFLAGS) $(ASNFLAGS)
|
||||
|
||||
OBJ= $(HWXAPP_OBJ) $(UTIL_OBJ) $(MSG_OBJ) $(ASN1C_MODULES) $(E2AP_OBJ) $(E2SM_OBJ) $(XAPP_OBJ)
|
||||
|
||||
print-% : ; @echo $* = $($*)
|
||||
|
||||
hw_xapp_main: $(OBJ)
|
||||
$(CXX) -o $@ $(OBJ) $(LIBS) $(RNIBFLAGS) $(CPPFLAGS) $(CLOGFLAGS) agent_connector.cc
|
||||
|
||||
install: hw_xapp_main
|
||||
install -D hw_xapp_main /usr/local/bin/hw_xapp_main
|
||||
|
||||
clean:
|
||||
-rm *.o $(ASNSRC)/*.o $(E2APSRC)/*.o $(UTILSRC)/*.o $(E2SMSRC)/*.o $(MSGSRC)/*.o $(SRC)/*.o hw_xapp_main
|
34
setup/xapp-bs-connector/src/README
Normal file
34
setup/xapp-bs-connector/src/README
Normal file
@@ -0,0 +1,34 @@
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
|
||||
This repository consists of HelloWorld Xapp developed in C++. Its envisioned to be the most simplest example Xapp.
|
||||
It is required to have following features
|
||||
|
||||
1) E2 Subscription Handling
|
||||
2) A1 Policy Handling
|
||||
3) SDL Access
|
||||
4) Health Check
|
||||
5)...
|
||||
|
||||
|
||||
|
||||
|
||||
Steps for installation/running HWXapp.
|
||||
|
||||
$ source ./run_xapp.sh
|
||||
$ make
|
||||
$ ./hw_xapp_main
|
141
setup/xapp-bs-connector/src/agent_connector.cc
Normal file
141
setup/xapp-bs-connector/src/agent_connector.cc
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "agent_connector.hpp"
|
||||
|
||||
|
||||
// open client of control socket with agent
|
||||
int open_control_socket_agent(const char* dest_ip, const int dest_port) {
|
||||
|
||||
std::cout << "Opening control socket with host " << dest_ip << ":" << dest_port << std::endl;
|
||||
|
||||
int control_sckfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (control_sckfd < 0) {
|
||||
std::cout << "ERROR: OPEN SOCKET" << std::endl;
|
||||
close(control_sckfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// SET SOCKET OPTIONS TO RELEASE THE SOCKET ADDRESS IMMEDIATELY AFTER
|
||||
// THE SOCKET IS CLOSED
|
||||
int option(1);
|
||||
setsockopt(control_sckfd, SOL_SOCKET, SO_REUSEADDR, (char*)&option, sizeof(option));
|
||||
|
||||
struct sockaddr_in dest_addr = {0};
|
||||
dest_addr.sin_family = AF_INET;
|
||||
dest_addr.sin_port = htons(dest_port);
|
||||
|
||||
// convert dest_ip from char* to network address
|
||||
if (inet_pton(AF_INET, dest_ip, &dest_addr.sin_addr) <= 0) {
|
||||
std::cout << "ERROR CONVERTING IP TO INTERNET ADDR" << std::endl;
|
||||
close(control_sckfd); // if conversion fail, close the socket and return error -2
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (connect(control_sckfd, (struct sockaddr *) &dest_addr, sizeof(dest_addr)) < 0) {
|
||||
std::cout << "ERROR: CONNECT" << std::endl;
|
||||
close(control_sckfd);
|
||||
return -3;
|
||||
}
|
||||
|
||||
// update map
|
||||
std::string agent_ip;
|
||||
agent_ip.assign(dest_ip);
|
||||
// std::cout << "Agent IP " << agent_ip << std::endl;
|
||||
agentIp_socket[agent_ip] = control_sckfd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// close control sockets
|
||||
void close_control_socket_agent(void) {
|
||||
|
||||
std::cout << "Closing control sockets with agent(s)" << std::endl;
|
||||
|
||||
std::map<std::string, int>::iterator it;
|
||||
for (it = agentIp_socket.begin(); it != agentIp_socket.end(); ++it) {
|
||||
std::string agent_ip = it->first;
|
||||
int control_sckfd = it->second;
|
||||
|
||||
close(control_sckfd);
|
||||
}
|
||||
|
||||
// clear maps
|
||||
std::cout << "Clearing maps" << std::endl;
|
||||
agentIp_socket.clear();
|
||||
agentIp_gnbId.clear();
|
||||
}
|
||||
|
||||
|
||||
// find agent IP of socket to use with gNB id
|
||||
std::string find_agent_ip_from_gnb(unsigned char* gnb_id_trans) {
|
||||
|
||||
std::map<std::string, int>::iterator it_sck;
|
||||
std::map<std::string, std::string>::iterator it_gnb;
|
||||
std::string agent_ip;
|
||||
|
||||
// convert transaction identifier (unsigned char*) to string
|
||||
std::string gnb_id(reinterpret_cast<char*>(gnb_id_trans));
|
||||
|
||||
// check if gnb_id is already in agentIp_gnbId map
|
||||
bool found = false;
|
||||
for (it_gnb = agentIp_gnbId.begin(); it_gnb != agentIp_gnbId.end(); ++it_gnb) {
|
||||
if (gnb_id.compare(it_gnb->second) == 0) {
|
||||
agent_ip = it_gnb->first;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// check if agent_ip is already in agentIp_gnbId map
|
||||
for (it_sck = agentIp_socket.begin(); it_sck != agentIp_socket.end(); ++it_sck) {
|
||||
agent_ip = it_sck->first;
|
||||
|
||||
it_gnb = agentIp_gnbId.find(agent_ip);
|
||||
if (it_gnb == agentIp_gnbId.end()) {
|
||||
// insert into agentIp_gnbId map
|
||||
agentIp_gnbId[agent_ip] = gnb_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return agent_ip;
|
||||
}
|
||||
|
||||
|
||||
// send through socket
|
||||
int send_socket(char* buf, std::string dest_ip) {
|
||||
|
||||
int control_sckfd = -1;
|
||||
|
||||
// get socket file descriptor
|
||||
std::map<std::string, int>::iterator it;
|
||||
for (it = agentIp_socket.begin(); it != agentIp_socket.end(); ++it) {
|
||||
std::string agent_ip = it->first;
|
||||
|
||||
if (dest_ip.compare(agent_ip) == 0) {
|
||||
control_sckfd = it->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (control_sckfd == -1) {
|
||||
std::cout << "ERROR: Could not find socket for destination " << dest_ip << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// const size_t max_size = 512;
|
||||
// char buf[max_size] = "Hello, Server!"; // store the data in a buffer
|
||||
size_t data_size = strlen(buf);
|
||||
int sent_size = send(control_sckfd ,buf, data_size, 0);
|
||||
|
||||
if(sent_size < 0) { // the send returns a size of -1 in case of errors
|
||||
std::cout << "ERROR: SEND to agent " << dest_ip << std::endl;
|
||||
return -2;
|
||||
}
|
||||
else {
|
||||
std::cout << "Message sent" << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
32
setup/xapp-bs-connector/src/agent_connector.hpp
Normal file
32
setup/xapp-bs-connector/src/agent_connector.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
#ifndef AGENT_CONNECTOR_HPP_
|
||||
#define AGENT_CONNECTOR_HPP_
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#define AGENT_0 "127.0.0.1"
|
||||
|
||||
// vector of agent IPs
|
||||
extern std::vector<std::string> drl_agent_ip;
|
||||
|
||||
// key: DRL agent IP, value: socket file descriptor
|
||||
extern std::map<std::string, int> agentIp_socket;
|
||||
|
||||
// key: DRL agent IP, value: gNB id
|
||||
extern std::map<std::string, std::string> agentIp_gnbId;
|
||||
|
||||
int open_control_socket_agent(const char* dest_ip, const int dest_port);
|
||||
void close_control_socket_agent(void);
|
||||
std::string find_agent_ip_from_gnb(unsigned char* gnb_id);
|
||||
int send_socket(char* buf, std::string dest_ip);
|
||||
|
||||
#endif
|
97
setup/xapp-bs-connector/src/hw_xapp_main.cc
Normal file
97
setup/xapp-bs-connector/src/hw_xapp_main.cc
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* hw_xapp_main.cc
|
||||
* Created on: Dec, 2019
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
|
||||
#include "xapp.hpp"
|
||||
#include <thread>
|
||||
|
||||
void signalHandler( int signum ) {
|
||||
cout << "Interrupt signal (" << signum << ") received.\n";
|
||||
exit(signum);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
|
||||
// Get the thread id
|
||||
std::thread::id my_id = std::this_thread::get_id();
|
||||
std::stringstream thread_id;
|
||||
std::stringstream ss;
|
||||
|
||||
thread_id << my_id;
|
||||
|
||||
mdclog_write(MDCLOG_INFO, "Starting thread %s", thread_id.str().c_str());
|
||||
|
||||
//get configuration
|
||||
XappSettings config;
|
||||
//change the priority depending upon application requirement
|
||||
config.loadDefaultSettings();
|
||||
config.loadEnvVarSettings();
|
||||
config.loadCmdlineSettings(argc, argv);
|
||||
|
||||
//Register signal handler to stop
|
||||
signal(SIGINT, signalHandler);
|
||||
signal(SIGTERM, signalHandler);
|
||||
|
||||
//getting the listening port and xapp name info
|
||||
std::string port = config[XappSettings::SettingName::HW_PORT];
|
||||
std::string name = config[XappSettings::SettingName::XAPP_NAME];
|
||||
|
||||
//initialize rmr
|
||||
std::unique_ptr<XappRmr> rmr = std::make_unique<XappRmr>(port);
|
||||
rmr->xapp_rmr_init(true);
|
||||
|
||||
|
||||
//Create Subscription Handler if Xapp deals with Subscription.
|
||||
std::unique_ptr<SubscriptionHandler> sub_handler = std::make_unique<SubscriptionHandler>();
|
||||
|
||||
//create HelloWorld Xapp Instance.
|
||||
std::unique_ptr<Xapp> hw_xapp;
|
||||
hw_xapp = std::make_unique<Xapp>(std::ref(config),std::ref(*rmr));
|
||||
|
||||
mdclog_write(MDCLOG_INFO, "Created Hello World Xapp Instance");
|
||||
|
||||
sleep(1);
|
||||
//Startup E2 subscription and A1 policy
|
||||
//hw_xapp->startup(std::ref(*sub_handler));
|
||||
|
||||
//start listener threads and register message handlers.
|
||||
int num_threads = std::stoi(config[XappSettings::SettingName::THREADS]);
|
||||
mdclog_write(MDCLOG_INFO, "Starting Listener Threads. Number of Workers = %d", num_threads);
|
||||
|
||||
std::unique_ptr<XappMsgHandler> mp_handler = std::make_unique<XappMsgHandler>(config[XappSettings::SettingName::XAPP_ID], std::ref(*sub_handler));
|
||||
hw_xapp->start_xapp_receiver(std::ref(*mp_handler));
|
||||
|
||||
sleep(1);
|
||||
|
||||
hw_xapp->startup(std::ref(*sub_handler));
|
||||
|
||||
//xapp->shutdown();
|
||||
|
||||
while(1){
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
13
setup/xapp-bs-connector/src/routes.txt
Executable file
13
setup/xapp-bs-connector/src/routes.txt
Executable file
@@ -0,0 +1,13 @@
|
||||
newrt|start
|
||||
rte|100|127.0.0.1:4560
|
||||
rte|101|127.0.0.1:4560
|
||||
rte|20010|127.0.0.1:4560
|
||||
rte|20011|127.0.0.1:4560
|
||||
rte|20012|127.0.0.1:4560
|
||||
rte|12010|127.0.0.1:4560
|
||||
rte|12011|127.0.0.1:4560
|
||||
rte|12012|127.0.0.1:4560
|
||||
rte|12020|127.0.0.1:4560
|
||||
rte|12021|127.0.0.1:4560
|
||||
rte|12022|127.0.0.1:4560
|
||||
newrt|end
|
21
setup/xapp-bs-connector/src/run_xapp.sh
Executable file
21
setup/xapp-bs-connector/src/run_xapp.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#! /bin/bash
|
||||
|
||||
export RMR_SEED_RT="routes.txt"
|
||||
export RMR_RTG_SVC="9999"
|
||||
export XAPP_NAME="HELLOWORLD_XAPP"
|
||||
export HW_PORTS="4560"
|
||||
export MSG_MAX_BUFFER="2048"
|
||||
export THREADS="1"
|
||||
export VERBOSE="0"
|
||||
export CONFIG_FILE="config/config-file.json"
|
||||
export GNODEB="NYC123"
|
||||
export XAPP_ID="3489-er492k-92389"
|
||||
export A1_SCHEMA_FILE="schemas/hwxapp-policy.json"
|
||||
export VES_SCHEMA_FILE="schemas/hwxapp-ves.json"
|
||||
export VES_COLLECTOR_URL="127.0.0.1:6350"
|
||||
export VES_MEASUREMENT_INTERVAL="10"
|
||||
export LOG_LEVEL="MDCLOG_ERR"
|
||||
export OPERATING_MODE="CONTROL"
|
||||
|
||||
|
||||
|
266
setup/xapp-bs-connector/src/xapp-asn/e2ap/e2ap_control.cc
Normal file
266
setup/xapp-bs-connector/src/xapp-asn/e2ap/e2ap_control.cc
Normal file
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_control_request.c
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#include "e2ap_control.hpp"
|
||||
|
||||
// Set up memory allocations for each IE for encoding
|
||||
// We are responsible for memory management for each IE for encoding
|
||||
// Hence destructor should clear out memory
|
||||
// When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
|
||||
// for releasing memory by external calling function)
|
||||
ric_control_request::ric_control_request(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
initMsg = 0;
|
||||
initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
|
||||
assert(initMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (RICcontrolRequest_IEs_t *)calloc(NUM_CONTROL_REQUEST_IES, sizeof(RICcontrolRequest_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
|
||||
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC control_request IE container
|
||||
ric_control_request::~ric_control_request(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Control Request object memory");
|
||||
|
||||
RICcontrolRequest_t *ricControl_Request = &(initMsg->value.choice.RICcontrolRequest);
|
||||
for(int i = 0; i < ricControl_Request->protocolIEs.list.size; i++){
|
||||
ricControl_Request->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (ricControl_Request->protocolIEs.list.size > 0){
|
||||
free(ricControl_Request->protocolIEs.list.array);
|
||||
ricControl_Request->protocolIEs.list.size = 0;
|
||||
ricControl_Request->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(initMsg);
|
||||
e2ap_pdu_obj->choice.initiatingMessage = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed E2AP Control Request object mempory");
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ric_control_request::encode_e2ap_control_request(unsigned char *buf, size_t *size, ric_control_helper & dinput){
|
||||
|
||||
initMsg->procedureCode = ProcedureCode_id_RICcontrol;
|
||||
initMsg->criticality = Criticality_ignore;
|
||||
initMsg->value.present = InitiatingMessage__value_PR_RICcontrolRequest;
|
||||
|
||||
bool res;
|
||||
|
||||
res = set_fields(initMsg, dinput);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding control . Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding event trigger definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ric_control_request::set_fields(InitiatingMessage_t *initMsg, ric_control_helper &dinput){
|
||||
unsigned int ie_index;
|
||||
|
||||
if (initMsg == 0){
|
||||
error_string = "Invalid reference for E2AP Control_Request message in set_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
RICcontrolRequest_t * ric_control_request = &(initMsg->value.choice.RICcontrolRequest);
|
||||
ric_control_request->protocolIEs.list.count = 0; // reset
|
||||
|
||||
// for(i = 0; i < NUM_CONTROL_REQUEST_IES;i++){
|
||||
// memset(&(IE_array[i]), 0, sizeof(RICcontrolRequest_IEs_t));
|
||||
// }
|
||||
|
||||
// Mandatory IE
|
||||
ie_index = 0;
|
||||
RICcontrolRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICcontrolRequest_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = dinput.req_id;
|
||||
//ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
// Mandatory IE
|
||||
ie_index = 1;
|
||||
RICcontrolRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICcontrolRequest_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = dinput.func_id;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
|
||||
// Mandatory IE
|
||||
ie_index = 2;
|
||||
RICcontrolRequest_IEs_t *ies_richead = &IE_array[ie_index];
|
||||
ies_richead->criticality = Criticality_reject;
|
||||
ies_richead->id = ProtocolIE_ID_id_RICcontrolHeader;
|
||||
ies_richead->value.present = RICcontrolRequest_IEs__value_PR_RICcontrolHeader;
|
||||
RICcontrolHeader_t *richeader_ie = &ies_richead->value.choice.RICcontrolHeader;
|
||||
richeader_ie->buf = dinput.control_header;
|
||||
richeader_ie->size = dinput.control_header_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
// Mandatory IE
|
||||
ie_index = 3;
|
||||
RICcontrolRequest_IEs_t *ies_indmsg = &IE_array[ie_index];
|
||||
ies_indmsg->criticality = Criticality_reject;
|
||||
ies_indmsg->id = ProtocolIE_ID_id_RICcontrolMessage;
|
||||
ies_indmsg->value.present = RICcontrolRequest_IEs__value_PR_RICcontrolMessage;
|
||||
RICcontrolMessage_t *ricmsg_ie = &ies_indmsg->value.choice.RICcontrolMessage;
|
||||
ricmsg_ie->buf = dinput.control_msg;
|
||||
ricmsg_ie->size = dinput.control_msg_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
// Optional IE
|
||||
ie_index = 4;
|
||||
if (dinput.control_ack >= 0){
|
||||
RICcontrolRequest_IEs_t *ies_indtyp = &IE_array[ie_index];
|
||||
ies_indtyp->criticality = Criticality_reject;
|
||||
ies_indtyp->id = ProtocolIE_ID_id_RICcontrolAckRequest;
|
||||
ies_indtyp->value.present = RICcontrolRequest_IEs__value_PR_RICcontrolAckRequest;
|
||||
RICcontrolAckRequest_t *ricackreq_ie = &ies_indtyp->value.choice.RICcontrolAckRequest;
|
||||
*ricackreq_ie = dinput.control_ack;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
}
|
||||
|
||||
// Optional IE
|
||||
ie_index = 5;
|
||||
if(dinput.call_process_id_size > 0){
|
||||
RICcontrolRequest_IEs_t *ies_callprocid = &IE_array[ie_index];
|
||||
ies_callprocid->criticality = Criticality_reject;
|
||||
ies_callprocid->id = ProtocolIE_ID_id_RICcallProcessID;
|
||||
ies_callprocid->value.present = RICcontrolRequest_IEs__value_PR_RICcallProcessID;
|
||||
RICcallProcessID_t *riccallprocessid_ie = &ies_callprocid->value.choice.RICcallProcessID;
|
||||
riccallprocessid_ie->buf = dinput.call_process_id;
|
||||
riccallprocessid_ie->size = dinput.call_process_id_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool ric_control_request:: get_fields(InitiatingMessage_t * init_msg, ric_control_helper &dout)
|
||||
{
|
||||
if (init_msg == 0){
|
||||
error_string = "Invalid reference for E2AP Control_Request message in get_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for(int edx = 0; edx < init_msg->value.choice.RICcontrolRequest.protocolIEs.list.count; edx++) {
|
||||
RICcontrolRequest_IEs_t *memb_ptr = init_msg->value.choice.RICcontrolRequest.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (ProtocolIE_ID_id_RICcontrolHeader):
|
||||
dout.control_header = memb_ptr->value.choice.RICcontrolHeader.buf;
|
||||
dout.control_header_size = memb_ptr->value.choice.RICcontrolHeader.size;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICcontrolMessage):
|
||||
dout.control_msg = memb_ptr->value.choice.RICcontrolMessage.buf;
|
||||
dout.control_msg_size = memb_ptr->value.choice.RICcontrolMessage.size;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICcallProcessID):
|
||||
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
|
||||
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
|
||||
//dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
dout.func_id = memb_ptr->value.choice.RANfunctionID;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICcontrolAckRequest):
|
||||
dout.control_ack = memb_ptr->value.choice.RICcontrolAckRequest;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
InitiatingMessage_t * ric_control_request::get_message(void) {
|
||||
return initMsg;
|
||||
}
|
66
setup/xapp-bs-connector/src/xapp-asn/e2ap/e2ap_control.hpp
Normal file
66
setup/xapp-bs-connector/src/xapp-asn/e2ap/e2ap_control.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#ifndef E2AP_RIC_CONTROL_REQUEST_H_
|
||||
#define E2AP_RIC_CONTROL_REQUEST_H_
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <sstream>
|
||||
#include <E2AP-PDU.h>
|
||||
#include <InitiatingMessage.h>
|
||||
#include <RICcontrolRequest.h>
|
||||
#include <ProtocolIE-Field.h>
|
||||
#include "e2ap_control_helper.hpp"
|
||||
|
||||
#define NUM_CONTROL_REQUEST_IES 6
|
||||
|
||||
|
||||
class ric_control_request{
|
||||
|
||||
public:
|
||||
ric_control_request(void);
|
||||
~ric_control_request(void);
|
||||
|
||||
bool encode_e2ap_control_request(unsigned char *, size_t *, ric_control_helper &);
|
||||
InitiatingMessage_t * get_message (void) ;
|
||||
bool set_fields(InitiatingMessage_t *, ric_control_helper &);
|
||||
bool get_fields(InitiatingMessage_t *, ric_control_helper &);
|
||||
std::string get_error(void) const {return error_string ; };
|
||||
private:
|
||||
|
||||
E2AP_PDU_t * e2ap_pdu_obj;
|
||||
InitiatingMessage_t *initMsg;
|
||||
RICcontrolRequest_IEs_t *IE_array;
|
||||
std::string error_string;
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
};
|
||||
|
||||
|
||||
#endif /* E2AP_RIC_CONTROL_REQUEST_H_ */
|
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#ifndef CONTROL_HELPER_H
|
||||
#define CONTROL_HELPER_H
|
||||
|
||||
// control and indication helper objects are very similar and can be merged into one
|
||||
// currently leaving them as two distnict entities till final design becomes clear
|
||||
|
||||
typedef struct ric_control_helper ric_control_helper;
|
||||
|
||||
struct ric_control_helper{
|
||||
ric_control_helper(void):req_id(1), req_seq_no(1), func_id(0), action_id(1), control_ack(-1), cause(0), sub_cause(0), control_status(1), control_msg(0), control_msg_size(0), control_header(0), control_header_size(0), call_process_id(0), call_process_id_size(0){};
|
||||
|
||||
long int req_id, req_seq_no, func_id, action_id, control_ack, cause, sub_cause, control_status;
|
||||
|
||||
unsigned char* control_msg;
|
||||
size_t control_msg_size;
|
||||
|
||||
unsigned char* control_header;
|
||||
size_t control_header_size;
|
||||
|
||||
unsigned char *call_process_id;
|
||||
size_t call_process_id_size;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_control_response.c
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#include "e2ap_control_response.hpp"
|
||||
|
||||
// Set up the initiating message and also allocate protocolIEs in container
|
||||
// Note : this bypasses requirement to use ASN_SEQUENCE_ADD. We can directly
|
||||
// assign pointers to the array in ProtocolIE. However, this also leaves us on the
|
||||
// hook to manually clear the memory
|
||||
|
||||
ric_control_response::ric_control_response(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
successMsg = 0;
|
||||
successMsg = (SuccessfulOutcome_t * )calloc(1, sizeof(SuccessfulOutcome_t));
|
||||
assert(successMsg != 0);
|
||||
|
||||
successMsg->procedureCode = ProcedureCode_id_RICcontrol;
|
||||
successMsg->criticality = Criticality_reject;
|
||||
successMsg->value.present = SuccessfulOutcome__value_PR_RICcontrolAcknowledge;
|
||||
|
||||
|
||||
unsuccessMsg = 0;
|
||||
unsuccessMsg = (UnsuccessfulOutcome_t * )calloc(1, sizeof(UnsuccessfulOutcome_t));
|
||||
assert(unsuccessMsg != 0);
|
||||
|
||||
|
||||
unsuccessMsg->procedureCode = ProcedureCode_id_RICcontrol;
|
||||
unsuccessMsg->criticality = Criticality_reject;
|
||||
unsuccessMsg->value.present = UnsuccessfulOutcome__value_PR_RICcontrolFailure;
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (RICcontrolAcknowledge_IEs_t *)calloc(NUM_CONTROL_ACKNOWLEDGE_IES, sizeof(RICcontrolAcknowledge_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
|
||||
for(int i = 0; i < NUM_CONTROL_ACKNOWLEDGE_IES; i++){
|
||||
ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), &(IE_array[i]));
|
||||
}
|
||||
|
||||
|
||||
IE_failure_array = 0;
|
||||
IE_failure_array = (RICcontrolFailure_IEs_t *)calloc(NUM_CONTROL_FAILURE_IES, sizeof(RICcontrolFailure_IEs_t));
|
||||
assert(IE_failure_array != 0);
|
||||
|
||||
RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
|
||||
for(int i = 0; i < NUM_CONTROL_FAILURE_IES; i++){
|
||||
ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), &(IE_failure_array[i]));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC control_request IE container
|
||||
ric_control_response::~ric_control_response(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Control Response object memory");
|
||||
|
||||
RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
|
||||
for(int i = 0; i < ric_acknowledge->protocolIEs.list.size; i++){
|
||||
ric_acknowledge->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
if (ric_acknowledge->protocolIEs.list.size > 0){
|
||||
free(ric_acknowledge->protocolIEs.list.array);
|
||||
ric_acknowledge->protocolIEs.list.array = 0;
|
||||
ric_acknowledge->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
|
||||
for(int i = 0; i < ric_failure->protocolIEs.list.size; i++){
|
||||
ric_failure->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
if (ric_failure->protocolIEs.list.size > 0){
|
||||
free(ric_failure->protocolIEs.list.array);
|
||||
ric_failure->protocolIEs.list.array = 0;
|
||||
ric_failure->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(IE_failure_array);
|
||||
free(successMsg);
|
||||
free(unsuccessMsg);
|
||||
|
||||
e2ap_pdu_obj->choice.initiatingMessage = 0;
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed E2AP Control Response object mempory");
|
||||
}
|
||||
|
||||
|
||||
bool ric_control_response::encode_e2ap_control_response(unsigned char *buf, size_t *size, ric_control_helper & dinput, bool is_success){
|
||||
|
||||
bool res;
|
||||
if (is_success){
|
||||
res = set_fields(successMsg, dinput);
|
||||
}
|
||||
else{
|
||||
res = set_fields(unsuccessMsg, dinput);
|
||||
}
|
||||
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (is_success){
|
||||
e2ap_pdu_obj->choice.successfulOutcome = successMsg;
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_successfulOutcome ;
|
||||
}
|
||||
else{
|
||||
e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_unsuccessfulOutcome ;
|
||||
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding control response. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding E2AP Control response . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ric_control_response::set_fields(SuccessfulOutcome_t *successMsg, ric_control_helper &dinput){
|
||||
unsigned int ie_index;
|
||||
|
||||
if (successMsg == 0){
|
||||
error_string = "Invalid reference for E2AP Control Acknowledge in set_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
// for(i = 0; i < NUM_CONTROL_ACKNOWLEDGE_IES;i++){
|
||||
// memset(&(IE_array[i]), 0, sizeof(RICcontrolAcknowledge_IEs_t));
|
||||
// }
|
||||
|
||||
//RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
|
||||
//ric_acknowledge->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
RICcontrolAcknowledge_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICcontrolAcknowledge_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = dinput.req_id;
|
||||
//ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
|
||||
//ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ricreq);
|
||||
|
||||
ie_index = 1;
|
||||
RICcontrolAcknowledge_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICcontrolAcknowledge_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = dinput.func_id;
|
||||
//ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ranfunc);
|
||||
|
||||
// ie_index = 2;
|
||||
// RICcontrolAcknowledge_IEs_t *ies_riccallprocessid = &IE_array[ie_index];
|
||||
// ies_riccallprocessid->criticality = Criticality_reject;
|
||||
// ies_riccallprocessid->id = ProtocolIE_ID_id_RICcallProcessID;
|
||||
// ies_riccallprocessid->value.present = RICcontrolAcknowledge_IEs__value_PR_RICcallProcessID;
|
||||
// RICcallProcessID_t *riccallprocessid_ie = &ies_riccallprocessid->value.choice.RICcallProcessID;
|
||||
// riccallprocessid_ie->buf = dinput.call_process_id;
|
||||
// riccallprocessid_ie->size = dinput.call_process_id_size;
|
||||
// ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_riccallprocessid);
|
||||
|
||||
ie_index = 2;
|
||||
RICcontrolAcknowledge_IEs_t *ies_ric_cause = &IE_array[ie_index];
|
||||
ies_ric_cause->criticality = Criticality_reject;
|
||||
ies_ric_cause->id = ProtocolIE_ID_id_RICcontrolStatus;
|
||||
ies_ric_cause->value.present = RICcontrolAcknowledge_IEs__value_PR_RICcontrolStatus;
|
||||
ies_ric_cause->value.choice.RICcontrolStatus = dinput.control_status;
|
||||
//ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ric_cause);
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
bool ric_control_response::set_fields(UnsuccessfulOutcome_t *unsuccessMsg, ric_control_helper &dinput){
|
||||
unsigned int ie_index;
|
||||
|
||||
if (unsuccessMsg == 0){
|
||||
error_string = "Invalid reference for E2AP Control Failure in set_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
// for(i = 0; i < NUM_CONTROL_FAILURE_IES;i++){
|
||||
// memset(&(IE_failure_array[i]), 0, sizeof(RICcontrolFailure_IEs_t));
|
||||
// }
|
||||
|
||||
//RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
|
||||
//ric_failure->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
RICcontrolFailure_IEs_t *ies_ricreq = &IE_failure_array[ie_index];
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICcontrolFailure_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &(ies_ricreq->value.choice.RICrequestID);
|
||||
ricrequest_ie->ricRequestorID = dinput.req_id;
|
||||
//ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
|
||||
//ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ricreq);
|
||||
|
||||
ie_index = 1;
|
||||
RICcontrolFailure_IEs_t *ies_ranfunc = &IE_failure_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICcontrolFailure_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &(ies_ranfunc->value.choice.RANfunctionID);
|
||||
*ranfunction_ie = dinput.func_id;
|
||||
//ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ranfunc);
|
||||
|
||||
// ie_index = 2;
|
||||
// RICcontrolFailure_IEs_t *ies_riccallprocessid = &IE_failure_array[i];
|
||||
// ies_riccallprocessid->criticality = Criticality_reject;
|
||||
// ies_riccallprocessid->id = ProtocolIE_ID_id_RICcallProcessID;
|
||||
// ies_riccallprocessid->value.present = RICcontrolFailure_IEs__value_PR_RICcallProcessID;
|
||||
// RICcallProcessID_t *riccallprocessid_ie = &(ies_riccallprocessid->value.choice.RICcallProcessID);
|
||||
// riccallprocessid_ie->buf = dinput.call_process_id;
|
||||
// riccallprocessid_ie->size = dinput.call_process_id_size;
|
||||
// ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_riccallprocessid);
|
||||
|
||||
ie_index = 2;
|
||||
RICcontrolFailure_IEs_t *ies_ric_cause = &IE_failure_array[ie_index];
|
||||
ies_ric_cause->criticality = Criticality_ignore;
|
||||
ies_ric_cause->id = ProtocolIE_ID_id_Cause;
|
||||
ies_ric_cause->value.present = RICcontrolFailure_IEs__value_PR_Cause;
|
||||
Cause_t * ric_cause = &(ies_ric_cause->value.choice.Cause);
|
||||
ric_cause->present = (Cause_PR)dinput.cause;
|
||||
|
||||
switch(dinput.cause){
|
||||
case Cause_PR_ricService:
|
||||
ric_cause->choice.ricService = dinput.sub_cause;
|
||||
break;
|
||||
case Cause_PR_transport:
|
||||
ric_cause->choice.transport = dinput.sub_cause;
|
||||
break;
|
||||
case Cause_PR_protocol:
|
||||
ric_cause->choice.protocol= dinput.sub_cause;
|
||||
break;
|
||||
case Cause_PR_misc:
|
||||
ric_cause->choice.misc = dinput.sub_cause;
|
||||
break;
|
||||
case Cause_PR_ricRequest:
|
||||
ric_cause->choice.ricRequest = dinput.sub_cause;
|
||||
break;
|
||||
default:
|
||||
std::cout <<"Error ! Illegal cause enum" << dinput.cause << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
//ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ric_cause);
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool ric_control_response:: get_fields(SuccessfulOutcome_t * success_msg, ric_control_helper &dout)
|
||||
{
|
||||
if (success_msg == 0){
|
||||
error_string = "Invalid reference for E2AP Control Acknowledge message in get_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for(int edx = 0; edx < success_msg->value.choice.RICcontrolAcknowledge.protocolIEs.list.count; edx++) {
|
||||
RICcontrolAcknowledge_IEs_t *memb_ptr = success_msg->value.choice.RICcontrolAcknowledge.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
|
||||
case (ProtocolIE_ID_id_RICcallProcessID):
|
||||
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
|
||||
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
|
||||
//dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
dout.func_id = memb_ptr->value.choice.RANfunctionID;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_Cause):
|
||||
dout.control_status = memb_ptr->value.choice.RICcontrolStatus;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ric_control_response:: get_fields(UnsuccessfulOutcome_t * unsuccess_msg, ric_control_helper &dout)
|
||||
{
|
||||
if (unsuccess_msg == 0){
|
||||
error_string = "Invalid reference for E2AP Control Failure message in get_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for(int edx = 0; edx < unsuccess_msg->value.choice.RICcontrolFailure.protocolIEs.list.count; edx++) {
|
||||
RICcontrolFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICcontrolFailure.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
|
||||
case (ProtocolIE_ID_id_RICcallProcessID):
|
||||
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
|
||||
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
|
||||
//dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
dout.func_id = memb_ptr->value.choice.RANfunctionID;
|
||||
break;
|
||||
|
||||
|
||||
case (ProtocolIE_ID_id_Cause):
|
||||
dout.cause = memb_ptr->value.choice.Cause.present;
|
||||
switch(dout.cause){
|
||||
case Cause_PR_ricService :
|
||||
dout.sub_cause = memb_ptr->value.choice.Cause.choice.ricService;
|
||||
break;
|
||||
|
||||
case Cause_PR_transport :
|
||||
dout.sub_cause = memb_ptr->value.choice.Cause.choice.transport;
|
||||
break;
|
||||
|
||||
case Cause_PR_protocol :
|
||||
dout.sub_cause = memb_ptr->value.choice.Cause.choice.protocol;
|
||||
break;
|
||||
|
||||
case Cause_PR_misc :
|
||||
dout.sub_cause = memb_ptr->value.choice.Cause.choice.misc;
|
||||
break;
|
||||
|
||||
case Cause_PR_ricRequest :
|
||||
dout.sub_cause = memb_ptr->value.choice.Cause.choice.ricRequest;
|
||||
break;
|
||||
|
||||
default:
|
||||
dout.sub_cause = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#ifndef E2AP_RIC_CONTROL_RESPONSE_H_
|
||||
#define E2AP_RIC_CONTROL_RESPONSE_H_
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <sstream>
|
||||
#include <E2AP-PDU.h>
|
||||
#include <SuccessfulOutcome.h>
|
||||
#include <UnsuccessfulOutcome.h>
|
||||
#include <RICcontrolAcknowledge.h>
|
||||
#include <RICcontrolFailure.h>
|
||||
#include <ProtocolIE-Field.h>
|
||||
#include "e2ap_control_helper.hpp"
|
||||
|
||||
#define NUM_CONTROL_ACKNOWLEDGE_IES 3
|
||||
#define NUM_CONTROL_FAILURE_IES 3
|
||||
|
||||
|
||||
class ric_control_response{
|
||||
|
||||
public:
|
||||
ric_control_response(void);
|
||||
~ric_control_response(void);
|
||||
|
||||
bool encode_e2ap_control_response(unsigned char *, size_t *, ric_control_helper &, bool);
|
||||
|
||||
|
||||
bool set_fields(SuccessfulOutcome_t *, ric_control_helper &);
|
||||
bool get_fields(SuccessfulOutcome_t *, ric_control_helper &);
|
||||
|
||||
bool set_fields(UnsuccessfulOutcome_t *, ric_control_helper &);
|
||||
bool get_fields(UnsuccessfulOutcome_t *, ric_control_helper &);
|
||||
|
||||
std::string get_error(void) const {return error_string ; };
|
||||
|
||||
private:
|
||||
|
||||
E2AP_PDU_t * e2ap_pdu_obj;
|
||||
SuccessfulOutcome_t * successMsg;
|
||||
UnsuccessfulOutcome_t * unsuccessMsg;
|
||||
|
||||
RICcontrolAcknowledge_IEs_t *IE_array;
|
||||
RICcontrolFailure_IEs_t *IE_failure_array;
|
||||
|
||||
std::string error_string;
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
};
|
||||
|
||||
|
||||
#endif /* E2AP_RIC_CONTROL_RESPONSE_H_ */
|
283
setup/xapp-bs-connector/src/xapp-asn/e2ap/e2ap_indication.cc
Normal file
283
setup/xapp-bs-connector/src/xapp-asn/e2ap/e2ap_indication.cc
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.c
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#include "e2ap_indication.hpp"
|
||||
|
||||
// Set up memory allocations for each IE for encoding
|
||||
// We are responsible for memory management for each IE for encoding
|
||||
// Hence destructor should clear out memory
|
||||
// When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
|
||||
// for releasing memory by external calling function)
|
||||
ric_indication::ric_indication(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
initMsg = 0;
|
||||
initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
|
||||
assert(initMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (RICindication_IEs_t *)calloc(NUM_INDICATION_IES, sizeof(RICindication_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
|
||||
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC indication IE container
|
||||
ric_indication::~ric_indication(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Indication object memory");
|
||||
RICindication_t *ricIndication = &(initMsg->value.choice.RICindication);
|
||||
for(int i = 0; i < ricIndication->protocolIEs.list.size; i++){
|
||||
ricIndication->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
if (ricIndication->protocolIEs.list.size > 0){
|
||||
free(ricIndication->protocolIEs.list.array);
|
||||
ricIndication->protocolIEs.list.array = 0;
|
||||
ricIndication->protocolIEs.list.count = 0;
|
||||
ricIndication->protocolIEs.list.size = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed E2AP Indication object mempory");
|
||||
}
|
||||
|
||||
|
||||
bool ric_indication::encode_e2ap_indication(unsigned char *buf, size_t *size, ric_indication_helper & dinput){
|
||||
|
||||
initMsg->procedureCode = ProcedureCode_id_RICindication;
|
||||
initMsg->criticality = Criticality_ignore;
|
||||
initMsg->value.present = InitiatingMessage__value_PR_RICindication;
|
||||
|
||||
bool res;
|
||||
asn_enc_rval_t retval;
|
||||
|
||||
res = set_fields(initMsg, dinput);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
error_string = "Error encoding E2AP Indication message. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
// std::cout <<"Constraint check ok ...." << std::endl;
|
||||
// xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding E2AP Indication . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ric_indication::set_fields(InitiatingMessage_t *initMsg, ric_indication_helper &dinput){
|
||||
unsigned int ie_index;
|
||||
|
||||
if (initMsg == 0){
|
||||
error_string = "Invalid reference for E2AP Indication message in set_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
RICindication_t * ric_indication = &(initMsg->value.choice.RICindication);
|
||||
ric_indication->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
|
||||
RICindication_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICindication_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = dinput.req_id;
|
||||
//ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 1;
|
||||
RICindication_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICindication_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = dinput.func_id;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 2;
|
||||
RICindication_IEs_t *ies_actid = &IE_array[ie_index];
|
||||
ies_actid->criticality = Criticality_reject;
|
||||
ies_actid->id = ProtocolIE_ID_id_RICactionID;
|
||||
ies_actid->value.present = RICindication_IEs__value_PR_RICactionID;
|
||||
RICactionID_t *ricaction_ie = &ies_actid->value.choice.RICactionID;
|
||||
*ricaction_ie = dinput.action_id;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 3;
|
||||
RICindication_IEs_t *ies_ricsn = &IE_array[ie_index];
|
||||
ies_ricsn->criticality = Criticality_reject;
|
||||
ies_ricsn->id = ProtocolIE_ID_id_RICindicationSN;
|
||||
ies_ricsn->value.present = RICindication_IEs__value_PR_RICindicationSN;
|
||||
RICindicationSN_t *ricsn_ie = &ies_ricsn->value.choice.RICindicationSN;
|
||||
*ricsn_ie = dinput.indication_sn;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
|
||||
ie_index = 4;
|
||||
RICindication_IEs_t *ies_indtyp = &IE_array[ie_index];
|
||||
ies_indtyp->criticality = Criticality_reject;
|
||||
ies_indtyp->id = ProtocolIE_ID_id_RICindicationType;
|
||||
ies_indtyp->value.present = RICindication_IEs__value_PR_RICindicationType;
|
||||
RICindicationType_t *rictype_ie = &ies_indtyp->value.choice.RICindicationType;
|
||||
*rictype_ie = dinput.indication_type;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 5;
|
||||
RICindication_IEs_t *ies_richead = &IE_array[ie_index];
|
||||
ies_richead->criticality = Criticality_reject;
|
||||
ies_richead->id = ProtocolIE_ID_id_RICindicationHeader;
|
||||
ies_richead->value.present = RICindication_IEs__value_PR_RICindicationHeader;
|
||||
RICindicationHeader_t *richeader_ie = &ies_richead->value.choice.RICindicationHeader;
|
||||
richeader_ie->buf = dinput.indication_header;
|
||||
richeader_ie->size = dinput.indication_header_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 6;
|
||||
RICindication_IEs_t *ies_indmsg = &IE_array[ie_index];
|
||||
ies_indmsg->criticality = Criticality_reject;
|
||||
ies_indmsg->id = ProtocolIE_ID_id_RICindicationMessage;
|
||||
ies_indmsg->value.present = RICindication_IEs__value_PR_RICindicationMessage;
|
||||
RICindicationMessage_t *ricmsg_ie = &ies_indmsg->value.choice.RICindicationMessage;
|
||||
ricmsg_ie->buf = dinput.indication_msg;
|
||||
ricmsg_ie->size = dinput.indication_msg_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
|
||||
// optional call process id ..
|
||||
if (dinput.call_process_id_size > 0){
|
||||
ie_index = 7;
|
||||
RICindication_IEs_t *ies_ind_callprocessid = &IE_array[ie_index];
|
||||
ies_ind_callprocessid->criticality = Criticality_reject;
|
||||
ies_ind_callprocessid->id = ProtocolIE_ID_id_RICcallProcessID;
|
||||
ies_ind_callprocessid->value.present = RICindication_IEs__value_PR_RICcallProcessID;
|
||||
RICcallProcessID_t *riccallprocessid_ie = &ies_ind_callprocessid->value.choice.RICcallProcessID;
|
||||
riccallprocessid_ie->buf = dinput.indication_msg;
|
||||
riccallprocessid_ie->size = dinput.indication_msg_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool ric_indication:: get_fields(InitiatingMessage_t * init_msg, ric_indication_helper &dout)
|
||||
{
|
||||
if (init_msg == 0){
|
||||
error_string = "Invalid reference for E2AP Indication message in get_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for(int edx = 0; edx < init_msg->value.choice.RICindication.protocolIEs.list.count; edx++) {
|
||||
RICindication_IEs_t *memb_ptr = init_msg->value.choice.RICindication.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (ProtocolIE_ID_id_RICindicationHeader):
|
||||
dout.indication_header = memb_ptr->value.choice.RICindicationHeader.buf;
|
||||
dout.indication_header_size = memb_ptr->value.choice.RICindicationHeader.size;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICindicationMessage):
|
||||
dout.indication_msg = memb_ptr->value.choice.RICindicationMessage.buf;
|
||||
dout.indication_msg_size = memb_ptr->value.choice.RICindicationMessage.size;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
|
||||
//dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
dout.func_id = memb_ptr->value.choice.RANfunctionID;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICindicationSN):
|
||||
dout.indication_sn = memb_ptr->value.choice.RICindicationSN;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICindicationType):
|
||||
dout.indication_type = memb_ptr->value.choice.RICindicationType;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICactionID):
|
||||
dout.action_id = memb_ptr->value.choice.RICactionID;
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICcallProcessID):
|
||||
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
|
||||
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
InitiatingMessage_t * ric_indication::get_message(void) {
|
||||
return initMsg;
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#ifndef E2AP_RIC_INDICATION_H_
|
||||
#define E2AP_RIC_INDICATION_H_
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <sstream>
|
||||
#include <E2AP-PDU.h>
|
||||
#include <InitiatingMessage.h>
|
||||
#include <RICindication.h>
|
||||
#include <ProtocolIE-Field.h>
|
||||
#include "e2ap_indication_helper.hpp"
|
||||
|
||||
#define NUM_INDICATION_IES 8
|
||||
|
||||
|
||||
|
||||
class ric_indication{
|
||||
|
||||
public:
|
||||
ric_indication(void);
|
||||
~ric_indication(void);
|
||||
|
||||
bool encode_e2ap_indication(unsigned char *, size_t *, ric_indication_helper &);
|
||||
InitiatingMessage_t * get_message (void) ;
|
||||
bool set_fields(InitiatingMessage_t *, ric_indication_helper &);
|
||||
bool get_fields(InitiatingMessage_t *, ric_indication_helper &);
|
||||
std::string get_error(void) const {return error_string ; };
|
||||
|
||||
private:
|
||||
|
||||
E2AP_PDU_t * e2ap_pdu_obj;
|
||||
InitiatingMessage_t *initMsg;
|
||||
RICindication_IEs_t *IE_array;
|
||||
std::string error_string;
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
};
|
||||
|
||||
|
||||
#endif /* E2AP_RIC_INDICATION_H_ */
|
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
|
||||
#ifndef E2AP_INDICATION_HELPER_
|
||||
#define E2AP_INDICATION_HELPER_
|
||||
|
||||
typedef struct ric_indication_helper ric_indication_helper;
|
||||
|
||||
struct ric_indication_helper{
|
||||
ric_indication_helper(void) : req_id(1), req_seq_no(1), func_id(0), action_id(1), indication_type(0), indication_sn(0), indication_msg(0), indication_msg_size(0), indication_header(0), indication_header_size(0), call_process_id(0), call_process_id_size(0) {};
|
||||
long int req_id, req_seq_no, func_id, action_id, indication_type, indication_sn;
|
||||
|
||||
unsigned char* indication_msg;
|
||||
size_t indication_msg_size;
|
||||
|
||||
unsigned char* indication_header;
|
||||
size_t indication_header_size;
|
||||
|
||||
unsigned char *call_process_id;
|
||||
size_t call_process_id_size;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef GENERIC_HELPERS
|
||||
#define GENERIC_HELPERS
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/* Utilities */
|
||||
|
||||
class octet_helper {
|
||||
|
||||
public:
|
||||
octet_helper(void):_ref(NULL), _size(0){};
|
||||
octet_helper(const void *ref, int size):_ref(ref), _size(size){};
|
||||
void set_ref(const void *ref){
|
||||
_ref = ref;
|
||||
}
|
||||
|
||||
void set_size(size_t size){
|
||||
_size = size;
|
||||
}
|
||||
|
||||
const void * get_ref(void){return _ref ; };
|
||||
size_t get_size(void) const {return _size ; } ;
|
||||
|
||||
private:
|
||||
const void *_ref;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
#endif
|
181
setup/xapp-bs-connector/src/xapp-asn/e2ap/response_helper.hpp
Normal file
181
setup/xapp-bs-connector/src/xapp-asn/e2ap/response_helper.hpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_RESPONSE_HELPER_
|
||||
#define S_RESPONSE_HELPER_
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
/* Simple structure to store action for RICaction of the Subscription response based on E2 v0.31 */
|
||||
struct ActionResponse {
|
||||
public:
|
||||
ActionResponse(int id): _is_admit(true), _id(id), _cause(-1), _sub_cause(-1){};
|
||||
ActionResponse(int id, int cause, int sub_cause): _is_admit(false), _id(id), _cause(cause), _sub_cause(sub_cause){};
|
||||
|
||||
int get_id() const{
|
||||
return _id;
|
||||
};
|
||||
|
||||
int get_cause() const{
|
||||
return _cause;
|
||||
};
|
||||
|
||||
int get_sub_cause() const{
|
||||
return _sub_cause;
|
||||
};
|
||||
|
||||
bool is_admitted(void){
|
||||
return _is_admit;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
bool _is_admit;
|
||||
int _id, _cause, _sub_cause;
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct subscription_response_helper {
|
||||
|
||||
public:
|
||||
|
||||
using action_t = std::vector<ActionResponse>;
|
||||
|
||||
subscription_response_helper(void){
|
||||
_action_admitted_ref = std::make_unique<action_t>();
|
||||
_action_not_admitted_ref = std::make_unique<action_t>();
|
||||
|
||||
};
|
||||
|
||||
// copy operator
|
||||
subscription_response_helper(const subscription_response_helper &he ){
|
||||
_action_admitted_ref = std::make_unique<action_t>();
|
||||
_action_not_admitted_ref = std::make_unique<action_t>();
|
||||
|
||||
_req_id = he.get_request_id();
|
||||
_req_seq_no = he.get_req_seq();
|
||||
_func_id = he.get_function_id();
|
||||
|
||||
// Take care of the actions
|
||||
for (auto const & e: *(he.get_admitted_list())){
|
||||
add_action(e.get_id());
|
||||
}
|
||||
|
||||
for(auto const & e: *(he.get_not_admitted_list())){
|
||||
add_action(e.get_id(), e.get_cause(), e.get_sub_cause());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// assignment operator
|
||||
void operator=(const subscription_response_helper & he){
|
||||
_action_admitted_ref = std::make_unique<action_t>();
|
||||
_action_not_admitted_ref = std::make_unique<action_t>();
|
||||
|
||||
_req_id = he.get_request_id();
|
||||
_req_seq_no = he.get_req_seq();
|
||||
_func_id = he.get_function_id();
|
||||
|
||||
|
||||
// Take care of the actions
|
||||
for (auto const & e: *(he.get_admitted_list())){
|
||||
add_action(e.get_id());
|
||||
}
|
||||
|
||||
for(auto const & e: *(he.get_not_admitted_list())){
|
||||
add_action(e.get_id(), e.get_cause(), e.get_sub_cause());
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
action_t * get_admitted_list (void ) const {return _action_admitted_ref.get();};
|
||||
action_t * get_not_admitted_list (void ) const{return _action_not_admitted_ref.get();};
|
||||
|
||||
void set_request(int id, int seq_no){
|
||||
_req_id = id;
|
||||
_req_seq_no = seq_no;
|
||||
|
||||
};
|
||||
|
||||
void clear(void){
|
||||
_action_admitted_ref.get()->clear();
|
||||
_action_not_admitted_ref.get()->clear();
|
||||
}
|
||||
|
||||
|
||||
void set_function_id(int id){
|
||||
_func_id = id;
|
||||
};
|
||||
|
||||
void add_action(int id){
|
||||
ActionResponse a(id) ;
|
||||
_action_admitted_ref.get()->push_back(a);
|
||||
};
|
||||
|
||||
void add_action(int id, int cause, int sub_cause){
|
||||
ActionResponse a (id, cause, sub_cause);
|
||||
_action_not_admitted_ref.get()->push_back(a);
|
||||
};
|
||||
|
||||
|
||||
int get_request_id(void) const{
|
||||
return _req_id;
|
||||
}
|
||||
|
||||
int get_req_seq(void) const{
|
||||
return _req_seq_no;
|
||||
}
|
||||
|
||||
int get_function_id(void) const{
|
||||
return _func_id;
|
||||
}
|
||||
|
||||
std::string to_string(void){
|
||||
std::string Info;
|
||||
Info += "Request ID = " + std::to_string(_req_id) + "\n";
|
||||
Info += "Request Sequence No = " + std::to_string(_req_seq_no) + "\n";
|
||||
Info += "RAN Function ID = " + std::to_string(_func_id) + "\n";
|
||||
Info += "Actions Admitted =\n";
|
||||
int i = 0;
|
||||
for(auto & e: *(_action_admitted_ref)){
|
||||
Info += std::to_string(i) + ": ID=" + std::to_string(e.get_id()) + "\n";
|
||||
i++;
|
||||
}
|
||||
Info += "Actions Not Admitted =\n";
|
||||
i = 0;
|
||||
for(auto & e: *(_action_not_admitted_ref)){
|
||||
Info += std::to_string(i) + ": ID=" + std::to_string(e.get_id()) + ": Cause =" + std::to_string(e.get_cause()) + ": Sub-Cause=" + std::to_string(e.get_sub_cause()) + "\n";
|
||||
i++;
|
||||
}
|
||||
|
||||
return Info;
|
||||
}
|
||||
|
||||
private:
|
||||
int _req_id, _req_seq_no, _func_id;
|
||||
std::unique_ptr<action_t> _action_admitted_ref;
|
||||
std::unique_ptr<action_t> _action_not_admitted_ref;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@@ -0,0 +1,180 @@
|
||||
|
||||
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "subscription_delete_request.hpp"
|
||||
|
||||
subscription_delete::subscription_delete(void){
|
||||
|
||||
_name = "default";
|
||||
|
||||
e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
|
||||
assert(initMsg != 0);
|
||||
|
||||
IE_array = (RICsubscriptionDeleteRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_DELETE_IES, sizeof(RICsubscriptionDeleteRequest_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
RICsubscriptionDeleteRequest_t * subscription_delete = &(initMsg->value.choice.RICsubscriptionDeleteRequest);
|
||||
for(int i = 0; i < NUM_SUBSCRIPTION_DELETE_IES; i++){
|
||||
ASN_SEQUENCE_ADD(&subscription_delete->protocolIEs, &(IE_array[i]));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC indication IE container
|
||||
subscription_delete::~subscription_delete(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing subscription delete request object memory");
|
||||
RICsubscriptionDeleteRequest_t * subscription_delete = &(initMsg->value.choice.RICsubscriptionDeleteRequest);
|
||||
|
||||
for(int i = 0; i < subscription_delete->protocolIEs.list.size; i++){
|
||||
subscription_delete->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (subscription_delete->protocolIEs.list.size > 0){
|
||||
free(subscription_delete->protocolIEs.list.array);
|
||||
subscription_delete->protocolIEs.list.count = 0;
|
||||
subscription_delete->protocolIEs.list.size = 0;
|
||||
subscription_delete->protocolIEs.list.array = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(initMsg);
|
||||
e2ap_pdu_obj->choice.initiatingMessage = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed subscription delete request object memory");
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool subscription_delete::encode_e2ap_subscription(unsigned char *buf, size_t *size, subscription_helper &dinput){
|
||||
|
||||
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
|
||||
set_fields( dinput);
|
||||
|
||||
initMsg->procedureCode = ProcedureCode_id_RICsubscriptionDelete;
|
||||
initMsg->criticality = Criticality_reject;
|
||||
initMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionDeleteRequest;
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding subscription delete request. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t res = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(res.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding Subscription Delete Request. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < res.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding Subscription Delete Request . Reason = encoded pdu size " << res.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
res.encoded = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = res.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool subscription_delete::set_fields( subscription_helper &helper){
|
||||
unsigned int ie_index;
|
||||
|
||||
ie_index = 0;
|
||||
RICsubscriptionDeleteRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
//ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
|
||||
|
||||
|
||||
ie_index = 1;
|
||||
RICsubscriptionDeleteRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool subscription_delete:: get_fields(InitiatingMessage_t * init_msg, subscription_helper & dout)
|
||||
{
|
||||
|
||||
if (init_msg == 0){
|
||||
error_string = "Invalid reference for initiating message for get string";
|
||||
return false;
|
||||
}
|
||||
|
||||
RICrequestID_t *requestid;
|
||||
RANfunctionID_t * ranfunctionid;
|
||||
|
||||
for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionDeleteRequest.protocolIEs.list.count; edx++) {
|
||||
RICsubscriptionDeleteRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionDeleteRequest.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_DELETE_
|
||||
#define S_DELETE_
|
||||
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <asn_application.h>
|
||||
#include <E2AP-PDU.h>
|
||||
#include <InitiatingMessage.h>
|
||||
#include <RICsubscriptionDeleteRequest.h>
|
||||
#include <ProtocolIE-Field.h>
|
||||
#include "subscription_helper.hpp"
|
||||
|
||||
#define NUM_SUBSCRIPTION_DELETE_IES 2
|
||||
|
||||
class subscription_delete{
|
||||
public:
|
||||
|
||||
subscription_delete(void);
|
||||
~subscription_delete(void);
|
||||
|
||||
bool encode_e2ap_subscription(unsigned char *, size_t *, subscription_helper &);
|
||||
bool set_fields(subscription_helper &);
|
||||
bool get_fields(InitiatingMessage_t *, subscription_helper &);
|
||||
|
||||
std::string get_error(void) const {
|
||||
return error_string ;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
InitiatingMessage_t *initMsg;
|
||||
E2AP_PDU_t * e2ap_pdu_obj;
|
||||
|
||||
RICsubscriptionDeleteRequest_IEs_t * IE_array;
|
||||
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
std::string _name;
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "subscription_delete_response.hpp"
|
||||
|
||||
/* The xAPP need only worry about the get_fields from a response, since it does
|
||||
not generate a response. Generating response however is included to support testing.
|
||||
*/
|
||||
|
||||
|
||||
// Primarly for generation
|
||||
subscription_delete_response::subscription_delete_response(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2AP_PDU_t *)calloc(1, sizeof(E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
successMsg = 0;
|
||||
successMsg = (SuccessfulOutcome_t *)calloc(1, sizeof(SuccessfulOutcome_t));
|
||||
assert(successMsg != 0);
|
||||
|
||||
unsuccessMsg = 0;
|
||||
unsuccessMsg = (UnsuccessfulOutcome_t *)calloc(1, sizeof(UnsuccessfulOutcome_t));
|
||||
assert(unsuccessMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (RICsubscriptionDeleteResponse_IEs_t *)calloc(NUM_SUBSCRIPTION_DELETE_RESPONSE_IES, sizeof(RICsubscriptionDeleteResponse_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
IE_Failure_array = 0;
|
||||
IE_Failure_array = (RICsubscriptionDeleteFailure_IEs_t *)calloc(NUM_SUBSCRIPTION_DELETE_FAILURE_IES, sizeof(RICsubscriptionDeleteFailure_IEs_t));
|
||||
assert(IE_Failure_array != 0);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC indication IE container
|
||||
subscription_delete_response::~subscription_delete_response(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing subscription delete response memory");
|
||||
RICsubscriptionDeleteResponse_t * ric_subscription_delete_response = &(successMsg->value.choice.RICsubscriptionDeleteResponse);
|
||||
|
||||
for(unsigned int i = 0; i < ric_subscription_delete_response->protocolIEs.list.size ; i++){
|
||||
ric_subscription_delete_response->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
RICsubscriptionDeleteFailure_t * ric_subscription_failure = &(unsuccessMsg->value.choice.RICsubscriptionDeleteFailure);
|
||||
for(unsigned int i = 0; i < ric_subscription_failure->protocolIEs.list.size; i++){
|
||||
ric_subscription_failure->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(IE_Failure_array);
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_SuccessfulOutcome, successMsg);
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_UnsuccessfulOutcome, unsuccessMsg);
|
||||
|
||||
e2ap_pdu_obj->choice.successfulOutcome = NULL;
|
||||
e2ap_pdu_obj->choice.unsuccessfulOutcome = NULL;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed subscription delete response memory");
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool subscription_delete_response::encode_e2ap_subscription_delete_response(unsigned char *buf, size_t *size, subscription_response_helper &dinput, bool is_success){
|
||||
|
||||
bool res;
|
||||
|
||||
if(is_success){
|
||||
res = set_fields(successMsg, dinput);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_successfulOutcome;
|
||||
e2ap_pdu_obj->choice.successfulOutcome = successMsg;
|
||||
}
|
||||
else{
|
||||
res = set_fields(unsuccessMsg, dinput);
|
||||
if(! res){
|
||||
return false;
|
||||
}
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_unsuccessfulOutcome;
|
||||
e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
|
||||
}
|
||||
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding subcription delete response. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding Subscription Delete Response . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
retval.encoded = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool subscription_delete_response::set_fields(SuccessfulOutcome_t *success, subscription_response_helper &helper){
|
||||
|
||||
if (success == 0){
|
||||
error_string = "Invalid reference to success message in set fields subscription delete response";
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int ie_index;
|
||||
|
||||
success->procedureCode = ProcedureCode_id_RICsubscriptionDelete;
|
||||
success->criticality = Criticality_reject;
|
||||
success->value.present = SuccessfulOutcome__value_PR_RICsubscriptionDeleteResponse;
|
||||
|
||||
RICsubscriptionDeleteResponse_t * subscription_delete_response = &(success->value.choice.RICsubscriptionDeleteResponse);
|
||||
subscription_delete_response->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
RICsubscriptionDeleteResponse_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
//ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
ASN_SEQUENCE_ADD(&subscription_delete_response->protocolIEs, ies_ricreq);
|
||||
|
||||
|
||||
ie_index = 1;
|
||||
RICsubscriptionDeleteResponse_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
ASN_SEQUENCE_ADD(&subscription_delete_response->protocolIEs, ies_ranfunc);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool subscription_delete_response:: get_fields(SuccessfulOutcome_t * success_msg, subscription_response_helper & dout)
|
||||
{
|
||||
|
||||
if (success_msg == 0){
|
||||
error_string = "Invalid reference to success message inn get fields subscription delete response";
|
||||
return false;
|
||||
}
|
||||
|
||||
RICrequestID_t *requestid;
|
||||
RANfunctionID_t * ranfunctionid;
|
||||
|
||||
for(int edx = 0; edx < success_msg->value.choice.RICsubscriptionDeleteResponse.protocolIEs.list.count; edx++) {
|
||||
RICsubscriptionDeleteResponse_IEs_t *memb_ptr = success_msg->value.choice.RICsubscriptionDeleteResponse.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
|
||||
bool subscription_delete_response::set_fields(UnsuccessfulOutcome_t *unsuccess, subscription_response_helper &helper){
|
||||
|
||||
if (unsuccess == 0){
|
||||
error_string = "Invalid reference to unsuccess message in set fields subscription delete response";
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int ie_index;
|
||||
|
||||
unsuccess->procedureCode = ProcedureCode_id_RICsubscriptionDelete;
|
||||
unsuccess->criticality = Criticality_reject;
|
||||
unsuccess->value.present = UnsuccessfulOutcome__value_PR_RICsubscriptionDeleteFailure;
|
||||
|
||||
RICsubscriptionDeleteFailure_t * ric_subscription_failure = &(unsuccess->value.choice.RICsubscriptionDeleteFailure);
|
||||
ric_subscription_failure->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
RICsubscriptionDeleteFailure_IEs_t *ies_ricreq = &IE_Failure_array[ie_index];
|
||||
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
//ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, ies_ricreq);
|
||||
|
||||
ie_index = 1;
|
||||
RICsubscriptionDeleteFailure_IEs_t *ies_ranfunc = &IE_Failure_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, ies_ranfunc);
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool subscription_delete_response:: get_fields(UnsuccessfulOutcome_t * unsuccess_msg, subscription_response_helper & dout)
|
||||
{
|
||||
|
||||
if (unsuccess_msg == 0){
|
||||
error_string = "Invalid reference to unsuccess message in get fields subscription delete response";
|
||||
return false;
|
||||
}
|
||||
|
||||
RICrequestID_t *requestid;
|
||||
RANfunctionID_t * ranfunctionid;
|
||||
|
||||
for(int edx = 0; edx < unsuccess_msg->value.choice.RICsubscriptionDeleteFailure.protocolIEs.list.count; edx++) {
|
||||
RICsubscriptionDeleteFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICsubscriptionDeleteFailure.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_DEL_RESPONSE_
|
||||
#define S_DEL_RESPONSE_
|
||||
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <asn_application.h>
|
||||
#include <E2AP-PDU.h>
|
||||
#include <SuccessfulOutcome.h>
|
||||
#include <UnsuccessfulOutcome.h>
|
||||
#include <RICsubscriptionDeleteResponse.h>
|
||||
#include <RICsubscriptionDeleteFailure.h>
|
||||
#include <ProtocolIE-Field.h>
|
||||
#include <ProcedureCode.h>
|
||||
#include "response_helper.hpp"
|
||||
|
||||
#define NUM_SUBSCRIPTION_DELETE_RESPONSE_IES 2
|
||||
#define NUM_SUBSCRIPTION_DELETE_FAILURE_IES 2
|
||||
|
||||
class subscription_delete_response {
|
||||
public:
|
||||
|
||||
subscription_delete_response(void);
|
||||
~subscription_delete_response(void);
|
||||
|
||||
bool encode_e2ap_subscription_delete_response(unsigned char *, size_t *, subscription_response_helper &, bool);
|
||||
bool set_fields(SuccessfulOutcome_t *, subscription_response_helper &);
|
||||
bool get_fields(SuccessfulOutcome_t *, subscription_response_helper &);
|
||||
|
||||
bool set_fields(UnsuccessfulOutcome_t *, subscription_response_helper &);
|
||||
bool get_fields(UnsuccessfulOutcome_t *, subscription_response_helper &);
|
||||
|
||||
std::string get_error_string(void) const {
|
||||
return error_string;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
E2AP_PDU_t * e2ap_pdu_obj;
|
||||
SuccessfulOutcome_t * successMsg;
|
||||
UnsuccessfulOutcome_t * unsuccessMsg;
|
||||
|
||||
|
||||
RICsubscriptionDeleteResponse_IEs_t *IE_array;
|
||||
RICsubscriptionDeleteFailure_IEs_t *IE_Failure_array;
|
||||
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
std::string error_string;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SUB_HELPER_
|
||||
#define SUB_HELPER_
|
||||
|
||||
/*
|
||||
Simple structure to store action related information based on E2 v0.22
|
||||
Used for subscription request, response etc
|
||||
|
||||
ricActionID RICactionID,
|
||||
ricActionType RICactionType,
|
||||
ricActionDefinition RICactionDefinition OPTIONAL,
|
||||
ricSubsequentAction RICsubsequentAction OPTIONAL,
|
||||
ricCause
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "generic_helpers.hpp"
|
||||
|
||||
|
||||
// Note : if no action definition specified, octet length of action definition is NULL
|
||||
// If no subsequent action specified, default is subsequent_action = 0, time to wait is 0
|
||||
struct Action {
|
||||
|
||||
public:
|
||||
|
||||
Action(int id, int type): _is_def(false), _is_subs_act(false), _id(id), _type(type), _next_action(0){};
|
||||
Action(int id, int type, const void *def, size_t def_size, int next_action): _is_def(false), _is_subs_act(false), _id(id), _type(type){
|
||||
|
||||
_is_def = true;
|
||||
_action_definition.set_ref(def);
|
||||
_action_definition.set_size(def_size);
|
||||
_is_subs_act = true;
|
||||
_next_action = next_action;
|
||||
|
||||
};
|
||||
|
||||
|
||||
int get_id() const{
|
||||
return _id;
|
||||
}
|
||||
|
||||
int get_type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
|
||||
const void * get_definition(void ) {
|
||||
return _action_definition.get_ref();
|
||||
}
|
||||
|
||||
int get_definition_size(void) const {
|
||||
return _action_definition.get_size();
|
||||
};
|
||||
|
||||
|
||||
int get_subsequent_action() const {
|
||||
return _next_action;
|
||||
};
|
||||
|
||||
bool is_definition() const{
|
||||
|
||||
return _is_def;
|
||||
}
|
||||
|
||||
bool is_subsequent_action() const{
|
||||
return _is_subs_act;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool _is_def;
|
||||
bool _is_subs_act;
|
||||
int _id, _type, _next_action, _cause, _sub_cause;
|
||||
bool _is_admit;
|
||||
octet_helper _action_definition;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Helper class that stores subscription data
|
||||
*/
|
||||
|
||||
|
||||
struct subscription_helper {
|
||||
|
||||
public:
|
||||
|
||||
using action_t = std::vector<Action>;
|
||||
subscription_helper(){
|
||||
_action_ref = std::make_unique<action_t>();
|
||||
};
|
||||
|
||||
action_t * get_list() const {return _action_ref.get();};
|
||||
|
||||
void clear(void){
|
||||
_action_ref.get()->clear();
|
||||
}
|
||||
|
||||
void set_request(int id){
|
||||
_req_id = id;
|
||||
|
||||
};
|
||||
|
||||
void set_function_id(int id){
|
||||
_func_id = id;
|
||||
};
|
||||
|
||||
void set_event_def(const void *ref, size_t size){
|
||||
_event_def.set_ref(ref);
|
||||
_event_def.set_size(size);
|
||||
};
|
||||
|
||||
|
||||
void add_action(int id, int type){
|
||||
Action a(id, type) ;
|
||||
_action_ref.get()->push_back(a);
|
||||
};
|
||||
|
||||
void add_action(int id, int type, const void *action_def, size_t size, int next_action){
|
||||
Action a (id, type, action_def, size, next_action);
|
||||
_action_ref.get()->push_back(a);
|
||||
};
|
||||
|
||||
|
||||
int get_request_id(void) const{
|
||||
return _req_id;
|
||||
}
|
||||
|
||||
|
||||
int get_function_id(void) const{
|
||||
return _func_id;
|
||||
}
|
||||
|
||||
const void * get_event_def(void) {
|
||||
return _event_def.get_ref();
|
||||
}
|
||||
|
||||
int get_event_def_size(void) const {
|
||||
return _event_def.get_size();
|
||||
}
|
||||
|
||||
void print_sub_info(void){
|
||||
std::cout <<"Request ID = " << _req_id << std::endl;
|
||||
std::cout <<"RAN Function ID = " << _func_id << std::endl;
|
||||
for(auto const & e: *(_action_ref.get())){
|
||||
std::cout <<"Action ID = " << e.get_id() << " Action Type = " << e.get_type() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<action_t> _action_ref;
|
||||
int curr_index;
|
||||
int _req_id, _func_id;
|
||||
octet_helper _event_def;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -0,0 +1,306 @@
|
||||
|
||||
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "subscription_request.hpp"
|
||||
|
||||
|
||||
// Set up memory allocations for each IE for encoding
|
||||
// We are responsible for memory management for each IE for encoding
|
||||
// Hence destructor should clear out memory
|
||||
// When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
|
||||
// for releasing memory by external calling function)
|
||||
subscription_request::subscription_request(void){
|
||||
|
||||
_name = "default";
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
initMsg = 0;
|
||||
initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
|
||||
assert(initMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (RICsubscriptionRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_REQUEST_IES, sizeof(RICsubscriptionRequest_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
action_array = 0;
|
||||
action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(INITIAL_REQUEST_LIST_SIZE, sizeof(RICaction_ToBeSetup_ItemIEs_t));
|
||||
assert(action_array != 0);
|
||||
action_array_size = INITIAL_REQUEST_LIST_SIZE;
|
||||
// also need to add subsequent action and time to wait ..
|
||||
for (unsigned int i = 0; i < action_array_size; i++){
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct RICsubsequentAction *)calloc(1, sizeof(struct RICsubsequentAction));
|
||||
assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction != 0);
|
||||
}
|
||||
|
||||
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC indication IE container
|
||||
subscription_request::~subscription_request(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing subscription request memory");;
|
||||
|
||||
// Sequence of actions to be admitted causes special heart-ache. Free ric subscription element manually and reset the ie pointer
|
||||
RICsubscriptionDetails_t * ricsubscription_ie = &(IE_array[2].value.choice.RICsubscriptionDetails);
|
||||
|
||||
for(int i = 0; i < ricsubscription_ie->ricAction_ToBeSetup_List.list.size; i++){
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (ricsubscription_ie->ricAction_ToBeSetup_List.list.size > 0){
|
||||
free(ricsubscription_ie->ricAction_ToBeSetup_List.list.array);
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.size = 0;
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.array = 0;
|
||||
}
|
||||
|
||||
// clear subsequent action array
|
||||
for (unsigned int i = 0; i < action_array_size; i++){
|
||||
free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
|
||||
}
|
||||
|
||||
free(action_array);
|
||||
RICsubscriptionRequest_t * subscription_request = &(initMsg->value.choice.RICsubscriptionRequest);
|
||||
|
||||
for(int i = 0; i < subscription_request->protocolIEs.list.size; i++){
|
||||
subscription_request->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if( subscription_request->protocolIEs.list.size > 0){
|
||||
free( subscription_request->protocolIEs.list.array);
|
||||
subscription_request->protocolIEs.list.array = 0;
|
||||
subscription_request->protocolIEs.list.size = 0;
|
||||
subscription_request->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(initMsg);
|
||||
e2ap_pdu_obj->choice.initiatingMessage = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed subscription request memory ");
|
||||
};
|
||||
|
||||
|
||||
bool subscription_request::encode_e2ap_subscription(unsigned char *buf, size_t *size, subscription_helper &dinput){
|
||||
|
||||
bool res;
|
||||
|
||||
initMsg->procedureCode = ProcedureCode_id_RICsubscription;
|
||||
initMsg->criticality = Criticality_ignore;
|
||||
initMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionRequest;
|
||||
|
||||
res = set_fields(initMsg, dinput);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding subscription request. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding Subscription Request. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding Subscription Request . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
retval.encoded = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool subscription_request::set_fields( InitiatingMessage_t * init_msg, subscription_helper &helper){
|
||||
|
||||
|
||||
int ie_index;
|
||||
int result = 0;
|
||||
|
||||
if (init_msg == 0){
|
||||
error_string = "Error. Invalid reference when getting fields from subscription request";
|
||||
return false;
|
||||
}
|
||||
|
||||
RICsubscriptionRequest_t * ric_subscription = &(init_msg->value.choice.RICsubscriptionRequest);
|
||||
ric_subscription->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
RICsubscriptionRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
//ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
|
||||
assert(result == 0);
|
||||
|
||||
ie_index = 1;
|
||||
RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
|
||||
assert(result == 0);
|
||||
|
||||
|
||||
ie_index = 2;
|
||||
RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
|
||||
ies_actid->criticality = Criticality_reject;
|
||||
ies_actid->id = ProtocolIE_ID_id_RICsubscriptionDetails;
|
||||
ies_actid->value.present = RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
|
||||
RICsubscriptionDetails_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscriptionDetails;
|
||||
|
||||
ricsubscription_ie->ricEventTriggerDefinition.buf = (uint8_t *) helper.get_event_def();
|
||||
ricsubscription_ie->ricEventTriggerDefinition.size = helper.get_event_def_size();
|
||||
|
||||
std::vector<Action> * ref_action_array = helper.get_list();
|
||||
// do we need to resize ?
|
||||
// we don't care about contents, so just do a free/calloc
|
||||
if(action_array_size < ref_action_array->size()){
|
||||
std::cout <<"re-allocating action array from " << action_array_size << " to " << 2 * ref_action_array->size() << std::endl;
|
||||
// free subsequent allocation
|
||||
for (unsigned int i = 0; i < action_array_size; i++){
|
||||
free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
|
||||
}
|
||||
|
||||
action_array_size = 2 * ref_action_array->size();
|
||||
free(action_array);
|
||||
action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(RICaction_ToBeSetup_ItemIEs_t));
|
||||
assert(action_array != 0);
|
||||
|
||||
// also need to add subsequent action and time to wait ..
|
||||
for (unsigned int i = 0; i < action_array_size; i++){
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct RICsubsequentAction *)calloc(1, sizeof(struct RICsubsequentAction));
|
||||
assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction != 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// reset the list count on ricAction_ToBeSetup_List;
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
|
||||
|
||||
for(unsigned int i = 0; i < ref_action_array->size(); i ++){
|
||||
action_array[i].criticality = Criticality_ignore;
|
||||
action_array[i].id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
|
||||
action_array[i].value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionID = (*ref_action_array)[i].get_id();
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionType = (*ref_action_array)[i].get_type();
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType = (*ref_action_array)[i].get_subsequent_action();
|
||||
|
||||
result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
|
||||
if (result == -1){
|
||||
error_string = "Erorr : Unable to assign memory to add Action item to set up list";
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
|
||||
assert(result == 0);
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool subscription_request:: get_fields(InitiatingMessage_t * init_msg, subscription_helper & dout)
|
||||
{
|
||||
|
||||
if (init_msg == 0){
|
||||
error_string = "Error. Invalid reference when getting fields from subscription request";
|
||||
return false;
|
||||
}
|
||||
|
||||
RICrequestID_t *requestid;
|
||||
RANfunctionID_t * ranfunctionid;
|
||||
RICsubscriptionDetails_t * ricsubscription;
|
||||
|
||||
for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.count; edx++) {
|
||||
RICsubscriptionRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICsubscriptionDetails):
|
||||
ricsubscription = &memb_ptr->value.choice.RICsubscriptionDetails;
|
||||
dout.set_event_def(ricsubscription->ricEventTriggerDefinition.buf, ricsubscription->ricEventTriggerDefinition.size);
|
||||
|
||||
for(int index = 0; index < ricsubscription->ricAction_ToBeSetup_List.list.count; index ++){
|
||||
RICaction_ToBeSetup_ItemIEs_t * item = (RICaction_ToBeSetup_ItemIEs_t *)ricsubscription->ricAction_ToBeSetup_List.list.array[index];
|
||||
if (item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction == NULL){
|
||||
dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType);
|
||||
}
|
||||
else{
|
||||
std::string action_def = ""; // for now we are ignoring action definition
|
||||
}
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_REQUEST_
|
||||
#define S_REQUEST_
|
||||
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include <asn_application.h>
|
||||
#include <E2AP-PDU.h>
|
||||
#include <InitiatingMessage.h>
|
||||
#include <RICsubscriptionRequest.h>
|
||||
#include <RICsubscriptionRequest.h>
|
||||
#include <ProtocolIE-Field.h>
|
||||
#include <ProtocolIE-SingleContainer.h>
|
||||
#include <RICactions-ToBeSetup-List.h>
|
||||
#include <RICsubsequentAction.h>
|
||||
#include "subscription_helper.hpp"
|
||||
|
||||
#define NUM_SUBSCRIPTION_REQUEST_IES 3
|
||||
#define INITIAL_REQUEST_LIST_SIZE 4
|
||||
|
||||
class subscription_request{
|
||||
public:
|
||||
|
||||
subscription_request(std::string name);
|
||||
subscription_request(void);
|
||||
~subscription_request(void);
|
||||
|
||||
bool encode_e2ap_subscription(unsigned char *, size_t *, subscription_helper &);
|
||||
bool set_fields(InitiatingMessage_t *, subscription_helper &);
|
||||
bool get_fields(InitiatingMessage_t *, subscription_helper &);
|
||||
|
||||
std::string get_error(void) const{
|
||||
return error_string;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
InitiatingMessage_t *initMsg;
|
||||
E2AP_PDU_t * e2ap_pdu_obj;
|
||||
|
||||
RICsubscriptionRequest_IEs_t * IE_array;
|
||||
RICaction_ToBeSetup_ItemIEs_t * action_array;
|
||||
unsigned int action_array_size;
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
std::string _name;
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
@@ -0,0 +1,583 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "subscription_response.hpp"
|
||||
|
||||
/* The xAPP need only worry about the get_fields from a response, since it does
|
||||
not generate a response. Generating response however is included to support testing.
|
||||
*/
|
||||
|
||||
|
||||
// Primarly for generation
|
||||
subscription_response::subscription_response(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2AP_PDU_t *)calloc(1, sizeof(E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
successMsg = 0;
|
||||
successMsg = (SuccessfulOutcome_t *)calloc(1, sizeof(SuccessfulOutcome_t));
|
||||
assert(successMsg != 0);
|
||||
|
||||
unsuccessMsg = 0;
|
||||
unsuccessMsg = (UnsuccessfulOutcome_t *)calloc(1, sizeof(UnsuccessfulOutcome_t));
|
||||
assert(unsuccessMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (RICsubscriptionResponse_IEs_t *)calloc(NUM_SUBSCRIPTION_RESPONSE_IES, sizeof(RICsubscriptionResponse_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
IE_Failure_array = 0;
|
||||
IE_Failure_array = (RICsubscriptionFailure_IEs_t *)calloc(NUM_SUBSCRIPTION_FAILURE_IES, sizeof(RICsubscriptionFailure_IEs_t));
|
||||
assert(IE_Failure_array != 0);
|
||||
|
||||
ie_admitted_list = 0;
|
||||
ie_admitted_list = (RICaction_Admitted_ItemIEs_t *)calloc(INITIAL_RESPONSE_LIST_SIZE, sizeof(RICaction_Admitted_ItemIEs_t));
|
||||
assert(ie_admitted_list != 0);
|
||||
ie_admitted_list_size = INITIAL_RESPONSE_LIST_SIZE;
|
||||
|
||||
ie_not_admitted_list = 0;
|
||||
ie_not_admitted_list = (RICaction_NotAdmitted_ItemIEs_t *)calloc(INITIAL_RESPONSE_LIST_SIZE, sizeof(RICaction_NotAdmitted_ItemIEs_t));
|
||||
assert(ie_not_admitted_list != 0);
|
||||
ie_not_admitted_list_size = INITIAL_RESPONSE_LIST_SIZE;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC indication IE container
|
||||
subscription_response::~subscription_response(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing subscription response memory");
|
||||
RICaction_Admitted_List_t * response_admitted_list = (RICaction_Admitted_List_t *) &(IE_array[2].value.choice.RICaction_Admitted_List);
|
||||
|
||||
for(int i = 0; i < response_admitted_list->list.size; i++){
|
||||
response_admitted_list->list.array[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (response_admitted_list->list.size > 0){
|
||||
free(response_admitted_list->list.array);
|
||||
response_admitted_list->list.array = 0;
|
||||
response_admitted_list->list.size = 0;
|
||||
response_admitted_list->list.count = 0;
|
||||
}
|
||||
|
||||
|
||||
RICaction_NotAdmitted_List_t * response_not_admitted_list = &(IE_array[3].value.choice.RICaction_NotAdmitted_List);
|
||||
for(int i = 0; i < response_not_admitted_list->list.size; i++){
|
||||
response_not_admitted_list->list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (response_not_admitted_list->list.size > 0){
|
||||
free(response_not_admitted_list->list.array);
|
||||
response_not_admitted_list->list.array = 0;
|
||||
response_not_admitted_list->list.size = 0;
|
||||
response_not_admitted_list->list.count = 0;
|
||||
}
|
||||
|
||||
RICsubscriptionResponse_t * ric_subscription_response = &(successMsg->value.choice.RICsubscriptionResponse);
|
||||
for(int i = 0; i < ric_subscription_response->protocolIEs.list.size ; i++){
|
||||
ric_subscription_response->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (ric_subscription_response->protocolIEs.list.size > 0){
|
||||
free(ric_subscription_response->protocolIEs.list.array);
|
||||
ric_subscription_response->protocolIEs.list.array = 0;
|
||||
ric_subscription_response->protocolIEs.list.size = 0;
|
||||
ric_subscription_response->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
|
||||
RICaction_NotAdmitted_List_t * failure_not_admitted_list = &(IE_Failure_array[2].value.choice.RICaction_NotAdmitted_List);
|
||||
for(int i = 0; i < failure_not_admitted_list->list.size; i++){
|
||||
failure_not_admitted_list->list.array[i] = 0;
|
||||
}
|
||||
|
||||
if ( failure_not_admitted_list->list.size > 0){
|
||||
free( failure_not_admitted_list->list.array);
|
||||
failure_not_admitted_list->list.array = 0;
|
||||
failure_not_admitted_list->list.size = 0;
|
||||
failure_not_admitted_list->list.count = 0;
|
||||
}
|
||||
|
||||
|
||||
RICsubscriptionFailure_t * ric_subscription_failure = &(unsuccessMsg->value.choice.RICsubscriptionFailure);
|
||||
for(int i = 0; i < ric_subscription_failure->protocolIEs.list.size; i++){
|
||||
ric_subscription_failure->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if ( ric_subscription_failure->protocolIEs.list.size > 0){
|
||||
free(ric_subscription_failure->protocolIEs.list.array);
|
||||
ric_subscription_failure->protocolIEs.list.array = 0;
|
||||
ric_subscription_failure->protocolIEs.list.size = 0;
|
||||
ric_subscription_failure->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
|
||||
free(ie_admitted_list);
|
||||
free(ie_not_admitted_list);
|
||||
free(IE_Failure_array);
|
||||
free(IE_array);
|
||||
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_SuccessfulOutcome, successMsg);
|
||||
ASN_STRUCT_FREE(asn_DEF_UnsuccessfulOutcome, unsuccessMsg);
|
||||
|
||||
|
||||
e2ap_pdu_obj->choice.initiatingMessage = NULL;
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_NOTHING;
|
||||
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed subscription response memory ");
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool subscription_response::encode_e2ap_subscription_response(unsigned char *buf, size_t *size, subscription_response_helper &dinput, bool is_success){
|
||||
|
||||
|
||||
if(is_success){
|
||||
set_fields_success(dinput);
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_successfulOutcome;
|
||||
e2ap_pdu_obj->choice.successfulOutcome = successMsg;
|
||||
|
||||
successMsg->procedureCode = ProcedureCode_id_RICsubscription;
|
||||
successMsg->criticality = Criticality_reject;
|
||||
successMsg->value.present = SuccessfulOutcome__value_PR_RICsubscriptionResponse;
|
||||
|
||||
}
|
||||
else{
|
||||
set_fields_unsuccess(dinput);
|
||||
e2ap_pdu_obj->present = E2AP_PDU_PR_unsuccessfulOutcome;
|
||||
e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
|
||||
|
||||
unsuccessMsg->procedureCode = ProcedureCode_id_RICsubscription;
|
||||
unsuccessMsg->criticality = Criticality_reject;
|
||||
unsuccessMsg->value.present = UnsuccessfulOutcome__value_PR_RICsubscriptionFailure;
|
||||
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding subscription response. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t res = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(res.encoded == -1){
|
||||
std::cout <<"Error encoding PDU. Reason =" << strerror(errno) << std::endl;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < res.encoded){
|
||||
fprintf(stderr, "Buffer assigned too small to encode: %s",(char *)(asn_DEF_E2AP_PDU.name));
|
||||
res.encoded = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = res.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void subscription_response::set_fields_success(subscription_response_helper &helper){
|
||||
|
||||
int ie_index;
|
||||
|
||||
RICsubscriptionResponse_t * subscription_response = &(successMsg->value.choice.RICsubscriptionResponse);
|
||||
//reset list count ..
|
||||
subscription_response->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
RICsubscriptionResponse_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICsubscriptionResponse_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
// ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
|
||||
|
||||
|
||||
ie_index = 1;
|
||||
RICsubscriptionResponse_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICsubscriptionResponse_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
|
||||
|
||||
|
||||
ie_index = 2;
|
||||
RICsubscriptionResponse_IEs_t *ies_admitted_actid = &IE_array[ie_index];
|
||||
ies_admitted_actid->criticality = Criticality_reject;
|
||||
ies_admitted_actid->id = ProtocolIE_ID_id_RICactions_Admitted;
|
||||
RICaction_Admitted_List_t *ric_admitted_actions_ie = &ies_admitted_actid->value.choice.RICaction_Admitted_List;
|
||||
ric_admitted_actions_ie->list.count = 0;
|
||||
std::vector<ActionResponse> * ref_admitted_action_array = helper.get_admitted_list();
|
||||
|
||||
if(ref_admitted_action_array->size() == 0){
|
||||
ies_admitted_actid->value.present = RICsubscriptionResponse_IEs__value_PR_NOTHING;
|
||||
}
|
||||
else{
|
||||
ies_admitted_actid->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
|
||||
|
||||
// resize memory ?
|
||||
if (ref_admitted_action_array->size() >= ie_admitted_list_size){
|
||||
ie_admitted_list_size = 2 * ref_admitted_action_array->size();
|
||||
free(ie_admitted_list);
|
||||
ie_admitted_list = (RICaction_Admitted_ItemIEs_t *)calloc(ie_admitted_list_size, sizeof(RICaction_Admitted_ItemIEs_t));
|
||||
assert(ie_admitted_list != 0);
|
||||
};
|
||||
|
||||
|
||||
for(unsigned int i = 0; i < ref_admitted_action_array->size(); i ++){
|
||||
ie_admitted_list[i].criticality = Criticality_ignore;
|
||||
ie_admitted_list[i].id = ProtocolIE_ID_id_RICaction_Admitted_Item ;
|
||||
ie_admitted_list[i].value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
|
||||
ie_admitted_list[i].value.choice.RICaction_Admitted_Item.ricActionID = (*ref_admitted_action_array)[i].get_id();
|
||||
ASN_SEQUENCE_ADD(ric_admitted_actions_ie, &(ie_admitted_list[i]));
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
|
||||
|
||||
// optional IE : add only if non-zero list
|
||||
ie_index = 3;
|
||||
std::vector<ActionResponse> * ref_notadmitted_action_array = helper.get_not_admitted_list();
|
||||
if (ref_notadmitted_action_array->size() > 0){
|
||||
|
||||
RICsubscriptionResponse_IEs_t *ies_notadmitted_actid = &IE_array[ie_index];
|
||||
ies_notadmitted_actid->criticality = Criticality_reject;
|
||||
ies_notadmitted_actid->id = ProtocolIE_ID_id_RICactions_NotAdmitted;
|
||||
|
||||
RICaction_NotAdmitted_List_t *ric_not_admitted_actions_ie = &ies_notadmitted_actid->value.choice.RICaction_NotAdmitted_List;
|
||||
ric_not_admitted_actions_ie->list.count = 0;
|
||||
|
||||
|
||||
ies_notadmitted_actid->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_NotAdmitted_List;
|
||||
|
||||
// resize memory ?
|
||||
if (ref_notadmitted_action_array->size() >= ie_not_admitted_list_size){
|
||||
ie_not_admitted_list_size = 2 * ref_notadmitted_action_array->size();
|
||||
free(ie_not_admitted_list);
|
||||
ie_not_admitted_list = (RICaction_NotAdmitted_ItemIEs_t *)calloc(ie_not_admitted_list_size, sizeof(RICaction_NotAdmitted_ItemIEs_t));
|
||||
assert(ie_not_admitted_list != 0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
for(unsigned int i = 0; i < ref_notadmitted_action_array->size(); i ++){
|
||||
ie_not_admitted_list[i].criticality = Criticality_ignore;
|
||||
ie_not_admitted_list[i].id = ProtocolIE_ID_id_RICaction_NotAdmitted_Item ;
|
||||
ie_not_admitted_list[i].value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;;
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricActionID = (*ref_notadmitted_action_array)[i].get_id();
|
||||
|
||||
int cause = (*ref_notadmitted_action_array)[i].get_cause();
|
||||
switch(cause){
|
||||
case Cause_PR_ricService:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case Cause_PR_transport:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.transport = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case Cause_PR_protocol:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol= (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case Cause_PR_misc:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.misc = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case Cause_PR_ricRequest:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
default:
|
||||
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
|
||||
return;
|
||||
}
|
||||
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.present = (Cause_PR)cause;
|
||||
ASN_SEQUENCE_ADD(ric_not_admitted_actions_ie, &(ie_not_admitted_list[i]));
|
||||
}
|
||||
|
||||
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void subscription_response:: get_fields(SuccessfulOutcome_t * success_msg, subscription_response_helper & dout)
|
||||
{
|
||||
|
||||
assert(success_msg != NULL);
|
||||
|
||||
RICrequestID_t *requestid;
|
||||
RANfunctionID_t * ranfunctionid;
|
||||
RICaction_Admitted_List_t * ric_admitted_action_list;
|
||||
RICaction_NotAdmitted_List_t * ric_not_admitted_action_list;
|
||||
|
||||
for(int edx = 0; edx < success_msg->value.choice.RICsubscriptionResponse.protocolIEs.list.count; edx++) {
|
||||
RICsubscriptionResponse_IEs_t *memb_ptr = success_msg->value.choice.RICsubscriptionResponse.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICactions_Admitted):
|
||||
ric_admitted_action_list = &memb_ptr->value.choice.RICaction_Admitted_List;
|
||||
|
||||
// admitted actions
|
||||
for(int index = 0; index < ric_admitted_action_list->list.count; index ++){
|
||||
RICaction_Admitted_ItemIEs_t * item = (RICaction_Admitted_ItemIEs_t *)ric_admitted_action_list->list.array[index];
|
||||
long int id = item->value.choice.RICaction_Admitted_Item.ricActionID;
|
||||
dout.get_admitted_list()->push_back(ActionResponse(id));
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RICactions_NotAdmitted):
|
||||
ric_not_admitted_action_list = &memb_ptr->value.choice.RICaction_NotAdmitted_List;
|
||||
|
||||
for(int index = 0; index < ric_not_admitted_action_list->list.count; index ++){
|
||||
RICaction_NotAdmitted_ItemIEs_t * item = (RICaction_NotAdmitted_ItemIEs_t *)ric_not_admitted_action_list->list.array[index];
|
||||
long int id = item->value.choice.RICaction_NotAdmitted_Item.ricActionID;
|
||||
int cause = item->value.choice.RICaction_NotAdmitted_Item.cause.present;
|
||||
int sub_cause;
|
||||
switch(cause){
|
||||
|
||||
case Cause_PR_ricService :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService;
|
||||
break;
|
||||
|
||||
case Cause_PR_transport :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.transport;
|
||||
break;
|
||||
|
||||
case Cause_PR_protocol :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol;
|
||||
break;
|
||||
|
||||
case Cause_PR_misc :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.misc;
|
||||
break;
|
||||
|
||||
case Cause_PR_ricRequest :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest;
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cout <<"Error ! Illegal cause enum" << cause << std::endl;
|
||||
return;
|
||||
}
|
||||
dout.get_not_admitted_list()->push_back(ActionResponse(id, cause, sub_cause));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
|
||||
void subscription_response::set_fields_unsuccess( subscription_response_helper &helper){
|
||||
|
||||
int ie_index;
|
||||
RICsubscriptionFailure_t * ric_subscription_failure = &(unsuccessMsg->value.choice.RICsubscriptionFailure);
|
||||
// reset list count
|
||||
ric_subscription_failure->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
RICsubscriptionFailure_IEs_t *ies_ricreq = &IE_Failure_array[ie_index];
|
||||
ies_ricreq->criticality = Criticality_reject;
|
||||
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
|
||||
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
// ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, &(IE_Failure_array[ie_index]));
|
||||
|
||||
ie_index = 1;
|
||||
RICsubscriptionFailure_IEs_t *ies_ranfunc = &IE_Failure_array[ie_index];
|
||||
ies_ranfunc->criticality = Criticality_reject;
|
||||
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
|
||||
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, &(IE_Failure_array[ie_index]));
|
||||
|
||||
ie_index = 2;
|
||||
RICsubscriptionFailure_IEs_t *ies_notadmitted_actid = &IE_Failure_array[ie_index];
|
||||
ies_notadmitted_actid->criticality = Criticality_reject;
|
||||
ies_notadmitted_actid->id = ProtocolIE_ID_id_RICactions_NotAdmitted;
|
||||
RICaction_NotAdmitted_List_t *ric_not_admitted_actions_ie = &ies_notadmitted_actid->value.choice.RICaction_NotAdmitted_List;
|
||||
ric_not_admitted_actions_ie->list.count = 0;
|
||||
std::vector<ActionResponse> * ref_notadmitted_action_array = helper.get_not_admitted_list();
|
||||
if(ref_notadmitted_action_array->size() == 0){
|
||||
ies_notadmitted_actid->value.present = RICsubscriptionFailure_IEs__value_PR_NOTHING;
|
||||
}
|
||||
else{
|
||||
ies_notadmitted_actid->value.present = RICsubscriptionFailure_IEs__value_PR_RICaction_NotAdmitted_List;
|
||||
|
||||
// resize memory ?
|
||||
if (ref_notadmitted_action_array->size() >= ie_not_admitted_list_size){
|
||||
ie_not_admitted_list_size = 2 * ref_notadmitted_action_array->size();
|
||||
free(ie_not_admitted_list);
|
||||
ie_not_admitted_list = (RICaction_NotAdmitted_ItemIEs_t *)calloc(ie_not_admitted_list_size, sizeof(RICaction_NotAdmitted_ItemIEs_t));
|
||||
assert(ie_not_admitted_list != 0);
|
||||
};
|
||||
|
||||
|
||||
// reset the list count on ricAction_ToBeSetup_List;
|
||||
for(unsigned int i = 0; i < ref_notadmitted_action_array->size(); i ++){
|
||||
ie_not_admitted_list[i].criticality = Criticality_ignore;
|
||||
ie_not_admitted_list[i].id = ProtocolIE_ID_id_RICaction_NotAdmitted_Item ;
|
||||
ie_not_admitted_list[i].value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;;
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricActionID = (*ref_notadmitted_action_array)[i].get_id();
|
||||
|
||||
int cause = (*ref_notadmitted_action_array)[i].get_cause();
|
||||
switch(cause){
|
||||
case Cause_PR_ricService:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case Cause_PR_transport:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.transport = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case Cause_PR_protocol:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol= (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case Cause_PR_misc:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.misc = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case Cause_PR_ricRequest:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
default:
|
||||
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
|
||||
return ;
|
||||
}
|
||||
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.present = (Cause_PR)cause;
|
||||
|
||||
ASN_SEQUENCE_ADD(ric_not_admitted_actions_ie, &(ie_not_admitted_list[i]));
|
||||
}
|
||||
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, &(IE_Failure_array[ie_index]));
|
||||
|
||||
|
||||
// // criticality diagnostics is not generated/parsed currently since optional
|
||||
// i = 3;
|
||||
// RICsubscriptionFailure_IEs_t *ies_criticality_diagnostics= &IE_Failure_array[i];
|
||||
// ies_criticality_diagnostics->criticality = Criticality_ignore;
|
||||
// ies_criticality_diagnostics->id = ProtocolIE_ID_id_CriticalityDiagnostics ;
|
||||
// ies_criticality_diagnostics->value.present = RICsubscriptionFailure_IEs__value_PR_NOTHING;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void subscription_response:: get_fields(UnsuccessfulOutcome_t * unsuccess_msg, subscription_response_helper & dout)
|
||||
{
|
||||
|
||||
assert(unsuccess_msg != NULL);
|
||||
|
||||
RICrequestID_t *requestid;
|
||||
RANfunctionID_t * ranfunctionid;
|
||||
RICaction_NotAdmitted_List_t * ric_not_admitted_action_list;
|
||||
|
||||
for(int edx = 0; edx < unsuccess_msg->value.choice.RICsubscriptionFailure.protocolIEs.list.count; edx++) {
|
||||
RICsubscriptionFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICsubscriptionFailure.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
|
||||
case (ProtocolIE_ID_id_RICactions_NotAdmitted):
|
||||
ric_not_admitted_action_list = &memb_ptr->value.choice.RICaction_NotAdmitted_List;
|
||||
|
||||
for(int index = 0; index < ric_not_admitted_action_list->list.count; index ++){
|
||||
RICaction_NotAdmitted_ItemIEs_t * item = (RICaction_NotAdmitted_ItemIEs_t *)ric_not_admitted_action_list->list.array[index];
|
||||
long int id = item->value.choice.RICaction_NotAdmitted_Item.ricActionID;
|
||||
int cause = item->value.choice.RICaction_NotAdmitted_Item.cause.present;
|
||||
int sub_cause;
|
||||
switch(cause){
|
||||
|
||||
case Cause_PR_ricService :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService;
|
||||
break;
|
||||
|
||||
case Cause_PR_transport :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.transport;
|
||||
break;
|
||||
|
||||
case Cause_PR_protocol :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol;
|
||||
break;
|
||||
|
||||
case Cause_PR_misc :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.misc;
|
||||
break;
|
||||
|
||||
case Cause_PR_ricRequest :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest;
|
||||
break;
|
||||
|
||||
default:
|
||||
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
|
||||
return;
|
||||
}
|
||||
dout.get_not_admitted_list()->push_back(ActionResponse(id, cause, sub_cause));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_RESPONSE_
|
||||
#define S_RESPONSE_
|
||||
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <asn_application.h>
|
||||
#include <E2AP-PDU.h>
|
||||
#include <SuccessfulOutcome.h>
|
||||
#include <UnsuccessfulOutcome.h>
|
||||
#include <ProtocolIE-Field.h>
|
||||
#include <ProtocolIE-SingleContainer.h>
|
||||
#include <ProcedureCode.h>
|
||||
#include "response_helper.hpp"
|
||||
|
||||
#define NUM_SUBSCRIPTION_RESPONSE_IES 4
|
||||
#define NUM_SUBSCRIPTION_FAILURE_IES 3
|
||||
#define INITIAL_RESPONSE_LIST_SIZE 4
|
||||
|
||||
class subscription_response{
|
||||
public:
|
||||
|
||||
subscription_response(void);
|
||||
~subscription_response(void);
|
||||
|
||||
bool encode_e2ap_subscription_response(unsigned char *, size_t *, subscription_response_helper &, bool);
|
||||
void get_fields(SuccessfulOutcome_t *, subscription_response_helper &);
|
||||
void get_fields(UnsuccessfulOutcome_t *, subscription_response_helper &);
|
||||
|
||||
std::string get_error(void) const{
|
||||
return error_string;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void set_fields_success( subscription_response_helper &);
|
||||
void set_fields_unsuccess( subscription_response_helper &);
|
||||
|
||||
E2AP_PDU_t * e2ap_pdu_obj;
|
||||
SuccessfulOutcome_t * successMsg;
|
||||
UnsuccessfulOutcome_t * unsuccessMsg;
|
||||
|
||||
|
||||
RICsubscriptionResponse_IEs_t *IE_array;
|
||||
RICsubscriptionFailure_IEs_t *IE_Failure_array;
|
||||
|
||||
|
||||
RICaction_Admitted_ItemIEs_t * ie_admitted_list;
|
||||
RICaction_NotAdmitted_ItemIEs_t * ie_not_admitted_list;
|
||||
unsigned int ie_admitted_list_size, ie_not_admitted_list_size;
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
195
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_control.cc
Normal file
195
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_control.cc
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, softwares
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* e2sm_control.cc
|
||||
*
|
||||
* Created on: Apr 30, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
/* Classes to handle E2 service model based on e2sm-HelloWorld-v001.asn */
|
||||
#include "e2sm_control.hpp"
|
||||
|
||||
//initialize
|
||||
e2sm_control::e2sm_control(void){
|
||||
|
||||
memset(&head_fmt1, 0, sizeof(E2SM_HelloWorld_ControlHeader_Format1_t));
|
||||
|
||||
memset(&msg_fmt1, 0, sizeof(E2SM_HelloWorld_ControlMessage_Format1_t));
|
||||
|
||||
|
||||
|
||||
control_head = 0;
|
||||
control_head = ( E2SM_HelloWorld_ControlHeader_t *)calloc(1, sizeof( E2SM_HelloWorld_ControlHeader_t));
|
||||
assert(control_head != 0);
|
||||
|
||||
control_msg = 0;
|
||||
control_msg = (E2SM_HelloWorld_ControlMessage_t*)calloc(1, sizeof(E2SM_HelloWorld_ControlMessage_t));
|
||||
assert(control_msg !=0);
|
||||
|
||||
errbuf_len = 128;
|
||||
};
|
||||
|
||||
e2sm_control::~e2sm_control(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing event trigger object memory");
|
||||
|
||||
control_head->choice.controlHeader_Format1 = 0;
|
||||
|
||||
control_msg->choice.controlMessage_Format1 = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2SM_HelloWorld_ControlHeader, control_head);
|
||||
ASN_STRUCT_FREE(asn_DEF_E2SM_HelloWorld_ControlMessage, control_msg);
|
||||
|
||||
|
||||
};
|
||||
|
||||
bool e2sm_control::encode_control_header(unsigned char *buf, size_t *size, e2sm_control_helper &helper){
|
||||
|
||||
ASN_STRUCT_RESET(asn_DEF_E2SM_HelloWorld_ControlHeader, control_head);
|
||||
|
||||
bool res;
|
||||
res = set_fields(control_head, helper);
|
||||
if (!res){
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2SM_HelloWorld_ControlHeader, control_head, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_E2SM_HelloWorld_ControlHeader, control_head);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_HelloWorld_ControlHeader, control_head, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding event trigger definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e2sm_control::encode_control_message(unsigned char *buf, size_t *size, e2sm_control_helper &helper){
|
||||
|
||||
bool res;
|
||||
res = set_fields(control_msg, helper);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2SM_HelloWorld_ControlMessage, control_msg, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_E2SM_HelloWorld_ControlMessage, control_msg);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_HelloWorld_ControlMessage, control_msg, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding action definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e2sm_control::set_fields(E2SM_HelloWorld_ControlHeader_t * ref_control_head, e2sm_control_helper & helper){
|
||||
|
||||
if(ref_control_head == 0){
|
||||
error_string = "Invalid reference for Event Trigger Definition set fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
ref_control_head->present = E2SM_HelloWorld_ControlHeader_PR_controlHeader_Format1;
|
||||
|
||||
head_fmt1.controlHeaderParam = helper.header;
|
||||
|
||||
ref_control_head->choice.controlHeader_Format1 = &head_fmt1;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool e2sm_control::set_fields(E2SM_HelloWorld_ControlMessage_t * ref_control_msg, e2sm_control_helper & helper){
|
||||
|
||||
if(ref_control_msg == 0){
|
||||
error_string = "Invalid reference for Event Action Definition set fields";
|
||||
return false;
|
||||
}
|
||||
ref_control_msg->present = E2SM_HelloWorld_ControlMessage_PR_controlMessage_Format1;
|
||||
|
||||
msg_fmt1.controlMsgParam.buf = helper.message;
|
||||
msg_fmt1.controlMsgParam.size = helper.message_len;
|
||||
|
||||
|
||||
ref_control_msg->choice.controlMessage_Format1 = &msg_fmt1;
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool e2sm_control::get_fields(E2SM_HelloWorld_ControlHeader_t * ref_indictaion_header, e2sm_control_helper & helper){
|
||||
|
||||
if (ref_indictaion_header == 0){
|
||||
error_string = "Invalid reference for Control Header get fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
helper.header = ref_indictaion_header->choice.controlHeader_Format1->controlHeaderParam;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e2sm_control::get_fields(E2SM_HelloWorld_ControlMessage_t * ref_control_message, e2sm_control_helper & helper){
|
||||
|
||||
if (ref_control_message == 0){
|
||||
error_string = "Invalid reference for Control Message get fields";
|
||||
return false;
|
||||
}
|
||||
helper.message = ref_control_message->choice.controlMessage_Format1->controlMsgParam.buf;
|
||||
helper.message_len = ref_control_message->choice.controlMessage_Format1->controlMsgParam.size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
73
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_control.hpp
Normal file
73
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_control.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, softwares
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* e2sm_control.hpp
|
||||
*
|
||||
* Created on: Apr, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
/* Classes to handle E2 service model based on e2sm-HelloWorld-v001.asn */
|
||||
#ifndef SRC_XAPP_ASN_E2SM_E2SM_CONTROL_HPP_
|
||||
#define SRC_XAPP_ASN_E2SM_E2SM_CONTROL_HPP_
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <e2sm_helpers.hpp>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
|
||||
#include <E2SM-HelloWorld-ControlHeader.h>
|
||||
#include <E2SM-HelloWorld-ControlMessage.h>
|
||||
#include <E2SM-HelloWorld-ControlHeader-Format1.h>
|
||||
#include <E2SM-HelloWorld-ControlMessage-Format1.h>
|
||||
#include <HW-Header.h>
|
||||
#include <HW-Message.h>
|
||||
class e2sm_control {
|
||||
public:
|
||||
e2sm_control(void);
|
||||
~e2sm_control(void);
|
||||
|
||||
bool set_fields(E2SM_HelloWorld_ControlHeader_t *, e2sm_control_helper &);
|
||||
bool set_fields(E2SM_HelloWorld_ControlMessage_t *, e2sm_control_helper &);
|
||||
|
||||
bool get_fields(E2SM_HelloWorld_ControlHeader_t *, e2sm_control_helper &);
|
||||
bool get_fields(E2SM_HelloWorld_ControlMessage_t *, e2sm_control_helper &);
|
||||
|
||||
bool encode_control_header(unsigned char *, size_t *, e2sm_control_helper &);
|
||||
bool encode_control_message(unsigned char*, size_t *, e2sm_control_helper &);
|
||||
|
||||
|
||||
std::string get_error (void) const {return error_string ;};
|
||||
|
||||
private:
|
||||
|
||||
E2SM_HelloWorld_ControlHeader_t * control_head; // used for encoding
|
||||
E2SM_HelloWorld_ControlMessage_t* control_msg;
|
||||
E2SM_HelloWorld_ControlHeader_Format1_t head_fmt1;
|
||||
E2SM_HelloWorld_ControlMessage_Format1_t msg_fmt1;
|
||||
|
||||
|
||||
size_t errbuf_len;
|
||||
char errbuf[128];
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_XAPP_ASN_E2SM_E2SM_CONTROL_HPP_ */
|
109
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_helpers.hpp
Normal file
109
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_helpers.hpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, softwares
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* e2sm_control.cc
|
||||
*
|
||||
* Created on: Apr 30, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
/* Classes to handle E2 service model based on e2sm-HelloWorld-v001.asn */
|
||||
#ifndef E2SM_HELPER_
|
||||
#define E2SM_HELPER_
|
||||
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
|
||||
typedef struct ranparam_helper ranparam_helper;
|
||||
struct ranparam_helper {
|
||||
long int _param_id;
|
||||
unsigned char* _param_name;
|
||||
size_t _param_name_len;
|
||||
int _param_test;
|
||||
unsigned char* _param_value;
|
||||
size_t _param_value_len;
|
||||
|
||||
};
|
||||
class RANParam_Helper{
|
||||
private:
|
||||
ranparam_helper _ranparam_helper;
|
||||
|
||||
public:
|
||||
|
||||
RANParam_Helper(int id, unsigned char *param_name, size_t param_name_len, int param_test, unsigned char* param_value, size_t param_value_len){
|
||||
_ranparam_helper._param_id = id;
|
||||
_ranparam_helper._param_name = param_name;
|
||||
_ranparam_helper._param_name_len = param_name_len;
|
||||
_ranparam_helper._param_test = param_test;
|
||||
_ranparam_helper._param_value = param_value;
|
||||
_ranparam_helper._param_value_len = param_value_len;
|
||||
}
|
||||
|
||||
const ranparam_helper & getran_helper() const {
|
||||
return _ranparam_helper;
|
||||
}
|
||||
void print_ranparam_info(void){
|
||||
std::cout <<"Param ID = " << _ranparam_helper._param_id << std::endl;
|
||||
std::cout << "Parame Name =" << _ranparam_helper._param_name << std::endl;
|
||||
std::cout <<"Param Test = " << _ranparam_helper._param_test << std::endl;
|
||||
std::cout <<"Param Value = " << _ranparam_helper._param_value << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
using ranparam_helper_t = std::vector<RANParam_Helper>;
|
||||
|
||||
typedef struct e2sm_subscription_helper e2sm_subscription_helper;
|
||||
struct e2sm_subscription_helper {
|
||||
public:
|
||||
|
||||
|
||||
int triger_nature;
|
||||
ranparam_helper_t param;
|
||||
void add_param(int id, unsigned char *param_name, size_t param_name_len, int param_test, unsigned char* param_value, size_t param_value_len){
|
||||
RANParam_Helper rparam(id,param_name,param_name_len,param_test,param_value,param_value_len);
|
||||
param.push_back(rparam);
|
||||
};
|
||||
ranparam_helper_t get_paramlist() const {return param;};
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct e2sm_indication_helper e2sm_indication_helper;
|
||||
|
||||
|
||||
struct e2sm_indication_helper {
|
||||
long int header;
|
||||
unsigned char* message;
|
||||
size_t message_len;
|
||||
};
|
||||
|
||||
typedef struct e2sm_control_helper e2sm_control_helper;
|
||||
|
||||
struct e2sm_control_helper {
|
||||
long int header;
|
||||
unsigned char* message;
|
||||
size_t message_len;
|
||||
};
|
||||
|
||||
#endif
|
192
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_indication.cc
Normal file
192
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_indication.cc
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* e2sm_indication.cc
|
||||
*
|
||||
* Created on: Apr, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
/* Classes to handle E2 service model based on e2sm-HelloWorld-v001.asn */
|
||||
#include "e2sm_indication.hpp"
|
||||
|
||||
//initialize
|
||||
e2sm_indication::e2sm_indication(void){
|
||||
|
||||
memset(&head_fmt1, 0, sizeof(E2SM_HelloWorld_IndicationHeader_Format1_t));
|
||||
|
||||
memset(&msg_fmt1, 0, sizeof(E2SM_HelloWorld_IndicationMessage_Format1_t));
|
||||
|
||||
|
||||
|
||||
indication_head = 0;
|
||||
indication_head = ( E2SM_HelloWorld_IndicationHeader_t *)calloc(1, sizeof( E2SM_HelloWorld_IndicationHeader_t));
|
||||
assert(indication_head != 0);
|
||||
|
||||
indication_msg = 0;
|
||||
indication_msg = (E2SM_HelloWorld_IndicationMessage_t*)calloc(1, sizeof(E2SM_HelloWorld_IndicationMessage_t));
|
||||
assert(indication_msg !=0);
|
||||
|
||||
errbuf_len = 128;
|
||||
};
|
||||
|
||||
e2sm_indication::~e2sm_indication(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing event trigger object memory");
|
||||
|
||||
indication_head->choice.indicationHeader_Format1 = 0;
|
||||
|
||||
indication_msg->choice.indicationMessage_Format1 = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2SM_HelloWorld_IndicationHeader, indication_head);
|
||||
ASN_STRUCT_FREE(asn_DEF_E2SM_HelloWorld_IndicationMessage, indication_msg);
|
||||
|
||||
|
||||
};
|
||||
|
||||
bool e2sm_indication::encode_indication_header(unsigned char *buf, size_t *size, e2sm_indication_helper &helper){
|
||||
|
||||
ASN_STRUCT_RESET(asn_DEF_E2SM_HelloWorld_IndicationHeader, indication_head);
|
||||
|
||||
bool res;
|
||||
res = set_fields(indication_head, helper);
|
||||
if (!res){
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2SM_HelloWorld_IndicationHeader, indication_head, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_E2SM_HelloWorld_IndicationHeader, indication_head);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_HelloWorld_IndicationHeader, indication_head, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding event trigger definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e2sm_indication::encode_indication_message(unsigned char *buf, size_t *size, e2sm_indication_helper &helper){
|
||||
|
||||
bool res;
|
||||
res = set_fields(indication_msg, helper);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2SM_HelloWorld_IndicationMessage, indication_msg, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_E2SM_HelloWorld_IndicationMessage, indication_msg);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_HelloWorld_IndicationMessage, indication_msg, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding action definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e2sm_indication::set_fields(E2SM_HelloWorld_IndicationHeader_t * ref_indication_head, e2sm_indication_helper & helper){
|
||||
|
||||
if(ref_indication_head == 0){
|
||||
error_string = "Invalid reference for Event Trigger Definition set fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
ref_indication_head->present = E2SM_HelloWorld_IndicationHeader_PR_indicationHeader_Format1;
|
||||
|
||||
head_fmt1.indicationHeaderParam = helper.header;
|
||||
|
||||
ref_indication_head->choice.indicationHeader_Format1 = &head_fmt1;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool e2sm_indication::set_fields(E2SM_HelloWorld_IndicationMessage_t * ref_indication_msg, e2sm_indication_helper & helper){
|
||||
|
||||
if(ref_indication_msg == 0){
|
||||
error_string = "Invalid reference for Event Action Definition set fields";
|
||||
return false;
|
||||
}
|
||||
ref_indication_msg->present = E2SM_HelloWorld_IndicationMessage_PR_indicationMessage_Format1;
|
||||
|
||||
msg_fmt1.indicationMsgParam.buf = helper.message;
|
||||
msg_fmt1.indicationMsgParam.size = helper.message_len;
|
||||
|
||||
|
||||
ref_indication_msg->choice.indicationMessage_Format1 = &msg_fmt1;
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool e2sm_indication::get_fields(E2SM_HelloWorld_IndicationHeader_t * ref_indictaion_header, e2sm_indication_helper & helper){
|
||||
|
||||
if (ref_indictaion_header == 0){
|
||||
error_string = "Invalid reference for Indication Header get fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
helper.header = ref_indictaion_header->choice.indicationHeader_Format1->indicationHeaderParam;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e2sm_indication::get_fields(E2SM_HelloWorld_IndicationMessage_t * ref_indication_message, e2sm_indication_helper & helper){
|
||||
|
||||
if (ref_indication_message == 0){
|
||||
error_string = "Invalid reference for Indication Message get fields";
|
||||
return false;
|
||||
}
|
||||
helper.message = ref_indication_message->choice.indicationMessage_Format1->indicationMsgParam.buf;
|
||||
helper.message_len = ref_indication_message->choice.indicationMessage_Format1->indicationMsgParam.size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* e2sm_indication.hpp
|
||||
*
|
||||
* Created on: Apr, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
|
||||
/* Classes to handle E2 service model based on e2sm-HelloWorld-v001.asn */
|
||||
#ifndef SRC_XAPP_ASN_E2SM_E2SM_INDICATION_HPP_
|
||||
#define SRC_XAPP_ASN_E2SM_E2SM_INDICATION_HPP_
|
||||
|
||||
#include <sstream>
|
||||
#include <e2sm_helpers.hpp>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
|
||||
#include <E2SM-HelloWorld-IndicationHeader.h>
|
||||
#include <E2SM-HelloWorld-IndicationMessage.h>
|
||||
#include <E2SM-HelloWorld-IndicationHeader-Format1.h>
|
||||
#include <E2SM-HelloWorld-IndicationMessage-Format1.h>
|
||||
#include <HW-Header.h>
|
||||
#include <HW-Message.h>
|
||||
|
||||
class e2sm_indication {
|
||||
public:
|
||||
e2sm_indication(void);
|
||||
~e2sm_indication(void);
|
||||
|
||||
bool set_fields(E2SM_HelloWorld_IndicationHeader_t *, e2sm_indication_helper &);
|
||||
bool set_fields(E2SM_HelloWorld_IndicationMessage_t *, e2sm_indication_helper &);
|
||||
|
||||
bool get_fields(E2SM_HelloWorld_IndicationHeader_t *, e2sm_indication_helper &);
|
||||
bool get_fields(E2SM_HelloWorld_IndicationMessage_t *, e2sm_indication_helper &);
|
||||
|
||||
bool encode_indication_header(unsigned char *, size_t *, e2sm_indication_helper &);
|
||||
bool encode_indication_message(unsigned char*, size_t *, e2sm_indication_helper &);
|
||||
|
||||
|
||||
std::string get_error (void) const {return error_string ;};
|
||||
|
||||
private:
|
||||
|
||||
E2SM_HelloWorld_IndicationHeader_t * indication_head; // used for encoding
|
||||
E2SM_HelloWorld_IndicationMessage_t* indication_msg;
|
||||
E2SM_HelloWorld_IndicationHeader_Format1_t head_fmt1;
|
||||
E2SM_HelloWorld_IndicationMessage_Format1_t msg_fmt1;
|
||||
|
||||
|
||||
size_t errbuf_len;
|
||||
char errbuf[128];
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_XAPP_ASN_E2SM_E2SM_INDICATION_HPP_ */
|
185
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_subscription.cc
Normal file
185
setup/xapp-bs-connector/src/xapp-asn/e2sm/e2sm_subscription.cc
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, softwares
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* e2sm_control.cc
|
||||
*
|
||||
* Created on: Apr 30, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
/* Classes to handle E2 service model based on e2sm-HelloWorld-v001.asn */
|
||||
|
||||
#include "e2sm_subscription.hpp"
|
||||
|
||||
//initialize
|
||||
e2sm_subscription::e2sm_subscription(void){
|
||||
|
||||
memset(&event_fmt1, 0, sizeof(E2SM_HelloWorld_EventTriggerDefinition_Format1_t));
|
||||
|
||||
memset(&actn_fmt1, 0, sizeof(E2SM_HelloWorld_ActionDefinition_Format1_t));
|
||||
|
||||
|
||||
ran_param = 0;
|
||||
ran_param = (RANparameter_Item_t*)calloc(1, sizeof(RANparameter_Item_t));
|
||||
assert(ran_param != 0);
|
||||
|
||||
event_trigger = 0;
|
||||
event_trigger = ( E2SM_HelloWorld_EventTriggerDefinition_t *)calloc(1, sizeof( E2SM_HelloWorld_EventTriggerDefinition_t));
|
||||
assert(event_trigger != 0);
|
||||
|
||||
action_defn = 0;
|
||||
action_defn = (E2SM_HelloWorld_ActionDefinition_t*)calloc(1, sizeof(E2SM_HelloWorld_ActionDefinition_t));
|
||||
assert(action_defn !=0);
|
||||
|
||||
errbuf_len = 128;
|
||||
};
|
||||
|
||||
e2sm_subscription::~e2sm_subscription(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing event trigger object memory");
|
||||
|
||||
event_trigger->choice.eventDefinition_Format1 = 0;
|
||||
|
||||
action_defn->choice.actionDefinition_Format1 = 0;
|
||||
|
||||
free(ran_param);
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2SM_HelloWorld_EventTriggerDefinition, event_trigger);
|
||||
ASN_STRUCT_FREE(asn_DEF_E2SM_HelloWorld_ActionDefinition, action_defn);
|
||||
|
||||
|
||||
};
|
||||
|
||||
bool e2sm_subscription::encode_event_trigger(unsigned char *buf, size_t *size, e2sm_subscription_helper &helper){
|
||||
|
||||
ASN_STRUCT_RESET(asn_DEF_E2SM_HelloWorld_EventTriggerDefinition, event_trigger);
|
||||
|
||||
bool res;
|
||||
res = set_fields(event_trigger, helper);
|
||||
if (!res){
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2SM_HelloWorld_EventTriggerDefinition, event_trigger, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_E2SM_HelloWorld_EventTriggerDefinition, event_trigger);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_HelloWorld_EventTriggerDefinition, event_trigger, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding event trigger definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e2sm_subscription::encode_action_defn(unsigned char *buf, size_t *size, e2sm_subscription_helper &helper){
|
||||
|
||||
bool res;
|
||||
res = set_fields(action_defn, helper);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2SM_HelloWorld_ActionDefinition, action_defn, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_E2SM_HelloWorld_ActionDefinition, action_defn);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_HelloWorld_ActionDefinition, action_defn, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding action definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e2sm_subscription::set_fields(E2SM_HelloWorld_EventTriggerDefinition_t * ref_event_trigger, e2sm_subscription_helper & helper){
|
||||
|
||||
if(ref_event_trigger == 0){
|
||||
error_string = "Invalid reference for Event Trigger Definition set fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
ref_event_trigger->present = E2SM_HelloWorld_EventTriggerDefinition_PR_eventDefinition_Format1;
|
||||
|
||||
event_fmt1.triggerNature = helper.triger_nature;
|
||||
|
||||
ref_event_trigger->choice.eventDefinition_Format1 = &event_fmt1;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool e2sm_subscription::set_fields(E2SM_HelloWorld_ActionDefinition_t * ref_action_defn, e2sm_subscription_helper & helper){
|
||||
|
||||
if(ref_action_defn == 0){
|
||||
error_string = "Invalid reference for Event Action Definition set fields";
|
||||
return false;
|
||||
}
|
||||
ref_action_defn->present = E2SM_HelloWorld_ActionDefinition_PR_actionDefinition_Format1;
|
||||
|
||||
|
||||
ranparam_helper_t paramlst = helper.get_paramlist();
|
||||
|
||||
for(RANParam_Helper item:paramlst){
|
||||
ran_param->ranParameter_ID = item.getran_helper()._param_id;
|
||||
ran_param->ranParameter_Name.buf = item.getran_helper()._param_name;
|
||||
ran_param->ranParameter_Name.size = item.getran_helper()._param_name_len;
|
||||
ran_param->ranParameter_Test = item.getran_helper()._param_test;
|
||||
ran_param->ranParameter_Value.buf = item.getran_helper()._param_value;
|
||||
ran_param->ranParameter_Value.size = item.getran_helper()._param_value_len;
|
||||
ASN_SEQUENCE_ADD(&(actn_fmt1.ranParameter_List->list.array), ran_param);
|
||||
}
|
||||
|
||||
|
||||
ref_action_defn->choice.actionDefinition_Format1 = &actn_fmt1;
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* e2sm_control.cc
|
||||
*
|
||||
* Created on: Apr 30, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
/* Classes to handle E2 service model based on e2sm-HelloWorld-v001.asn */
|
||||
#ifndef E2SM_
|
||||
#define E2SM_
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <e2sm_helpers.hpp>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
|
||||
#include <E2SM-HelloWorld-EventTriggerDefinition.h>
|
||||
#include <E2SM-HelloWorld-ActionDefinition.h>
|
||||
#include <E2SM-HelloWorld-EventTriggerDefinition-Format1.h>
|
||||
#include <E2SM-HelloWorld-ActionDefinition-Format1.h>
|
||||
#include <HW-TriggerNature.h>
|
||||
#include <RANparameter-Item.h>
|
||||
|
||||
/* builder class for E2SM event trigger definition */
|
||||
|
||||
class e2sm_subscription {
|
||||
public:
|
||||
e2sm_subscription(void);
|
||||
~e2sm_subscription(void);
|
||||
|
||||
bool set_fields(E2SM_HelloWorld_EventTriggerDefinition_t *, e2sm_subscription_helper &);
|
||||
bool set_fields(E2SM_HelloWorld_ActionDefinition_t *, e2sm_subscription_helper &);
|
||||
|
||||
bool encode_event_trigger(unsigned char *, size_t *, e2sm_subscription_helper &);
|
||||
bool encode_action_defn(unsigned char*, size_t *, e2sm_subscription_helper &);
|
||||
|
||||
|
||||
std::string get_error (void) const {return error_string ;};
|
||||
|
||||
private:
|
||||
|
||||
E2SM_HelloWorld_EventTriggerDefinition_t * event_trigger; // used for encoding
|
||||
E2SM_HelloWorld_ActionDefinition_t* action_defn;
|
||||
E2SM_HelloWorld_EventTriggerDefinition_Format1_t event_fmt1;
|
||||
E2SM_HelloWorld_ActionDefinition_Format1_t actn_fmt1;
|
||||
RANparameter_Item_t *ran_param;
|
||||
|
||||
|
||||
size_t errbuf_len;
|
||||
char errbuf[128];
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
266
setup/xapp-bs-connector/src/xapp-formats/e2ap/e2ap_control.cc
Normal file
266
setup/xapp-bs-connector/src/xapp-formats/e2ap/e2ap_control.cc
Normal file
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_control_request.c
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#include "e2ap_control.hpp"
|
||||
|
||||
// Set up memory allocations for each IE for encoding
|
||||
// We are responsible for memory management for each IE for encoding
|
||||
// Hence destructor should clear out memory
|
||||
// When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
|
||||
// for releasing memory by external calling function)
|
||||
ric_control_request::ric_control_request(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2N_E2AP_PDU_t * )calloc(1, sizeof(E2N_E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
initMsg = 0;
|
||||
initMsg = (E2N_InitiatingMessage_t * )calloc(1, sizeof(E2N_InitiatingMessage_t));
|
||||
assert(initMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (E2N_RICcontrolRequest_IEs_t *)calloc(NUM_CONTROL_REQUEST_IES, sizeof(E2N_RICcontrolRequest_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_initiatingMessage;
|
||||
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC control_request IE container
|
||||
ric_control_request::~ric_control_request(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Control Request object memory");
|
||||
|
||||
E2N_RICcontrolRequest_t *ricControl_Request = &(initMsg->value.choice.RICcontrolRequest);
|
||||
for(int i = 0; i < ricControl_Request->protocolIEs.list.size; i++){
|
||||
ricControl_Request->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (ricControl_Request->protocolIEs.list.size > 0){
|
||||
free(ricControl_Request->protocolIEs.list.array);
|
||||
ricControl_Request->protocolIEs.list.size = 0;
|
||||
ricControl_Request->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(initMsg);
|
||||
e2ap_pdu_obj->choice.initiatingMessage = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed E2N_E2AP Control Request object mempory");
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ric_control_request::encode_e2ap_control_request(unsigned char *buf, size_t *size, ric_control_helper & dinput){
|
||||
|
||||
initMsg->procedureCode = E2N_ProcedureCode_id_ricControl;
|
||||
initMsg->criticality = E2N_Criticality_ignore;
|
||||
initMsg->value.present = E2N_InitiatingMessage__value_PR_RICcontrolRequest;
|
||||
|
||||
bool res;
|
||||
|
||||
res = set_fields(initMsg, dinput);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding control . Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding event trigger definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ric_control_request::set_fields(E2N_InitiatingMessage_t *initMsg, ric_control_helper &dinput){
|
||||
unsigned int ie_index;
|
||||
|
||||
if (initMsg == 0){
|
||||
error_string = "Invalid reference for E2AP Control_Request message in set_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
E2N_RICcontrolRequest_t * ric_control_request = &(initMsg->value.choice.RICcontrolRequest);
|
||||
ric_control_request->protocolIEs.list.count = 0; // reset
|
||||
|
||||
// for(i = 0; i < NUM_CONTROL_REQUEST_IES;i++){
|
||||
// memset(&(IE_array[i]), 0, sizeof(RICcontrolRequest_IEs_t));
|
||||
// }
|
||||
|
||||
// Mandatory IE
|
||||
ie_index = 0;
|
||||
E2N_RICcontrolRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICcontrolRequest_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = dinput.req_id;
|
||||
ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
// Mandatory IE
|
||||
ie_index = 1;
|
||||
E2N_RICcontrolRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICcontrolRequest_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = dinput.func_id;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
|
||||
// Mandatory IE
|
||||
ie_index = 2;
|
||||
E2N_RICcontrolRequest_IEs_t *ies_richead = &IE_array[ie_index];
|
||||
ies_richead->criticality = E2N_Criticality_reject;
|
||||
ies_richead->id = E2N_ProtocolIE_ID_id_RICcontrolHeader;
|
||||
ies_richead->value.present = E2N_RICcontrolRequest_IEs__value_PR_RICcontrolHeader;
|
||||
E2N_RICcontrolHeader_t *richeader_ie = &ies_richead->value.choice.RICcontrolHeader;
|
||||
richeader_ie->buf = dinput.control_header;
|
||||
richeader_ie->size = dinput.control_header_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
// Mandatory IE
|
||||
ie_index = 3;
|
||||
E2N_RICcontrolRequest_IEs_t *ies_indmsg = &IE_array[ie_index];
|
||||
ies_indmsg->criticality = E2N_Criticality_reject;
|
||||
ies_indmsg->id = E2N_ProtocolIE_ID_id_RICcontrolMessage;
|
||||
ies_indmsg->value.present = E2N_RICcontrolRequest_IEs__value_PR_RICcontrolMessage;
|
||||
E2N_RICcontrolMessage_t *ricmsg_ie = &ies_indmsg->value.choice.RICcontrolMessage;
|
||||
ricmsg_ie->buf = dinput.control_msg;
|
||||
ricmsg_ie->size = dinput.control_msg_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
// Optional IE
|
||||
ie_index = 4;
|
||||
if (dinput.control_ack >= 0){
|
||||
E2N_RICcontrolRequest_IEs_t *ies_indtyp = &IE_array[ie_index];
|
||||
ies_indtyp->criticality = E2N_Criticality_reject;
|
||||
ies_indtyp->id = E2N_ProtocolIE_ID_id_RICcontrolAckRequest;
|
||||
ies_indtyp->value.present = E2N_RICcontrolRequest_IEs__value_PR_RICcontrolAckRequest;
|
||||
E2N_RICcontrolAckRequest_t *ricackreq_ie = &ies_indtyp->value.choice.RICcontrolAckRequest;
|
||||
*ricackreq_ie = dinput.control_ack;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
}
|
||||
|
||||
// Optional IE
|
||||
ie_index = 5;
|
||||
if(dinput.call_process_id_size > 0){
|
||||
E2N_RICcontrolRequest_IEs_t *ies_callprocid = &IE_array[ie_index];
|
||||
ies_callprocid->criticality = E2N_Criticality_reject;
|
||||
ies_callprocid->id = E2N_ProtocolIE_ID_id_RICcallProcessID;
|
||||
ies_callprocid->value.present = E2N_RICcontrolRequest_IEs__value_PR_RICcallProcessID;
|
||||
E2N_RICcallProcessID_t *riccallprocessid_ie = &ies_callprocid->value.choice.RICcallProcessID;
|
||||
riccallprocessid_ie->buf = dinput.call_process_id;
|
||||
riccallprocessid_ie->size = dinput.call_process_id_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool ric_control_request:: get_fields(E2N_InitiatingMessage_t * init_msg, ric_control_helper &dout)
|
||||
{
|
||||
if (init_msg == 0){
|
||||
error_string = "Invalid reference for E2AP Control_Request message in get_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for(int edx = 0; edx < init_msg->value.choice.RICcontrolRequest.protocolIEs.list.count; edx++) {
|
||||
E2N_RICcontrolRequest_IEs_t *memb_ptr = init_msg->value.choice.RICcontrolRequest.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (E2N_ProtocolIE_ID_id_RICcontrolHeader):
|
||||
dout.control_header = memb_ptr->value.choice.RICcontrolHeader.buf;
|
||||
dout.control_header_size = memb_ptr->value.choice.RICcontrolHeader.size;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICcontrolMessage):
|
||||
dout.control_msg = memb_ptr->value.choice.RICcontrolMessage.buf;
|
||||
dout.control_msg_size = memb_ptr->value.choice.RICcontrolMessage.size;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICcallProcessID):
|
||||
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
|
||||
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
|
||||
dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
dout.func_id = memb_ptr->value.choice.RANfunctionID;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICcontrolAckRequest):
|
||||
dout.control_ack = memb_ptr->value.choice.RICcontrolAckRequest;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
E2N_InitiatingMessage_t * ric_control_request::get_message(void) {
|
||||
return initMsg;
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#ifndef E2AP_RIC_CONTROL_REQUEST_H_
|
||||
#define E2AP_RIC_CONTROL_REQUEST_H_
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <sstream>
|
||||
#include <E2N_E2AP-PDU.h>
|
||||
#include <E2N_InitiatingMessage.h>
|
||||
#include <E2N_RICcontrolRequest.h>
|
||||
#include <E2N_ProtocolIE-Field.h>
|
||||
#include "e2ap_control_helper.hpp"
|
||||
|
||||
#define NUM_CONTROL_REQUEST_IES 6
|
||||
|
||||
|
||||
class ric_control_request{
|
||||
|
||||
public:
|
||||
ric_control_request(void);
|
||||
~ric_control_request(void);
|
||||
|
||||
bool encode_e2ap_control_request(unsigned char *, size_t *, ric_control_helper &);
|
||||
E2N_InitiatingMessage_t * get_message (void) ;
|
||||
bool set_fields(E2N_InitiatingMessage_t *, ric_control_helper &);
|
||||
bool get_fields(E2N_InitiatingMessage_t *, ric_control_helper &);
|
||||
std::string get_error(void) const {return error_string ; };
|
||||
private:
|
||||
|
||||
E2N_E2AP_PDU_t * e2ap_pdu_obj;
|
||||
E2N_InitiatingMessage_t *initMsg;
|
||||
E2N_RICcontrolRequest_IEs_t *IE_array;
|
||||
std::string error_string;
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
};
|
||||
|
||||
|
||||
#endif /* E2AP_RIC_CONTROL_REQUEST_H_ */
|
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#ifndef CONTROL_HELPER_H
|
||||
#define CONTROL_HELPER_H
|
||||
|
||||
// control and indication helper objects are very similar and can be merged into one
|
||||
// currently leaving them as two distnict entities till final design becomes clear
|
||||
|
||||
typedef struct ric_control_helper ric_control_helper;
|
||||
|
||||
struct ric_control_helper{
|
||||
ric_control_helper(void):req_id(1), req_seq_no(1), func_id(0), action_id(1), control_ack(-1), cause(0), sub_cause(0), control_status(1), control_msg(0), control_msg_size(0), control_header(0), control_header_size(0), call_process_id(0), call_process_id_size(0){};
|
||||
|
||||
long int req_id, req_seq_no, func_id, action_id, control_ack, cause, sub_cause, control_status;
|
||||
|
||||
unsigned char* control_msg;
|
||||
size_t control_msg_size;
|
||||
|
||||
unsigned char* control_header;
|
||||
size_t control_header_size;
|
||||
|
||||
unsigned char *call_process_id;
|
||||
size_t call_process_id_size;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_control_response.c
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#include "e2ap_control_response.hpp"
|
||||
|
||||
// Set up the initiating message and also allocate protocolIEs in container
|
||||
// Note : this bypasses requirement to use ASN_SEQUENCE_ADD. We can directly
|
||||
// assign pointers to the array in ProtocolIE. However, this also leaves us on the
|
||||
// hook to manually clear the memory
|
||||
|
||||
ric_control_response::ric_control_response(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2N_E2AP_PDU_t * )calloc(1, sizeof(E2N_E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
successMsg = 0;
|
||||
successMsg = (E2N_SuccessfulOutcome_t * )calloc(1, sizeof(E2N_SuccessfulOutcome_t));
|
||||
assert(successMsg != 0);
|
||||
|
||||
successMsg->procedureCode = E2N_ProcedureCode_id_ricControl;
|
||||
successMsg->criticality = E2N_Criticality_reject;
|
||||
successMsg->value.present = E2N_SuccessfulOutcome__value_PR_RICcontrolAcknowledge;
|
||||
|
||||
|
||||
unsuccessMsg = 0;
|
||||
unsuccessMsg = (E2N_UnsuccessfulOutcome_t * )calloc(1, sizeof(E2N_UnsuccessfulOutcome_t));
|
||||
assert(unsuccessMsg != 0);
|
||||
|
||||
|
||||
unsuccessMsg->procedureCode = E2N_ProcedureCode_id_ricControl;
|
||||
unsuccessMsg->criticality = E2N_Criticality_reject;
|
||||
unsuccessMsg->value.present = E2N_UnsuccessfulOutcome__value_PR_RICcontrolFailure;
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (E2N_RICcontrolAcknowledge_IEs_t *)calloc(NUM_CONTROL_ACKNOWLEDGE_IES, sizeof(E2N_RICcontrolAcknowledge_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
E2N_RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
|
||||
for(int i = 0; i < NUM_CONTROL_ACKNOWLEDGE_IES; i++){
|
||||
ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), &(IE_array[i]));
|
||||
}
|
||||
|
||||
|
||||
IE_failure_array = 0;
|
||||
IE_failure_array = (E2N_RICcontrolFailure_IEs_t *)calloc(NUM_CONTROL_FAILURE_IES, sizeof(E2N_RICcontrolFailure_IEs_t));
|
||||
assert(IE_failure_array != 0);
|
||||
|
||||
E2N_RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
|
||||
for(int i = 0; i < NUM_CONTROL_FAILURE_IES; i++){
|
||||
ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), &(IE_failure_array[i]));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC control_request IE container
|
||||
ric_control_response::~ric_control_response(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Control Response object memory");
|
||||
|
||||
E2N_RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
|
||||
for(int i = 0; i < ric_acknowledge->protocolIEs.list.size; i++){
|
||||
ric_acknowledge->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
if (ric_acknowledge->protocolIEs.list.size > 0){
|
||||
free(ric_acknowledge->protocolIEs.list.array);
|
||||
ric_acknowledge->protocolIEs.list.array = 0;
|
||||
ric_acknowledge->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
E2N_RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
|
||||
for(int i = 0; i < ric_failure->protocolIEs.list.size; i++){
|
||||
ric_failure->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
if (ric_failure->protocolIEs.list.size > 0){
|
||||
free(ric_failure->protocolIEs.list.array);
|
||||
ric_failure->protocolIEs.list.array = 0;
|
||||
ric_failure->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(IE_failure_array);
|
||||
free(successMsg);
|
||||
free(unsuccessMsg);
|
||||
|
||||
e2ap_pdu_obj->choice.initiatingMessage = 0;
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_initiatingMessage;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed E2AP Control Response object mempory");
|
||||
}
|
||||
|
||||
|
||||
bool ric_control_response::encode_e2ap_control_response(unsigned char *buf, size_t *size, ric_control_helper & dinput, bool is_success){
|
||||
|
||||
bool res;
|
||||
if (is_success){
|
||||
res = set_fields(successMsg, dinput);
|
||||
}
|
||||
else{
|
||||
res = set_fields(unsuccessMsg, dinput);
|
||||
}
|
||||
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (is_success){
|
||||
e2ap_pdu_obj->choice.successfulOutcome = successMsg;
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_successfulOutcome ;
|
||||
}
|
||||
else{
|
||||
e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_unsuccessfulOutcome ;
|
||||
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding control response. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding E2AP Control response . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ric_control_response::set_fields(E2N_SuccessfulOutcome_t *successMsg, ric_control_helper &dinput){
|
||||
unsigned int ie_index;
|
||||
|
||||
if (successMsg == 0){
|
||||
error_string = "Invalid reference for E2AP Control Acknowledge in set_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
// for(i = 0; i < NUM_CONTROL_ACKNOWLEDGE_IES;i++){
|
||||
// memset(&(IE_array[i]), 0, sizeof(RICcontrolAcknowledge_IEs_t));
|
||||
// }
|
||||
|
||||
//E2N_RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
|
||||
//ric_acknowledge->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
E2N_RICcontrolAcknowledge_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICcontrolAcknowledge_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = dinput.req_id;
|
||||
ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
|
||||
//ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ricreq);
|
||||
|
||||
ie_index = 1;
|
||||
E2N_RICcontrolAcknowledge_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICcontrolAcknowledge_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = dinput.func_id;
|
||||
//ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ranfunc);
|
||||
|
||||
// ie_index = 2;
|
||||
// E2N_RICcontrolAcknowledge_IEs_t *ies_riccallprocessid = &IE_array[ie_index];
|
||||
// ies_riccallprocessid->criticality = E2N_Criticality_reject;
|
||||
// ies_riccallprocessid->id = E2N_ProtocolIE_ID_id_RICcallProcessID;
|
||||
// ies_riccallprocessid->value.present = E2N_RICcontrolAcknowledge_IEs__value_PR_RICcallProcessID;
|
||||
// RICcallProcessID_t *riccallprocessid_ie = &ies_riccallprocessid->value.choice.RICcallProcessID;
|
||||
// riccallprocessid_ie->buf = dinput.call_process_id;
|
||||
// riccallprocessid_ie->size = dinput.call_process_id_size;
|
||||
// ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_riccallprocessid);
|
||||
|
||||
ie_index = 2;
|
||||
E2N_RICcontrolAcknowledge_IEs_t *ies_ric_cause = &IE_array[ie_index];
|
||||
ies_ric_cause->criticality = E2N_Criticality_reject;
|
||||
ies_ric_cause->id = E2N_ProtocolIE_ID_id_RICcontrolStatus;
|
||||
ies_ric_cause->value.present = E2N_RICcontrolAcknowledge_IEs__value_PR_RICcontrolStatus;
|
||||
ies_ric_cause->value.choice.RICcontrolStatus = dinput.control_status;
|
||||
//ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ric_cause);
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
bool ric_control_response::set_fields(E2N_UnsuccessfulOutcome_t *unsuccessMsg, ric_control_helper &dinput){
|
||||
unsigned int ie_index;
|
||||
|
||||
if (unsuccessMsg == 0){
|
||||
error_string = "Invalid reference for E2AP Control Failure in set_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
// for(i = 0; i < NUM_CONTROL_FAILURE_IES;i++){
|
||||
// memset(&(IE_failure_array[i]), 0, sizeof(RICcontrolFailure_IEs_t));
|
||||
// }
|
||||
|
||||
//E2N_RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
|
||||
//ric_failure->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
E2N_RICcontrolFailure_IEs_t *ies_ricreq = &IE_failure_array[ie_index];
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICcontrolFailure_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &(ies_ricreq->value.choice.RICrequestID);
|
||||
ricrequest_ie->ricRequestorID = dinput.req_id;
|
||||
ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
|
||||
//ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ricreq);
|
||||
|
||||
ie_index = 1;
|
||||
E2N_RICcontrolFailure_IEs_t *ies_ranfunc = &IE_failure_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICcontrolFailure_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &(ies_ranfunc->value.choice.RANfunctionID);
|
||||
*ranfunction_ie = dinput.func_id;
|
||||
//ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ranfunc);
|
||||
|
||||
// ie_index = 2;
|
||||
// E2N_RICcontrolFailure_IEs_t *ies_riccallprocessid = &IE_failure_array[i];
|
||||
// ies_riccallprocessid->criticality = E2N_Criticality_reject;
|
||||
// ies_riccallprocessid->id = E2N_ProtocolIE_ID_id_RICcallProcessID;
|
||||
// ies_riccallprocessid->value.present = E2N_RICcontrolFailure_IEs__value_PR_RICcallProcessID;
|
||||
// RICcallProcessID_t *riccallprocessid_ie = &(ies_riccallprocessid->value.choice.RICcallProcessID);
|
||||
// riccallprocessid_ie->buf = dinput.call_process_id;
|
||||
// riccallprocessid_ie->size = dinput.call_process_id_size;
|
||||
// ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_riccallprocessid);
|
||||
|
||||
ie_index = 2;
|
||||
E2N_RICcontrolFailure_IEs_t *ies_ric_cause = &IE_failure_array[ie_index];
|
||||
ies_ric_cause->criticality = E2N_Criticality_ignore;
|
||||
ies_ric_cause->id = E2N_ProtocolIE_ID_id_RICcause;
|
||||
ies_ric_cause->value.present = E2N_RICcontrolFailure_IEs__value_PR_RICcause;
|
||||
E2N_RICcause_t * ric_cause = &(ies_ric_cause->value.choice.RICcause);
|
||||
ric_cause->present = (E2N_RICcause_PR)dinput.cause;
|
||||
|
||||
switch(dinput.cause){
|
||||
case E2N_RICcause_PR_radioNetwork:
|
||||
ric_cause->choice.radioNetwork = dinput.sub_cause;
|
||||
break;
|
||||
case E2N_RICcause_PR_transport:
|
||||
ric_cause->choice.transport = dinput.sub_cause;
|
||||
break;
|
||||
case E2N_RICcause_PR_protocol:
|
||||
ric_cause->choice.protocol= dinput.sub_cause;
|
||||
break;
|
||||
case E2N_RICcause_PR_misc:
|
||||
ric_cause->choice.misc = dinput.sub_cause;
|
||||
break;
|
||||
case E2N_RICcause_PR_ric:
|
||||
ric_cause->choice.ric = dinput.sub_cause;
|
||||
break;
|
||||
default:
|
||||
std::cout <<"Error ! Illegal cause enum" << dinput.cause << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
//ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ric_cause);
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool ric_control_response:: get_fields(E2N_SuccessfulOutcome_t * success_msg, ric_control_helper &dout)
|
||||
{
|
||||
if (success_msg == 0){
|
||||
error_string = "Invalid reference for E2AP Control Acknowledge message in get_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for(int edx = 0; edx < success_msg->value.choice.RICcontrolAcknowledge.protocolIEs.list.count; edx++) {
|
||||
E2N_RICcontrolAcknowledge_IEs_t *memb_ptr = success_msg->value.choice.RICcontrolAcknowledge.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICcallProcessID):
|
||||
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
|
||||
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
|
||||
dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
dout.func_id = memb_ptr->value.choice.RANfunctionID;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICcause):
|
||||
dout.control_status = memb_ptr->value.choice.RICcontrolStatus;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ric_control_response:: get_fields(E2N_UnsuccessfulOutcome_t * unsuccess_msg, ric_control_helper &dout)
|
||||
{
|
||||
if (unsuccess_msg == 0){
|
||||
error_string = "Invalid reference for E2AP Control Failure message in get_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for(int edx = 0; edx < unsuccess_msg->value.choice.RICcontrolFailure.protocolIEs.list.count; edx++) {
|
||||
E2N_RICcontrolFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICcontrolFailure.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICcallProcessID):
|
||||
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
|
||||
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
|
||||
dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
dout.func_id = memb_ptr->value.choice.RANfunctionID;
|
||||
break;
|
||||
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICcause):
|
||||
dout.cause = memb_ptr->value.choice.RICcause.present;
|
||||
switch(dout.cause){
|
||||
case E2N_RICcause_PR_radioNetwork :
|
||||
dout.sub_cause = memb_ptr->value.choice.RICcause.choice.radioNetwork;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_transport :
|
||||
dout.sub_cause = memb_ptr->value.choice.RICcause.choice.transport;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_protocol :
|
||||
dout.sub_cause = memb_ptr->value.choice.RICcause.choice.protocol;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_misc :
|
||||
dout.sub_cause = memb_ptr->value.choice.RICcause.choice.misc;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_ric :
|
||||
dout.sub_cause = memb_ptr->value.choice.RICcause.choice.ric;
|
||||
break;
|
||||
|
||||
default:
|
||||
dout.sub_cause = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#ifndef E2AP_RIC_CONTROL_RESPONSE_H_
|
||||
#define E2AP_RIC_CONTROL_RESPONSE_H_
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <sstream>
|
||||
#include <E2N_E2AP-PDU.h>
|
||||
#include <E2N_SuccessfulOutcome.h>
|
||||
#include <E2N_UnsuccessfulOutcome.h>
|
||||
#include <E2N_RICcontrolAcknowledge.h>
|
||||
#include <E2N_RICcontrolFailure.h>
|
||||
#include <E2N_ProtocolIE-Field.h>
|
||||
#include "e2ap_control_helper.hpp"
|
||||
|
||||
#define NUM_CONTROL_ACKNOWLEDGE_IES 3
|
||||
#define NUM_CONTROL_FAILURE_IES 3
|
||||
|
||||
|
||||
class ric_control_response{
|
||||
|
||||
public:
|
||||
ric_control_response(void);
|
||||
~ric_control_response(void);
|
||||
|
||||
bool encode_e2ap_control_response(unsigned char *, size_t *, ric_control_helper &, bool);
|
||||
|
||||
|
||||
bool set_fields(E2N_SuccessfulOutcome_t *, ric_control_helper &);
|
||||
bool get_fields(E2N_SuccessfulOutcome_t *, ric_control_helper &);
|
||||
|
||||
bool set_fields(E2N_UnsuccessfulOutcome_t *, ric_control_helper &);
|
||||
bool get_fields(E2N_UnsuccessfulOutcome_t *, ric_control_helper &);
|
||||
|
||||
std::string get_error(void) const {return error_string ; };
|
||||
|
||||
private:
|
||||
|
||||
E2N_E2AP_PDU_t * e2ap_pdu_obj;
|
||||
E2N_SuccessfulOutcome_t * successMsg;
|
||||
E2N_UnsuccessfulOutcome_t * unsuccessMsg;
|
||||
|
||||
E2N_RICcontrolAcknowledge_IEs_t *IE_array;
|
||||
E2N_RICcontrolFailure_IEs_t *IE_failure_array;
|
||||
|
||||
std::string error_string;
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
};
|
||||
|
||||
|
||||
#endif /* E2AP_RIC_CONTROL_RESPONSE_H_ */
|
283
setup/xapp-bs-connector/src/xapp-formats/e2ap/e2ap_indication.cc
Normal file
283
setup/xapp-bs-connector/src/xapp-formats/e2ap/e2ap_indication.cc
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.c
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#include "e2ap_indication.hpp"
|
||||
|
||||
// Set up memory allocations for each IE for encoding
|
||||
// We are responsible for memory management for each IE for encoding
|
||||
// Hence destructor should clear out memory
|
||||
// When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
|
||||
// for releasing memory by external calling function)
|
||||
ric_indication::ric_indication(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2N_E2AP_PDU_t * )calloc(1, sizeof(E2N_E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
initMsg = 0;
|
||||
initMsg = (E2N_InitiatingMessage_t * )calloc(1, sizeof(E2N_InitiatingMessage_t));
|
||||
assert(initMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (E2N_RICindication_IEs_t *)calloc(NUM_INDICATION_IES, sizeof(E2N_RICindication_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_initiatingMessage;
|
||||
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC indication IE container
|
||||
ric_indication::~ric_indication(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Indication object memory");
|
||||
E2N_RICindication_t *ricIndication = &(initMsg->value.choice.RICindication);
|
||||
for(int i = 0; i < ricIndication->protocolIEs.list.size; i++){
|
||||
ricIndication->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
if (ricIndication->protocolIEs.list.size > 0){
|
||||
free(ricIndication->protocolIEs.list.array);
|
||||
ricIndication->protocolIEs.list.array = 0;
|
||||
ricIndication->protocolIEs.list.count = 0;
|
||||
ricIndication->protocolIEs.list.size = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed E2AP Indication object mempory");
|
||||
}
|
||||
|
||||
|
||||
bool ric_indication::encode_e2ap_indication(unsigned char *buf, size_t *size, ric_indication_helper & dinput){
|
||||
|
||||
initMsg->procedureCode = E2N_ProcedureCode_id_ricIndication;
|
||||
initMsg->criticality = E2N_Criticality_ignore;
|
||||
initMsg->value.present = E2N_InitiatingMessage__value_PR_RICindication;
|
||||
|
||||
bool res;
|
||||
asn_enc_rval_t retval;
|
||||
|
||||
res = set_fields(initMsg, dinput);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
error_string = "Error encoding E2AP Indication message. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
// std::cout <<"Constraint check ok ...." << std::endl;
|
||||
// xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding E2AP Indication . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ric_indication::set_fields(E2N_InitiatingMessage_t *initMsg, ric_indication_helper &dinput){
|
||||
unsigned int ie_index;
|
||||
|
||||
if (initMsg == 0){
|
||||
error_string = "Invalid reference for E2AP Indication message in set_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
E2N_RICindication_t * ric_indication = &(initMsg->value.choice.RICindication);
|
||||
ric_indication->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
|
||||
E2N_RICindication_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICindication_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = dinput.req_id;
|
||||
ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 1;
|
||||
E2N_RICindication_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICindication_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = dinput.func_id;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 2;
|
||||
E2N_RICindication_IEs_t *ies_actid = &IE_array[ie_index];
|
||||
ies_actid->criticality = E2N_Criticality_reject;
|
||||
ies_actid->id = E2N_ProtocolIE_ID_id_RICactionID;
|
||||
ies_actid->value.present = E2N_RICindication_IEs__value_PR_RICactionID;
|
||||
E2N_RICactionID_t *ricaction_ie = &ies_actid->value.choice.RICactionID;
|
||||
*ricaction_ie = dinput.action_id;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 3;
|
||||
E2N_RICindication_IEs_t *ies_ricsn = &IE_array[ie_index];
|
||||
ies_ricsn->criticality = E2N_Criticality_reject;
|
||||
ies_ricsn->id = E2N_ProtocolIE_ID_id_RICindicationSN;
|
||||
ies_ricsn->value.present = E2N_RICindication_IEs__value_PR_RICindicationSN;
|
||||
E2N_RICindicationSN_t *ricsn_ie = &ies_ricsn->value.choice.RICindicationSN;
|
||||
*ricsn_ie = dinput.indication_sn;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
|
||||
ie_index = 4;
|
||||
E2N_RICindication_IEs_t *ies_indtyp = &IE_array[ie_index];
|
||||
ies_indtyp->criticality = E2N_Criticality_reject;
|
||||
ies_indtyp->id = E2N_ProtocolIE_ID_id_RICindicationType;
|
||||
ies_indtyp->value.present = E2N_RICindication_IEs__value_PR_RICindicationType;
|
||||
E2N_RICindicationType_t *rictype_ie = &ies_indtyp->value.choice.RICindicationType;
|
||||
*rictype_ie = dinput.indication_type;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 5;
|
||||
E2N_RICindication_IEs_t *ies_richead = &IE_array[ie_index];
|
||||
ies_richead->criticality = E2N_Criticality_reject;
|
||||
ies_richead->id = E2N_ProtocolIE_ID_id_RICindicationHeader;
|
||||
ies_richead->value.present = E2N_RICindication_IEs__value_PR_RICindicationHeader;
|
||||
E2N_RICindicationHeader_t *richeader_ie = &ies_richead->value.choice.RICindicationHeader;
|
||||
richeader_ie->buf = dinput.indication_header;
|
||||
richeader_ie->size = dinput.indication_header_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
ie_index = 6;
|
||||
E2N_RICindication_IEs_t *ies_indmsg = &IE_array[ie_index];
|
||||
ies_indmsg->criticality = E2N_Criticality_reject;
|
||||
ies_indmsg->id = E2N_ProtocolIE_ID_id_RICindicationMessage;
|
||||
ies_indmsg->value.present = E2N_RICindication_IEs__value_PR_RICindicationMessage;
|
||||
E2N_RICindicationMessage_t *ricmsg_ie = &ies_indmsg->value.choice.RICindicationMessage;
|
||||
ricmsg_ie->buf = dinput.indication_msg;
|
||||
ricmsg_ie->size = dinput.indication_msg_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
|
||||
|
||||
// optional call process id ..
|
||||
if (dinput.call_process_id_size > 0){
|
||||
ie_index = 7;
|
||||
E2N_RICindication_IEs_t *ies_ind_callprocessid = &IE_array[ie_index];
|
||||
ies_ind_callprocessid->criticality = E2N_Criticality_reject;
|
||||
ies_ind_callprocessid->id = E2N_ProtocolIE_ID_id_RICcallProcessID;
|
||||
ies_ind_callprocessid->value.present = E2N_RICindication_IEs__value_PR_RICcallProcessID;
|
||||
E2N_RICcallProcessID_t *riccallprocessid_ie = &ies_ind_callprocessid->value.choice.RICcallProcessID;
|
||||
riccallprocessid_ie->buf = dinput.indication_msg;
|
||||
riccallprocessid_ie->size = dinput.indication_msg_size;
|
||||
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool ric_indication:: get_fields(E2N_InitiatingMessage_t * init_msg, ric_indication_helper &dout)
|
||||
{
|
||||
if (init_msg == 0){
|
||||
error_string = "Invalid reference for E2AP Indication message in get_fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for(int edx = 0; edx < init_msg->value.choice.RICindication.protocolIEs.list.count; edx++) {
|
||||
E2N_RICindication_IEs_t *memb_ptr = init_msg->value.choice.RICindication.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (E2N_ProtocolIE_ID_id_RICindicationHeader):
|
||||
dout.indication_header = memb_ptr->value.choice.RICindicationHeader.buf;
|
||||
dout.indication_header_size = memb_ptr->value.choice.RICindicationHeader.size;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICindicationMessage):
|
||||
dout.indication_msg = memb_ptr->value.choice.RICindicationMessage.buf;
|
||||
dout.indication_msg_size = memb_ptr->value.choice.RICindicationMessage.size;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
|
||||
dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
dout.func_id = memb_ptr->value.choice.RANfunctionID;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICindicationSN):
|
||||
dout.indication_sn = memb_ptr->value.choice.RICindicationSN;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICindicationType):
|
||||
dout.indication_type = memb_ptr->value.choice.RICindicationType;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICactionID):
|
||||
dout.action_id = memb_ptr->value.choice.RICactionID;
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICcallProcessID):
|
||||
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
|
||||
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
E2N_InitiatingMessage_t * ric_indication::get_message(void) {
|
||||
return initMsg;
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
#ifndef E2AP_RIC_INDICATION_H_
|
||||
#define E2AP_RIC_INDICATION_H_
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <sstream>
|
||||
#include <E2N_E2AP-PDU.h>
|
||||
#include <E2N_InitiatingMessage.h>
|
||||
#include <E2N_RICindication.h>
|
||||
#include <E2N_ProtocolIE-Field.h>
|
||||
#include "e2ap_indication_helper.hpp"
|
||||
|
||||
#define NUM_INDICATION_IES 8
|
||||
|
||||
|
||||
|
||||
class ric_indication{
|
||||
|
||||
public:
|
||||
ric_indication(void);
|
||||
~ric_indication(void);
|
||||
|
||||
bool encode_e2ap_indication(unsigned char *, size_t *, ric_indication_helper &);
|
||||
E2N_InitiatingMessage_t * get_message (void) ;
|
||||
bool set_fields(E2N_InitiatingMessage_t *, ric_indication_helper &);
|
||||
bool get_fields(E2N_InitiatingMessage_t *, ric_indication_helper &);
|
||||
std::string get_error(void) const {return error_string ; };
|
||||
|
||||
private:
|
||||
|
||||
E2N_E2AP_PDU_t * e2ap_pdu_obj;
|
||||
E2N_InitiatingMessage_t *initMsg;
|
||||
E2N_RICindication_IEs_t *IE_array;
|
||||
std::string error_string;
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
};
|
||||
|
||||
|
||||
#endif /* E2AP_RIC_INDICATION_H_ */
|
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* ric_indication.h
|
||||
*
|
||||
* Created on: Jul 11, 2019
|
||||
* Author: sjana, Ashwin Sridharan
|
||||
*/
|
||||
|
||||
|
||||
#ifndef E2AP_INDICATION_HELPER_
|
||||
#define E2AP_INDICATION_HELPER_
|
||||
|
||||
typedef struct ric_indication_helper ric_indication_helper;
|
||||
|
||||
struct ric_indication_helper{
|
||||
ric_indication_helper(void) : req_id(1), req_seq_no(1), func_id(0), action_id(1), indication_type(0), indication_sn(0), indication_msg(0), indication_msg_size(0), indication_header(0), indication_header_size(0), call_process_id(0), call_process_id_size(0) {};
|
||||
long int req_id, req_seq_no, func_id, action_id, indication_type, indication_sn;
|
||||
|
||||
unsigned char* indication_msg;
|
||||
size_t indication_msg_size;
|
||||
|
||||
unsigned char* indication_header;
|
||||
size_t indication_header_size;
|
||||
|
||||
unsigned char *call_process_id;
|
||||
size_t call_process_id_size;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef GENERIC_HELPERS
|
||||
#define GENERIC_HELPERS
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/* Utilities */
|
||||
|
||||
class octet_helper {
|
||||
|
||||
public:
|
||||
octet_helper(void):_ref(NULL), _size(0){};
|
||||
octet_helper(const void *ref, int size):_ref(ref), _size(size){};
|
||||
void set_ref(const void *ref){
|
||||
_ref = ref;
|
||||
}
|
||||
|
||||
void set_size(size_t size){
|
||||
_size = size;
|
||||
}
|
||||
|
||||
const void * get_ref(void){return _ref ; };
|
||||
size_t get_size(void) const {return _size ; } ;
|
||||
|
||||
private:
|
||||
const void *_ref;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
#endif
|
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_RESPONSE_HELPER_
|
||||
#define S_RESPONSE_HELPER_
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
/* Simple structure to store action for RICaction of the Subscription response based on E2 v0.31 */
|
||||
struct ActionResponse {
|
||||
public:
|
||||
ActionResponse(int id): _is_admit(true), _id(id), _cause(-1), _sub_cause(-1){};
|
||||
ActionResponse(int id, int cause, int sub_cause): _is_admit(false), _id(id), _cause(cause), _sub_cause(sub_cause){};
|
||||
|
||||
int get_id() const{
|
||||
return _id;
|
||||
};
|
||||
|
||||
int get_cause() const{
|
||||
return _cause;
|
||||
};
|
||||
|
||||
int get_sub_cause() const{
|
||||
return _sub_cause;
|
||||
};
|
||||
|
||||
bool is_admitted(void){
|
||||
return _is_admit;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
bool _is_admit;
|
||||
int _id, _cause, _sub_cause;
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct subscription_response_helper {
|
||||
|
||||
public:
|
||||
|
||||
using action_t = std::vector<ActionResponse>;
|
||||
|
||||
subscription_response_helper(void){
|
||||
_action_admitted_ref = std::make_unique<action_t>();
|
||||
_action_not_admitted_ref = std::make_unique<action_t>();
|
||||
|
||||
};
|
||||
|
||||
// copy operator
|
||||
subscription_response_helper(const subscription_response_helper &he ){
|
||||
_action_admitted_ref = std::make_unique<action_t>();
|
||||
_action_not_admitted_ref = std::make_unique<action_t>();
|
||||
|
||||
_req_id = he.get_request_id();
|
||||
_req_seq_no = he.get_req_seq();
|
||||
_func_id = he.get_function_id();
|
||||
|
||||
// Take care of the actions
|
||||
for (auto const & e: *(he.get_admitted_list())){
|
||||
add_action(e.get_id());
|
||||
}
|
||||
|
||||
for(auto const & e: *(he.get_not_admitted_list())){
|
||||
add_action(e.get_id(), e.get_cause(), e.get_sub_cause());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// assignment operator
|
||||
void operator=(const subscription_response_helper & he){
|
||||
_action_admitted_ref = std::make_unique<action_t>();
|
||||
_action_not_admitted_ref = std::make_unique<action_t>();
|
||||
|
||||
_req_id = he.get_request_id();
|
||||
_req_seq_no = he.get_req_seq();
|
||||
_func_id = he.get_function_id();
|
||||
|
||||
|
||||
// Take care of the actions
|
||||
for (auto const & e: *(he.get_admitted_list())){
|
||||
add_action(e.get_id());
|
||||
}
|
||||
|
||||
for(auto const & e: *(he.get_not_admitted_list())){
|
||||
add_action(e.get_id(), e.get_cause(), e.get_sub_cause());
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
action_t * get_admitted_list (void ) const {return _action_admitted_ref.get();};
|
||||
action_t * get_not_admitted_list (void ) const{return _action_not_admitted_ref.get();};
|
||||
|
||||
void set_request(int id, int seq_no){
|
||||
_req_id = id;
|
||||
_req_seq_no = seq_no;
|
||||
|
||||
};
|
||||
|
||||
void clear(void){
|
||||
_action_admitted_ref.get()->clear();
|
||||
_action_not_admitted_ref.get()->clear();
|
||||
}
|
||||
|
||||
|
||||
void set_function_id(int id){
|
||||
_func_id = id;
|
||||
};
|
||||
|
||||
void add_action(int id){
|
||||
ActionResponse a(id) ;
|
||||
_action_admitted_ref.get()->push_back(a);
|
||||
};
|
||||
|
||||
void add_action(int id, int cause, int sub_cause){
|
||||
ActionResponse a (id, cause, sub_cause);
|
||||
_action_not_admitted_ref.get()->push_back(a);
|
||||
};
|
||||
|
||||
|
||||
int get_request_id(void) const{
|
||||
return _req_id;
|
||||
}
|
||||
|
||||
int get_req_seq(void) const{
|
||||
return _req_seq_no;
|
||||
}
|
||||
|
||||
int get_function_id(void) const{
|
||||
return _func_id;
|
||||
}
|
||||
|
||||
std::string to_string(void){
|
||||
std::string Info;
|
||||
Info += "Request ID = " + std::to_string(_req_id) + "\n";
|
||||
Info += "Request Sequence No = " + std::to_string(_req_seq_no) + "\n";
|
||||
Info += "RAN Function ID = " + std::to_string(_func_id) + "\n";
|
||||
Info += "Actions Admitted =\n";
|
||||
int i = 0;
|
||||
for(auto & e: *(_action_admitted_ref)){
|
||||
Info += std::to_string(i) + ": ID=" + std::to_string(e.get_id()) + "\n";
|
||||
i++;
|
||||
}
|
||||
Info += "Actions Not Admitted =\n";
|
||||
i = 0;
|
||||
for(auto & e: *(_action_not_admitted_ref)){
|
||||
Info += std::to_string(i) + ": ID=" + std::to_string(e.get_id()) + ": Cause =" + std::to_string(e.get_cause()) + ": Sub-Cause=" + std::to_string(e.get_sub_cause()) + "\n";
|
||||
i++;
|
||||
}
|
||||
|
||||
return Info;
|
||||
}
|
||||
|
||||
private:
|
||||
int _req_id, _req_seq_no, _func_id;
|
||||
std::unique_ptr<action_t> _action_admitted_ref;
|
||||
std::unique_ptr<action_t> _action_not_admitted_ref;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@@ -0,0 +1,180 @@
|
||||
|
||||
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "subscription_delete_request.hpp"
|
||||
|
||||
subscription_delete::subscription_delete(void){
|
||||
|
||||
_name = "default";
|
||||
|
||||
e2ap_pdu_obj = (E2N_E2AP_PDU_t * )calloc(1, sizeof(E2N_E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
initMsg = (E2N_InitiatingMessage_t * )calloc(1, sizeof(E2N_InitiatingMessage_t));
|
||||
assert(initMsg != 0);
|
||||
|
||||
IE_array = (E2N_RICsubscriptionDeleteRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_DELETE_IES, sizeof(E2N_RICsubscriptionDeleteRequest_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
E2N_RICsubscriptionDeleteRequest_t * subscription_delete = &(initMsg->value.choice.RICsubscriptionDeleteRequest);
|
||||
for(int i = 0; i < NUM_SUBSCRIPTION_DELETE_IES; i++){
|
||||
ASN_SEQUENCE_ADD(&subscription_delete->protocolIEs, &(IE_array[i]));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC indication IE container
|
||||
subscription_delete::~subscription_delete(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing subscription delete request object memory");
|
||||
E2N_RICsubscriptionDeleteRequest_t * subscription_delete = &(initMsg->value.choice.RICsubscriptionDeleteRequest);
|
||||
|
||||
for(int i = 0; i < subscription_delete->protocolIEs.list.size; i++){
|
||||
subscription_delete->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (subscription_delete->protocolIEs.list.size > 0){
|
||||
free(subscription_delete->protocolIEs.list.array);
|
||||
subscription_delete->protocolIEs.list.count = 0;
|
||||
subscription_delete->protocolIEs.list.size = 0;
|
||||
subscription_delete->protocolIEs.list.array = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(initMsg);
|
||||
e2ap_pdu_obj->choice.initiatingMessage = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed subscription delete request object memory");
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool subscription_delete::encode_e2ap_subscription(unsigned char *buf, size_t *size, subscription_helper &dinput){
|
||||
|
||||
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_initiatingMessage;
|
||||
set_fields( dinput);
|
||||
|
||||
initMsg->procedureCode = E2N_ProcedureCode_id_ricSubscriptionDelete;
|
||||
initMsg->criticality = E2N_Criticality_reject;
|
||||
initMsg->value.present = E2N_InitiatingMessage__value_PR_RICsubscriptionDeleteRequest;
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding subscription delete request. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t res = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(res.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding Subscription Delete Request. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < res.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding Subscription Delete Request . Reason = encoded pdu size " << res.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
res.encoded = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = res.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool subscription_delete::set_fields( subscription_helper &helper){
|
||||
unsigned int ie_index;
|
||||
|
||||
ie_index = 0;
|
||||
E2N_RICsubscriptionDeleteRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICsubscriptionDeleteRequest_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
|
||||
|
||||
|
||||
ie_index = 1;
|
||||
E2N_RICsubscriptionDeleteRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICsubscriptionDeleteRequest_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool subscription_delete:: get_fields(E2N_InitiatingMessage_t * init_msg, subscription_helper & dout)
|
||||
{
|
||||
|
||||
if (init_msg == 0){
|
||||
error_string = "Invalid reference for initiating message for get string";
|
||||
return false;
|
||||
}
|
||||
|
||||
E2N_RICrequestID_t *requestid;
|
||||
E2N_RANfunctionID_t * ranfunctionid;
|
||||
|
||||
for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionDeleteRequest.protocolIEs.list.count; edx++) {
|
||||
E2N_RICsubscriptionDeleteRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionDeleteRequest.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
//asn_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_DELETE_
|
||||
#define S_DELETE_
|
||||
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <asn_application.h>
|
||||
#include <E2N_E2AP-PDU.h>
|
||||
#include <E2N_InitiatingMessage.h>
|
||||
#include <E2N_RICsubscriptionDeleteRequest.h>
|
||||
#include <E2N_ProtocolIE-Field.h>
|
||||
#include "subscription_helper.hpp"
|
||||
|
||||
#define NUM_SUBSCRIPTION_DELETE_IES 2
|
||||
|
||||
class subscription_delete{
|
||||
public:
|
||||
|
||||
subscription_delete(void);
|
||||
~subscription_delete(void);
|
||||
|
||||
bool encode_e2ap_subscription(unsigned char *, size_t *, subscription_helper &);
|
||||
bool set_fields(subscription_helper &);
|
||||
bool get_fields(E2N_InitiatingMessage_t *, subscription_helper &);
|
||||
|
||||
std::string get_error(void) const {
|
||||
return error_string ;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
E2N_InitiatingMessage_t *initMsg;
|
||||
E2N_E2AP_PDU_t * e2ap_pdu_obj;
|
||||
|
||||
E2N_RICsubscriptionDeleteRequest_IEs_t * IE_array;
|
||||
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
std::string _name;
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "subscription_delete_response.hpp"
|
||||
|
||||
/* The xAPP need only worry about the get_fields from a response, since it does
|
||||
not generate a response. Generating response however is included to support testing.
|
||||
*/
|
||||
|
||||
|
||||
// Primarly for generation
|
||||
subscription_delete_response::subscription_delete_response(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2N_E2AP_PDU_t *)calloc(1, sizeof(E2N_E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
successMsg = 0;
|
||||
successMsg = (E2N_SuccessfulOutcome_t *)calloc(1, sizeof(E2N_SuccessfulOutcome_t));
|
||||
assert(successMsg != 0);
|
||||
|
||||
unsuccessMsg = 0;
|
||||
unsuccessMsg = (E2N_UnsuccessfulOutcome_t *)calloc(1, sizeof(E2N_UnsuccessfulOutcome_t));
|
||||
assert(unsuccessMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (E2N_RICsubscriptionDeleteResponse_IEs_t *)calloc(NUM_SUBSCRIPTION_DELETE_RESPONSE_IES, sizeof(E2N_RICsubscriptionDeleteResponse_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
IE_Failure_array = 0;
|
||||
IE_Failure_array = (E2N_RICsubscriptionDeleteFailure_IEs_t *)calloc(NUM_SUBSCRIPTION_DELETE_FAILURE_IES, sizeof(E2N_RICsubscriptionDeleteFailure_IEs_t));
|
||||
assert(IE_Failure_array != 0);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from E2N_RIC indication IE container
|
||||
subscription_delete_response::~subscription_delete_response(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing subscription delete response memory");
|
||||
E2N_RICsubscriptionDeleteResponse_t * ric_subscription_delete_response = &(successMsg->value.choice.RICsubscriptionDeleteResponse);
|
||||
|
||||
for(unsigned int i = 0; i < ric_subscription_delete_response->protocolIEs.list.size ; i++){
|
||||
ric_subscription_delete_response->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
E2N_RICsubscriptionDeleteFailure_t * ric_subscription_failure = &(unsuccessMsg->value.choice.RICsubscriptionDeleteFailure);
|
||||
for(unsigned int i = 0; i < ric_subscription_failure->protocolIEs.list.size; i++){
|
||||
ric_subscription_failure->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(IE_Failure_array);
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_SuccessfulOutcome, successMsg);
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_UnsuccessfulOutcome, unsuccessMsg);
|
||||
|
||||
e2ap_pdu_obj->choice.successfulOutcome = NULL;
|
||||
e2ap_pdu_obj->choice.unsuccessfulOutcome = NULL;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed subscription delete response memory");
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool subscription_delete_response::encode_e2ap_subscription_delete_response(unsigned char *buf, size_t *size, subscription_response_helper &dinput, bool is_success){
|
||||
|
||||
bool res;
|
||||
|
||||
if(is_success){
|
||||
res = set_fields(successMsg, dinput);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_successfulOutcome;
|
||||
e2ap_pdu_obj->choice.successfulOutcome = successMsg;
|
||||
}
|
||||
else{
|
||||
res = set_fields(unsuccessMsg, dinput);
|
||||
if(! res){
|
||||
return false;
|
||||
}
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_unsuccessfulOutcome;
|
||||
e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
|
||||
}
|
||||
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding subcription delete response. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding Subscription Delete Response . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
retval.encoded = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool subscription_delete_response::set_fields(E2N_SuccessfulOutcome_t *success, subscription_response_helper &helper){
|
||||
|
||||
if (success == 0){
|
||||
error_string = "Invalid reference to success message in set fields subscription delete response";
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int ie_index;
|
||||
|
||||
success->procedureCode = E2N_ProcedureCode_id_ricSubscriptionDelete;
|
||||
success->criticality = E2N_Criticality_reject;
|
||||
success->value.present = E2N_SuccessfulOutcome__value_PR_RICsubscriptionDeleteResponse;
|
||||
|
||||
E2N_RICsubscriptionDeleteResponse_t * subscription_delete_response = &(success->value.choice.RICsubscriptionDeleteResponse);
|
||||
subscription_delete_response->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
E2N_RICsubscriptionDeleteResponse_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICsubscriptionDeleteResponse_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
ASN_SEQUENCE_ADD(&subscription_delete_response->protocolIEs, ies_ricreq);
|
||||
|
||||
|
||||
ie_index = 1;
|
||||
E2N_RICsubscriptionDeleteResponse_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICsubscriptionDeleteResponse_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
ASN_SEQUENCE_ADD(&subscription_delete_response->protocolIEs, ies_ranfunc);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool subscription_delete_response:: get_fields(E2N_SuccessfulOutcome_t * success_msg, subscription_response_helper & dout)
|
||||
{
|
||||
|
||||
if (success_msg == 0){
|
||||
error_string = "Invalid reference to success message inn get fields subscription delete response";
|
||||
return false;
|
||||
}
|
||||
|
||||
E2N_RICrequestID_t *requestid;
|
||||
E2N_RANfunctionID_t * ranfunctionid;
|
||||
|
||||
for(int edx = 0; edx < success_msg->value.choice.RICsubscriptionDeleteResponse.protocolIEs.list.count; edx++) {
|
||||
E2N_RICsubscriptionDeleteResponse_IEs_t *memb_ptr = success_msg->value.choice.RICsubscriptionDeleteResponse.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
|
||||
bool subscription_delete_response::set_fields(E2N_UnsuccessfulOutcome_t *unsuccess, subscription_response_helper &helper){
|
||||
|
||||
if (unsuccess == 0){
|
||||
error_string = "Invalid reference to unsuccess message in set fields subscription delete response";
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int ie_index;
|
||||
|
||||
unsuccess->procedureCode = E2N_ProcedureCode_id_ricSubscriptionDelete;
|
||||
unsuccess->criticality = E2N_Criticality_reject;
|
||||
unsuccess->value.present = E2N_UnsuccessfulOutcome__value_PR_RICsubscriptionDeleteFailure;
|
||||
|
||||
E2N_RICsubscriptionDeleteFailure_t * ric_subscription_failure = &(unsuccess->value.choice.RICsubscriptionDeleteFailure);
|
||||
ric_subscription_failure->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
E2N_RICsubscriptionDeleteFailure_IEs_t *ies_ricreq = &IE_Failure_array[ie_index];
|
||||
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICsubscriptionDeleteFailure_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, ies_ricreq);
|
||||
|
||||
ie_index = 1;
|
||||
E2N_RICsubscriptionDeleteFailure_IEs_t *ies_ranfunc = &IE_Failure_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICsubscriptionDeleteFailure_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, ies_ranfunc);
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool subscription_delete_response:: get_fields(E2N_UnsuccessfulOutcome_t * unsuccess_msg, subscription_response_helper & dout)
|
||||
{
|
||||
|
||||
if (unsuccess_msg == 0){
|
||||
error_string = "Invalid reference to unsuccess message in get fields subscription delete response";
|
||||
return false;
|
||||
}
|
||||
|
||||
E2N_RICrequestID_t *requestid;
|
||||
E2N_RANfunctionID_t * ranfunctionid;
|
||||
|
||||
for(int edx = 0; edx < unsuccess_msg->value.choice.RICsubscriptionDeleteFailure.protocolIEs.list.count; edx++) {
|
||||
E2N_RICsubscriptionDeleteFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICsubscriptionDeleteFailure.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_DEL_RESPONSE_
|
||||
#define S_DEL_RESPONSE_
|
||||
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <asn_application.h>
|
||||
#include <E2N_E2AP-PDU.h>
|
||||
#include <E2N_SuccessfulOutcome.h>
|
||||
#include <E2N_UnsuccessfulOutcome.h>
|
||||
#include <E2N_RICsubscriptionDeleteResponse.h>
|
||||
#include <E2N_RICsubscriptionDeleteFailure.h>
|
||||
#include <E2N_ProtocolIE-Field.h>
|
||||
#include <E2N_ProcedureCode.h>
|
||||
#include "response_helper.hpp"
|
||||
|
||||
#define NUM_SUBSCRIPTION_DELETE_RESPONSE_IES 2
|
||||
#define NUM_SUBSCRIPTION_DELETE_FAILURE_IES 2
|
||||
|
||||
class subscription_delete_response {
|
||||
public:
|
||||
|
||||
subscription_delete_response(void);
|
||||
~subscription_delete_response(void);
|
||||
|
||||
bool encode_e2ap_subscription_delete_response(unsigned char *, size_t *, subscription_response_helper &, bool);
|
||||
bool set_fields(E2N_SuccessfulOutcome_t *, subscription_response_helper &);
|
||||
bool get_fields(E2N_SuccessfulOutcome_t *, subscription_response_helper &);
|
||||
|
||||
bool set_fields(E2N_UnsuccessfulOutcome_t *, subscription_response_helper &);
|
||||
bool get_fields(E2N_UnsuccessfulOutcome_t *, subscription_response_helper &);
|
||||
|
||||
std::string get_error_string(void) const {
|
||||
return error_string;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
E2N_E2AP_PDU_t * e2ap_pdu_obj;
|
||||
E2N_SuccessfulOutcome_t * successMsg;
|
||||
E2N_UnsuccessfulOutcome_t * unsuccessMsg;
|
||||
|
||||
|
||||
E2N_RICsubscriptionDeleteResponse_IEs_t *IE_array;
|
||||
E2N_RICsubscriptionDeleteFailure_IEs_t *IE_Failure_array;
|
||||
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
std::string error_string;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SUB_HELPER_
|
||||
#define SUB_HELPER_
|
||||
|
||||
/*
|
||||
Simple structure to store action related information based on E2 v0.22
|
||||
Used for subscription request, response etc
|
||||
|
||||
ricActionID RICactionID,
|
||||
ricActionType RICactionType,
|
||||
ricActionDefinition RICactionDefinition OPTIONAL,
|
||||
ricSubsequentAction RICsubsequentAction OPTIONAL,
|
||||
ricCause
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "generic_helpers.hpp"
|
||||
|
||||
|
||||
// Note : if no action definition specified, octet length of action definition is NULL
|
||||
// If no subsequent action specified, default is subsequent_action = 0, time to wait is 0
|
||||
struct Action {
|
||||
|
||||
public:
|
||||
|
||||
Action(int id, int type): _is_def(false), _is_subs_act(false), _id(id), _type(type), _next_action(0), _wait(0){};
|
||||
Action(int id, int type, const void *def, size_t def_size, int next, int wait): _is_def(false), _is_subs_act(false), _id(id), _type(type){
|
||||
|
||||
if (def_size > 0){
|
||||
_is_def = true;
|
||||
_action_definition.set_ref(def);
|
||||
_action_definition.set_size(def_size);
|
||||
}
|
||||
|
||||
if(next >= 0 && wait >= 0){
|
||||
_is_subs_act = true;
|
||||
_next_action = next;
|
||||
_wait = wait;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int get_id() const{
|
||||
return _id;
|
||||
}
|
||||
|
||||
int get_type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
|
||||
const void * get_definition(void ) {
|
||||
return _action_definition.get_ref();
|
||||
}
|
||||
|
||||
int get_definition_size(void) const {
|
||||
return _action_definition.get_size();
|
||||
};
|
||||
|
||||
|
||||
int get_subsequent_action() const {
|
||||
return _next_action;
|
||||
};
|
||||
|
||||
int get_wait() const {
|
||||
return _wait;
|
||||
}
|
||||
|
||||
bool is_definition() const{
|
||||
|
||||
return _is_def;
|
||||
}
|
||||
|
||||
bool is_subsequent_action() const{
|
||||
return _is_subs_act;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool _is_def;
|
||||
bool _is_subs_act;
|
||||
int _id, _type, _next_action, _wait, _cause, _sub_cause;
|
||||
bool _is_admit;
|
||||
octet_helper _action_definition;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Helper class that stores subscription data
|
||||
*/
|
||||
|
||||
|
||||
struct subscription_helper {
|
||||
|
||||
public:
|
||||
|
||||
using action_t = std::vector<Action>;
|
||||
|
||||
subscription_helper(){
|
||||
_action_ref = std::make_unique<action_t>();
|
||||
curr_index = 0;
|
||||
};
|
||||
|
||||
action_t * get_list() const {return _action_ref.get();};
|
||||
|
||||
void clear(void){
|
||||
_action_ref.get()->clear();
|
||||
}
|
||||
|
||||
void set_request(int id, int seq_no){
|
||||
_req_id = id;
|
||||
_req_seq_no = seq_no;
|
||||
|
||||
};
|
||||
|
||||
void set_function_id(int id){
|
||||
_func_id = id;
|
||||
};
|
||||
|
||||
void set_event_def(const void *ref, size_t size){
|
||||
_event_def.set_ref(ref);
|
||||
_event_def.set_size(size);
|
||||
};
|
||||
|
||||
|
||||
void add_action(int id, int type){
|
||||
Action a(id, type) ;
|
||||
_action_ref.get()->push_back(a);
|
||||
};
|
||||
|
||||
void add_action(int id, int type, std::string action_def, int next_action, int wait_time){
|
||||
Action a (id, type, action_def.c_str(), action_def.length(), next_action, wait_time);
|
||||
_action_ref.get()->push_back(a);
|
||||
};
|
||||
|
||||
|
||||
int get_request_id(void) const{
|
||||
return _req_id;
|
||||
}
|
||||
|
||||
int get_req_seq(void) const {
|
||||
return _req_seq_no;
|
||||
}
|
||||
|
||||
int get_function_id(void) const{
|
||||
return _func_id;
|
||||
}
|
||||
|
||||
const void * get_event_def(void) {
|
||||
return _event_def.get_ref();
|
||||
}
|
||||
|
||||
int get_event_def_size(void) const {
|
||||
return _event_def.get_size();
|
||||
}
|
||||
|
||||
void print_sub_info(void){
|
||||
std::cout <<"Request ID = " << _req_id << std::endl;
|
||||
std::cout <<"Request Sequence Number = " << _req_seq_no << std::endl;
|
||||
std::cout <<"RAN Function ID = " << _func_id << std::endl;
|
||||
for(auto const & e: *(_action_ref.get())){
|
||||
std::cout <<"Action ID = " << e.get_id() << " Action Type = " << e.get_type() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<action_t> _action_ref;
|
||||
int curr_index;
|
||||
int _req_id, _req_seq_no, _func_id;
|
||||
octet_helper _event_def;
|
||||
};
|
||||
|
||||
#endif
|
@@ -0,0 +1,308 @@
|
||||
|
||||
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "subscription_request.hpp"
|
||||
|
||||
|
||||
// Set up memory allocations for each IE for encoding
|
||||
// We are responsible for memory management for each IE for encoding
|
||||
// Hence destructor should clear out memory
|
||||
// When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
|
||||
// for releasing memory by external calling function)
|
||||
subscription_request::subscription_request(void){
|
||||
|
||||
_name = "default";
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2N_E2AP_PDU_t * )calloc(1, sizeof(E2N_E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
initMsg = 0;
|
||||
initMsg = (E2N_InitiatingMessage_t * )calloc(1, sizeof(E2N_InitiatingMessage_t));
|
||||
assert(initMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (E2N_RICsubscriptionRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_REQUEST_IES, sizeof(E2N_RICsubscriptionRequest_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
action_array = 0;
|
||||
action_array = (E2N_RICaction_ToBeSetup_ItemIEs_t *)calloc(INITIAL_REQUEST_LIST_SIZE, sizeof(E2N_RICaction_ToBeSetup_ItemIEs_t));
|
||||
assert(action_array != 0);
|
||||
action_array_size = INITIAL_REQUEST_LIST_SIZE;
|
||||
// also need to add subsequent action and time to wait ..
|
||||
for (unsigned int i = 0; i < action_array_size; i++){
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct E2N_RICsubsequentAction *)calloc(1, sizeof(struct E2N_RICsubsequentAction));
|
||||
assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction != 0);
|
||||
}
|
||||
|
||||
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_initiatingMessage;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC indication IE container
|
||||
subscription_request::~subscription_request(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing subscription request memory for");;
|
||||
|
||||
// Sequence of actions to be admitted causes special heart-ache. Free ric subscription element manually and reset the ie pointer
|
||||
E2N_RICsubscription_t * ricsubscription_ie = &(IE_array[2].value.choice.RICsubscription);
|
||||
|
||||
for(int i = 0; i < ricsubscription_ie->ricAction_ToBeSetup_List.list.size; i++){
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (ricsubscription_ie->ricAction_ToBeSetup_List.list.size > 0){
|
||||
free(ricsubscription_ie->ricAction_ToBeSetup_List.list.array);
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.size = 0;
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.array = 0;
|
||||
}
|
||||
|
||||
// clear subsequent action array
|
||||
for (unsigned int i = 0; i < action_array_size; i++){
|
||||
free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
|
||||
}
|
||||
|
||||
free(action_array);
|
||||
E2N_RICsubscriptionRequest_t * subscription_request = &(initMsg->value.choice.RICsubscriptionRequest);
|
||||
|
||||
for(int i = 0; i < subscription_request->protocolIEs.list.size; i++){
|
||||
subscription_request->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if( subscription_request->protocolIEs.list.size > 0){
|
||||
free( subscription_request->protocolIEs.list.array);
|
||||
subscription_request->protocolIEs.list.array = 0;
|
||||
subscription_request->protocolIEs.list.size = 0;
|
||||
subscription_request->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
free(IE_array);
|
||||
free(initMsg);
|
||||
e2ap_pdu_obj->choice.initiatingMessage = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed subscription request memory ");
|
||||
};
|
||||
|
||||
|
||||
bool subscription_request::encode_e2ap_subscription(unsigned char *buf, size_t *size, subscription_helper &dinput){
|
||||
|
||||
bool res;
|
||||
|
||||
initMsg->procedureCode = E2N_ProcedureCode_id_ricSubscription;
|
||||
initMsg->criticality = E2N_Criticality_ignore;
|
||||
initMsg->value.present = E2N_InitiatingMessage__value_PR_RICsubscriptionRequest;
|
||||
|
||||
res = set_fields(initMsg, dinput);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding subscription request. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding Subscription Request. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < retval.encoded){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding Subscription Request . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
retval.encoded = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = retval.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool subscription_request::set_fields( E2N_InitiatingMessage_t * init_msg, subscription_helper &helper){
|
||||
|
||||
|
||||
int ie_index;
|
||||
int result = 0;
|
||||
|
||||
if (init_msg == 0){
|
||||
error_string = "Error. Invalid reference when getting fields from subscription request";
|
||||
return false;
|
||||
}
|
||||
|
||||
E2N_RICsubscriptionRequest_t * ric_subscription = &(init_msg->value.choice.RICsubscriptionRequest);
|
||||
ric_subscription->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
E2N_RICsubscriptionRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICsubscriptionRequest_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
|
||||
assert(result == 0);
|
||||
|
||||
ie_index = 1;
|
||||
E2N_RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
|
||||
assert(result == 0);
|
||||
|
||||
|
||||
ie_index = 2;
|
||||
E2N_RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
|
||||
ies_actid->criticality = E2N_Criticality_reject;
|
||||
ies_actid->id = E2N_ProtocolIE_ID_id_RICsubscription;
|
||||
ies_actid->value.present = E2N_RICsubscriptionRequest_IEs__value_PR_RICsubscription;
|
||||
E2N_RICsubscription_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscription;
|
||||
|
||||
ricsubscription_ie->ricEventTriggerDefinition.buf = (uint8_t *) helper.get_event_def();
|
||||
ricsubscription_ie->ricEventTriggerDefinition.size = helper.get_event_def_size();
|
||||
|
||||
std::vector<Action> * ref_action_array = helper.get_list();
|
||||
// do we need to resize ?
|
||||
// we don't care about contents, so just do a free/calloc
|
||||
if(action_array_size < ref_action_array->size()){
|
||||
std::cout <<"re-allocating action array from " << action_array_size << " to " << 2 * ref_action_array->size() << std::endl;
|
||||
// free subsequent allocation
|
||||
for (unsigned int i = 0; i < action_array_size; i++){
|
||||
free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
|
||||
}
|
||||
|
||||
action_array_size = 2 * ref_action_array->size();
|
||||
free(action_array);
|
||||
action_array = (E2N_RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(E2N_RICaction_ToBeSetup_ItemIEs_t));
|
||||
assert(action_array != 0);
|
||||
|
||||
// also need to add subsequent action and time to wait ..
|
||||
for (unsigned int i = 0; i < action_array_size; i++){
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct E2N_RICsubsequentAction *)calloc(1, sizeof(struct E2N_RICsubsequentAction));
|
||||
assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction != 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// reset the list count on ricAction_ToBeSetup_List;
|
||||
ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
|
||||
|
||||
for(unsigned int i = 0; i < ref_action_array->size(); i ++){
|
||||
action_array[i].criticality = E2N_Criticality_ignore;
|
||||
action_array[i].id = E2N_ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
|
||||
action_array[i].value.present = E2N_RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionID = (*ref_action_array)[i].get_id();
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionType = (*ref_action_array)[i].get_type();
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType = (*ref_action_array)[i].get_subsequent_action();
|
||||
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricTimeToWait = (*ref_action_array)[i].get_wait();
|
||||
|
||||
result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
|
||||
if (result == -1){
|
||||
error_string = "Erorr : Unable to assign memory to add Action item to set up list";
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
|
||||
assert(result == 0);
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool subscription_request:: get_fields(E2N_InitiatingMessage_t * init_msg, subscription_helper & dout)
|
||||
{
|
||||
|
||||
if (init_msg == 0){
|
||||
error_string = "Error. Invalid reference when getting fields from subscription request";
|
||||
return false;
|
||||
}
|
||||
|
||||
E2N_RICrequestID_t *requestid;
|
||||
E2N_RANfunctionID_t * ranfunctionid;
|
||||
E2N_RICsubscription_t * ricsubscription;
|
||||
|
||||
for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.count; edx++) {
|
||||
E2N_RICsubscriptionRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICsubscription):
|
||||
ricsubscription = &memb_ptr->value.choice.RICsubscription;
|
||||
dout.set_event_def(ricsubscription->ricEventTriggerDefinition.buf, ricsubscription->ricEventTriggerDefinition.size);
|
||||
|
||||
for(int index = 0; index < ricsubscription->ricAction_ToBeSetup_List.list.count; index ++){
|
||||
E2N_RICaction_ToBeSetup_ItemIEs_t * item = (E2N_RICaction_ToBeSetup_ItemIEs_t *)ricsubscription->ricAction_ToBeSetup_List.list.array[index];
|
||||
if (item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction == NULL){
|
||||
dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType);
|
||||
}
|
||||
else{
|
||||
std::string action_def = ""; // for now we are ignoring action definition
|
||||
dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType, action_def, item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType, item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricTimeToWait);
|
||||
}
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//asn_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2pdu);
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_REQUEST_
|
||||
#define S_REQUEST_
|
||||
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include <asn_application.h>
|
||||
#include <E2N_E2AP-PDU.h>
|
||||
#include <E2N_InitiatingMessage.h>
|
||||
#include <E2N_RICsubscriptionRequest.h>
|
||||
#include <E2N_RICsubscription.h>
|
||||
#include <E2N_ProtocolIE-Field.h>
|
||||
#include <E2N_ProtocolIE-Single-Container.h>
|
||||
#include <E2N_RICactions-ToBeSetup-List.h>
|
||||
#include <E2N_RICsubsequentAction.h>
|
||||
#include "subscription_helper.hpp"
|
||||
|
||||
#define NUM_SUBSCRIPTION_REQUEST_IES 3
|
||||
#define INITIAL_REQUEST_LIST_SIZE 4
|
||||
|
||||
class subscription_request{
|
||||
public:
|
||||
|
||||
subscription_request(std::string name);
|
||||
subscription_request(void);
|
||||
~subscription_request(void);
|
||||
|
||||
bool encode_e2ap_subscription(unsigned char *, size_t *, subscription_helper &);
|
||||
bool set_fields(E2N_InitiatingMessage_t *, subscription_helper &);
|
||||
bool get_fields(E2N_InitiatingMessage_t *, subscription_helper &);
|
||||
|
||||
std::string get_error(void) const{
|
||||
return error_string;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
E2N_InitiatingMessage_t *initMsg;
|
||||
E2N_E2AP_PDU_t * e2ap_pdu_obj;
|
||||
|
||||
E2N_RICsubscriptionRequest_IEs_t * IE_array;
|
||||
E2N_RICaction_ToBeSetup_ItemIEs_t * action_array;
|
||||
unsigned int action_array_size;
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
std::string _name;
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
@@ -0,0 +1,583 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "subscription_response.hpp"
|
||||
|
||||
/* The xAPP need only worry about the get_fields from a response, since it does
|
||||
not generate a response. Generating response however is included to support testing.
|
||||
*/
|
||||
|
||||
|
||||
// Primarly for generation
|
||||
subscription_response::subscription_response(void){
|
||||
|
||||
e2ap_pdu_obj = 0;
|
||||
e2ap_pdu_obj = (E2N_E2AP_PDU_t *)calloc(1, sizeof(E2N_E2AP_PDU_t));
|
||||
assert(e2ap_pdu_obj != 0);
|
||||
|
||||
successMsg = 0;
|
||||
successMsg = (E2N_SuccessfulOutcome_t *)calloc(1, sizeof(E2N_SuccessfulOutcome_t));
|
||||
assert(successMsg != 0);
|
||||
|
||||
unsuccessMsg = 0;
|
||||
unsuccessMsg = (E2N_UnsuccessfulOutcome_t *)calloc(1, sizeof(E2N_UnsuccessfulOutcome_t));
|
||||
assert(unsuccessMsg != 0);
|
||||
|
||||
IE_array = 0;
|
||||
IE_array = (E2N_RICsubscriptionResponse_IEs_t *)calloc(NUM_SUBSCRIPTION_RESPONSE_IES, sizeof(E2N_RICsubscriptionResponse_IEs_t));
|
||||
assert(IE_array != 0);
|
||||
|
||||
IE_Failure_array = 0;
|
||||
IE_Failure_array = (E2N_RICsubscriptionFailure_IEs_t *)calloc(NUM_SUBSCRIPTION_FAILURE_IES, sizeof(E2N_RICsubscriptionFailure_IEs_t));
|
||||
assert(IE_Failure_array != 0);
|
||||
|
||||
ie_admitted_list = 0;
|
||||
ie_admitted_list = (E2N_RICaction_Admitted_ItemIEs_t *)calloc(INITIAL_RESPONSE_LIST_SIZE, sizeof(E2N_RICaction_Admitted_ItemIEs_t));
|
||||
assert(ie_admitted_list != 0);
|
||||
ie_admitted_list_size = INITIAL_RESPONSE_LIST_SIZE;
|
||||
|
||||
ie_not_admitted_list = 0;
|
||||
ie_not_admitted_list = (E2N_RICaction_NotAdmitted_ItemIEs_t *)calloc(INITIAL_RESPONSE_LIST_SIZE, sizeof(E2N_RICaction_NotAdmitted_ItemIEs_t));
|
||||
assert(ie_not_admitted_list != 0);
|
||||
ie_not_admitted_list_size = INITIAL_RESPONSE_LIST_SIZE;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Clear assigned protocolIE list from RIC indication IE container
|
||||
subscription_response::~subscription_response(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing subscription response memory");
|
||||
E2N_RICaction_Admitted_List_t * response_admitted_list = (E2N_RICaction_Admitted_List_t *) &(IE_array[2].value.choice.RICaction_Admitted_List);
|
||||
|
||||
for(int i = 0; i < response_admitted_list->list.size; i++){
|
||||
response_admitted_list->list.array[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (response_admitted_list->list.size > 0){
|
||||
free(response_admitted_list->list.array);
|
||||
response_admitted_list->list.array = 0;
|
||||
response_admitted_list->list.size = 0;
|
||||
response_admitted_list->list.count = 0;
|
||||
}
|
||||
|
||||
|
||||
E2N_RICaction_NotAdmitted_List_t * response_not_admitted_list = &(IE_array[3].value.choice.RICaction_NotAdmitted_List);
|
||||
for(int i = 0; i < response_not_admitted_list->list.size; i++){
|
||||
response_not_admitted_list->list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (response_not_admitted_list->list.size > 0){
|
||||
free(response_not_admitted_list->list.array);
|
||||
response_not_admitted_list->list.array = 0;
|
||||
response_not_admitted_list->list.size = 0;
|
||||
response_not_admitted_list->list.count = 0;
|
||||
}
|
||||
|
||||
E2N_RICsubscriptionResponse_t * ric_subscription_response = &(successMsg->value.choice.RICsubscriptionResponse);
|
||||
for(int i = 0; i < ric_subscription_response->protocolIEs.list.size ; i++){
|
||||
ric_subscription_response->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (ric_subscription_response->protocolIEs.list.size > 0){
|
||||
free(ric_subscription_response->protocolIEs.list.array);
|
||||
ric_subscription_response->protocolIEs.list.array = 0;
|
||||
ric_subscription_response->protocolIEs.list.size = 0;
|
||||
ric_subscription_response->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
|
||||
E2N_RICaction_NotAdmitted_List_t * failure_not_admitted_list = &(IE_Failure_array[2].value.choice.RICaction_NotAdmitted_List);
|
||||
for(int i = 0; i < failure_not_admitted_list->list.size; i++){
|
||||
failure_not_admitted_list->list.array[i] = 0;
|
||||
}
|
||||
|
||||
if ( failure_not_admitted_list->list.size > 0){
|
||||
free( failure_not_admitted_list->list.array);
|
||||
failure_not_admitted_list->list.array = 0;
|
||||
failure_not_admitted_list->list.size = 0;
|
||||
failure_not_admitted_list->list.count = 0;
|
||||
}
|
||||
|
||||
|
||||
E2N_RICsubscriptionFailure_t * ric_subscription_failure = &(unsuccessMsg->value.choice.RICsubscriptionFailure);
|
||||
for(int i = 0; i < ric_subscription_failure->protocolIEs.list.size; i++){
|
||||
ric_subscription_failure->protocolIEs.list.array[i] = 0;
|
||||
}
|
||||
|
||||
if ( ric_subscription_failure->protocolIEs.list.size > 0){
|
||||
free(ric_subscription_failure->protocolIEs.list.array);
|
||||
ric_subscription_failure->protocolIEs.list.array = 0;
|
||||
ric_subscription_failure->protocolIEs.list.size = 0;
|
||||
ric_subscription_failure->protocolIEs.list.count = 0;
|
||||
}
|
||||
|
||||
|
||||
free(ie_admitted_list);
|
||||
free(ie_not_admitted_list);
|
||||
free(IE_Failure_array);
|
||||
free(IE_array);
|
||||
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_SuccessfulOutcome, successMsg);
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_UnsuccessfulOutcome, unsuccessMsg);
|
||||
|
||||
|
||||
e2ap_pdu_obj->choice.initiatingMessage = NULL;
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_NOTHING;
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed subscription response memory ");
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool subscription_response::encode_e2ap_subscription_response(unsigned char *buf, size_t *size, subscription_response_helper &dinput, bool is_success){
|
||||
|
||||
|
||||
if(is_success){
|
||||
set_fields_success(dinput);
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_successfulOutcome;
|
||||
e2ap_pdu_obj->choice.successfulOutcome = successMsg;
|
||||
|
||||
successMsg->procedureCode = E2N_ProcedureCode_id_ricSubscription;
|
||||
successMsg->criticality = E2N_Criticality_reject;
|
||||
successMsg->value.present = E2N_SuccessfulOutcome__value_PR_RICsubscriptionResponse;
|
||||
|
||||
}
|
||||
else{
|
||||
set_fields_unsuccess(dinput);
|
||||
e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_unsuccessfulOutcome;
|
||||
e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
|
||||
|
||||
unsuccessMsg->procedureCode = E2N_ProcedureCode_id_ricSubscription;
|
||||
unsuccessMsg->criticality = E2N_Criticality_reject;
|
||||
unsuccessMsg->value.present = E2N_UnsuccessfulOutcome__value_PR_RICsubscriptionFailure;
|
||||
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(errbuf, errbuf_len);
|
||||
error_string = "Constraints failed for encoding subscription response. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t res = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
|
||||
|
||||
if(res.encoded == -1){
|
||||
std::cout <<"Error encoding PDU. Reason =" << strerror(errno) << std::endl;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*size < res.encoded){
|
||||
fprintf(stderr, "Buffer assigned too small to encode: %s",(char *)(asn_DEF_E2N_E2AP_PDU.name));
|
||||
res.encoded = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*size = res.encoded;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void subscription_response::set_fields_success(subscription_response_helper &helper){
|
||||
|
||||
int ie_index;
|
||||
|
||||
E2N_RICsubscriptionResponse_t * subscription_response = &(successMsg->value.choice.RICsubscriptionResponse);
|
||||
//reset list count ..
|
||||
subscription_response->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
E2N_RICsubscriptionResponse_IEs_t *ies_ricreq = &IE_array[ie_index];
|
||||
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICsubscriptionResponse_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
|
||||
|
||||
|
||||
ie_index = 1;
|
||||
E2N_RICsubscriptionResponse_IEs_t *ies_ranfunc = &IE_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICsubscriptionResponse_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
|
||||
|
||||
|
||||
ie_index = 2;
|
||||
E2N_RICsubscriptionResponse_IEs_t *ies_admitted_actid = &IE_array[ie_index];
|
||||
ies_admitted_actid->criticality = E2N_Criticality_reject;
|
||||
ies_admitted_actid->id = E2N_ProtocolIE_ID_id_RICactions_Admitted;
|
||||
E2N_RICaction_Admitted_List_t *ric_admitted_actions_ie = &ies_admitted_actid->value.choice.RICaction_Admitted_List;
|
||||
ric_admitted_actions_ie->list.count = 0;
|
||||
std::vector<ActionResponse> * ref_admitted_action_array = helper.get_admitted_list();
|
||||
|
||||
if(ref_admitted_action_array->size() == 0){
|
||||
ies_admitted_actid->value.present = E2N_RICsubscriptionResponse_IEs__value_PR_NOTHING;
|
||||
}
|
||||
else{
|
||||
ies_admitted_actid->value.present = E2N_RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
|
||||
|
||||
// resize memory ?
|
||||
if (ref_admitted_action_array->size() >= ie_admitted_list_size){
|
||||
ie_admitted_list_size = 2 * ref_admitted_action_array->size();
|
||||
free(ie_admitted_list);
|
||||
ie_admitted_list = (E2N_RICaction_Admitted_ItemIEs_t *)calloc(ie_admitted_list_size, sizeof(E2N_RICaction_Admitted_ItemIEs_t));
|
||||
assert(ie_admitted_list != 0);
|
||||
};
|
||||
|
||||
|
||||
for(unsigned int i = 0; i < ref_admitted_action_array->size(); i ++){
|
||||
ie_admitted_list[i].criticality = E2N_Criticality_ignore;
|
||||
ie_admitted_list[i].id = E2N_ProtocolIE_ID_id_RICaction_Admitted_Item ;
|
||||
ie_admitted_list[i].value.present = E2N_RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
|
||||
ie_admitted_list[i].value.choice.RICaction_Admitted_Item.ricActionID = (*ref_admitted_action_array)[i].get_id();
|
||||
ASN_SEQUENCE_ADD(ric_admitted_actions_ie, &(ie_admitted_list[i]));
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
|
||||
|
||||
// optional IE : add only if non-zero list
|
||||
ie_index = 3;
|
||||
std::vector<ActionResponse> * ref_notadmitted_action_array = helper.get_not_admitted_list();
|
||||
if (ref_notadmitted_action_array->size() > 0){
|
||||
|
||||
E2N_RICsubscriptionResponse_IEs_t *ies_notadmitted_actid = &IE_array[ie_index];
|
||||
ies_notadmitted_actid->criticality = E2N_Criticality_reject;
|
||||
ies_notadmitted_actid->id = E2N_ProtocolIE_ID_id_RICactions_NotAdmitted;
|
||||
|
||||
E2N_RICaction_NotAdmitted_List_t *ric_not_admitted_actions_ie = &ies_notadmitted_actid->value.choice.RICaction_NotAdmitted_List;
|
||||
ric_not_admitted_actions_ie->list.count = 0;
|
||||
|
||||
|
||||
ies_notadmitted_actid->value.present = E2N_RICsubscriptionResponse_IEs__value_PR_RICaction_NotAdmitted_List;
|
||||
|
||||
// resize memory ?
|
||||
if (ref_notadmitted_action_array->size() >= ie_not_admitted_list_size){
|
||||
ie_not_admitted_list_size = 2 * ref_notadmitted_action_array->size();
|
||||
free(ie_not_admitted_list);
|
||||
ie_not_admitted_list = (E2N_RICaction_NotAdmitted_ItemIEs_t *)calloc(ie_not_admitted_list_size, sizeof(E2N_RICaction_NotAdmitted_ItemIEs_t));
|
||||
assert(ie_not_admitted_list != 0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
for(unsigned int i = 0; i < ref_notadmitted_action_array->size(); i ++){
|
||||
ie_not_admitted_list[i].criticality = E2N_Criticality_ignore;
|
||||
ie_not_admitted_list[i].id = E2N_ProtocolIE_ID_id_RICaction_NotAdmitted_Item ;
|
||||
ie_not_admitted_list[i].value.present = E2N_RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;;
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricActionID = (*ref_notadmitted_action_array)[i].get_id();
|
||||
|
||||
int cause = (*ref_notadmitted_action_array)[i].get_cause();
|
||||
switch(cause){
|
||||
case E2N_RICcause_PR_radioNetwork:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.radioNetwork = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case E2N_RICcause_PR_transport:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.transport = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case E2N_RICcause_PR_protocol:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.protocol= (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case E2N_RICcause_PR_misc:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.misc = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case E2N_RICcause_PR_ric:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.ric = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
default:
|
||||
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
|
||||
return;
|
||||
}
|
||||
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.present = (E2N_RICcause_PR)cause;
|
||||
ASN_SEQUENCE_ADD(ric_not_admitted_actions_ie, &(ie_not_admitted_list[i]));
|
||||
}
|
||||
|
||||
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void subscription_response:: get_fields(E2N_SuccessfulOutcome_t * success_msg, subscription_response_helper & dout)
|
||||
{
|
||||
|
||||
assert(success_msg != NULL);
|
||||
|
||||
E2N_RICrequestID_t *requestid;
|
||||
E2N_RANfunctionID_t * ranfunctionid;
|
||||
E2N_RICaction_Admitted_List_t * ric_admitted_action_list;
|
||||
E2N_RICaction_NotAdmitted_List_t * ric_not_admitted_action_list;
|
||||
|
||||
for(int edx = 0; edx < success_msg->value.choice.RICsubscriptionResponse.protocolIEs.list.count; edx++) {
|
||||
E2N_RICsubscriptionResponse_IEs_t *memb_ptr = success_msg->value.choice.RICsubscriptionResponse.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICactions_Admitted):
|
||||
ric_admitted_action_list = &memb_ptr->value.choice.RICaction_Admitted_List;
|
||||
|
||||
// admitted actions
|
||||
for(int index = 0; index < ric_admitted_action_list->list.count; index ++){
|
||||
E2N_RICaction_Admitted_ItemIEs_t * item = (E2N_RICaction_Admitted_ItemIEs_t *)ric_admitted_action_list->list.array[index];
|
||||
long int id = item->value.choice.RICaction_Admitted_Item.ricActionID;
|
||||
dout.get_admitted_list()->push_back(ActionResponse(id));
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICactions_NotAdmitted):
|
||||
ric_not_admitted_action_list = &memb_ptr->value.choice.RICaction_NotAdmitted_List;
|
||||
|
||||
for(int index = 0; index < ric_not_admitted_action_list->list.count; index ++){
|
||||
E2N_RICaction_NotAdmitted_ItemIEs_t * item = (E2N_RICaction_NotAdmitted_ItemIEs_t *)ric_not_admitted_action_list->list.array[index];
|
||||
long int id = item->value.choice.RICaction_NotAdmitted_Item.ricActionID;
|
||||
int cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.present;
|
||||
int sub_cause;
|
||||
switch(cause){
|
||||
|
||||
case E2N_RICcause_PR_radioNetwork :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.radioNetwork;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_transport :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.transport;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_protocol :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.protocol;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_misc :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.misc;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_ric :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.ric;
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cout <<"Error ! Illegal cause enum" << cause << std::endl;
|
||||
return;
|
||||
}
|
||||
dout.get_not_admitted_list()->push_back(ActionResponse(id, cause, sub_cause));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
|
||||
void subscription_response::set_fields_unsuccess( subscription_response_helper &helper){
|
||||
|
||||
int ie_index;
|
||||
E2N_RICsubscriptionFailure_t * ric_subscription_failure = &(unsuccessMsg->value.choice.RICsubscriptionFailure);
|
||||
// reset list count
|
||||
ric_subscription_failure->protocolIEs.list.count = 0;
|
||||
|
||||
ie_index = 0;
|
||||
E2N_RICsubscriptionFailure_IEs_t *ies_ricreq = &IE_Failure_array[ie_index];
|
||||
ies_ricreq->criticality = E2N_Criticality_reject;
|
||||
ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
|
||||
ies_ricreq->value.present = E2N_RICsubscriptionFailure_IEs__value_PR_RICrequestID;
|
||||
E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
|
||||
ricrequest_ie->ricRequestorID = helper.get_request_id();
|
||||
ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, &(IE_Failure_array[ie_index]));
|
||||
|
||||
ie_index = 1;
|
||||
E2N_RICsubscriptionFailure_IEs_t *ies_ranfunc = &IE_Failure_array[ie_index];
|
||||
ies_ranfunc->criticality = E2N_Criticality_reject;
|
||||
ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
|
||||
ies_ranfunc->value.present = E2N_RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
|
||||
E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
|
||||
*ranfunction_ie = helper.get_function_id();
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, &(IE_Failure_array[ie_index]));
|
||||
|
||||
ie_index = 2;
|
||||
E2N_RICsubscriptionFailure_IEs_t *ies_notadmitted_actid = &IE_Failure_array[ie_index];
|
||||
ies_notadmitted_actid->criticality = E2N_Criticality_reject;
|
||||
ies_notadmitted_actid->id = E2N_ProtocolIE_ID_id_RICactions_NotAdmitted;
|
||||
E2N_RICaction_NotAdmitted_List_t *ric_not_admitted_actions_ie = &ies_notadmitted_actid->value.choice.RICaction_NotAdmitted_List;
|
||||
ric_not_admitted_actions_ie->list.count = 0;
|
||||
std::vector<ActionResponse> * ref_notadmitted_action_array = helper.get_not_admitted_list();
|
||||
if(ref_notadmitted_action_array->size() == 0){
|
||||
ies_notadmitted_actid->value.present = E2N_RICsubscriptionFailure_IEs__value_PR_NOTHING;
|
||||
}
|
||||
else{
|
||||
ies_notadmitted_actid->value.present = E2N_RICsubscriptionFailure_IEs__value_PR_RICaction_NotAdmitted_List;
|
||||
|
||||
// resize memory ?
|
||||
if (ref_notadmitted_action_array->size() >= ie_not_admitted_list_size){
|
||||
ie_not_admitted_list_size = 2 * ref_notadmitted_action_array->size();
|
||||
free(ie_not_admitted_list);
|
||||
ie_not_admitted_list = (E2N_RICaction_NotAdmitted_ItemIEs_t *)calloc(ie_not_admitted_list_size, sizeof(E2N_RICaction_NotAdmitted_ItemIEs_t));
|
||||
assert(ie_not_admitted_list != 0);
|
||||
};
|
||||
|
||||
|
||||
// reset the list count on ricAction_ToBeSetup_List;
|
||||
for(unsigned int i = 0; i < ref_notadmitted_action_array->size(); i ++){
|
||||
ie_not_admitted_list[i].criticality = E2N_Criticality_ignore;
|
||||
ie_not_admitted_list[i].id = E2N_ProtocolIE_ID_id_RICaction_NotAdmitted_Item ;
|
||||
ie_not_admitted_list[i].value.present = E2N_RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;;
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricActionID = (*ref_notadmitted_action_array)[i].get_id();
|
||||
|
||||
int cause = (*ref_notadmitted_action_array)[i].get_cause();
|
||||
switch(cause){
|
||||
case E2N_RICcause_PR_radioNetwork:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.radioNetwork = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case E2N_RICcause_PR_transport:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.transport = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case E2N_RICcause_PR_protocol:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.protocol= (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case E2N_RICcause_PR_misc:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.misc = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
case E2N_RICcause_PR_ric:
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.choice.ric = (*ref_notadmitted_action_array)[i].get_sub_cause();
|
||||
break;
|
||||
default:
|
||||
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
|
||||
return ;
|
||||
}
|
||||
|
||||
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricCause.present = (E2N_RICcause_PR)cause;
|
||||
|
||||
ASN_SEQUENCE_ADD(ric_not_admitted_actions_ie, &(ie_not_admitted_list[i]));
|
||||
}
|
||||
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, &(IE_Failure_array[ie_index]));
|
||||
|
||||
|
||||
// // criticality diagnostics is not generated/parsed currently since optional
|
||||
// i = 3;
|
||||
// E2N_RICsubscriptionFailure_IEs_t *ies_criticality_diagnostics= &IE_Failure_array[i];
|
||||
// ies_criticality_diagnostics->criticality = E2N_Criticality_ignore;
|
||||
// ies_criticality_diagnostics->id = E2N_ProtocolIE_ID_id_CriticalityDiagnostics ;
|
||||
// ies_criticality_diagnostics->value.present = E2N_RICsubscriptionFailure_IEs__value_PR_NOTHING;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void subscription_response:: get_fields(E2N_UnsuccessfulOutcome_t * unsuccess_msg, subscription_response_helper & dout)
|
||||
{
|
||||
|
||||
assert(unsuccess_msg != NULL);
|
||||
|
||||
E2N_RICrequestID_t *requestid;
|
||||
E2N_RANfunctionID_t * ranfunctionid;
|
||||
E2N_RICaction_NotAdmitted_List_t * ric_not_admitted_action_list;
|
||||
|
||||
for(int edx = 0; edx < unsuccess_msg->value.choice.RICsubscriptionFailure.protocolIEs.list.count; edx++) {
|
||||
E2N_RICsubscriptionFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICsubscriptionFailure.protocolIEs.list.array[edx];
|
||||
|
||||
switch(memb_ptr->id)
|
||||
{
|
||||
case (E2N_ProtocolIE_ID_id_RICrequestID):
|
||||
requestid = &memb_ptr->value.choice.RICrequestID;
|
||||
dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
|
||||
break;
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RANfunctionID):
|
||||
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
|
||||
dout.set_function_id(*ranfunctionid);
|
||||
break;
|
||||
|
||||
|
||||
case (E2N_ProtocolIE_ID_id_RICactions_NotAdmitted):
|
||||
ric_not_admitted_action_list = &memb_ptr->value.choice.RICaction_NotAdmitted_List;
|
||||
|
||||
for(int index = 0; index < ric_not_admitted_action_list->list.count; index ++){
|
||||
E2N_RICaction_NotAdmitted_ItemIEs_t * item = (E2N_RICaction_NotAdmitted_ItemIEs_t *)ric_not_admitted_action_list->list.array[index];
|
||||
long int id = item->value.choice.RICaction_NotAdmitted_Item.ricActionID;
|
||||
int cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.present;
|
||||
int sub_cause;
|
||||
switch(cause){
|
||||
|
||||
case E2N_RICcause_PR_radioNetwork :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.radioNetwork;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_transport :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.transport;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_protocol :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.protocol;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_misc :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.misc;
|
||||
break;
|
||||
|
||||
case E2N_RICcause_PR_ric :
|
||||
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.ricCause.choice.ric;
|
||||
break;
|
||||
|
||||
default:
|
||||
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
|
||||
return;
|
||||
}
|
||||
dout.get_not_admitted_list()->push_back(ActionResponse(id, cause, sub_cause));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef S_RESPONSE_
|
||||
#define S_RESPONSE_
|
||||
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <asn_application.h>
|
||||
#include <E2N_E2AP-PDU.h>
|
||||
#include <E2N_SuccessfulOutcome.h>
|
||||
#include <E2N_UnsuccessfulOutcome.h>
|
||||
#include <E2N_ProtocolIE-Field.h>
|
||||
#include <E2N_ProtocolIE-Single-Container.h>
|
||||
#include <E2N_ProcedureCode.h>
|
||||
#include "response_helper.hpp"
|
||||
|
||||
#define NUM_SUBSCRIPTION_RESPONSE_IES 4
|
||||
#define NUM_SUBSCRIPTION_FAILURE_IES 3
|
||||
#define INITIAL_RESPONSE_LIST_SIZE 4
|
||||
|
||||
class subscription_response{
|
||||
public:
|
||||
|
||||
subscription_response(void);
|
||||
~subscription_response(void);
|
||||
|
||||
bool encode_e2ap_subscription_response(unsigned char *, size_t *, subscription_response_helper &, bool);
|
||||
void get_fields(E2N_SuccessfulOutcome_t *, subscription_response_helper &);
|
||||
void get_fields(E2N_UnsuccessfulOutcome_t *, subscription_response_helper &);
|
||||
|
||||
std::string get_error(void) const{
|
||||
return error_string;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void set_fields_success( subscription_response_helper &);
|
||||
void set_fields_unsuccess( subscription_response_helper &);
|
||||
|
||||
E2N_E2AP_PDU_t * e2ap_pdu_obj;
|
||||
E2N_SuccessfulOutcome_t * successMsg;
|
||||
E2N_UnsuccessfulOutcome_t * unsuccessMsg;
|
||||
|
||||
|
||||
E2N_RICsubscriptionResponse_IEs_t *IE_array;
|
||||
E2N_RICsubscriptionFailure_IEs_t *IE_Failure_array;
|
||||
|
||||
|
||||
E2N_RICaction_Admitted_ItemIEs_t * ie_admitted_list;
|
||||
E2N_RICaction_NotAdmitted_ItemIEs_t * ie_not_admitted_list;
|
||||
unsigned int ie_admitted_list_size, ie_not_admitted_list_size;
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len = 128;
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
660
setup/xapp-bs-connector/src/xapp-formats/e2sm/e2sm.cc
Normal file
660
setup/xapp-bs-connector/src/xapp-formats/e2sm/e2sm.cc
Normal file
@@ -0,0 +1,660 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, softwares
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
/* Classes to handle E2 service model based on e2sm-gNB-X2-release-1-v040.asn */
|
||||
|
||||
#include "e2sm.hpp"
|
||||
|
||||
|
||||
|
||||
//initialize
|
||||
e2sm_event_trigger::e2sm_event_trigger(void){
|
||||
|
||||
memset(&gNodeB_ID, 0, sizeof(E2N_GlobalGNB_ID_t));
|
||||
|
||||
event_trigger = 0;
|
||||
event_trigger = ( E2N_E2SM_gNB_X2_eventTriggerDefinition_t *)calloc(1, sizeof( E2N_E2SM_gNB_X2_eventTriggerDefinition_t));
|
||||
assert(event_trigger != 0);
|
||||
|
||||
// allocate space for gNodeB id (used for encoding)
|
||||
gNodeB_ID.gNB_ID.choice.gNB_ID.buf = 0;
|
||||
gNodeB_ID.gNB_ID.choice.gNB_ID.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
|
||||
assert(gNodeB_ID.gNB_ID.choice.gNB_ID.buf != 0);
|
||||
|
||||
// allocate space for plmn identity (used for encoding)
|
||||
gNodeB_ID.pLMN_Identity.buf = 0;
|
||||
gNodeB_ID.pLMN_Identity.buf = (uint8_t *) calloc(4, sizeof(uint8_t));
|
||||
assert(gNodeB_ID.pLMN_Identity.buf != 0);
|
||||
|
||||
ie_list = 0;
|
||||
ie_list = ( struct E2N_InterfaceProtocolIE_Item *) calloc(INITIAL_LIST_SIZE, sizeof( struct E2N_InterfaceProtocolIE_Item));
|
||||
assert(ie_list != 0);
|
||||
ie_list_size = INITIAL_LIST_SIZE;
|
||||
|
||||
condition_list = 0;
|
||||
condition_list = (E2N_E2SM_gNB_X2_eventTriggerDefinition::E2N_E2SM_gNB_X2_eventTriggerDefinition__interfaceProtocolIE_List *) calloc(1, sizeof(E2N_E2SM_gNB_X2_eventTriggerDefinition::E2N_E2SM_gNB_X2_eventTriggerDefinition__interfaceProtocolIE_List ));
|
||||
assert(condition_list != 0);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
e2sm_event_trigger::~e2sm_event_trigger(void){
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing event trigger object memory");
|
||||
for(int i = 0; i < condition_list->list.size; i++){
|
||||
condition_list->list.array[i] = 0;
|
||||
}
|
||||
|
||||
if (condition_list->list.size > 0){
|
||||
free(condition_list->list.array);
|
||||
condition_list->list.array = 0;
|
||||
condition_list->list.size = 0;
|
||||
condition_list->list.count = 0;
|
||||
}
|
||||
|
||||
free(condition_list);
|
||||
condition_list = 0;
|
||||
|
||||
free(gNodeB_ID.gNB_ID.choice.gNB_ID.buf);
|
||||
gNodeB_ID.gNB_ID.choice.gNB_ID.buf = 0;
|
||||
|
||||
free(gNodeB_ID.pLMN_Identity.buf);
|
||||
gNodeB_ID.pLMN_Identity.buf = 0;
|
||||
|
||||
free(ie_list);
|
||||
ie_list = 0;
|
||||
|
||||
event_trigger->interface_ID.choice.global_gNB_ID = 0;
|
||||
event_trigger->interfaceProtocolIE_List = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_eventTriggerDefinition, event_trigger);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed event trigger object memory");
|
||||
|
||||
|
||||
};
|
||||
|
||||
bool e2sm_event_trigger::encode_event_trigger(unsigned char *buf, size_t *size, e2sm_event_trigger_helper &helper){
|
||||
|
||||
bool res;
|
||||
res = set_fields(event_trigger, helper);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_eventTriggerDefinition, event_trigger, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_E2N_E2SM_gNB_X2_eventTriggerDefinition, event_trigger);
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2SM_gNB_X2_eventTriggerDefinition, event_trigger, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding event trigger definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool e2sm_event_trigger::set_fields(E2N_E2SM_gNB_X2_eventTriggerDefinition_t * ref_event_trigger, e2sm_event_trigger_helper & helper){
|
||||
if(ref_event_trigger == 0){
|
||||
error_string = "Invalid reference for Event Trigger Definition set fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the message type
|
||||
ref_event_trigger->interfaceMessageType.procedureCode = helper.procedure_code;
|
||||
ref_event_trigger->interfaceMessageType.typeOfMessage = helper.message_type;
|
||||
|
||||
ref_event_trigger->interfaceDirection = helper.interface_direction;
|
||||
ref_event_trigger->interface_ID.present = E2N_Interface_ID_PR_global_gNB_ID;
|
||||
|
||||
ref_event_trigger->interface_ID.choice.global_gNB_ID = &gNodeB_ID;
|
||||
|
||||
// to do : need to put correct code here for upding plmn id and gNodeB
|
||||
// for now just place holders :
|
||||
//================================================================
|
||||
memcpy(gNodeB_ID.pLMN_Identity.buf, helper.plmn_id.c_str(), 3);
|
||||
gNodeB_ID.pLMN_Identity.size = 3;
|
||||
|
||||
memcpy(gNodeB_ID.gNB_ID.choice.gNB_ID.buf, helper.egNB_id.c_str(), 3);
|
||||
gNodeB_ID.gNB_ID.choice.gNB_ID.size = 3;
|
||||
|
||||
// we only do global gNodeB id for now, not eNodeB
|
||||
gNodeB_ID.gNB_ID.present = E2N_GNB_ID_PR_gNB_ID;
|
||||
//================================================================
|
||||
|
||||
|
||||
// Add in any requested IE items
|
||||
std::vector<Item> * ref_ie_array = helper.get_list();
|
||||
|
||||
if (ref_ie_array->size() == 0){
|
||||
ref_event_trigger->interfaceProtocolIE_List = 0;
|
||||
|
||||
}
|
||||
else{
|
||||
ref_event_trigger->interfaceProtocolIE_List = condition_list;
|
||||
|
||||
//resize memory ?
|
||||
if(ref_ie_array->size() > ie_list_size){
|
||||
ie_list_size = 2 * ref_ie_array->size();
|
||||
free(ie_list);
|
||||
ie_list = (struct E2N_InterfaceProtocolIE_Item *)calloc(ie_list_size, sizeof(struct E2N_InterfaceProtocolIE_Item));
|
||||
assert(ie_list != 0);
|
||||
}
|
||||
|
||||
// reset the count so that adds start from the beginning
|
||||
ref_event_trigger->interfaceProtocolIE_List->list.count = 0;
|
||||
|
||||
for(unsigned int i = 0; i < ref_ie_array->size(); i++){
|
||||
|
||||
ie_list[i].interfaceProtocolIE_ID = (*ref_ie_array)[i].interface_id;
|
||||
ie_list[i].interfaceProtocolIE_Test = (*ref_ie_array)[i].test;
|
||||
|
||||
//switch(ie_list[i].interfaceProtocolIE_Value.present){
|
||||
switch((*ref_ie_array)[i].val_type){
|
||||
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueInt):
|
||||
ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueInt;
|
||||
ie_list[i].interfaceProtocolIE_Value.choice.valueInt = (*ref_ie_array)[i].value_n;
|
||||
break;
|
||||
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueEnum):
|
||||
ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueEnum;
|
||||
ie_list[i].interfaceProtocolIE_Value.choice.valueEnum = (*ref_ie_array)[i].value_n;
|
||||
break;
|
||||
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueBool):
|
||||
ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueBool;
|
||||
ie_list[i].interfaceProtocolIE_Value.choice.valueBool = (*ref_ie_array)[i].value_n;
|
||||
break;
|
||||
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueBitS):
|
||||
ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueBitS;
|
||||
ie_list[i].interfaceProtocolIE_Value.choice.valueBitS.buf = (uint8_t *)(*ref_ie_array)[i].value_s.c_str();
|
||||
ie_list[i].interfaceProtocolIE_Value.choice.valueBitS.size = (*ref_ie_array)[i].value_s.length();
|
||||
break;
|
||||
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueOctS):
|
||||
ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueOctS;
|
||||
ie_list[i].interfaceProtocolIE_Value.choice.valueOctS.buf = (uint8_t *)(*ref_ie_array)[i].value_s.c_str();
|
||||
ie_list[i].interfaceProtocolIE_Value.choice.valueOctS.size = (*ref_ie_array)[i].value_s.length();
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss <<"Error ! " << __FILE__ << "," << __LINE__ << " illegal enum " << (*ref_ie_array)[i].val_type << " for interface Protocol IE value" << std::endl;
|
||||
std::string error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ASN_SEQUENCE_ADD(ref_event_trigger->interfaceProtocolIE_List, &ie_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
bool e2sm_event_trigger::get_fields(E2N_E2SM_gNB_X2_eventTriggerDefinition_t * ref_event_trigger, e2sm_event_trigger_helper & helper){
|
||||
|
||||
if (ref_event_trigger == 0){
|
||||
error_string = "Invalid reference for Event Trigger definition get fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
helper.procedure_code = ref_event_trigger->interfaceMessageType.procedureCode;
|
||||
helper.message_type = ref_event_trigger->interfaceMessageType.typeOfMessage;
|
||||
helper.interface_direction = ref_event_trigger->interfaceDirection;
|
||||
|
||||
helper.plmn_id.assign((const char *)ref_event_trigger->interface_ID.choice.global_gNB_ID->pLMN_Identity.buf, ref_event_trigger->interface_ID.choice.global_gNB_ID->pLMN_Identity.size);
|
||||
helper.egNB_id.assign((const char *)ref_event_trigger->interface_ID.choice.global_gNB_ID->gNB_ID.choice.gNB_ID.buf, ref_event_trigger->interface_ID.choice.global_gNB_ID->gNB_ID.choice.gNB_ID.size);
|
||||
for(int i = 0; i < ref_event_trigger->interfaceProtocolIE_List->list.count; i++){
|
||||
struct E2N_InterfaceProtocolIE_Item * ie_item = ref_event_trigger->interfaceProtocolIE_List->list.array[i];
|
||||
switch(ie_item->interfaceProtocolIE_Value.present){
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueInt):
|
||||
helper.add_protocol_ie_item(ie_item->interfaceProtocolIE_ID, ie_item->interfaceProtocolIE_Test, ie_item->interfaceProtocolIE_Value.present, ie_item->interfaceProtocolIE_Value.choice.valueInt);
|
||||
break;
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueEnum):
|
||||
helper.add_protocol_ie_item(ie_item->interfaceProtocolIE_ID, ie_item->interfaceProtocolIE_Test, ie_item->interfaceProtocolIE_Value.present, ie_item->interfaceProtocolIE_Value.choice.valueEnum);
|
||||
break;
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueBool):
|
||||
helper.add_protocol_ie_item(ie_item->interfaceProtocolIE_ID, ie_item->interfaceProtocolIE_Test, ie_item->interfaceProtocolIE_Value.present, ie_item->interfaceProtocolIE_Value.choice.valueBool);
|
||||
break;
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueBitS):
|
||||
helper.add_protocol_ie_item(ie_item->interfaceProtocolIE_ID, ie_item->interfaceProtocolIE_Test, ie_item->interfaceProtocolIE_Value.present, std::string((const char *)ie_item->interfaceProtocolIE_Value.choice.valueBitS.buf,ie_item->interfaceProtocolIE_Value.choice.valueBitS.size) );
|
||||
break;
|
||||
case (E2N_InterfaceProtocolIE_Value_PR_valueOctS):
|
||||
helper.add_protocol_ie_item(ie_item->interfaceProtocolIE_ID, ie_item->interfaceProtocolIE_Test, ie_item->interfaceProtocolIE_Value.present, std::string((const char *)ie_item->interfaceProtocolIE_Value.choice.valueOctS.buf,ie_item->interfaceProtocolIE_Value.choice.valueOctS.size) );
|
||||
break;
|
||||
default:
|
||||
mdclog_write(MDCLOG_ERR, "Error : %s, %d: Unkown interface protocol IE type %d in event trigger definition\n", __FILE__, __LINE__, ie_item->interfaceProtocolIE_Value.present);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// initialize
|
||||
e2sm_indication::e2sm_indication(void) {
|
||||
|
||||
memset(&gNodeB_ID, 0, sizeof(E2N_GlobalGNB_ID_t));
|
||||
|
||||
// allocate space for gNodeB id (used for encoding)
|
||||
gNodeB_ID.gNB_ID.choice.gNB_ID.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
|
||||
assert(gNodeB_ID.gNB_ID.choice.gNB_ID.buf != 0);
|
||||
|
||||
// allocate space for plmn identity (used for encoding)
|
||||
gNodeB_ID.pLMN_Identity.buf = (uint8_t *) calloc(4, sizeof(uint8_t));
|
||||
assert(gNodeB_ID.pLMN_Identity.buf != 0);
|
||||
|
||||
header = 0;
|
||||
header = (E2N_E2SM_gNB_X2_indicationHeader_t *)calloc(1, sizeof(E2N_E2SM_gNB_X2_indicationHeader_t));
|
||||
assert(header != 0);
|
||||
|
||||
message = 0;
|
||||
message = (E2N_E2SM_gNB_X2_indicationMessage_t *)calloc(1, sizeof(E2N_E2SM_gNB_X2_indicationMessage_t));
|
||||
assert(message != 0);
|
||||
}
|
||||
|
||||
e2sm_indication::~e2sm_indication(void){
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing E2N_E2SM Indication object memory");
|
||||
|
||||
free(gNodeB_ID.gNB_ID.choice.gNB_ID.buf);
|
||||
free(gNodeB_ID.pLMN_Identity.buf);
|
||||
|
||||
header->interface_ID.choice.global_gNB_ID = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_indicationHeader, header);
|
||||
|
||||
message->interfaceMessage.buf = 0;
|
||||
message->interfaceMessage.size = 0;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_indicationMessage, message);
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed E2SM Indication object memory");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool e2sm_indication::encode_indication_header(unsigned char *buf, size_t *size, e2sm_header_helper &helper){
|
||||
|
||||
bool res;
|
||||
res = set_header_fields(header, helper);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_indicationHeader, header, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
error_string = "E2SM Indication Header Constraint failed : " + error_string;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2SM_gNB_X2_indicationHeader, header, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding E2N_E2SM Indication Header. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding E2SM Indication Header . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool e2sm_indication::encode_indication_message(unsigned char *buf, size_t *size, e2sm_message_helper &helper){
|
||||
|
||||
set_message_fields(message, helper);
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_indicationMessage, message, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
error_string = "E2SM Indication Message Constraint failed : " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2SM_gNB_X2_indicationMessage, message, buf, *size);
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding E2SM Indication Header. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding E2N_E2SM Indication Message . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Used when generating an indication header
|
||||
bool e2sm_indication::set_header_fields(E2N_E2SM_gNB_X2_indicationHeader_t *header, e2sm_header_helper &helper){
|
||||
|
||||
if (header == 0){
|
||||
error_string = "Invalid reference for E2SM Indication Header set fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
header->interfaceDirection = helper.interface_direction;
|
||||
header->interface_ID.present = E2N_Interface_ID_PR_global_gNB_ID;
|
||||
header->interface_ID.choice.global_gNB_ID = &gNodeB_ID;
|
||||
|
||||
|
||||
// to do : need to put correct code here for upding plmn id and gNodeB
|
||||
// for now just place holders :
|
||||
memcpy(gNodeB_ID.pLMN_Identity.buf, helper.plmn_id.c_str(), 3);
|
||||
gNodeB_ID.pLMN_Identity.size = 3;
|
||||
|
||||
memcpy(gNodeB_ID.gNB_ID.choice.gNB_ID.buf, helper.egNB_id.c_str(), 3);
|
||||
gNodeB_ID.gNB_ID.choice.gNB_ID.size = 3;
|
||||
|
||||
// we only do global gNodeB id for now, not eNodeB
|
||||
gNodeB_ID.gNB_ID.present = E2N_GNB_ID_PR_gNB_ID;
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// used when decoding an indication header
|
||||
bool e2sm_indication::get_header_fields(E2N_E2SM_gNB_X2_indicationHeader_t *header, e2sm_header_helper &helper){
|
||||
|
||||
if (header == 0){
|
||||
error_string = "Invalid reference for E2SM Indication header get fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
helper.interface_direction = header->interfaceDirection;
|
||||
helper.plmn_id.assign((const char *)header->interface_ID.choice.global_gNB_ID->pLMN_Identity.buf, header->interface_ID.choice.global_gNB_ID->pLMN_Identity.size);
|
||||
helper.egNB_id.assign((const char *)header->interface_ID.choice.global_gNB_ID->gNB_ID.choice.gNB_ID.buf, header->interface_ID.choice.global_gNB_ID->gNB_ID.choice.gNB_ID.size);
|
||||
|
||||
// to do : add code to decipher plmn and global gnodeb from ints (since that is likely the convention for packing)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Used when generating an indication message
|
||||
bool e2sm_indication::set_message_fields(E2N_E2SM_gNB_X2_indicationMessage_t *interface_message, e2sm_message_helper &helper){
|
||||
|
||||
if(interface_message == 0){
|
||||
error_string = "Invalid reference for E2SM Indication Message set fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
// interface-message is an octet string. just point it to the buffer
|
||||
interface_message->interfaceMessage.buf = &(helper.x2ap_pdu[0]);
|
||||
interface_message->interfaceMessage.size = helper.x2ap_pdu_size;
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
// used when decoding an indication message
|
||||
bool e2sm_indication::get_message_fields( E2N_E2SM_gNB_X2_indicationMessage_t *interface_message, e2sm_message_helper &helper){
|
||||
|
||||
|
||||
if(interface_message == 0){
|
||||
error_string = "Invalid reference for E2SM Indication Message get fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
// interface message is an octet string
|
||||
helper.x2ap_pdu = interface_message->interfaceMessage.buf;;
|
||||
helper.x2ap_pdu_size = interface_message->interfaceMessage.size;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// initialize
|
||||
e2sm_control::e2sm_control(void) {
|
||||
|
||||
memset(&gNodeB_ID, 0, sizeof(E2N_GlobalGNB_ID_t));
|
||||
|
||||
// allocate space for gNodeB id (used for encoding)
|
||||
gNodeB_ID.gNB_ID.choice.gNB_ID.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
|
||||
assert(gNodeB_ID.gNB_ID.choice.gNB_ID.buf != 0);
|
||||
|
||||
// allocate space for plmn identity (used for encoding)
|
||||
gNodeB_ID.pLMN_Identity.buf = (uint8_t *) calloc(4, sizeof(uint8_t));
|
||||
assert(gNodeB_ID.pLMN_Identity.buf != 0);
|
||||
|
||||
header = 0;
|
||||
header = (E2N_E2SM_gNB_X2_controlHeader_t *)calloc(1, sizeof(E2N_E2SM_gNB_X2_controlHeader_t));
|
||||
assert(header != 0);
|
||||
|
||||
message = 0;
|
||||
message = (E2N_E2SM_gNB_X2_controlMessage_t *)calloc(1, sizeof(E2N_E2SM_gNB_X2_controlMessage_t));
|
||||
assert(message != 0);
|
||||
}
|
||||
|
||||
e2sm_control::~e2sm_control(void){
|
||||
mdclog_write(MDCLOG_DEBUG, "Freeing E2SM Control object memory");
|
||||
|
||||
free(gNodeB_ID.gNB_ID.choice.gNB_ID.buf);
|
||||
free(gNodeB_ID.pLMN_Identity.buf);
|
||||
header->interface_ID.choice.global_gNB_ID = 0;
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_controlHeader, header);
|
||||
|
||||
message->interfaceMessage.buf = 0;
|
||||
ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_controlMessage, message);
|
||||
|
||||
mdclog_write(MDCLOG_DEBUG, "Freed E2SM Control object memory");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool e2sm_control::encode_control_header(unsigned char *buf, size_t *size, e2sm_header_helper &helper){
|
||||
|
||||
bool res;
|
||||
res = set_header_fields(header, helper);
|
||||
if (!res){
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_controlHeader, header, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
error_string = "E2SM Control Header Constraint failed : " + error_string;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2SM_gNB_X2_controlHeader, header, buf, *size);
|
||||
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding E2SM Control Header. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding E2N_E2SM Control Header . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool e2sm_control::encode_control_message(unsigned char *buf, size_t *size, e2sm_message_helper &helper){
|
||||
|
||||
set_message_fields(message, helper);
|
||||
|
||||
int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_controlMessage, message, errbuf, &errbuf_len);
|
||||
if(ret_constr){
|
||||
error_string.assign(&errbuf[0], errbuf_len);
|
||||
error_string = "E2SM Control Message Constraint failed : " + error_string;
|
||||
return false;
|
||||
}
|
||||
|
||||
asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2SM_gNB_X2_controlMessage, message, buf, *size);
|
||||
if(retval.encoded == -1){
|
||||
error_string.assign(strerror(errno));
|
||||
error_string = "Error encoding E2SM Control Message. Reason = " + error_string;
|
||||
return false;
|
||||
}
|
||||
else if (retval.encoded > *size){
|
||||
std::stringstream ss;
|
||||
ss <<"Error encoding E2SM Control Message . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
|
||||
error_string = ss.str();
|
||||
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
*size = retval.encoded;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Used when generating an indication header
|
||||
bool e2sm_control::set_header_fields(E2N_E2SM_gNB_X2_controlHeader_t *header, e2sm_header_helper &helper){
|
||||
|
||||
if (header == 0){
|
||||
error_string = "Invalid reference for E2SM Control Header set fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
header->interfaceDirection = helper.interface_direction;
|
||||
header->interface_ID.present = E2N_Interface_ID_PR_global_gNB_ID;
|
||||
header->interface_ID.choice.global_gNB_ID = &gNodeB_ID;
|
||||
|
||||
|
||||
// to do : need to put correct code here for upding plmn id and gNodeB
|
||||
// for now just place holders :
|
||||
memcpy(gNodeB_ID.pLMN_Identity.buf, helper.plmn_id.c_str(), 3);
|
||||
gNodeB_ID.pLMN_Identity.size = 3;
|
||||
|
||||
memcpy(gNodeB_ID.gNB_ID.choice.gNB_ID.buf, helper.egNB_id.c_str(), 3);
|
||||
gNodeB_ID.gNB_ID.choice.gNB_ID.size = 3;
|
||||
|
||||
// we only do global gNodeB id for now, not eNodeB
|
||||
gNodeB_ID.gNB_ID.present = E2N_GNB_ID_PR_gNB_ID;
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// used when decoding an indication header
|
||||
bool e2sm_control::get_header_fields(E2N_E2SM_gNB_X2_controlHeader_t *header, e2sm_header_helper &helper){
|
||||
|
||||
if (header == 0){
|
||||
error_string = "Invalid reference for E2SM Control header get fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
helper.interface_direction = header->interfaceDirection;
|
||||
helper.plmn_id.assign((const char *)header->interface_ID.choice.global_gNB_ID->pLMN_Identity.buf, header->interface_ID.choice.global_gNB_ID->pLMN_Identity.size);
|
||||
helper.egNB_id.assign((const char *)header->interface_ID.choice.global_gNB_ID->gNB_ID.choice.gNB_ID.buf, header->interface_ID.choice.global_gNB_ID->gNB_ID.choice.gNB_ID.size);
|
||||
|
||||
// to do : add code to decipher plmn and global gnodeb from ints (since that is likely the convention for packing)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Used when generating an indication message
|
||||
bool e2sm_control::set_message_fields(E2N_E2SM_gNB_X2_controlMessage_t *interface_message, e2sm_message_helper &helper){
|
||||
|
||||
if(interface_message == 0){
|
||||
error_string = "Invalid reference for E2SM Control Message set fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
// interface-message is an octet string. just point it to the buffer
|
||||
interface_message->interfaceMessage.buf = &(helper.x2ap_pdu[0]);
|
||||
interface_message->interfaceMessage.size = helper.x2ap_pdu_size;
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
// used when decoding an indication message
|
||||
bool e2sm_control::get_message_fields( E2N_E2SM_gNB_X2_controlMessage_t *interface_message, e2sm_message_helper &helper){
|
||||
|
||||
|
||||
if(interface_message == 0){
|
||||
error_string = "Invalid reference for E2SM Control Message get fields";
|
||||
return false;
|
||||
}
|
||||
|
||||
// interface message is an octet string
|
||||
helper.x2ap_pdu = interface_message->interfaceMessage.buf;;
|
||||
helper.x2ap_pdu_size = interface_message->interfaceMessage.size;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
145
setup/xapp-bs-connector/src/xapp-formats/e2sm/e2sm.hpp
Normal file
145
setup/xapp-bs-connector/src/xapp-formats/e2sm/e2sm.hpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
/* Classes to handle E2 service model based on e2sm-gNB-X2-release-1-v040.asn */
|
||||
|
||||
#ifndef E2SM_
|
||||
#define E2SM_
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <E2N_E2SM-gNB-X2-indicationHeader.h>
|
||||
#include <E2N_E2SM-gNB-X2-indicationMessage.h>
|
||||
#include <E2N_E2SM-gNB-X2-controlHeader.h>
|
||||
#include <E2N_E2SM-gNB-X2-controlMessage.h>
|
||||
#include <E2N_E2SM-gNB-X2-eventTriggerDefinition.h>
|
||||
|
||||
#include <E2N_GlobalGNB-ID.h>
|
||||
#include <E2N_TypeOfMessage.h>
|
||||
#include <E2N_InterfaceProtocolIE-Item.h>
|
||||
|
||||
#include<E2N_InterfaceProtocolIE-ID.h>
|
||||
#include<E2N_InterfaceProtocolIE-Value.h>
|
||||
#include<E2N_InterfaceProtocolIE-Test.h>
|
||||
#include "../../xapp-formats/e2sm/e2sm_helpers.hpp"
|
||||
|
||||
#define INITIAL_LIST_SIZE 4
|
||||
|
||||
|
||||
|
||||
|
||||
/* builder class for E2SM event trigger definition */
|
||||
|
||||
class e2sm_event_trigger {
|
||||
public:
|
||||
e2sm_event_trigger(void);
|
||||
~e2sm_event_trigger(void);
|
||||
|
||||
bool set_fields(E2N_E2SM_gNB_X2_eventTriggerDefinition_t *, e2sm_event_trigger_helper &);
|
||||
bool get_fields(E2N_E2SM_gNB_X2_eventTriggerDefinition_t *, e2sm_event_trigger_helper &);
|
||||
bool encode_event_trigger(unsigned char *, size_t *, e2sm_event_trigger_helper &);
|
||||
|
||||
std::string get_error (void) const {return error_string ;};
|
||||
|
||||
private:
|
||||
|
||||
E2N_E2SM_gNB_X2_eventTriggerDefinition_t * event_trigger; // used for encoding
|
||||
E2N_GlobalGNB_ID_t gNodeB_ID;
|
||||
struct E2N_InterfaceProtocolIE_Item * ie_list;
|
||||
unsigned int ie_list_size;
|
||||
|
||||
//std::vector<struct InterfaceProtocolIE_Item> ie_list;
|
||||
E2N_E2SM_gNB_X2_eventTriggerDefinition::E2N_E2SM_gNB_X2_eventTriggerDefinition__interfaceProtocolIE_List *condition_list;
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len;
|
||||
std::string error_string;
|
||||
};
|
||||
|
||||
|
||||
/* builder class for E2SM indication using ASN1c */
|
||||
|
||||
class e2sm_indication {
|
||||
public:
|
||||
|
||||
e2sm_indication(void);
|
||||
~e2sm_indication(void);
|
||||
|
||||
E2N_E2SM_gNB_X2_indicationHeader_t * get_header(void);
|
||||
E2N_E2SM_gNB_X2_indicationMessage_t * get_message(void);
|
||||
|
||||
bool set_header_fields(E2N_E2SM_gNB_X2_indicationHeader_t *, e2sm_header_helper &);
|
||||
bool get_header_fields(E2N_E2SM_gNB_X2_indicationHeader_t *, e2sm_header_helper &);
|
||||
|
||||
bool set_message_fields(E2N_E2SM_gNB_X2_indicationMessage_t *, e2sm_message_helper &);
|
||||
bool get_message_fields(E2N_E2SM_gNB_X2_indicationMessage_t *, e2sm_message_helper &);
|
||||
|
||||
bool encode_indication_header(unsigned char * , size_t * , e2sm_header_helper &);
|
||||
bool encode_indication_message(unsigned char *, size_t *, e2sm_message_helper &);
|
||||
std::string get_error (void) const {return error_string ; };
|
||||
|
||||
private:
|
||||
|
||||
E2N_E2SM_gNB_X2_indicationHeader_t *header; // used for encoding
|
||||
E2N_E2SM_gNB_X2_indicationMessage_t *message; // used for encoding
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len;
|
||||
E2N_GlobalGNB_ID_t gNodeB_ID;
|
||||
std::string error_string;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/* builder class for E2SM control using ASN1c */
|
||||
|
||||
class e2sm_control {
|
||||
public:
|
||||
|
||||
e2sm_control(void);
|
||||
~e2sm_control(void);
|
||||
|
||||
E2N_E2SM_gNB_X2_controlHeader_t * get_header(void);
|
||||
E2N_E2SM_gNB_X2_controlMessage_t * get_message(void);
|
||||
|
||||
bool set_header_fields(E2N_E2SM_gNB_X2_controlHeader_t *, e2sm_header_helper &);
|
||||
bool get_header_fields(E2N_E2SM_gNB_X2_controlHeader_t *, e2sm_header_helper &);
|
||||
|
||||
bool set_message_fields(E2N_E2SM_gNB_X2_controlMessage_t *, e2sm_message_helper &);
|
||||
bool get_message_fields(E2N_E2SM_gNB_X2_controlMessage_t *, e2sm_message_helper &);
|
||||
|
||||
bool encode_control_header(unsigned char * , size_t * , e2sm_header_helper &);
|
||||
bool encode_control_message(unsigned char *, size_t *, e2sm_message_helper &);
|
||||
std::string get_error (void) const {return error_string ; };
|
||||
|
||||
private:
|
||||
|
||||
E2N_E2SM_gNB_X2_controlHeader_t *header; // used for encoding
|
||||
E2N_E2SM_gNB_X2_controlMessage_t *message; // used for encoding
|
||||
|
||||
char errbuf[128];
|
||||
size_t errbuf_len;
|
||||
E2N_GlobalGNB_ID_t gNodeB_ID;
|
||||
std::string error_string;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
115
setup/xapp-bs-connector/src/xapp-formats/e2sm/e2sm_helpers.hpp
Normal file
115
setup/xapp-bs-connector/src/xapp-formats/e2sm/e2sm_helpers.hpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, softwares
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
/* Classes to handle E2 service model based on e2sm-gNB-X2-release-1-v040.asn */
|
||||
|
||||
#ifndef E2SM_HELPER_
|
||||
#define E2SM_HELPER_
|
||||
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
/* information holder for E2SM indication header */
|
||||
typedef struct e2sm_header_helper e2sm_header_helper;
|
||||
struct e2sm_header_helper {
|
||||
int egNB_id_type;
|
||||
|
||||
std::string egNB_id;
|
||||
std::string plmn_id;
|
||||
|
||||
long int interface_direction;
|
||||
unsigned char* timestamp;
|
||||
};
|
||||
|
||||
/* information holder for E2SM indication message */
|
||||
typedef struct e2sm_message_helper e2sm_message_helper;
|
||||
struct e2sm_message_helper {
|
||||
unsigned char * x2ap_pdu;
|
||||
size_t x2ap_pdu_size;
|
||||
};
|
||||
|
||||
|
||||
/* information holder for E2SM Action Trigger Definition */
|
||||
struct Item
|
||||
{
|
||||
Item(long int id, long int test, long int val_type, int value):interface_id(id), test(test), val_type(val_type), value_n(value){};
|
||||
Item(long int id, long int test, long int val_type, std::string value):interface_id(id), test(test), val_type(val_type), value_s(value){};
|
||||
|
||||
long int interface_id;
|
||||
long int test;
|
||||
long int val_type;
|
||||
long int value_n;
|
||||
std::string value_s;
|
||||
|
||||
};
|
||||
|
||||
typedef struct e2sm_event_trigger_helper e2sm_event_trigger_helper;
|
||||
struct e2sm_event_trigger_helper {
|
||||
|
||||
int egNB_id_type;
|
||||
std::string egNB_id;
|
||||
std::string plmn_id;
|
||||
|
||||
long int interface_direction;
|
||||
long int procedure_code;
|
||||
|
||||
long int message_type;
|
||||
|
||||
|
||||
std::vector<struct Item> * get_list(void){ return &protocol_ie_list; };
|
||||
void add_protocol_ie_item(long int id, long int test , unsigned int val_type, long int value ){
|
||||
// into list
|
||||
protocol_ie_list.emplace_back(id, test, val_type, value);
|
||||
};
|
||||
|
||||
void add_protocol_ie_item(long int id, long int test, unsigned int val_type, std::string value){
|
||||
// into list
|
||||
protocol_ie_list.emplace_back(id, test, val_type, value);
|
||||
};
|
||||
|
||||
void clear(void){
|
||||
protocol_ie_list.clear();
|
||||
}
|
||||
|
||||
std::string get_string(void) const {
|
||||
std::stringstream ss;
|
||||
ss << "egNB_ID_type = " << egNB_id_type << std::endl;
|
||||
ss << "PLMN Id = " << plmn_id << std::endl;
|
||||
ss << "Procedure Code = " << procedure_code << std::endl;
|
||||
ss << "Message Type = " << message_type << std::endl;
|
||||
|
||||
std::string info;
|
||||
info = ss.str();
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::vector<struct Item> protocol_ie_list;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
49
setup/xapp-bs-connector/src/xapp-mgmt/a1_helper.hpp
Normal file
49
setup/xapp-bs-connector/src/xapp-mgmt/a1_helper.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* a1_policy.hpp
|
||||
*
|
||||
* Created on: Mar, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
|
||||
#ifndef SRC_XAPP_MGMT_A1MSG_A1_POLICY_HELPER_HPP_
|
||||
#define SRC_XAPP_MGMT_A1MSG_A1_POLICY_HELPER_HPP_
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/schema.h>
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
typedef struct a1_policy_helper a1_policy_helper;
|
||||
|
||||
struct a1_policy_helper{
|
||||
|
||||
std::string operation;
|
||||
std::string policy_type_id;
|
||||
std::string policy_instance_id;
|
||||
std::string handler_id;
|
||||
std::string status;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* SRC_XAPP_FORMATS_A1MSG_A1_POLICY_HELPER_HPP_ */
|
49
setup/xapp-bs-connector/src/xapp-mgmt/format_helper.hpp
Normal file
49
setup/xapp-bs-connector/src/xapp-mgmt/format_helper.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2018-2019 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* a1_policy.hpp
|
||||
*
|
||||
* Created on: Mar, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
|
||||
#ifndef SRC_XAPP_MGMT_A1MSG_A1_POLICY_HELPER_HPP_
|
||||
#define SRC_XAPP_MGMT_A1MSG_A1_POLICY_HELPER_HPP_
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/schema.h>
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
typedef struct a1_policy_helper a1_policy_helper;
|
||||
|
||||
struct a1_policy_helper{
|
||||
|
||||
std::string operation;
|
||||
std::string policy_type_id;
|
||||
std::string policy_instance_id;
|
||||
std::string handler_id;
|
||||
std::string status;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* SRC_XAPP_FORMATS_A1MSG_A1_POLICY_HELPER_HPP_ */
|
293
setup/xapp-bs-connector/src/xapp-mgmt/msgs_proc.cc
Normal file
293
setup/xapp-bs-connector/src/xapp-mgmt/msgs_proc.cc
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* msgs_proc.cc
|
||||
* Created on: 2019
|
||||
* Author: Ashwin Shridharan, Shraboni Jana
|
||||
*/
|
||||
|
||||
|
||||
#include "msgs_proc.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
bool XappMsgHandler::encode_subscription_delete_request(unsigned char* buffer, size_t *buf_len){
|
||||
|
||||
subscription_helper sub_helper;
|
||||
sub_helper.set_request(0); // requirement of subscription manager ... ?
|
||||
sub_helper.set_function_id(0);
|
||||
|
||||
subscription_delete e2ap_sub_req_del;
|
||||
|
||||
// generate the delete request pdu
|
||||
|
||||
bool res = e2ap_sub_req_del.encode_e2ap_subscription(&buffer[0], buf_len, sub_helper);
|
||||
if(! res){
|
||||
mdclog_write(MDCLOG_ERR, "%s, %d: Error encoding subscription delete request pdu. Reason = %s", __FILE__, __LINE__, e2ap_sub_req_del.get_error().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool XappMsgHandler::decode_subscription_response(unsigned char* data_buf, size_t data_size){
|
||||
|
||||
subscription_helper subhelper;
|
||||
subscription_response subresponse;
|
||||
bool res = true;
|
||||
E2AP_PDU_t *e2pdu = 0;
|
||||
|
||||
asn_dec_rval_t rval;
|
||||
|
||||
ASN_STRUCT_RESET(asn_DEF_E2AP_PDU, e2pdu);
|
||||
|
||||
rval = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void**)&e2pdu, data_buf, data_size);
|
||||
switch(rval.code)
|
||||
{
|
||||
case RC_OK:
|
||||
//Put in Subscription Response Object.
|
||||
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
|
||||
break;
|
||||
case RC_WMORE:
|
||||
mdclog_write(MDCLOG_ERR, "RC_WMORE");
|
||||
res = false;
|
||||
break;
|
||||
case RC_FAIL:
|
||||
mdclog_write(MDCLOG_ERR, "RC_FAIL");
|
||||
res = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2pdu);
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
bool XappMsgHandler::a1_policy_handler(char * message, int *message_len, a1_policy_helper &helper){
|
||||
|
||||
rapidjson::Document doc;
|
||||
if (doc.Parse(message).HasParseError()){
|
||||
mdclog_write(MDCLOG_ERR, "Error: %s, %d :: Could not decode A1 JSON message %s\n", __FILE__, __LINE__, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Extract Operation
|
||||
rapidjson::Pointer temp1("/operation");
|
||||
rapidjson::Value * ref1 = temp1.Get(doc);
|
||||
if (ref1 == NULL){
|
||||
mdclog_write(MDCLOG_ERR, "Error : %s, %d:: Could not extract policy type id from %s\n", __FILE__, __LINE__, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
helper.operation = ref1->GetString();
|
||||
|
||||
// Extract policy id type
|
||||
rapidjson::Pointer temp2("/policy_type_id");
|
||||
rapidjson::Value * ref2 = temp2.Get(doc);
|
||||
if (ref2 == NULL){
|
||||
mdclog_write(MDCLOG_ERR, "Error : %s, %d:: Could not extract policy type id from %s\n", __FILE__, __LINE__, message);
|
||||
return false;
|
||||
}
|
||||
//helper.policy_type_id = ref2->GetString();
|
||||
helper.policy_type_id = to_string(ref2->GetInt());
|
||||
|
||||
// Extract policy instance id
|
||||
rapidjson::Pointer temp("/policy_instance_id");
|
||||
rapidjson::Value * ref = temp.Get(doc);
|
||||
if (ref == NULL){
|
||||
mdclog_write(MDCLOG_ERR, "Error : %s, %d:: Could not extract policy type id from %s\n", __FILE__, __LINE__, message);
|
||||
return false;
|
||||
}
|
||||
helper.policy_instance_id = ref->GetString();
|
||||
|
||||
if (helper.policy_type_id == "1" && helper.operation == "CREATE"){
|
||||
helper.status = "OK";
|
||||
Document::AllocatorType& alloc = doc.GetAllocator();
|
||||
|
||||
Value handler_id;
|
||||
handler_id.SetString(helper.handler_id.c_str(), helper.handler_id.length(), alloc);
|
||||
|
||||
Value status;
|
||||
status.SetString(helper.status.c_str(), helper.status.length(), alloc);
|
||||
|
||||
|
||||
doc.AddMember("handler_id", handler_id, alloc);
|
||||
doc.AddMember("status",status, alloc);
|
||||
doc.RemoveMember("operation");
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
doc.Accept(writer);
|
||||
strncpy(message,buffer.GetString(), buffer.GetLength());
|
||||
*message_len = buffer.GetLength();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//For processing received messages.XappMsgHandler should mention if resend is required or not.
|
||||
void XappMsgHandler::operator()(rmr_mbuf_t *message, bool *resend){
|
||||
|
||||
if (message->len > MAX_RMR_RECV_SIZE){
|
||||
mdclog_write(MDCLOG_ERR, "Error : %s, %d, RMR message larger than %d. Ignoring ...", __FILE__, __LINE__, MAX_RMR_RECV_SIZE);
|
||||
return;
|
||||
}
|
||||
a1_policy_helper helper;
|
||||
bool res=false;
|
||||
switch(message->mtype){
|
||||
//need to fix the health check.
|
||||
case (RIC_HEALTH_CHECK_REQ):
|
||||
message->mtype = RIC_HEALTH_CHECK_RESP; // if we're here we are running and all is ok
|
||||
message->sub_id = -1;
|
||||
strncpy( (char*)message->payload, "HELLOWORLD OK\n", rmr_payload_size( message) );
|
||||
*resend = true;
|
||||
break;
|
||||
|
||||
case (RIC_INDICATION): {
|
||||
|
||||
mdclog_write(MDCLOG_INFO, "Received RIC indication message of type = %d", message->mtype);
|
||||
|
||||
unsigned char *me_id_null;
|
||||
unsigned char *me_id = rmr_get_meid(message, me_id_null);
|
||||
mdclog_write(MDCLOG_INFO,"RMR Received MEID: %s",me_id);
|
||||
|
||||
process_ric_indication(message->mtype, me_id, message->payload, message->len);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case (RIC_SUB_RESP): {
|
||||
mdclog_write(MDCLOG_INFO, "Received subscription message of type = %d", message->mtype);
|
||||
|
||||
unsigned char *me_id_null;
|
||||
unsigned char *me_id = rmr_get_meid(message, me_id_null);
|
||||
mdclog_write(MDCLOG_INFO,"RMR Received MEID: %s",me_id);
|
||||
|
||||
if(_ref_sub_handler !=NULL){
|
||||
_ref_sub_handler->manage_subscription_response(message->mtype, me_id, message->payload, message->len);
|
||||
} else {
|
||||
mdclog_write(MDCLOG_ERR, " Error :: %s, %d : Subscription handler not assigned in message processor !", __FILE__, __LINE__);
|
||||
}
|
||||
*resend = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case A1_POLICY_REQ:
|
||||
|
||||
mdclog_write(MDCLOG_INFO, "In Message Handler: Received A1_POLICY_REQ.");
|
||||
helper.handler_id = xapp_id;
|
||||
|
||||
res = a1_policy_handler((char*)message->payload, &message->len, helper);
|
||||
if(res){
|
||||
message->mtype = A1_POLICY_RESP; // if we're here we are running and all is ok
|
||||
message->sub_id = -1;
|
||||
*resend = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
mdclog_write(MDCLOG_ERR, "Error :: Unknown message type %d received from RMR", message->mtype);
|
||||
*resend = false;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
};
|
||||
|
||||
void process_ric_indication(int message_type, transaction_identifier id, const void *message_payload, size_t message_len) {
|
||||
|
||||
std::cout << "In Process RIC indication" << std::endl;
|
||||
std::cout << "ID " << id << std::endl;
|
||||
|
||||
// decode received message payload
|
||||
E2AP_PDU_t *pdu = nullptr;
|
||||
auto retval = asn_decode(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void **) &pdu, message_payload, message_len);
|
||||
|
||||
// print decoded payload
|
||||
if (retval.code == RC_OK) {
|
||||
char *printBuffer;
|
||||
size_t size;
|
||||
FILE *stream = open_memstream(&printBuffer, &size);
|
||||
asn_fprint(stream, &asn_DEF_E2AP_PDU, pdu);
|
||||
mdclog_write(MDCLOG_DEBUG, "Decoded E2AP PDU: %s", printBuffer);
|
||||
|
||||
uint8_t res = procRicIndication(pdu, id);
|
||||
}
|
||||
else {
|
||||
std::cout << "process_ric_indication, retval.code " << retval.code << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle RIC indication
|
||||
* TODO doxy
|
||||
*/
|
||||
uint8_t procRicIndication(E2AP_PDU_t *e2apMsg, transaction_identifier gnb_id)
|
||||
{
|
||||
uint8_t idx;
|
||||
uint8_t ied;
|
||||
uint8_t ret = RC_OK;
|
||||
uint32_t recvBufLen;
|
||||
RICindication_t *ricIndication;
|
||||
RICaction_ToBeSetup_ItemIEs_t *actionItem;
|
||||
|
||||
printf("\nE2AP : RIC Indication received");
|
||||
ricIndication = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
|
||||
|
||||
printf("protocolIEs elements %d\n", ricIndication->protocolIEs.list.count);
|
||||
|
||||
for (idx = 0; idx < ricIndication->protocolIEs.list.count; idx++)
|
||||
{
|
||||
switch(ricIndication->protocolIEs.list.array[idx]->id)
|
||||
{
|
||||
case 28: // RIC indication type
|
||||
{
|
||||
long ricindicationType = ricIndication->protocolIEs.list.array[idx]-> \
|
||||
value.choice.RICindicationType;
|
||||
|
||||
printf("ricindicationType %ld\n", ricindicationType);
|
||||
|
||||
break;
|
||||
}
|
||||
case 26: // RIC indication message
|
||||
{
|
||||
int payload_size = ricIndication->protocolIEs.list.array[idx]-> \
|
||||
value.choice.RICindicationMessage.size;
|
||||
|
||||
|
||||
char* payload = (char*) calloc(payload_size, sizeof(char));
|
||||
memcpy(payload, ricIndication->protocolIEs.list.array[idx]-> \
|
||||
value.choice.RICindicationMessage.buf, payload_size);
|
||||
|
||||
printf("Payload %s\n", payload);
|
||||
|
||||
// send payload to agent
|
||||
std::string agent_ip = find_agent_ip_from_gnb(gnb_id);
|
||||
send_socket(payload, agent_ip);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret; // TODO update ret value in case of errors
|
||||
}
|
74
setup/xapp-bs-connector/src/xapp-mgmt/msgs_proc.hpp
Normal file
74
setup/xapp-bs-connector/src/xapp-mgmt/msgs_proc.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* msgs_proc.hpp
|
||||
* Created on: 2019
|
||||
* Author: Ashwin Shridharan, Shraboni Jana
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef XAPP_MSG_XAPP_MSG_HPP_
|
||||
#define XAPP_MSG_XAPP_MSG_HPP_
|
||||
|
||||
#include <iostream>
|
||||
#include<rmr/rmr.h>
|
||||
#include <rmr/RIC_message_types.h>
|
||||
#include <mdclog/mdclog.h>
|
||||
|
||||
#include "a1_helper.hpp"
|
||||
#include "e2ap_control.hpp"
|
||||
#include "e2ap_control_response.hpp"
|
||||
#include "e2ap_indication.hpp"
|
||||
#include "subscription_delete_request.hpp"
|
||||
#include "subscription_delete_response.hpp"
|
||||
#include "subscription_helper.hpp"
|
||||
#include "subscription_request.hpp"
|
||||
#include "subscription_request.hpp"
|
||||
#include "subscription_response.hpp"
|
||||
#include "e2sm_subscription.hpp"
|
||||
#include "subs_mgmt.hpp"
|
||||
#include "../agent_connector.hpp"
|
||||
|
||||
#define MAX_RMR_RECV_SIZE 2<<15
|
||||
|
||||
class XappMsgHandler{
|
||||
|
||||
private:
|
||||
std::string xapp_id;
|
||||
SubscriptionHandler *_ref_sub_handler;
|
||||
public:
|
||||
//constructor for xapp_id.
|
||||
XappMsgHandler(std::string xid){xapp_id=xid; _ref_sub_handler=NULL;};
|
||||
XappMsgHandler(std::string xid, SubscriptionHandler &subhandler){xapp_id=xid; _ref_sub_handler=&subhandler;};
|
||||
|
||||
void operator() (rmr_mbuf_t *, bool*);
|
||||
|
||||
void register_handler();
|
||||
bool encode_subscription_delete_request(unsigned char*, size_t* );
|
||||
|
||||
bool decode_subscription_response(unsigned char*, size_t );
|
||||
|
||||
bool a1_policy_handler(char *, int* , a1_policy_helper &);
|
||||
|
||||
void testfunction() {std::cout << "<<<<<<<<<<<<<<<<<<IN TEST FUNCTION<<<<<<<<<<<<<<<" << std::endl;}
|
||||
};
|
||||
|
||||
void process_ric_indication(int message_type, transaction_identifier id, const void *message_payload, size_t message_len);
|
||||
uint8_t procRicIndication(E2AP_PDU_t *e2apMsg, transaction_identifier gnb_id);
|
||||
|
||||
#endif /* XAPP_MSG_XAPP_MSG_HPP_ */
|
177
setup/xapp-bs-connector/src/xapp-mgmt/subs_mgmt.cc
Normal file
177
setup/xapp-bs-connector/src/xapp-mgmt/subs_mgmt.cc
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* subs_mgmt.cc
|
||||
* Created on: 2019
|
||||
* Author: Ashwin Shridharan, Shraboni Jana
|
||||
*/
|
||||
#include "subs_mgmt.hpp"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
SubscriptionHandler::SubscriptionHandler(unsigned int timeout_seconds):_time_out(std::chrono::seconds(timeout_seconds)){
|
||||
_data_lock = std::make_unique<std::mutex>();
|
||||
_cv = std::make_unique<std::condition_variable>();
|
||||
};
|
||||
|
||||
void SubscriptionHandler::clear(void){
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(*(_data_lock).get());
|
||||
status_table.clear();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool SubscriptionHandler::add_request_entry(transaction_identifier id, transaction_status status){
|
||||
|
||||
// add entry in hash table if it does not exist
|
||||
//auto search = status_table.find(id);
|
||||
//if(search != status_table.end()){
|
||||
if(transaction_present(status_table, id)){
|
||||
return false;
|
||||
}
|
||||
std::cout << "add_request_entry " << id << std::endl;
|
||||
status_table[id] = status;
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool SubscriptionHandler::delete_request_entry(transaction_identifier id){
|
||||
|
||||
auto search = status_table.find(id);
|
||||
|
||||
if (!trans_table.empty()) {
|
||||
auto search2 = trans_table.find(id);
|
||||
if(search2 !=trans_table.end()){
|
||||
trans_table.erase(search2);
|
||||
}
|
||||
}
|
||||
|
||||
if (search != status_table.end()){
|
||||
status_table.erase(search);
|
||||
mdclog_write(MDCLOG_INFO,"Entry for Transaction ID deleted: %s", id);
|
||||
|
||||
return true;
|
||||
}
|
||||
mdclog_write(MDCLOG_INFO,"Entry not found in SubscriptionHandler for Transaction ID: %d",id);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
bool SubscriptionHandler::set_request_status(transaction_identifier id, transaction_status status){
|
||||
|
||||
// change status of a request only if it exists.
|
||||
//auto search = status_table.find(id);
|
||||
if(transaction_present(status_table, id)){
|
||||
status_table[id] = status;
|
||||
std::cout << "set_request_status " << id << " to status " << status << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
|
||||
int const SubscriptionHandler::get_request_status(transaction_identifier id){
|
||||
//auto search = status_table.find(id);
|
||||
auto search = find_transaction(status_table, id);
|
||||
std::cout << "get_request_status " << id << std::endl;
|
||||
if (search == status_table.end()){
|
||||
return -1;
|
||||
}
|
||||
|
||||
return search->second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SubscriptionHandler::is_request_entry(transaction_identifier id){
|
||||
|
||||
std::cout << "is_request_entry, looking for key: " << id << std::endl;
|
||||
|
||||
if (transaction_present(status_table, id)) {
|
||||
std::cout << "Key found" << std::endl;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
std::cout << "Key NOT found" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handles subscription responses
|
||||
void SubscriptionHandler::manage_subscription_response(int message_type, transaction_identifier id, const void *message_payload, size_t message_len){
|
||||
|
||||
bool res;
|
||||
std::cout << "In Manage subscription" << std::endl;
|
||||
|
||||
// wake up all waiting users ...
|
||||
if(is_request_entry(id)){
|
||||
std::cout << "In Manage subscription, inside if loop" << std::endl;
|
||||
std::cout << "Setting to request_success: " << request_success << std::endl;
|
||||
|
||||
set_request_status(id, request_success);
|
||||
_cv.get()->notify_all();
|
||||
}
|
||||
|
||||
// decode received message payload
|
||||
E2AP_PDU_t *pdu = nullptr;
|
||||
auto retval = asn_decode(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void **) &pdu, message_payload, message_len);
|
||||
|
||||
// print decoded payload
|
||||
if (retval.code == RC_OK) {
|
||||
char *printBuffer;
|
||||
size_t size;
|
||||
FILE *stream = open_memstream(&printBuffer, &size);
|
||||
asn_fprint(stream, &asn_DEF_E2AP_PDU, pdu);
|
||||
mdclog_write(MDCLOG_DEBUG, "Decoded E2AP PDU: %s", printBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<transaction_identifier, transaction_status>::iterator find_transaction(std::unordered_map<transaction_identifier, transaction_status> map,
|
||||
transaction_identifier id) {
|
||||
auto iter = map.begin();
|
||||
while (iter != map.end()) {
|
||||
if (strcmp((const char*) iter->first, (const char*) id) == 0) {
|
||||
break;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
bool transaction_present(std::unordered_map<transaction_identifier, transaction_status> map, transaction_identifier id) {
|
||||
auto iter = map.begin();
|
||||
while (iter != map.end()) {
|
||||
if (strcmp((const char*) iter->first, (const char*) id) == 0) {
|
||||
return true;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
269
setup/xapp-bs-connector/src/xapp-mgmt/subs_mgmt.hpp
Normal file
269
setup/xapp-bs-connector/src/xapp-mgmt/subs_mgmt.hpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
==================================================================================
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* subs_mgmt.hpp
|
||||
* Created on: 2019
|
||||
* Author: Ashwin Shridharan, Shraboni Jana
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SUBSCRIPTION_HANDLER
|
||||
#define SUBSCRIPTION_HANDLER
|
||||
|
||||
#include <functional>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <unordered_map>
|
||||
#include <chrono>
|
||||
#include <tuple>
|
||||
|
||||
#include "../xapp-asn/e2ap/subscription_delete_request.hpp"
|
||||
#include "../xapp-asn/e2ap/subscription_delete_response.hpp"
|
||||
#include "../xapp-asn/e2ap/subscription_request.hpp"
|
||||
#include "../xapp-asn/e2ap/subscription_response.hpp"
|
||||
|
||||
#define SUBSCR_SUCCESS 1
|
||||
#define SUBSCR_ERR_TX -1
|
||||
#define SUBSCR_ERR_TIMEOUT -2
|
||||
#define SUBSCR_ERR_FAIL -3
|
||||
#define SUBSCR_ERR_UNKNOWN -4
|
||||
#define SUBSCR_ERR_DUPLICATE -5
|
||||
|
||||
using namespace std;
|
||||
|
||||
class TransmitterBase
|
||||
{
|
||||
public:
|
||||
virtual ~TransmitterBase() {}
|
||||
|
||||
template<class T>
|
||||
const T& getParam() const; //to be implemented after Parameter
|
||||
|
||||
template<class T, class U>
|
||||
void setParam(const U& rhs); //to be implemented after Parameter
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Transmitter : public TransmitterBase
|
||||
{
|
||||
public:
|
||||
Transmitter(const T& tx) :obj(tx) {}
|
||||
const T& getParam() const {return obj;}
|
||||
void setParam(const T& tx) {obj=tx;}
|
||||
private:
|
||||
T obj;
|
||||
};
|
||||
|
||||
//Here's the trick: dynamic_cast rather than virtual
|
||||
template<class T> const T& TransmitterBase::getParam() const
|
||||
{
|
||||
return dynamic_cast<const Transmitter<T>&>(*this).getParam();
|
||||
}
|
||||
template<class T, class U> void TransmitterBase::setParam(const U& rhs)
|
||||
{
|
||||
dynamic_cast<Transmitter<T>&>(*this).setParam(rhs);
|
||||
return;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
request_pending = 1,
|
||||
request_success,
|
||||
request_failed,
|
||||
delete_request_pending,
|
||||
delete_request_success,
|
||||
delete_request_failed,
|
||||
request_duplicate
|
||||
}Subscription_Status_Types;
|
||||
|
||||
using transaction_identifier = unsigned char*;
|
||||
using transaction_status = Subscription_Status_Types;
|
||||
|
||||
class SubscriptionHandler {
|
||||
|
||||
public:
|
||||
|
||||
SubscriptionHandler(unsigned int timeout_seconds = 10);
|
||||
|
||||
template <typename AppTransmitter>
|
||||
int manage_subscription_request(transaction_identifier, AppTransmitter &&);
|
||||
|
||||
template <typename AppTransmitter>
|
||||
int manage_subscription_delete_request(transaction_identifier, AppTransmitter &&);
|
||||
|
||||
void manage_subscription_response(int message_type, transaction_identifier id, const void *message_payload, size_t message_len);
|
||||
|
||||
int const get_request_status(transaction_identifier);
|
||||
bool set_request_status(transaction_identifier, transaction_status);
|
||||
bool is_request_entry(transaction_identifier);
|
||||
void set_timeout(unsigned int);
|
||||
void clear(void);
|
||||
void set_ignore_subs_resp(bool b){_ignore_subs_resp = b;};
|
||||
|
||||
private:
|
||||
|
||||
bool add_request_entry(transaction_identifier, transaction_status);
|
||||
bool delete_request_entry(transaction_identifier);
|
||||
|
||||
template <typename AppTransmitter>
|
||||
bool add_transmitter_entry(transaction_identifier, AppTransmitter&&);
|
||||
|
||||
std::unordered_map<transaction_identifier, TransmitterBase> trans_table;
|
||||
std::unordered_map<transaction_identifier, transaction_status> status_table;
|
||||
|
||||
std::unique_ptr<std::mutex> _data_lock;
|
||||
std::unique_ptr<std::condition_variable> _cv;
|
||||
|
||||
std::chrono::seconds _time_out;
|
||||
|
||||
bool _ignore_subs_resp = false;
|
||||
};
|
||||
|
||||
template <typename AppTransmitter>
|
||||
bool SubscriptionHandler::add_transmitter_entry(transaction_identifier id, AppTransmitter &&trans){
|
||||
|
||||
// add entry in hash table if it does not exist
|
||||
//auto search = trans_table.find(id);
|
||||
auto search = trans_table.begin();
|
||||
while (search != trans_table.end()) {
|
||||
if (strcmp((const char*) search->first, (const char*) id) == 0) {
|
||||
break;
|
||||
}
|
||||
++search;
|
||||
}
|
||||
|
||||
if(search != trans_table.end()){
|
||||
return false;
|
||||
}
|
||||
|
||||
Transmitter<AppTransmitter> tptr(trans);
|
||||
trans_table[id] = tptr;
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
//this will work for both sending subscription request and subscription delete request.
|
||||
//The handler is oblivious of the message content and follows the transaction id.
|
||||
template<typename AppTransmitter>
|
||||
int SubscriptionHandler::manage_subscription_request(transaction_identifier rmr_trans_id, AppTransmitter && tx){
|
||||
int res;
|
||||
// put entry in request table
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(*(_data_lock.get()));
|
||||
|
||||
res = add_request_entry(rmr_trans_id, request_pending);
|
||||
if(! res){
|
||||
mdclog_write(MDCLOG_ERR, "%s, %d : Error adding new subscription request %s to queue because request with identical key already present", __FILE__, __LINE__, rmr_trans_id);
|
||||
return SUBSCR_ERR_DUPLICATE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Added status pending to request " << rmr_trans_id << std::endl;
|
||||
}}
|
||||
|
||||
|
||||
// acquire lock ...
|
||||
std::unique_lock<std::mutex> _local_lock(*(_data_lock.get()));
|
||||
|
||||
// Send the message
|
||||
bool flg = tx();
|
||||
|
||||
if (!flg){
|
||||
// clear state
|
||||
delete_request_entry(rmr_trans_id);
|
||||
mdclog_write(MDCLOG_ERR, "%s, %d :: Error transmitting subscription request %s", __FILE__, __LINE__, rmr_trans_id );
|
||||
return SUBSCR_ERR_TX;
|
||||
} else {
|
||||
mdclog_write(MDCLOG_INFO, "%s, %d :: Transmitted subscription request for trans_id %s", __FILE__, __LINE__, rmr_trans_id );
|
||||
add_transmitter_entry(rmr_trans_id, tx);
|
||||
|
||||
}
|
||||
|
||||
// record time stamp ..
|
||||
auto start = std::chrono::system_clock::now();
|
||||
res = SUBSCR_ERR_UNKNOWN;
|
||||
|
||||
|
||||
while(1){
|
||||
// release lock and wait to be woken up
|
||||
_cv.get()->wait_for(_local_lock, _time_out);
|
||||
|
||||
// we have woken and acquired data_lock
|
||||
// check status and return appropriate object
|
||||
int status = get_request_status(rmr_trans_id);
|
||||
|
||||
if (status == request_success){
|
||||
mdclog_write(MDCLOG_INFO, "Successfully subscribed for request for trans_id %s", rmr_trans_id);
|
||||
res = SUBSCR_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == request_pending){
|
||||
// woken up spuriously or timed out
|
||||
auto end = std::chrono::system_clock::now();
|
||||
std::chrono::duration<double> f = end - start;
|
||||
|
||||
if ( f > _time_out){
|
||||
|
||||
mdclog_write(MDCLOG_ERR, "%s, %d:: Subscription request with transaction id %s timed out waiting for response ", __FILE__, __LINE__, rmr_trans_id);
|
||||
|
||||
//res = SUBSCR_ERR_TIMEOUT;
|
||||
//sunny side scenario. assuming subscription response is received.
|
||||
res = SUBSCR_SUCCESS;
|
||||
break;
|
||||
}
|
||||
else{
|
||||
mdclog_write(MDCLOG_INFO, "Subscription request with transaction id %s Waiting for response....", rmr_trans_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(status == request_failed){
|
||||
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Subscription Request with transaction id %s got failure response .. \n", __FILE__, __LINE__, rmr_trans_id);
|
||||
res = SUBSCR_ERR_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == request_duplicate){
|
||||
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Subscription Request with transaction id %s is duplicate : subscription already present in table .. \n", __FILE__, __LINE__, rmr_trans_id);
|
||||
res = SUBSCR_ERR_DUPLICATE;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// if we are here, some spurious
|
||||
// status obtained or request failed . we return appropriate error code
|
||||
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Spurious time out caused by invalid state of request %s, and state = %d. Deleting request entry and failing .. \n", __FILE__, __LINE__, rmr_trans_id, status);
|
||||
res = SUBSCR_ERR_UNKNOWN;
|
||||
break;
|
||||
};
|
||||
|
||||
delete_request_entry(rmr_trans_id);
|
||||
|
||||
// release data lock
|
||||
_local_lock.unlock();
|
||||
// std::cout <<"Returning res = " << res << " for request = " << rmr_trans_id << std::endl;
|
||||
return res;
|
||||
};
|
||||
|
||||
std::unordered_map<transaction_identifier, transaction_status>::iterator find_transaction(std::unordered_map<transaction_identifier, transaction_status> map,
|
||||
transaction_identifier id);
|
||||
bool transaction_present(std::unordered_map<transaction_identifier, transaction_status> map, transaction_identifier id);
|
||||
|
||||
#endif
|
21
setup/xapp-bs-connector/src/xapp-mgmt/xapp_handler.hpp
Normal file
21
setup/xapp-bs-connector/src/xapp-mgmt/xapp_handler.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* xapp_handler.hpp
|
||||
*
|
||||
* Created on: Mar 16, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
|
||||
#ifndef SRC_XAPP_MGMT_XAPP_HANDLER_HPP_
|
||||
#define SRC_XAPP_MGMT_XAPP_HANDLER_HPP_
|
||||
|
||||
class XappHandler{
|
||||
XappHandler *xhandler;
|
||||
public:
|
||||
virtual ~XappHandler(){delete xhandler;};
|
||||
virtual void register_handler(XappHandler *xhandler) = 0;
|
||||
virtual XappHandler* get_handler() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_XAPP_MGMT_XAPP_HANDLER_HPP_ */
|
144
setup/xapp-bs-connector/src/xapp-utils/xapp_config.cc
Normal file
144
setup/xapp-bs-connector/src/xapp-utils/xapp_config.cc
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* xapp_config.cc
|
||||
* Created on: 2019
|
||||
* Author: Ashwin Shridharan, Shraboni Jana
|
||||
*/
|
||||
|
||||
#include "xapp_config.hpp"
|
||||
|
||||
string& XappSettings::operator[](const SettingName& theName){
|
||||
return theSettings[theName];
|
||||
}
|
||||
|
||||
void XappSettings::loadCmdlineSettings(int argc, char **argv){
|
||||
|
||||
// Parse command line options to over ride
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"xappname", required_argument, 0, 'n'},
|
||||
{"xappid", required_argument, 0, 'x'},
|
||||
{"port", required_argument, 0, 'p'},
|
||||
{"threads", required_argument, 0, 't'},
|
||||
{"ves-interval", required_argument, 0, 'i'},
|
||||
{"gNodeB", required_argument, 0, 'g'}
|
||||
|
||||
};
|
||||
|
||||
|
||||
while(1) {
|
||||
|
||||
int option_index = 0;
|
||||
char c = getopt_long(argc, argv, "n:p:t:s:g:a:v:u:i:c:x:", long_options, &option_index);
|
||||
|
||||
if(c == -1){
|
||||
break;
|
||||
}
|
||||
|
||||
switch(c)
|
||||
{
|
||||
|
||||
case 'n':
|
||||
theSettings[XAPP_NAME].assign(optarg);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
theSettings[HW_PORT].assign(optarg);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
theSettings[THREADS].assign(optarg);
|
||||
mdclog_write(MDCLOG_INFO, "Number of threads set to %s from command line e\n", theSettings[THREADS].c_str());
|
||||
break;
|
||||
|
||||
|
||||
case 'x':
|
||||
theSettings[XAPP_ID].assign(optarg);
|
||||
mdclog_write(MDCLOG_INFO, "XAPP ID set to %s from command line ", theSettings[XAPP_ID].c_str());
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(0);
|
||||
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void XappSettings::loadDefaultSettings(){
|
||||
|
||||
|
||||
if(theSettings[XAPP_NAME].empty()){
|
||||
theSettings[XAPP_NAME] = DEFAULT_XAPP_NAME;
|
||||
}
|
||||
|
||||
if(theSettings[XAPP_ID].empty()){
|
||||
theSettings[XAPP_ID] = DEFAULT_XAPP_NAME; //for now xapp_id is same as xapp_name since single xapp instance.
|
||||
}
|
||||
if(theSettings[LOG_LEVEL].empty()){
|
||||
theSettings[LOG_LEVEL] = DEFAULT_LOG_LEVEL;
|
||||
}
|
||||
if(theSettings[HW_PORT].empty()){
|
||||
theSettings[HW_PORT] = DEFAULT_PORT;
|
||||
}
|
||||
if(theSettings[MSG_MAX_BUFFER].empty()){
|
||||
theSettings[MSG_MAX_BUFFER] = DEFAULT_MSG_MAX_BUFFER;
|
||||
}
|
||||
|
||||
if(theSettings[THREADS].empty()){
|
||||
theSettings[THREADS] = DEFAULT_THREADS;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void XappSettings::loadEnvVarSettings(){
|
||||
|
||||
if (const char *env_xname = std::getenv("XAPP_NAME")){
|
||||
theSettings[XAPP_NAME].assign(env_xname);
|
||||
mdclog_write(MDCLOG_INFO,"Xapp Name set to %s from environment variable", theSettings[XAPP_NAME].c_str());
|
||||
}
|
||||
if (const char *env_xid = std::getenv("XAPP_NAME")){
|
||||
theSettings[XAPP_ID].assign(env_xid);
|
||||
mdclog_write(MDCLOG_INFO,"Xapp ID set to %s from environment variable", theSettings[XAPP_ID].c_str());
|
||||
}
|
||||
|
||||
if (const char *env_ports = std::getenv("HW_PORT")){
|
||||
theSettings[HW_PORT].assign(env_ports);
|
||||
mdclog_write(MDCLOG_INFO,"Ports set to %s from environment variable", theSettings[HW_PORT].c_str());
|
||||
}
|
||||
if (const char *env_ports = std::getenv("MSG_MAX_BUFFER")){
|
||||
theSettings[MSG_MAX_BUFFER].assign(env_ports);
|
||||
mdclog_write(MDCLOG_INFO,"Ports set to %s from environment variable", theSettings[MSG_MAX_BUFFER].c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void XappSettings::usage(char *command){
|
||||
std::cout <<"Usage : " << command << " " << std::endl;
|
||||
std::cout <<" --name[-n] xapp_instance_name "<< std::endl;
|
||||
std::cout <<" --port[-p] port to listen on e.g tcp:4561 "<< std::endl;
|
||||
std::cout << "--threads[-t] number of listener threads "<< std::endl ;
|
||||
|
||||
}
|
72
setup/xapp-bs-connector/src/xapp-utils/xapp_config.hpp
Normal file
72
setup/xapp-bs-connector/src/xapp-utils/xapp_config.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* xapp_config.hpp
|
||||
* Created on: 2019
|
||||
* Author: Ashwin Shridharan, Shraboni Jana
|
||||
*/
|
||||
|
||||
#ifndef SRC_XAPP_CONFIG_XAPP_CONFIG_HPP_
|
||||
#define SRC_XAPP_CONFIG_XAPP_CONFIG_HPP_
|
||||
|
||||
#include <getopt.h>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <mdclog/mdclog.h>
|
||||
|
||||
#define DEFAULT_XAPP_NAME "hwxapp"
|
||||
#define DEFAULT_PORT "4560"
|
||||
#define DEFAULT_MSG_MAX_BUFFER "2072"
|
||||
#define DEFAULT_THREADS "1"
|
||||
|
||||
#define DEFAULT_LOG_LEVEL MDCLOG_WARN
|
||||
|
||||
#define ASN_BUFF_MAX_SIZE 4096
|
||||
#define MAX_SUBSCRIPTION_ATTEMPTS 10
|
||||
#define HELLOWORLD_POLICY_ID 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct XappSettings{
|
||||
|
||||
public:
|
||||
typedef enum{
|
||||
XAPP_ID,
|
||||
XAPP_NAME,
|
||||
HW_PORT,
|
||||
MSG_MAX_BUFFER,
|
||||
THREADS,
|
||||
LOG_LEVEL
|
||||
}SettingName;
|
||||
|
||||
void loadDefaultSettings();
|
||||
void loadCmdlineSettings(int, char **);
|
||||
void loadEnvVarSettings();
|
||||
void usage(char*);
|
||||
string& operator[](const SettingName& theName);
|
||||
private:
|
||||
typedef map<SettingName, std::string> SettingCollection;
|
||||
SettingCollection theSettings;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_XAPP_CONFIG_XAPP_CONFIG_HPP_ */
|
174
setup/xapp-bs-connector/src/xapp-utils/xapp_rmr.cc
Executable file
174
setup/xapp-bs-connector/src/xapp-utils/xapp_rmr.cc
Executable file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "xapp_rmr.hpp"
|
||||
|
||||
XappRmr::XappRmr(std::string port, int rmrattempts){
|
||||
|
||||
_proto_port = port;
|
||||
_nattempts = rmrattempts;
|
||||
_xapp_rmr_ctx = NULL;
|
||||
_xapp_received_buff = NULL;
|
||||
_xapp_send_buff =NULL;
|
||||
_rmr_is_ready = false;
|
||||
_listen = false;
|
||||
|
||||
};
|
||||
|
||||
XappRmr::~XappRmr(void){
|
||||
// free memory
|
||||
if(_xapp_received_buff)
|
||||
rmr_free_msg(_xapp_received_buff);
|
||||
|
||||
if(_xapp_send_buff)
|
||||
rmr_free_msg(_xapp_send_buff);
|
||||
|
||||
if (_xapp_rmr_ctx){
|
||||
rmr_close(_xapp_rmr_ctx);
|
||||
}
|
||||
};
|
||||
|
||||
//Get RMR Context.
|
||||
void XappRmr::xapp_rmr_init(bool rmr_listen){
|
||||
|
||||
|
||||
// Initialize the RMR context
|
||||
_xapp_rmr_ctx = rmr_init(const_cast<char*>(_proto_port.c_str()), RMR_MAX_RCV_BYTES, RMRFL_NONE);
|
||||
|
||||
if ( _xapp_rmr_ctx == NULL){
|
||||
mdclog_write(MDCLOG_ERR,"Error Initializing RMR, file= %s, line=%d",__FILE__,__LINE__);
|
||||
}
|
||||
while( ! rmr_ready(_xapp_rmr_ctx) ) {
|
||||
mdclog_write(MDCLOG_INFO,">>> waiting for RMR, file= %s, line=%d",__FILE__,__LINE__);
|
||||
sleep(1);
|
||||
}
|
||||
_rmr_is_ready = true;
|
||||
mdclog_write(MDCLOG_INFO,"RMR Context is Ready, file= %s, line=%d",__FILE__,__LINE__);
|
||||
|
||||
//Set the listener requirement
|
||||
_listen = rmr_listen;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
bool XappRmr::rmr_header(xapp_rmr_header *hdr){
|
||||
|
||||
_xapp_send_buff->mtype = hdr->message_type;
|
||||
_xapp_send_buff->len = hdr->payload_length;
|
||||
_xapp_send_buff->sub_id = -1;
|
||||
rmr_str2meid(_xapp_send_buff, hdr->meid);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//RMR Send with payload and header.
|
||||
bool XappRmr::xapp_rmr_send(xapp_rmr_header *hdr, void *payload){
|
||||
|
||||
// Get the thread id
|
||||
std::thread::id my_id = std::this_thread::get_id();
|
||||
std::stringstream thread_id;
|
||||
std::stringstream ss;
|
||||
|
||||
thread_id << my_id;
|
||||
mdclog_write(MDCLOG_INFO, "Sending thread %s", thread_id.str().c_str());
|
||||
|
||||
|
||||
int rmr_attempts = _nattempts;
|
||||
|
||||
if( _xapp_send_buff == NULL ) {
|
||||
_xapp_send_buff = rmr_alloc_msg(_xapp_rmr_ctx, RMR_DEF_SIZE);
|
||||
}
|
||||
|
||||
bool res = rmr_header(hdr);
|
||||
if(!res){
|
||||
mdclog_write(MDCLOG_ERR,"RMR HEADERS were incorrectly populated, file= %s, line=%d",__FILE__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(_xapp_send_buff->payload, payload, hdr->payload_length);
|
||||
_xapp_send_buff->len = hdr->payload_length;
|
||||
|
||||
if(!_rmr_is_ready) {
|
||||
mdclog_write(MDCLOG_ERR,"RMR Context is Not Ready in SENDER, file= %s, line=%d",__FILE__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
while(rmr_attempts > 0){
|
||||
|
||||
_xapp_send_buff = rmr_send_msg(_xapp_rmr_ctx,_xapp_send_buff);
|
||||
if(!_xapp_send_buff) {
|
||||
mdclog_write(MDCLOG_ERR,"Error In Sending Message , file= %s, line=%d, attempt=%d",__FILE__,__LINE__,rmr_attempts);
|
||||
rmr_attempts--;
|
||||
}
|
||||
else if (_xapp_send_buff->state == RMR_OK){
|
||||
mdclog_write(MDCLOG_INFO,"Message Sent: RMR State = RMR_OK");
|
||||
rmr_attempts = 0;
|
||||
_xapp_send_buff = NULL;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mdclog_write(MDCLOG_INFO,"Need to retry RMR: state=%d, attempt=%d, file=%s, line=%d",_xapp_send_buff->state, rmr_attempts,__FILE__,__LINE__);
|
||||
if(_xapp_send_buff->state == RMR_ERR_RETRY){
|
||||
usleep(1); }
|
||||
rmr_attempts--;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Some get/set methods
|
||||
//---------------------------------------
|
||||
bool XappRmr::get_listen(void){
|
||||
return _listen;
|
||||
}
|
||||
|
||||
|
||||
void XappRmr::set_listen(bool listen){
|
||||
_listen = listen;
|
||||
}
|
||||
|
||||
int XappRmr::get_is_ready(void){
|
||||
return _rmr_is_ready;
|
||||
}
|
||||
|
||||
bool XappRmr::get_isRunning(void){
|
||||
return _listen;
|
||||
}
|
||||
|
||||
|
||||
void * XappRmr::get_rmr_context(void){
|
||||
return _xapp_rmr_ctx;
|
||||
}
|
||||
|
||||
|
||||
void init_logger(const char *AppName, mdclog_severity_t log_level)
|
||||
{
|
||||
mdclog_attr_t *attr;
|
||||
mdclog_attr_init(&attr);
|
||||
mdclog_attr_set_ident(attr, AppName);
|
||||
mdclog_init(attr);
|
||||
mdclog_level_set(log_level);
|
||||
mdclog_attr_destroy(attr);
|
||||
}
|
||||
|
175
setup/xapp-bs-connector/src/xapp-utils/xapp_rmr.hpp
Executable file
175
setup/xapp-bs-connector/src/xapp-utils/xapp_rmr.hpp
Executable file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
#ifndef XAPP_RMR_XAPP_RMR_H_
|
||||
#define XAPP_RMR_XAPP_RMR_H_
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define likely(x) __builtin_expect((x), 1)
|
||||
#define unlikely(x) __builtin_expect((x), 0)
|
||||
#else
|
||||
#define likely(x) (x)
|
||||
#define unlikely(x) (x)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <error.h>
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <sys/epoll.h>
|
||||
#include <rmr/rmr.h>
|
||||
#include <rmr/RIC_message_types.h>
|
||||
#include <mdclog/mdclog.h>
|
||||
#include <vector>
|
||||
|
||||
typedef struct{
|
||||
struct timespec ts;
|
||||
int32_t message_type;
|
||||
int32_t state;
|
||||
int32_t payload_length;
|
||||
unsigned char sid[RMR_MAX_SID]; //Subscription ID.
|
||||
unsigned char src[RMR_MAX_SRC]; //Xapp Name
|
||||
unsigned char meid[RMR_MAX_MEID]={};
|
||||
|
||||
} xapp_rmr_header;
|
||||
|
||||
|
||||
class XappRmr{
|
||||
private:
|
||||
std::string _proto_port;
|
||||
int _nattempts;
|
||||
bool _rmr_is_ready;
|
||||
bool _listen;
|
||||
void* _xapp_rmr_ctx;
|
||||
rmr_mbuf_t* _xapp_send_buff; // send buffer
|
||||
rmr_mbuf_t* _xapp_received_buff; // received buffer
|
||||
|
||||
|
||||
public:
|
||||
|
||||
XappRmr(std::string, int rmrattempts=10);
|
||||
~XappRmr(void);
|
||||
void xapp_rmr_init(bool);
|
||||
|
||||
template <class MessageProcessor>
|
||||
void xapp_rmr_receive(MessageProcessor&&, XappRmr *parent);
|
||||
|
||||
bool xapp_rmr_send(xapp_rmr_header*, void*);
|
||||
|
||||
bool rmr_header(xapp_rmr_header*);
|
||||
void set_listen(bool);
|
||||
bool get_listen(void);
|
||||
int get_is_ready(void);
|
||||
bool get_isRunning(void);
|
||||
void* get_rmr_context(void);
|
||||
|
||||
};
|
||||
|
||||
|
||||
// main workhorse thread which does the listen->process->respond loop
|
||||
template <class MsgHandler>
|
||||
void XappRmr::xapp_rmr_receive(MsgHandler&& msgproc, XappRmr *parent){
|
||||
|
||||
bool* resend = new bool(false);
|
||||
// Get the thread id
|
||||
std::thread::id my_id = std::this_thread::get_id();
|
||||
std::stringstream thread_id;
|
||||
std::stringstream ss;
|
||||
|
||||
thread_id << my_id;
|
||||
|
||||
// Get the rmr context from parent (all threads and parent use same rmr context. rmr context is expected to be thread safe)
|
||||
if(!parent->get_is_ready()){
|
||||
mdclog_write( MDCLOG_ERR, "RMR Shows Not Ready in RECEIVER, file= %s, line=%d ",__FILE__,__LINE__);
|
||||
return;
|
||||
}
|
||||
void *rmr_context = parent->get_rmr_context();
|
||||
assert(rmr_context != NULL);
|
||||
|
||||
// Get buffer specific to this thread
|
||||
this->_xapp_received_buff = NULL;
|
||||
this->_xapp_received_buff = rmr_alloc_msg(rmr_context, RMR_DEF_SIZE);
|
||||
assert(this->_xapp_received_buff != NULL);
|
||||
|
||||
mdclog_write(MDCLOG_INFO, "Starting receiver thread %s", thread_id.str().c_str());
|
||||
|
||||
while(parent->get_listen()) {
|
||||
mdclog_write(MDCLOG_INFO, "Listening at Thread: %s", thread_id.str().c_str());
|
||||
|
||||
this->_xapp_received_buff = rmr_rcv_msg( rmr_context, this->_xapp_received_buff );
|
||||
//this->_xapp_received_buff = rmr_rcv_msg( rmr_context, this->_xapp_received_buff );
|
||||
//this->_xapp_received_buff = rmr_call( rmr_context, this->_xapp_received_buff);
|
||||
|
||||
if( this->_xapp_received_buff->mtype < 0 || this->_xapp_received_buff->state != RMR_OK ) {
|
||||
mdclog_write(MDCLOG_ERR, "bad msg: state=%d errno=%d, file= %s, line=%d", this->_xapp_received_buff->state, errno, __FILE__,__LINE__ );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
mdclog_write(MDCLOG_INFO,"RMR Received Message of Type: %d, Message length: %d", this->_xapp_received_buff->mtype, this->_xapp_received_buff->len);
|
||||
|
||||
char printBuffer[4096] = {0};
|
||||
char *tmp = printBuffer;
|
||||
for (size_t i = 0; i < (size_t)_xapp_received_buff->len; ++i) {
|
||||
snprintf(tmp, 3, "%02x", _xapp_received_buff->payload[i]);
|
||||
tmp += 2;
|
||||
}
|
||||
mdclog_write(MDCLOG_INFO,"RMR Received Message: %s", printBuffer);
|
||||
|
||||
//in case message handler returns true, need to resend the message.
|
||||
msgproc(this->_xapp_received_buff, resend);
|
||||
|
||||
if(*resend){
|
||||
mdclog_write(MDCLOG_INFO,"RMR Return to Sender Message of Type: %d, Message length: %d", this->_xapp_received_buff->mtype, this->_xapp_received_buff->len);
|
||||
mdclog_write(MDCLOG_INFO,"RMR Return to Sender Message: %s", printBuffer);
|
||||
rmr_rts_msg(rmr_context, this->_xapp_received_buff );
|
||||
sleep(1);
|
||||
*resend = false;
|
||||
}
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// Clean up
|
||||
try{
|
||||
delete resend;
|
||||
rmr_free_msg(this->_xapp_received_buff);
|
||||
}
|
||||
catch(std::runtime_error &e){
|
||||
std::string identifier = __FILE__ + std::string(", Line: ") + std::to_string(__LINE__) ;
|
||||
std::string error_string = identifier = " Error freeing RMR message ";
|
||||
mdclog_write(MDCLOG_ERR, error_string.c_str(), "");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* XAPP_RMR_XAPP_RMR_H_ */
|
71
setup/xapp-bs-connector/src/xapp-utils/xapp_sdl.cc
Normal file
71
setup/xapp-bs-connector/src/xapp-utils/xapp_sdl.cc
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* xapp_sdl.cc
|
||||
*
|
||||
* Created on: Mar, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
#include "xapp_sdl.hpp"
|
||||
/*need to work on the SDL FLow. Currently data hardcoded.
|
||||
An xApp can use the SDL for two things:
|
||||
- persisting state for itself (in case it fails and recovers)
|
||||
- making information available for other xApps. The xApp would typically write using SDL directly.
|
||||
- The consumer of the data could also use SDL directly or use an access library like in the case of the R-NIB.
|
||||
*/
|
||||
bool XappSDL::set_data(shareddatalayer::SyncStorage *sdl){
|
||||
try{
|
||||
//connecting to the Redis and generating a random key for namespace "hwxapp"
|
||||
mdclog_write(MDCLOG_INFO, "IN SDL Set Data", __FILE__, __LINE__);
|
||||
DataMap dmap;
|
||||
char key[4]="abc";
|
||||
std::cout << "KEY: "<< key << std::endl;
|
||||
Key k = key;
|
||||
Data d;
|
||||
uint8_t num = 101;
|
||||
d.push_back(num);
|
||||
dmap.insert({k,d});
|
||||
Namespace ns(sdl_namespace);
|
||||
sdl->set(ns, dmap);
|
||||
}
|
||||
catch(...){
|
||||
mdclog_write(MDCLOG_ERR, "SDL Error in Set Data for Namespace=%s",sdl_namespace);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void XappSDL::get_data(shareddatalayer::SyncStorage *sdl){
|
||||
Namespace ns(sdl_namespace);
|
||||
DataMap dmap;
|
||||
std::string prefix="";
|
||||
Keys K = sdl->findKeys(ns, prefix); // just the prefix
|
||||
DataMap Dk = sdl->get(ns, K);
|
||||
for(auto si=K.begin();si!=K.end();++si){
|
||||
std::vector<uint8_t> val_v = Dk[(*si)]; // 4 lines to unpack a string
|
||||
char val[val_v.size()+1]; // from Data
|
||||
int i;
|
||||
for(i=0;i<val_v.size();++i) val[i] = (char)(val_v[i]);
|
||||
val[i]='\0';
|
||||
printf("KEYS and Values %s = %s\n",(*si).c_str(), val);
|
||||
}
|
||||
|
||||
mdclog_write(MDCLOG_INFO, "IN SDL Get Data", __FILE__, __LINE__);
|
||||
}
|
57
setup/xapp-bs-connector/src/xapp-utils/xapp_sdl.hpp
Normal file
57
setup/xapp-bs-connector/src/xapp-utils/xapp_sdl.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* xapp_sdl.hpp
|
||||
*
|
||||
* Created on: Mar, 2020
|
||||
* Author: Shraboni Jana
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef SRC_XAPP_UTILS_XAPP_SDL_HPP_
|
||||
#define SRC_XAPP_UTILS_XAPP_SDL_HPP_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sdl/syncstorage.hpp>
|
||||
#include <mdclog/mdclog.h>
|
||||
|
||||
using namespace std;
|
||||
using Namespace = std::string;
|
||||
using Key = std::string;
|
||||
using Data = std::vector<uint8_t>;
|
||||
using DataMap = std::map<Key, Data>;
|
||||
using Keys = std::set<Key>;
|
||||
|
||||
class XappSDL{
|
||||
private:
|
||||
std::string sdl_namespace;
|
||||
|
||||
public:
|
||||
XappSDL(std::string ns) { sdl_namespace=ns; }
|
||||
void get_data(shareddatalayer::SyncStorage *);
|
||||
bool set_data(shareddatalayer::SyncStorage *);
|
||||
};
|
||||
|
||||
#endif /* SRC_XAPP_UTILS_XAPP_SDL_HPP_ */
|
539
setup/xapp-bs-connector/src/xapp.cc
Normal file
539
setup/xapp-bs-connector/src/xapp.cc
Normal file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*/
|
||||
/*
|
||||
* xapp.cc
|
||||
*
|
||||
* Mar, 2020 (Shraboni Jana)
|
||||
*/
|
||||
|
||||
#include "xapp.hpp"
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
std::map<string, int> agentIp_socket;
|
||||
std::map<std::string, std::string> agentIp_gnbId;
|
||||
std::vector<std::string> drl_agent_ip{AGENT_0};
|
||||
|
||||
Xapp::Xapp(XappSettings &config, XappRmr &rmr){
|
||||
|
||||
rmr_ref = &rmr;
|
||||
config_ref = &config;
|
||||
xapp_mutex = NULL;
|
||||
subhandler_ref = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
Xapp::~Xapp(void){
|
||||
|
||||
//Joining the threads
|
||||
int threadcnt = xapp_rcv_thread.size();
|
||||
for(int i=0; i<threadcnt; i++){
|
||||
if(xapp_rcv_thread[i].joinable())
|
||||
xapp_rcv_thread[i].join();
|
||||
}
|
||||
xapp_rcv_thread.clear();
|
||||
|
||||
if(xapp_mutex!=NULL){
|
||||
xapp_mutex->~mutex();
|
||||
delete xapp_mutex;
|
||||
}
|
||||
|
||||
// close sockets
|
||||
close_control_socket_agent();
|
||||
|
||||
// join threads
|
||||
for (int i = 0; i < control_thr_rx.size(); ++i) {
|
||||
if(control_thr_rx[i] && control_thr_rx[i]->joinable()) {
|
||||
control_thr_rx[i]->join();
|
||||
}
|
||||
}
|
||||
|
||||
if(ext_control_thr_rx && ext_control_thr_rx->joinable()) {
|
||||
ext_control_thr_rx->join();
|
||||
}
|
||||
};
|
||||
|
||||
//Stop the xapp. Note- To be run only from unit test scripts.
|
||||
void Xapp::stop(void){
|
||||
// Get the mutex lock
|
||||
std::lock_guard<std::mutex> guard(*xapp_mutex);
|
||||
rmr_ref->set_listen(false);
|
||||
rmr_ref->~XappRmr();
|
||||
|
||||
//Detaching the threads....not sure if this is the right way to stop the receiver threads.
|
||||
//Hence function should be called only in Unit Tests
|
||||
int threadcnt = xapp_rcv_thread.size();
|
||||
for(int i=0; i<threadcnt; i++){
|
||||
xapp_rcv_thread[i].detach();
|
||||
}
|
||||
sleep(10);
|
||||
}
|
||||
|
||||
void Xapp::startup(SubscriptionHandler &sub_ref) {
|
||||
|
||||
subhandler_ref = &sub_ref;
|
||||
|
||||
if (GNB_ID == "") {
|
||||
// get list of gnbs from ric
|
||||
std::cout << "Getting gNB list from RIC" << std::endl;
|
||||
set_rnib_gnblist();
|
||||
}
|
||||
else {
|
||||
// only insert target gnb
|
||||
std::cout << "Querying target gNB" << std::endl;
|
||||
rnib_gnblist.push_back(GNB_ID);
|
||||
}
|
||||
|
||||
// open external control socket in thread and wait for message
|
||||
ext_control_thr_rx = std::unique_ptr<std::thread>(new std::thread{&Xapp::handle_external_control_message, this, SOCKET_PORT_EXT});
|
||||
|
||||
for (int i = 0; i < drl_agent_ip.size(); ++i) {
|
||||
// open control socket with agent
|
||||
if (open_control_socket_agent(const_cast<char*>(drl_agent_ip[i].c_str()), 4200) == 0) {
|
||||
// start receive thread
|
||||
std::unique_ptr<std::thread> tmp_thr = std::unique_ptr<std::thread>(new std::thread{&Xapp::handle_rx_msg_agent, this, drl_agent_ip[i]});
|
||||
control_thr_rx.push_back(std::move(tmp_thr));
|
||||
}
|
||||
}
|
||||
|
||||
// send test message
|
||||
// send_socket("Hello, Server!", AGENT_1);
|
||||
|
||||
//send subscriptions.
|
||||
startup_subscribe_requests();
|
||||
|
||||
//read A1 policies
|
||||
// startup_get_policies();
|
||||
|
||||
// send control
|
||||
// send_ric_control_request();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Xapp::Run(){
|
||||
rmr_ref->set_listen(true);
|
||||
if(xapp_mutex == NULL){
|
||||
xapp_mutex = new std::mutex();
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(*xapp_mutex);
|
||||
|
||||
for(size_t j=0; j < _callbacks.size(); j++){
|
||||
std::thread th_recv([&](){ rmr_ref->xapp_rmr_receive(std::move(_callbacks[j]), rmr_ref);});
|
||||
xapp_rcv_thread.push_back(std::move(th_recv));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Starting a seperate single receiver
|
||||
void Xapp::start_xapp_receiver(XappMsgHandler& mp_handler){
|
||||
//start a receiver thread. Can be multiple receiver threads for more than 1 listening port.
|
||||
rmr_ref->set_listen(true);
|
||||
if(xapp_mutex == NULL){
|
||||
xapp_mutex = new std::mutex();
|
||||
}
|
||||
|
||||
mdclog_write(MDCLOG_INFO,"Receiver Thread file= %s, line=%d",__FILE__,__LINE__);
|
||||
std::lock_guard<std::mutex> guard(*xapp_mutex);
|
||||
std::thread th_recv([&](){ rmr_ref->xapp_rmr_receive(std::move(mp_handler), rmr_ref);});
|
||||
xapp_rcv_thread.push_back(std::move(th_recv));
|
||||
return;
|
||||
}
|
||||
|
||||
void Xapp::shutdown(){
|
||||
return;
|
||||
}
|
||||
|
||||
// handle received message from DRL agent
|
||||
void Xapp::handle_rx_msg(void) {
|
||||
std::cout << "handle_rx_msg" << std::endl;
|
||||
|
||||
const size_t max_size = 256;
|
||||
char buf[max_size] = {0};
|
||||
|
||||
// listen to control from agent
|
||||
while (true) {
|
||||
// iterate through map
|
||||
std::map<std::string, int>::iterator it;
|
||||
for (it = agentIp_socket.begin(); it != agentIp_socket.end(); ++it) {
|
||||
std::string agent_ip = it->first;
|
||||
int control_sckfd = it->second;
|
||||
|
||||
int rcv_size = recv(control_sckfd, buf, max_size, 0);
|
||||
if (rcv_size > 0) {
|
||||
std::cout << "Message from agent " << agent_ip << std::endl;
|
||||
std::cout << buf << std::endl;
|
||||
|
||||
// get gnb_id from agent IP
|
||||
std::map<std::string, std::string>::iterator it_gnb;
|
||||
it_gnb = agentIp_gnbId.find(agent_ip);
|
||||
|
||||
// send RIC control request
|
||||
if (it_gnb != agentIp_gnbId.end()) {
|
||||
send_ric_control_request(buf, it_gnb->second);
|
||||
}
|
||||
else {
|
||||
std::cout << "ERROR: No gNB ID found for agent " << agent_ip << std::endl;
|
||||
}
|
||||
|
||||
memset(buf, 0, max_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle received message from a specific DRL agent
|
||||
void Xapp::handle_rx_msg_agent(std::string agent_ip) {
|
||||
std::cout << "Opening RX thread with agent " << agent_ip << std::endl;
|
||||
|
||||
const size_t max_size = 256;
|
||||
char buf[max_size] = {0};
|
||||
|
||||
// listen to control from agent
|
||||
while (true) {
|
||||
// get control_sckfd from agent IP
|
||||
std::map<std::string, int>::iterator it;
|
||||
it = agentIp_socket.find(agent_ip);
|
||||
|
||||
if (it != agentIp_socket.end()) {
|
||||
int control_sckfd = it->second;
|
||||
|
||||
int rcv_size = recv(control_sckfd, buf, max_size, 0);
|
||||
if (rcv_size > 0) {
|
||||
std::cout << "Message from agent " << agent_ip << std::endl;
|
||||
std::cout << buf << std::endl;
|
||||
|
||||
// get gnb_id from agent IP
|
||||
std::map<std::string, std::string>::iterator it_gnb;
|
||||
it_gnb = agentIp_gnbId.find(agent_ip);
|
||||
|
||||
// send RIC control request
|
||||
if (it_gnb != agentIp_gnbId.end()) {
|
||||
send_ric_control_request(buf, it_gnb->second);
|
||||
}
|
||||
else {
|
||||
std::cout << "ERROR: No gNB ID found for agent " << agent_ip << std::endl;
|
||||
}
|
||||
|
||||
memset(buf, 0, max_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle external control socket message
|
||||
void Xapp::handle_external_control_message(int port) {
|
||||
|
||||
// Create a socket (IPv4, TCP)
|
||||
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd == -1) {
|
||||
std::cout << "Failed to create socket. errno: " << errno << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Listen on given port on any address
|
||||
sockaddr_in sockaddr;
|
||||
sockaddr.sin_family = AF_INET;
|
||||
sockaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
sockaddr.sin_port = htons(port);
|
||||
|
||||
if (bind(sockfd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
|
||||
std::cout << "Failed to bind to port. Errno: " << errno << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Start listening. Hold at most 10 connections in the queue
|
||||
if (listen(sockfd, 10) < 0) {
|
||||
std::cout << "Failed to listen on socket. Errno: " << errno << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Opened control socket server on port " << port << std::endl;
|
||||
|
||||
while (true) {
|
||||
auto addrlen = sizeof(sockaddr);
|
||||
int connection = accept(sockfd, (struct sockaddr*)&sockaddr, (socklen_t*)&addrlen);
|
||||
|
||||
if (connection < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read from the connection
|
||||
const size_t max_size = 256;
|
||||
char buffer[max_size] = {0};
|
||||
auto bytes_read = read(connection, buffer, 100);
|
||||
|
||||
if (bytes_read > 0) {
|
||||
std::cout << "External control socket. Message received: " << buffer << std::endl;
|
||||
|
||||
// TODO: check if message is termination, send to DU and shutdown xApp
|
||||
if (strcmp(buffer, XAPP_TERMINATE) == 0) {
|
||||
terminate_du_reporting();
|
||||
}
|
||||
}
|
||||
|
||||
memset(buffer, 0, max_size);
|
||||
close(connection);
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// terminate all DU reportings and shutdown xApp
|
||||
void Xapp::terminate_du_reporting(void) {
|
||||
|
||||
std::map<std::string, int>::iterator it;
|
||||
for (it = agentIp_socket.begin(); it != agentIp_socket.end(); ++it) {
|
||||
std::string agent_ip = it->first;
|
||||
int control_sckfd = it->second;
|
||||
|
||||
// get gnb_id from agent IP
|
||||
std::map<std::string, std::string>::iterator it_gnb;
|
||||
it_gnb = agentIp_gnbId.find(agent_ip);
|
||||
|
||||
std::cout << "Terminating reporting gNB " << it_gnb->second << std::endl;
|
||||
send_ric_control_request(XAPP_TERMINATE, it_gnb->second);
|
||||
}
|
||||
|
||||
// stop xapp docker container with SIGTERM (15)
|
||||
if (DEBUG) {
|
||||
std::cout << "Debug mode, only echoing" << std::endl;
|
||||
system("echo kill -s 15 1");
|
||||
}
|
||||
else {
|
||||
system("kill -s 15 1");
|
||||
}
|
||||
}
|
||||
|
||||
void Xapp::send_ric_control_request(char* payload, std::string gnb_id) {
|
||||
|
||||
std::cout << "Sending RIC Control Request" << std::endl;
|
||||
|
||||
bool res;
|
||||
size_t data_size = ASN_BUFF_MAX_SIZE;
|
||||
unsigned char data[data_size];
|
||||
unsigned char meid[RMR_MAX_MEID];
|
||||
std::string xapp_id = config_ref->operator [](XappSettings::SettingName::XAPP_ID);
|
||||
|
||||
mdclog_write(MDCLOG_INFO, "Preparing to send control in file= %s, line=%d", __FILE__, __LINE__);
|
||||
|
||||
auto gnblist = get_rnib_gnblist();
|
||||
int sz = gnblist.size();
|
||||
|
||||
if(sz <= 0) {
|
||||
mdclog_write(MDCLOG_INFO, "Subscriptions cannot be sent as GNBList in RNIB is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
// give the message to subscription handler, along with the transmitter.
|
||||
strcpy((char*)meid, gnb_id.c_str());
|
||||
std::cout << "RIC Control Request, gNB " << gnb_id << std::endl;
|
||||
|
||||
// helpers
|
||||
// set fields randomly
|
||||
ric_control_helper din {};
|
||||
//= {
|
||||
// 1,
|
||||
// 1,
|
||||
// 0,
|
||||
// 1,
|
||||
// -1,
|
||||
// 0,
|
||||
// 0,
|
||||
// 1,
|
||||
// "test", // control_msg
|
||||
// 5, // control_msg_size
|
||||
// "testh", // control header
|
||||
// 6,
|
||||
// "testp", // call process id
|
||||
// 6
|
||||
//};
|
||||
const char* msg = payload;
|
||||
din.control_msg_size = strlen(msg) + 1;
|
||||
mdclog_write(MDCLOG_INFO, "Size of msg %d", din.control_msg_size);
|
||||
din.control_msg = (uint8_t*) calloc(din.control_msg_size, sizeof(uint8_t));
|
||||
std::memcpy(din.control_msg, msg, din.control_msg_size);
|
||||
ric_control_helper dout {};
|
||||
|
||||
// control request object
|
||||
ric_control_request ctrl_req {};
|
||||
ric_control_request ctrl_recv {};
|
||||
|
||||
unsigned char buf[BUFFER_SIZE];
|
||||
size_t buf_size = BUFFER_SIZE;
|
||||
|
||||
res = ctrl_req.encode_e2ap_control_request(&buf[0], &buf_size, din);
|
||||
|
||||
xapp_rmr_header rmr_header;
|
||||
rmr_header.message_type = RIC_CONTROL_REQ;
|
||||
rmr_header.payload_length = buf_size; //data_size
|
||||
strcpy((char*)rmr_header.meid, gnb_id.c_str());
|
||||
|
||||
mdclog_write(MDCLOG_INFO, "Sending CTRL REQ in file= %s, line=%d for MEID %s", __FILE__, __LINE__, meid);
|
||||
|
||||
int result = rmr_ref->xapp_rmr_send(&rmr_header, (void*)buf);
|
||||
if(result) {
|
||||
mdclog_write(MDCLOG_INFO, "CTRL REQ SUCCESSFUL in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
|
||||
}
|
||||
}
|
||||
|
||||
void Xapp::startup_subscribe_requests(void ){
|
||||
|
||||
bool res;
|
||||
size_t data_size = ASN_BUFF_MAX_SIZE;
|
||||
unsigned char data[data_size];
|
||||
unsigned char meid[RMR_MAX_MEID];
|
||||
std::string xapp_id = config_ref->operator [](XappSettings::SettingName::XAPP_ID);
|
||||
|
||||
mdclog_write(MDCLOG_INFO,"Preparing to send subscription in file= %s, line=%d", __FILE__, __LINE__);
|
||||
|
||||
auto gnblist = get_rnib_gnblist();
|
||||
|
||||
int sz = gnblist.size();
|
||||
|
||||
if(sz <= 0)
|
||||
mdclog_write(MDCLOG_INFO,"Subscriptions cannot be sent as GNBList in RNIB is NULL");
|
||||
|
||||
for(int i = 0; i<sz; i++){
|
||||
std::cout << "Sending subscriptions to: " << gnblist[i] << std::endl;
|
||||
|
||||
// give the message to subscription handler, along with the transmitter.
|
||||
strcpy((char*)meid,gnblist[i].c_str());
|
||||
|
||||
// char *strMsg = "Subscription Request from HelloWorld XApp\0";
|
||||
// strncpy((char *)data,strMsg,strlen(strMsg));
|
||||
// data_size = strlen(strMsg);
|
||||
|
||||
subscription_helper din;
|
||||
subscription_helper dout;
|
||||
|
||||
subscription_request sub_req;
|
||||
subscription_request sub_recv;
|
||||
|
||||
unsigned char buf[BUFFER_SIZE];
|
||||
size_t buf_size = BUFFER_SIZE;
|
||||
bool res;
|
||||
|
||||
//Random Data for request
|
||||
int request_id = XAPP_REQ_ID;
|
||||
int function_id = 0;
|
||||
|
||||
// DU report timer in ms
|
||||
std::string event_def = "1000";
|
||||
|
||||
din.set_request(request_id);
|
||||
din.set_function_id(function_id);
|
||||
din.set_event_def(event_def.c_str(), event_def.length());
|
||||
|
||||
std::string act_def = "HelloWorld Action Definition";
|
||||
|
||||
din.add_action(1,1,(void*)act_def.c_str(), act_def.length(), 0);
|
||||
|
||||
res = sub_req.encode_e2ap_subscription(&buf[0], &buf_size, din);
|
||||
|
||||
xapp_rmr_header rmr_header;
|
||||
rmr_header.message_type = RIC_SUB_REQ;
|
||||
rmr_header.payload_length = buf_size; //data_size
|
||||
strcpy((char*)rmr_header.meid,gnblist[i].c_str());
|
||||
|
||||
mdclog_write(MDCLOG_INFO,"Sending subscription in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
|
||||
auto transmitter = std::bind(&XappRmr::xapp_rmr_send,rmr_ref, &rmr_header, (void*)buf );//(void*)data);
|
||||
|
||||
int result = subhandler_ref->manage_subscription_request(meid, transmitter);
|
||||
if(result){
|
||||
mdclog_write(MDCLOG_INFO,"Subscription SUCCESSFUL in file= %s, line=%d for MEID %s",__FILE__,__LINE__, meid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Xapp::startup_get_policies(void){
|
||||
|
||||
int policy_id = HELLOWORLD_POLICY_ID;
|
||||
|
||||
std::string policy_query = "{\"policy_type_id\":" + std::to_string(policy_id) + "}";
|
||||
unsigned char * message = (unsigned char *)calloc(policy_query.length(), sizeof(unsigned char));
|
||||
memcpy(message, policy_query.c_str(), policy_query.length());
|
||||
xapp_rmr_header header;
|
||||
header.payload_length = policy_query.length();
|
||||
header.message_type = A1_POLICY_QUERY;
|
||||
mdclog_write(MDCLOG_INFO, "Sending request for policy id %d\n", policy_id);
|
||||
rmr_ref->xapp_rmr_send(&header, (void *)message);
|
||||
free(message);
|
||||
|
||||
}
|
||||
|
||||
void Xapp::set_rnib_gnblist(void) {
|
||||
|
||||
openSdl();
|
||||
|
||||
void *result = getListGnbIds();
|
||||
if(strlen((char*)result) < 1){
|
||||
mdclog_write(MDCLOG_ERR, "ERROR: no data from getListGnbIds\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mdclog_write(MDCLOG_INFO, "GNB List in R-NIB %s\n", (char*)result);
|
||||
|
||||
// remove non-unicode characters that make rapodjson fail the parsing
|
||||
std::string result_clean((char*) result);
|
||||
while (result_clean.back() != '}') {
|
||||
result_clean.pop_back();
|
||||
}
|
||||
|
||||
Document doc;
|
||||
ParseResult parseJson = doc.Parse(result_clean.c_str());
|
||||
if (!parseJson) {
|
||||
//std::cerr << "JSON parse error: %s (%u)\n", GetParseErrorFunc(parseJson.Code());
|
||||
std::cerr << "JSON parse error: " << GetParseErrorFunc(parseJson.Code()) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!doc.HasMember("gnb_list")){
|
||||
mdclog_write(MDCLOG_INFO, "JSON Has No GNB List Object");
|
||||
return;
|
||||
}
|
||||
assert(doc.HasMember("gnb_list"));
|
||||
|
||||
const Value& gnblist = doc["gnb_list"];
|
||||
if (gnblist.IsNull())
|
||||
return;
|
||||
|
||||
if(!gnblist.IsArray()){
|
||||
mdclog_write(MDCLOG_INFO, "GNB List is not an array");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
assert(gnblist.IsArray());
|
||||
for (SizeType i = 0; i < gnblist.Size(); i++) { // Uses SizeType instead of size_t
|
||||
assert(gnblist[i].IsObject());
|
||||
const Value& gnbobj = gnblist[i];
|
||||
assert(gnbobj.HasMember("inventory_name"));
|
||||
assert(gnbobj["inventory_name"].IsString());
|
||||
std::string name = gnbobj["inventory_name"].GetString();
|
||||
rnib_gnblist.push_back(name);
|
||||
}
|
||||
|
||||
closeSdl();
|
||||
return;
|
||||
}
|
125
setup/xapp-bs-connector/src/xapp.hpp
Normal file
125
setup/xapp-bs-connector/src/xapp.hpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
==================================================================================
|
||||
|
||||
Copyright (c) 2019-2020 AT&T Intellectual Property.
|
||||
|
||||
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
==================================================================================
|
||||
*//*
|
||||
* xapp.hpp
|
||||
*
|
||||
* Mar, 2020 (Shraboni Jana)
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SRC_XAPP_HPP_
|
||||
#define SRC_XAPP_HPP_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <csignal>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <unordered_map>
|
||||
#include "xapp_rmr.hpp"
|
||||
#include "xapp_sdl.hpp"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/error.h"
|
||||
#include <thread>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include "agent_connector.hpp"
|
||||
#include <vector>
|
||||
|
||||
#include "msgs_proc.hpp"
|
||||
#include "subs_mgmt.hpp"
|
||||
#include "xapp_config.hpp"
|
||||
extern "C" {
|
||||
#include "rnib/rnibreader.h"
|
||||
}
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
using namespace rapidjson;
|
||||
|
||||
// used to identify xApp requests with DUs
|
||||
// Note: this value is updated at Docker build to use the last octet of the xApp IP
|
||||
#define XAPP_REQ_ID 0
|
||||
|
||||
#define SOCKET_PORT_EXT 7000
|
||||
#define XAPP_TERMINATE "terminate"
|
||||
|
||||
// id of gnb to control as seen from the ric
|
||||
#define GNB_ID ""
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
class Xapp{
|
||||
public:
|
||||
|
||||
Xapp(XappSettings &, XappRmr &);
|
||||
|
||||
~Xapp(void);
|
||||
|
||||
void stop(void);
|
||||
|
||||
void startup(SubscriptionHandler &);
|
||||
void shutdown(void);
|
||||
|
||||
void start_xapp_receiver(XappMsgHandler &);
|
||||
void Run();
|
||||
|
||||
void sdl_data(void);
|
||||
|
||||
Xapp(Xapp const &)=delete;
|
||||
Xapp& operator=(Xapp const &) = delete;
|
||||
|
||||
void register_handler(XappMsgHandler &fn){
|
||||
_callbacks.emplace_back(fn);
|
||||
}
|
||||
|
||||
//getters/setters.
|
||||
void set_rnib_gnblist(void);
|
||||
std::vector<std::string> get_rnib_gnblist(){ return rnib_gnblist; }
|
||||
|
||||
private:
|
||||
void startup_subscribe_requests(void );
|
||||
void shutdown_subscribe_deletes(void);
|
||||
void send_ric_control_request(char* payload, std::string gnb_id);
|
||||
void startup_get_policies(void );
|
||||
|
||||
void handle_rx_msg(void);
|
||||
void handle_rx_msg_agent(std::string agent_ip);
|
||||
void handle_external_control_message(int port);
|
||||
void terminate_du_reporting(void);
|
||||
|
||||
XappRmr * rmr_ref;
|
||||
XappSettings * config_ref;
|
||||
SubscriptionHandler *subhandler_ref;
|
||||
|
||||
std::mutex *xapp_mutex;
|
||||
std::vector<std::thread> xapp_rcv_thread;
|
||||
std::vector<std::string> rnib_gnblist;
|
||||
std::vector<XappMsgHandler> _callbacks;
|
||||
|
||||
std::vector<std::unique_ptr<std::thread>> control_thr_rx;
|
||||
std::unique_ptr<std::thread> ext_control_thr_rx;
|
||||
};
|
||||
|
||||
|
||||
#endif /* SRC_XAPP_HPP_ */
|
12
setup/xapp-bs-connector/src/xapp_env.sh
Executable file
12
setup/xapp-bs-connector/src/xapp_env.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#! /bin/bash
|
||||
|
||||
export RMR_SEED_RT="routes.txt"
|
||||
export RMR_RTG_SVC="9999"
|
||||
export MSG_MAX_BUFFER="2072"
|
||||
export THREADS="1"
|
||||
export VERBOSE="0"
|
||||
export CONFIG_FILE="config/config-file.json"
|
||||
export XAPP_ID="3489-er492k-92389"
|
||||
export LOG_LEVEL="MDCLOG_ERR"
|
||||
export DBAAS_SERVICE_HOST="10.0.2.12"
|
||||
export DBAAS_SERVICE_PORT="6379"
|
Reference in New Issue
Block a user