Sync from Azure to LF
[ric-plt/e2.git] / RIC-E2-TERMINATION / TEST / e2sm.c
1 /*
2  * Copyright 2019 AT&T Intellectual Property
3  * Copyright 2019 Nokia
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 //
19 // Created by adi ENZEL on 6/19/19.
20 //
21
22 #include "e2sm.h"
23
24 #define printEntry(type, function) \
25     if (mdclog_level_get() >= MDCLOG_DEBUG) { \
26         mdclog_write(MDCLOG_DEBUG, "start Test %s , %s", type, function); \
27     }
28
29
30 static void checkAndPrint(asn_TYPE_descriptor_t *typeDescriptor, void *data, char *dataType, const char *function) {
31     char errbuf[128]; /* Buffer for error message */
32     size_t errlen = sizeof(errbuf); /* Size of the buffer */
33     if (asn_check_constraints(typeDescriptor, data, errbuf, &errlen) != 0) {
34         mdclog_write(MDCLOG_ERR, "%s Constraint validation failed: %s", dataType, errbuf);
35     } else if (mdclog_level_get() >= MDCLOG_DEBUG) {
36         mdclog_write(MDCLOG_DEBUG, "%s successes function %s", dataType, function);
37     }
38 }
39
40 static size_t encodebuff(int codingType,
41                          asn_TYPE_descriptor_t *typeDescriptor,
42                          void *objectData,
43                          uint8_t *buffer,
44                          size_t buffer_size) {
45     asn_enc_rval_t er;
46     struct timespec start = {0,0};
47     struct timespec end   = {0,0};
48     clock_gettime(CLOCK_MONOTONIC, &start);
49     er = asn_encode_to_buffer(0, codingType, typeDescriptor, objectData, buffer, buffer_size);
50     clock_gettime(CLOCK_MONOTONIC, &end);
51     if (er.encoded == -1) {
52         mdclog_write(MDCLOG_ERR, "encoding of %s failed, %s", asn_DEF_E2SM_gNB_X2_eventTriggerDefinition.name, strerror(errno));
53     } else if (er.encoded > buffer_size) {
54         mdclog_write(MDCLOG_ERR, "Buffer of size %d is to small for %s", (int) buffer_size,
55                      typeDescriptor->name);
56     } else if (mdclog_level_get() >= MDCLOG_DEBUG) {
57         if (codingType == ATS_BASIC_XER) {
58             mdclog_write(MDCLOG_DEBUG, "Buffer of size %d, data = %s", (int) er.encoded, buffer);
59         }
60         else {
61             if (mdclog_level_get() >= MDCLOG_INFO) {
62                 char *printBuffer;
63                 size_t size;
64                 FILE *stream = open_memstream(&printBuffer, &size);
65                 asn_fprint(stream, typeDescriptor, objectData);
66                 mdclog_write(MDCLOG_DEBUG, "Encoding E2SM PDU past : %s", printBuffer);
67             }
68
69
70             mdclog_write(MDCLOG_DEBUG, "Buffer of size %d", (int) er.encoded);
71         }
72     }
73     mdclog_write(MDCLOG_INFO, "Encoding type %d, time is %ld seconds, %ld nanoseconds", codingType, end.tv_sec - start.tv_sec, end.tv_nsec - start.tv_nsec);
74     //mdclog_write(MDCLOG_INFO, "Encoding time is %3.9f seconds", ((double)end.tv_sec + 1.0e-9 * end.tv_nsec) - ((double)start.tv_sec + 1.0e-9 * start.tv_nsec));
75     return er.encoded;
76 }
77
78 PLMN_Identity_t *createPLMN_ID(const unsigned char *data) {
79     printEntry("PLMN_Identity_t", __func__);
80     PLMN_Identity_t *plmnId = calloc(1, sizeof(PLMN_Identity_t));
81     ASN_STRUCT_RESET(asn_DEF_PLMN_Identity, plmnId);
82     plmnId->size = 3;
83     plmnId->buf = calloc(1, 3);
84     memcpy(plmnId->buf, data, 3);
85
86     if (mdclog_level_get() >= MDCLOG_DEBUG) {
87         checkAndPrint(&asn_DEF_PLMN_Identity, plmnId, "PLMN_Identity_t", __func__);
88     }
89
90     return plmnId;
91 }
92
93 ENB_ID_t *createENB_ID(ENB_ID_PR enbType, unsigned char *data) {
94     printEntry("ENB_ID_t", __func__);
95     ENB_ID_t *enb = calloc(1, sizeof(ENB_ID_t));
96     ASN_STRUCT_RESET(asn_DEF_ENB_ID, enb);
97     switch (enbType) {
98         case ENB_ID_PR_macro_eNB_ID: { // 20 bit 3 bytes
99             enb->choice.macro_eNB_ID.size = 3;
100             enb->choice.macro_eNB_ID.bits_unused = 4;
101
102             enb->present = ENB_ID_PR_macro_eNB_ID;
103
104             enb->choice.macro_eNB_ID.buf = calloc(1, enb->choice.macro_eNB_ID.size);
105             data[enb->choice.macro_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.macro_eNB_ID.size - 1] >>
106                     (unsigned)enb->choice.macro_eNB_ID.bits_unused) << (unsigned)enb->choice.macro_eNB_ID.bits_unused);
107             memcpy(enb->choice.macro_eNB_ID.buf, data, enb->choice.macro_eNB_ID.size);
108
109             break;
110         }
111         case ENB_ID_PR_home_eNB_ID: { // 28 bit 4 bytes
112             enb->choice.home_eNB_ID.size = 4;
113             enb->choice.home_eNB_ID.bits_unused = 4;
114             enb->present = ENB_ID_PR_home_eNB_ID;
115
116             enb->choice.home_eNB_ID.buf = calloc(1, enb->choice.home_eNB_ID.size);
117             data[enb->choice.home_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.home_eNB_ID.size - 1] >>
118                     (unsigned)enb->choice.home_eNB_ID.bits_unused) << (unsigned)enb->choice.home_eNB_ID.bits_unused);
119             memcpy(enb->choice.home_eNB_ID.buf, data, enb->choice.home_eNB_ID.size);
120             break;
121         }
122         case ENB_ID_PR_short_Macro_eNB_ID: { // 18 bit - 3 bytes
123             enb->choice.short_Macro_eNB_ID.size = 3;
124             enb->choice.short_Macro_eNB_ID.bits_unused = 6;
125             enb->present = ENB_ID_PR_short_Macro_eNB_ID;
126
127             enb->choice.short_Macro_eNB_ID.buf = calloc(1, enb->choice.short_Macro_eNB_ID.size);
128             data[enb->choice.short_Macro_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.short_Macro_eNB_ID.size - 1] >>
129                     (unsigned)enb->choice.short_Macro_eNB_ID.bits_unused) << (unsigned)enb->choice.short_Macro_eNB_ID.bits_unused);
130             memcpy(enb->choice.short_Macro_eNB_ID.buf, data, enb->choice.short_Macro_eNB_ID.size);
131             break;
132         }
133         case ENB_ID_PR_long_Macro_eNB_ID: { // 21
134             enb->choice.long_Macro_eNB_ID.size = 3;
135             enb->choice.long_Macro_eNB_ID.bits_unused = 3;
136             enb->present = ENB_ID_PR_long_Macro_eNB_ID;
137
138             enb->choice.long_Macro_eNB_ID.buf = calloc(1, enb->choice.long_Macro_eNB_ID.size);
139             data[enb->choice.long_Macro_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.long_Macro_eNB_ID.size - 1] >>
140                     (unsigned)enb->choice.long_Macro_eNB_ID.bits_unused) << (unsigned)enb->choice.long_Macro_eNB_ID.bits_unused);
141             memcpy(enb->choice.long_Macro_eNB_ID.buf, data, enb->choice.long_Macro_eNB_ID.size);
142             break;
143         }
144         default:
145             free(enb);
146             return NULL;
147
148     }
149
150     if (mdclog_level_get() >= MDCLOG_DEBUG) {
151         checkAndPrint(&asn_DEF_ENB_ID, enb, "ENB_ID_t", __func__);
152     }
153     return enb;
154 }
155
156 GNB_ID_t *createGnb_id(const unsigned char *data, int numOfBits) {
157     printEntry("GNB_ID_t", __func__);
158     if (numOfBits < 22 || numOfBits > 32) {
159         mdclog_write(MDCLOG_ERR, "GNB_ID_t number of bits = %d, needs to be 22 .. 32", numOfBits);
160         return NULL;
161     }
162     GNB_ID_t *gnb = calloc(1, sizeof(GNB_ID_t));
163     ASN_STRUCT_RESET(asn_DEF_GNB_ID, gnb);
164
165     gnb->present = GNB_ID_PR_gNB_ID;
166     gnb->choice.gNB_ID.size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1);
167     gnb->choice.gNB_ID.bits_unused = gnb->choice.gNB_ID.size * 8 - numOfBits;
168     gnb->choice.gNB_ID.buf = calloc(1, gnb->choice.gNB_ID.size);
169     memcpy(gnb->choice.gNB_ID.buf, data, gnb->choice.gNB_ID.size);
170     gnb->choice.gNB_ID.buf[gnb->choice.gNB_ID.size - 1] =
171             ((unsigned)(gnb->choice.gNB_ID.buf[gnb->choice.gNB_ID.size - 1] >> (unsigned)gnb->choice.gNB_ID.bits_unused)
172                   << (unsigned)gnb->choice.gNB_ID.bits_unused);
173
174     if (mdclog_level_get() >= MDCLOG_DEBUG) {
175         checkAndPrint(&asn_DEF_GNB_ID, gnb, "GNB_ID_t", __func__);
176     }
177
178     return gnb;
179
180 }
181
182 GlobalENB_ID_t *createGlobalENB_ID(PLMN_Identity_t *plmnIdentity, ENB_ID_t *enbId) {
183     printEntry("GlobalENB_ID_t", __func__);
184     GlobalENB_ID_t *genbId = calloc(1, sizeof(GlobalENB_ID_t));
185     ASN_STRUCT_RESET(asn_DEF_GlobalENB_ID, genbId);
186     memcpy(&genbId->pLMN_Identity, plmnIdentity, sizeof(PLMN_Identity_t));
187     memcpy(&genbId->eNB_ID, enbId, sizeof(ENB_ID_t));
188
189     if (mdclog_level_get() >= MDCLOG_DEBUG) {
190         checkAndPrint(&asn_DEF_GlobalENB_ID, genbId, "GlobalENB_ID_t", __func__);
191     }
192     return genbId;
193 }
194
195 GlobalGNB_ID_t *createGlobalGNB_ID(PLMN_Identity_t *plmnIdentity, GNB_ID_t *gnb) {
196     printEntry("GlobalGNB_ID_t", __func__);
197     GlobalGNB_ID_t *ggnbId = calloc(1, sizeof(GlobalGNB_ID_t));
198     ASN_STRUCT_RESET(asn_DEF_GlobalGNB_ID, ggnbId);
199
200     memcpy(&ggnbId->pLMN_Identity, plmnIdentity, sizeof(PLMN_Identity_t));
201     memcpy(&ggnbId->gNB_ID, gnb, sizeof(GNB_ID_t));
202
203     if (mdclog_level_get() >= MDCLOG_DEBUG) {
204         checkAndPrint(&asn_DEF_GlobalGNB_ID, ggnbId, "GlobalGNB_ID_t", __func__);
205     }
206
207     return ggnbId;
208 }
209
210
211 Interface_ID_t *createInterfaceIDForGnb(GlobalGNB_ID_t *gnb) {
212     printEntry("Interface_ID_t", __func__);
213     Interface_ID_t *interfaceId = calloc(1, sizeof(Interface_ID_t));
214     ASN_STRUCT_RESET(asn_DEF_Interface_ID, interfaceId);
215
216     interfaceId->present = Interface_ID_PR_global_gNB_ID;
217     //memcpy(&interfaceId->choice.global_gNB_ID, gnb, sizeof(GlobalGNB_ID_t));
218     interfaceId->choice.global_gNB_ID = gnb;
219
220     if (mdclog_level_get() >= MDCLOG_DEBUG) {
221         checkAndPrint(&asn_DEF_Interface_ID, interfaceId, "Interface_ID_t", __func__);
222     }
223
224     return interfaceId;
225 }
226
227 Interface_ID_t *createInterfaceIDForEnb(GlobalENB_ID_t *enb) {
228     printEntry("Interface_ID_t", __func__);
229     Interface_ID_t *interfaceId = calloc(1, sizeof(Interface_ID_t));
230     ASN_STRUCT_RESET(asn_DEF_Interface_ID, interfaceId);
231
232     interfaceId->present = Interface_ID_PR_global_eNB_ID;
233     //memcpy(&interfaceId->choice.global_eNB_ID, enb, sizeof(GlobalENB_ID_t));
234     interfaceId->choice.global_eNB_ID = enb;
235
236     if (mdclog_level_get() >= MDCLOG_DEBUG) {
237         checkAndPrint(&asn_DEF_Interface_ID, interfaceId, "Interface_ID_t", __func__);
238     }
239
240     return interfaceId;
241 }
242
243
244
245 InterfaceMessageType_t *createInterfaceMessageInitiating(long procedureCode) {
246     printEntry("InterfaceMessageType_t", __func__);
247     InterfaceMessageType_t *intMsgT = calloc(1, sizeof(InterfaceMessageType_t));
248     ASN_STRUCT_RESET(asn_DEF_InterfaceMessageType, intMsgT);
249
250     intMsgT->procedureCode = procedureCode;
251     intMsgT->typeOfMessage = TypeOfMessage_initiating_message;
252
253     if (mdclog_level_get() >= MDCLOG_DEBUG) {
254         checkAndPrint(&asn_DEF_InterfaceMessageType, intMsgT, "InterfaceMessageType_t", __func__);
255     }
256
257     return intMsgT;
258 }
259
260 InterfaceMessageType_t *createInterfaceMessageSuccsesful(long procedureCode) {
261     printEntry("InterfaceMessageType_t", __func__);
262     InterfaceMessageType_t *intMsgT = calloc(1, sizeof(InterfaceMessageType_t));
263     ASN_STRUCT_RESET(asn_DEF_InterfaceMessageType, intMsgT);
264
265     intMsgT->procedureCode = procedureCode;
266     intMsgT->typeOfMessage = TypeOfMessage_successful_outcome;
267
268     if (mdclog_level_get() >= MDCLOG_DEBUG) {
269         checkAndPrint(&asn_DEF_InterfaceMessageType, intMsgT, "InterfaceMessageType_t", __func__);
270     }
271
272     return intMsgT;
273 }
274
275 InterfaceMessageType_t *createInterfaceMessageUnsuccessful(long procedureCode) {
276     printEntry("InterfaceMessageType_t", __func__);
277     InterfaceMessageType_t *intMsgT = calloc(1, sizeof(InterfaceMessageType_t));
278     ASN_STRUCT_RESET(asn_DEF_InterfaceMessageType, intMsgT);
279
280     intMsgT->procedureCode = procedureCode;
281     intMsgT->typeOfMessage = TypeOfMessage_unsuccessful_outcome;
282
283     if (mdclog_level_get() >= MDCLOG_DEBUG) {
284         checkAndPrint(&asn_DEF_InterfaceMessageType, intMsgT, "InterfaceMessageType_t", __func__);
285     }
286
287     return intMsgT;
288 }
289
290 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueInt(long number) {
291     printEntry("InterfaceProtocolIE_Value_t", __func__);
292     InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t));
293     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value);
294
295     value->present = InterfaceProtocolIE_Value_PR_valueInt;
296     value->choice.valueInt = number;
297
298     if (mdclog_level_get() >= MDCLOG_DEBUG) {
299         checkAndPrint(&asn_DEF_InterfaceProtocolIE_Value, value, "InterfaceProtocolIE_Value_t", __func__);
300     }
301
302     return value;
303 }
304
305 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueEnum(long number) {
306     printEntry("InterfaceProtocolIE_Value_t", __func__);
307     InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t));
308     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value);
309
310     value->present = InterfaceProtocolIE_Value_PR_valueEnum;
311     value->choice.valueEnum = number;
312
313     if (mdclog_level_get() >= MDCLOG_DEBUG) {
314         checkAndPrint(&asn_DEF_InterfaceProtocolIE_Value, value, "InterfaceProtocolIE_Value_t", __func__);
315     }
316
317     return value;
318 }
319
320 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBool(int val) {
321     printEntry("InterfaceProtocolIE_Value_t", __func__);
322     InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t));
323     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value);
324
325     value->present = InterfaceProtocolIE_Value_PR_valueBool;
326     value->choice.valueBool = val == 0 ? 0 : 1;
327
328     if (mdclog_level_get() >= MDCLOG_DEBUG) {
329         checkAndPrint(&asn_DEF_InterfaceProtocolIE_Value, value, "InterfaceProtocolIE_Value_t", __func__);
330     }
331
332     return value;
333 }
334
335
336 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueBitString(unsigned char *buf, int numOfBits) {
337     printEntry("InterfaceProtocolIE_Value_t", __func__);
338     size_t size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1);
339     if (strlen((const char *)buf) < size) {
340         mdclog_write(MDCLOG_ERR, "size of buffer is small : %d needs to be %d in %s", (int)strlen((const char *)buf), (int)size, __func__);
341     }
342     InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t));
343     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value);
344
345     value->present = InterfaceProtocolIE_Value_PR_valueBitS;
346     value->choice.valueBitS.size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1);
347     value->choice.valueBitS.buf = calloc(1, value->choice.valueBitS.size);
348     int bits_unused = value->choice.valueBitS.size * 8 - numOfBits;
349     value->choice.valueBitS.bits_unused = bits_unused;
350
351     memcpy(value->choice.valueBitS.buf, buf, value->choice.valueBitS.size);
352     value->choice.valueBitS.buf[size -1] = ((unsigned)(buf[size - 1]) >> (unsigned)bits_unused << (unsigned)bits_unused);
353
354     if (mdclog_level_get() >= MDCLOG_DEBUG) {
355         checkAndPrint(&asn_DEF_InterfaceProtocolIE_Value, value, "InterfaceProtocolIE_Value_t", __func__);
356     }
357
358     return value;
359 }
360
361
362 InterfaceProtocolIE_Value_t *createInterfaceProtocolValueOCTETS(uint8_t *buf) {
363     printEntry("InterfaceProtocolIE_Value_t", __func__);
364     size_t size = strlen((const char *)buf);
365     InterfaceProtocolIE_Value_t *value = calloc(1, sizeof(InterfaceProtocolIE_Value_t));
366     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Value, value);
367
368     value->present = InterfaceProtocolIE_Value_PR_valueOctS;
369     value->choice.valueOctS.size = size;
370     value->choice.valueOctS.buf = calloc(1, value->choice.valueOctS.size);
371     memcpy(value->choice.valueOctS.buf, buf, value->choice.valueOctS.size);
372
373     if (mdclog_level_get() >= MDCLOG_DEBUG) {
374         checkAndPrint(&asn_DEF_InterfaceProtocolIE_Value, value, "InterfaceProtocolIE_Value_t", __func__);
375     }
376
377     return value;
378 }
379
380
381 InterfaceProtocolIE_Item_t *createInterfaceProtocolIE_Item(long id, long test, InterfaceProtocolIE_Value_t *value) {
382     printEntry("InterfaceProtocolIE_Item_t", __func__);
383     if (test < InterfaceProtocolIE_Test_equal || test > InterfaceProtocolIE_Test_present) {
384         mdclog_write(MDCLOG_ERR, "InterfaceProtocolIE_Item_t test value is %ld,  out of scope %d .. %d ",
385                 test, InterfaceProtocolIE_Test_equal, InterfaceProtocolIE_Test_present);
386         return NULL;
387     }
388     InterfaceProtocolIE_Item_t *intProtIt = calloc(1, sizeof(InterfaceProtocolIE_Item_t));
389     ASN_STRUCT_RESET(asn_DEF_InterfaceProtocolIE_Item, intProtIt);
390
391
392     intProtIt->interfaceProtocolIE_ID = id;
393
394     intProtIt->interfaceProtocolIE_Test = test;
395
396     memcpy(&intProtIt->interfaceProtocolIE_Value, value, sizeof(InterfaceProtocolIE_Value_t));
397
398     if (mdclog_level_get() >= MDCLOG_DEBUG) {
399         checkAndPrint(&asn_DEF_InterfaceProtocolIE_Item, intProtIt, "InterfaceProtocolIE_Item_t", __func__);
400     }
401
402     return intProtIt;
403
404 }
405
406
407
408 ActionParameter_Value_t *createActionParameterValue_Int(long number) {
409     printEntry("ActionParameter_Value_t", __func__);
410     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
411     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
412
413     value->present = ActionParameter_Value_PR_valueInt;
414     value->choice.valueInt = number;
415
416     if (mdclog_level_get() >= MDCLOG_DEBUG) {
417         checkAndPrint(&asn_DEF_ActionParameter_Value, value, "ActionParameter_Value_t", __func__);
418     }
419
420     return value;
421 }
422
423 ActionParameter_Value_t *createActionParameterValue_Enum(long number) {
424     printEntry("ActionParameter_Value_t", __func__);
425     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
426     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
427
428     value->present = ActionParameter_Value_PR_valueEnum;
429     value->choice.valueEnum = number;
430
431     if (mdclog_level_get() >= MDCLOG_DEBUG) {
432         checkAndPrint(&asn_DEF_ActionParameter_Value, value, "ActionParameter_Value_t", __func__);
433     }
434
435     return value;
436 }
437
438 ActionParameter_Value_t *createActionParameterValue_Bool(int val) {
439     printEntry("ActionParameter_Value_t", __func__);
440     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
441     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
442
443     value->present = ActionParameter_Value_PR_valueBool;
444     value->choice.valueBool = val == 0 ? 0 : 1;
445
446     if (mdclog_level_get() >= MDCLOG_DEBUG) {
447         checkAndPrint(&asn_DEF_ActionParameter_Value, value, "ActionParameter_Value_t", __func__);
448     }
449
450     return value;
451 }
452
453
454 ActionParameter_Value_t *createActionParameterValue_Bit_String(unsigned char *buf, int numOfBits) {
455     printEntry("ActionParameter_Value_t", __func__);
456     size_t size = numOfBits % 8 == 0 ? (unsigned int)(numOfBits / 8) : (unsigned int)(numOfBits / 8 + 1);
457     if (strlen((const char *)buf) < size) {
458         mdclog_write(MDCLOG_ERR, "size of buffer is small : %d needs to be %d in %s", (int)strlen((const char *)buf), (int)size, __func__);
459     }
460     int bits_unused = size * 8 - numOfBits;
461
462     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
463     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
464
465     value->present = ActionParameter_Value_PR_valueBitS;
466     value->choice.valueBitS.size = size;
467     value->choice.valueBitS.buf = calloc(1, size);
468     value->choice.valueBitS.bits_unused = bits_unused;
469
470     memcpy(value->choice.valueBitS.buf, buf, size);
471     value->choice.valueBitS.buf[size -1] = ((unsigned)(buf[size - 1]) >> (unsigned)bits_unused << (unsigned)bits_unused);
472
473     if (mdclog_level_get() >= MDCLOG_DEBUG) {
474         checkAndPrint(&asn_DEF_ActionParameter_Value, value, "ActionParameter_Value_t", __func__);
475     }
476
477     return value;
478 }
479
480
481 ActionParameter_Value_t *createActionParameterValue_OCTETS(uint8_t *buf) {
482     printEntry("ActionParameter_Value_t", __func__);
483     size_t size = strlen((const char *)buf);
484     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
485     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
486
487     value->present = ActionParameter_Value_PR_valueOctS;
488     value->choice.valueOctS.size = size;
489     value->choice.valueOctS.buf = calloc(1, value->choice.valueOctS.size);
490     memcpy(value->choice.valueOctS.buf, buf, value->choice.valueOctS.size);
491
492     if (mdclog_level_get() >= MDCLOG_DEBUG) {
493         checkAndPrint(&asn_DEF_ActionParameter_Value, value, "ActionParameter_Value_t", __func__);
494     }
495
496     return value;
497 }
498
499 /**
500  *
501  * @param buf buffer that must be null terminated
502  * @return ActionParameter_Value_t *
503  */
504 ActionParameter_Value_t *createActionParameterValue_PRINTS(char *buf) {
505     printEntry("ActionParameter_Value_t", __func__);
506     size_t size = strlen((const char *)buf);
507     ActionParameter_Value_t *value = calloc(1, sizeof(ActionParameter_Value_t));
508     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Value, value);
509
510     value->present = ActionParameter_Value_PR_valuePrtS;
511     value->choice.valuePrtS.size = size;
512     value->choice.valuePrtS.buf = calloc(1, value->choice.valuePrtS.size);
513     memcpy(value->choice.valuePrtS.buf, buf, value->choice.valuePrtS.size);
514
515     if (mdclog_level_get() >= MDCLOG_DEBUG) {
516         checkAndPrint(&asn_DEF_ActionParameter_Value, value, "ActionParameter_Value_t", __func__);
517     }
518
519     return value;
520 }
521
522 ActionParameter_Item_t *creatActionParameter_Item(long id, ActionParameter_Value_t *val) {
523     printEntry("ActionParameter_Item_t", __func__);
524     if (id < 0 || id > 255) {
525         mdclog_write(MDCLOG_ERR, "ActionParameter_Item_t id = %ld, values are 0 .. 255", id);
526         return NULL;
527     }
528     ActionParameter_Item_t *actionParameterItem = calloc(1, sizeof(ActionParameter_Item_t));
529     ASN_STRUCT_RESET(asn_DEF_ActionParameter_Item, actionParameterItem);
530
531     actionParameterItem->actionParameter_ID = id;
532     memcpy(&actionParameterItem->actionParameter_Value, val, sizeof(ActionParameter_Value_t));
533
534     if (mdclog_level_get() >= MDCLOG_DEBUG) {
535         checkAndPrint(&asn_DEF_ActionParameter_Item, actionParameterItem, "ActionParameter_Item_t", __func__);
536     }
537
538     return actionParameterItem;
539 }
540
541 /**
542  *
543  * @param interfaceId
544  * @param direction
545  * @param messageType
546  * @param interfaceProtocolItemList
547  * @param listSize
548  * @param buffer
549  * @param buffer_size
550  * @return
551  */
552 size_t createEventTrigger(Interface_ID_t *interfaceId, long direction,
553                           InterfaceMessageType_t *messageType,
554                           InterfaceProtocolIE_Item_t interfaceProtocolItemList[],
555                           int listSize,
556                           uint8_t *buffer,
557                           size_t buffer_size) {
558     printEntry("E2SM_gNB_X2_eventTriggerDefinition_t", __func__);
559     if (direction < InterfaceDirection_incoming || direction > InterfaceDirection_outgoing) {
560         mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_eventTriggerDefinition_t direction = %ld, values are %d .. %d",
561                      direction, InterfaceDirection_incoming, InterfaceDirection_outgoing);
562         return -1;
563     }
564
565     E2SM_gNB_X2_eventTriggerDefinition_t *eventTrigger = calloc(1, sizeof(E2SM_gNB_X2_eventTriggerDefinition_t));
566     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_eventTriggerDefinition, eventTrigger);
567
568     memcpy(&eventTrigger->interface_ID , interfaceId, sizeof(Interface_ID_t));
569
570     eventTrigger->interfaceDirection = direction;
571     memcpy(&eventTrigger->interfaceMessageType, messageType, sizeof(InterfaceMessageType_t));
572
573     for (int i = 0; i < listSize; i++) {
574         ASN_SEQUENCE_ADD(eventTrigger->interfaceProtocolIE_List, &interfaceProtocolItemList[i]);
575     }
576
577     if (mdclog_level_get() >= MDCLOG_DEBUG) {
578         checkAndPrint(&asn_DEF_E2SM_gNB_X2_eventTriggerDefinition, eventTrigger, "E2SM_gNB_X2_eventTriggerDefinition_t", __func__);
579     }
580
581     size_t  len = encodebuff(ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_gNB_X2_eventTriggerDefinition,
582                              eventTrigger,
583                              buffer,
584                              buffer_size);
585
586
587     if (mdclog_level_get() >= MDCLOG_INFO) {
588         uint8_t buf1[4096];
589         asn_enc_rval_t er1;
590         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_eventTriggerDefinition,
591                                  eventTrigger,
592                                  buf1,
593                                  4096);
594
595     }
596
597     return len;
598 }
599
600
601 size_t createActionDefinition(long styleId, ActionParameter_Item_t actionParamList[], int listSize,
602                                                        uint8_t *buffer,
603                                                        size_t buffer_size) {
604     printEntry("E2SM_gNB_X2_actionDefinition_t", __func__);
605     E2SM_gNB_X2_actionDefinition_t *actDef = calloc(1, sizeof(E2SM_gNB_X2_actionDefinition_t));
606     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_actionDefinition, actDef);
607
608     actDef->style_ID = styleId;
609     for (int i = 0; i < listSize; i++) {
610         ASN_SEQUENCE_ADD(actDef->actionParameter_List, &actionParamList[i]);
611     }
612
613     if (mdclog_level_get() >= MDCLOG_DEBUG) {
614         checkAndPrint(&asn_DEF_E2SM_gNB_X2_actionDefinition, actDef, "E2SM_gNB_X2_actionDefinition_t", __func__);
615     }
616
617     size_t  len = encodebuff(ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_gNB_X2_actionDefinition,
618                              actDef,
619                              buffer,
620                              buffer_size);
621
622
623     if (mdclog_level_get() >= MDCLOG_INFO) {
624         uint8_t buf1[4096];
625         asn_enc_rval_t er1;
626         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_actionDefinition,
627                    actDef,
628                    buf1,
629                    4096);
630
631     }
632
633     return len;
634 }
635
636 size_t createE2SM_gNB_X2_indicationHeader(long direction,
637                                           Interface_ID_t *interfaceId,
638                                           uint8_t *timestamp, //can put NULL if size == 0
639                                           int size,
640                                           uint8_t *buffer,
641                                           size_t buffer_size) {
642     printEntry("E2SM_gNB_X2_indicationHeader_t", __func__);
643     if (direction < InterfaceDirection_incoming || direction > InterfaceDirection_outgoing) {
644         mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_indicationHeader_t direction = %ld, values are %d .. %d",
645                      direction, InterfaceDirection_incoming, InterfaceDirection_outgoing);
646         return -1;
647     }
648
649     E2SM_gNB_X2_indicationHeader_t *indiHead = calloc(1, sizeof(E2SM_gNB_X2_indicationHeader_t));
650     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_indicationHeader, indiHead);
651
652     indiHead->interfaceDirection = direction;
653     memcpy(&indiHead->interface_ID, interfaceId, sizeof(Interface_ID_t));
654     if (size > 0) {
655         indiHead->timestamp->size = size;
656         indiHead->timestamp->buf = calloc(1, sizeof(uint8_t) * size);
657         memcpy(indiHead->timestamp->buf, timestamp, size);
658     }
659
660     if (mdclog_level_get() >= MDCLOG_DEBUG) {
661         checkAndPrint(&asn_DEF_E2SM_gNB_X2_indicationHeader, indiHead, "E2SM_gNB_X2_indicationHeader_t", __func__);
662     }
663
664     size_t  len = encodebuff(ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_gNB_X2_indicationHeader,
665                              indiHead,
666                              buffer,
667                             buffer_size);
668
669     if (mdclog_level_get() >= MDCLOG_INFO) {
670         uint8_t buf1[4096];
671         asn_enc_rval_t er1;
672         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_indicationHeader,
673                    indiHead,
674                    buf1,
675                    4096);
676
677     }
678
679     return len;
680 }
681
682 size_t createE2SM_gNB_X2_indicationMessage(uint8_t *message, uint msgSize,
683                                                                      uint8_t *buffer,
684                                                                      size_t buffer_size) {
685     printEntry("E2SM_gNB_X2_indicationMessage_t", __func__);
686     if (msgSize <= 0) {
687         mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_indicationMessage_t failed messsage size =  %d", msgSize);
688         return -1;
689     }
690
691     E2SM_gNB_X2_indicationMessage_t *indicationMessage = calloc(1, sizeof(E2SM_gNB_X2_indicationMessage_t));
692     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_indicationMessage, indicationMessage);
693
694     indicationMessage->interfaceMessage.size = msgSize;
695     indicationMessage->interfaceMessage.buf = calloc(1, sizeof(uint8_t) * msgSize);
696     memcpy(indicationMessage->interfaceMessage.buf, message, msgSize);
697
698     if (mdclog_level_get() >= MDCLOG_DEBUG) {
699         checkAndPrint(&asn_DEF_E2SM_gNB_X2_indicationMessage, indicationMessage, "E2SM_gNB_X2_indicationMessage_t", __func__);
700     }
701
702     size_t  len = encodebuff(ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_gNB_X2_indicationMessage,
703                              indicationMessage,
704                              buffer,
705                              buffer_size);
706
707
708     if (mdclog_level_get() >= MDCLOG_INFO) {
709         uint8_t buf1[4096];
710         asn_enc_rval_t er1;
711         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_indicationMessage,
712                    indicationMessage,
713                    buf1,
714                    4096);
715
716     }
717
718     return len;
719 }
720
721
722 size_t createE2SM_gNB_X2_callProcessID(long callProcess_Id,
723                                                              uint8_t *buffer,
724                                                              size_t buffer_size) {
725     printEntry("E2SM_gNB_X2_callProcessID_t", __func__);
726     E2SM_gNB_X2_callProcessID_t *callProcessId = calloc(1, sizeof(E2SM_gNB_X2_callProcessID_t));
727     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_callProcessID, callProcessId);
728
729     callProcessId->callProcess_ID = callProcess_Id;
730
731     if (mdclog_level_get() >= MDCLOG_DEBUG) {
732         checkAndPrint(&asn_DEF_E2SM_gNB_X2_callProcessID, callProcessId, "E2SM_gNB_X2_indicationMessage_t", __func__);
733     }
734
735     size_t  len = encodebuff(ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_gNB_X2_callProcessID,
736                              callProcessId,
737                              buffer,
738                              buffer_size);
739
740
741     if (mdclog_level_get() >= MDCLOG_INFO) {
742         uint8_t buf1[4096];
743         asn_enc_rval_t er1;
744         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_callProcessID,
745                    callProcessId,
746                    buf1,
747                    4096);
748
749     }
750
751     return len;
752 }
753
754 size_t createE2SM_gNB_X2_controlHeader(Interface_ID_t *interfaceId, long direction,
755                                                              uint8_t *buffer,
756                                                              size_t buffer_size) {
757     printEntry("E2SM_gNB_X2_controlHeader_t", __func__);
758     if (direction < InterfaceDirection_incoming || direction > InterfaceDirection_outgoing) {
759         mdclog_write(MDCLOG_ERR, "E2SM_gNB_X2_controlHeader_t direction = %ld, values are %d .. %d",
760                      direction, InterfaceDirection_incoming, InterfaceDirection_outgoing);
761         return -1;
762     }
763     E2SM_gNB_X2_controlHeader_t *controlHeader = calloc(1, sizeof(E2SM_gNB_X2_controlHeader_t));
764     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_controlHeader, controlHeader);
765
766     memcpy(&controlHeader->interface_ID, interfaceId, sizeof(Interface_ID_t));
767     controlHeader->interfaceDirection = direction;
768
769     if (mdclog_level_get() >= MDCLOG_DEBUG) {
770         checkAndPrint(&asn_DEF_E2SM_gNB_X2_controlHeader, controlHeader, "E2SM_gNB_X2_controlHeader_t", __func__);
771     }
772
773     size_t  len = encodebuff(ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_gNB_X2_controlHeader,
774                              controlHeader,
775                              buffer,
776                              buffer_size);
777
778
779     if (mdclog_level_get() >= MDCLOG_INFO) {
780         uint8_t buf1[4096];
781         asn_enc_rval_t er1;
782         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_controlHeader,
783                    controlHeader,
784                    buf1,
785                    4096);
786
787     }
788
789     return len;
790 }
791
792
793 size_t createE2SM_gNB_X2_controlMessage(uint8_t *message, uint msgSize,
794                                                                uint8_t *buffer,
795                                                                size_t buffer_size) {
796     printEntry("E2SM_gNB_X2_controlMessage_t", __func__);
797     E2SM_gNB_X2_controlMessage_t *controlMsg = calloc(1, sizeof(E2SM_gNB_X2_controlMessage_t));
798     ASN_STRUCT_RESET(asn_DEF_E2SM_gNB_X2_controlMessage, controlMsg);
799
800     controlMsg->interfaceMessage.size = msgSize;
801     controlMsg->interfaceMessage.buf = calloc(1, sizeof(uint8_t) * msgSize);
802     memcpy(controlMsg->interfaceMessage.buf, message, msgSize);
803
804     if (mdclog_level_get() >= MDCLOG_DEBUG) {
805         checkAndPrint(&asn_DEF_E2SM_gNB_X2_controlMessage, controlMsg, "E2SM_gNB_X2_controlMessage_t", __func__);
806     }
807
808     size_t  len = encodebuff(ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_gNB_X2_controlMessage,
809                              controlMsg,
810                              buffer,
811                              buffer_size);
812
813
814     if (mdclog_level_get() >= MDCLOG_INFO) {
815         uint8_t buf1[4096];
816         asn_enc_rval_t er1;
817         encodebuff(ATS_BASIC_XER, &asn_DEF_E2SM_gNB_X2_controlMessage,
818                    controlMsg,
819                    buf1,
820                    4096);
821
822     }
823
824     return len;
825 }