From 1c30f69292028960884213eba12a24c22cc3b8b9 Mon Sep 17 00:00:00 2001 From: Lionel Gauthier Date: Thu, 6 Nov 2014 08:41:44 +0000 Subject: [PATCH] git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5982 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair-cn/GTPV1-U/gtpv1u.h | 3 + openair-cn/GTPV1-U/gtpv1u_eNB.c | 11 +- openair-cn/GTPV1-U/gtpv1u_task.c | 116 ++++++++++++++---- .../nw-gtpv1u/include/NwGtpv1uPrivate.h | 4 +- .../GTPV1-U/nw-gtpv1u/shared/NwGtpv1uMsg.h | 1 + openair-cn/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c | 30 +++-- .../GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c | 19 ++- 7 files changed, 135 insertions(+), 49 deletions(-) diff --git a/openair-cn/GTPV1-U/gtpv1u.h b/openair-cn/GTPV1-U/gtpv1u.h index 108208ffdf..109ffb5b7b 100644 --- a/openair-cn/GTPV1-U/gtpv1u.h +++ b/openair-cn/GTPV1-U/gtpv1u.h @@ -51,6 +51,9 @@ # define GTPU_ERROR(x, args...) fprintf(stderr, "[GTPU][E]"x, ##args) #endif +#warning "TO BE REFINED" +# define GTPU_HEADER_OVERHEAD_MAX 64 + uint32_t gtpv1u_new_teid(void); #endif /* GTPV1_U_H_ */ diff --git a/openair-cn/GTPV1-U/gtpv1u_eNB.c b/openair-cn/GTPV1-U/gtpv1u_eNB.c index 9241040680..ce50b34776 100644 --- a/openair-cn/GTPV1-U/gtpv1u_eNB.c +++ b/openair-cn/GTPV1-U/gtpv1u_eNB.c @@ -86,6 +86,7 @@ NwGtpv1uRcT NwGtpv1uUdpHandleT udpHandle, NwU8T *buffer, NwU32T buffer_len, + NwU32T buffer_offset, NwU32T peerIpAddr, NwU16T peerPort); @@ -100,6 +101,7 @@ int uint32_t address, uint8_t *buffer, uint32_t length, + uint32_t offset, void *arg_p); //int //gtpv1u_create_tunnel_endpoint( @@ -187,6 +189,7 @@ NwGtpv1uRcT gtpv1u_eNB_send_udp_msg( NwGtpv1uUdpHandleT udpHandle, NwU8T *buffer, NwU32T buffer_len, + NwU32T buffer_offset, NwU32T peerIpAddr, NwU16T peerPort) { @@ -202,6 +205,7 @@ NwGtpv1uRcT gtpv1u_eNB_send_udp_msg( udp_data_req_p->peer_port = peerPort; udp_data_req_p->buffer = buffer; udp_data_req_p->buffer_length = buffer_len; + udp_data_req_p->buffer_offset = buffer_offset; return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p); } else { return NW_GTPV1U_FAILURE; @@ -858,7 +862,7 @@ void *gtpv1u_eNB_task(void *args) udp_data_ind_p->buffer_length, udp_data_ind_p->peer_port, udp_data_ind_p->peer_address); - itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer); + //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer); } break; @@ -896,6 +900,7 @@ void *gtpv1u_eNB_task(void *args) gtpv1u_data_g.seq_num++, data_req_p->buffer, data_req_p->length, + data_req_p->offset, &(stack_req.apiInfo.sendtoInfo.hMsg)); if (rc != NW_GTPV1U_OK) { @@ -913,8 +918,8 @@ void *gtpv1u_eNB_task(void *args) } } } - /* Buffer is no longer needed, free it */ - itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer); + /* Buffer still needed, do not free it */ + //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer); } break; diff --git a/openair-cn/GTPV1-U/gtpv1u_task.c b/openair-cn/GTPV1-U/gtpv1u_task.c index ed2d706932..053d09671d 100644 --- a/openair-cn/GTPV1-U/gtpv1u_task.c +++ b/openair-cn/GTPV1-U/gtpv1u_task.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "mme_config.h" @@ -62,6 +63,7 @@ NwGtpv1uRcT gtpv1u_send_udp_msg( NwGtpv1uUdpHandleT udpHandle, NwU8T *buffer, NwU32T buffer_len, + NwU32T buffer_offset, NwU32T peerIpAddr, NwU32T peerPort); @@ -76,6 +78,69 @@ NwGtpv1uRcT gtpv1u_process_stack_req( NwGtpv1uUlpHandleT hUlp, NwGtpv1uUlpApiT *pUlpApi); + +//----------------------------------------------------------------------------- +void gtpu_print_hex_octets(unsigned char* dataP, unsigned long sizeP) +//----------------------------------------------------------------------------- +{ + unsigned long octet_index = 0; + unsigned long buffer_marker = 0; + unsigned char aindex; +#define GTPU_2_PRINT_BUFFER_LEN 8000 + char gtpu_2_print_buffer[GTPU_2_PRINT_BUFFER_LEN]; + struct timeval tv; + struct timezone tz; + char timeofday[64]; + unsigned int h,m,s; + + if (dataP == NULL) { + return; + } + + gettimeofday(&tv, &tz); + h = tv.tv_sec/3600/24; + m = (tv.tv_sec / 60) % 60; + s = tv.tv_sec % 60; + snprintf(timeofday, 64, "%02d:%02d:%02d.%06d", h,m,s,tv.tv_usec); + + GTPU_DEBUG("%s------+-------------------------------------------------|\n",timeofday); + GTPU_DEBUG("%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday); + GTPU_DEBUG("%s------+-------------------------------------------------|\n",timeofday); + for (octet_index = 0; octet_index < sizeP; octet_index++) { + if (GTPU_2_PRINT_BUFFER_LEN < (buffer_marker + 32)) { + buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, + "... (print buffer overflow)"); + GTPU_DEBUG("%s%s",timeofday,gtpu_2_print_buffer); + return; + } + if ((octet_index % 16) == 0){ + if (octet_index != 0) { + buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " |\n"); + GTPU_DEBUG("%s%s",timeofday, gtpu_2_print_buffer); + buffer_marker = 0; + } + buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " %04ld |", octet_index); + } + /* + * Print every single octet in hexadecimal form + */ + buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " %02x", dataP[octet_index]); + /* + * Align newline and pipes according to the octets in groups of 2 + */ + } + + /* + * Append enough spaces and put final pipe + */ + for (aindex = octet_index; aindex < 16; ++aindex) + buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " "); + //GTPU_DEBUG(" "); + buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " |\n"); + GTPU_DEBUG("%s%s",timeofday,gtpu_2_print_buffer); +} + + static int gtpv1u_send_init_udp(uint16_t port_number) { // Create and alloc new message @@ -111,6 +176,7 @@ NwGtpv1uRcT gtpv1u_send_udp_msg( NwGtpv1uUdpHandleT udpHandle, NwU8T *buffer, NwU32T buffer_len, + NwU32T buffer_offset, NwU32T peerIpAddr, NwU32T peerPort) { @@ -126,6 +192,7 @@ NwGtpv1uRcT gtpv1u_send_udp_msg( udp_data_req_p->peer_port = peerPort; udp_data_req_p->buffer = buffer; udp_data_req_p->buffer_length = buffer_len; + udp_data_req_p->buffer_offset = buffer_offset; return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p); } @@ -141,34 +208,38 @@ NwGtpv1uRcT gtpv1u_process_stack_req( * - END-MARKER */ case NW_GTPV1U_ULP_API_RECV_TPDU: { - uint8_t buffer[4096]; - uint32_t buffer_len; - MessageDef *message_p; - Gtpv1uTunnelDataInd *data_ind_p; + //uint8_t buffer[4096]; + //uint32_t buffer_len; + MessageDef *message_p = NULL; + Gtpv1uTunnelDataInd *data_ind_p = NULL; /* Nw-gptv1u stack has processed a PDU. we can forward it to IPV4 * task for transmission. */ - if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg, + /*if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg, buffer, (NwU32T *)&buffer_len)) { GTPU_ERROR("Error while retrieving T-PDU\n"); - } - GTPU_DEBUG("Received TPDU from gtpv1u stack %u with size %d\n", pUlpApi->apiInfo.recvMsgInfo.teid, buffer_len); + }*/ + GTPU_DEBUG("Received TPDU from gtpv1u stack %u with size %d\n", + pUlpApi->apiInfo.recvMsgInfo.teid, + ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen); message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_TUNNEL_DATA_IND); if (message_p == NULL) { return -1; } data_ind_p = &message_p->ittiMsg.gtpv1uTunnelDataInd; - data_ind_p->buffer = malloc(sizeof(uint8_t) * buffer_len); + data_ind_p->buffer = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf; + data_ind_p->length = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen; + data_ind_p->offset = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufOffset; data_ind_p->local_S1u_teid = pUlpApi->apiInfo.recvMsgInfo.teid; if (data_ind_p->buffer == NULL) { GTPU_ERROR("Failed to allocate new buffer\n"); itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); message_p = NULL; } else { - memcpy(data_ind_p->buffer, buffer, buffer_len); - data_ind_p->length = buffer_len; + //memcpy(data_ind_p->buffer, buffer, buffer_len); + //data_ind_p->length = buffer_len; if (itti_send_msg_to_task(TASK_FW_IP, INSTANCE_DEFAULT, message_p) < 0) { GTPU_ERROR("Failed to send message to task\n"); itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); @@ -387,7 +458,7 @@ static void *gtpv1u_thread(void *args) udp_data_ind_p->buffer_length, udp_data_ind_p->peer_port, udp_data_ind_p->peer_address); - itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer); + //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer); } break; @@ -400,19 +471,14 @@ static void *gtpv1u_thread(void *args) gtpv1u_teid2enb_info_t *gtpv1u_teid2enb_info = NULL; data_req_p = &received_message_p->ittiMsg.gtpv1uTunnelDataReq; - //ipv4_send_data(ipv4_data_p->sd, data_ind_p->buffer, data_ind_p->length); + + GTPU_DEBUG("-- GTPV1U_TUNNEL_DATA_REQ -----------------------------------------------------\n%s :\n", + __FUNCTION__); + gtpu_print_hex_octets(data_req_p->buffer, data_req_p->length); + memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); - /* - * typedef struct - { - NW_IN NwU32T teid; - NW_IN NwU32T ipAddr; - NW_IN NwU8T flags; - NW_IN NwGtpv1uMsgHandleT hMsg; - } NwGtpv1uSendtoInfoT;*/ - hash_rc = hashtable_get(gtpv1u_sgw_data.S1U_mapping, (uint64_t)data_req_p->local_S1u_teid, (void**)>pv1u_teid2enb_info); if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { @@ -430,8 +496,7 @@ static void *gtpv1u_thread(void *args) NW_IN NwU8T *tpdu, NW_IN NwU16T tpduLength, NW_OUT NwGtpv1uMsgHandleT *phMsg)*/ - GTPU_DEBUG("GTPV1U_TUNNEL_DATA_REQ buffer %p seq num %d %d bytes\n", - data_req_p->buffer, + GTPU_DEBUG("GTPV1U_TUNNEL_DATA_REQ seq num %d %d bytes\n", gtpv1u_sgw_data.seq_num, data_req_p->length); rc = nwGtpv1uGpduMsgNew(gtpv1u_sgw_data.gtpv1u_stack, @@ -440,6 +505,7 @@ static void *gtpv1u_thread(void *args) gtpv1u_sgw_data.seq_num++, data_req_p->buffer, data_req_p->length, + data_req_p->offset, &(stack_req.apiInfo.sendtoInfo.hMsg)); if (rc != NW_GTPV1U_OK) { @@ -456,8 +522,8 @@ static void *gtpv1u_thread(void *args) } } } - /* Buffer is no longer needed, free it */ - itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer); + /* Buffer is still needed, do not free it */ + //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer); } break; case TERMINATE_MESSAGE: { diff --git a/openair-cn/GTPV1-U/nw-gtpv1u/include/NwGtpv1uPrivate.h b/openair-cn/GTPV1-U/nw-gtpv1u/include/NwGtpv1uPrivate.h index 5b9d4bdaee..107a5c6428 100644 --- a/openair-cn/GTPV1-U/nw-gtpv1u/include/NwGtpv1uPrivate.h +++ b/openair-cn/GTPV1-U/nw-gtpv1u/include/NwGtpv1uPrivate.h @@ -166,7 +166,9 @@ typedef struct NwGtpv1uMsg NwU16T seqNum; NwU8T npduNum; NwU8T nextExtHdrType; - NwU8T msgBuf[NW_GTPV1U_MAX_MSG_LEN]; + NwU8T* msgBuf; + NwU32T msgBufLen; + NwU32T msgBufOffset; struct NwGtpv1uMsg* next; } NwGtpv1uMsgT; diff --git a/openair-cn/GTPV1-U/nw-gtpv1u/shared/NwGtpv1uMsg.h b/openair-cn/GTPV1-U/nw-gtpv1u/shared/NwGtpv1uMsg.h index 2e636ccf3c..66feae289b 100644 --- a/openair-cn/GTPV1-U/nw-gtpv1u/shared/NwGtpv1uMsg.h +++ b/openair-cn/GTPV1-U/nw-gtpv1u/shared/NwGtpv1uMsg.h @@ -121,6 +121,7 @@ nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, NW_IN NwU16T seqNum, NW_IN NwU8T* tpdu, NW_IN NwU16T tpduLength, + NW_IN NwU32T tpduOffset, NW_OUT NwGtpv1uMsgHandleT *phMsg); /** diff --git a/openair-cn/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c b/openair-cn/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c index 59659c4256..97ea58cb53 100644 --- a/openair-cn/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c +++ b/openair-cn/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c @@ -198,7 +198,7 @@ nwGtpv1uCreateAndSendMsg( NwGtpv1uStackT *thiz, NwU32T peerIp, NwU16T peerPort, NW_ENTER(thiz); - msgHdr = pMsg->msgBuf; + msgHdr = &pMsg->msgBuf[pMsg->msgBufOffset]; NW_ASSERT(msgHdr != NULL); *(msgHdr++) = (pMsg->version << 5) | @@ -228,7 +228,8 @@ nwGtpv1uCreateAndSendMsg( NwGtpv1uStackT *thiz, NwU32T peerIp, NwU16T peerPort, rc = thiz->udp.udpDataReqCallback(thiz->udp.hUdp, pMsg->msgBuf, - pMsg->msgLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE, + pMsg->msgLen, + pMsg->msgOffset, peerIp, peerPort); @@ -490,11 +491,11 @@ nwGtpv1uProcessGpdu( NwGtpv1uStackT *thiz, NwGtpv1uMsgHeaderT *msgHdr = NULL; NwGtpv1uTunnelEndPointT *pTunnelEndPoint = NULL; NwGtpv1uTunnelEndPointT tunnelEndPointKey; - NwU16T payload_len = 0; NwU16T hdr_len = 0; NW_ENTER(thiz); + // no buffer offset msgHdr = (NwGtpv1uMsgHeaderT *) gpdu; tunnelEndPointKey.teid = ntohl(msgHdr->teid); @@ -509,22 +510,19 @@ nwGtpv1uProcessGpdu( NwGtpv1uStackT *thiz, (NwU8T *)gpdu, gpduLen, &hMsg); - - +/* + NwU8T* msgBuf; + NwU32T msgBufLen; + NwU32T msgBufOffset; + */ if(NW_GTPV1U_OK == rc) { NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg; - GTPU_DEBUG("Received T-PDU over tunnel end-point '%x' of size %u from "NW_IPV4_ADDR"\n", - ntohl(msgHdr->teid), pMsg->msgLen, NW_IPV4_ADDR_FORMAT((peerIp))); + GTPU_DEBUG("Received T-PDU over tunnel end-point '%x' of size %u (decapsulated %u)from "NW_IPV4_ADDR"\n", + ntohl(msgHdr->teid), gpduLen, pMsg->msgLen, NW_IPV4_ADDR_FORMAT((peerIp))); - payload_len = ntohs(msgHdr->msgLength); - hdr_len = NW_GTPV1U_EPC_MIN_HEADER_SIZE; - if (msgHdr->S || msgHdr->PN || msgHdr->E ) { - hdr_len = NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE; - payload_len = payload_len - (NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE - NW_GTPV1U_EPC_MIN_HEADER_SIZE); - } - AssertFatal(gpduLen == (payload_len + hdr_len), - "Mismatch gpduLen %d / hdr_len %d / payload_len %d", - gpduLen, hdr_len, payload_len); + AssertFatal(gpduLen == (pMsg->msgLen + pMsg->msgOffset), + "Mismatch gpduLen %d / buffer offset %d / msg len %d / buffer len", + gpduLen, pMsg->msgBufOffset, pMsg->msgLen, pMsg->msgBufLen); rc = nwGtpSessionSendMsgApiToUlpEntity(pTunnelEndPoint, pMsg); } diff --git a/openair-cn/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c b/openair-cn/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c index 80fa364846..870dc35f49 100644 --- a/openair-cn/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c +++ b/openair-cn/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c @@ -117,11 +117,13 @@ nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, NW_IN NwU16T seqNum, NW_IN NwU8T *tpdu, NW_IN NwU16T tpduLength, + NW_IN NwU32T tpduOffset, NW_OUT NwGtpv1uMsgHandleT *phMsg) { NwGtpv1uStackT *pStack = (NwGtpv1uStackT *) hGtpuStackHandle; NwGtpv1uMsgT *pMsg; - NwU32T header_len = 0; + NwU32T header_len = 0; + NwU32T msgExtraLen = 0; if(gpGtpv1uMsgPool) { pMsg = gpGtpv1uMsgPool; @@ -130,7 +132,15 @@ nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uMsgT), pMsg, NwGtpv1uMsgT *); } + if(pMsg) { + msgExtraLen = (((seqNumFlag) || (NW_FALSE) || (NW_FALSE) ) ? + (NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE - NW_GTPV1U_EPC_MIN_HEADER_SIZE) : 0); + AssertFatal((msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE) <= tpduOffset); + pMsg->msgBuf = tpdu; + pMsg->msgBufLen = tpduLength + msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE; + pMsg->msgBufOffset = tpduOffset - (msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE); + // Version field: This field is used to determine the version of the GTP-U protocol. // The version number shall be set to '1'. pMsg->version = NW_GTPU_VERSION; @@ -181,7 +191,7 @@ nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, pMsg->teid = teid; pMsg->nextExtHdrType= 0x00; - memcpy(pMsg->msgBuf + header_len, tpdu, tpduLength); + //memcpy(pMsg->msgBuf + header_len, tpdu, tpduLength); *phMsg = (NwGtpv1uMsgHandleT) pMsg; return NW_GTPV1U_OK; } @@ -231,8 +241,7 @@ nwGtpv1uMsgFromBufferNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, if(pMsg) { - memcpy(pMsg->msgBuf, pBuf, bufLen); - pMsg->msgLen = bufLen; + pMsg->msgBuf = pBuf; pMsg->version = ((*pBuf) & 0xE0) >> 5; pMsg->protocolType = ((*pBuf) & 0x10) >> 4; @@ -255,6 +264,8 @@ nwGtpv1uMsgFromBufferNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, pMsg->npduNum = *(pBuf++); pMsg->nextExtHdrType = *(pBuf++); } + pMsg->msgOffset = (NwU32T)(pBuf - pMsg->msgBuf); + pMsg->msgLen = bufLen - pMsg->msgOffset; *phMsg = (NwGtpv1uMsgHandleT) pMsg; return NW_GTPV1U_OK; }