diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 9592334125..f11c71d5d8 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1983,6 +1983,10 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ) +set(NR_SDAP_SRC + ${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap_gnb.c + ) + set(L2_SRC ${PDCP_DIR}/pdcp.c ${PDCP_DIR}/pdcp_fifo.c @@ -2026,6 +2030,7 @@ set(L2_LTE_SRC set(L2_NR_SRC ${NR_RLC_SRC} ${NR_PDCP_SRC} + ${NR_SDAP_SRC} ${NR_RRC_DIR}/rrc_gNB.c ${NR_RRC_DIR}/nr_rrc_common.c ${NR_RRC_DIR}/L2_nr_interface.c @@ -2061,6 +2066,7 @@ set(L2_RRC_SRC_UE set(NR_L2_SRC_UE ${NR_RLC_SRC} ${NR_PDCP_SRC} + ${NR_SDAP_SRC} ${NR_UE_RRC_DIR}/L2_interface_ue.c ${NR_UE_RRC_DIR}/main_ue.c ${NR_UE_RRC_DIR}/rrc_UE.c diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index f9076c50ae..0e22869dcd 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -36,6 +36,7 @@ #include "pdcp.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include +#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h" #define TODO do { \ printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \ @@ -447,10 +448,18 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){ LOG_D(PDCP, "IP packet received, to be sent to TUN interface"); - len = write(nas_sock_fd[0], buf, size); + + if(entity->has_sdapDLheader){ + size -= SDAP_HDR_LENGTH; + len = write(nas_sock_fd[0], &buf[SDAP_HDR_LENGTH], size); + } else { + len = write(nas_sock_fd[0], buf, size); + } + if (len != size) { LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); } + } else{ for (i = 0; i < 5; i++) { @@ -480,7 +489,10 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti; GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id = entity->pdusession_id; - if (offset==1) LOG_D(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]); + if (offset==1) { + LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]); + sdap_gnb_ul_header_handler(buf[0]); // Handler for the UL gNB SDAP Header + } LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size-offset); itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p); } @@ -828,10 +840,6 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, has_sdap = 1; has_sdapULheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present ? 1 : 0; has_sdapDLheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present ? 1 : 0; - if (has_sdapDLheader==1) { - LOG_E(PDCP,"%s:%d:%s: fatal, no support for SDAP DL yet\n",__FILE__,__LINE__,__FUNCTION__); - exit(-1); - } } /* TODO(?): accept different UL and DL SN sizes? */ if (sn_size_ul != sn_size_dl) { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 655e6973a1..da7a016137 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1010,7 +1010,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); memset(sdap_config, 0, sizeof(NR_SDAP_Config_t)); sdap_config->pdu_Session = ue_context_pP->ue_context.pduSession[i].param.pdusession_id; - sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; + sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; sdap_config->defaultDRB = TRUE; sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); diff --git a/openair2/SDAP/nr_sdap/nr_sdap_gnb.c b/openair2/SDAP/nr_sdap/nr_sdap_gnb.c new file mode 100644 index 0000000000..5f0a2640e9 --- /dev/null +++ b/openair2/SDAP/nr_sdap/nr_sdap_gnb.c @@ -0,0 +1,87 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_sdap_gnb.h" +#include + +boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id + ) { + if(sdu_buffer == NULL) { + LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if(sdu_buffer_size == 0) { + LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL or 0 sdu_buffer_size \n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + uint8_t *sdap_buf = (uint8_t *)malloc(sdu_buffer_size+SDAP_HDR_LENGTH); + nr_sdap_dl_hdr_t sdap_hdr; + sdap_hdr.RDI = 0; // SDAP_Hardcoded - + sdap_hdr.RQI = 0; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION + sdap_hdr.QFI = 1; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION + memcpy(&sdap_buf[0], &sdap_hdr, 1); + memcpy(&sdap_buf[1], sdu_buffer, sdu_buffer_size); + rb_id_t sdap_drb_id = rb_id; // SDAP_Hardcoded - Should get this info from QFI to DRB mapping table + boolean_t ret = pdcp_data_req(ctxt_p, + srb_flag, + sdap_drb_id, + mui, + confirm, + sdu_buffer_size+1, + sdap_buf, + pt_mode, + sourceL2Id, + destinationL2Id); + + if(!ret) { + LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - PDCP DL refused PDU\n", __FILE__, __LINE__, __FUNCTION__); + free(sdap_buf); + return 0; + } + + free(sdap_buf); + return 1; +} + +void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr) { + nr_sdap_ul_hdr_t *sdap_hdr_ul = (nr_sdap_ul_hdr_t *)&sdap_gnb_ul_hdr; + + switch (sdap_hdr_ul->DC) { + case SDAP_HDR_UL_DATA_PDU: + LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - UL Received SDAP Data PDU\n", __FILE__, __LINE__, __FUNCTION__); + break; + + case SDAP_HDR_UL_CTRL_PDU: + LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - Received SDAP Control PDU\n", __FILE__, __LINE__, __FUNCTION__); + break; + } +} \ No newline at end of file diff --git a/openair2/SDAP/nr_sdap/nr_sdap_gnb.h b/openair2/SDAP/nr_sdap/nr_sdap_gnb.h new file mode 100644 index 0000000000..243aa89010 --- /dev/null +++ b/openair2/SDAP/nr_sdap/nr_sdap_gnb.h @@ -0,0 +1,61 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_SDAP_GNB_ +#define _NR_SDAP_GNB_ + +#include "openair2/COMMON/platform_types.h" +#include "common/utils/LOG/log.h" + +#define SDAP_BITMASK_DC (0x80) +#define SDAP_BITMASK_R (0x40) +#define SDAP_BITMASK_QFI (0x3F) +#define SDAP_HDR_UL_DATA_PDU (1) +#define SDAP_HDR_UL_CTRL_PDU (0) +#define SDAP_HDR_LENGTH (1) + +typedef struct nr_sdap_dl_hdr_s { + uint8_t QFI:6; + uint8_t RQI:1; + uint8_t RDI:1; +} __attribute__((packed)) nr_sdap_dl_hdr_t; + +typedef struct nr_sdap_ul_hdr_s { + uint8_t QFI:6; + uint8_t R:1; + uint8_t DC:1; +} __attribute__((packed)) nr_sdap_ul_hdr_t; + +boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id + ); + +void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr); + +#endif \ No newline at end of file diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index ca199c1308..a3eeb26540 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -17,6 +17,7 @@ extern "C" { #include #include #include +#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h" //#include #pragma pack(1) @@ -539,8 +540,8 @@ int gtpv1u_create_ngu_tunnel( const instance_t instance, create_tunnel_req->incoming_rb_id[i], create_tunnel_req->pdusession_id[i], create_tunnel_req->upf_NGu_teid[i], - create_tunnel_req->upf_addr[i], dstport, - pdcp_data_req); + create_tunnel_req->upf_addr[i], dstport, + sdap_gnb_data_req); create_tunnel_resp->status=0; create_tunnel_resp->rnti=create_tunnel_req->rnti; create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels;