78b853cfda2232adae94ff064935381f5c2ccb50
[ric-plt/e2.git] / RIC-E2-TERMINATION / TEST / T1 / E2Builder.h
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 12/10/19.
20 //
21
22 #ifndef E2_E2BUILDER_H
23 #define E2_E2BUILDER_H
24
25 #include <cstring>
26 #include <cstdio>
27 #include <cerrno>
28 #include <cstdlib>
29 #include <sys/types.h>
30 #include <error.h>
31 #include <mdclog/mdclog.h>
32 #include <algorithm>
33
34
35 #include <mdclog/mdclog.h>
36
37
38 #include "asn1cFiles/E2AP-PDU.h"
39 #include "asn1cFiles/InitiatingMessage.h"
40 #include "asn1cFiles/SuccessfulOutcome.h"
41 #include "asn1cFiles/UnsuccessfulOutcome.h"
42
43 #include "asn1cFiles/ProtocolIE-Field.h"
44
45 #include "asn1cFiles/FDD-Info.h"
46 #include "asn1cFiles/TDD-Info.h"
47 #include "asn1cFiles/Neighbour-Information.h"
48
49
50 #include "asn1cFiles/constr_TYPE.h"
51 #include "asn1cFiles/asn_constant.h"
52
53 using namespace std;
54
55 #define printEntry(type, function) \
56     if (mdclog_level_get() >= MDCLOG_DEBUG) { \
57         mdclog_write(MDCLOG_DEBUG, "start Test %s , %s", type, function); \
58     }
59
60
61 static void checkAndPrint(asn_TYPE_descriptor_t *typeDescriptor, void *data, char *dataType, const char *function) {
62     char errbuf[128]; /* Buffer for error message */
63     size_t errlen = sizeof(errbuf); /* Size of the buffer */
64     if (asn_check_constraints(typeDescriptor, data, errbuf, &errlen) != 0) {
65         mdclog_write(MDCLOG_ERR, "%s Constraint validation failed: %s", dataType, errbuf);
66     } else if (mdclog_level_get() >= MDCLOG_DEBUG) {
67         mdclog_write(MDCLOG_DEBUG, "%s successes function %s", dataType, function);
68     }
69 }
70
71 BIT_STRING_t *createBIT_STRING(int size, int unusedBits, uint8_t *data) {
72     printEntry("BIT_STRING_t", __func__)
73     auto *bitString = (BIT_STRING_t *)calloc(1, sizeof(BIT_STRING_t));
74     ASN_STRUCT_RESET(asn_DEF_BIT_STRING, bitString);
75     bitString->size = size;
76     bitString->bits_unused = unusedBits;
77     bitString->buf = (uint8_t *)calloc(1, size);
78     // set bits to zero
79     data[bitString->size - 1] = ((unsigned)(data[bitString->size - 1] >>
80             (unsigned)bitString->bits_unused) << (unsigned)bitString->bits_unused);
81     memcpy(bitString->buf, data, size);
82
83     if (mdclog_level_get() >= MDCLOG_DEBUG) {
84         checkAndPrint(&asn_DEF_BIT_STRING, bitString, (char *)"BIT_STRING_t", __func__);
85     }
86
87     return bitString;
88 }
89
90
91 OCTET_STRING_t *createOCTET_STRING(const unsigned char *data, int size) {
92     printEntry("OCTET_STRING_t", __func__)
93     auto *octs = (PLMN_Identity_t *)calloc(1, sizeof(PLMN_Identity_t));
94     ASN_STRUCT_RESET(asn_DEF_OCTET_STRING, octs);
95     octs->size = size;
96     octs->buf = (uint8_t *)calloc(1, size);
97     memcpy(octs->buf, data, size);
98
99     if (mdclog_level_get() >= MDCLOG_DEBUG) {
100         checkAndPrint(&asn_DEF_OCTET_STRING, octs, (char *)"OCTET_STRING_t", __func__);
101     }
102     return octs;
103 }
104
105
106 PLMN_Identity_t *createPLMN_ID(const unsigned char *data) {
107     printEntry("PLMN_Identity_t", __func__)
108     auto *plmnId = (PLMN_Identity_t *)calloc(1, sizeof(PLMN_Identity_t));
109     ASN_STRUCT_RESET(asn_DEF_PLMN_Identity, plmnId);
110     plmnId->size = 3;
111     plmnId->buf = (uint8_t *)calloc(1, 3);
112     memcpy(plmnId->buf, data, 3);
113
114     if (mdclog_level_get() >= MDCLOG_DEBUG) {
115         checkAndPrint(&asn_DEF_PLMN_Identity, plmnId, (char *)"PLMN_Identity_t", __func__);
116     }
117     return plmnId;
118 }
119
120 ENB_ID_t *createENB_ID(ENB_ID_PR enbType, unsigned char *data) {
121     printEntry("ENB_ID_t", __func__)
122     auto *enb = (ENB_ID_t *)calloc(1, sizeof(ENB_ID_t));
123     ASN_STRUCT_RESET(asn_DEF_ENB_ID, enb);
124
125     enb->present = enbType;
126
127     switch (enbType) {
128         case ENB_ID_PR_macro_eNB_ID: { // 20 bit 3 bytes
129             enb->choice.macro_eNB_ID.size = 3;
130             enb->choice.macro_eNB_ID.bits_unused = 4;
131
132             enb->present = ENB_ID_PR_macro_eNB_ID;
133
134             enb->choice.macro_eNB_ID.buf = (uint8_t *)calloc(1, enb->choice.macro_eNB_ID.size);
135             data[enb->choice.macro_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.macro_eNB_ID.size - 1] >>
136                     (unsigned)enb->choice.macro_eNB_ID.bits_unused) << (unsigned)enb->choice.macro_eNB_ID.bits_unused);
137             memcpy(enb->choice.macro_eNB_ID.buf, data, enb->choice.macro_eNB_ID.size);
138
139             break;
140         }
141         case ENB_ID_PR_home_eNB_ID: { // 28 bit 4 bytes
142             enb->choice.home_eNB_ID.size = 4;
143             enb->choice.home_eNB_ID.bits_unused = 4;
144             enb->present = ENB_ID_PR_home_eNB_ID;
145
146             enb->choice.home_eNB_ID.buf = (uint8_t *)calloc(1, enb->choice.home_eNB_ID.size);
147             data[enb->choice.home_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.home_eNB_ID.size - 1] >>
148                     (unsigned)enb->choice.home_eNB_ID.bits_unused) << (unsigned)enb->choice.home_eNB_ID.bits_unused);
149             memcpy(enb->choice.home_eNB_ID.buf, data, enb->choice.home_eNB_ID.size);
150             break;
151         }
152         case ENB_ID_PR_short_Macro_eNB_ID: { // 18 bit - 3 bytes
153             enb->choice.short_Macro_eNB_ID.size = 3;
154             enb->choice.short_Macro_eNB_ID.bits_unused = 6;
155             enb->present = ENB_ID_PR_short_Macro_eNB_ID;
156
157             enb->choice.short_Macro_eNB_ID.buf = (uint8_t *)calloc(1, enb->choice.short_Macro_eNB_ID.size);
158             data[enb->choice.short_Macro_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.short_Macro_eNB_ID.size - 1] >>
159                     (unsigned)enb->choice.short_Macro_eNB_ID.bits_unused) << (unsigned)enb->choice.short_Macro_eNB_ID.bits_unused);
160             memcpy(enb->choice.short_Macro_eNB_ID.buf, data, enb->choice.short_Macro_eNB_ID.size);
161             break;
162         }
163         case ENB_ID_PR_long_Macro_eNB_ID: { // 21
164             enb->choice.long_Macro_eNB_ID.size = 3;
165             enb->choice.long_Macro_eNB_ID.bits_unused = 3;
166             enb->present = ENB_ID_PR_long_Macro_eNB_ID;
167
168             enb->choice.long_Macro_eNB_ID.buf = (uint8_t *)calloc(1, enb->choice.long_Macro_eNB_ID.size);
169             data[enb->choice.long_Macro_eNB_ID.size - 1] = ((unsigned)(data[enb->choice.long_Macro_eNB_ID.size - 1] >>
170                     (unsigned)enb->choice.long_Macro_eNB_ID.bits_unused) << (unsigned)enb->choice.long_Macro_eNB_ID.bits_unused);
171             memcpy(enb->choice.long_Macro_eNB_ID.buf, data, enb->choice.long_Macro_eNB_ID.size);
172             break;
173         }
174         default:
175             free(enb);
176             return nullptr;
177     }
178
179     if (mdclog_level_get() >= MDCLOG_DEBUG) {
180         checkAndPrint(&asn_DEF_ENB_ID, enb, (char *)"ENB_ID_t", __func__);
181     }
182     return enb;
183 }
184
185 GlobalENB_ID_t *createGlobalENB_ID(PLMN_Identity_t *plmnIdentity, ENB_ID_t *enbId) {
186     printEntry("GlobalENB_ID_t", __func__)
187     auto *genbId = (GlobalENB_ID_t *)calloc(1, sizeof(GlobalENB_ID_t));
188     ASN_STRUCT_RESET(asn_DEF_GlobalENB_ID, genbId);
189     memcpy(&genbId->pLMN_Identity, plmnIdentity, sizeof(PLMN_Identity_t));
190     memcpy(&genbId->eNB_ID, enbId, sizeof(ENB_ID_t));
191
192     if (mdclog_level_get() >= MDCLOG_DEBUG) {
193         checkAndPrint(&asn_DEF_GlobalENB_ID, genbId, (char *)"GlobalENB_ID_t", __func__);
194     }
195     return genbId;
196 }
197
198
199 ECGI_t *CreateECGI(PLMN_Identity_t *plmnIdentity, BIT_STRING_t * eUtran) {
200     printEntry("ECGI_t", __func__)
201     auto *ecgi = (ECGI_t *)calloc(1, sizeof(ECGI_t));
202     ASN_STRUCT_RESET(asn_DEF_ECGI, ecgi);
203
204     memcpy(&ecgi->pLMN_Identity, plmnIdentity, sizeof(PLMN_Identity_t));
205     memcpy(&ecgi->eUTRANcellIdentifier, eUtran, sizeof(BIT_STRING_t));
206
207     if (mdclog_level_get() >= MDCLOG_DEBUG) {
208         checkAndPrint(&asn_DEF_ECGI, ecgi, (char *)"ECGI_t", __func__);
209     }
210     return ecgi;
211 }
212
213 //
214 //FDD-Info ::= SEQUENCE {
215 //        uL-EARFCN                                             EARFCN,
216 //        dL-EARFCN                                             EARFCN,
217 //        uL-Transmission-Bandwidth             Transmission-Bandwidth,
218 //        dL-Transmission-Bandwidth             Transmission-Bandwidth,
219 //        iE-Extensions                         ProtocolExtensionContainer { {FDD-Info-ExtIEs} } OPTIONAL,
220 //        ...
221 //}
222 //
223 //FDD-Info-ExtIEs X2AP-PROTOCOL-EXTENSION ::= {
224 //        { ID id-UL-EARFCNExtension                                            CRITICALITY reject      EXTENSION EARFCNExtension                                                                       PRESENCE optional}|
225 //        { ID id-DL-EARFCNExtension                                            CRITICALITY reject      EXTENSION EARFCNExtension                                                                       PRESENCE optional}|
226 //        { ID id-OffsetOfNbiotChannelNumberToDL-EARFCN CRITICALITY reject      EXTENSION OffsetOfNbiotChannelNumberToEARFCN            PRESENCE optional}|
227 //        { ID id-OffsetOfNbiotChannelNumberToUL-EARFCN CRITICALITY reject      EXTENSION OffsetOfNbiotChannelNumberToEARFCN            PRESENCE optional}|
228 //        { ID id-NRS-NSSS-PowerOffset                                  CRITICALITY ignore      EXTENSION NRS-NSSS-PowerOffset                                                  PRESENCE optional}|
229 //        { ID id-NSSS-NumOccasionDifferentPrecoder             CRITICALITY ignore      EXTENSION NSSS-NumOccasionDifferentPrecoder                     PRESENCE optional},
230 //        ...
231 //}
232
233 static FDD_Info_t *create_fdd(long dL_EARFCN,
234         long uL_EARFCN,
235         e_Transmission_Bandwidth ultb,
236         e_Transmission_Bandwidth dltb) {
237     printEntry("FDD_Info_t", __func__)
238     auto *fdd = (FDD_Info_t *)calloc(1, sizeof(FDD_Info_t));
239     ASN_STRUCT_RESET(asn_DEF_FDD_Info, fdd);
240
241     //EARFCN ::= INTEGER (0..maxEARFCN)
242
243     if (dL_EARFCN >= 0 && dL_EARFCN <= maxEARFCN) {
244         fdd->dL_EARFCN = dL_EARFCN;
245     } else {
246         fdd->dL_EARFCN = maxEARFCN;
247     }
248     if (uL_EARFCN >= 0 && uL_EARFCN <= maxEARFCN) {
249         fdd->uL_EARFCN = uL_EARFCN;
250     } else {
251         fdd->uL_EARFCN = maxEARFCN;
252     }
253
254     fdd->uL_Transmission_Bandwidth = ultb;
255     fdd->dL_Transmission_Bandwidth = dltb;
256
257     if (mdclog_level_get() >= MDCLOG_DEBUG) {
258         checkAndPrint(&asn_DEF_FDD_Info, fdd, (char *)"FDD_Info_t", __func__);
259     }
260
261     return fdd;
262 }
263
264 SpecialSubframe_Info_t *createSpecialSubframe_Info(e_CyclicPrefixDL eCyclicPrefixDl,
265         e_CyclicPrefixUL eCyclicPrefixUl,
266         e_SpecialSubframePatterns eSpecialSubframePatterns) {
267     printEntry("SpecialSubframe_Info_t", __func__)
268     auto *ssf = (SpecialSubframe_Info_t *)calloc(1, sizeof(SpecialSubframe_Info_t));
269     ASN_STRUCT_RESET(asn_DEF_SpecialSubframe_Info, ssf);
270
271     ssf->cyclicPrefixDL = eCyclicPrefixDl;
272     ssf->cyclicPrefixUL = eCyclicPrefixUl;
273     ssf->specialSubframePatterns = eSpecialSubframePatterns;
274
275     if (mdclog_level_get() >= MDCLOG_DEBUG) {
276         checkAndPrint(&asn_DEF_SpecialSubframe_Info, ssf, (char *)"SpecialSubframe_Info_t", __func__);
277     }
278     return ssf;
279 }
280
281 //TDD-Info ::= SEQUENCE {
282 //        eARFCN                                                        EARFCN,
283 //        transmission-Bandwidth                        Transmission-Bandwidth,
284 //        subframeAssignment                            SubframeAssignment,
285 //        specialSubframe-Info                  SpecialSubframe-Info,
286 //        iE-Extensions                                 ProtocolExtensionContainer { {TDD-Info-ExtIEs} } OPTIONAL,
287 //        ...
288 //}
289 //
290 //TDD-Info-ExtIEs X2AP-PROTOCOL-EXTENSION ::= {
291 //        { ID id-AdditionalSpecialSubframe-Info                        CRITICALITY ignore      EXTENSION AdditionalSpecialSubframe-Info                                PRESENCE optional}|
292 //        { ID id-eARFCNExtension                                                       CRITICALITY reject      EXTENSION EARFCNExtension                                                                       PRESENCE optional}|
293 //        { ID id-AdditionalSpecialSubframeExtension-Info       CRITICALITY ignore      EXTENSION AdditionalSpecialSubframeExtension-Info       PRESENCE optional}|
294 //        { ID id-OffsetOfNbiotChannelNumberToDL-EARFCN CRITICALITY reject      EXTENSION OffsetOfNbiotChannelNumberToEARFCN            PRESENCE optional}|
295 //        { ID id-NBIoT-UL-DL-AlignmentOffset                           CRITICALITY reject      EXTENSION NBIoT-UL-DL-AlignmentOffset                                   PRESENCE optional},
296 //        ...
297 //}
298
299 static TDD_Info_t *create_Tdd(long eARFCN,
300         e_Transmission_Bandwidth tb,
301         e_SubframeAssignment sfA,
302         SpecialSubframe_Info_t *ssfi) {
303     printEntry("TDD_Info_t", __func__)
304     auto *tdd = (TDD_Info_t *)calloc(1, sizeof(FDD_Info_t));
305     ASN_STRUCT_RESET(asn_DEF_TDD_Info, tdd);
306
307     if (eARFCN >= 0 && eARFCN <= maxEARFCN) {
308         tdd->eARFCN = eARFCN;
309     } else {
310         tdd->eARFCN = maxEARFCN;
311     }
312     tdd->transmission_Bandwidth = tb;
313     tdd->subframeAssignment = sfA;
314     memcpy(&tdd->specialSubframe_Info, ssfi, sizeof(SpecialSubframe_Info_t));
315
316     if (mdclog_level_get() >= MDCLOG_DEBUG) {
317         checkAndPrint(&asn_DEF_TDD_Info, tdd, (char *)"TDD_Info_t", __func__);
318     }
319     return tdd;
320 }
321
322 static EUTRA_Mode_Info_t *createEUTRA_Mode_Info_FDD(FDD_Info_t *fdd) {
323     printEntry("EUTRA_Mode_Info_t", __func__)
324     auto *eutraModeInfo = (EUTRA_Mode_Info_t *)calloc(1, sizeof(EUTRA_Mode_Info_t));
325     ASN_STRUCT_RESET(asn_DEF_EUTRA_Mode_Info, eutraModeInfo);
326
327     eutraModeInfo->present = EUTRA_Mode_Info_PR_fDD;
328     eutraModeInfo->choice.fDD = fdd;
329
330     if (mdclog_level_get() >= MDCLOG_DEBUG) {
331         checkAndPrint(&asn_DEF_EUTRA_Mode_Info, eutraModeInfo, (char *)"EUTRA_Mode_Info_t", __func__);
332     }
333     return eutraModeInfo;
334
335 }
336
337 static EUTRA_Mode_Info_t *createEUTRA_Mode_Info_TDD(TDD_Info_t *tdd) {
338     printEntry("EUTRA_Mode_Info_t", __func__)
339     auto *eutraModeInfo = (EUTRA_Mode_Info_t *)calloc(1, sizeof(EUTRA_Mode_Info_t));
340     ASN_STRUCT_RESET(asn_DEF_EUTRA_Mode_Info, eutraModeInfo);
341
342     eutraModeInfo->present = EUTRA_Mode_Info_PR_tDD;
343     eutraModeInfo->choice.tDD = tdd;
344
345     if (mdclog_level_get() >= MDCLOG_DEBUG) {
346         checkAndPrint(&asn_DEF_EUTRA_Mode_Info, eutraModeInfo, (char *)"EUTRA_Mode_Info_t", __func__);
347     }
348     return eutraModeInfo;
349
350 }
351
352 Neighbour_Information__Member *createNeighbour_Information__Member(ECGI_t *eCGI, long pci, long eARFCN) {
353     printEntry("Neighbour_Information__Member", __func__)
354     auto *nigborInformation = (Neighbour_Information__Member *)calloc(1, sizeof(Neighbour_Information__Member));
355     ASN_STRUCT_RESET(asn_DEF_Neighbour_Information, nigborInformation);
356
357     memcpy(&nigborInformation->eCGI, eCGI, sizeof(ECGI_t));
358     nigborInformation->pCI = pci;
359     nigborInformation->eARFCN = eARFCN;
360
361     if (mdclog_level_get() >= MDCLOG_DEBUG) {
362         checkAndPrint(&asn_DEF_Neighbour_Information, nigborInformation, (char *)"Neighbour_Information__Member", __func__);
363     }
364     return nigborInformation;
365 }
366
367 void buildNeighbour_InformationVector(Neighbour_Information_t *neighbourInformation, Neighbour_Information__Member *member) {
368     ASN_SEQUENCE_ADD(&neighbourInformation->list, member);
369 }
370
371 //ServedCell-Information ::= SEQUENCE {
372 //        pCI                                   PCI,
373 //        cellId                                ECGI,
374 //        tAC                                   TAC,
375 //        broadcastPLMNs                BroadcastPLMNs-Item,
376 //        eUTRA-Mode-Info               EUTRA-Mode-Info,
377 //        iE-Extensions         ProtocolExtensionContainer { {ServedCell-Information-ExtIEs} } OPTIONAL,
378 //        ...
379 //}
380 //
381 //ServedCell-Information-ExtIEs X2AP-PROTOCOL-EXTENSION ::= {
382 //        { ID id-Number-of-Antennaports                                CRITICALITY ignore      EXTENSION Number-of-Antennaports                                        PRESENCE optional}|
383 //        { ID id-PRACH-Configuration                                   CRITICALITY ignore      EXTENSION PRACH-Configuration                                           PRESENCE optional}|
384 //        { ID id-MBSFN-Subframe-Info                                   CRITICALITY ignore      EXTENSION MBSFN-Subframe-Infolist                               PRESENCE optional}|
385 //        { ID id-CSG-Id                                                                CRITICALITY ignore      EXTENSION CSG-Id                                                                        PRESENCE optional}|
386 //        { ID id-MBMS-Service-Area-List                                CRITICALITY ignore      EXTENSION MBMS-Service-Area-Identity-List               PRESENCE optional}|
387 //        { ID id-MultibandInfoList                                     CRITICALITY ignore      EXTENSION MultibandInfoList                                                     PRESENCE optional}|
388 //        { ID id-FreqBandIndicatorPriority                     CRITICALITY ignore      EXTENSION FreqBandIndicatorPriority                             PRESENCE optional}|
389 //        { ID id-BandwidthReducedSI                                    CRITICALITY ignore      EXTENSION BandwidthReducedSI                                            PRESENCE optional}|
390 //        { ID id-ProtectedEUTRAResourceIndication      CRITICALITY ignore      EXTENSION ProtectedEUTRAResourceIndication      PRESENCE optional}|
391 //        { ID id-BPLMN-ID-Info-EUTRA                                   CRITICALITY ignore      EXTENSION BPLMN-ID-Info-EUTRA                                           PRESENCE optional},
392 //        ...
393 //}
394
395 /**
396  *
397  * @param pci
398  * @param cellId
399  * @param tac
400  * @param broadcastPLMNs
401  * @param eutranModeInfo
402  * @return
403  */
404 ServedCell_Information_t *createServedCellInfo(long pci,
405         ECGI_t *cellId,
406         TAC_t *tac,
407         vector<PLMN_Identity_t> &broadcastPLMNs,
408         EUTRA_Mode_Info_t *eutranModeInfo) {
409
410     printEntry("ServedCell_Information_t", __func__)
411     auto servedCellinfo = (ServedCell_Information_t *)calloc(1, sizeof(ServedCell_Information_t));
412     ASN_STRUCT_RESET(asn_DEF_ServedCell_Information, servedCellinfo);
413
414     servedCellinfo->pCI = pci;
415     memcpy(&servedCellinfo->cellId, cellId, sizeof(ECGI_t));
416     memcpy(&servedCellinfo->tAC, tac, sizeof(TAC_t));
417
418     for (auto v : broadcastPLMNs) {
419         ASN_SEQUENCE_ADD(&servedCellinfo->broadcastPLMNs.list, &v);
420     }
421
422     memcpy(&servedCellinfo->eUTRA_Mode_Info, eutranModeInfo, sizeof(EUTRA_Mode_Info_t));
423
424     if (mdclog_level_get() >= MDCLOG_DEBUG) {
425         checkAndPrint(&asn_DEF_ServedCell_Information, servedCellinfo, (char *)"ServedCell_Information_t", __func__);
426     }
427
428     return servedCellinfo;
429 }
430
431
432 ServedCells__Member *createServedCellsMember(ServedCell_Information_t *servedCellInfo, Neighbour_Information_t *neighbourInformation) {
433     printEntry("ServedCells__Member", __func__)
434     auto servedCellMember = (ServedCells__Member *)calloc(1, sizeof(ServedCells__Member));
435
436     memcpy(&servedCellMember->servedCellInfo, servedCellInfo, sizeof(ServedCell_Information_t));
437     servedCellMember->neighbour_Info = neighbourInformation;
438
439     if (mdclog_level_get() >= MDCLOG_DEBUG) {
440         checkAndPrint(&asn_DEF_ServedCells, servedCellMember, (char *)"ServedCells__Member", __func__);
441     }
442
443     return servedCellMember;
444 }
445
446 void buildServedCells(ServedCells_t *servedCells, ServedCells__Member *member) {
447     ASN_SEQUENCE_ADD(&servedCells->list, member);
448 }
449
450
451 static void buildInitiatingMessagePDU(E2AP_PDU_t &pdu, InitiatingMessage_t *initMsg) {
452     pdu.present = E2AP_PDU_PR_initiatingMessage;
453     pdu.choice.initiatingMessage = initMsg;
454 }
455
456 template<typename T>
457 static void buildInitMsg(InitiatingMessage_t &initMsg,
458                          InitiatingMessage__value_PR present,
459                          ProcedureCode_t procedureCode,
460                          Criticality_t criticality,
461                          T *value) {
462     initMsg.value.present = present;
463     initMsg.procedureCode = procedureCode;
464     initMsg.criticality = criticality;
465
466     switch (present) {
467         case InitiatingMessage__value_PR_RICsubscriptionRequest: {
468             memcpy(&initMsg.value.choice.RICsubscriptionRequest, value, sizeof(*value));
469             break;
470         }
471         case InitiatingMessage__value_PR_RICsubscriptionDeleteRequest: {
472             memcpy(&initMsg.value.choice.RICsubscriptionDeleteRequest, value, sizeof(*value));
473             break;
474         }
475         case InitiatingMessage__value_PR_RICserviceUpdate: {
476             memcpy(&initMsg.value.choice.RICserviceUpdate, value, sizeof(*value));
477             break;
478         }
479         case InitiatingMessage__value_PR_RICcontrolRequest: {
480             memcpy(&initMsg.value.choice.RICcontrolRequest, value, sizeof(*value));
481             break;
482         }
483         case InitiatingMessage__value_PR_X2SetupRequest: {
484             memcpy(&initMsg.value.choice.X2SetupRequest, value, sizeof(*value));
485             break;
486         }
487         case InitiatingMessage__value_PR_ENDCX2SetupRequest: {
488             memcpy(&initMsg.value.choice.ENDCX2SetupRequest, value, sizeof(*value));
489             break;
490         }
491         case InitiatingMessage__value_PR_ResourceStatusRequest: {
492             memcpy(&initMsg.value.choice.ResourceStatusRequest, value, sizeof(*value));
493             break;
494         }
495         case InitiatingMessage__value_PR_ENBConfigurationUpdate: {
496             memcpy(&initMsg.value.choice.ENBConfigurationUpdate, value, sizeof(*value));
497             break;
498         }
499         case InitiatingMessage__value_PR_ENDCConfigurationUpdate: {
500             memcpy(&initMsg.value.choice.ENDCConfigurationUpdate, value, sizeof(*value));
501             break;
502         }
503         case InitiatingMessage__value_PR_ResetRequest: {
504             memcpy(&initMsg.value.choice.ResetRequest, value, sizeof(*value));
505             break;
506         }
507         case InitiatingMessage__value_PR_RICindication: {
508             memcpy(&initMsg.value.choice.RICindication, value, sizeof(*value));
509             break;
510         }
511         case InitiatingMessage__value_PR_RICserviceQuery: {
512             memcpy(&initMsg.value.choice.RICserviceQuery, value, sizeof(*value));
513             break;
514         }
515         case InitiatingMessage__value_PR_LoadInformation: {
516             memcpy(&initMsg.value.choice.LoadInformation, value, sizeof(*value));
517             break;
518         }
519         case InitiatingMessage__value_PR_GNBStatusIndication: {
520             memcpy(&initMsg.value.choice.GNBStatusIndication, value, sizeof(*value));
521             break;
522         }
523         case InitiatingMessage__value_PR_ResourceStatusUpdate: {
524             memcpy(&initMsg.value.choice.ResourceStatusUpdate, value, sizeof(*value));
525             break;
526         }
527         case InitiatingMessage__value_PR_ErrorIndication: {
528             memcpy(&initMsg.value.choice.ErrorIndication, value, sizeof(*value));
529             break;
530         }
531         case InitiatingMessage__value_PR_NOTHING:
532         default : {
533             break;
534         }
535     }
536 }
537
538 static void buildSuccsesfulMessagePDU(E2AP_PDU_t &pdu, SuccessfulOutcome_t *succMsg) {
539     pdu.present = E2AP_PDU_PR_successfulOutcome;
540     pdu.choice.successfulOutcome = succMsg;
541 }
542
543 template<typename T>
544 static void buildSuccMsg(SuccessfulOutcome_t &succMsg,
545                          SuccessfulOutcome__value_PR present,
546                          ProcedureCode_t procedureCode,
547                          Criticality_t criticality,
548                          T *value) {
549     succMsg.value.present = present;
550     succMsg.procedureCode = procedureCode;
551     succMsg.criticality = criticality;
552
553     switch (present) {
554         case SuccessfulOutcome__value_PR_RICsubscriptionResponse: {
555             memcpy(&succMsg.value.choice.RICsubscriptionResponse, value, sizeof(*value));
556             break;
557         }
558         case SuccessfulOutcome__value_PR_RICsubscriptionDeleteResponse: {
559             memcpy(&succMsg.value.choice.RICsubscriptionDeleteResponse, value, sizeof(*value));
560             break;
561         }
562         case SuccessfulOutcome__value_PR_RICserviceUpdateAcknowledge: {
563             memcpy(&succMsg.value.choice.RICserviceUpdateAcknowledge, value, sizeof(*value));
564             break;
565         }
566         case SuccessfulOutcome__value_PR_RICcontrolAcknowledge: {
567             memcpy(&succMsg.value.choice.RICcontrolAcknowledge, value, sizeof(*value));
568             break;
569         }
570         case SuccessfulOutcome__value_PR_X2SetupResponse: {
571             memcpy(&succMsg.value.choice.X2SetupResponse, value, sizeof(*value));
572             break;
573         }
574         case SuccessfulOutcome__value_PR_ENDCX2SetupResponse: {
575             memcpy(&succMsg.value.choice.ENDCX2SetupResponse, value, sizeof(*value));
576             break;
577         }
578         case SuccessfulOutcome__value_PR_ResourceStatusResponse: {
579             memcpy(&succMsg.value.choice.ResourceStatusResponse, value, sizeof(*value));
580             break;
581         }
582         case SuccessfulOutcome__value_PR_ENBConfigurationUpdateAcknowledge: {
583             memcpy(&succMsg.value.choice.ENBConfigurationUpdateAcknowledge, value, sizeof(*value));
584             break;
585         }
586         case SuccessfulOutcome__value_PR_ENDCConfigurationUpdateAcknowledge: {
587             memcpy(&succMsg.value.choice.ENDCConfigurationUpdateAcknowledge, value, sizeof(*value));
588             break;
589         }
590         case SuccessfulOutcome__value_PR_ResetResponse: {
591             memcpy(&succMsg.value.choice.ResetResponse, value, sizeof(*value));
592             break;
593         }
594         case SuccessfulOutcome__value_PR_NOTHING:
595         default:
596             break;
597     }
598 }
599
600
601 static void buildUnSucssesfullMessagePDU(E2AP_PDU_t &pdu, UnsuccessfulOutcome_t *unSuccMsg) {
602     pdu.present = E2AP_PDU_PR_unsuccessfulOutcome;
603     pdu.choice.unsuccessfulOutcome = unSuccMsg;
604 }
605
606 template<typename T>
607 static void buildUnSuccMsg(UnsuccessfulOutcome_t &unSuccMsg,
608                            UnsuccessfulOutcome__value_PR present,
609                            ProcedureCode_t procedureCode,
610                            Criticality_t criticality,
611                            T *value) {
612     unSuccMsg.value.present = present;
613     unSuccMsg.procedureCode = procedureCode;
614     unSuccMsg.criticality = criticality;
615
616     switch (present) {
617         case UnsuccessfulOutcome__value_PR_RICsubscriptionFailure: {
618             memcpy(&unSuccMsg.value.choice.RICsubscriptionFailure, value, sizeof(*value));
619             break;
620         }
621         case UnsuccessfulOutcome__value_PR_RICsubscriptionDeleteFailure: {
622             memcpy(&unSuccMsg.value.choice.RICsubscriptionDeleteFailure, value, sizeof(*value));
623             break;
624         }
625         case UnsuccessfulOutcome__value_PR_RICserviceUpdateFailure: {
626             memcpy(&unSuccMsg.value.choice.RICserviceUpdateFailure, value, sizeof(*value));
627             break;
628         }
629         case UnsuccessfulOutcome__value_PR_RICcontrolFailure: {
630             memcpy(&unSuccMsg.value.choice.RICcontrolFailure, value, sizeof(*value));
631             break;
632         }
633         case UnsuccessfulOutcome__value_PR_X2SetupFailure: {
634             memcpy(&unSuccMsg.value.choice.X2SetupFailure, value, sizeof(*value));
635             break;
636         }
637         case UnsuccessfulOutcome__value_PR_ENDCX2SetupFailure: {
638             memcpy(&unSuccMsg.value.choice.ENDCX2SetupFailure, value, sizeof(*value));
639             break;
640         }
641         case UnsuccessfulOutcome__value_PR_ResourceStatusFailure: {
642             memcpy(&unSuccMsg.value.choice.ResourceStatusFailure, value, sizeof(*value));
643             break;
644         }
645         case UnsuccessfulOutcome__value_PR_ENBConfigurationUpdateFailure: {
646             memcpy(&unSuccMsg.value.choice.ENBConfigurationUpdateFailure, value, sizeof(*value));
647             break;
648         }
649         case UnsuccessfulOutcome__value_PR_ENDCConfigurationUpdateFailure: {
650             memcpy(&unSuccMsg.value.choice.ENDCConfigurationUpdateFailure, value, sizeof(*value));
651             break;
652         }
653         case UnsuccessfulOutcome__value_PR_NOTHING:
654         default:
655             break;
656     }
657 }
658
659
660 static void createPLMN_ID(PLMN_Identity_t &plmnId, const unsigned char *data) {
661     //printEntry("PLMN_Identity_t", __func__)
662     //PLMN_Identity_t *plmnId = calloc(1, sizeof(PLMN_Identity_t));
663     ASN_STRUCT_RESET(asn_DEF_PLMN_Identity, &plmnId);
664     plmnId.size = 3;
665     plmnId.buf = (uint8_t *) calloc(1, 3);
666     memcpy(plmnId.buf, data, 3);
667
668     if (mdclog_level_get() >= MDCLOG_DEBUG) {
669         checkAndPrint(&asn_DEF_PLMN_Identity, &plmnId, (char *) "PLMN_Identity_t", __func__);
670     }
671
672 }
673
674 static void createENB_ID(ENB_ID_t &enb, ENB_ID_PR enbType, unsigned char *data) {
675     //printEntry("ENB_ID_t", __func__)
676     ASN_STRUCT_RESET(asn_DEF_ENB_ID, &enb);
677     enb.present = enbType;
678     switch (enbType) {
679         case ENB_ID_PR_macro_eNB_ID: { // 20 bit 3 bytes
680             enb.choice.macro_eNB_ID.size = 3;
681             enb.choice.macro_eNB_ID.bits_unused = 4;
682
683             enb.present = ENB_ID_PR_macro_eNB_ID;
684
685             enb.choice.macro_eNB_ID.buf = (uint8_t *) calloc(1, enb.choice.macro_eNB_ID.size);
686             data[enb.choice.macro_eNB_ID.size - 1] = ((unsigned) (data[enb.choice.macro_eNB_ID.size - 1]
687                     >> (unsigned) enb.choice.macro_eNB_ID.bits_unused)
688                     << (unsigned) enb.choice.macro_eNB_ID.bits_unused);
689             memcpy(enb.choice.macro_eNB_ID.buf, data, enb.choice.macro_eNB_ID.size);
690
691             break;
692         }
693         case ENB_ID_PR_home_eNB_ID: { // 28 bit 4 bytes
694             enb.choice.home_eNB_ID.size = 4;
695             enb.choice.home_eNB_ID.bits_unused = 4;
696             enb.present = ENB_ID_PR_home_eNB_ID;
697
698             enb.choice.home_eNB_ID.buf = (uint8_t *) calloc(1, enb.choice.home_eNB_ID.size);
699             data[enb.choice.home_eNB_ID.size - 1] = ((unsigned) (data[enb.choice.home_eNB_ID.size - 1]
700                     >> (unsigned) enb.choice.home_eNB_ID.bits_unused)
701                     << (unsigned) enb.choice.home_eNB_ID.bits_unused);
702             memcpy(enb.choice.home_eNB_ID.buf, data, enb.choice.home_eNB_ID.size);
703             break;
704         }
705         case ENB_ID_PR_short_Macro_eNB_ID: { // 18 bit - 3 bytes
706             enb.choice.short_Macro_eNB_ID.size = 3;
707             enb.choice.short_Macro_eNB_ID.bits_unused = 6;
708             enb.present = ENB_ID_PR_short_Macro_eNB_ID;
709
710             enb.choice.short_Macro_eNB_ID.buf = (uint8_t *) calloc(1, enb.choice.short_Macro_eNB_ID.size);
711             data[enb.choice.short_Macro_eNB_ID.size - 1] = ((unsigned) (data[enb.choice.short_Macro_eNB_ID.size - 1]
712                     >> (unsigned) enb.choice.short_Macro_eNB_ID.bits_unused)
713                     << (unsigned) enb.choice.short_Macro_eNB_ID.bits_unused);
714             memcpy(enb.choice.short_Macro_eNB_ID.buf, data, enb.choice.short_Macro_eNB_ID.size);
715             break;
716         }
717         case ENB_ID_PR_long_Macro_eNB_ID: { // 21
718             enb.choice.long_Macro_eNB_ID.size = 3;
719             enb.choice.long_Macro_eNB_ID.bits_unused = 3;
720             enb.present = ENB_ID_PR_long_Macro_eNB_ID;
721
722             enb.choice.long_Macro_eNB_ID.buf = (uint8_t *) calloc(1, enb.choice.long_Macro_eNB_ID.size);
723             data[enb.choice.long_Macro_eNB_ID.size - 1] = ((unsigned) (data[enb.choice.long_Macro_eNB_ID.size - 1]
724                     >> (unsigned) enb.choice.long_Macro_eNB_ID.bits_unused)
725                     << (unsigned) enb.choice.long_Macro_eNB_ID.bits_unused);
726             memcpy(enb.choice.long_Macro_eNB_ID.buf, data, enb.choice.long_Macro_eNB_ID.size);
727             break;
728         }
729         default:
730             break;
731     }
732
733     if (mdclog_level_get() >= MDCLOG_DEBUG) {
734         checkAndPrint(&asn_DEF_ENB_ID, &enb, (char *) "ENB_ID_t", __func__);
735     }
736 }
737
738
739 static void buildGlobalENB_ID(GlobalENB_ID_t *gnbId,
740                               const unsigned char *gnbData,
741                               ENB_ID_PR enbType,
742                               unsigned char *enbData) {
743     createPLMN_ID(gnbId->pLMN_Identity, gnbData);
744     createENB_ID(gnbId->eNB_ID, enbType, enbData);
745     if (mdclog_level_get() >= MDCLOG_DEBUG) {
746         checkAndPrint(&asn_DEF_GlobalENB_ID, gnbId, (char *) "GlobalENB_ID_t", __func__);
747     }
748 }
749
750 #endif //E2_E2BUILDER_H