2 ==================================================================================
4 Copyright (c) 2018-2019 AT&T Intellectual Property.
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 ==================================================================================
19 /* Author : Ashwin Sridharan
25 holds all functionality related to message exchange upon startup
26 - subscription requests
29 NOTE : This module only sends out requests. Responses are assumed to be
30 handled on RMR listening threads that are expected to already running in
35 #include "adm-ctrl-xapp.hpp"
38 // function to call to add subscriptions
39 // Note 1 : it is synchronous. will block till it succeeds or fails
40 // Note 2: we bind and pass the xapp tx function to separate out RMR from subscription process
42 int add_subscription(subscription_handler *sub_handler_ref, XaPP * xapp_ref, subscription_helper & he, subscription_response_helper he_resp, std::string & gNodeB){
43 unsigned char node_buffer[32];
44 std::copy(gNodeB.begin(), gNodeB.end(), node_buffer);
45 node_buffer[gNodeB.length()] = '\0';
47 int res = sub_handler_ref->request_subscription(he, he_resp, gNodeB, RIC_SUB_REQ, std::bind(static_cast<bool (XaPP::*)(int, size_t, void *, unsigned char const*, link_types, tx_types)>( &XaPP::Send), xapp_ref, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, node_buffer, link_types::HIGH_RELIABILITY, tx_types::ROUTE));
52 // function to call to delete subscription
53 // Note 1 : it is synchronous. will block till it succeeds or fails
54 // Note 2: we bind and pass the xapp tx function to separate out RMR from subscription process
56 int delete_subscription(subscription_handler *sub_handler_ref, XaPP * xapp_ref, subscription_helper & he, subscription_response_helper he_resp, std::string & gNodeB){
57 unsigned char node_buffer[32];
58 std::copy(gNodeB.begin(), gNodeB.end(), node_buffer);
59 node_buffer[gNodeB.length()] = '\0';
61 int res = sub_handler_ref->request_subscription_delete(he, he_resp, gNodeB, RIC_SUB_DEL_REQ, std::bind(static_cast<bool (XaPP::*)(int, size_t, void *, unsigned char const*, link_types, tx_types)>(&XaPP::Send), xapp_ref, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, node_buffer, link_types::HIGH_RELIABILITY, tx_types::ROUTE));
67 init::init (XaPP & xapp, subscription_handler & sub_handler, configuration & my_config){
69 sub_handler_ref = &sub_handler;
70 config_ref = &my_config;
74 // Main handle to subscribe to requests
75 // AC xAPP basically subscribes to just one subscription (SgNB Addition Request), but can be extended to subscribe to
77 void init::startup_subscribe_requests(void ){
79 //======================================================
80 // sgnb Subscription spec
82 int request_id = 2; // will be over-written by subscription handler
86 int action_type = config_ref->report_mode_only ? 0:1;
89 int procedure_code = 27;
90 std::string egnb_id = "Testgnb";
91 std::string plmn_id = "Testplmn";
93 unsigned char event_buf[128];
94 size_t event_buf_len = 128;
98 e2sm_event_trigger_helper trigger_data;
99 e2sm_event_trigger event_trigger;
101 trigger_data.egNB_id = egnb_id;
102 trigger_data.plmn_id = plmn_id;
103 trigger_data.egNB_id_type = 2;
104 trigger_data.interface_direction = 1;
105 trigger_data.procedure_code = procedure_code;
106 trigger_data.message_type = message_type;
107 //======================================================
109 // Encode the event trigger definition
110 res = event_trigger.encode_event_trigger(&event_buf[0], &event_buf_len, trigger_data);
112 mdclog_write(MDCLOG_ERR, "Error : %s, %d: Could not encode subscription Request. Reason = %s\n", __FILE__, __LINE__, event_trigger.get_error().c_str());
115 mdclog_write(MDCLOG_INFO, "Encoded event trigger definition into PDU of size %lu bytes\n", event_buf_len);
117 // create the subscription
118 subscription_helper sgnb_add_subscr_req;
119 subscription_response_helper subscr_response;
121 sgnb_add_subscr_req.clear();
122 sgnb_add_subscr_req.set_request(request_id, req_seq);
123 sgnb_add_subscr_req.set_function_id(function_id);
124 sgnb_add_subscr_req.add_action(action_id, action_type);
126 sgnb_add_subscr_req.set_event_def(&event_buf[0], event_buf_len);
129 //======================================================
130 // Purely for testing purposes ... write subscription ASN binary to file
132 // pfile = fopen("event_trigger.pr", "wb");
133 // fwrite(event_buf, 1, event_buf_len, pfile);
135 //======================================================
138 // for each gNodeB, try MAX_SUBSCRIPTION_ATTEMPTS
139 // record gNodeBs for which we could not subscribe.
140 // note that there could be multiple subscriptions for each gNodeB.
141 // for AC xAPP we are doing just one ...
142 std::vector<std::string> failed_gNodeBs;
144 for(auto &it: config_ref->gNodeB_list){
146 int subscr_result = -1;
151 std::cout <<"Shutdown signal received during subscription process. Quitting ....." << std::endl;
155 mdclog_write(MDCLOG_INFO, "Sending subscription request for %s ... Attempt number = %d\n", it.c_str(), attempt);
156 subscr_result = add_subscription(sub_handler_ref, xapp_ref, sgnb_add_subscr_req, subscr_response, it);
157 if (subscr_result == SUBSCR_SUCCESS){
162 if (attempt > MAX_SUBSCRIPTION_ATTEMPTS){
167 if(subscr_result == SUBSCR_SUCCESS){
168 mdclog_write(MDCLOG_INFO, "Successfully subscribed for gNodeB %s", (it).c_str());
171 failed_gNodeBs.push_back(it);
175 if (failed_gNodeBs.size() == 0){
176 std::cout <<"SUBSCRIPTION REQUEST :: Successfully subscribed to events for all gNodeBs " << std::endl;
179 std::cerr <<"SUBSCRIPTION REQUEST :: Failed to subscribe for following gNodeBs" << std::endl;
180 for(const auto &e: failed_gNodeBs){
181 std::cerr <<"Failed to subscribe for gNodeB " << e << std::endl;
189 // Main handle to delete subscription requests
190 // Called upon shutdown
191 void init::shutdown_subscribe_deletes(){
192 std::vector<subscription_identifier> sub_ids;
194 subscription_helper sub_helper;
195 subscription_response_helper subscr_response;
197 // get list of subscriptions
198 sub_handler_ref->get_subscription_keys(sub_ids);
200 // send delete for each one ..
201 // this is synchronous, hence will block ...
202 for(auto & id: sub_ids){
203 std::string gnodeb_id = std::get<0>(id);
204 subscription_response_helper * sub_info = sub_handler_ref->get_subscription(id);
205 int subscr_result = -1;
206 if(sub_info != NULL){
207 sub_helper.set_request(0, 0); // requirement of subscription manager ... ?
208 sub_helper.set_function_id(sub_info->get_function_id());
209 mdclog_write(MDCLOG_INFO, "Sending subscription delete for gNodeB %s\n", gnodeb_id.c_str());
210 subscr_result = delete_subscription(sub_handler_ref, xapp_ref, sub_helper, subscr_response, gnodeb_id);
211 if(subscr_result == SUBSCR_SUCCESS){
212 mdclog_write(MDCLOG_INFO, "Successfully deleted subscription for %s, %d\n", gnodeb_id.c_str(), sub_helper.get_function_id());
215 mdclog_write(MDCLOG_ERR, "Error : %s, %d. Could not delete subcription for %s, %d. Reason = %d\n", __FILE__, __LINE__, gnodeb_id.c_str(), sub_helper.get_function_id(), subscr_result);
219 mdclog_write(MDCLOG_ERR, "Error : %s, %d. Could not get subscription for %s, %d\n", __FILE__, __LINE__, std::get<0>(id).c_str(), std::get<1>(id));
226 //Request policies on start up
227 // This is async : once query is sent. responses from A1 are handled on RMR threads
228 void init::startup_get_policies(void){
230 int policy_id = 21000;
232 // we simply create json from scratch for now since it is quite simple
233 std::string policy_query = "{\"policy_id\":" + std::to_string(policy_id) + "}";
234 unsigned char * message = (unsigned char *)calloc(policy_query.length(), sizeof(unsigned char));
235 memcpy(message, policy_query.c_str(), policy_query.length());
236 mdclog_write(MDCLOG_INFO, "Sending request for policy id %d\n", policy_id);
237 xapp_ref->Send(A1_POLICY_QUERY, policy_query.length(), message, link_types::HIGH_RELIABILITY);
243 // start up subroutines go hear
244 void init::startup(void){
245 startup_subscribe_requests();
246 startup_get_policies();
250 // shutdown subroutines go here
251 void init::shutdown(void ){
252 std::cout <<"Initiating shutdown subroutines ..." << std::endl;
253 shutdown_subscribe_deletes();