a159f98d580930f1d8083eafc6bcfb28792a03e2
[ric-plt/e2mgr.git] / E2Manager / asn1codec / src / x2setup_request_wrapper.c
1 /*
2  *
3  * Copyright 2019 AT&T Intellectual Property
4  * Copyright 2019 Nokia
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
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  *
18  */
19
20 #include <string.h>
21 #include <errno.h>
22 #undef NDEBUG
23 #include <assert.h>
24 #include <asn_application.h>
25 #include <E2AP-PDU.h>
26 #include <ProcedureCode.h>
27 #include <InitiatingMessage.h>
28 #include <X2SetupRequest.h>
29 #include <GlobalENB-ID.h>
30 #include <PLMN-Identity.h>
31 #include <ENB-ID.h>
32 #include <FDD-Info.h>
33 #include <ServedCells.h>
34 #include <ProtocolIE-ID.h>
35 #include <ProtocolIE-Field.h>
36 #include <x2setup_request_wrapper.h>
37
38 static void assignPLMN_Identity (PLMN_Identity_t *pLMN_Identity, uint8_t const* pLMNId);
39 static void assignENB_ID(GlobalENB_ID_t *globalENB_ID,uint8_t const* eNBId, unsigned int bitqty);
40 static void assignServedCell_Information(ServedCell_Information_t *servedCell_Information,uint8_t const* pLMN_Identity, uint8_t const* eNBId, unsigned int bitqty,uint8_t const *ric_flag);
41
42 /*
43  * Build and pack X2 setup request.
44  * Abort the process on allocation failure.
45  *  packed_buf_size - in: size of packed_buf; out: number of chars used.
46  */
47
48 bool
49 build_pack_x2setup_request(
50                 uint8_t const* pLMN_Identity, uint8_t const* eNBId, unsigned int bitqty /*18, 20, 21, 28*/, uint8_t const *ric_flag,
51                 size_t* packed_buf_size, unsigned char* packed_buf,size_t err_buf_size, char* err_buf
52 )
53 {
54         return build_pack_x2setup_request_aux(
55                         pLMN_Identity, eNBId, bitqty, ric_flag,
56                         packed_buf_size, packed_buf,err_buf_size,err_buf,ATS_ALIGNED_BASIC_PER);
57
58 }
59
60 bool
61 build_pack_x2setup_request_aux(
62                 uint8_t const* pLMN_Identity, uint8_t const* eNBId, unsigned int bitqty /*18, 20, 21, 28*/, uint8_t const *ric_flag,
63                 size_t* packed_buf_size, unsigned char* packed_buf,size_t err_buf_size, char* err_buf,enum asn_transfer_syntax syntax
64 )
65 {
66         bool rc = true;
67         E2AP_PDU_t *pdu = calloc(1, sizeof(E2AP_PDU_t));
68         InitiatingMessage_t *initiatingMessage = calloc(1, sizeof(InitiatingMessage_t));
69         X2SetupRequest_t *x2SetupRequest;
70
71     assert(pdu != 0);
72     assert(initiatingMessage != 0);
73
74
75     pdu->present = E2AP_PDU_PR_initiatingMessage;
76     pdu->choice.initiatingMessage = initiatingMessage;
77
78     initiatingMessage->procedureCode = ProcedureCode_id_x2Setup;
79     initiatingMessage->criticality = Criticality_reject;
80     initiatingMessage->value.present = InitiatingMessage__value_PR_X2SetupRequest;
81     x2SetupRequest = &initiatingMessage->value.choice.X2SetupRequest;
82
83     X2SetupRequest_IEs_t *globalENB_ID_ie = calloc(1, sizeof(X2SetupRequest_IEs_t));
84     assert(globalENB_ID_ie != 0);
85     ASN_SEQUENCE_ADD(&x2SetupRequest->protocolIEs, globalENB_ID_ie);
86
87     globalENB_ID_ie->id = ProtocolIE_ID_id_GlobalENB_ID;
88     globalENB_ID_ie->criticality = Criticality_reject;
89     globalENB_ID_ie->value.present = X2SetupRequest_IEs__value_PR_GlobalENB_ID;
90         GlobalENB_ID_t *globalENB_ID = &globalENB_ID_ie->value.choice.GlobalENB_ID;
91
92         assignPLMN_Identity(&globalENB_ID->pLMN_Identity, pLMN_Identity);
93         assignENB_ID(globalENB_ID, eNBId, bitqty);
94
95     X2SetupRequest_IEs_t *servedCells_ie = calloc(1, sizeof(X2SetupRequest_IEs_t));
96     assert(servedCells_ie != 0);
97     ASN_SEQUENCE_ADD(&x2SetupRequest->protocolIEs, servedCells_ie);
98
99     servedCells_ie->id = ProtocolIE_ID_id_ServedCells;
100     servedCells_ie->criticality = Criticality_reject;
101     servedCells_ie->value.present = X2SetupRequest_IEs__value_PR_ServedCells;
102
103     ServedCells__Member *servedCells__Member = calloc(1,sizeof(ServedCells__Member));
104     assert(servedCells__Member !=0);
105     ASN_SEQUENCE_ADD(&servedCells_ie->value.choice.ServedCells, servedCells__Member);
106
107     assignServedCell_Information(&servedCells__Member->servedCellInfo, pLMN_Identity,eNBId, bitqty,ric_flag);
108
109     rc = pack_pdu_aux(pdu, packed_buf_size, packed_buf,err_buf_size, err_buf,syntax);
110
111     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
112     return rc;
113 }
114
115 static void assignPLMN_Identity (PLMN_Identity_t *pLMN_Identity, uint8_t const* pLMNId)
116 {
117         pLMN_Identity->size = pLMN_Identity_size;
118         pLMN_Identity->buf = calloc(1,pLMN_Identity->size);
119         assert(pLMN_Identity->buf != 0);
120         memcpy(pLMN_Identity->buf, pLMNId, pLMN_Identity->size);
121 }
122
123 /*
124  * Calculate and assign the value of ENB_ID.
125  * Abort the process on allocation failure.
126  */
127 static void assignENB_ID(GlobalENB_ID_t *globalENB_ID,uint8_t const* eNBId, unsigned int bitqty)
128 {
129         size_t size_in_bytes = (bitqty / 8) + ((bitqty % 8) > 0);
130         int unused_bits = 8 - (bitqty % 8);
131         uint8_t *tbuf;
132         switch (bitqty){
133         case shortMacro_eNB_ID_size:
134                 globalENB_ID->eNB_ID.present = ENB_ID_PR_short_Macro_eNB_ID;
135                 globalENB_ID->eNB_ID.choice.short_Macro_eNB_ID.size = size_in_bytes;
136                 globalENB_ID->eNB_ID.choice.short_Macro_eNB_ID.bits_unused = unused_bits;
137                 tbuf = globalENB_ID->eNB_ID.choice.short_Macro_eNB_ID.buf = calloc(1, size_in_bytes);
138                 assert(globalENB_ID->eNB_ID.choice.short_Macro_eNB_ID.buf  != 0);
139                 memcpy(globalENB_ID->eNB_ID.choice.short_Macro_eNB_ID.buf,eNBId, size_in_bytes) ;
140                 tbuf[size_in_bytes - 1] <<= unused_bits;
141                 break;
142         case macro_eNB_ID_size:
143                 globalENB_ID->eNB_ID.present =ENB_ID_PR_macro_eNB_ID;
144                 globalENB_ID->eNB_ID.choice.macro_eNB_ID.size = size_in_bytes;
145                 globalENB_ID->eNB_ID.choice.macro_eNB_ID.bits_unused = unused_bits;
146                 tbuf = globalENB_ID->eNB_ID.choice.macro_eNB_ID.buf = calloc(1, size_in_bytes);
147                 assert(globalENB_ID->eNB_ID.choice.macro_eNB_ID.buf != 0);
148                 memcpy(globalENB_ID->eNB_ID.choice.macro_eNB_ID.buf,eNBId,size_in_bytes);
149                 tbuf[size_in_bytes - 1] <<= unused_bits;
150                 break;
151         case longMacro_eNB_ID_size:
152                 globalENB_ID->eNB_ID.present =ENB_ID_PR_long_Macro_eNB_ID;
153                 globalENB_ID->eNB_ID.choice.long_Macro_eNB_ID.size = size_in_bytes;
154                 globalENB_ID->eNB_ID.choice.long_Macro_eNB_ID.bits_unused = unused_bits;
155                 tbuf = globalENB_ID->eNB_ID.choice.long_Macro_eNB_ID.buf = calloc(1, size_in_bytes);
156                 assert(globalENB_ID->eNB_ID.choice.long_Macro_eNB_ID.buf != 0);
157                 memcpy(globalENB_ID->eNB_ID.choice.long_Macro_eNB_ID.buf,eNBId,size_in_bytes);
158                 tbuf[size_in_bytes - 1] <<= unused_bits;
159                 break;
160         case home_eNB_ID_size:
161                 globalENB_ID->eNB_ID.present = ENB_ID_PR_home_eNB_ID;
162                 globalENB_ID->eNB_ID.choice.home_eNB_ID.size = size_in_bytes;
163                 globalENB_ID->eNB_ID.choice.home_eNB_ID.bits_unused =unused_bits;
164                 tbuf = globalENB_ID->eNB_ID.choice.home_eNB_ID.buf = calloc(1,size_in_bytes);
165                 assert(globalENB_ID->eNB_ID.choice.home_eNB_ID.buf != 0);
166                 memcpy(globalENB_ID->eNB_ID.choice.home_eNB_ID.buf,eNBId,size_in_bytes);
167                 tbuf[size_in_bytes - 1] <<= unused_bits;
168                 break;
169         default:
170                 break;
171         }
172
173 }
174
175 /*
176  * Calculate and assign the value of ServedCell_Information.
177  * Abort the process on allocation failure.
178  */
179 static void assignServedCell_Information(
180                 ServedCell_Information_t *servedCell_Information,
181                 uint8_t const* pLMN_Identity,
182                 uint8_t const* eNBId,
183                 unsigned int bitqty,
184                 uint8_t const *ric_flag)
185 {
186         size_t size_in_bytes =  (eUTRANcellIdentifier_size / 8) + ((eUTRANcellIdentifier_size % 8) > 0);
187         int unused_bits = 8 - (eUTRANcellIdentifier_size % 8);
188         size_t bitqty_size_in_bytes = (bitqty / 8) + ((bitqty % 8) > 0);
189         int bitqty_unused_bits = 8 - (bitqty % 8);
190
191         servedCell_Information->pCI = 503;
192         assignPLMN_Identity(&servedCell_Information->cellId.pLMN_Identity, pLMN_Identity);
193
194         servedCell_Information->cellId.eUTRANcellIdentifier.size = size_in_bytes;
195         servedCell_Information->cellId.eUTRANcellIdentifier.bits_unused = unused_bits;
196         servedCell_Information->cellId.eUTRANcellIdentifier.buf = calloc(1,servedCell_Information->cellId.eUTRANcellIdentifier.size);
197         assert(servedCell_Information->cellId.eUTRANcellIdentifier.buf != 0);
198         memcpy(servedCell_Information->cellId.eUTRANcellIdentifier.buf, eNBId, bitqty_size_in_bytes);
199         if (bitqty < eUTRANcellIdentifier_size) {
200                 servedCell_Information->cellId.eUTRANcellIdentifier.buf[bitqty_size_in_bytes - 1] <<= bitqty_unused_bits;
201         } else {
202                 servedCell_Information->cellId.eUTRANcellIdentifier.buf[size_in_bytes - 1] <<= unused_bits;
203         }
204
205         servedCell_Information->tAC.size = 2;
206         servedCell_Information->tAC.buf = calloc(1,servedCell_Information->tAC.size);
207         assert(servedCell_Information->tAC.buf != 0);
208
209
210         PLMN_Identity_t *broadcastPLMN_Identity = calloc(1, sizeof(PLMN_Identity_t));
211         assert(broadcastPLMN_Identity != 0);
212         ASN_SEQUENCE_ADD(&servedCell_Information->broadcastPLMNs, broadcastPLMN_Identity);
213
214         assignPLMN_Identity(broadcastPLMN_Identity,ric_flag);
215
216         servedCell_Information->eUTRA_Mode_Info.present= EUTRA_Mode_Info_PR_fDD;
217         servedCell_Information->eUTRA_Mode_Info.choice.fDD = calloc(1, sizeof(FDD_Info_t));
218         assert(servedCell_Information->eUTRA_Mode_Info.choice.fDD != 0);
219         servedCell_Information->eUTRA_Mode_Info.choice.fDD->uL_EARFCN = 0;
220         servedCell_Information->eUTRA_Mode_Info.choice.fDD->dL_EARFCN = 0;
221         servedCell_Information->eUTRA_Mode_Info.choice.fDD->uL_Transmission_Bandwidth = Transmission_Bandwidth_bw6;
222         servedCell_Information->eUTRA_Mode_Info.choice.fDD->dL_Transmission_Bandwidth = Transmission_Bandwidth_bw15;
223 }
224
225 /* Build and pack X2 setup request.
226  * Abort the process on allocation failure.
227  * packed_buf_size - in: size of packed_buf; out: number of chars used.
228  */
229 bool
230 build_pack_endc_x2setup_request(
231                 uint8_t const* pLMN_Identity, uint8_t const* eNBId, unsigned int bitqty /*18, 20, 21, 28*/, uint8_t const *ric_flag,
232                 size_t* packed_buf_size, unsigned char* packed_buf,size_t err_buf_size, char* err_buf
233 )
234 {
235         return build_pack_endc_x2setup_request_aux(
236                         pLMN_Identity, eNBId, bitqty, ric_flag,
237                         packed_buf_size, packed_buf,err_buf_size,  err_buf,ATS_ALIGNED_BASIC_PER
238         );
239 }
240
241 bool
242 build_pack_endc_x2setup_request_aux(
243                 uint8_t const* pLMN_Identity, uint8_t const* eNBId, unsigned int bitqty /*18, 20, 21, 28*/, uint8_t const *ric_flag,
244                 size_t* packed_buf_size, unsigned char* packed_buf,size_t err_buf_size, char* err_buf,enum asn_transfer_syntax syntax
245 )
246 {
247         bool rc = true;
248         E2AP_PDU_t *pdu = calloc(1, sizeof(E2AP_PDU_t));
249         InitiatingMessage_t *initiatingMessage = calloc(1, sizeof(InitiatingMessage_t));
250         ENDCX2SetupRequest_t *endcX2SetupRequest;
251
252     assert(pdu != 0);
253     assert(initiatingMessage != 0);
254
255     pdu->present = E2AP_PDU_PR_initiatingMessage;
256     pdu->choice.initiatingMessage = initiatingMessage;
257
258     initiatingMessage->procedureCode = ProcedureCode_id_endcX2Setup;
259     initiatingMessage->criticality = Criticality_reject;
260     initiatingMessage->value.present = InitiatingMessage__value_PR_ENDCX2SetupRequest;
261     endcX2SetupRequest = &initiatingMessage->value.choice.ENDCX2SetupRequest;
262     ENDCX2SetupRequest_IEs_t *endcX2SetupRequest_IEs = calloc(1, sizeof(ENDCX2SetupRequest_IEs_t));
263     assert(endcX2SetupRequest_IEs != 0);
264         ASN_SEQUENCE_ADD(&endcX2SetupRequest->protocolIEs, endcX2SetupRequest_IEs);
265         endcX2SetupRequest_IEs->id = ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup;
266         endcX2SetupRequest_IEs->criticality = Criticality_reject;
267         endcX2SetupRequest_IEs->value.present = ENDCX2SetupRequest_IEs__value_PR_InitiatingNodeType_EndcX2Setup;
268         endcX2SetupRequest_IEs->value.choice.InitiatingNodeType_EndcX2Setup.present = InitiatingNodeType_EndcX2Setup_PR_init_eNB;
269
270         ProtocolIE_Container_119P85_t *enb_ENDCX2SetupReqIE_Container = calloc(1, sizeof(ProtocolIE_Container_119P85_t));
271         assert(enb_ENDCX2SetupReqIE_Container != 0);
272         endcX2SetupRequest_IEs->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB = (struct ProtocolIE_Container*)enb_ENDCX2SetupReqIE_Container;
273         ENB_ENDCX2SetupReqIEs_t *globalENB_ID_ie = calloc(1, sizeof(ENB_ENDCX2SetupReqIEs_t));
274         assert(globalENB_ID_ie != 0);
275         ASN_SEQUENCE_ADD(enb_ENDCX2SetupReqIE_Container,globalENB_ID_ie);
276         globalENB_ID_ie->id = ProtocolIE_ID_id_GlobalENB_ID;
277         globalENB_ID_ie->criticality = Criticality_reject;
278         globalENB_ID_ie->value.present = ENB_ENDCX2SetupReqIEs__value_PR_GlobalENB_ID;
279
280         GlobalENB_ID_t *globalENB_ID = &globalENB_ID_ie->value.choice.GlobalENB_ID;
281         assignPLMN_Identity(&globalENB_ID->pLMN_Identity, pLMN_Identity);
282         assignENB_ID(globalENB_ID, eNBId, bitqty);
283
284
285         ENB_ENDCX2SetupReqIEs_t *ServedEUTRAcellsENDCX2ManagementList_ie = calloc(1, sizeof(ENB_ENDCX2SetupReqIEs_t));
286         assert(ServedEUTRAcellsENDCX2ManagementList_ie != 0);
287     ASN_SEQUENCE_ADD(enb_ENDCX2SetupReqIE_Container, ServedEUTRAcellsENDCX2ManagementList_ie);
288
289     ServedEUTRAcellsENDCX2ManagementList_ie->id = ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList;
290         ServedEUTRAcellsENDCX2ManagementList_ie->criticality = Criticality_reject;
291         ServedEUTRAcellsENDCX2ManagementList_ie->value.present = ENB_ENDCX2SetupReqIEs__value_PR_ServedEUTRAcellsENDCX2ManagementList;
292
293
294         ServedEUTRAcellsENDCX2ManagementList__Member *servedEUTRAcellsENDCX2ManagementList__Member = calloc(1, sizeof(ServedEUTRAcellsENDCX2ManagementList__Member));
295         assert(servedEUTRAcellsENDCX2ManagementList__Member != 0);
296         ASN_SEQUENCE_ADD(&ServedEUTRAcellsENDCX2ManagementList_ie->value.choice.ServedEUTRAcellsENDCX2ManagementList, servedEUTRAcellsENDCX2ManagementList__Member);
297
298         assignServedCell_Information(&servedEUTRAcellsENDCX2ManagementList__Member->servedEUTRACellInfo, pLMN_Identity, eNBId, bitqty,ric_flag);
299
300     rc = pack_pdu_aux(pdu, packed_buf_size, packed_buf,err_buf_size, err_buf, syntax);
301
302     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
303     return rc;
304 }