version 4.0.2
[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 <ctime>
45 #include <netdb.h>
46 #include <sys/epoll.h>
47 #include <mutex>
48 #include <shared_mutex>
49 #include <iterator>
50 #include <map>
51 #include <sys/inotify.h>
52 #include <csignal>
53
54 #include <rmr/rmr.h>
55 #include <rmr/RIC_message_types.h>
56 #include <mdclog/mdclog.h>
57 #include <functional>
58 #include <iostream>
59
60 #include <boost/algorithm/string/predicate.hpp>
61 #include <boost/lexical_cast.hpp>
62 #include <boost/move/utility.hpp>
63 #include <boost/log/sources/logger.hpp>
64 #include <boost/log/sources/record_ostream.hpp>
65 #include <boost/log/sources/global_logger_storage.hpp>
66 #include <boost/log/utility/setup/file.hpp>
67 #include <boost/log/utility/setup/common_attributes.hpp>
68 #include <boost/filesystem.hpp>
69
70 #include <mdclog/mdclog.h>
71
72 #include "oranE2/E2AP-PDU.h"
73 #include "oranE2/ProtocolIE-Container.h"
74 #include "oranE2/InitiatingMessage.h"
75 #include "oranE2/SuccessfulOutcome.h"
76 #include "oranE2/UnsuccessfulOutcome.h"
77 #include "oranE2/ProtocolIE-Container.h"
78 #include "oranE2/ProtocolIE-Field.h"
79 #include "oranE2/GlobalE2node-gNB-ID.h"
80 #include "oranE2/GlobalE2node-en-gNB-ID.h"
81 #include "oranE2/GlobalE2node-ng-eNB-ID.h"
82 #include "oranE2/GlobalE2node-eNB-ID.h"
83
84 #include "cxxopts.hpp"
85 //#include "config-cpp/include/config-cpp/config-cpp.h"
86
87 #ifdef __TRACING__
88 #include "openTracing.h"
89 #endif
90
91 #include "mapWrapper.h"
92
93 #include "base64.h"
94
95 #include "ReadConfigFile.h"
96
97 using namespace std;
98 namespace logging = boost::log;
99 namespace src = boost::log::sources;
100 namespace keywords = boost::log::keywords;
101 namespace sinks = boost::log::sinks;
102 namespace posix_time = boost::posix_time;
103 namespace expr = boost::log::expressions;
104
105 #define SRC_PORT 36422
106 #define SA      struct sockaddr
107 #define MAX_ENODB_NAME_SIZE 64
108
109 #define MAXEVENTS 128
110
111 #define RECEIVE_SCTP_BUFFER_SIZE (8 * 1024)
112 #define RECEIVE_XAPP_BUFFER_SIZE RECEIVE_SCTP_BUFFER_SIZE 
113
114 typedef mapWrapper Sctp_Map_t;
115
116
117 #define VOLUME_URL_SIZE 256
118 #define KA_MESSAGE_SIZE 2048
119
120 typedef struct sctp_params {
121     uint16_t rmrPort = 0;
122     uint16_t sctpPort = SRC_PORT;
123     int      epoll_fd = 0;
124     int      listenFD = 0;
125     int      rmrListenFd = 0;
126     int      inotifyFD = 0;
127     int      inotifyWD = 0;
128     void     *rmrCtx = nullptr;
129     Sctp_Map_t *sctpMap = nullptr;
130     char      ka_message[KA_MESSAGE_SIZE] {};
131     int       ka_message_length = 0;
132     char       rmrAddress[256] {}; // "tcp:portnumber" "tcp:5566" listen to all address on port 5566
133     mdclog_severity_t logLevel = MDCLOG_INFO;
134     char volume[VOLUME_URL_SIZE];
135     string myIP {};
136     string fqdn {};
137     string podName {};
138     string configFilePath {};
139     string configFileName {};
140     bool trace = true;
141     //shared_timed_mutex fence; // moved to mapWrapper
142 } sctp_params_t;
143
144 typedef struct ConnectedCU {
145     int fileDescriptor = 0;
146     char hostName[NI_MAXHOST] {};
147     char portNumber[NI_MAXSERV] {};
148     char enodbName[MAX_ENODB_NAME_SIZE] {};
149     char asnData[RECEIVE_SCTP_BUFFER_SIZE] {};
150     int rcvMsgs = 0;
151     int sentMesgs = 0;
152     size_t asnLength = 0;
153     int mtype = 0;
154     bool isConnected = false;
155     bool gotSetup = false;
156     sctp_params_t *sctpParams = nullptr;
157 } ConnectedCU_t ;
158
159 #define MAX_RMR_BUFF_ARRY 32
160 typedef struct RmrMessagesBuffer {
161     char ka_message[KA_MESSAGE_SIZE] {};
162     int  ka_message_len = 0;
163     void *rmrCtx = nullptr;
164     rmr_mbuf_t *sendMessage= nullptr;
165     rmr_mbuf_t *sendBufferedMessages[MAX_RMR_BUFF_ARRY] {};
166     rmr_mbuf_t *rcvMessage= nullptr;
167     rmr_mbuf_t *rcvBufferedMessages[MAX_RMR_BUFF_ARRY] {};
168 } RmrMessagesBuffer_t;
169
170 typedef struct formatedMessage {
171     char enodbName[MAX_ENODB_NAME_SIZE];
172     struct timespec time;
173     int messageType;
174     char direction;
175     ssize_t asnLength;
176     unsigned char *asndata;
177 } FormatedMessage_t;
178
179 typedef struct ReportingMessages {
180     FormatedMessage_t message {};
181     ConnectedCU_t *peerInfo = nullptr;
182     long outLen = 0;
183     unsigned char base64Data[RECEIVE_SCTP_BUFFER_SIZE * 2] {};
184     char buffer[RECEIVE_SCTP_BUFFER_SIZE * 8] {};
185 } ReportingMessages_t;
186
187 cxxopts::ParseResult parse(int argc, char *argv[], sctp_params_t &pSctpParams);
188
189 int buildInotify(sctp_params_t &sctpParams);
190
191 void handleTermInit(sctp_params_t &sctpParams);
192
193 void handleConfigChange(sctp_params_t *sctpParams);
194
195 void listener(sctp_params_t *params);
196
197 void sendTermInit(sctp_params_t &sctpParams);
198
199 int setSocketNoBlocking(int socket);
200
201 void handleEinprogressMessages(struct epoll_event &event,
202                                ReportingMessages_t &message,
203                                RmrMessagesBuffer_t &rmrMessageBuffer,
204                                sctp_params_t *params);
205
206 void handlepoll_error(struct epoll_event &event,
207                       ReportingMessages_t &message,
208                       RmrMessagesBuffer_t &rmrMessageBuffer,
209                       sctp_params_t *params);
210
211
212 void cleanHashEntry(ConnectedCU_t *peerInfo, Sctp_Map_t *m);
213
214
215 /**
216  *
217  * @param message
218  * @param rmrMessageBuffer
219  */
220 void getRequestMetaData(ReportingMessages_t &message, RmrMessagesBuffer_t &rmrMessageBuffer);
221
222 /**
223  *
224  * @param sctpMap
225  * @param messagBuffer
226  * @param message
227  * @param failedMesgId
228  * @return
229  */
230 int sendMessagetoCu(Sctp_Map_t *sctpMap,
231                     RmrMessagesBuffer_t &messagBuffer,
232                     ReportingMessages_t &message,
233                     int failedMesgId);
234
235 void sendFailedSendingMessagetoXapp(RmrMessagesBuffer_t &rmrMessageBuffer,
236                                     ReportingMessages_t &message,
237                                     int failedMesgId);
238
239 int sendRequestToXapp(ReportingMessages_t &message,
240                       int requestId,
241                       RmrMessagesBuffer_t &rmrMmessageBuffer);
242
243 /**
244  *
245  * @param message
246  * @param msgType
247  * @param requestType
248  * @param rmrMessageBuffer
249  * @param sctpMap
250  * @return
251  */
252 /*
253 int sendResponseToXapp(ReportingMessages_t &message,
254                        int msgType,
255                        int requestType,
256                        RmrMessagesBuffer_t &rmrMessageBuffer,
257                        Sctp_Map_t *sctpMap);
258 */
259
260 /**
261  *
262  * @param peerInfo
263  * @param message
264  * @param m
265  * @return
266  */
267 int sendSctpMsg(ConnectedCU_t *peerInfo,
268                 ReportingMessages_t &message,
269                 Sctp_Map_t *m);
270
271 /**
272  *
273  * @param events
274  * @param sctpMap
275  * @param numOfMessages
276  * @param rmrMessageBuffer
277  * @param ts
278  * @return
279  */
280 int receiveDataFromSctp(struct epoll_event *events,
281                         Sctp_Map_t *sctpMap,
282                         int &numOfMessages,
283                         RmrMessagesBuffer_t &rmrMessageBuffer,
284                         struct timespec &ts);
285
286 /**
287  *
288  * @param rmrAddress
289  * @return
290  */
291 void getRmrContext(sctp_params_t &pSctpParams);
292
293 /**
294  *
295  * @param epoll_fd
296  * @param rmrCtx
297  * @param sctpMap
298  * @param messagBuffer
299  * @return
300  */
301 int receiveXappMessages(Sctp_Map_t *sctpMap,
302                         RmrMessagesBuffer_t &rmrMessageBuffer,
303                         struct timespec &ts);
304
305 /**
306  *
307  * @param messagBuffer
308  * @param failedMsgId
309  * @param sctpMap
310  * @return
311  */
312 int sendDirectionalSctpMsg(RmrMessagesBuffer_t &messagBuffer,
313                            ReportingMessages_t &message,
314                            int failedMsgId,
315                            Sctp_Map_t *sctpMap);
316 /**
317  *
318  * @param pdu
319  * @param message
320  * @param rmrMessageBuffer
321  */
322 void asnInitiatingRequest(E2AP_PDU_t *pdu,
323                           ReportingMessages_t &message,
324                           RmrMessagesBuffer_t &rmrMessageBuffer);
325 /**
326  *
327  * @param pdu
328  * @param message
329  * @param sctpMap
330  * @param rmrMessageBuffer
331  */
332 void asnSuccsesfulMsg(E2AP_PDU_t *pdu,
333                       ReportingMessages_t &message,
334                       RmrMessagesBuffer_t &rmrMessageBuffer);
335 /**
336  *
337  * @param pdu
338  * @param message
339  * @param sctpMap
340  * @param rmrMessageBuffer
341  */
342 void asnUnSuccsesfulMsg(E2AP_PDU_t *pdu,
343                         ReportingMessages_t &message,
344                         RmrMessagesBuffer_t &rmrMessageBuffer);
345
346 /**
347  *
348  * @param rmrMessageBuffer
349  * @param message
350  * @return
351  */
352 int sendRmrMessage(RmrMessagesBuffer_t &rmrMessageBuffer, ReportingMessages_t &message);
353 /**
354  *
355  * @param epoll_fd
356  * @param peerInfo
357  * @param events
358  * @param sctpMap
359  * @param enodbName
360  * @param msgType
361  * @returnsrc::logger_mt& lg = my_logger::get();
362  */
363 int addToEpoll(int epoll_fd, ConnectedCU_t *peerInfo, uint32_t events, Sctp_Map_t *sctpMap, char *enodbName, int msgType);
364 /**
365  *
366  * @param epoll_fd
367  * @param peerInfo
368  * @param events
369  * @param sctpMap
370  * @param enodbName
371  * @param msgType
372  * @return
373  */
374 int modifyToEpoll(int epoll_fd, ConnectedCU_t *peerInfo, uint32_t events, Sctp_Map_t *sctpMap, char *enodbName, int msgType);
375
376 /**
377  *
378  * @param message
379  */
380 void buildJsonMessage(ReportingMessages_t &message);
381
382 /**
383  *
384  *
385  * @param state
386  * @return
387  */
388 string translateRmrErrorMessages(int state);
389
390
391 static inline uint64_t rdtscp(uint32_t &aux) {
392     uint64_t rax,rdx;
393     asm volatile ("rdtscp\n" : "=a" (rax), "=d" (rdx), "=c" (aux) : :);
394     return (rdx << (unsigned)32) + rax;
395 }
396 #ifndef RIC_SCTP_CONNECTION_FAILURE
397 #define RIC_SCTP_CONNECTION_FAILURE  10080
398 #endif
399
400 #endif //X2_SCTP_THREAD_H