4 ==================================================================================
5 Copyright (c) 2019-2020 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 = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
36 assert(e2ap_pdu_obj != 0);
39 initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
43 IE_array = (RICsubscriptionRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_REQUEST_IES, sizeof(RICsubscriptionRequest_IEs_t));
44 assert(IE_array != 0);
47 action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(INITIAL_REQUEST_LIST_SIZE, sizeof(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 RICsubsequentAction *)calloc(1, sizeof(struct 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 = 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");;
70 // Sequence of actions to be admitted causes special heart-ache. Free ric subscription element manually and reset the ie pointer
71 RICsubscriptionDetails_t * ricsubscription_ie = &(IE_array[2].value.choice.RICsubscriptionDetails);
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 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_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 = ProcedureCode_id_RICsubscription;
117 initMsg->criticality = Criticality_ignore;
118 initMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionRequest;
120 res = set_fields(initMsg, dinput);
125 int ret_constr = asn_check_constraints(&asn_DEF_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_E2AP_PDU, e2ap_pdu_obj);
134 asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_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( InitiatingMessage_t * init_msg, subscription_helper &helper){
164 error_string = "Error. Invalid reference when getting fields from subscription request";
168 RICsubscriptionRequest_t * ric_subscription = &(init_msg->value.choice.RICsubscriptionRequest);
169 ric_subscription->protocolIEs.list.count = 0;
172 RICsubscriptionRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
173 ies_ricreq->criticality = Criticality_reject;
174 ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
175 ies_ricreq->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
176 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 RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
184 ies_ranfunc->criticality = Criticality_reject;
185 ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
186 ies_ranfunc->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
187 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 RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
195 ies_actid->criticality = Criticality_reject;
196 ies_actid->id = ProtocolIE_ID_id_RICsubscriptionDetails;
197 ies_actid->value.present = RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
198 RICsubscriptionDetails_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscriptionDetails;
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 = (RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(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 RICsubsequentAction *)calloc(1, sizeof(struct 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 = Criticality_ignore;
231 action_array[i].id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
232 action_array[i].value.present = 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();
237 result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
239 error_string = "Erorr : Unable to assign memory to add Action item to set up list";
245 result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
255 bool subscription_request:: get_fields(InitiatingMessage_t * init_msg, subscription_helper & dout)
259 error_string = "Error. Invalid reference when getting fields from subscription request";
263 RICrequestID_t *requestid;
264 RANfunctionID_t * ranfunctionid;
265 RICsubscriptionDetails_t * ricsubscription;
267 for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.count; edx++) {
268 RICsubscriptionRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.array[edx];
272 case (ProtocolIE_ID_id_RICrequestID):
273 requestid = &memb_ptr->value.choice.RICrequestID;
274 //dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
277 case (ProtocolIE_ID_id_RANfunctionID):
278 ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
279 dout.set_function_id(*ranfunctionid);
282 case (ProtocolIE_ID_id_RICsubscriptionDetails):
283 ricsubscription = &memb_ptr->value.choice.RICsubscriptionDetails;
284 dout.set_event_def(ricsubscription->ricEventTriggerDefinition.buf, ricsubscription->ricEventTriggerDefinition.size);
286 for(int index = 0; index < ricsubscription->ricAction_ToBeSetup_List.list.count; index ++){
287 RICaction_ToBeSetup_ItemIEs_t * item = (RICaction_ToBeSetup_ItemIEs_t *)ricsubscription->ricAction_ToBeSetup_List.list.array[index];
288 if (item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction == NULL){
289 dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType);
292 std::string action_def = ""; // for now we are ignoring action definition
301 //asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);