2 * Copyright 2019 AT&T Intellectual Property
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20 * platform project (RICP).
25 // Created by adi on 6/11/19.
28 #include <mdclog/mdclog.h>
30 #include "asn1cFiles/E2AP-PDU.h"
31 #include "asn1cFiles/InitiatingMessage.h"
44 #include <rmr/RIC_message_types.h>
48 // test X2SetUP request and response
53 int main(const int argc, char **argv) {
54 mdclog_severity_t loglevel = MDCLOG_INFO;
56 auto buff = new string("SETUP TEST");
57 init_log((char *)buff->c_str());
59 mdclog_level_set(loglevel);
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]");
69 char ranName[256] {0};
70 char rmrAddress[256] {0};
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]);
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;
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));
105 // get the RMR fd for the epoll
106 auto rmrListenFd = rmr_get_rcvfd(rmrCtx);
108 auto epoll_fd = epoll_create1(0);
109 if (epoll_fd == -1) {
110 mdclog_write(MDCLOG_ERR,"failed to open epoll descriptor");
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");
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");
135 if ((rmrReady = rmr_ready(rmrCtx)) == 0) {
139 if (count % 60 == 0) {
140 mdclog_write(MDCLOG_INFO, "waiting to RMR ready state for %d seconds", count);
143 mdclog_write(MDCLOG_ERR, "RMR not ready tried for 3 minutes ");
147 if (mdclog_level_get() >= MDCLOG_INFO) {
148 mdclog_write(MDCLOG_INFO, "RMR running");
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();
157 auto &ies = x2setup.ref_protocolIEs();
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);
166 val.ref_value().select_id_GlobalENB_ID().ref_eNB_ID().select_macro_eNB_ID().set_buffer(20,reinterpret_cast<uint8_t*>(&eNBId));
170 X2SetupRequest::protocolIEs_t::value_type sc {};
173 sc.ref_id().select_id_ServedCells();
174 sc.ref_criticality().select_id_ServedCells();
176 ServedCells::value_type sce;
177 sc.ref_value().select_id_ServedCells().push_back(sce);
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);
186 BroadcastPLMNs_Item::value_type bpe;
187 sce.ref_servedCellInfo().ref_broadcastPLMNs().push_back(bpe);
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);
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;
200 if (!asn::per::pack(pdu, ctx)) {
201 std::cout << ctx.refErrorCtx().toString() << std::endl;
204 size_t packed_buf_size;
205 packed_buf_size = static_cast<size_t>(ctx.refBuffer().getBytesUsed());
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));
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;
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);
229 unsigned char allocBuffer[64*1024] {0};
230 auto *events = (struct epoll_event *)calloc(MAXEVENTS, sizeof(event));
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));
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));
251 msg = rmr_rcv_msg(rmrCtx, msg);
252 if (msg == nullptr) {
253 mdclog_write(MDCLOG_ERR, "RMR Receving message, %s", strerror(errno));
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)};
263 if (!asn::per::unpack(opdu, dCtx)) {
264 mdclog_write(MDCLOG_ERR, "Failed to unpack ASN message, %s", dCtx.refErrorCtx().toString());
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)};
275 if (!asn::per::unpack(opdu, dCtx)) {
276 mdclog_write(MDCLOG_ERR, "Failed to unpack ASN message, %s", dCtx.refErrorCtx().toString());
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)};
288 if (!asn::per::unpack(opdu, dCtx)) {
289 mdclog_write(MDCLOG_ERR, "Failed to unpack ASN message, %s", dCtx.refErrorCtx().toString());
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());
300 case 2: { //successful message
301 mdclog_write(MDCLOG_INFO, "ASN initiating message type %ld",
302 opdu.get_successfulOutcome()->ref_procedureCode().ref_value().get());
305 case 3: { //unsuccessesful message
306 mdclog_write(MDCLOG_INFO, "ASN initiating message type %ld",
307 opdu.get_unsuccessfulOutcome()->ref_procedureCode().ref_value().get());
312 mdclog_write(MDCLOG_INFO, "RMR receiveing message from E2 terminator, %d",