Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include <map>
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netdb.h>
#include <openair2/COMMON/platform_types.h>
#include <openair3/UTILS/conversions.h>
#include "common/utils/LOG/log.h"
#include <common/utils/ocp_itti/intertask_interface.h>
#include <openair2/COMMON/gtpv1_u_messages_types.h>
#include <openair3/ocp-gtpu/gtp_itf.h>
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
#include <openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h>
#include <openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h>
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
#include "sim.h"
#pragma pack(1)
typedef struct Gtpv1uMsgHeader {
uint8_t PN:1;
uint8_t S:1;
uint8_t E:1;
uint8_t spare:1;
uint8_t PT:1;
uint8_t version:3;
uint8_t msgType;
uint16_t msgLength;
teid_t teid;
} __attribute__((packed)) Gtpv1uMsgHeaderT;
//TS 38.425, Figure 5.5.2.2-1
typedef struct DlDataDeliveryStatus_flags {
uint8_t LPR:1; //Lost packet report
uint8_t FFI:1; //Final Frame Ind
uint8_t deliveredPdcpSn:1; //Highest Delivered NR PDCP SN Ind
uint8_t transmittedPdcpSn:1; //Highest Transmitted NR PDCP SN Ind
uint8_t pduType:4; //PDU type
uint8_t CR:1; //Cause Report
uint8_t deliveredReTxPdcpSn:1; //Delivered retransmitted NR PDCP SN Ind
uint8_t reTxPdcpSn:1; //Retransmitted NR PDCP SN Ind
uint8_t DRI:1; //Data Rate Indication
uint8_t deliveredPdcpSnRange:1; //Delivered NR PDCP SN Range Ind
uint8_t spare:3;
uint32_t drbBufferSize; //Desired buffer size for the data radio bearer
} __attribute__((packed)) DlDataDeliveryStatus_flagsT;
typedef struct Gtpv1uMsgHeaderOptFields {
uint8_t seqNum1Oct;
uint8_t seqNum2Oct;
uint8_t NPDUNum;
uint8_t NextExtHeaderType;
} __attribute__((packed)) Gtpv1uMsgHeaderOptFieldsT;
#define DL_PDU_SESSION_INFORMATION 0
#define UL_PDU_SESSION_INFORMATION 1
typedef struct PDUSessionContainer {
uint8_t spare:4;
uint8_t PDU_type:4;
uint8_t QFI:6;
uint8_t Reflective_QoS_activation:1;
uint8_t Paging_Policy_Indicator:1;
} __attribute__((packed)) PDUSessionContainerT;
typedef struct Gtpv1uExtHeader {
uint8_t ExtHeaderLen;
PDUSessionContainerT pdusession_cntr;
uint8_t NextExtHeaderType;
}__attribute__((packed)) Gtpv1uExtHeaderT;
#pragma pack()
// TS 29.281, fig 5.2.1-3
#define PDU_SESSION_CONTAINER (0x85)
#define NR_RAN_CONTAINER (0x84)
// TS 29.281, 5.2.1
#define EXT_HDR_LNTH_OCTET_UNITS (4)
#define NO_MORE_EXT_HDRS (0)
// TS 29.060, table 7.1 defines the possible message types
// here are all the possible messages (3GPP R16)
#define GTP_ECHO_REQ (1)
#define GTP_ECHO_RSP (2)
#define GTP_ERROR_INDICATION (26)
#define GTP_SUPPORTED_EXTENSION_HEADER_INDICATION (31)
#define GTP_END_MARKER (254)
#define GTP_GPDU (255)
typedef struct gtpv1u_bearer_s {
/* TEID used in dl and ul */
teid_t teid_incoming; ///< eNB TEID
teid_t teid_outgoing; ///< Remote TEID
in_addr_t outgoing_ip_addr;
struct in6_addr outgoing_ip6_addr;
tcp_udp_port_t outgoing_port;
uint16_t seqNum;
uint8_t npduNum;
int outgoing_qfi;
} gtpv1u_bearer_t;
typedef struct {
map<ue_id_t, gtpv1u_bearer_t> bearers;
teid_t outgoing_teid;
} teidData_t;
typedef struct {
ue_id_t ue_id;
ebi_t incoming_rb_id;
gtpCallback callBack;
teid_t outgoing_teid;
gtpCallbackSDAP callBackSDAP;
int pdusession_id;
} ueidData_t;
class gtpEndPoint {
public:
openAddr_t addr;
uint8_t foundAddr[20];
int foundAddrLen;
int ipVersion;
map<uint64_t, teidData_t> ue2te_mapping;
// we use the same port number for source and destination address
// this allow using non standard gtp port number (different from 2152)
// and so, for example tu run 4G and 5G cores on one system
tcp_udp_port_t get_dstport() {
return (tcp_udp_port_t)atol(addr.destinationService);
}
};
class gtpEndPoints {
public:
pthread_mutex_t gtp_lock=PTHREAD_MUTEX_INITIALIZER;
// the instance id will be the Linux socket handler, as this is uniq
map<uint64_t, gtpEndPoint> instances;
map<uint64_t, ueidData_t> te2ue_mapping;
gtpEndPoints() {
unsigned int seed;
fill_random(&seed, sizeof(seed));
srandom(seed);
}
~gtpEndPoints() {
// automatically close all sockets on quit
for (const auto &p : instances)
close(p.first);
}
};
gtpEndPoints globGtp;
// note TEid 0 is reserved for specific usage: echo req/resp, error and supported extensions
static teid_t gtpv1uNewTeid(void) {
#ifdef GTPV1U_LINEAR_TEID_ALLOCATION
g_gtpv1u_teid = g_gtpv1u_teid + 1;
return g_gtpv1u_teid;
#else
return random() + random() % (RAND_MAX - 1) + 1;
#endif
}
instance_t legacyInstanceMapping=0;
#define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT ? legacyInstanceMapping:a)
#define getInstRetVoid(insT) \
auto instChk=globGtp.instances.find(compatInst(insT)); \
if (instChk == globGtp.instances.end()) { \
LOG_E(GTPU,"try to get a gtp-u not existing output\n"); \
pthread_mutex_unlock(&globGtp.gtp_lock); \
return; \
} \
gtpEndPoint * inst=&instChk->second;
#define getInstRetInt(insT) \
auto instChk=globGtp.instances.find(compatInst(insT)); \
if (instChk == globGtp.instances.end()) { \
LOG_E(GTPU,"try to get a gtp-u not existing output\n"); \
pthread_mutex_unlock(&globGtp.gtp_lock); \
return GTPNOK; \
} \
gtpEndPoint * inst=&instChk->second;
#define getUeRetVoid(insT, Ue) \
auto ptrUe=insT->ue2te_mapping.find(Ue); \
\
if ( ptrUe==insT->ue2te_mapping.end() ) { \
LOG_E(GTPU, "[%ld] gtpv1uSend failed: while getting ue id %ld in hashtable ue_mapping\n", instance, ue_id); \
pthread_mutex_unlock(&globGtp.gtp_lock); \
return; \
}
Loading
Loading full blame...