ASN compiled code for E2AP v1.1
[ric-plt/e2.git] / RIC-E2-TERMINATION / sctpThread.h
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 #ifndef X2_SCTP_THREAD_H
24 #define X2_SCTP_THREAD_H
25
26 #include <algorithm>
27
28 #include <cstdio>
29 #include <cerrno>
30 #include <cstdlib>
31 #include <cstring>
32 #include <random>
33 #include <sys/socket.h>
34 #include <arpa/inet.h>
35 #include <netinet/in_systm.h>
36 #include <netinet/in.h>
37 #include <netinet/ip.h>
38 #include <netinet/ip_icmp.h>
39 #include <netinet/sctp.h>
40 #include <thread>
41 #include <atomic>
42 #include <sys/param.h>
43 #include <sys/file.h>
44 #include <sys/types.h>
45 #include <ifaddrs.h>
46 #include <ctime>
47 #include <netdb.h>
48 #include <sys/epoll.h>
49 #include <mutex>
50 #include <shared_mutex>
51 #include <iterator>
52 #include <map>
53 #include <sys/inotify.h>
54 #include <csignal>
55 #include <future>
56
57 #include <rmr/rmr.h>
58 #include <rmr/RIC_message_types.h>
59 #include <mdclog/mdclog.h>
60 #include <functional>
61 #include <iostream>
62
63 #include <boost/algorithm/string/predicate.hpp>
64 #include <boost/lexical_cast.hpp>
65 #include <boost/move/utility.hpp>
66 #include <boost/log/sources/logger.hpp>
67 #include <boost/log/sources/record_ostream.hpp>
68 #include <boost/log/sources/global_logger_storage.hpp>
69 #include <boost/log/utility/setup/file.hpp>
70 #include <boost/log/utility/setup/common_attributes.hpp>
71 #include <boost/filesystem.hpp>
72
73 #include <mdclog/mdclog.h>
74
75 #include "oranE2/E2AP-PDU.h"
76 #include "oranE2/ProtocolIE-Container.h"
77 #include "oranE2/InitiatingMessage.h"
78 #include "oranE2/SuccessfulOutcome.h"
79 #include "oranE2/UnsuccessfulOutcome.h"
80 #include "oranE2/ProtocolIE-Container.h"
81 #include "oranE2/ProtocolIE-Field.h"
82 #include "oranE2/GlobalE2node-gNB-ID.h"
83 #include "oranE2/GlobalE2node-en-gNB-ID.h"
84 #include "oranE2/GlobalE2node-ng-eNB-ID.h"
85 #include "oranE2/GlobalE2node-eNB-ID.h"
86
87 #include "cxxopts.hpp"
88 //#include "config-cpp/include/config-cpp/config-cpp.h"
89 #include <zlib.h>
90 #include <prometheus/counter.h>
91 #include <prometheus/exposer.h>
92 #include <prometheus/gateway.h>
93 #include <prometheus/registry.h>
94
95 using namespace prometheus;
96
97 #include "mapWrapper.h"
98
99 #include "base64.h"
100
101 #include "ReadConfigFile.h"
102
103 using namespace std;
104 namespace logging = boost::log;
105 namespace src = boost::log::sources;
106 namespace keywords = boost::log::keywords;
107 namespace sinks = boost::log::sinks;
108 namespace posix_time = boost::posix_time;
109 namespace expr = boost::log::expressions;
110
111 #define SRC_PORT 36422
112 #define SA      struct sockaddr
113 #define MAX_ENODB_NAME_SIZE 64
114
115 #define MAXEVENTS 128
116
117 #define RECEIVE_SCTP_BUFFER_SIZE (256 * 1024)
118 #define RECEIVE_XAPP_BUFFER_SIZE RECEIVE_SCTP_BUFFER_SIZE
119
120 typedef mapWrapper Sctp_Map_t;
121
122
123
124 #define VOLUME_URL_SIZE 256
125 #define KA_MESSAGE_SIZE 2048
126
127 typedef struct sctp_params {
128     int      epollTimeOut = -1;
129     uint16_t rmrPort = 0;
130     uint16_t sctpPort = SRC_PORT;
131     int      epoll_fd = 0;
132     int      listenFD = 0;
133     int      rmrListenFd = 0;
134     int      inotifyFD = 0;
135     int      inotifyWD = 0;
136     void     *rmrCtx = nullptr;
137     Sctp_Map_t *sctpMap = nullptr;
138     char      ka_message[KA_MESSAGE_SIZE] {};
139     int       ka_message_length = 0;
140     char       rmrAddress[256] {}; // "tcp:port number" "tcp:5566" listen to all address on port 5566
141     mdclog_severity_t logLevel = MDCLOG_INFO;
142     char volume[VOLUME_URL_SIZE];
143     string myIP {};
144     string fqdn {};
145     string podName {};
146     string configFilePath {};
147     string configFileName {};
148     bool trace = true;
149     shared_ptr<prometheus::Registry> prometheusRegistry;
150     string prometheusPort {"8088"};
151     Family<Counter> *prometheusFamily;
152     Exposer *prometheusExposer = nullptr;
153     Counter *e2tCounters[6][2][ProcedureCode_id_RICsubscriptionDelete + 1] {};
154 } sctp_params_t;
155
156 // RAN to RIC
157 #define IN_INITI 0 //INITIATING
158 #define IN_SUCC 1 //SUCCESSFUL
159 #define IN_UN_SUCC 2 //UN-Successful
160
161 // RIC To RAN
162 #define OUT_INITI 3 //INITIATING
163 #define OUT_SUCC 4 //SUCCESSFUL
164 #define OUT_UN_SUCC 5 //UN-Successful
165
166 #define MSG_COUNTER 0
167 #define BYTES_COUNTER 1
168
169 typedef struct ConnectedCU {
170     int fileDescriptor = 0;
171     char hostName[NI_MAXHOST] {};
172     char portNumber[NI_MAXSERV] {};
173     char enodbName[MAX_ENODB_NAME_SIZE] {};
174     char asnData[RECEIVE_SCTP_BUFFER_SIZE] {};
175     size_t asnLength = 0;
176     int mtype = 0;
177     bool isConnected = false;
178     bool gotSetup = false;
179     sctp_params_t *sctpParams = nullptr;
180     Counter *counters[6][2][ProcedureCode_id_RICsubscriptionDelete + 1] {};
181 } ConnectedCU_t ;
182
183
184 #define MAX_RMR_BUFF_ARRAY 32
185 typedef struct RmrMessagesBuffer {
186     char ka_message[KA_MESSAGE_SIZE] {};
187     int  ka_message_len = 0;
188     void *rmrCtx = nullptr;
189     rmr_mbuf_t *sendMessage= nullptr;
190     //rmr_mbuf_t *sendBufferedMessages[MAX_RMR_BUFF_ARRAY] {};
191     rmr_mbuf_t *rcvMessage= nullptr;
192     //rmr_mbuf_t *rcvBufferedMessages[MAX_RMR_BUFF_ARRAY] {};
193 } RmrMessagesBuffer_t;
194
195 typedef struct formatedMessage {
196     char enodbName[MAX_ENODB_NAME_SIZE];
197     struct timespec time;
198     int messageType;
199     char direction;
200     ssize_t asnLength;
201     unsigned char *asndata;
202 } FormatedMessage_t;
203
204 typedef struct ReportingMessages {
205     FormatedMessage_t message {};
206     ConnectedCU_t *peerInfo = nullptr;
207     long outLen = 0;
208     unsigned char base64Data[RECEIVE_SCTP_BUFFER_SIZE * 2] {};
209     char buffer[RECEIVE_SCTP_BUFFER_SIZE * 8] {};
210 } ReportingMessages_t;
211
212 cxxopts::ParseResult parse(int argc, char *argv[], sctp_params_t &pSctpParams);
213
214 int buildInotify(sctp_params_t &sctpParams);
215
216 void handleTermInit(sctp_params_t &sctpParams);
217
218 void handleConfigChange(sctp_params_t *sctpParams);
219
220 void listener(sctp_params_t *params);
221
222 void sendTermInit(sctp_params_t &sctpParams);
223
224 int setSocketNoBlocking(int socket);
225
226 void handleEinprogressMessages(struct epoll_event &event,
227                                ReportingMessages_t &message,
228                                RmrMessagesBuffer_t &rmrMessageBuffer,
229                                sctp_params_t *params);
230
231 void handlepoll_error(struct epoll_event &event,
232                       ReportingMessages_t &message,
233                       RmrMessagesBuffer_t &rmrMessageBuffer,
234                       sctp_params_t *params);
235
236
237 void cleanHashEntry(ConnectedCU_t *peerInfo, Sctp_Map_t *m);
238
239
240 /**
241  *
242  * @param message
243  * @param rmrMessageBuffer
244  */
245 void getRequestMetaData(ReportingMessages_t &message, RmrMessagesBuffer_t &rmrMessageBuffer);
246
247 /**
248  *
249  * @param sctpMap
250  * @param messageBuffer
251  * @param message
252  * @param failedMesgId
253  * @return
254  */
255 int sendMessagetoCu(Sctp_Map_t *sctpMap,
256                     RmrMessagesBuffer_t &messageBuffer,
257                     ReportingMessages_t &message,
258                     int failedMesgId);
259
260 void sendFailedSendingMessagetoXapp(RmrMessagesBuffer_t &rmrMessageBuffer,
261                                     ReportingMessages_t &message,
262                                     int failedMesgId);
263
264 int sendRequestToXapp(ReportingMessages_t &message,
265                       int requestId,
266                       RmrMessagesBuffer_t &rmrMmessageBuffer);
267
268 /**
269  *
270  * @param message
271  * @param msgType
272  * @param requestType
273  * @param rmrMessageBuffer
274  * @param sctpMap
275  * @return
276  */
277 /*
278 int sendResponseToXapp(ReportingMessages_t &message,
279                        int msgType,
280                        int requestType,
281                        RmrMessagesBuffer_t &rmrMessageBuffer,
282                        Sctp_Map_t *sctpMap);
283 */
284
285 /**
286  *
287  * @param peerInfo
288  * @param message
289  * @param m
290  * @return
291  */
292 int sendSctpMsg(ConnectedCU_t *peerInfo,
293                 ReportingMessages_t &message,
294                 Sctp_Map_t *m);
295
296 /**
297  *
298  * @param events
299  * @param sctpMap
300  * @param numOfMessages
301  * @param rmrMessageBuffer
302  * @param ts
303  * @return
304  */
305 int receiveDataFromSctp(struct epoll_event *events,
306                         Sctp_Map_t *sctpMap,
307                         int &numOfMessages,
308                         RmrMessagesBuffer_t &rmrMessageBuffer,
309                         struct timespec &ts);
310
311 /**
312  *
313  * @param rmrAddress
314  * @return
315  */
316 void getRmrContext(sctp_params_t &pSctpParams);
317
318 /**
319  *
320  * @param sctpMap
321  * @param rmrMessageBuffer
322  * @param ts
323  * @return
324  */
325 int receiveXappMessages(Sctp_Map_t *sctpMap,
326                         RmrMessagesBuffer_t &rmrMessageBuffer,
327                         struct timespec &ts);
328
329 /**
330  *
331  * @param messageBuffer
332  * @param failedMsgId
333  * @param sctpMap
334  * @return
335  */
336 int sendDirectionalSctpMsg(RmrMessagesBuffer_t &messageBuffer,
337                            ReportingMessages_t &message,
338                            int failedMsgId,
339                            Sctp_Map_t *sctpMap);
340 /**
341  *
342  * @param pdu
343  * @param message
344  * @param rmrMessageBuffer
345  */
346 void asnInitiatingRequest(E2AP_PDU_t *pdu,
347                           Sctp_Map_t *sctpMap,
348                           ReportingMessages_t &message,
349                           RmrMessagesBuffer_t &rmrMessageBuffer);
350 /**
351  *
352  * @param pdu
353  * @param message
354  * @param sctpMap
355  * @param rmrMessageBuffer
356  */
357 void asnSuccessfulMsg(E2AP_PDU_t *pdu,
358                       Sctp_Map_t *sctpMap,
359                       ReportingMessages_t &message,
360                       RmrMessagesBuffer_t &rmrMessageBuffer);
361 /**
362  *
363  * @param pdu
364  * @param message
365  * @param sctpMap
366  * @param rmrMessageBuffer
367  */
368 void asnUnSuccsesfulMsg(E2AP_PDU_t *pdu,
369                         Sctp_Map_t *sctpMap,
370                         ReportingMessages_t &message,
371                         RmrMessagesBuffer_t &rmrMessageBuffer);
372
373 /**
374  *
375  * @param rmrMessageBuffer
376  * @param message
377  * @return
378  */
379 int sendRmrMessage(RmrMessagesBuffer_t &rmrMessageBuffer, ReportingMessages_t &message);
380 /**
381  *
382  * @param epoll_fd
383  * @param peerInfo
384  * @param events
385  * @param sctpMap
386  * @param enodbName
387  * @param msgType
388  * @returnsrc::logger_mt& lg = my_logger::get();
389  */
390 int addToEpoll(int epoll_fd, ConnectedCU_t *peerInfo, uint32_t events, Sctp_Map_t *sctpMap, char *enodbName, int msgType);
391 /**
392  *
393  * @param epoll_fd
394  * @param peerInfo
395  * @param events
396  * @param sctpMap
397  * @param enodbName
398  * @param msgType
399  * @return
400  */
401 int modifyToEpoll(int epoll_fd, ConnectedCU_t *peerInfo, uint32_t events, Sctp_Map_t *sctpMap, char *enodbName, int msgType);
402
403 /**
404  *
405  * @param message
406  */
407 void buildJsonMessage(ReportingMessages_t &message);
408
409 /**
410  *
411  *
412  * @param state
413  * @return
414  */
415 string translateRmrErrorMessages(int state);
416
417 int buildConfiguration(sctp_params_t &sctpParams);
418 void startPrometheus(sctp_params_t &sctpParams);
419 static int enable_log_change_notify(const char* fileName);
420 static int register_log_change_notify(const char *fileName);
421 static void * monitor_loglevel_change_handler(void* arg);
422 void  update_mdc_log_level_severity(char* log_level);
423 char* getinterfaceip();
424 static char* parse_file(char* filename);
425
426
427 static inline uint64_t rdtscp(uint32_t &aux) {
428     uint64_t rax,rdx;
429     asm volatile ("rdtscp\n" : "=a" (rax), "=d" (rdx), "=c" (aux) : :);
430     return (rdx << (unsigned)32) + rax;
431 }
432 #ifndef RIC_SCTP_CONNECTION_FAILURE
433 #define RIC_SCTP_CONNECTION_FAILURE  10080
434 #endif
435
436 #ifdef UNIT_TEST
437     #define FILE_DESCRIPTOR 53424 /*Dummy value for file descriptor only when UT is defined*/
438 #endif
439
440 int buildListeningPort(sctp_params_t &sctpParams);
441 void buildE2TPrometheusCounters(sctp_params_t &sctpParams);
442
443 #endif //X2_SCTP_THREAD_H