4 ==================================================================================
5 Copyright (c) 2018-2019 AT&T Intellectual Property.
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 ==================================================================================
22 #include "subscription_request.hpp"
25 // Set up memory allocations for each IE for encoding
26 // We are responsible for memory management for each IE for encoding
27 // Hence destructor should clear out memory
28 // When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
29 // for releasing memory by external calling function)
30 subscription_request::subscription_request(void){
35 e2ap_pdu_obj = (E2N_E2AP_PDU_t * )calloc(1, sizeof(E2N_E2AP_PDU_t));
36 assert(e2ap_pdu_obj != 0);
39 initMsg = (E2N_InitiatingMessage_t * )calloc(1, sizeof(E2N_InitiatingMessage_t));
43 IE_array = (E2N_RICsubscriptionRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_REQUEST_IES, sizeof(E2N_RICsubscriptionRequest_IEs_t));
44 assert(IE_array != 0);
47 action_array = (E2N_RICaction_ToBeSetup_ItemIEs_t *)calloc(INITIAL_REQUEST_LIST_SIZE, sizeof(E2N_RICaction_ToBeSetup_ItemIEs_t));
48 assert(action_array != 0);
49 action_array_size = INITIAL_REQUEST_LIST_SIZE;
50 // also need to add subsequent action and time to wait ..
51 for (unsigned int i = 0; i < action_array_size; i++){
52 action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct E2N_RICsubsequentAction *)calloc(1, sizeof(struct E2N_RICsubsequentAction));
53 assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction != 0);
56 e2ap_pdu_obj->choice.initiatingMessage = initMsg;
57 e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_initiatingMessage;
65 // Clear assigned protocolIE list from RIC indication IE container
66 subscription_request::~subscription_request(void){
68 mdclog_write(MDCLOG_DEBUG, "Freeing subscription request memory for");;
70 // Sequence of actions to be admitted causes special heart-ache. Free ric subscription element manually and reset the ie pointer
71 E2N_RICsubscription_t * ricsubscription_ie = &(IE_array[2].value.choice.RICsubscription);
73 for(int i = 0; i < ricsubscription_ie->ricAction_ToBeSetup_List.list.size; i++){
74 ricsubscription_ie->ricAction_ToBeSetup_List.list.array[i] = 0;
77 if (ricsubscription_ie->ricAction_ToBeSetup_List.list.size > 0){
78 free(ricsubscription_ie->ricAction_ToBeSetup_List.list.array);
79 ricsubscription_ie->ricAction_ToBeSetup_List.list.size = 0;
80 ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
81 ricsubscription_ie->ricAction_ToBeSetup_List.list.array = 0;
84 // clear subsequent action array
85 for (unsigned int i = 0; i < action_array_size; i++){
86 free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
90 E2N_RICsubscriptionRequest_t * subscription_request = &(initMsg->value.choice.RICsubscriptionRequest);
92 for(int i = 0; i < subscription_request->protocolIEs.list.size; i++){
93 subscription_request->protocolIEs.list.array[i] = 0;
96 if( subscription_request->protocolIEs.list.size > 0){
97 free( subscription_request->protocolIEs.list.array);
98 subscription_request->protocolIEs.list.array = 0;
99 subscription_request->protocolIEs.list.size = 0;
100 subscription_request->protocolIEs.list.count = 0;
105 e2ap_pdu_obj->choice.initiatingMessage = 0;
107 ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
108 mdclog_write(MDCLOG_DEBUG, "Freed subscription request memory ");
112 bool subscription_request::encode_e2ap_subscription(unsigned char *buf, size_t *size, subscription_helper &dinput){
116 initMsg->procedureCode = E2N_ProcedureCode_id_ricSubscription;
117 initMsg->criticality = E2N_Criticality_ignore;
118 initMsg->value.present = E2N_InitiatingMessage__value_PR_RICsubscriptionRequest;
120 res = set_fields(initMsg, dinput);
125 int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
127 error_string.assign(errbuf, errbuf_len);
128 error_string = "Constraints failed for encoding subscription request. Reason = " + error_string;
132 //xer_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
134 asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
136 if(retval.encoded == -1){
137 error_string.assign(strerror(errno));
138 error_string = "Error encoding Subscription Request. Reason = " + error_string;
142 if(*size < retval.encoded){
143 std::stringstream ss;
144 ss <<"Error encoding Subscription Request . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
145 error_string = ss.str();
151 *size = retval.encoded;
157 bool subscription_request::set_fields( E2N_InitiatingMessage_t * init_msg, subscription_helper &helper){
164 error_string = "Error. Invalid reference when getting fields from subscription request";
168 E2N_RICsubscriptionRequest_t * ric_subscription = &(init_msg->value.choice.RICsubscriptionRequest);
169 ric_subscription->protocolIEs.list.count = 0;
172 E2N_RICsubscriptionRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
173 ies_ricreq->criticality = E2N_Criticality_reject;
174 ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
175 ies_ricreq->value.present = E2N_RICsubscriptionRequest_IEs__value_PR_RICrequestID;
176 E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
177 ricrequest_ie->ricRequestorID = helper.get_request_id();
178 ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
179 result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
183 E2N_RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
184 ies_ranfunc->criticality = E2N_Criticality_reject;
185 ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
186 ies_ranfunc->value.present = E2N_RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
187 E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
188 *ranfunction_ie = helper.get_function_id();
189 result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
194 E2N_RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
195 ies_actid->criticality = E2N_Criticality_reject;
196 ies_actid->id = E2N_ProtocolIE_ID_id_RICsubscription;
197 ies_actid->value.present = E2N_RICsubscriptionRequest_IEs__value_PR_RICsubscription;
198 E2N_RICsubscription_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscription;
200 ricsubscription_ie->ricEventTriggerDefinition.buf = (uint8_t *) helper.get_event_def();
201 ricsubscription_ie->ricEventTriggerDefinition.size = helper.get_event_def_size();
203 std::vector<Action> * ref_action_array = helper.get_list();
204 // do we need to resize ?
205 // we don't care about contents, so just do a free/calloc
206 if(action_array_size < ref_action_array->size()){
207 std::cout <<"re-allocating action array from " << action_array_size << " to " << 2 * ref_action_array->size() << std::endl;
208 // free subsequent allocation
209 for (unsigned int i = 0; i < action_array_size; i++){
210 free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
213 action_array_size = 2 * ref_action_array->size();
215 action_array = (E2N_RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(E2N_RICaction_ToBeSetup_ItemIEs_t));
216 assert(action_array != 0);
218 // also need to add subsequent action and time to wait ..
219 for (unsigned int i = 0; i < action_array_size; i++){
220 action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct E2N_RICsubsequentAction *)calloc(1, sizeof(struct E2N_RICsubsequentAction));
221 assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction != 0);
226 // reset the list count on ricAction_ToBeSetup_List;
227 ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
229 for(unsigned int i = 0; i < ref_action_array->size(); i ++){
230 action_array[i].criticality = E2N_Criticality_ignore;
231 action_array[i].id = E2N_ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
232 action_array[i].value.present = E2N_RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
233 action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionID = (*ref_action_array)[i].get_id();
234 action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionType = (*ref_action_array)[i].get_type();
235 action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType = (*ref_action_array)[i].get_subsequent_action();
236 action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricTimeToWait = (*ref_action_array)[i].get_wait();
238 result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
240 error_string = "Erorr : Unable to assign memory to add Action item to set up list";
246 result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
256 bool subscription_request:: get_fields(E2N_InitiatingMessage_t * init_msg, subscription_helper & dout)
260 error_string = "Error. Invalid reference when getting fields from subscription request";
264 E2N_RICrequestID_t *requestid;
265 E2N_RANfunctionID_t * ranfunctionid;
266 E2N_RICsubscription_t * ricsubscription;
268 for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.count; edx++) {
269 E2N_RICsubscriptionRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.array[edx];
273 case (E2N_ProtocolIE_ID_id_RICrequestID):
274 requestid = &memb_ptr->value.choice.RICrequestID;
275 dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
278 case (E2N_ProtocolIE_ID_id_RANfunctionID):
279 ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
280 dout.set_function_id(*ranfunctionid);
283 case (E2N_ProtocolIE_ID_id_RICsubscription):
284 ricsubscription = &memb_ptr->value.choice.RICsubscription;
285 dout.set_event_def(ricsubscription->ricEventTriggerDefinition.buf, ricsubscription->ricEventTriggerDefinition.size);
287 for(int index = 0; index < ricsubscription->ricAction_ToBeSetup_List.list.count; index ++){
288 E2N_RICaction_ToBeSetup_ItemIEs_t * item = (E2N_RICaction_ToBeSetup_ItemIEs_t *)ricsubscription->ricAction_ToBeSetup_List.list.array[index];
289 if (item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction == NULL){
290 dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType);
293 std::string action_def = ""; // for now we are ignoring action definition
294 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);
303 //asn_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2pdu);