1 /*****************************************************************************
3 # Copyright 2019 AT&T Intellectual Property *
4 # Copyright 2019 Nokia *
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, 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. *
18 ******************************************************************************/
20 #include "asn_x2ap.hpp"
21 #include "asn_x2ap_wrapper.hpp"
23 /*-----------------------------------------------------------------------
25 -------------------------------------------------------------------------
27 x2ap_pdu_t* new_x2ap_pdu(void)
29 X2APpduWrapper* pduWrapper = new X2APpduWrapper();
30 return reinterpret_cast<x2ap_pdu_t*>(pduWrapper);
33 void x2ap_asn_print(x2ap_pdu_t* pdu, char* buf, size_t buf_size)
35 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
39 strncat(buf, asn::get_printed(pduWrapper->ref_pdu()).c_str(), buf_size - 1);
42 int x2ap_asn_per_encode(x2ap_pdu_t* pdu, unsigned char* buf, size_t buf_size,
43 char* err_buf, size_t err_buf_size)
45 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
47 asn::per::EncoderCtx ctx{ buf, buf_size };
49 if (!asn::per::pack(pduWrapper->ref_pdu(), ctx)) {
51 // strncat(err_buf, ctx.refErrorCtx().toString().c_str(), err_buf_size - 1);
54 return static_cast<int>(ctx.refBuffer().getBytesUsed());
59 int x2ap_asn_per_decode(x2ap_pdu_t* pdu, unsigned char const* buf, size_t buf_size,
60 char* err_buf, size_t err_buf_size)
62 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
64 asn::per::DecoderCtx ctx{ buf,
66 pduWrapper->m_allocation_buffer,
67 pduWrapper->m_allocation_buffer_size };
69 if (!asn::per::unpack(pduWrapper->ref_pdu(), ctx)) {
71 // strncat(err_buf, ctx.refErrorCtx().toString().c_str(), err_buf_size - 1);
79 int x2ap_get_index(x2ap_pdu_t* pdu)
81 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
83 return pduWrapper->ref_pdu().get_index();
86 int x2ap_get_procedureCode(x2ap_pdu_t* pdu)
88 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
90 switch(pduWrapper->ref_pdu().get_index())
93 return pduWrapper->ref_pdu().get_initiatingMessage()->ref_procedureCode().get();
97 return pduWrapper->ref_pdu().get_successfulOutcome()->ref_procedureCode().get();
101 return pduWrapper->ref_pdu().get_unsuccessfulOutcome()->ref_procedureCode().get();
110 /*-----------------------------------------------------------------------
112 -------------------------------------------------------------------------
115 bool x2ap_init_X2SetupRequest(x2ap_pdu_t* pdu)
117 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
120 pduWrapper->ref_pdu().select_initiatingMessage();
121 pduWrapper->ref_pdu().select_initiatingMessage().clear();
122 pduWrapper->ref_pdu().select_initiatingMessage().ref_procedureCode().select_id_x2Setup();
123 pduWrapper->ref_pdu().select_initiatingMessage().ref_criticality().select_id_x2Setup();
124 pduWrapper->ref_pdu().select_initiatingMessage().ref_value().select_id_x2Setup();
129 bool x2ap_create_X2SetupRequest(x2ap_pdu_t* pdu, eNB_config &cfg)
131 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
134 pduWrapper->ref_pdu().select_initiatingMessage().ref_procedureCode().select_id_x2Setup();
135 pduWrapper->ref_pdu().select_initiatingMessage().ref_criticality().select_id_x2Setup();
137 X2SetupRequest* container =
138 &(pduWrapper->ref_pdu().select_initiatingMessage().ref_value().select_id_x2Setup());
140 using IE_value_t = X2SetupRequest::protocolIEs_t::value_type;
142 /* X2SetupRequest-IEs : GlobalENB-ID*/
143 IE_value_t* val_GlobalENB_ID = new IE_value_t;
144 container->ref_protocolIEs().push_back(*val_GlobalENB_ID);
146 val_GlobalENB_ID->ref_id().select_id_GlobalENB_ID();
147 val_GlobalENB_ID->ref_criticality().select_id_GlobalENB_ID();
148 val_GlobalENB_ID->ref_value().select_id_GlobalENB_ID().ref_pLMN_Identity()
149 .set(3, cfg.pLMN_Identity);
151 val_GlobalENB_ID->ref_value().select_id_GlobalENB_ID().ref_eNB_ID()
152 .select_macro_eNB_ID().set_buffer(20, cfg.macro_eNB_ID);
154 /* X2SetupRequest-IEs : ServedCells*/
155 IE_value_t* val_ServedCells = new IE_value_t;
156 container->ref_protocolIEs().push_back(*val_ServedCells);
158 val_ServedCells->ref_id().select_id_ServedCells();
159 val_ServedCells->ref_criticality().select_id_ServedCells();
160 val_ServedCells->ref_value().select_id_ServedCells();
163 ServedCells::value_type* elm = new ServedCells::value_type();
164 ServedCell_Information* info = &(elm->ref_servedCellInfo());
166 //Set ServedCell-Information: pCI, cellId, tAC, broadcastPLMNs, eUTRA-Mode-Info
167 info->ref_pCI().set(cfg.pCI);
168 info->ref_cellId().ref_pLMN_Identity().set(3, cfg.pLMN_Identity);
169 info->ref_cellId().ref_eUTRANcellIdentifier().set_buffer(28, cfg.eUTRANcellIdentifier);
170 info->ref_tAC().set(2, cfg.tAC);
172 BroadcastPLMNs_Item::value_type* item = new BroadcastPLMNs_Item::value_type();
173 item->set(3, cfg.pLMN_Identity);
174 info->ref_broadcastPLMNs().push_back(*item);
176 info->ref_eUTRA_Mode_Info().select_fDD().ref_uL_EARFCN().set(cfg.uL_EARFCN);
177 info->ref_eUTRA_Mode_Info().select_fDD().ref_dL_EARFCN().set(cfg.dL_EARFCN);
178 info->ref_eUTRA_Mode_Info().select_fDD().ref_uL_Transmission_Bandwidth()
179 .set(static_cast<Transmission_Bandwidth::index_t>(cfg.uL_Bandwidth));
180 info->ref_eUTRA_Mode_Info().select_fDD().ref_dL_Transmission_Bandwidth()
181 .set(static_cast<Transmission_Bandwidth::index_t>(cfg.dL_Bandwidth));
183 val_ServedCells->ref_value().select_id_ServedCells().push_back(*elm);
188 bool x2ap_create_X2SetupResponse(x2ap_pdu_t* pdu, eNB_config &cfg)
190 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
193 pduWrapper->ref_pdu().select_successfulOutcome().ref_procedureCode().select_id_x2Setup();
194 pduWrapper->ref_pdu().select_successfulOutcome().ref_criticality().select_id_x2Setup();
196 X2SetupResponse* container =
197 &(pduWrapper->ref_pdu().select_successfulOutcome().ref_value().select_id_x2Setup());
199 using IE_value_t = X2SetupResponse::protocolIEs_t::value_type;
201 /* X2SetupResponse-IEs : GlobalENB-ID*/
202 IE_value_t* val_GlobalENB_ID = new IE_value_t;
203 container->ref_protocolIEs().push_back(*val_GlobalENB_ID);
205 val_GlobalENB_ID->ref_id().select_id_GlobalENB_ID();
206 val_GlobalENB_ID->ref_criticality().select_id_GlobalENB_ID();
207 val_GlobalENB_ID->ref_value().select_id_GlobalENB_ID().ref_pLMN_Identity()
208 .set(3, cfg.pLMN_Identity);
210 val_GlobalENB_ID->ref_value().select_id_GlobalENB_ID().ref_eNB_ID()
211 .select_macro_eNB_ID().set_buffer(20, cfg.macro_eNB_ID);
213 /* X2SetupResponse-IEs : ServedCells*/
214 IE_value_t* val_ServedCells = new IE_value_t;
215 container->ref_protocolIEs().push_back(*val_ServedCells);
217 val_ServedCells->ref_id().select_id_ServedCells();
218 val_ServedCells->ref_criticality().select_id_ServedCells();
219 val_ServedCells->ref_value().select_id_ServedCells();
222 ServedCells::value_type* elm = new ServedCells::value_type();
223 ServedCell_Information* info = &(elm->ref_servedCellInfo());
225 //Set ServedCell-Information: pCI, cellId, tAC, broadcastPLMNs, eUTRA-Mode-Info
226 info->ref_pCI().set(cfg.pCI);
227 info->ref_cellId().ref_pLMN_Identity().set(3, cfg.pLMN_Identity);
228 info->ref_cellId().ref_eUTRANcellIdentifier().set_buffer(28, cfg.eUTRANcellIdentifier);
229 info->ref_tAC().set(2, cfg.tAC);
231 BroadcastPLMNs_Item::value_type* item = new BroadcastPLMNs_Item::value_type();
232 item->set(3, cfg.pLMN_Identity);
233 info->ref_broadcastPLMNs().push_back(*item);
235 info->ref_eUTRA_Mode_Info().select_fDD().ref_uL_EARFCN().set(cfg.uL_EARFCN);
236 info->ref_eUTRA_Mode_Info().select_fDD().ref_dL_EARFCN().set(cfg.dL_EARFCN);
237 info->ref_eUTRA_Mode_Info().select_fDD().ref_uL_Transmission_Bandwidth()
238 .set(static_cast<Transmission_Bandwidth::index_t>(cfg.uL_Bandwidth));
239 info->ref_eUTRA_Mode_Info().select_fDD().ref_dL_Transmission_Bandwidth()
240 .set(static_cast<Transmission_Bandwidth::index_t>(cfg.dL_Bandwidth));
242 val_ServedCells->ref_value().select_id_ServedCells().push_back(*elm);
247 bool x2ap_create_X2SetupFailure(x2ap_pdu_t* pdu)
249 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
252 pduWrapper->ref_pdu().select_unsuccessfulOutcome().ref_procedureCode().select_id_x2Setup();
253 pduWrapper->ref_pdu().select_unsuccessfulOutcome().ref_criticality().select_id_x2Setup();
255 X2SetupFailure* container =
256 &(pduWrapper->ref_pdu().select_unsuccessfulOutcome().ref_value().select_id_x2Setup());
258 using IE_value_t = X2SetupFailure::protocolIEs_t::value_type;
260 /* X2SetupFailure-IEs << id-Cause */
261 IE_value_t* val_cause = new IE_value_t;
262 container->ref_protocolIEs().push_back(*val_cause);
264 val_cause->ref_id().select_id_Cause();
265 val_cause->ref_criticality().select_id_Cause();
267 /* Cause << radioNetwork */
268 val_cause->ref_value().select_id_Cause().select_radioNetwork();
270 /* CauseRadioNetwork = ho-target-not-allowed (enum = 8)*/
271 val_cause->ref_value().select_id_Cause().select_radioNetwork()
272 .set(static_cast<CauseRadioNetwork::index_t>(8));
278 bool x2ap_create_ENDCX2SetupRequest(x2ap_pdu_t* pdu, eNB_config &cfg)
280 X2APpduWrapper* pduWrapper = reinterpret_cast<X2APpduWrapper*>(pdu);
283 pduWrapper->ref_pdu().select_initiatingMessage().ref_procedureCode().select_id_endcX2Setup();
284 pduWrapper->ref_pdu().select_initiatingMessage().ref_criticality().select_id_endcX2Setup();
286 ENDCX2SetupRequest* container =
287 &(pduWrapper->ref_pdu().select_initiatingMessage().ref_value().select_id_endcX2Setup());
289 using IE_value_t = ENDCX2SetupRequest::protocolIEs_t::value_type;
291 /* ENDCX2SetupRequest-IEs = id-InitiatingNodeType-EndcX2Setup */
292 IE_value_t* ie = new IE_value_t;
293 container->ref_protocolIEs().push_back(*ie);
294 ie->ref_id().select_id_InitiatingNodeType_EndcX2Setup();
295 ie->ref_criticality().select_id_InitiatingNodeType_EndcX2Setup();
296 ie->ref_value().select_id_InitiatingNodeType_EndcX2Setup();
298 /* InitiatingNodeType-EndcX2Setup = init-eNB {ENB-ENDCX2SetupReqIEs} */
299 ie->ref_value().select_id_InitiatingNodeType_EndcX2Setup().select_init_eNB();
301 using eNB_val_t = InitiatingNodeType_EndcX2Setup::init_eNB_t::value_type;
303 ProtocolIE_Container<ENB_ENDCX2SetupReqIEs>* eNB_node =
304 &(ie->ref_value().select_id_InitiatingNodeType_EndcX2Setup().select_init_eNB());
306 /* ENB-ENDCX2SetupReqIEs <-- id-GlobalENB-ID */
307 eNB_val_t* val_GlobalENB_ID = new eNB_val_t;
308 eNB_node->push_back(*val_GlobalENB_ID);
310 val_GlobalENB_ID->ref_id().select_id_GlobalENB_ID();
311 val_GlobalENB_ID->ref_criticality().select_id_GlobalENB_ID();
312 val_GlobalENB_ID->ref_value().select_id_GlobalENB_ID()
313 .ref_pLMN_Identity().set(3, cfg.pLMN_Identity);
314 val_GlobalENB_ID->ref_value().select_id_GlobalENB_ID().ref_eNB_ID()
315 .select_macro_eNB_ID().set_buffer(20, cfg.macro_eNB_ID);
317 /* ENB-ENDCX2SetupReqIEs <-- id-ServedEUTRAcellsENDCX2ManagementList */
318 eNB_val_t* val_EUTRAlist = new eNB_val_t;
319 eNB_node->push_back(*val_EUTRAlist);
321 val_EUTRAlist->ref_id().select_id_ServedEUTRAcellsENDCX2ManagementList();
322 val_EUTRAlist->ref_criticality().select_id_ServedEUTRAcellsENDCX2ManagementList();
323 val_EUTRAlist->ref_value().select_id_ServedEUTRAcellsENDCX2ManagementList();
325 /* ServedEUTRAcellsENDCX2ManagementList <-- servedEUTRACellInfo */
326 ServedEUTRAcellsENDCX2ManagementList::value_type* elm =
327 new ServedEUTRAcellsENDCX2ManagementList::value_type();
328 ServedCell_Information* info = &(elm->ref_servedEUTRACellInfo());
330 //Set ServedCell-Information: pCI, cellId, tAC, broadcastPLMNs, eUTRA-Mode-Info
331 info->ref_pCI().set(cfg.pCI);
332 info->ref_cellId().ref_pLMN_Identity().set(3, cfg.pLMN_Identity);
333 info->ref_cellId().ref_eUTRANcellIdentifier().set_buffer(28, cfg.eUTRANcellIdentifier);
334 info->ref_tAC().set(2, cfg.tAC);
336 BroadcastPLMNs_Item::value_type* item = new BroadcastPLMNs_Item::value_type();
337 item->set(3, cfg.pLMN_Identity);
338 info->ref_broadcastPLMNs().push_back(*item);
340 info->ref_eUTRA_Mode_Info().select_fDD().ref_uL_EARFCN().set(cfg.uL_EARFCN);
341 info->ref_eUTRA_Mode_Info().select_fDD().ref_dL_EARFCN().set(cfg.dL_EARFCN);
342 info->ref_eUTRA_Mode_Info().select_fDD().ref_uL_Transmission_Bandwidth()
343 .set(static_cast<Transmission_Bandwidth::index_t>(cfg.uL_Bandwidth));
344 info->ref_eUTRA_Mode_Info().select_fDD().ref_dL_Transmission_Bandwidth()
345 .set(static_cast<Transmission_Bandwidth::index_t>(cfg.dL_Bandwidth));
347 val_EUTRAlist->ref_value().select_id_ServedEUTRAcellsENDCX2ManagementList()
353 /*-----------------------------------------------------------------------
355 -------------------------------------------------------------------------
357 void test_X2Setup_codec(void)
359 x2ap_pdu_t* pdu = new_x2ap_pdu();
362 x2ap_create_X2SetupRequest(pdu, cfg);
365 x2ap_asn_print(pdu, pdu_str, sizeof(pdu_str));
366 printf("%s\n", pdu_str);
369 unsigned char packed_buf[4096];
372 int packed_len = x2ap_asn_per_encode(pdu, packed_buf, sizeof(packed_buf),
373 err_buf, sizeof(err_buf));
374 if(packed_len != -1) {
375 printf("Encode successful, packed_len = %d\n", packed_len);
377 printf("Encode Error: %s\n", err_buf);
381 x2ap_pdu_t* pdu1 = new_x2ap_pdu();
382 x2ap_init_X2SetupRequest(pdu1);
384 int packed_len1 = x2ap_asn_per_encode(pdu1, packed_buf, sizeof(packed_buf),
385 err_buf, sizeof(err_buf));
386 if(packed_len1 != -1) {
387 printf("Encode successful, packed_len = %d\n", packed_len1);
389 printf("Encode Error: %s\n", err_buf);
393 x2ap_pdu_t* pdu2 = new_x2ap_pdu();
394 int rc = x2ap_asn_per_decode(pdu2, packed_buf, packed_len, err_buf, sizeof(err_buf));
396 printf("Decode error: %s\n", err_buf);
398 printf("Decode successful\n");
401 x2ap_asn_print(pdu2, pdu_str, sizeof(pdu_str));
402 printf("%s\n", pdu_str);
404 printf("index = %d\n", x2ap_get_index(pdu2));
405 printf("procedureCode = %d\n", x2ap_get_procedureCode(pdu2));
409 x2ap_pdu_t* pdu3 = new_x2ap_pdu();
410 int rc2 = x2ap_asn_per_decode(pdu3, packed_buf, 1, err_buf, sizeof(err_buf));
412 printf("Decode error: %s\n", err_buf);
414 printf("Decode successful\n");
417 //Test X2SetupResponse
418 x2ap_pdu_t* pdu_resp = new_x2ap_pdu();
419 x2ap_create_X2SetupResponse(pdu_resp, cfg);
420 x2ap_asn_print(pdu_resp, pdu_str, sizeof(pdu_str));
421 printf("%s\n", pdu_str);
423 //Test X2SetupFailure
424 x2ap_pdu_t* pdu_failure = new_x2ap_pdu();
425 x2ap_create_X2SetupFailure(pdu_failure);
426 x2ap_asn_print(pdu_failure, pdu_str, sizeof(pdu_str));
427 printf("%s \n", pdu_str);