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, softwares
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 ==================================================================================
20 /* Classes to handle E2 service model based on e2sm-gNB-X2-release-1-v040.asn */
27 e2sm_event_trigger::e2sm_event_trigger(void){
29 memset(&gNodeB_ID, 0, sizeof(E2N_GlobalGNB_ID_t));
32 event_trigger = ( E2N_E2SM_gNB_X2_eventTriggerDefinition_t *)calloc(1, sizeof( E2N_E2SM_gNB_X2_eventTriggerDefinition_t));
33 assert(event_trigger != 0);
35 // allocate space for gNodeB id (used for encoding)
36 gNodeB_ID.gNB_ID.choice.gNB_ID.buf = 0;
37 gNodeB_ID.gNB_ID.choice.gNB_ID.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
38 assert(gNodeB_ID.gNB_ID.choice.gNB_ID.buf != 0);
40 // allocate space for plmn identity (used for encoding)
41 gNodeB_ID.pLMN_Identity.buf = 0;
42 gNodeB_ID.pLMN_Identity.buf = (uint8_t *) calloc(4, sizeof(uint8_t));
43 assert(gNodeB_ID.pLMN_Identity.buf != 0);
46 ie_list = ( struct E2N_InterfaceProtocolIE_Item *) calloc(INITIAL_LIST_SIZE, sizeof( struct E2N_InterfaceProtocolIE_Item));
48 ie_list_size = INITIAL_LIST_SIZE;
51 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 ));
52 assert(condition_list != 0);
58 e2sm_event_trigger::~e2sm_event_trigger(void){
60 mdclog_write(MDCLOG_DEBUG, "Freeing event trigger object memory");
61 for(int i = 0; i < condition_list->list.size; i++){
62 condition_list->list.array[i] = 0;
65 if (condition_list->list.size > 0){
66 free(condition_list->list.array);
67 condition_list->list.array = 0;
68 condition_list->list.size = 0;
69 condition_list->list.count = 0;
75 free(gNodeB_ID.gNB_ID.choice.gNB_ID.buf);
76 gNodeB_ID.gNB_ID.choice.gNB_ID.buf = 0;
78 free(gNodeB_ID.pLMN_Identity.buf);
79 gNodeB_ID.pLMN_Identity.buf = 0;
84 event_trigger->interface_ID.choice.global_gNB_ID = 0;
85 event_trigger->interfaceProtocolIE_List = 0;
87 ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_eventTriggerDefinition, event_trigger);
88 mdclog_write(MDCLOG_DEBUG, "Freed event trigger object memory");
93 bool e2sm_event_trigger::encode_event_trigger(unsigned char *buf, size_t *size, e2sm_event_trigger_helper &helper){
96 res = set_fields(event_trigger, helper);
101 int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_eventTriggerDefinition, event_trigger, errbuf, &errbuf_len);
103 error_string.assign(&errbuf[0], errbuf_len);
107 //xer_fprint(stdout, &asn_DEF_E2N_E2SM_gNB_X2_eventTriggerDefinition, event_trigger);
109 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);
111 if(retval.encoded == -1){
112 error_string.assign(strerror(errno));
115 else if (retval.encoded > *size){
116 std::stringstream ss;
117 ss <<"Error encoding event trigger definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
118 error_string = ss.str();
122 *size = retval.encoded;
129 bool e2sm_event_trigger::set_fields(E2N_E2SM_gNB_X2_eventTriggerDefinition_t * ref_event_trigger, e2sm_event_trigger_helper & helper){
130 if(ref_event_trigger == 0){
131 error_string = "Invalid reference for Event Trigger Definition set fields";
135 // set the message type
136 ref_event_trigger->interfaceMessageType.procedureCode = helper.procedure_code;
137 ref_event_trigger->interfaceMessageType.typeOfMessage = helper.message_type;
139 ref_event_trigger->interfaceDirection = helper.interface_direction;
140 ref_event_trigger->interface_ID.present = E2N_Interface_ID_PR_global_gNB_ID;
142 ref_event_trigger->interface_ID.choice.global_gNB_ID = &gNodeB_ID;
144 // to do : need to put correct code here for upding plmn id and gNodeB
145 // for now just place holders :
146 //================================================================
147 memcpy(gNodeB_ID.pLMN_Identity.buf, helper.plmn_id.c_str(), 3);
148 gNodeB_ID.pLMN_Identity.size = 3;
150 memcpy(gNodeB_ID.gNB_ID.choice.gNB_ID.buf, helper.egNB_id.c_str(), 3);
151 gNodeB_ID.gNB_ID.choice.gNB_ID.size = 3;
153 // we only do global gNodeB id for now, not eNodeB
154 gNodeB_ID.gNB_ID.present = E2N_GNB_ID_PR_gNB_ID;
155 //================================================================
158 // Add in any requested IE items
159 std::vector<Item> * ref_ie_array = helper.get_list();
161 if (ref_ie_array->size() == 0){
162 ref_event_trigger->interfaceProtocolIE_List = 0;
166 ref_event_trigger->interfaceProtocolIE_List = condition_list;
169 if(ref_ie_array->size() > ie_list_size){
170 ie_list_size = 2 * ref_ie_array->size();
172 ie_list = (struct E2N_InterfaceProtocolIE_Item *)calloc(ie_list_size, sizeof(struct E2N_InterfaceProtocolIE_Item));
173 assert(ie_list != 0);
176 // reset the count so that adds start from the beginning
177 ref_event_trigger->interfaceProtocolIE_List->list.count = 0;
179 for(unsigned int i = 0; i < ref_ie_array->size(); i++){
181 ie_list[i].interfaceProtocolIE_ID = (*ref_ie_array)[i].interface_id;
182 ie_list[i].interfaceProtocolIE_Test = (*ref_ie_array)[i].test;
184 //switch(ie_list[i].interfaceProtocolIE_Value.present){
185 switch((*ref_ie_array)[i].val_type){
187 case (E2N_InterfaceProtocolIE_Value_PR_valueInt):
188 ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueInt;
189 ie_list[i].interfaceProtocolIE_Value.choice.valueInt = (*ref_ie_array)[i].value_n;
192 case (E2N_InterfaceProtocolIE_Value_PR_valueEnum):
193 ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueEnum;
194 ie_list[i].interfaceProtocolIE_Value.choice.valueEnum = (*ref_ie_array)[i].value_n;
197 case (E2N_InterfaceProtocolIE_Value_PR_valueBool):
198 ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueBool;
199 ie_list[i].interfaceProtocolIE_Value.choice.valueBool = (*ref_ie_array)[i].value_n;
202 case (E2N_InterfaceProtocolIE_Value_PR_valueBitS):
203 ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueBitS;
204 ie_list[i].interfaceProtocolIE_Value.choice.valueBitS.buf = (uint8_t *)(*ref_ie_array)[i].value_s.c_str();
205 ie_list[i].interfaceProtocolIE_Value.choice.valueBitS.size = (*ref_ie_array)[i].value_s.length();
208 case (E2N_InterfaceProtocolIE_Value_PR_valueOctS):
209 ie_list[i].interfaceProtocolIE_Value.present = E2N_InterfaceProtocolIE_Value_PR_valueOctS;
210 ie_list[i].interfaceProtocolIE_Value.choice.valueOctS.buf = (uint8_t *)(*ref_ie_array)[i].value_s.c_str();
211 ie_list[i].interfaceProtocolIE_Value.choice.valueOctS.size = (*ref_ie_array)[i].value_s.length();
216 std::stringstream ss;
217 ss <<"Error ! " << __FILE__ << "," << __LINE__ << " illegal enum " << (*ref_ie_array)[i].val_type << " for interface Protocol IE value" << std::endl;
218 std::string error_string = ss.str();
223 ASN_SEQUENCE_ADD(ref_event_trigger->interfaceProtocolIE_List, &ie_list[i]);
231 bool e2sm_event_trigger::get_fields(E2N_E2SM_gNB_X2_eventTriggerDefinition_t * ref_event_trigger, e2sm_event_trigger_helper & helper){
233 if (ref_event_trigger == 0){
234 error_string = "Invalid reference for Event Trigger definition get fields";
238 helper.procedure_code = ref_event_trigger->interfaceMessageType.procedureCode;
239 helper.message_type = ref_event_trigger->interfaceMessageType.typeOfMessage;
240 helper.interface_direction = ref_event_trigger->interfaceDirection;
242 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);
243 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);
244 for(int i = 0; i < ref_event_trigger->interfaceProtocolIE_List->list.count; i++){
245 struct E2N_InterfaceProtocolIE_Item * ie_item = ref_event_trigger->interfaceProtocolIE_List->list.array[i];
246 switch(ie_item->interfaceProtocolIE_Value.present){
247 case (E2N_InterfaceProtocolIE_Value_PR_valueInt):
248 helper.add_protocol_ie_item(ie_item->interfaceProtocolIE_ID, ie_item->interfaceProtocolIE_Test, ie_item->interfaceProtocolIE_Value.present, ie_item->interfaceProtocolIE_Value.choice.valueInt);
250 case (E2N_InterfaceProtocolIE_Value_PR_valueEnum):
251 helper.add_protocol_ie_item(ie_item->interfaceProtocolIE_ID, ie_item->interfaceProtocolIE_Test, ie_item->interfaceProtocolIE_Value.present, ie_item->interfaceProtocolIE_Value.choice.valueEnum);
253 case (E2N_InterfaceProtocolIE_Value_PR_valueBool):
254 helper.add_protocol_ie_item(ie_item->interfaceProtocolIE_ID, ie_item->interfaceProtocolIE_Test, ie_item->interfaceProtocolIE_Value.present, ie_item->interfaceProtocolIE_Value.choice.valueBool);
256 case (E2N_InterfaceProtocolIE_Value_PR_valueBitS):
257 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) );
259 case (E2N_InterfaceProtocolIE_Value_PR_valueOctS):
260 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) );
263 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);
275 e2sm_indication::e2sm_indication(void) {
277 memset(&gNodeB_ID, 0, sizeof(E2N_GlobalGNB_ID_t));
279 // allocate space for gNodeB id (used for encoding)
280 gNodeB_ID.gNB_ID.choice.gNB_ID.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
281 assert(gNodeB_ID.gNB_ID.choice.gNB_ID.buf != 0);
283 // allocate space for plmn identity (used for encoding)
284 gNodeB_ID.pLMN_Identity.buf = (uint8_t *) calloc(4, sizeof(uint8_t));
285 assert(gNodeB_ID.pLMN_Identity.buf != 0);
288 header = (E2N_E2SM_gNB_X2_indicationHeader_t *)calloc(1, sizeof(E2N_E2SM_gNB_X2_indicationHeader_t));
292 message = (E2N_E2SM_gNB_X2_indicationMessage_t *)calloc(1, sizeof(E2N_E2SM_gNB_X2_indicationMessage_t));
293 assert(message != 0);
296 e2sm_indication::~e2sm_indication(void){
297 mdclog_write(MDCLOG_DEBUG, "Freeing E2N_E2SM Indication object memory");
299 free(gNodeB_ID.gNB_ID.choice.gNB_ID.buf);
300 free(gNodeB_ID.pLMN_Identity.buf);
302 header->interface_ID.choice.global_gNB_ID = 0;
304 ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_indicationHeader, header);
306 message->interfaceMessage.buf = 0;
307 message->interfaceMessage.size = 0;
309 ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_indicationMessage, message);
310 mdclog_write(MDCLOG_DEBUG, "Freed E2SM Indication object memory");
316 bool e2sm_indication::encode_indication_header(unsigned char *buf, size_t *size, e2sm_header_helper &helper){
319 res = set_header_fields(header, helper);
324 int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_indicationHeader, header, errbuf, &errbuf_len);
326 error_string.assign(&errbuf[0], errbuf_len);
327 error_string = "E2SM Indication Header Constraint failed : " + error_string;
332 asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2SM_gNB_X2_indicationHeader, header, buf, *size);
334 if(retval.encoded == -1){
335 error_string.assign(strerror(errno));
336 error_string = "Error encoding E2N_E2SM Indication Header. Reason = " + error_string;
339 else if (retval.encoded > *size){
340 std::stringstream ss;
341 ss <<"Error encoding E2SM Indication Header . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
342 error_string = ss.str();
346 *size = retval.encoded;
353 bool e2sm_indication::encode_indication_message(unsigned char *buf, size_t *size, e2sm_message_helper &helper){
355 set_message_fields(message, helper);
357 int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_indicationMessage, message, errbuf, &errbuf_len);
359 error_string.assign(&errbuf[0], errbuf_len);
360 error_string = "E2SM Indication Message Constraint failed : " + error_string;
364 asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2SM_gNB_X2_indicationMessage, message, buf, *size);
365 if(retval.encoded == -1){
366 error_string.assign(strerror(errno));
367 error_string = "Error encoding E2SM Indication Header. Reason = " + error_string;
370 else if (retval.encoded > *size){
371 std::stringstream ss;
372 ss <<"Error encoding E2N_E2SM Indication Message . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
373 error_string = ss.str();
378 *size = retval.encoded;
386 // Used when generating an indication header
387 bool e2sm_indication::set_header_fields(E2N_E2SM_gNB_X2_indicationHeader_t *header, e2sm_header_helper &helper){
390 error_string = "Invalid reference for E2SM Indication Header set fields";
395 header->interfaceDirection = helper.interface_direction;
396 header->interface_ID.present = E2N_Interface_ID_PR_global_gNB_ID;
397 header->interface_ID.choice.global_gNB_ID = &gNodeB_ID;
400 // to do : need to put correct code here for upding plmn id and gNodeB
401 // for now just place holders :
402 memcpy(gNodeB_ID.pLMN_Identity.buf, helper.plmn_id.c_str(), 3);
403 gNodeB_ID.pLMN_Identity.size = 3;
405 memcpy(gNodeB_ID.gNB_ID.choice.gNB_ID.buf, helper.egNB_id.c_str(), 3);
406 gNodeB_ID.gNB_ID.choice.gNB_ID.size = 3;
408 // we only do global gNodeB id for now, not eNodeB
409 gNodeB_ID.gNB_ID.present = E2N_GNB_ID_PR_gNB_ID;
416 // used when decoding an indication header
417 bool e2sm_indication::get_header_fields(E2N_E2SM_gNB_X2_indicationHeader_t *header, e2sm_header_helper &helper){
420 error_string = "Invalid reference for E2SM Indication header get fields";
424 helper.interface_direction = header->interfaceDirection;
425 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);
426 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);
428 // to do : add code to decipher plmn and global gnodeb from ints (since that is likely the convention for packing)
435 // Used when generating an indication message
436 bool e2sm_indication::set_message_fields(E2N_E2SM_gNB_X2_indicationMessage_t *interface_message, e2sm_message_helper &helper){
438 if(interface_message == 0){
439 error_string = "Invalid reference for E2SM Indication Message set fields";
443 // interface-message is an octet string. just point it to the buffer
444 interface_message->interfaceMessage.buf = &(helper.x2ap_pdu[0]);
445 interface_message->interfaceMessage.size = helper.x2ap_pdu_size;
451 // used when decoding an indication message
452 bool e2sm_indication::get_message_fields( E2N_E2SM_gNB_X2_indicationMessage_t *interface_message, e2sm_message_helper &helper){
455 if(interface_message == 0){
456 error_string = "Invalid reference for E2SM Indication Message get fields";
460 // interface message is an octet string
461 helper.x2ap_pdu = interface_message->interfaceMessage.buf;;
462 helper.x2ap_pdu_size = interface_message->interfaceMessage.size;
471 e2sm_control::e2sm_control(void) {
473 memset(&gNodeB_ID, 0, sizeof(E2N_GlobalGNB_ID_t));
475 // allocate space for gNodeB id (used for encoding)
476 gNodeB_ID.gNB_ID.choice.gNB_ID.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
477 assert(gNodeB_ID.gNB_ID.choice.gNB_ID.buf != 0);
479 // allocate space for plmn identity (used for encoding)
480 gNodeB_ID.pLMN_Identity.buf = (uint8_t *) calloc(4, sizeof(uint8_t));
481 assert(gNodeB_ID.pLMN_Identity.buf != 0);
484 header = (E2N_E2SM_gNB_X2_controlHeader_t *)calloc(1, sizeof(E2N_E2SM_gNB_X2_controlHeader_t));
488 message = (E2N_E2SM_gNB_X2_controlMessage_t *)calloc(1, sizeof(E2N_E2SM_gNB_X2_controlMessage_t));
489 assert(message != 0);
492 e2sm_control::~e2sm_control(void){
493 mdclog_write(MDCLOG_DEBUG, "Freeing E2SM Control object memory");
495 free(gNodeB_ID.gNB_ID.choice.gNB_ID.buf);
496 free(gNodeB_ID.pLMN_Identity.buf);
497 header->interface_ID.choice.global_gNB_ID = 0;
498 ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_controlHeader, header);
500 message->interfaceMessage.buf = 0;
501 ASN_STRUCT_FREE(asn_DEF_E2N_E2SM_gNB_X2_controlMessage, message);
503 mdclog_write(MDCLOG_DEBUG, "Freed E2SM Control object memory");
509 bool e2sm_control::encode_control_header(unsigned char *buf, size_t *size, e2sm_header_helper &helper){
512 res = set_header_fields(header, helper);
517 int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_controlHeader, header, errbuf, &errbuf_len);
519 error_string.assign(&errbuf[0], errbuf_len);
520 error_string = "E2SM Control Header Constraint failed : " + error_string;
525 asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2SM_gNB_X2_controlHeader, header, buf, *size);
527 if(retval.encoded == -1){
528 error_string.assign(strerror(errno));
529 error_string = "Error encoding E2SM Control Header. Reason = " + error_string;
532 else if (retval.encoded > *size){
533 std::stringstream ss;
534 ss <<"Error encoding E2N_E2SM Control Header . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
535 error_string = ss.str();
539 *size = retval.encoded;
546 bool e2sm_control::encode_control_message(unsigned char *buf, size_t *size, e2sm_message_helper &helper){
548 set_message_fields(message, helper);
550 int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2SM_gNB_X2_controlMessage, message, errbuf, &errbuf_len);
552 error_string.assign(&errbuf[0], errbuf_len);
553 error_string = "E2SM Control Message Constraint failed : " + error_string;
557 asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2SM_gNB_X2_controlMessage, message, buf, *size);
558 if(retval.encoded == -1){
559 error_string.assign(strerror(errno));
560 error_string = "Error encoding E2SM Control Message. Reason = " + error_string;
563 else if (retval.encoded > *size){
564 std::stringstream ss;
565 ss <<"Error encoding E2SM Control Message . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
566 error_string = ss.str();
571 *size = retval.encoded;
579 // Used when generating an indication header
580 bool e2sm_control::set_header_fields(E2N_E2SM_gNB_X2_controlHeader_t *header, e2sm_header_helper &helper){
583 error_string = "Invalid reference for E2SM Control Header set fields";
588 header->interfaceDirection = helper.interface_direction;
589 header->interface_ID.present = E2N_Interface_ID_PR_global_gNB_ID;
590 header->interface_ID.choice.global_gNB_ID = &gNodeB_ID;
593 // to do : need to put correct code here for upding plmn id and gNodeB
594 // for now just place holders :
595 memcpy(gNodeB_ID.pLMN_Identity.buf, helper.plmn_id.c_str(), 3);
596 gNodeB_ID.pLMN_Identity.size = 3;
598 memcpy(gNodeB_ID.gNB_ID.choice.gNB_ID.buf, helper.egNB_id.c_str(), 3);
599 gNodeB_ID.gNB_ID.choice.gNB_ID.size = 3;
601 // we only do global gNodeB id for now, not eNodeB
602 gNodeB_ID.gNB_ID.present = E2N_GNB_ID_PR_gNB_ID;
609 // used when decoding an indication header
610 bool e2sm_control::get_header_fields(E2N_E2SM_gNB_X2_controlHeader_t *header, e2sm_header_helper &helper){
613 error_string = "Invalid reference for E2SM Control header get fields";
617 helper.interface_direction = header->interfaceDirection;
618 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);
619 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);
621 // to do : add code to decipher plmn and global gnodeb from ints (since that is likely the convention for packing)
628 // Used when generating an indication message
629 bool e2sm_control::set_message_fields(E2N_E2SM_gNB_X2_controlMessage_t *interface_message, e2sm_message_helper &helper){
631 if(interface_message == 0){
632 error_string = "Invalid reference for E2SM Control Message set fields";
636 // interface-message is an octet string. just point it to the buffer
637 interface_message->interfaceMessage.buf = &(helper.x2ap_pdu[0]);
638 interface_message->interfaceMessage.size = helper.x2ap_pdu_size;
644 // used when decoding an indication message
645 bool e2sm_control::get_message_fields( E2N_E2SM_gNB_X2_controlMessage_t *interface_message, e2sm_message_helper &helper){
648 if(interface_message == 0){
649 error_string = "Invalid reference for E2SM Control Message get fields";
653 // interface message is an octet string
654 helper.x2ap_pdu = interface_message->interfaceMessage.buf;;
655 helper.x2ap_pdu_size = interface_message->interfaceMessage.size;