diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 80b625d7db..0b9d925017 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1968,6 +1968,7 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ) set(L2_SRC diff --git a/openair2/LAYER2/nr_pdcp/asn1_utils.c b/openair2/LAYER2/nr_pdcp/asn1_utils.c new file mode 100644 index 0000000000..264a2815bb --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/asn1_utils.c @@ -0,0 +1,68 @@ +/* + * 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 "pdcp.h" + +int decode_t_reordering(int v) +{ + static int tab[36] = { + 0, 1, 2, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 80, 100, 120, 140, 160, 180, + 200, 220, 240, 260, 280, 300, 500, 750, 1000, 1250, 1500, 1750, 2000, + 2250, 2500, 2750, 3000 + }; + + if (v < 0 || v > 35) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_sn_size_ul(long s) +{ + if (s == 0) return 12; + if (s == 1) return 18; + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); +} + +int decode_sn_size_dl(long s) +{ + if (s == 0) return 12; + if (s == 1) return 18; + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); +} + +int decode_discard_timer(long v) +{ + static int tab[16] = { + 10, 20, 30, 40, 50, 60, 75, 100, 150, 200, 250, 300, 500, 750, 1500, -1, + }; + + if (v < 0 || v > 15) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} diff --git a/openair2/LAYER2/nr_pdcp/asn1_utils.h b/openair2/LAYER2/nr_pdcp/asn1_utils.h new file mode 100644 index 0000000000..d525bce287 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/asn1_utils.h @@ -0,0 +1,30 @@ +/* + * 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 _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ +#define _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ + +int decode_t_reordering(int v); +int decode_sn_size_ul(long s); +int decode_sn_size_dl(long s); +int decode_discard_timer(long v); + +#endif /* _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index e25201c22c..f3d4b16130 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -44,7 +44,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_sdu_data, void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size, int sdu_id), - void *deliver_pdu_data) + void *deliver_pdu_data, + int sn_size, + int t_reordering, + int discard_timer) { nr_pdcp_entity_drb_am_t *ret; @@ -66,9 +69,12 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( ret->common.deliver_pdu = deliver_pdu; ret->common.deliver_pdu_data = deliver_pdu_data; - ret->rb_id = rb_id; + ret->rb_id = rb_id; + ret->sn_size = sn_size; + ret->t_reordering = t_reordering; + ret->discard_timer = discard_timer; - ret->common.maximum_nr_pdcp_sn = 4095; + ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1; return (nr_pdcp_entity_t *)ret; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 45555ad6af..b1d37830e9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -58,7 +58,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_sdu_data, void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size, int sdu_id), - void *deliver_pdu_data); + void *deliver_pdu_data, + int sn_size, + int t_reordering, + int discard_timer); void nr_DRB_preconfiguration(void); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h index faa8226e93..d7c42e6a62 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h @@ -27,6 +27,9 @@ typedef struct { nr_pdcp_entity_t common; int rb_id; + int sn_size; /* unit: bits */ + int t_reordering; /* unit: ms */ + int discard_timer; /* unit: ms, -1 means infinity */ } nr_pdcp_entity_drb_am_t; void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ca37026e54..51d4e44fab 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -22,6 +22,7 @@ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif +#include "asn1_utils.h" #include "nr_pdcp_ue_manager.h" #include "NR_RadioBearerConfig.h" #include "NR_RLC-BearerConfig.h" @@ -595,8 +596,17 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) nr_pdcp_ue_t *ue; int drb_id = s->drb_Identity; + int t_reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering); + int sn_size_ul = decode_sn_size_ul(*s->pdcp_Config->drb->pdcp_SN_SizeUL); + int sn_size_dl = decode_sn_size_dl(*s->pdcp_Config->drb->pdcp_SN_SizeDL); + int discard_timer = decode_discard_timer(*s->pdcp_Config->drb->discardTimer); -printf("\n\n################# rnti %d add drb %d\n\n\n", rnti, drb_id); + /* TODO(?): accept different UL and DL SN sizes? */ + if (sn_size_ul != sn_size_dl) { + LOG_E(PDCP, "%s:%d:%s: fatal, bad SN sizes, must be same. ul=%d, dl=%d\n", + __FILE__, __LINE__, __FUNCTION__, sn_size_ul, sn_size_dl); + exit(1); + } if (drb_id != 1) { LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id %d\n", @@ -610,7 +620,8 @@ printf("\n\n################# rnti %d add drb %d\n\n\n", rnti, drb_id); LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue); + pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue, + sn_size_dl, t_reordering, discard_timer); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); LOG_D(PDCP, "%s:%d:%s: added drb %d to ue %d\n",