Commit 954b0f55 authored by Laurent Thomas's avatar Laurent Thomas

new gtp before tests

parent 06366787
...@@ -2883,8 +2883,8 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer) ...@@ -2883,8 +2883,8 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer)
target_link_libraries (lte-softmodem target_link_libraries (lte-softmodem
-Wl,--start-group -Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE ${GTPV1U} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl) -Wl,--end-group z dl)
......
...@@ -296,6 +296,28 @@ gtp thread calls directly pdcp_data_req(), so it runs inside it's context intern ...@@ -296,6 +296,28 @@ gtp thread calls directly pdcp_data_req(), so it runs inside it's context intern
## inside other threads ## inside other threads
gtpv1u_create_s1u_tunnel(), delete tunnel, ... functions are called inside the other threads, without mutex. gtpv1u_create_s1u_tunnel(), delete tunnel, ... functions are called inside the other threads, without mutex.
# New GTP
## initialization
Coexistance until full merge with legacy GTP
cmake new option: NEW_GTPU to use the new implementation (it changes for the entire executable)
It is possible to use both old and new GTP in same executable because the itti task and all functions names are different
Current status of new implementation: not tested, X2 not developped, 5G new GTP option not developped, remain issues on data coming from void: muid, enb_flag, ...
ocp_gtpv1uTask(): this creates only the thread, doesn't configure anything
gtpv1Init(): creates a listening socket to Linux for a given reception and select a local IP address
newGtpuCreateTunnel() this function will replace the xxx_create_tunnel_xxx() for various cases
This creates a outgoing context for a teid (in input), it computes and return the incoming teid that will be used for incoming packets
These teids and in a "instance", so in a Linux socket: same teid can co-exist for different sockets
Remain here a lack to fill: the information given in the legacy funtions is not enough to fullfil the data needed by the callback
stuff like enb_flag, but also mui and more important data are not given explicitly by any legacy function (gtpv1u_create_s1u_tunnel), but the legacy and the new interface to lower layer (like pdcp) require this data.
The datamodel is still not fully understood, so this data source remain unknown
A new parameter is the callback function: will be pdpcp_data_req() and gtpv_data_req() (x2 case) for existing implementation and later other call backs like the F1-U implementation.
incoming packets
the gtp layer retrieves the data, the teid, find out the related data: rnti, bearer and quite a lot of other parameters (not clear why, because it looks like all is statefull, so the lower layer should have the context)
if lower layers can be stateless, it is a good idea to keep the context in the gtp layer and pass it to the callback, but the design remain obfuscated.
# NGAP # NGAP
NGAP would be a itti thread as is S1AP (+twin thread SCTP that is almost void processing)? NGAP would be a itti thread as is S1AP (+twin thread SCTP that is almost void processing)?
About all messages are exchanged with RRC thread About all messages are exchanged with RRC thread
......
...@@ -170,6 +170,8 @@ typedef struct gtpv1u_enb_end_marker_ind_s { ...@@ -170,6 +170,8 @@ typedef struct gtpv1u_enb_end_marker_ind_s {
typedef struct { typedef struct {
in_addr_t enb_ip_address_for_S1u_S12_S4_up; in_addr_t enb_ip_address_for_S1u_S12_S4_up;
tcp_udp_port_t enb_port_for_S1u_S12_S4_up; tcp_udp_port_t enb_port_for_S1u_S12_S4_up;
char addrStr[256];
char portStr[256];
} Gtpv1uS1Req; } Gtpv1uS1Req;
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */ #endif /* GTPV1_U_MESSAGES_TYPES_H_ */
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include "enb_paramdef.h" #include "enb_paramdef.h"
#include "proto_agent.h" #include "proto_agent.h"
#include "executables/thread-common.h" #include "executables/thread-common.h"
#include <openair3/ocp-gtpu/gtp_itf.h>
extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw); extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw);
...@@ -2055,7 +2056,9 @@ int RCconfig_gtpu(void ) { ...@@ -2055,7 +2056,9 @@ int RCconfig_gtpu(void ) {
IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = enb_port_for_S1U; GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = enb_port_for_S1U;
itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address);
sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", enb_port_for_S1U);
itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
} else } else
LOG_E(GTPU,"invalid address for S1U\n"); LOG_E(GTPU,"invalid address for S1U\n");
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
//#include "RRC_config_tools.h" //#include "RRC_config_tools.h"
#include "gnb_paramdef.h" #include "gnb_paramdef.h"
#include "NR_MAC_gNB/mac_proto.h" #include "NR_MAC_gNB/mac_proto.h"
#include <openair3/ocp-gtpu/gtp_itf.h>
#include "NR_asn_constant.h" #include "NR_asn_constant.h"
#include "executables/thread-common.h" #include "executables/thread-common.h"
...@@ -740,8 +741,9 @@ int RCconfig_nr_gtpu(void ) { ...@@ -740,8 +741,9 @@ int RCconfig_nr_gtpu(void ) {
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_NGU; GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_NGU;
} }
strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address);
itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", gnb_port_for_NGU);
itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
} else } else
LOG_E(GTPU,"invalid address for NGU\n"); LOG_E(GTPU,"invalid address for NGU\n");
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
# include "gtpv1u_eNB_task.h" # include "gtpv1u_eNB_task.h"
# include "gtpv1u.h" # include "gtpv1u.h"
#include <openair3/ocp-gtpu/gtp_itf.h>
#include "ENB_APP/enb_config.h" #include "ENB_APP/enb_config.h"
...@@ -937,7 +938,7 @@ pdcp_data_ind( ...@@ -937,7 +938,7 @@ pdcp_data_ind(
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4;
itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p);
packet_forwarded = TRUE; packet_forwarded = TRUE;
} }
} else { } else {
......
...@@ -242,17 +242,18 @@ typedef struct pdcp_mbms_s { ...@@ -242,17 +242,18 @@ typedef struct pdcp_mbms_s {
* \note None * \note None
* @ingroup _pdcp * @ingroup _pdcp
*/ */
boolean_t pdcp_data_req( boolean_t pdcp_data_req(
protocol_ctxt_t *ctxt_pP, protocol_ctxt_t *ctxt_pP,
const srb_flag_t srb_flagP, const srb_flag_t srb_flagP,
const rb_id_t rb_id, const rb_id_t rb_id,
const mui_t muiP, const mui_t muiP,
const confirm_t confirmP, \ const confirm_t confirmP,
const sdu_size_t sdu_buffer_size, const sdu_size_t sdu_buffer_size,
unsigned char *const sdu_buffer, unsigned char *const sdu_buffer,
const pdcp_transmission_mode_t mode, const pdcp_transmission_mode_t mode,
const uint32_t *const sourceL2Id, const uint32_t * sourceL2Id,
const uint32_t *const destinationL2Id const uint32_t * destinationL2Id
); );
/*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t) /*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t)
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
/* from OAI */ /* from OAI */
#include "pdcp.h" #include "pdcp.h"
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include <openair3/ocp-gtpu/gtp_itf.h>
#define TODO do { \ #define TODO do { \
printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \ printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
...@@ -442,7 +443,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, ...@@ -442,7 +443,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size);
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]);
//printf("\n"); //printf("\n");
itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p);
} }
} }
......
...@@ -5034,7 +5034,7 @@ void rrc_eNB_handover_ue_context_release( ...@@ -5034,7 +5034,7 @@ void rrc_eNB_handover_ue_context_release(
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
} }
itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); itti_send_msg_to_task(TASK_VARIABLE, ctxt_pP->module_id, msg_delete_tunnels_p);
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id);
......
...@@ -1763,7 +1763,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms ...@@ -1763,7 +1763,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms
} }
} }
itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p); itti_send_msg_to_task(TASK_VARIABLE, instance, msg_delete_tunnels_p);
//S1AP_E_RAB_RELEASE_RESPONSE //S1AP_E_RAB_RELEASE_RESPONSE
rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid); rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
} }
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
#include <openair2/RRC/NR/rrc_gNB_UE_context.h> #include <openair2/RRC/NR/rrc_gNB_UE_context.h>
#include <openair3/ocp-gtpu/gtp_itf.h>
extern boolean_t nr_rrc_pdcp_config_asn1_req( extern boolean_t nr_rrc_pdcp_config_asn1_req(
const protocol_ctxt_t *const ctxt_pP, const protocol_ctxt_t *const ctxt_pP,
...@@ -341,7 +342,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { ...@@ -341,7 +342,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0; ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0;
} }
itti_send_msg_to_task(TASK_GTPV1_U, rrc->module_id, msg_delete_tunnels_p); itti_send_msg_to_task(TASK_VARIABLE, rrc->module_id, msg_delete_tunnels_p);
/* remove context */ /* remove context */
rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context); rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context);
......
#include <map>
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
...@@ -10,9 +16,8 @@ ...@@ -10,9 +16,8 @@
#include <common/utils/ocp_itti/intertask_interface.h> #include <common/utils/ocp_itti/intertask_interface.h>
#include <openair2/COMMON/gtpv1_u_messages_types.h> #include <openair2/COMMON/gtpv1_u_messages_types.h>
#include <openair3/ocp-gtpu/gtp_itf.h> #include <openair3/ocp-gtpu/gtp_itf.h>
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
//#include <openair1/PHY/phy_extern.h> //#include <openair1/PHY/phy_extern.h>
#include <map>
using namespace std;
#pragma pack(1) #pragma pack(1)
...@@ -25,13 +30,13 @@ typedef struct Gtpv1uMsgHeader { ...@@ -25,13 +30,13 @@ typedef struct Gtpv1uMsgHeader {
uint8_t version:3; uint8_t version:3;
uint8_t msgType; uint8_t msgType;
uint16_t msgLength; uint16_t msgLength;
uint32_t teid; teid_t teid;
} __attribute__((packed)) Gtpv1uMsgHeaderT; } __attribute__((packed)) Gtpv1uMsgHeaderT;
#pragma pack() #pragma pack()
// TS 29.060, table 7.1 defines the possible message types // TS 29.060, table 7.1 defines the possible message types
// here are all the possible messages (3GPP R16) // here are all the possible messages (3GPP R16)
#define GTP_ECHO_REQ (1) #define GTP_ECHO_REQ (1)
#define GTP_ECHO_RSP (2) #define GTP_ECHO_RSP (2)
#define GTP_ERROR_INDICATION (26) #define GTP_ERROR_INDICATION (26)
...@@ -57,11 +62,14 @@ typedef struct { ...@@ -57,11 +62,14 @@ typedef struct {
typedef struct { typedef struct {
rnti_t rnti; rnti_t rnti;
gtpCallback callBack;
} rntiData_t; } rntiData_t;
class gtpEndPoint { class gtpEndPoint {
public: public:
openAddr_t addr; openAddr_t addr;
uint8_t foundAddr[20];
int foundAddrLen;
map<int,teidData_t> ue2te_mapping; map<int,teidData_t> ue2te_mapping;
map<int,rntiData_t> te2ue_mapping; map<int,rntiData_t> te2ue_mapping;
}; };
...@@ -75,10 +83,6 @@ class gtpEndPoints { ...@@ -75,10 +83,6 @@ class gtpEndPoints {
gtpEndPoints globGtp; gtpEndPoints globGtp;
#ifdef __cplusplus
extern "C" {
#endif
static uint32_t gtpv1uNewTeid(void) { static uint32_t gtpv1uNewTeid(void) {
#ifdef GTPV1U_LINEAR_TEID_ALLOCATION #ifdef GTPV1U_LINEAR_TEID_ALLOCATION
g_gtpv1u_teid = g_gtpv1u_teid + 1; g_gtpv1u_teid = g_gtpv1u_teid + 1;
...@@ -90,7 +94,7 @@ static uint32_t gtpv1uNewTeid(void) { ...@@ -90,7 +94,7 @@ static uint32_t gtpv1uNewTeid(void) {
#define GTPV1U_HEADER_SIZE (8) #define GTPV1U_HEADER_SIZE (8)
static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, uint32_t teid, uint8_t *Msg,int msgLen, static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, teid_t teid, uint8_t *Msg,int msgLen,
bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) { bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) {
AssertFatal(extHdrFlag==false,"Not developped"); AssertFatal(extHdrFlag==false,"Not developped");
int headerAdditional=0; int headerAdditional=0;
...@@ -203,6 +207,11 @@ static int udpServerSocket(openAddr_s addr) { ...@@ -203,6 +207,11 @@ static int udpServerSocket(openAddr_s addr) {
close(sockfd); close(sockfd);
LOG_W(GTPU,"bind: %s\n", strerror(errno)); LOG_W(GTPU,"bind: %s\n", strerror(errno));
continue; continue;
} else {
// We create the gtp instance on the socket
globGtp.instances[sockfd].addr=addr;
memcpy(globGtp.instances[sockfd].foundAddr, p->ai_addr, p->ai_addrlen);
globGtp.instances[sockfd].foundAddrLen=p->ai_addrlen;
} }
break; // if we get here, we must have connected successfully break; // if we get here, we must have connected successfully
...@@ -215,6 +224,28 @@ static int udpServerSocket(openAddr_s addr) { ...@@ -215,6 +224,28 @@ static int udpServerSocket(openAddr_s addr) {
} }
freeaddrinfo(servinfo); // all done with this structure freeaddrinfo(servinfo); // all done with this structure
if (strlen(addr.destinationHost)>1) {
struct addrinfo hints;
memset(&hints,0,sizeof(hints));
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_protocol=0;
hints.ai_flags=AI_PASSIVE|AI_ADDRCONFIG;
struct addrinfo *res=0;
int err=getaddrinfo(addr.destinationHost,addr.destinationService,&hints,&res);
if (err==0) {
for(p = res; p != NULL; p = p->ai_next) {
if ((err=connect(sockfd, p->ai_addr, p->ai_addrlen))==0)
break;
}
}
if (err)
LOG_E(GTPU,"Can't filter remote host: %s, %s\n", addr.destinationHost,addr.destinationService);
}
int sendbuff = 1000*1000*10; int sendbuff = 1000*1000*10;
AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),""); AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),"");
LOG_D(GTPU,"Created listener for paquets to: %s:%s, send buffer size: %d\n", addr.originHost, addr.originService,sendbuff); LOG_D(GTPU,"Created listener for paquets to: %s:%s, send buffer size: %d\n", addr.originHost, addr.originService,sendbuff);
...@@ -226,113 +257,90 @@ instance_t ocp_gtpv1Init(openAddr_t context) { ...@@ -226,113 +257,90 @@ instance_t ocp_gtpv1Init(openAddr_t context) {
int id=udpServerSocket(context); int id=udpServerSocket(context);
if (id>=0) { if (id>=0) {
globGtp.instances[id].addr=context;
itti_subscribe_event_fd(OCP_GTPV1_U, id); itti_subscribe_event_fd(OCP_GTPV1_U, id);
} else } else
LOG_E(GTPU,"can't create GTP-U instance\n"); LOG_E(GTPU,"can't create GTP-U instance\n");
pthread_mutex_unlock(&globGtp.gtp_lock); pthread_mutex_unlock(&globGtp.gtp_lock);
return id; return id;
} }
int ocp_gtpv1u_create_s1u_tunnel(instance_t instance, teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t teid, transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req,
gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) {
LOG_D(GTPU, "Start create tunnels for RNTI %x, num_tunnels %d, sgw_S1u_teid %d\n",
create_tunnel_req->rnti,
create_tunnel_req->num_tunnels,
create_tunnel_req->sgw_S1u_teid[0]);
pthread_mutex_lock(&globGtp.gtp_lock); pthread_mutex_lock(&globGtp.gtp_lock);
auto inst=&globGtp.instances[instance]; auto inst=&globGtp.instances[instance];
auto it=inst->ue2te_mapping.find(create_tunnel_req->rnti); auto it=inst->ue2te_mapping.find(rnti);
if ( it != inst->ue2te_mapping.end() ) { if ( it != inst->ue2te_mapping.end() ) {
LOG_W(GTPU,"Create a config for a already existing GTP tunnel (rnti %x)\n", create_tunnel_req->rnti); LOG_W(GTPU,"Create a config for a already existing GTP tunnel (rnti %x)\n", rnti);
inst->ue2te_mapping.erase(it); inst->ue2te_mapping.erase(it);
} }
rntiData_t rntiData= {create_tunnel_req->rnti}; uint32_t s1u_teid=gtpv1uNewTeid();
for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { while ( inst->te2ue_mapping.find(s1u_teid) != inst->te2ue_mapping.end() ) {
ocp_gtpv1u_bearer_t gtpv1u_ue_data; LOG_W(GTPU, "generated a random Teid that exists, re-generating (%u)\n",s1u_teid);
uint32_t s1u_teid=gtpv1uNewTeid(); s1u_teid=gtpv1uNewTeid();
};
while ( inst->te2ue_mapping.find(s1u_teid) != inst->te2ue_mapping.end() ) { inst->te2ue_mapping[s1u_teid].rnti=rnti;
LOG_W(GTPU, "generated a random Teid that exists, re-generating (%u)\n",s1u_teid);
s1u_teid=gtpv1uNewTeid();
};
inst->te2ue_mapping[s1u_teid]=rntiData; inst->te2ue_mapping[s1u_teid].callBack=callBack;
int addrs_length_in_bytes = create_tunnel_req->sgw_addr[i].length / 8; auto tmp=&inst->ue2te_mapping[rnti].bearers[bearer_id];
switch (addrs_length_in_bytes) { int addrs_length_in_bytes = remoteAddr.length / 8;
case 4:
memcpy(&gtpv1u_ue_data.outgoing_ip_addr,create_tunnel_req->sgw_addr[i].buffer,4);
break;
case 16: switch (addrs_length_in_bytes) {
memcpy(&gtpv1u_ue_data.outgoing_ip6_addr.s6_addr, case 4:
create_tunnel_req->sgw_addr[i].buffer, memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4);
16); break;
break;
case 20: case 16:
memcpy(&gtpv1u_ue_data.outgoing_ip_addr,create_tunnel_req->sgw_addr[i].buffer,4); memcpy(tmp->outgoing_ip6_addr.s6_addr,remoteAddr.buffer,
memcpy(&gtpv1u_ue_data.outgoing_ip6_addr.s6_addr, 16);
create_tunnel_req->sgw_addr[i].buffer+4, break;
16);
default: case 20:
AssertFatal(false, "SGW Address size impossible"); memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4);
} memcpy(&tmp->outgoing_ip6_addr.s6_addr,
remoteAddr.buffer+4,
16);
default:
AssertFatal(false, "SGW Address size impossible");
}
tmp->teid_incoming = s1u_teid;
tmp->outgoing_port=port;
tmp->teid_outgoing= teid;
pthread_mutex_unlock(&globGtp.gtp_lock);
return s1u_teid;
}
int ocp_gtpv1u_create_s1u_tunnel(instance_t instance,
const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req,
gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) {
LOG_D(GTPU, "Start create tunnels for RNTI %x, num_tunnels %d, sgw_S1u_teid %d\n",
create_tunnel_req->rnti,
create_tunnel_req->num_tunnels,
create_tunnel_req->sgw_S1u_teid[0]);
gtpv1u_ue_data.teid_incoming = s1u_teid; for (int i = 0; i < create_tunnel_req->num_tunnels; i++) {
gtpv1u_ue_data.outgoing_port=2152; teid_t teid=newGtpuCreateTunnel(instance, create_tunnel_req->rnti,
gtpv1u_ue_data.teid_outgoing= create_tunnel_req->sgw_S1u_teid[i]; create_tunnel_req->eps_bearer_id[i],
inst->ue2te_mapping[create_tunnel_req->rnti].bearers[create_tunnel_req->eps_bearer_id[i]]=gtpv1u_ue_data; create_tunnel_req->eps_bearer_id[i],
LOG_D(GTPU, "Created tunnel %x for RNTI %x, SGW: " IPV4_ADDR ":%d\n", create_tunnel_req->sgw_addr[i], 2152,
s1u_teid, create_tunnel_req->rnti, pdcp_data_req);
IPV4_ADDR_FORMAT(inst->ue2te_mapping[create_tunnel_req->rnti].bearers[create_tunnel_req->eps_bearer_id[i]].outgoing_ip_addr),
inst->ue2te_mapping[create_tunnel_req->rnti].bearers[create_tunnel_req->eps_bearer_id[i]].outgoing_port );
create_tunnel_resp->status=0; create_tunnel_resp->status=0;
create_tunnel_resp->rnti=create_tunnel_req->rnti; create_tunnel_resp->rnti=create_tunnel_req->rnti;
create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels;
create_tunnel_resp->enb_S1u_teid[i]=gtpv1u_ue_data.teid_incoming; create_tunnel_resp->enb_S1u_teid[i]=teid;
create_tunnel_resp->eps_bearer_id[i] = create_tunnel_req->eps_bearer_id[i]; create_tunnel_resp->eps_bearer_id[i] = create_tunnel_req->eps_bearer_id[i];
//TBD: fix me this is quite bad, for IPv4 only and memcpy(create_tunnel_resp->enb_addr.buffer,globGtp.instances[instance].foundAddr,
// Overcomplex stuff to fill InitialContextSetupResponse in S1AP globGtp.instances[instance].foundAddrLen);
int status; create_tunnel_resp->enb_addr.length= globGtp.instances[instance].foundAddrLen;
struct addrinfo hints= {0}, *servinfo, *p;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
openAddr_t *addr=&globGtp.instances[instance].addr;
if ((status = getaddrinfo(addr->originHost, addr->originService, &hints, &servinfo)) != 0) {
LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status));
pthread_mutex_unlock(&globGtp.gtp_lock);
return -1;
}
// TBD: we take the first IPv4 addr, but it should be coded in the right way
for(p = servinfo; p != NULL; p = p->ai_next)
if (p->ai_family == AF_INET) {
struct sockaddr_in *ipv4P=(struct sockaddr_in *)p->ai_addr;
memcpy(create_tunnel_resp->enb_addr.buffer,
&ipv4P->sin_addr.s_addr, sizeof(ipv4P->sin_addr.s_addr));
create_tunnel_resp->enb_addr.length = sizeof(ipv4P->sin_addr.s_addr);
break;
}
if ( p == NULL )
LOG_E(GTPU,"can't translate IP address string: %s\n",addr->originHost);
freeaddrinfo(servinfo); // all done with this structure
} }
pthread_mutex_unlock(&globGtp.gtp_lock);
return !GTPNOK; return !GTPNOK;
} }
...@@ -358,9 +366,9 @@ int ocp_gtpv1u_update_s1u_tunnel( ...@@ -358,9 +366,9 @@ int ocp_gtpv1u_update_s1u_tunnel(
if ( it != inst->ue2te_mapping.end() ) { if ( it != inst->ue2te_mapping.end() ) {
LOG_W(GTPU,"Update a not existing tunnel, start create the new one (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti); LOG_W(GTPU,"Update a not existing tunnel, start create the new one (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti);
pthread_mutex_unlock(&globGtp.gtp_lock);
gtpv1u_enb_create_tunnel_resp_t tmp; gtpv1u_enb_create_tunnel_resp_t tmp;
(void)ocp_gtpv1u_create_s1u_tunnel(instance, create_tunnel_req, &tmp); (void)ocp_gtpv1u_create_s1u_tunnel(instance, create_tunnel_req, &tmp);
pthread_mutex_unlock(&globGtp.gtp_lock);
return 0; return 0;
} }
...@@ -369,16 +377,16 @@ int ocp_gtpv1u_update_s1u_tunnel( ...@@ -369,16 +377,16 @@ int ocp_gtpv1u_update_s1u_tunnel(
pthread_mutex_unlock(&globGtp.gtp_lock); pthread_mutex_unlock(&globGtp.gtp_lock);
return 0; return 0;
} }
int ocp_gtpv1u_create_x2u_tunnel( int ocp_gtpv1u_create_x2u_tunnel(
const instance_t instanceP, const instance_t instanceP,
const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP, const gtpv1u_enb_create_x2u_tunnel_req_t *const create_tunnel_req_pP,
gtpv1u_enb_create_x2u_tunnel_resp_t * const create_tunnel_resp_pP){ gtpv1u_enb_create_x2u_tunnel_resp_t *const create_tunnel_resp_pP) {
AssertFatal( false, "to be developped\n"); AssertFatal( false, "to be developped\n");
} }
int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance,
const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { const gtpv1u_enb_delete_tunnel_req_t *const req_pP) {
LOG_D(GTPU, "Start delete tunnels for RNTI %x, num_erab %d, eps_bearer_id %d \n", LOG_D(GTPU, "Start delete tunnels for RNTI %x, num_erab %d, eps_bearer_id %d \n",
req_pP->rnti, req_pP->rnti,
req_pP->num_erab, req_pP->num_erab,
...@@ -422,22 +430,22 @@ static int Gtpv1uHandleError(int h, ...@@ -422,22 +430,22 @@ static int Gtpv1uHandleError(int h,
int rc = GTPNOK; int rc = GTPNOK;
return rc; return rc;
} }
static int Gtpv1uHandleSupportedExt(int h, static int Gtpv1uHandleSupportedExt(int h,
uint8_t *msgBuf, uint8_t *msgBuf,
uint32_t msgBufLen, uint32_t msgBufLen,
uint16_t peerPort, uint16_t peerPort,
uint32_t peerIp) { uint32_t peerIp) {
LOG_E(GTPU,"to be dev\n"); LOG_E(GTPU,"to be dev\n");
int rc = GTPNOK; int rc = GTPNOK;
return rc; return rc;
} }
static int Gtpv1uHandleEndMarker(int h, static int Gtpv1uHandleEndMarker(int h,
uint8_t *msgBuf, uint8_t *msgBuf,
uint32_t msgBufLen, uint32_t msgBufLen,
uint16_t peerPort, uint16_t peerPort,
uint32_t peerIp) { uint32_t peerIp) {
LOG_E(GTPU,"to be dev\n"); LOG_E(GTPU,"to be dev\n");
int rc = GTPNOK; int rc = GTPNOK;
return rc; return rc;
...@@ -460,52 +468,52 @@ static int Gtpv1uHandleGpdu(int h, ...@@ -460,52 +468,52 @@ static int Gtpv1uHandleGpdu(int h,
auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid)); auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid));
if ( tunnel == inst->te2ue_mapping.end() ) { if ( tunnel == inst->te2ue_mapping.end() ) {
LOG_E(GTPU,"Received a incoming packet on non open teid (%d)\n", msgHdr->teid); LOG_E(GTPU,"Received a incoming packet on unknown teid (%d) Dropping!\n", msgHdr->teid);
pthread_mutex_unlock(&globGtp.gtp_lock); pthread_mutex_unlock(&globGtp.gtp_lock);
return GTPNOK; return GTPNOK;
} }
int offset=8; int offset=8;
if( msgHdr->E || msgHdr->S ||msgHdr->PN) if( msgHdr->E || msgHdr->S ||msgHdr->PN)
offset+=4; offset+=4;
/*
gtpv1u_enb_tunnel_data_ind_t tmp; // This context is not good for gtp
// frame, ... has no meaning
// manyother attributes may come from create tunnel
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
ctxt.module_id = 0; ctxt.module_id = 0;
ctxt.enb_flag = 1; ctxt.enb_flag = 1;
ctxt.instance = 0; ctxt.instance = inst->addr.originInstance;
ctxt.frame = 0; ctxt.rnti = tunnel->second.rnti;
ctxt.subframe = 0; ctxt.frame = 0;
ctxt.eNB_index = 0; ctxt.subframe = 0;
ctxt.configured = 1; ctxt.eNB_index = 0;
ctxt.brOption = 0; ctxt.configured = 1;
result = pdcp_data_req(&ctxt, ctxt.brOption = 0;
SRB_FLAG_YES, const srb_flag_t srb_flag=SRB_FLAG_NO;
RRC_DCCH_DATA_REQ(msg_p).rb_id, const rb_id_t rb_id=0;
RRC_DCCH_DATA_REQ(msg_p).muip, const mui_t mui=RLC_MUI_UNDEFINED;
RRC_DCCH_DATA_REQ(msg_p).confirmp, const confirm_t confirm=RLC_SDU_CONFIRM_NO;
RRC_DCCH_DATA_REQ(msg_p).sdu_size, const sdu_size_t sdu_buffer_size=msgBufLen-offset;
RRC_DCCH_DATA_REQ(msg_p).sdu_p, unsigned char *const sdu_buffer=msgBuf+offset;
RRC_DCCH_DATA_REQ(msg_p).mode, const pdcp_transmission_mode_t mode=PDCP_TRANSMISSION_MODE_DATA;
NULL, NULL); const uint32_t sourceL2Id=0;
const uint32_t destinationL2Id=0;
ctxt.rnti = rnti;
pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf,
PDCP_TRANSMISSION_MODE_DATA, NULL, NULL);
MessageDef *msg_p=itti_alloc_new_message_sized(OCP_GTPV1_U,GTPV1U_ENB_TUNNEL_DATA_IND,
sizeof(MessageDef) + msgBufLen);
GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).buffer=(uint8_t *)(msg_p+1);
memcpy(GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).buffer,msgBuf,msgBufLen);
GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).length=msgBufLen;
GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).offset=offset;
pthread_mutex_unlock(&globGtp.gtp_lock); pthread_mutex_unlock(&globGtp.gtp_lock);
inst->addr.dlCallBack(msg_p);
*/ if ( !tunnel->second.callBack(&ctxt,
// could be a full itti msg, make it in the call back if you need srb_flag,
//itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(0), msg_p); rb_id,
mui,
confirm,
sdu_buffer_size,
sdu_buffer,
mode,
&sourceL2Id,
&destinationL2Id) )
LOG_E(GTPU,"down layer refused incoming packet\n");
LOG_D(GTPU,"Received a %d bytes packet for: teid:%x\n", LOG_D(GTPU,"Received a %d bytes packet for: teid:%x\n",
msgBufLen-offset, msgBufLen-offset,
ntohl(msgHdr->teid)); ntohl(msgHdr->teid));
...@@ -541,26 +549,28 @@ void gtpv1uReceiver(int h) { ...@@ -541,26 +549,28 @@ void gtpv1uReceiver(int h) {
case GTP_ERROR_INDICATION: case GTP_ERROR_INDICATION:
Gtpv1uHandleError( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); Gtpv1uHandleError( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr);
break; break;
case GTP_SUPPORTED_EXTENSION_HEADER_INDICATION: case GTP_SUPPORTED_EXTENSION_HEADER_INDICATION:
Gtpv1uHandleSupportedExt( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); Gtpv1uHandleSupportedExt( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr);
break; break;
case GTP_END_MARKER: case GTP_END_MARKER:
Gtpv1uHandleEndMarker( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); Gtpv1uHandleEndMarker( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr);
break; break;
case GTP_GPDU: case GTP_GPDU:
Gtpv1uHandleGpdu( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); Gtpv1uHandleGpdu( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr);
break; break;
default: default:
LOG_E(GTPU, "Received a GTP packet of unknown type: %d\n",msgType); LOG_E(GTPU, "Received a GTP packet of unknown type: %d\n",msgType);
break; break;
} }
} }
} }
#include <openair2/ENB_APP/enb_paramdef.h>
void *ocp_gtpv1uTask(void *args) { void *ocp_gtpv1uTask(void *args) {
while(1) { while(1) {
/* Trying to fetch a message from the message queue. /* Trying to fetch a message from the message queue.
...@@ -571,6 +581,8 @@ void *ocp_gtpv1uTask(void *args) { ...@@ -571,6 +581,8 @@ void *ocp_gtpv1uTask(void *args) {
itti_receive_msg(OCP_GTPV1_U, &message_p); itti_receive_msg(OCP_GTPV1_U, &message_p);
if (message_p != NULL ) { if (message_p != NULL ) {
openAddr_t addr= {0};
switch (ITTI_MSG_ID(message_p)) { switch (ITTI_MSG_ID(message_p)) {
// DATA TO BE SENT TO UDP // DATA TO BE SENT TO UDP
case GTPV1U_ENB_TUNNEL_DATA_REQ: { case GTPV1U_ENB_TUNNEL_DATA_REQ: {
...@@ -587,19 +599,24 @@ void *ocp_gtpv1uTask(void *args) { ...@@ -587,19 +599,24 @@ void *ocp_gtpv1uTask(void *args) {
LOG_E(GTPU, "Received unexpected timer expired (no need of timers in this version) %s\n", ITTI_MSG_NAME(message_p)); LOG_E(GTPU, "Received unexpected timer expired (no need of timers in this version) %s\n", ITTI_MSG_NAME(message_p));
break; break;
case GTPV1U_ENB_DATA_FORWARDING_REQ:
case GTPV1U_ENB_DATA_FORWARDING_REQ: case GTPV1U_ENB_DATA_FORWARDING_IND:
case GTPV1U_ENB_DATA_FORWARDING_IND: case GTPV1U_ENB_END_MARKER_REQ:
case GTPV1U_ENB_END_MARKER_REQ: case GTPV1U_ENB_END_MARKER_IND:
case GTPV1U_ENB_END_MARKER_IND: LOG_E(GTPU, "to be developped %s\n", ITTI_MSG_NAME(message_p));
case GTPV1U_ENB_S1_REQ: abort();
LOG_E(GTPU, "to be developped %s\n", ITTI_MSG_NAME(message_p)); break;
abort();
break; case GTPV1U_ENB_S1_REQ:
// to be dev: should be removed, to use API
default: strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr);
LOG_E(GTPU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr);
abort(); AssertFatal(ocp_gtpv1Init(addr),"Only one instance 0 supprted\n");
break;
default:
LOG_E(GTPU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
abort();
break; break;
} }
......
#ifndef __UDP_ITF_H__ #ifndef __GTPUNEW_ITF_H__
#define __UDP_ITF_H__ #define __GTPUNEW_ITF_H__
#define GTPNOK -1 #define GTPNOK -1
# define GTPU_HEADER_OVERHEAD_MAX 64 # define GTPU_HEADER_OVERHEAD_MAX 64
...@@ -9,11 +9,27 @@ extern "C" { ...@@ -9,11 +9,27 @@ extern "C" {
#include <openair3/GTPV1-U/gtpv1u_eNB_defs.h> #include <openair3/GTPV1-U/gtpv1u_eNB_defs.h>
#if defined(NEW_GTPU) #if defined(NEW_GTPU)
#define gtpv1u_create_s1u_tunnel ocp_gtpv1u_create_s1u_tunnel #define gtpv1u_create_s1u_tunnel ocp_gtpv1u_create_s1u_tunnel
#define gtpv1u_update_s1u_tunnel ocp_gtpv1u_update_s1u_tunnel #define gtpv1u_update_s1u_tunnel ocp_gtpv1u_update_s1u_tunnel
#define gtpv1u_delete_s1u_tunnel ocp_gtpv1u_delete_s1u_tunnel #define gtpv1u_delete_s1u_tunnel ocp_gtpv1u_delete_s1u_tunnel
#define gtpv1u_create_x2u_tunnel ocp_gtpv1u_create_x2u_tunnel #define gtpv1u_create_x2u_tunnel ocp_gtpv1u_create_x2u_tunnel
#endif #define gtpv1u_eNB_task ocp_gtpv1uTask
#define TASK_VARIABLE OCP_GTPV1_U
#else
#define TASK_VARIABLE TASK_GTPV1_U
#endif
typedef boolean_t (*gtpCallback)(
protocol_ctxt_t *ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_idP,
const mui_t muiP,
const confirm_t confirmP,
const sdu_size_t sdu_buffer_sizeP,
unsigned char *const sdu_buffer_pP,
const pdcp_transmission_mode_t modeP,
const uint32_t *sourceL2Id,
const uint32_t *destinationL2Id);
typedef struct openAddr_s { typedef struct openAddr_s {
char originHost[HOST_NAME_MAX]; char originHost[HOST_NAME_MAX];
...@@ -25,7 +41,6 @@ typedef struct openAddr_s { ...@@ -25,7 +41,6 @@ typedef struct openAddr_s {
// the init function create a gtp instance and return the gtp instance id // the init function create a gtp instance and return the gtp instance id
// the parameter originInstance will be sent back in each message from gtp to the creator // the parameter originInstance will be sent back in each message from gtp to the creator
instance_t ocp_gtpv1Init(openAddr_t context);
void ocp_gtpv1uReceiver(int h); void ocp_gtpv1uReceiver(int h);
void ocp_gtpv1uProcessTimeout(int handle,void *arg); void ocp_gtpv1uProcessTimeout(int handle,void *arg);
int ocp_gtpv1u_create_s1u_tunnel(const instance_t instance, const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req, int ocp_gtpv1u_create_s1u_tunnel(const instance_t instance, const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req,
...@@ -36,13 +51,19 @@ int ocp_gtpv1u_update_s1u_tunnel(const instance_t instanceP, ...@@ -36,13 +51,19 @@ int ocp_gtpv1u_update_s1u_tunnel(const instance_t instanceP,
); );
int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP); int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP);
int gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP); int gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP);
int ocp_gtpv1u_create_x2u_tunnel( int ocp_gtpv1u_create_x2u_tunnel(
const instance_t instanceP, const instance_t instanceP,
const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP, const gtpv1u_enb_create_x2u_tunnel_req_t *const create_tunnel_req_pP,
gtpv1u_enb_create_x2u_tunnel_resp_t * const create_tunnel_resp_pP); gtpv1u_enb_create_x2u_tunnel_resp_t *const create_tunnel_resp_pP);
void *ocp_gtpv1uTask(void *args);
// New API
teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t teid,
transport_layer_addr_t remoteAddr, int port, gtpCallback callBack);
instance_t ocp_gtpv1Init(openAddr_t context);
void *ocp_gtpv1uTask(void *args);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment