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