Remove all old PI3 ASN files in first step because of change is too large
[ric-plt/e2.git] / RIC-E2-TERMINATION / TEST / testAsn / T2 / SubscriptionTest.cpp
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  * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20  * platform project (RICP).
21  */
22
23
24 //
25 // Created by adi ENZEL on 6/17/19.
26 //
27
28 #include <mdclog/mdclog.h>
29
30 #include "asn/type_defs.h"
31 #include "asn/per/codec.hpp"
32 #include "asn/printer.hpp"
33
34 #include "X2AP-CommonDataTypes.hpp"
35 #include "X2AP-Containers.hpp"
36 #include "X2AP-Constants.hpp"
37 #include "X2AP-IEs.hpp"
38 #include "X2AP-PDU-Contents.hpp"
39
40 #include "E2AP-Constants.hpp"
41 #include "E2AP-IEs.hpp"
42 #include "E2AP-PDU-Contents.hpp"
43 #include "E2AP-PDU-Descriptions.hpp"
44
45
46 #include <iostream>
47 #include <cstdio>
48 #include <cctype>
49 #include <cstring>
50
51 #include <pthread.h>
52 #include <rmr/rmr.h>
53 #include <rmr/RIC_message_types.h>
54
55 #include "logInit.h"
56
57 // test X2SetUP request and response
58 using namespace std;
59
60 #define MAXEVENTS 64
61
62 int main(const int argc, char **argv) {
63     mdclog_severity_t loglevel = MDCLOG_INFO;
64
65     auto buff = new string("Subscription TEST");
66     init_log((char *)buff->c_str());
67
68     mdclog_level_set(loglevel);
69
70     if (argc < 5){
71         mdclog_mdc_add("app", argv[0]);
72         mdclog_write(MDCLOG_ERR, "Usage ran <ran name> rmr <rmr address> [logLevel <debug/warning/info/error]");
73         return -1 ;
74     }
75
76     char ranName[256] {0};
77     char rmrAddress[256] {0};
78
79     char str1[128];
80     for (int i = 1; i < argc; i += 2) {
81         for (int j = 0; j < strlen(argv[i]); j++) {
82             str1[j] = (char)tolower(argv[i][j]);
83         }
84         str1[strlen(argv[i])] = 0;
85         if (strcmp("ran", str1) == 0) {
86             strcpy(ranName, argv[i + 1]);
87         } else if (strcmp("rmr", str1) == 0) {
88             strcpy(rmrAddress, argv[i + 1]);
89         } else if (strcmp("loglevel", str1) == 0) {
90             if (strcmp("debug", argv[i + 1]) == 0) {
91                 loglevel = MDCLOG_DEBUG;
92             } else if (strcmp("info", argv[i + 1]) == 0) {
93                 loglevel = MDCLOG_INFO;
94             } else if (strcmp("warning", argv[i + 1]) == 0) {
95                 loglevel = MDCLOG_WARN;
96             } else if (strcmp("error", argv[i + 1]) == 0) {
97                 loglevel = MDCLOG_ERR;
98             }
99         }
100     }
101
102     void *rmrCtx = rmr_init(rmrAddress, RMR_MAX_RCV_BYTES, RMRFL_NONE);
103     if (rmrCtx == nullptr ) {
104         mdclog_write(MDCLOG_ERR, "RMR failed to initialise : %s", strerror(errno));
105         return(-1);
106     }
107
108     // get the RMR fd for the epoll
109     auto rmrListenFd = rmr_get_rcvfd(rmrCtx);
110
111     auto epoll_fd = epoll_create1(0);
112     if (epoll_fd == -1) {
113         mdclog_write(MDCLOG_ERR,"failed to open epoll descriptor");
114         rmr_close(rmrCtx);
115         return -2;
116     }
117
118     struct epoll_event event {};
119     event.events = EPOLLIN;
120     event.data.fd = rmrListenFd;
121     // add listening sctpPort to epoll
122     if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, rmrListenFd, &event)) {
123         mdclog_write(MDCLOG_ERR, "Failed to add RMR descriptor to epoll");
124         close(rmrListenFd);
125         rmr_close(rmrCtx);
126         return -3;
127     }
128
129
130     // we need to find that routing table exist and we can run
131     if (mdclog_level_get() >= MDCLOG_INFO) {
132         mdclog_write(MDCLOG_INFO, "We are after RMR INIT wait for RMR_Ready");
133     }
134
135     int rmrReady = 0;
136     int count = 0;
137     while (!rmrReady) {
138         if ((rmrReady = rmr_ready(rmrCtx)) == 0) {
139             sleep(1);
140         }
141         count++;
142         if (count % 60 == 0) {
143             mdclog_write(MDCLOG_INFO, "waiting to RMR ready state for %d seconds", count);
144         }
145         if (count > 180) {
146             mdclog_write(MDCLOG_ERR, "RMR not ready tried for 3 minutes ");
147             return(-2);
148         }
149     }
150     if (mdclog_level_get() >= MDCLOG_INFO) {
151         mdclog_write(MDCLOG_INFO, "RMR running");
152     }
153
154     E2AP_PDU cuAckPdu {};
155     auto &succ = cuAckPdu.select_successfulOutcome();
156     succ.ref_procedureCode().select_id_endcConfigurationUpdate();
157     succ.ref_criticality().select_id_endcConfigurationUpdate();
158     auto &endcConfAck = succ.ref_value().select_id_endcConfigurationUpdate();
159     auto &confAckIes =  endcConfAck.ref_protocolIEs();
160
161     ENDCConfigurationUpdateAcknowledge::protocolIEs_t::value_type endcENB {};
162     endcENB.ref_id().select_id_RespondingNodeType_EndcConfigUpdate();
163     endcENB.ref_criticality().select_id_RespondingNodeType_EndcConfigUpdate();
164
165     auto &respondingNode = endcENB.ref_value().select_id_RespondingNodeType_EndcConfigUpdate();
166
167     auto &enb = respondingNode.select_respond_eNB();
168
169
170     confAckIes.push_back(endcENB);
171
172
173
174     E2AP_PDU pdu {};
175     auto &initiatingMsg = pdu.select_initiatingMessage();
176     initiatingMsg.ref_procedureCode().select_id_ricSubscription();
177     initiatingMsg.ref_criticality().select_id_ricSubscription();
178     auto &subscription = initiatingMsg.ref_value().select_id_ricSubscription();
179
180     auto &ies = subscription.ref_protocolIEs();
181
182
183
184     RICsubscriptionRequest::protocolIEs_t::value_type ranFuncId {};
185     ranFuncId.ref_id().select_id_RANfunctionID();
186     ranFuncId.ref_criticality().select_id_RANfunctionID();
187     ranFuncId.ref_value().select_id_RANfunctionID().set(28);
188     ies.push_back(ranFuncId);
189
190     RICsubscriptionRequest::protocolIEs_t::value_type ricRequestId {};
191     ricRequestId.ref_id().select_id_RICrequestID();
192     ricRequestId.ref_criticality().select_id_RICrequestID();
193     ricRequestId.ref_value().select_id_RICrequestID().ref_ricRequestorID().set(44);
194     ricRequestId.ref_value().select_id_RICrequestID().ref_ricRequestSequenceNumber().set(55);
195     ies.push_back(ricRequestId);
196
197     RICsubscriptionRequest::protocolIEs_t::value_type ricSubId {};
198     ricSubId.ref_id().select_id_RICsubscription();
199     ricSubId.ref_criticality().select_id_RICsubscription();
200
201     //E2SM_gNB_X2_eventTriggerDefinition_t evt;
202     uint8_t v1[] = {0x02, 0xf8, 0x29, 0x88};
203
204     RICeventTriggerDefinition eventTriggerDef {};  // octet string in E2AP but struct in E2SM
205     eventTriggerDef.set(4, v1);
206
207 //    eventTriggerDef.
208 //
209 //
210 //    RICaction_Admitted_List::value_type actbl {};
211 //    actbl.ref_id().select_id_RICaction_Admitted_Item();
212 //    actbl.ref_criticality().select_id_RICaction_Admitted_Item();
213
214
215 //    RICaction_ToBeSetup_Item actb1{};
216 //
217 //    actbl.ref_value().select_id_RICaction_Admitted_Item().ref_ricActionID().set(actb1);
218 //    ricSubId.ref_value().select_id_RICsubscription().ref_ricAction_ToBeSetup_List().set(actbl);
219
220
221     ies.push_back(ricSubId);
222
223 /*
224
225     ies.push_back(ranFuncId);
226
227     X2SetupRequest::protocolIEs_t::value_type sc {};
228     ies.push_back(sc);
229
230     sc.ref_id().select_id_ServedCells();
231     sc.ref_criticality().select_id_ServedCells();
232
233     ServedCells::value_type sce;
234     sc.ref_value().select_id_ServedCells().push_back(sce);
235
236     sce.ref_servedCellInfo().ref_pCI().set(0x1F7);
237     uint8_t v3[] = {0x1, 0x2};
238     sce.ref_servedCellInfo().ref_tAC().set(2,v3);
239     sce.ref_servedCellInfo().ref_cellId().ref_pLMN_Identity().set(3, v1);
240     uint8_t v4[] = {0x00, 0x07, 0xab, ((unsigned)0x50) >> (unsigned)4};
241     sce.ref_servedCellInfo().ref_cellId().ref_eUTRANcellIdentifier().set_buffer(28, v4);
242
243     BroadcastPLMNs_Item::value_type bpe;
244     sce.ref_servedCellInfo().ref_broadcastPLMNs().push_back(bpe);
245     bpe.set(3, v1);
246
247     sce.ref_servedCellInfo().ref_eUTRA_Mode_Info().select_fDD().ref_uL_EARFCN().set(0x1);
248     sce.ref_servedCellInfo().ref_eUTRA_Mode_Info().select_fDD().ref_dL_EARFCN().set(0x1);
249     sce.ref_servedCellInfo().ref_eUTRA_Mode_Info().select_fDD().ref_uL_Transmission_Bandwidth().set(Transmission_Bandwidth::bw50);
250     sce.ref_servedCellInfo().ref_eUTRA_Mode_Info().select_fDD().ref_dL_Transmission_Bandwidth().set(Transmission_Bandwidth::bw50);
251
252 */
253
254     unsigned char s_buffer[64 * 1024];
255     asn::per::EncoderCtx ctx{s_buffer, sizeof(s_buffer)};
256     std::cout << asn::get_printed(pdu) << std::endl;
257     if (!asn::per::pack(pdu, ctx)) {
258         std::cout << ctx.refErrorCtx().toString() << std::endl;
259         return -3;
260     }
261     size_t packed_buf_size;
262     packed_buf_size = static_cast<size_t>(ctx.refBuffer().getBytesUsed());
263
264     // build message
265     char data[4096] {};
266     //auto delimiter = (const char) '|';
267     sprintf(data, "%s/0", ctx.refBuffer().getBytes(packed_buf_size));
268
269     rmr_mbuf_t *msg = rmr_alloc_msg(rmrCtx, int(strlen(data)));
270     rmr_bytes2meid(msg, (unsigned char const*)ranName, strlen(ranName));
271     rmr_bytes2payload(msg, (unsigned char const*)data, strlen(data));
272     rmr_bytes2xact(msg, (unsigned char const*)ranName, strlen(ranName));
273     msg->mtype = RIC_SUB_REQ;
274     msg->state = 0;
275
276     msg = rmr_send_msg(rmrCtx, msg);
277     if (msg->state != 0) {
278         mdclog_write(MDCLOG_ERR, "Message state %d while sending RIC_X2_SETUP to %s", msg->state, ranName);
279         rmr_free_msg(msg);
280         rmr_close(rmrCtx);
281         return -4;
282     }
283     rmr_free_msg(msg);
284
285
286     unsigned char allocBuffer[64*1024] {0};
287     auto *events = (struct epoll_event *)calloc(MAXEVENTS, sizeof(event));
288
289     while (true) {
290
291         auto numOfEvents = epoll_wait(epoll_fd, events, MAXEVENTS, -1);
292         if (numOfEvents < 0) {
293             mdclog_write(MDCLOG_ERR, "Epoll wait failed, errno = %s", strerror(errno));
294             rmr_close(rmrCtx);
295             return -4;
296         }
297         for (auto i = 0; i < numOfEvents; i++) {
298             if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) {
299                 mdclog_write(MDCLOG_ERR, "epoll error");
300             } else if (rmrListenFd == events[i].data.fd) {
301                 msg = rmr_alloc_msg(rmrCtx, 4096);
302                 if (msg == nullptr) {
303                     mdclog_write(MDCLOG_ERR, "RMR Allocation message, %s", strerror(errno));
304                     rmr_close(rmrCtx);
305                     return -5;
306                 }
307
308                 msg = rmr_rcv_msg(rmrCtx, msg);
309                 if (msg == nullptr) {
310                     mdclog_write(MDCLOG_ERR, "RMR Receving message, %s", strerror(errno));
311                     rmr_close(rmrCtx);
312                     return -6;
313                 }
314                 memset(allocBuffer, 0, 64*1024);
315                 switch (msg->mtype) {
316                     default: {
317                         mdclog_write(MDCLOG_INFO, "RMR receiveing message type %d", msg->mtype);
318                         asn::per::DecoderCtx dCtx{msg->payload, (size_t) msg->len, allocBuffer, sizeof(allocBuffer)};
319                         E2AP_PDU opdu;
320                         if (!asn::per::unpack(opdu, dCtx)) {
321                             mdclog_write(MDCLOG_ERR, "Failed to unpack ASN message, %s", dCtx.refErrorCtx().toString());
322                             rmr_close(rmrCtx);
323                             return -7;
324                         }
325
326                         switch (opdu.get_index()) {
327                             case 1: { //initiating message
328                                 mdclog_write(MDCLOG_INFO, "ASN initiating message type %ld",
329                                              opdu.get_initiatingMessage()->ref_procedureCode().ref_value().get());
330                                 break;
331                             }
332                             case 2: { //successful message
333                                 mdclog_write(MDCLOG_INFO, "ASN initiating message type %ld",
334                                              opdu.get_successfulOutcome()->ref_procedureCode().ref_value().get());
335                                 break;
336                             }
337                             case 3: { //unsuccessesful message
338                                 mdclog_write(MDCLOG_INFO, "ASN initiating message type %ld",
339                                              opdu.get_unsuccessfulOutcome()->ref_procedureCode().ref_value().get());
340                                 break;
341                             }
342
343                         }
344                         mdclog_write(MDCLOG_INFO, "RMR receiveing message from E2 terminator, %d",
345                                      msg->mtype);
346                         break;
347                     }
348                 }
349             }
350         }
351     }
352 }