Add basic E1 functionality
With contributions from * Sakthivel Velumani <velumani@eurecom.fr> * Robert Schmidt <robert.schmidt@openairinterface.org> Squashed commit of the following: commit e8488acbcdaef6ee1688dc233c9e48e85b0fbfc8 Merge: f09468eb135d58645a85Author: laurent <laurent Thomas> Date: Sat Jan 21 15:03:40 2023 +0100 merge develop commit f09468eb13f729c49830786150918b03ae2d7524 Author: laurent <laurent Thomas> Date: Fri Jan 20 10:43:51 2023 +0100 continue e1AP development commit 76545cfbfc7ec5031633b1b0ec599c3560c1e5a7 Author: laurent <laurent Thomas> Date: Wed Jan 18 14:18:47 2023 +0100 fix regressions after merge develop commit 7071c480a6c433eb94501c49f4a7694ba77f4f6d Merge: 569b9fc5f3214aa50595Author: laurent <laurent Thomas> Date: Mon Jan 16 15:51:50 2023 +0100 merge develop commit 569b9fc5f37b9947b722885e423572a211d658da Author: laurent <laurent Thomas> Date: Wed Jan 4 17:07:01 2023 +0100 fix srb2 addition, simplify and remove dead code, fix one race commit 9fa89151c0f9b4a16a79d0685cc04d8cf2adfa44 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Jan 4 20:02:05 2023 +0530 Bearer context release decoder and encoder commit 7011cb518ed6df015ace536e9a08b2d1865188d9 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Jan 4 13:43:58 2023 +0530 Update documentation commit 3e8899fc962cb16fc1ded49590ca5dddede54978 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Jan 4 10:14:11 2023 +0530 Fix function arguments and warnings commit 989ad183a8d66961facaa6719fa7793b9d40d5b4 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Jan 3 20:18:31 2023 +0530 Moved E1-design.md to doc/ commit 04a8633dd509d9525755c5f3abfad976a1ba704e Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Jan 3 20:13:46 2023 +0530 Make libraries lower case in CMakeLists commit 033ec174c1f48a0e745a2a2e1c367aa361f5ae76 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Jan 3 17:55:25 2023 +0530 Renamed and updated cucp cuup config files commit f76a6913352bd8b2bb73ac25f225140cf05f93f2 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Jan 3 13:31:19 2023 +0530 Removed CU-UP checks from nr-softmodem commit ae70afe44c84ac16b977b388c63e80e24803c43c Author: laurent <laurent Thomas> Date: Mon Jan 2 13:01:45 2023 +0100 fix for gcc version hat doesnt accept declarations in switch commit 6a7a01043bf1e6e0ee9ac40b4d85ced7cdf6dcf4 Author: laurent <laurent Thomas> Date: Tue Dec 27 15:59:28 2022 +0100 first functional commit standalone cu-up commit 0caa4690f9e1acbe578d4de5a82ba62f45444a12 Merge: 3619f9550e1a0c0cd1c9Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Fri Dec 23 14:21:00 2022 +0530 Merge remote-tracking branch 'origin/develop' into e1-implementation-wip commit 3619f9550e4d3e78815334150ff8443db914f738 Merge: 1bcf8d5e00cfe698eb70Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Dec 21 15:47:40 2022 +0530 Merge remote-tracking branch 'origin/develop' into e1-implementation-wip commit 1bcf8d5e00a9b9ce440d825f83ddc1b48086daa8 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Sep 13 02:10:34 2022 -0400 Fix GTP rnti to ue_id after rebase commit 23075ff8b7ef5d56df844c05e0a7100fe7bd35de Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Sep 6 00:32:12 2022 -0400 Added documentation commit 28f6e507f74d3fb069441e05da523378dee0f6ed Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Mon Sep 5 15:02:02 2022 -0400 Header cleaups and unitary simulators build fixes commit e665dbab28c49327066cff72aed22e1de7797b59 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu Sep 1 17:52:07 2022 -0400 Common interface between CUCP & CUUP for E1 and non E1 modes commit 5dcc1bf59a37ed87d7d32a617cfcd663d6415757 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu Sep 1 13:53:49 2022 -0400 Allocate stack where ever possible Free memory after ASN encode commit 793a5379539a3a2b6c42cd327d8cef79fe21fb55 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu Sep 1 10:41:50 2022 -0400 Fixes for build issues commit 0d3564f25a0d8746b0fc550ed371ce21e08cd05a Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Aug 31 20:57:14 2022 -0400 Fixed uesoftmodem linkage error commit 34adf865820f09900a5efed693ada1ccf6f0f1ad Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Aug 31 19:31:50 2022 -0400 Removed RRC thread from CUUP commit 536741910aff90a86ba3a60612f943b412c5ab40 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Aug 31 14:21:31 2022 -0400 Add header guard in one of E1AP header commit 22e9d9b6dea5d84d259ee2dc1aaa7cb943e55b08 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Aug 31 14:00:47 2022 -0400 Fix bug in PDCP ue_id commit 4c65339b07d347003ed89d5e00f49a62e9b21483 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Aug 30 18:04:59 2022 -0400 Linked E1AP lib to L2_NR target E1AP builds for nr-softmodem commit 014fe30ac93c84d810e0209bc7f0d3b7a1bbaee3 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Aug 30 15:49:27 2022 -0400 Remove xer prints from e1ap and gcc warning fixes commit 71f0c9126bbb91bc595b66d57e1e91db676d3b9d Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Aug 30 15:42:30 2022 -0400 Fixed bug in integrity protection config commit 4e393ef9528c2b14d670a341b52fc63262abf894 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Aug 30 14:34:37 2022 -0400 GTP init with only local address IP traffic works both directions in Mono, F1 and E1 commit ec3bde2c5deb99f554afc2053e351b9f79525e96 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Aug 30 00:16:03 2022 -0400 Fix bug in pdcp config and GTP instance UL iperf still not works. Can see packets in wireshark. commit be8df4435eeae0a0755e2ac658f33caa2a3e3c94 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Sat Aug 27 20:15:04 2022 -0400 Fixes in node config after rebase commit 6f42ff88de7f1615f87c46771fd6617a5fdfc48f Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Sat Aug 27 01:38:21 2022 -0400 Added N3 tunnel address in config params fixed bug in address length feild commit b5e132041994344ebb5c2c59ca392612a32658fd Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Fri Aug 26 20:38:47 2022 -0400 Send UL UP address via F1 UE cxt mod msg commit ecfd0fe260aee6aad78c291368c246f88b6bffcf Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Fri Aug 26 15:08:53 2022 -0400 Update GTP remote address from response message Modified GTP tunnel update function accordingly Put GTP tunnel update out of F1AP F1 split works commit 14a37e414de3d653f25ccef1a790bc5b08fc7dc2 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Sat Aug 20 01:17:36 2022 -0400 Moved GTP tunnel creation out of F1AP message sending commit cdd58ab96e84f48cc8ab8f0fe6b3133081ff02f7 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Fri Aug 19 17:40:43 2022 -0400 Moved DRB config out of RRCReconfig complete Monolithic and F1 split works commit 61d66e490a1b61aa2b6ce18d993bb90d112d6374 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu Aug 11 01:30:10 2022 -0400 Allow CUUP to have RRC inst without error commit dd7ae889372bb9fdf9e96be87c28eed0d9461d7f Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu Aug 11 01:29:21 2022 -0400 Added missing IEs in bearer cxt response handler commit a6f1fe5fd254ccb36a54ede5b652161cb5e542e8 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Aug 10 21:02:30 2022 -0400 Unified bearer context message transfer for E1 and non-E1 mode compiles, to be tested commit f245ace285632edcc28d669123746b9bf458bc38 Author: laurent <laurent Thomas> Date: Tue Aug 9 17:46:52 2022 +0200 remove log_i() of fatal errors commit d2a0f3c8620981f3b65a136f0169e3be9c549742 Author: laurent <laurent Thomas> Date: Fri Aug 5 15:01:39 2022 +0200 fix rnti/ue_id for ue commit 7b52c6cd9e675c28cb9d6347d122f77234ec6542 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu Aug 4 19:14:46 2022 -0400 Created separate functions in PDCP for E1 mode commit 46680d2b3d221e675c3aeb675137f45318e31acb Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu Aug 4 19:13:10 2022 -0400 Bug fixes in bearer context setup response commit 3d091bfd31b7aba625e4ba4b4f0f337cf2c1f6db Author: laurent <laurent Thomas> Date: Thu Aug 4 15:42:11 2022 +0200 add missing file from previous commit commit 21838572196dec947da99f350f20c4d9408c3c17 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed Aug 3 16:59:16 2022 -0400 Minor bug fixes commit 34eb73fbc6f9d33098850d62b4808e54c80bb4ca Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Aug 2 23:16:47 2022 -0400 Added config files for testing To be renamed or removed later commit a7e9c6fb9332295ad42585eb4338a6f9ff0ae7c0 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Aug 2 23:15:21 2022 -0400 Made rrc_gNB_get_ue_context_from_ngap_ids() non static commit 028f0407571466ff24cf72b5c3814e42c346ae81 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Aug 2 23:12:16 2022 -0400 Completed bearer context setup cycle To be tested: Handling of bearer context setup response and subsequent UE context modifition msg to F1AP task commit 4481d11324b13efa73ab0b5f4f156012485661ae Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Aug 2 23:01:50 2022 -0400 Fixed E1AP PPID (wireshark fixed) commit 7a22573f3e7e16960e3310609dea2783ddf404a2 Author: laurent <laurent Thomas> Date: Fri Jul 29 13:03:31 2022 +0200 fix compile issues, simplify gtp send function commit 0209011aa75a16e4c9c1eb36ebcf4fe0ff93aba2 Author: laurent <laurent Thomas> Date: Thu Jul 28 11:51:18 2022 +0200 restore compilation capability, gtp replacement of rnti by ueid commit ce3b886fd7f11322a8d37b924d1752e6a6adf777 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Fri Jul 22 08:35:31 2022 -0400 Included missing IEs in bearer cxt setup message commit 1208ae0d6fe4b25341c9036dde111fd4d00fd6e9 Author: Cedric Roux <cedric.roux@eurecom.fr> Date: Tue Jul 19 10:53:35 2022 +0200 replace rnti by ue_id in pdcp some sdap and gtp files had to be touched, the work is not finished in there some changes in nr_pdcp_oai_api.c simply assume ue_id is indeed rnti (will functions in this file be used by cu-up?) commit e67d1c88c786267458194e4de516919d0b5d1002 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Jul 19 10:08:39 2022 +0200 Replace RNTI with UE ID in GTP files (half done. Laurent to change ctxt_t) commit 7a141e8e941e5c2624a47da7c764531c03b8f617 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Jul 19 10:04:15 2022 +0200 Added RRC handler for bearer cxt setup in CUUP commit fe2106676bf9144347f30969a1bfd351136f536a Author: laurent <laurent Thomas> Date: Mon Jul 11 13:30:30 2022 +0200 fix race in startup procedure (config before starting threads that use the config) commit 3197baab60e53459928da30cea7a4e0514a074e3 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Sun Jul 10 11:30:31 2022 +0200 Fixed bugs in bearer creation commit 26be61167dec9068e572e08a21ddc96a0f2a7731 Author: laurent <laurent Thomas> Date: Sun Jul 10 10:50:57 2022 +0200 fix a race, add asn1c debug method commit 26750d1818aa206c4c56ada6dbed9bb66dfe3811 Author: laurent <laurent Thomas> Date: Wed Jul 6 22:34:10 2022 +0200 e1ap bearer setup encoding invalid commit d092788aa3f8229eb5c938a41534dfb318955135 Author: laurent <laurent Thomas> Date: Wed Jul 6 14:18:39 2022 +0200 fix regression with F1, some basic cleaning in NGAP commit 41a135734a33b284808d4c5049c431dbc0ff1c46 Author: laurent <laurent Thomas> Date: Wed Jul 6 11:24:52 2022 +0200 fix some ngap regressions commit 460acd840dd58fd46a995219cb9da8fda103668e Author: laurent <laurent Thomas> Date: Tue Jul 5 21:19:13 2022 +0200 build, run in F1 mode until UE connect but pdu session still fails commit 7c067095df287cc7a542be53e9a1471c11ec5af8 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Sat Jun 25 22:45:46 2022 +0530 Populate PDU and DRB paramenters from NGAP commit c4ada56a8c31b4c07fc1498e15b0954d9b1ad2f6 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue Jun 7 22:16:58 2022 +0530 setup resp decoding success commit a2f41597c7438934a203ccf3cced35b6b65e8cee Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Sat Jun 4 13:50:55 2022 +0530 Fixed bugs in E1 setup procedure E1 setup request decoding successful commit 6106207ba74c74579b5f375d572930a609abe3a9 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu May 26 20:13:14 2022 +0530 Fixing build issues commit 67235fac01aaca4c17da13bf658144ffe6bd12df Author: Robert Schmidt <robert.schmidt@openairinterface.org> Date: Mon May 23 12:04:22 2022 +0200 Make nr-softmodem depend on E1AP module commit 391cee938e8250c355b6b914e747f2004c795817 Author: Robert Schmidt <robert.schmidt@openairinterface.org> Date: Mon May 23 11:57:15 2022 +0200 Fix ITTI errors in E1AP target commit db4146e4a0432b7e3759d71efbeb450754c1f0d3 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Wed May 18 06:59:03 2022 +0530 CP UP task created commit 3058d2fc445acf5681a09f70409023718294d093 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue May 10 08:12:19 2022 +0530 Bearer context setup response message commit b911e9db2a4d0a35eb9a449ef02acefff30b558f Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Tue May 3 16:52:49 2022 +0530 Bearer context setup c structs commit d0f4d5f3539803253b9a995a90a47b3d825ea0ca Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu Apr 28 02:21:50 2022 +0530 Bearer context setup message commit 489a5358fa0e199314254561a2d52c1a93f7803e Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu Apr 21 10:11:03 2022 +0530 Started with CUUP task commit b416061f5a237cbabbe09c6d81fe92df9e33fd72 Author: Sakthivel Velumani <velumani@eurecom.fr> Date: Fri Apr 15 18:46:27 2022 +0530 Setup request and response messages commit faca4b97dba92be857bd8442193365fc2c8ed122 Author: Robert Schmidt <robert.schmidt@openairinterface.org> Date: Mon Apr 11 15:01:48 2022 +0200 Fixup for cmake execution commit ecfd9f7608a5820ae85278939e9bbaf7f1245dd6 Author: Robert Schmidt <robert.schmidt@eurecom.fr> Date: Tue Nov 24 21:39:20 2020 +0100 Move CMakeLists.txt into root commit 9f41f7c52b3c7a185e5e34bb1591b0eb66459837 Author: Robert Schmidt <robert.schmidt@openairinterface.org> Date: Tue Apr 12 12:07:18 2022 +0200 Remove hwlat refs in build_oai: targets don't exist anymore commit e666cf5eedc67695febd33de1397331d6b7b2320 Author: Robert Schmidt <robert.schmidt@openairinterface.org> Date: Mon Apr 11 14:37:32 2022 +0200 Create CMake E1AP_RELEASE variable from E1AP_VERSION commit 1f8413361c1b99ea46ee613da035803a1387f65c Author: Robert Schmidt <robert.schmidt@openairinterface.org> Date: Sun Apr 10 14:25:38 2022 +0200 Add E1AP lib commit 7465cea49243fd6eb9869035b18860dface57098 Author: Robert Schmidt <robert.schmidt@openairinterface.org> Date: Sun Apr 10 14:48:40 2022 +0200 Add E1AP Grammar and build ASN.1 lib at build time commit cde22f83032a199387ae1eae6b702f44ed154f3e Author: Robert Schmidt <robert.schmidt@openairinterface.org> Date: Fri Apr 22 13:42:51 2022 +0200 Accept higher vers. nums in make_version/MAKE_VERSION commit d5127b23608240374a439d1d9c2ff6d53c4b527c Author: Robert Schmidt <robert.schmidt@eurecom.fr> Date: Tue Nov 24 21:39:20 2020 +0100 Move CMakeLists.txt into root
This commit is contained in:
committed by
Robert Schmidt
parent
f984f49310
commit
553f1d1a52
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* gNB_CUUP application layer -> E1AP messages */
|
||||
MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req)
|
||||
|
||||
/* E1AP -> eNB_DU or eNB_CU_RRC -> E1AP application layer messages */
|
||||
MESSAGE_DEF(E1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, e1ap_setup_resp_t , e1ap_setup_resp)
|
||||
|
||||
MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_setup_req)
|
||||
|
||||
MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_resp_t , e1ap_bearer_setup_resp)
|
||||
|
||||
MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req)
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* 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 E1AP_MESSAGES_TYPES_H
|
||||
#define E1AP_MESSAGES_TYPES_H
|
||||
|
||||
#include "f1ap_messages_types.h"
|
||||
#include "ngap_messages_types.h"
|
||||
|
||||
#define E1AP_MAX_NUM_TRANSAC_IDS 4
|
||||
#define E1AP_MAX_NUM_PLMNS 4
|
||||
#define E1AP_MAX_NUM_CELL_GROUPS 4
|
||||
#define E1AP_MAX_NUM_QOS_FLOWS 4
|
||||
#define E1AP_MAX_NUM_NGRAN_DRB 4
|
||||
#define E1AP_MAX_NUM_PDU_SESSIONS 4
|
||||
#define E1AP_MAX_NUM_DRBS 4
|
||||
#define E1AP_MAX_NUM_DRBS 4
|
||||
#define E1AP_MAX_NUM_UP_PARAM 4
|
||||
|
||||
#define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req
|
||||
#define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp
|
||||
#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
|
||||
#define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp
|
||||
#define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
|
||||
|
||||
typedef f1ap_net_ip_address_t e1ap_net_ip_address_t;
|
||||
|
||||
typedef struct PLMN_ID_s {
|
||||
int mcc;
|
||||
int mnc;
|
||||
int mnc_digit_length;
|
||||
} PLMN_ID_t;
|
||||
|
||||
typedef struct e1ap_setup_req_s {
|
||||
uint64_t gNB_cu_up_id;
|
||||
char * gNB_cu_up_name;
|
||||
int assoc_id;
|
||||
uint64_t transac_id;
|
||||
int supported_plmns;
|
||||
PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS];
|
||||
uint16_t sctp_in_streams;
|
||||
uint16_t sctp_out_streams;
|
||||
uint16_t default_sctp_stream_id;
|
||||
net_ip_address_t CUUP_e1_ip_address;
|
||||
net_ip_address_t CUCP_e1_ip_address;
|
||||
long cn_support;
|
||||
uint16_t remotePortF1U;
|
||||
char* localAddressF1U;
|
||||
uint16_t localPortF1U;
|
||||
char* localAddressN3;
|
||||
uint16_t localPortN3;
|
||||
uint16_t remotePortN3;
|
||||
} e1ap_setup_req_t;
|
||||
|
||||
typedef struct e1ap_setup_resp_s {
|
||||
long transac_id;
|
||||
} e1ap_setup_resp_t;
|
||||
|
||||
typedef struct cell_group_s {
|
||||
long id;
|
||||
} cell_group_t;
|
||||
|
||||
typedef struct up_params_s {
|
||||
in_addr_t tlAddress;
|
||||
long teId;
|
||||
int cell_group_id;
|
||||
} up_params_t;
|
||||
|
||||
typedef struct drb_to_setup_s {
|
||||
long drbId;
|
||||
long pDCP_SN_Size_UL;
|
||||
long pDCP_SN_Size_DL;
|
||||
long rLC_Mode;
|
||||
long qci;
|
||||
long qosPriorityLevel;
|
||||
long pre_emptionCapability;
|
||||
long pre_emptionVulnerability;
|
||||
in_addr_t tlAddress;
|
||||
long teId;
|
||||
int numCellGroups;
|
||||
cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
|
||||
} drb_to_setup_t;
|
||||
|
||||
typedef struct qos_flow_to_setup_s {
|
||||
long id;
|
||||
fiveQI_type_t fiveQI_type;
|
||||
long fiveQI;
|
||||
long qoSPriorityLevel;
|
||||
long packetDelayBudget;
|
||||
long packetError_scalar;
|
||||
long packetError_exponent;
|
||||
long priorityLevel;
|
||||
long pre_emptionCapability;
|
||||
long pre_emptionVulnerability;
|
||||
} qos_flow_to_setup_t;
|
||||
|
||||
typedef struct DRB_nGRAN_to_setup_s {
|
||||
long id;
|
||||
long defaultDRB;
|
||||
long sDAP_Header_UL;
|
||||
long sDAP_Header_DL;
|
||||
long pDCP_SN_Size_UL;
|
||||
long pDCP_SN_Size_DL;
|
||||
long discardTimer;
|
||||
long reorderingTimer;
|
||||
long rLC_Mode;
|
||||
in_addr_t tlAddress;
|
||||
int teId;
|
||||
int numDlUpParam;
|
||||
up_params_t DlUpParamList[E1AP_MAX_NUM_UP_PARAM];
|
||||
int numCellGroups;
|
||||
cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
|
||||
int numQosFlow2Setup;
|
||||
qos_flow_to_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
|
||||
} DRB_nGRAN_to_setup_t;
|
||||
|
||||
typedef struct pdu_session_to_setup_s {
|
||||
long sessionId;
|
||||
long sessionType;
|
||||
int8_t sst;
|
||||
long integrityProtectionIndication;
|
||||
long confidentialityProtectionIndication;
|
||||
in_addr_t tlAddress;
|
||||
in_addr_t tlAddress_dl;
|
||||
int32_t teId;
|
||||
int32_t teId_dl;
|
||||
int tl_port;
|
||||
int tl_port_dl;
|
||||
long numDRB2Setup;
|
||||
DRB_nGRAN_to_setup_t DRBnGRanList[E1AP_MAX_NUM_NGRAN_DRB];
|
||||
long numDRB2Modify;
|
||||
DRB_nGRAN_to_setup_t DRBnGRanModList[E1AP_MAX_NUM_NGRAN_DRB];
|
||||
} pdu_session_to_setup_t;
|
||||
|
||||
typedef struct e1ap_bearer_setup_req_s {
|
||||
uint32_t gNB_cu_cp_ue_id;
|
||||
uint32_t gNB_cu_up_ue_id;
|
||||
rnti_t rnti;
|
||||
uint64_t cipheringAlgorithm;
|
||||
uint64_t integrityProtectionAlgorithm;
|
||||
char encryptionKey[128];
|
||||
char integrityProtectionKey[128];
|
||||
long ueDlAggMaxBitRate;
|
||||
PLMN_ID_t servingPLMNid;
|
||||
long activityNotificationLevel;
|
||||
int numDRBs;
|
||||
drb_to_setup_t DRBList[E1AP_MAX_NUM_DRBS];
|
||||
int numPDUSessions;
|
||||
pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS];
|
||||
int numPDUSessionsMod;
|
||||
pdu_session_to_setup_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS];
|
||||
} e1ap_bearer_setup_req_t;
|
||||
|
||||
typedef struct e1ap_bearer_release_cmd_s {
|
||||
uint32_t gNB_cu_cp_ue_id;
|
||||
uint32_t gNB_cu_up_ue_id;
|
||||
long cause_type;
|
||||
long cause;
|
||||
} e1ap_bearer_release_cmd_t;
|
||||
|
||||
typedef struct drb_setup_s {
|
||||
int drbId;
|
||||
in_addr_t tlAddress;
|
||||
int teId;
|
||||
int numUpParam;
|
||||
up_params_t UpParamList[E1AP_MAX_NUM_UP_PARAM];
|
||||
} drb_setup_t;
|
||||
|
||||
typedef struct qos_flow_setup_s {
|
||||
long id;
|
||||
} qos_flow_setup_t;
|
||||
|
||||
typedef struct DRB_nGRAN_setup_s {
|
||||
long id;
|
||||
int numUpParam;
|
||||
up_params_t UpParamList[E1AP_MAX_NUM_UP_PARAM];
|
||||
int numQosFlowSetup;
|
||||
qos_flow_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
|
||||
} DRB_nGRAN_setup_t;
|
||||
|
||||
typedef struct DRB_nGRAN_failed_s {
|
||||
long id;
|
||||
long cause_type;
|
||||
long cause;
|
||||
} DRB_nGRAN_failed_t;
|
||||
|
||||
typedef struct pdu_session_setup_s {
|
||||
long id;
|
||||
in_addr_t tlAddress;
|
||||
long teId;
|
||||
int numDRBSetup;
|
||||
DRB_nGRAN_setup_t DRBnGRanList[E1AP_MAX_NUM_NGRAN_DRB];
|
||||
int numDRBFailed;
|
||||
DRB_nGRAN_failed_t DRBnGRanFailedList[E1AP_MAX_NUM_NGRAN_DRB];
|
||||
} pdu_session_setup_t;
|
||||
|
||||
typedef struct e1ap_bearer_setup_resp_s {
|
||||
uint64_t gNB_cu_cp_ue_id;
|
||||
uint64_t gNB_cu_up_ue_id;
|
||||
int numDRBs;
|
||||
drb_setup_t DRBList[E1AP_MAX_NUM_DRBS];
|
||||
int numPDUSessions;
|
||||
pdu_session_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS];
|
||||
} e1ap_bearer_setup_resp_t;
|
||||
|
||||
#endif /* E1AP_MESSAGES_TYPES_H */
|
||||
@@ -185,7 +185,7 @@ typedef struct gtpv1u_gnb_create_tunnel_resp_s {
|
||||
ue_id_t ue_id;
|
||||
int num_tunnels;
|
||||
teid_t gnb_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
||||
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
transport_layer_addr_t gnb_addr;
|
||||
} gtpv1u_gnb_create_tunnel_resp_t;
|
||||
typedef struct gtpv1u_gnb_delete_tunnel_req_s {
|
||||
|
||||
@@ -41,3 +41,4 @@
|
||||
#include "sctp_messages_def.h"
|
||||
#include "udp_messages_def.h"
|
||||
#include "gtpv1_u_messages_def.h"
|
||||
#include "e1ap_messages_def.h"
|
||||
|
||||
@@ -274,9 +274,15 @@ typedef struct ngap_transport_layer_addr_s {
|
||||
dEST.length = sOURCE.length; \
|
||||
} while (0)
|
||||
|
||||
typedef enum {
|
||||
non_dynamic,
|
||||
dynamic
|
||||
} fiveQI_type_t;
|
||||
|
||||
typedef struct pdusession_level_qos_parameter_s {
|
||||
uint8_t qfi;
|
||||
uint64_t fiveQI;
|
||||
fiveQI_type_t fiveQI_type;
|
||||
ngap_allocation_retention_priority_t allocation_retention_priority;
|
||||
} pdusession_level_qos_parameter_t;
|
||||
|
||||
@@ -706,12 +712,21 @@ typedef struct ngap_pdusession_setup_req_s {
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* S-NSSAI */
|
||||
ngap_allowed_NSSAI_t allowed_nssai[8];
|
||||
|
||||
/* Number of pdusession to be setup in the list */
|
||||
uint8_t nb_pdusessions_tosetup;
|
||||
|
||||
/* E RAB setup request */
|
||||
pdusession_t pdusession_setup_params[NGAP_MAX_PDUSESSION];
|
||||
|
||||
/* UE Uplink Aggregated Max Bitrates */
|
||||
uint64_t ueAggMaxBitRateUplink;
|
||||
|
||||
/* UE Downlink Aggregated Max Bitrates */
|
||||
uint64_t ueAggMaxBitRateDownlink;
|
||||
|
||||
} ngap_pdusession_setup_req_t;
|
||||
|
||||
typedef struct ngap_pdusession_setup_resp_s {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
add_subdirectory(MESSAGES)
|
||||
|
||||
add_library(E1AP e1ap.c)
|
||||
target_link_libraries(E1AP
|
||||
PUBLIC asn1_e1ap
|
||||
PRIVATE UTIL asn1_nr_rrc asn1_lte_rrc)
|
||||
target_include_directories(E1AP PUBLIC ${CMAKE_CURRENT_DIR})
|
||||
add_library(e1ap e1ap.c e1ap_common.c e1ap_api.c)
|
||||
target_link_libraries(e1ap
|
||||
PUBLIC asn1_e1ap f1ap
|
||||
PRIVATE asn1_nr_rrc asn1_lte_rrc asn1_f1ap UTIL e1_pdcp_if e1_if)
|
||||
target_include_directories(e1ap PUBLIC ${CMAKE_CURRENT_DIR})
|
||||
|
||||
+1471
-111
File diff suppressed because it is too large
Load Diff
+28
-6
@@ -24,11 +24,33 @@
|
||||
#ifndef __E1AP_H_
|
||||
#define __E1AP_H_
|
||||
|
||||
#include <common/utils/LOG/log.h>
|
||||
#include "common/openairinterface5g_limits.h"
|
||||
#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
|
||||
#include "openair2/COMMON/e1ap_messages_types.h"
|
||||
#include "e1ap_asnc.h"
|
||||
#include "openair2/E1AP/e1ap_common.h"
|
||||
|
||||
#include <E1AP_Cause.h>
|
||||
#include <E1AP_InitiatingMessage.h>
|
||||
#include <E1AP_E1AP-PDU.h>
|
||||
int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
|
||||
|
||||
int e1apCUUP_handle_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
|
||||
|
||||
int e1apCUUP_handle_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
|
||||
|
||||
int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
|
||||
|
||||
int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
|
||||
|
||||
void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, e1ap_bearer_setup_resp_t *const resp);
|
||||
|
||||
int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
|
||||
|
||||
int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, e1ap_bearer_release_cmd_t *const cmd);
|
||||
|
||||
void *E1AP_CUUP_task(void *arg);
|
||||
|
||||
void *E1AP_CUCP_task(void *arg);
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* 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 <arpa/inet.h>
|
||||
#include "e1ap_api.h"
|
||||
#include "UTIL/OSA/osa_defs.h"
|
||||
#include "nr_pdcp/nr_pdcp_entity.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h"
|
||||
#include "openair2/RRC/NR/cucp_cuup_if.h"
|
||||
#include "openair2/RRC/LTE/MESSAGES/asn1_msg.h"
|
||||
#include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
#include "e1ap_asnc.h"
|
||||
#include "e1ap_common.h"
|
||||
#include "e1ap.h"
|
||||
|
||||
struct NR_DRB_ToAddMod;
|
||||
static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_to_setup_t *pdu) {
|
||||
|
||||
for (int i=0; i < pdu->numDRB2Setup; i++) {
|
||||
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + i;
|
||||
asn1cSequenceAdd(DRB_configList->list, struct NR_DRB_ToAddMod, ie);
|
||||
ie->drb_Identity = drb->id;
|
||||
ie->cnAssociation = CALLOC(1, sizeof(*ie->cnAssociation));
|
||||
ie->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||
|
||||
// sdap_Config
|
||||
asn1cCalloc(ie->cnAssociation->choice.sdap_Config, sdap_config);
|
||||
sdap_config->pdu_Session = pdu->sessionId;
|
||||
sdap_config->sdap_HeaderDL = drb->sDAP_Header_DL;
|
||||
sdap_config->sdap_HeaderUL = drb->sDAP_Header_UL;
|
||||
sdap_config->defaultDRB = drb->defaultDRB;
|
||||
|
||||
asn1cCalloc(sdap_config->mappedQoS_FlowsToAdd, FlowsToAdd);
|
||||
for (int j=0; j < drb->numQosFlow2Setup; j++) {
|
||||
asn1cSequenceAdd(FlowsToAdd->list, NR_QFI_t, qfi);
|
||||
*qfi = drb->qosFlows[j].fiveQI;
|
||||
}
|
||||
sdap_config->mappedQoS_FlowsToRelease = NULL;
|
||||
|
||||
// pdcp_Config
|
||||
ie->reestablishPDCP = NULL;
|
||||
ie->recoverPDCP = NULL;
|
||||
asn1cCalloc(ie->pdcp_Config, pdcp_config);
|
||||
asn1cCalloc(pdcp_config->drb, drbCfg);
|
||||
asn1cCallocOne(drbCfg->discardTimer, drb->discardTimer);
|
||||
asn1cCallocOne(drbCfg->pdcp_SN_SizeUL, drb->pDCP_SN_Size_UL);
|
||||
asn1cCallocOne(drbCfg->pdcp_SN_SizeDL, drb->pDCP_SN_Size_DL);
|
||||
drbCfg->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
drbCfg->headerCompression.choice.notUsed = 0;
|
||||
|
||||
drbCfg->integrityProtection = NULL;
|
||||
drbCfg->statusReportRequired = NULL;
|
||||
drbCfg->outOfOrderDelivery = NULL;
|
||||
pdcp_config->moreThanOneRLC = NULL;
|
||||
|
||||
pdcp_config->t_Reordering = calloc(1, sizeof(*pdcp_config->t_Reordering));
|
||||
*pdcp_config->t_Reordering = drb->reorderingTimer;
|
||||
pdcp_config->ext1 = NULL;
|
||||
|
||||
if (pdu->integrityProtectionIndication == 0 || // Required
|
||||
pdu->integrityProtectionIndication == 1) { // Preferred
|
||||
asn1cCallocOne(drbCfg->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled);
|
||||
}
|
||||
|
||||
if (pdu->confidentialityProtectionIndication == 0 || // Required
|
||||
pdu->confidentialityProtectionIndication == 1) { // Preferred
|
||||
asn1cCalloc(pdcp_config->ext1, ext1);
|
||||
asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req,
|
||||
gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp,
|
||||
instance_t instance) {
|
||||
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
|
||||
NR_DRB_ToAddModList_t DRB_configList = {0};
|
||||
for (int i=0; i < req->numPDUSessions; i++) {
|
||||
pdu_session_to_setup_t *const pdu = &req->pduSession[i];
|
||||
create_tunnel_req.pdusession_id[i] = pdu->sessionId;
|
||||
create_tunnel_req.incoming_rb_id[i] = pdu->DRBnGRanList[0].id; // taking only the first DRB. TODO:change this
|
||||
memcpy(&create_tunnel_req.dst_addr[i].buffer,
|
||||
&pdu->tlAddress,
|
||||
sizeof(uint8_t)*4);
|
||||
create_tunnel_req.dst_addr[i].length = 32; // 8bits * 4bytes
|
||||
create_tunnel_req.outgoing_teid[i] = pdu->teId;
|
||||
fill_DRB_configList_e1(&DRB_configList, pdu);
|
||||
}
|
||||
create_tunnel_req.num_tunnels = req->numPDUSessions;
|
||||
create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
|
||||
|
||||
// Create N3 tunnel
|
||||
int ret = gtpv1u_create_ngu_tunnel(instance,
|
||||
&create_tunnel_req,
|
||||
create_tunnel_resp);
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE id %ld\n",
|
||||
create_tunnel_req.ue_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Configure DRBs
|
||||
uint8_t *kUPenc = NULL;
|
||||
uint8_t *kUPint = NULL;
|
||||
|
||||
nr_derive_key(UP_ENC_ALG, req->cipheringAlgorithm, (uint8_t *)req->encryptionKey, &kUPenc);
|
||||
|
||||
nr_derive_key(UP_INT_ALG, req->integrityProtectionAlgorithm, (uint8_t *)req->integrityProtectionKey, &kUPint);
|
||||
|
||||
nr_pdcp_e1_add_drbs(true, // set this to notify PDCP that his not UE
|
||||
create_tunnel_req.ue_id,
|
||||
&DRB_configList,
|
||||
(req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm,
|
||||
kUPenc,
|
||||
kUPint);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_req_t *const req)
|
||||
{
|
||||
e1ap_upcp_inst_t *inst = getCxtE1(instance);
|
||||
AssertFatal(inst, "");
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0};
|
||||
|
||||
// GTP tunnel for UL
|
||||
drb_config_N3gtpu_create(req, &create_tunnel_resp_N3, inst->gtpInstN3);
|
||||
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_RESP);
|
||||
e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg);
|
||||
|
||||
in_addr_t my_addr;
|
||||
if (inet_pton(AF_INET, inst->setupReq.localAddressF1U, &my_addr) != 1)
|
||||
LOG_E(E1AP, "can't use the F1-U local interface: %s\n", inst->setupReq.localAddressF1U);
|
||||
fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->setupReq.remotePortF1U, my_addr);
|
||||
|
||||
resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id;
|
||||
resp->numPDUSessions = req->numPDUSessions;
|
||||
for (int i=0; i < req->numPDUSessions; i++) {
|
||||
pdu_session_setup_t *pduSetup = resp->pduSession + i;
|
||||
pdu_session_to_setup_t *pdu2Setup = req->pduSession + i;
|
||||
|
||||
pduSetup->id = pdu2Setup->sessionId;
|
||||
if (inet_pton(AF_INET, inst->setupReq.localAddressN3, &pduSetup->tlAddress) != 1)
|
||||
LOG_E(E1AP, "can't use the N3 local interface: %s\n", inst->setupReq.localAddressN3);
|
||||
pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i];
|
||||
pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup;
|
||||
|
||||
// At this point we don't have a way to know the DRBs that failed to setup
|
||||
// We assume all DRBs to setup have are setup successfully so we always send successful outcome in response
|
||||
// TODO: Modify nr_pdcp_add_drbs() to return DRB list that failed to setup to support E1AP
|
||||
pduSetup->numDRBFailed = 0;
|
||||
}
|
||||
|
||||
e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst, resp);
|
||||
}
|
||||
|
||||
void CUUP_process_bearer_context_mod_req(instance_t instance, e1ap_bearer_setup_req_t *const req)
|
||||
{
|
||||
e1ap_upcp_inst_t *inst = getCxtE1(instance);
|
||||
AssertFatal(inst, "");
|
||||
// assume we receive modification of F1-U but it is wrong, we can also get modification of N3 when HO will occur
|
||||
CU_update_UP_DL_tunnel(req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id);
|
||||
// TODO: send bearer cxt mod response
|
||||
}
|
||||
|
||||
void CUUP_process_bearer_release_command(instance_t instance, e1ap_bearer_release_cmd_t *const cmd)
|
||||
{
|
||||
e1ap_upcp_inst_t *inst = getCxtE1(instance);
|
||||
AssertFatal(inst, "");
|
||||
newGtpuDeleteAllTunnels(inst->gtpInstN3, cmd->gNB_cu_up_ue_id);
|
||||
newGtpuDeleteAllTunnels(inst->gtpInstF1U, cmd->gNB_cu_up_ue_id);
|
||||
e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst, cmd);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* 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 E1AP_API_H
|
||||
#define E1AP_API_H
|
||||
|
||||
#include "platform_types.h"
|
||||
#include "openair2/COMMON/e1ap_messages_types.h"
|
||||
#include "openair2/E1AP/e1ap_common.h"
|
||||
void cuup_init_n3(instance_t instance);
|
||||
void process_e1_bearer_context_setup_req(instance_t, e1ap_bearer_setup_req_t *const req);
|
||||
void CUUP_process_bearer_context_mod_req(instance_t, e1ap_bearer_setup_req_t *const req);
|
||||
|
||||
void CUUP_process_bearer_release_command(instance_t, e1ap_bearer_release_cmd_t *const cmd);
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* 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 E1AP_ASNC_H
|
||||
#define E1AP_ASNC_H
|
||||
|
||||
#include <E1AP_Cause.h>
|
||||
#include <E1AP_InitiatingMessage.h>
|
||||
#include <E1AP_E1AP-PDU.h>
|
||||
#include <E1AP_ProtocolIE-Field.h>
|
||||
#include <E1AP_SupportedPLMNs-Item.h>
|
||||
#include <E1AP_SuccessfulOutcome.h>
|
||||
#include <E1AP_ProtocolIE-Field.h>
|
||||
#include <E1AP_UnsuccessfulOutcome.h>
|
||||
#include <E1AP_GNB-CU-UP-E1SetupFailure.h>
|
||||
#include <E1AP_GNB-CU-UP-ConfigurationUpdate.h>
|
||||
#include <E1AP_GNB-CU-UP-TNLA-To-Remove-Item.h>
|
||||
#include <E1AP_CP-TNL-Information.h>
|
||||
#include <E1AP_UP-Parameters-Item.h>
|
||||
#include <E1AP_UP-TNL-Information.h>
|
||||
#include <E1AP_PDU-Session-Resource-Setup-Item.h>
|
||||
#include <E1AP_DRB-Setup-Item-EUTRAN.h>
|
||||
#include <E1AP_DRB-Setup-Item-NG-RAN.h>
|
||||
#include <E1AP_QoS-Flow-QoS-Parameter-Item.h>
|
||||
#include <E1AP_QoS-Flow-Item.h>
|
||||
#include <E1AP_DRB-Failed-List-NG-RAN.h>
|
||||
#include <E1AP_DRB-Failed-Item-NG-RAN.h>
|
||||
#include <E1AP_BearerContextSetupResponse.h>
|
||||
#include <E1AP_BearerContextSetupRequest.h>
|
||||
#include <E1AP_DRB-To-Setup-Item-EUTRAN.h>
|
||||
#include <E1AP_DRB-To-Setup-Item-NG-RAN.h>
|
||||
#include <E1AP_Cell-Group-Information-Item.h>
|
||||
#include <E1AP_PDU-Session-Resource-To-Setup-Item.h>
|
||||
#include <E1AP_PDU-Session-Resource-To-Modify-List.h>
|
||||
#include <E1AP_PDU-Session-Resource-To-Modify-Item.h>
|
||||
#include <E1AP_DRB-To-Modify-List-NG-RAN.h>
|
||||
#include <E1AP_DRB-To-Modify-Item-NG-RAN.h>
|
||||
#include <E1AP_GTPTunnel.h>
|
||||
#include <E1AP_Non-Dynamic5QIDescriptor.h>
|
||||
#include <E1AP_Dynamic5QIDescriptor.h>
|
||||
#include <E1AP_T-ReorderingTimer.h>
|
||||
#include <E1AP_SDAP-Configuration.h>
|
||||
#include <E1AP_PDCP-Configuration.h>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* 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 <time.h>
|
||||
#include <stdlib.h>
|
||||
#include "e1ap_common.h"
|
||||
#include "e1ap_default_values.h"
|
||||
#include "e1ap_asnc.h"
|
||||
#include "common/openairinterface5g_limits.h"
|
||||
#include "common/utils/ocp_itti/intertask_interface.h"
|
||||
|
||||
static e1ap_upcp_inst_t *e1ap_inst[NUMBER_OF_gNB_MAX] = {0};
|
||||
|
||||
e1ap_upcp_inst_t *getCxtE1(instance_t instance)
|
||||
{
|
||||
AssertFatal(instance < sizeofArray(e1ap_inst), "instance exceeds limit\n");
|
||||
return e1ap_inst[instance];
|
||||
}
|
||||
|
||||
int e1ap_assoc_id(E1_t type, instance_t instance) {
|
||||
AssertFatal(e1ap_inst[instance] != NULL, "Trying to access uninitiated instance of CUCP\n");
|
||||
return e1ap_inst[instance]->setupReq.assoc_id;
|
||||
}
|
||||
|
||||
void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) {
|
||||
AssertFatal(e1ap_inst[instance] == NULL, "Double call to E1 instance %d\n", (int)instance);
|
||||
e1ap_inst[instance] = calloc(1, sizeof(e1ap_upcp_inst_t));
|
||||
e1ap_inst[instance]->type = type;
|
||||
e1ap_inst[instance]->instance = instance;
|
||||
if (req)
|
||||
memcpy(&e1ap_inst[instance]->setupReq, req, sizeof(*req));
|
||||
e1ap_inst[instance]->gtpInstN3 = -1;
|
||||
e1ap_inst[instance]->gtpInstF1U = -1;
|
||||
}
|
||||
|
||||
E1AP_TransactionID_t transacID[E1AP_MAX_NUM_TRANSAC_IDS] = {0};
|
||||
|
||||
void e1ap_common_init() {
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx) {
|
||||
|
||||
bool isFreeIdxSet = false;
|
||||
for (int i=0; i < E1AP_MAX_NUM_TRANSAC_IDS; i++) {
|
||||
if (id == transacID[i])
|
||||
return false;
|
||||
else if (!isFreeIdxSet && (transacID[i] == 0)) {
|
||||
*freeIdx = i;
|
||||
isFreeIdxSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
E1AP_TransactionID_t E1AP_get_next_transaction_identifier() {
|
||||
E1AP_TransactionID_t genTransacId;
|
||||
bool isTransacIdValid = false;
|
||||
int freeIdx;
|
||||
|
||||
while (!isTransacIdValid) {
|
||||
genTransacId = rand() & 255;
|
||||
isTransacIdValid = check_transac_id(genTransacId, &freeIdx);
|
||||
}
|
||||
|
||||
AssertFatal(freeIdx < E1AP_MAX_NUM_TRANSAC_IDS, "Free Index exceeds array length\n");
|
||||
transacID[freeIdx] = genTransacId;
|
||||
return genTransacId;
|
||||
}
|
||||
|
||||
void E1AP_free_transaction_identifier(E1AP_TransactionID_t id) {
|
||||
|
||||
for (int i=0; i < E1AP_MAX_NUM_TRANSAC_IDS; i++) {
|
||||
if (id == transacID[i]) {
|
||||
transacID[i] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG_E(E1AP, "Couldn't find transaction ID %ld in list\n", id);
|
||||
}
|
||||
|
||||
int e1ap_decode_initiating_message(E1AP_E1AP_PDU_t *pdu) {
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.initiatingMessage->procedureCode) {
|
||||
case E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup:
|
||||
break;
|
||||
|
||||
case E1AP_ProcedureCode_id_gNB_CU_UP_ConfigurationUpdate:
|
||||
break;
|
||||
|
||||
case E1AP_ProcedureCode_id_bearerContextSetup:
|
||||
break;
|
||||
|
||||
case E1AP_ProcedureCode_id_bearerContextModification:
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(E1AP, "Unsupported procedure code (%d) for initiating message\n",
|
||||
(int)pdu->choice.initiatingMessage->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int e1ap_decode_successful_outcome(E1AP_E1AP_PDU_t *pdu) {
|
||||
DevAssert(pdu != NULL);
|
||||
switch(pdu->choice.successfulOutcome->procedureCode) {
|
||||
case E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup:
|
||||
break;
|
||||
|
||||
case E1AP_ProcedureCode_id_bearerContextSetup:
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(E1AP, "Unsupported procedure code (%d) for successful message\n",
|
||||
(int)pdu->choice.successfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int e1ap_decode_unsuccessful_outcome(E1AP_E1AP_PDU_t *pdu) {
|
||||
DevAssert(pdu != NULL);
|
||||
switch(pdu->choice.unsuccessfulOutcome->procedureCode) {
|
||||
case E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup:
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(E1AP, "Unsupported procedure code (%d) for unsuccessful message\n",
|
||||
(int)pdu->choice.unsuccessfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) {
|
||||
asn_dec_rval_t dec_ret;
|
||||
DevAssert(buffer != NULL);
|
||||
dec_ret = aper_decode(NULL,
|
||||
&asn_DEF_E1AP_E1AP_PDU,
|
||||
(void **)&pdu,
|
||||
buffer,
|
||||
length,
|
||||
0,
|
||||
0);
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
||||
LOG_E(E1AP, "----------------- ASN1 DECODER PRINT START----------------- \n");
|
||||
xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, pdu);
|
||||
LOG_E(E1AP, "----------------- ASN1 DECODER PRINT END ----------------- \n");
|
||||
}
|
||||
|
||||
if (dec_ret.code != RC_OK) {
|
||||
AssertFatal(1==0,"Failed to decode pdu\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(pdu->present) {
|
||||
case E1AP_E1AP_PDU_PR_initiatingMessage:
|
||||
return e1ap_decode_initiating_message(pdu);
|
||||
|
||||
case E1AP_E1AP_PDU_PR_successfulOutcome:
|
||||
return e1ap_decode_successful_outcome(pdu);
|
||||
|
||||
case E1AP_E1AP_PDU_PR_unsuccessfulOutcome:
|
||||
return e1ap_decode_unsuccessful_outcome(pdu);
|
||||
|
||||
default:
|
||||
LOG_E(E1AP, "Unknown presence (%d) or not implemented\n", (int)pdu->present);
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func)
|
||||
{
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
||||
LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT START ----------------- \n");
|
||||
xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, pdu);
|
||||
LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n");
|
||||
}
|
||||
|
||||
char errbuf[2048]; /* Buffer for error message */
|
||||
size_t errlen = sizeof(errbuf); /* Size of the buffer */
|
||||
int ret = asn_check_constraints(&asn_DEF_E1AP_E1AP_PDU, pdu, errbuf, &errlen);
|
||||
|
||||
if(ret) {
|
||||
LOG_E(E1AP, "%s: Constraint validation failed: %s\n", func, errbuf);
|
||||
}
|
||||
|
||||
void *buffer = NULL;
|
||||
ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, &buffer);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, pdu);
|
||||
|
||||
if (encoded < 0) {
|
||||
LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func);
|
||||
return -1;
|
||||
} else {
|
||||
MessageDef *message = itti_alloc_new_message((type==CPtype)?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ);
|
||||
sctp_data_req_t *s = &message->ittiMsg.sctp_data_req;
|
||||
s->assoc_id = setupReq->assoc_id;
|
||||
s->buffer = buffer;
|
||||
s->buffer_length = encoded;
|
||||
s->stream = stream;
|
||||
LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func);
|
||||
itti_send_msg_to_task(TASK_SCTP, 0 /*unused by callee*/, message);
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* 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 E1AP_COMMON_H_
|
||||
#define E1AP_COMMON_H_
|
||||
#include "openair2/COMMON/e1ap_messages_types.h"
|
||||
#include "e1ap_asnc.h"
|
||||
#include "openair2/COMMON/sctp_messages_types.h"
|
||||
#include "common/ngran_types.h"
|
||||
|
||||
typedef struct e1ap_upcp_inst_s {
|
||||
bool incoming_sock;
|
||||
instance_t instance;
|
||||
bool same_process;
|
||||
E1_t type;
|
||||
enum sctp_state_e sockState;
|
||||
uint32_t assoc_id;
|
||||
instance_t gtpInstN3;
|
||||
instance_t gtpInstF1U;
|
||||
e1ap_setup_req_t setupReq;
|
||||
e1ap_bearer_setup_req_t bearerSetupReq;
|
||||
e1ap_bearer_setup_resp_t bearerSetupResp;
|
||||
} e1ap_upcp_inst_t;
|
||||
|
||||
extern int asn1_xer_print;
|
||||
|
||||
int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length);
|
||||
|
||||
e1ap_upcp_inst_t *getCxtE1(instance_t instance);
|
||||
|
||||
E1AP_TransactionID_t E1AP_get_next_transaction_identifier();
|
||||
|
||||
void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req);
|
||||
|
||||
bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx);
|
||||
|
||||
int e1ap_assoc_id(E1_t type, instance_t instance);
|
||||
|
||||
int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func);
|
||||
|
||||
void e1ap_common_init();
|
||||
|
||||
void E1AP_free_transaction_identifier(E1AP_TransactionID_t id);
|
||||
#endif /* E1AP_COMMON_H_ */
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 E1AP_DEFAULT_VALUES_H
|
||||
#define E1AP_DEFAULT_VALUES_H
|
||||
|
||||
#define E1AP_PORT_NUMBER (38462)
|
||||
#define E1AP_SCTP_PPID (64)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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 <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "common/utils/LOG/log_extern.h"
|
||||
#include "assertions.h"
|
||||
#include "common/utils/ocp_itti/intertask_interface.h"
|
||||
#include "openair2/GNB_APP/gnb_paramdef.h"
|
||||
#include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
|
||||
static void get_NGU_S1U_addr(char **addr, uint16_t *port)
|
||||
{
|
||||
int num_gnbs = 0;
|
||||
char *gnb_ipv4_address_for_NGU = NULL;
|
||||
uint32_t gnb_port_for_NGU = 0;
|
||||
char *gnb_ipv4_address_for_S1U = NULL;
|
||||
uint32_t gnb_port_for_S1U = 0;
|
||||
char gtpupath[MAX_OPTNAME_SIZE * 2 + 8];
|
||||
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
paramdef_t NETParams[] = GNBNETPARAMS_DESC;
|
||||
LOG_I(GTPU, "Configuring GTPu\n");
|
||||
|
||||
/* get number of active eNodeBs */
|
||||
config_get(GNBSParams, sizeof(GNBSParams) / sizeof(paramdef_t), NULL);
|
||||
num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
|
||||
AssertFatal(num_gnbs > 0, "Failed to parse config file no active gNodeBs in %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS);
|
||||
|
||||
sprintf(gtpupath, "%s.[%i].%s", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
|
||||
config_get(NETParams, sizeof(NETParams) / sizeof(paramdef_t), gtpupath);
|
||||
char *address;
|
||||
if (NETParams[1].strptr != NULL) {
|
||||
LOG_I(GTPU, "SA mode \n");
|
||||
address = strdup(gnb_ipv4_address_for_NGU);
|
||||
*port = gnb_port_for_NGU;
|
||||
} else {
|
||||
LOG_I(GTPU, "NSA mode \n");
|
||||
address = strdup(gnb_ipv4_address_for_S1U);
|
||||
*port = gnb_port_for_S1U;
|
||||
}
|
||||
if (strchr(address, '/'))
|
||||
*strchr(address, '/') = 0;
|
||||
*addr = address;
|
||||
return;
|
||||
}
|
||||
|
||||
MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process)
|
||||
{
|
||||
MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ);
|
||||
if (!msgConfig)
|
||||
return NULL;
|
||||
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
paramdef_t GNBParams[] = GNBPARAMS_DESC;
|
||||
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST, NULL, 0};
|
||||
config_get(GNBSParams, sizeofArray(GNBSParams), NULL);
|
||||
char aprefix[MAX_OPTNAME_SIZE * 2 + 8];
|
||||
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
|
||||
int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
|
||||
AssertFatal(num_gnbs == 1, "Support only one gNB per process\n");
|
||||
|
||||
if (num_gnbs > 0) {
|
||||
config_getlist(&GNBParamList, GNBParams, sizeofArray(GNBParams), NULL);
|
||||
paramdef_t *gnbParms = GNBParamList.paramarray[0];
|
||||
AssertFatal(gnbParms[GNB_GNB_ID_IDX].uptr != NULL, "gNB id %u is not defined in configuration file\n", 0);
|
||||
e1ap_setup_req_t *e1Setup = &E1AP_SETUP_REQ(msgConfig);
|
||||
msgConfig->ittiMsgHeader.destinationInstance = 0;
|
||||
e1Setup->gNB_cu_up_id = *(gnbParms[GNB_GNB_ID_IDX].uptr);
|
||||
|
||||
paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC;
|
||||
paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
|
||||
/* map parameter checking array instances to parameter definition array instances */
|
||||
checkedparam_t config_check_PLMNParams[] = PLMNPARAMS_CHECK;
|
||||
|
||||
for (int I = 0; I < sizeofArray(PLMNParams); ++I)
|
||||
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
|
||||
|
||||
config_getlist(&PLMNParamList, PLMNParams, sizeofArray(PLMNParams), aprefix);
|
||||
int numPLMNs = PLMNParamList.numelt;
|
||||
e1Setup->supported_plmns = numPLMNs;
|
||||
|
||||
for (int I = 0; I < numPLMNs; I++) {
|
||||
e1Setup->plmns[I].mcc = *PLMNParamList.paramarray[I][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
}
|
||||
|
||||
e1Setup->remotePortF1U = *(GNBParamList.paramarray[0][GNB_REMOTE_S_PORTD_IDX].uptr);
|
||||
e1Setup->localAddressF1U = strdup(*(GNBParamList.paramarray[0][GNB_LOCAL_S_ADDRESS_IDX].strptr));
|
||||
e1Setup->localPortF1U = *(GNBParamList.paramarray[0][GNB_LOCAL_S_PORTD_IDX].uptr);
|
||||
get_NGU_S1U_addr(&e1Setup->localAddressN3, &e1Setup->localPortN3);
|
||||
e1Setup->remotePortN3 = GTPV1_U_PORT_NUMBER;
|
||||
|
||||
if (separate_CUUP_process) {
|
||||
paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0};
|
||||
paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC;
|
||||
config_getlist(&GNBE1ParamList, GNBE1Params, sizeofArray(GNBE1Params), aprefix);
|
||||
paramdef_t *e1Parms = GNBE1ParamList.paramarray[0];
|
||||
strcpy(e1Setup->CUCP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr));
|
||||
e1Setup->CUCP_e1_ip_address.ipv4 = 1;
|
||||
strcpy(e1Setup->CUUP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr));
|
||||
e1Setup->CUUP_e1_ip_address.ipv4 = 1;
|
||||
e1Setup->cn_support = *e1Parms[GNB_CONFIG_E1_CN_SUPPORT].uptr;
|
||||
}
|
||||
}
|
||||
return msgConfig;
|
||||
}
|
||||
@@ -40,7 +40,8 @@
|
||||
|
||||
# include "intertask_interface.h"
|
||||
# include "s1ap_eNB.h"
|
||||
#include "sctp_eNB_task.h"
|
||||
# include "sctp_eNB_task.h"
|
||||
# include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
|
||||
# include "x2ap_eNB.h"
|
||||
# include "x2ap_messages_types.h"
|
||||
|
||||
@@ -2015,7 +2015,7 @@ int RCconfig_gtpu(void ) {
|
||||
int num_enbs = 0;
|
||||
char *enb_interface_name_for_S1U = NULL;
|
||||
char *enb_ipv4_address_for_S1U = NULL;
|
||||
uint32_t enb_port_for_S1U = 0;
|
||||
uint16_t enb_port_for_S1U = 0;
|
||||
char *address = NULL;
|
||||
char *cidr = NULL;
|
||||
char gtpupath[MAX_OPTNAME_SIZE*2 + 8];
|
||||
|
||||
@@ -1123,12 +1123,13 @@ typedef struct srb1_params_s {
|
||||
/* S1/X2 interface configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
// clang-format off
|
||||
#define NETPARAMS_DESC { \
|
||||
{ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, u16ptr:NULL, defuintval:GTPV1_U_PORT_NUMBER, TYPE_UINT16, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_M2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
@@ -1144,8 +1145,10 @@ typedef struct srb1_params_s {
|
||||
#define GTPUPARAMS_DESC { \
|
||||
{ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:&enb_interface_name_for_S1U, defstrval:"lo", TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:&enb_ipv4_address_for_S1U, defstrval:"127.0.0.1", TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, uptr:&enb_port_for_S1U, defintval:2152, TYPE_UINT, 0} \
|
||||
{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, u16ptr:&enb_port_for_S1U, defuintval:GTPV1_U_PORT_NUMBER, TYPE_UINT16, 0} \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -26,12 +26,6 @@
|
||||
#include "NR_ServingCellConfigCommon.h"
|
||||
#include "NR_MIB.h"
|
||||
|
||||
void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP ) {
|
||||
abort();
|
||||
}
|
||||
|
||||
bool sdap_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const ue_id_t ue_id,
|
||||
const srb_flag_t srb_flag,
|
||||
|
||||
@@ -144,7 +144,9 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance,
|
||||
|
||||
// LTS: FIXME data model failure: we don't KNOW if we receive a 4G or a 5G cell
|
||||
// Furthermore, cell_type is not a attribute of a cell in the data structure !!!!!!!!!!
|
||||
if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU)
|
||||
if (RC.nrrrc &&
|
||||
( RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU ||
|
||||
RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CUCP) )
|
||||
f1ap_req(true, instance)->cell_type=CELL_MACRO_GNB;
|
||||
else
|
||||
f1ap_req(true, instance)->cell_type=CELL_MACRO_ENB;
|
||||
|
||||
@@ -57,8 +57,11 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_as
|
||||
f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams;
|
||||
f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams;
|
||||
f1ap_cu_data->default_sctp_stream_id = 0;
|
||||
getCxt(CUtype, instance)->gtpInst=cu_task_create_gtpu_instance(IPaddrs);
|
||||
AssertFatal(getCxt(CUtype, instance)->gtpInst>0,"Failed to create CU F1-U UDP listener");
|
||||
if (RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type != ngran_gNB_CUCP) {
|
||||
getCxt(CUtype, instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs);
|
||||
AssertFatal(getCxt(CUtype, instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener");
|
||||
} else
|
||||
LOG_I(F1AP, "In F1AP connection, don't start GTP-U, as we have also E1AP\n");
|
||||
// Fixme: fully inconsistent instances management
|
||||
// dirty global var is a bad fix
|
||||
CUuniqInstance=getCxt(CUtype, instance)->gtpInst;
|
||||
@@ -120,7 +123,9 @@ void *F1AP_CU_task(void *arg) {
|
||||
eth_params_t *IPaddrs;
|
||||
|
||||
// Hardcoded instance id!
|
||||
if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_CU)
|
||||
if (RC.nrrrc &&
|
||||
(RC.nrrrc[0]->node_type == ngran_gNB_CU ||
|
||||
RC.nrrrc[0]->node_type == ngran_gNB_CUCP ) )
|
||||
IPaddrs=&RC.nrrrc[0]->eth_params_s;
|
||||
else
|
||||
IPaddrs=&RC.rrc[0]->eth_params_s;
|
||||
@@ -129,71 +134,57 @@ void *F1AP_CU_task(void *arg) {
|
||||
|
||||
while (1) {
|
||||
itti_receive_msg(TASK_CU_F1, &received_msg);
|
||||
|
||||
LOG_I(F1AP, "CU Task Received %s for instance %ld\n",
|
||||
ITTI_MSG_NAME(received_msg), ITTI_MSG_DESTINATION_INSTANCE(received_msg));
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
case SCTP_NEW_ASSOCIATION_IND:
|
||||
LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_IND for instance %ld\n",
|
||||
ITTI_MSG_DESTINATION_INSTANCE(received_msg));
|
||||
cu_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_ind,
|
||||
IPaddrs);
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP:
|
||||
LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_RESP for instance %ld\n",
|
||||
ITTI_MSG_DESTINATION_INSTANCE(received_msg));
|
||||
cu_task_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND:
|
||||
LOG_I(F1AP, "CU Task Received SCTP_DATA_IND for Instance %ld\n",
|
||||
ITTI_MSG_DESTINATION_INSTANCE(received_msg));
|
||||
cu_task_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_data_ind);
|
||||
break;
|
||||
|
||||
case F1AP_SETUP_RESP: // from rrc
|
||||
LOG_I(F1AP, "CU Task Received F1AP_SETUP_RESP\n");
|
||||
CU_send_F1_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_SETUP_RESP(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE: // from rrc
|
||||
LOG_I(F1AP, "CU Task Received F1AP_GNB_CU_CONFIGURAITON_UPDATE\n");
|
||||
// CU_send_f1setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &F1AP_SETUP_RESP(received_msg));
|
||||
CU_send_gNB_CU_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_DL_RRC_MESSAGE: // from rrc
|
||||
LOG_I(F1AP, "CU Task Received F1AP_DL_RRC_MESSAGE\n");
|
||||
CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_DL_RRC_MESSAGE(received_msg));
|
||||
free(F1AP_DL_RRC_MESSAGE(received_msg).rrc_container);
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc
|
||||
LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_SETUP_REQ\n");
|
||||
CU_send_UE_CONTEXT_SETUP_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_MODIFICATION_REQ:
|
||||
LOG_I(F1AP, "CU Task received F1AP_UE_CONTEXT_MODIFICATION_REQ\n");
|
||||
CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg));
|
||||
&F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
|
||||
LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n");
|
||||
CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_UE_CONTEXT_RELEASE_CMD(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_PAGING_IND:
|
||||
LOG_I(F1AP, "CU Task Received F1AP_PAGING_IND\n");
|
||||
CU_send_Paging(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_PAGING_IND(received_msg));
|
||||
break;
|
||||
|
||||
@@ -510,6 +510,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
|
||||
/* 12.1.3 uLUPTNLInformation_ToBeSetup_List */
|
||||
for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) {
|
||||
/*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/
|
||||
/* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */
|
||||
transport_layer_addr_t addr = { length: 32, buffer: { 0 } };
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
||||
@@ -1009,7 +1010,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
f1ap_remove_ue(CUtype, instance, rnti);
|
||||
return 0;
|
||||
}
|
||||
//void CU_send_UE_CONTEXT_MODIFICATION_REQUEST(F1AP_UEContextModificationRequest_t *UEContextModificationRequest) {
|
||||
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_setup_t *f1ap_ue_context_modification_req) {
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
F1AP_UEContextModificationRequest_t *out;
|
||||
@@ -1477,19 +1478,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context
|
||||
/* 12.1.3 uLUPTNLInformation_ToBeSetup_List */
|
||||
for (int j = 0; j < f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) {
|
||||
/* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context modification response from the DU */
|
||||
transport_layer_addr_t addr = { length: 32, buffer: { 0 } };
|
||||
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
||||
f1ap_ue_context_modification_req->rnti,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
||||
0xFFFF, // We will set the right value from DU answer
|
||||
-1, // no qfi
|
||||
addr, // We will set the right value from DU answer
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
||||
cu_f1u_data_req,
|
||||
NULL);
|
||||
/* 12.3.1 ULTunnels_ToBeSetup_Item */
|
||||
asn1cSequenceAdd(drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list,
|
||||
F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
|
||||
uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
|
||||
|
||||
@@ -166,7 +166,8 @@ static int f1ap_decode_unsuccessful_outcome(F1AP_F1AP_PDU_t *pdu) {
|
||||
int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) {
|
||||
asn_dec_rval_t dec_ret;
|
||||
DevAssert(buffer != NULL);
|
||||
dec_ret = aper_decode(NULL,
|
||||
asn_codec_ctx_t st={.max_stack_size = 100 * 1000};
|
||||
dec_ret = aper_decode(&st,
|
||||
&asn_DEF_F1AP_F1AP_PDU,
|
||||
(void **)&pdu,
|
||||
buffer,
|
||||
|
||||
@@ -107,18 +107,18 @@ void *F1AP_DU_task(void *arg) {
|
||||
MessageDef *msg = NULL;
|
||||
itti_receive_msg(TASK_DU_F1, &msg);
|
||||
instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg);
|
||||
|
||||
LOG_I(F1AP, "DU Task Received %s for instance %ld\n",
|
||||
ITTI_MSG_NAME(msg),myInstance);
|
||||
switch (ITTI_MSG_ID(msg)) {
|
||||
case F1AP_SETUP_REQ:
|
||||
case F1AP_SETUP_REQ: {
|
||||
// this is not a true F1 message, but rather an ITTI message sent by enb_app
|
||||
// 1. save the itti msg so that you can use it to sen f1ap_setup_req, fill the f1ap_setup_req message,
|
||||
// 2. store the message in f1ap context, that is also stored in RC
|
||||
// 2. send a sctp_association req
|
||||
LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n");
|
||||
f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg);
|
||||
f1ap_setup_req_t *msgSetup = &F1AP_SETUP_REQ(msg);
|
||||
createF1inst(false, myInstance, msgSetup);
|
||||
du_task_send_sctp_association_req(myInstance,msgSetup);
|
||||
break;
|
||||
du_task_send_sctp_association_req(myInstance, msgSetup);
|
||||
} break;
|
||||
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
|
||||
DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_ORIGIN_INSTANCE(msg),
|
||||
@@ -133,32 +133,23 @@ void *F1AP_DU_task(void *arg) {
|
||||
case SCTP_NEW_ASSOCIATION_RESP:
|
||||
// 1. store the respon
|
||||
// 2. send the f1setup_req
|
||||
LOG_I(F1AP, "DU Task Received SCTP_NEW_ASSOCIATION_RESP\n");
|
||||
du_task_handle_sctp_association_resp(myInstance,
|
||||
&msg->ittiMsg.sctp_new_association_resp);
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND:
|
||||
// ex: any F1 incoming message for DU ends here
|
||||
LOG_I(F1AP, "DU Task Received SCTP_DATA_IND\n");
|
||||
du_task_handle_sctp_data_ind(myInstance,
|
||||
&msg->ittiMsg.sctp_data_ind);
|
||||
break;
|
||||
|
||||
case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc
|
||||
LOG_I(F1AP, "DU Task Received F1AP_INITIAL_UL_RRC_MESSAGE\n");
|
||||
{
|
||||
f1ap_initial_ul_rrc_message_t *msgRrc = &F1AP_INITIAL_UL_RRC_MESSAGE(msg);
|
||||
DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0,0,0,msgRrc->crnti,
|
||||
msgRrc->rrc_container,
|
||||
msgRrc->rrc_container_length,
|
||||
msgRrc->du2cu_rrc_container,
|
||||
msgRrc->du2cu_rrc_container_length
|
||||
);
|
||||
break;
|
||||
DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0, 0, 0, msgRrc->crnti, msgRrc->rrc_container, msgRrc->rrc_container_length, msgRrc->du2cu_rrc_container, msgRrc->du2cu_rrc_container_length);
|
||||
} break;
|
||||
|
||||
case F1AP_UL_RRC_MESSAGE: // to rrc
|
||||
LOG_D(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n");
|
||||
|
||||
if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) {
|
||||
DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance,
|
||||
&F1AP_UL_RRC_MESSAGE(msg));
|
||||
@@ -174,12 +165,10 @@ void *F1AP_DU_task(void *arg) {
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_MODIFICATION_RESP:
|
||||
LOG_I(F1AP, "DU task received itti message from RRC for F1AP_UE_CONTEXT_MODIFICATION_RESP message generation \n");
|
||||
DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC
|
||||
LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n");
|
||||
DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance,
|
||||
&F1AP_UE_CONTEXT_RELEASE_REQ(msg));
|
||||
break;
|
||||
|
||||
@@ -1078,7 +1078,7 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
|
||||
static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport)
|
||||
{
|
||||
openAddr_t tmp={0};
|
||||
openAddr_t tmp = {0};
|
||||
strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1);
|
||||
strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1);
|
||||
sprintf(tmp.originService, "%d", DUport);
|
||||
|
||||
+29
-58
@@ -35,7 +35,6 @@
|
||||
#include <split_headers.h>
|
||||
|
||||
#include "gnb_app.h"
|
||||
#include "gnb_config.h"
|
||||
#include "assertions.h"
|
||||
#include "common/ran_context.h"
|
||||
|
||||
@@ -52,6 +51,8 @@
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include <openair2/LAYER2/nr_pdcp/nr_pdcp.h>
|
||||
#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h"
|
||||
#include "openair2/E1AP/e1ap.h"
|
||||
#include "gnb_config.h"
|
||||
extern unsigned char NB_gNB_INST;
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
@@ -59,7 +60,7 @@ extern RAN_CONTEXT_t RC;
|
||||
#define GNB_REGISTER_RETRY_DELAY 10
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static void configure_nr_rrc(uint32_t gnb_id)
|
||||
void configure_nr_rrc(uint32_t gnb_id)
|
||||
{
|
||||
MessageDef *msg_p = NULL;
|
||||
// int CC_id;
|
||||
@@ -80,7 +81,7 @@ static void configure_nr_rrc(uint32_t gnb_id)
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties)
|
||||
uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties)
|
||||
{
|
||||
uint32_t gnb_id;
|
||||
MessageDef *msg_p;
|
||||
@@ -102,7 +103,6 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//,
|
||||
|
||||
itti_send_msg_to_task (TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
|
||||
}
|
||||
if (gnb_id == 0) RCconfig_nr_gtpu();
|
||||
}
|
||||
|
||||
LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id));
|
||||
@@ -115,7 +115,7 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//,
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) {
|
||||
uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) {
|
||||
uint32_t gnb_id;
|
||||
MessageDef *msg_p;
|
||||
uint32_t register_gnb_x2_pending = 0;
|
||||
@@ -138,10 +138,6 @@ static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end)
|
||||
void *gNB_app_task(void *args_p)
|
||||
{
|
||||
|
||||
uint32_t gnb_nb = RC.nb_nr_inst;
|
||||
uint32_t gnb_id_start = 0;
|
||||
uint32_t gnb_id_end = gnb_id_start + gnb_nb;
|
||||
uint32_t gnb_id;
|
||||
MessageDef *msg_p = NULL;
|
||||
const char *msg_name = NULL;
|
||||
instance_t instance;
|
||||
@@ -151,60 +147,35 @@ void *gNB_app_task(void *args_p)
|
||||
|
||||
int cell_to_activate = 0;
|
||||
itti_mark_task_ready (TASK_GNB_APP);
|
||||
ngran_node_t node_type = get_node_type();
|
||||
|
||||
LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
|
||||
|
||||
RCconfig_NR_L1();
|
||||
RCconfig_nr_prs();
|
||||
|
||||
if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc();
|
||||
|
||||
LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
|
||||
|
||||
if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n");
|
||||
|
||||
AssertFatal (gnb_nb <= RC.nb_nr_inst,
|
||||
"Number of gNB is greater than gNB defined in configuration file (%d/%d)!",
|
||||
gnb_nb, RC.nb_nr_inst);
|
||||
|
||||
LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst);
|
||||
|
||||
RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
|
||||
LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
|
||||
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
|
||||
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST));
|
||||
LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end);
|
||||
configure_nr_rrc(gnb_id);
|
||||
}
|
||||
|
||||
if (RC.nb_nr_inst > 0 && !get_softmodem_params()->nsa) {
|
||||
init_pdcp();
|
||||
}
|
||||
|
||||
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
|
||||
LOG_I(X2AP, "X2AP enabled \n");
|
||||
__attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
|
||||
}
|
||||
|
||||
/* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info
|
||||
* can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/
|
||||
if ((get_softmodem_params()->sa || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) ) { //&& !NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
/* Try to register each gNB */
|
||||
//registered_gnb = 0;
|
||||
__attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);
|
||||
}
|
||||
|
||||
if (RC.nb_nr_inst > 0) {
|
||||
if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
if (node_type == ngran_gNB_CUCP ||
|
||||
node_type == ngran_gNB_CU ||
|
||||
node_type == ngran_eNB_CU ||
|
||||
node_type == ngran_ng_eNB_CU) {
|
||||
|
||||
if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) {
|
||||
LOG_E(F1AP, "Create task for F1AP CU failed\n");
|
||||
AssertFatal(1==0,"exiting");
|
||||
LOG_E(F1AP, "Create task for F1AP CU failed\n");
|
||||
AssertFatal(1==0,"exiting");
|
||||
}
|
||||
}
|
||||
|
||||
if (NODE_IS_DU(RC.nrrrc[0]->node_type)) {
|
||||
if (node_type == ngran_gNB_CUCP) {
|
||||
if (itti_create_task(TASK_CUCP_E1, E1AP_CUCP_task, NULL) < 0)
|
||||
AssertFatal(false, "Create task for E1AP CP failed\n");
|
||||
MessageDef *msg = RCconfig_NR_CU_E1(true);
|
||||
if (msg)
|
||||
itti_send_msg_to_task(TASK_CUCP_E1, 0, msg);
|
||||
else
|
||||
AssertFatal(false, "Send inti to task for E1AP CP failed\n");
|
||||
}
|
||||
|
||||
if (node_type == ngran_gNB_CUUP) {
|
||||
AssertFatal(false, "To run CU-UP use executable nr-cuup\n");
|
||||
}
|
||||
|
||||
if (NODE_IS_DU(node_type)) {
|
||||
if (itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL) < 0) {
|
||||
LOG_E(F1AP, "Create task for F1AP DU failed\n");
|
||||
AssertFatal(1==0,"exiting");
|
||||
@@ -213,7 +184,7 @@ void *gNB_app_task(void *args_p)
|
||||
LOG_I(GNB_APP,"ngran_gNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
|
||||
msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_SETUP_REQ);
|
||||
RCconfig_NR_DU_F1(msg_p, 0);
|
||||
|
||||
|
||||
itti_send_msg_to_task (TASK_DU_F1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
|
||||
}
|
||||
}
|
||||
@@ -279,7 +250,7 @@ void *gNB_app_task(void *args_p)
|
||||
break;
|
||||
|
||||
case F1AP_SETUP_RESP:
|
||||
AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n");
|
||||
AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n");
|
||||
|
||||
LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
|
||||
F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
|
||||
@@ -289,7 +260,7 @@ void *gNB_app_task(void *args_p)
|
||||
|
||||
break;
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE:
|
||||
AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n");
|
||||
AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n");
|
||||
|
||||
LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).gNB_CU_name,F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
void *gNB_app_task(void *args_p);
|
||||
|
||||
|
||||
void configure_nr_rrc(uint32_t gnb_id);
|
||||
uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end);
|
||||
uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end);
|
||||
#endif /* GNB_APP_H_ */
|
||||
|
||||
@@ -91,8 +91,6 @@
|
||||
extern uint16_t sf_ahead;
|
||||
int macrlc_has_f1 = 0;
|
||||
|
||||
static ngran_node_t get_node_type(void);
|
||||
|
||||
extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency,
|
||||
int32_t uplink_frequency_offset, uint32_t frame_type);
|
||||
|
||||
@@ -1154,7 +1152,8 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
|
||||
printf("NRRRC %d: Southbound Transport %s\n",i,*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr));
|
||||
|
||||
if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) {
|
||||
rrc->node_type = get_node_type();
|
||||
if (NODE_IS_CU(rrc->node_type)) {
|
||||
paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC;
|
||||
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
|
||||
sprintf(aprefix,"%s.[%u].%s",GNB_CONFIG_STRING_GNB_LIST,i,GNB_CONFIG_STRING_SCTP_CONFIG);
|
||||
@@ -1171,21 +1170,12 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
rrc->eth_params_s.my_portd = *(GNBParamList.paramarray[i][GNB_LOCAL_S_PORTD_IDX].uptr);
|
||||
rrc->eth_params_s.remote_portd = *(GNBParamList.paramarray[i][GNB_REMOTE_S_PORTD_IDX].uptr);
|
||||
rrc->eth_params_s.transp_preference = ETH_UDP_MODE;
|
||||
rrc->node_type = ngran_gNB_CU;
|
||||
rrc->sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
|
||||
rrc->sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
|
||||
} else {
|
||||
// set to ngran_gNB for now, it will get set to ngran_gNB_DU if macrlc entity which uses F1 is present
|
||||
// Note: we will have to handle the case of ngran_ng_gNB_DU
|
||||
if (macrlc_has_f1 == 0) {
|
||||
rrc->node_type = ngran_gNB;
|
||||
LOG_I(NR_RRC,"Setting node_type to ngran_gNB\n");
|
||||
} else {
|
||||
rrc->node_type = ngran_gNB_DU;
|
||||
LOG_I(NR_RRC,"Setting node_type to ngran_gNB_DU\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
rrc->nr_cellid = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr);
|
||||
|
||||
rrc->um_on_default_drb = *(GNBParamList.paramarray[i][GNB_UMONDEFAULTDRB_IDX].uptr);
|
||||
@@ -1282,55 +1272,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
config_security(rrc);
|
||||
}//End RCconfig_NRRRC function
|
||||
|
||||
int RCconfig_nr_gtpu(void ) {
|
||||
|
||||
int num_gnbs = 0;
|
||||
char* gnb_ipv4_address_for_NGU = NULL;
|
||||
uint32_t gnb_port_for_NGU = 0;
|
||||
char* gnb_ipv4_address_for_S1U = NULL;
|
||||
uint32_t gnb_port_for_S1U = 0;
|
||||
char gtpupath[MAX_OPTNAME_SIZE*2 + 8];
|
||||
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
paramdef_t NETParams[] = GNBNETPARAMS_DESC;
|
||||
LOG_I(GTPU,"Configuring GTPu\n");
|
||||
|
||||
/* get number of active eNodeBs */
|
||||
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
|
||||
num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
|
||||
AssertFatal (num_gnbs >0,
|
||||
"Failed to parse config file no active gNodeBs in %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS);
|
||||
|
||||
sprintf(gtpupath,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
|
||||
config_get(NETParams,sizeof(NETParams)/sizeof(paramdef_t),gtpupath);
|
||||
char *cidr=NULL, *address = NULL;
|
||||
int port;
|
||||
if (NETParams[1].strptr != NULL) {
|
||||
LOG_I(GTPU, "SA mode \n");
|
||||
address = strtok_r(gnb_ipv4_address_for_NGU, "/", &cidr);
|
||||
port=gnb_port_for_NGU;
|
||||
} else {
|
||||
LOG_I(GTPU, "NSA mode \n");
|
||||
address = strtok_r(gnb_ipv4_address_for_S1U, "/", &cidr);
|
||||
port=gnb_port_for_S1U;
|
||||
}
|
||||
|
||||
if (address) {
|
||||
MessageDef *message;
|
||||
message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_REQ);
|
||||
AssertFatal(message!=NULL,"");
|
||||
IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_REQ(message).localAddr, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_REQ(message).localAddr);
|
||||
GTPV1U_REQ(message).localPort = port;
|
||||
strcpy(GTPV1U_REQ(message).localAddrStr,address);
|
||||
sprintf(GTPV1U_REQ(message).localPortStr,"%d", port);
|
||||
itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
|
||||
} else
|
||||
LOG_E(GTPU,"invalid address for NGU or S1U\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
|
||||
|
||||
int j,k = 0;
|
||||
@@ -1957,8 +1898,8 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) {
|
||||
f1Setup->mib_length[k] = rrc->carrier.sizeof_MIB;
|
||||
|
||||
NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
|
||||
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
||||
asn_codec_ctx_t st={100*1000};
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete( &st,
|
||||
&asn_DEF_NR_BCCH_DL_SCH_Message,
|
||||
(void **)&bcch_message,
|
||||
(const void *)rrc->carrier.SIB1,
|
||||
@@ -2252,16 +2193,24 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static ngran_node_t get_node_type(void)
|
||||
ngran_node_t get_node_type(void)
|
||||
{
|
||||
paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
|
||||
paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
|
||||
paramdef_t GNBParams[] = GNBPARAMS_DESC;
|
||||
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
|
||||
paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC;
|
||||
paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0};
|
||||
|
||||
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
|
||||
|
||||
if (GNBParamList.numelt == 0) // We have no valid configuration, let's return a default
|
||||
return ngran_gNB;
|
||||
|
||||
config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);
|
||||
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
|
||||
|
||||
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
|
||||
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
|
||||
config_getlist( &GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params)/sizeof(paramdef_t), aprefix);
|
||||
if ( MacRLC_ParamList.numelt > 0) {
|
||||
RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt;
|
||||
for (int j = 0; j < RC.nb_nr_macrlc_inst; j++) {
|
||||
@@ -2271,9 +2220,16 @@ static ngran_node_t get_node_type(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0)
|
||||
return ngran_gNB_CU;
|
||||
else if (macrlc_has_f1 == 0)
|
||||
if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) {
|
||||
if ( GNBE1ParamList.paramarray == NULL || GNBE1ParamList.numelt == 0 )
|
||||
return ngran_gNB_CU;
|
||||
else if (strcmp(*(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CU_TYPE_IDX].strptr), "cp") == 0)
|
||||
return ngran_gNB_CUCP;
|
||||
else if (strcmp(*(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CU_TYPE_IDX].strptr), "up") == 0)
|
||||
return ngran_gNB_CUUP;
|
||||
else
|
||||
return ngran_gNB_CU;
|
||||
} else if (macrlc_has_f1 == 0)
|
||||
return ngran_gNB;
|
||||
else
|
||||
return ngran_gNB_DU;
|
||||
@@ -2309,9 +2265,7 @@ void nr_read_config_and_init(void) {
|
||||
RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
|
||||
}
|
||||
|
||||
if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
if (NODE_IS_CU(RC.nrrrc[0]->node_type) && RC.nrrrc[0]->node_type != ngran_gNB_CUCP) {
|
||||
pdcp_layer_init();
|
||||
// nr_DRB_preconfiguration(0x1234);
|
||||
rrc_init_nr_global_param();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "s1ap_messages_types.h"
|
||||
#include "ngap_messages_types.h"
|
||||
#include "f1ap_messages_types.h"
|
||||
#include "e1ap_messages_types.h"
|
||||
|
||||
#include "rrc_messages_types.h"
|
||||
#include "intertask_interface.h"
|
||||
@@ -94,7 +95,6 @@ extern void NRRCconfig_RU(void);
|
||||
extern void RCconfig_nr_prs(void);
|
||||
extern void RCconfig_NR_L1(void);
|
||||
extern void RCconfig_nr_macrlc(void);
|
||||
extern int RCconfig_nr_gtpu(void );
|
||||
extern void NRRCConfig(void);
|
||||
|
||||
//void enb_config_display(void);
|
||||
@@ -107,6 +107,8 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i);
|
||||
int gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp);
|
||||
int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update);
|
||||
void nr_read_config_and_init(void);
|
||||
MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process);
|
||||
ngran_node_t get_node_type(void);
|
||||
|
||||
#endif /* GNB_CONFIG_H_ */
|
||||
/** @} */
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define __GNB_APP_GNB_PARAMDEF__H__
|
||||
|
||||
#include "common/config/config_paramdesc.h"
|
||||
#include "common/ngran_types.h"
|
||||
#include "RRC_nr_paramsvalues.h"
|
||||
|
||||
|
||||
@@ -369,6 +370,27 @@ typedef enum {
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* E1 configuration section */
|
||||
#define GNB_CONFIG_STRING_E1_PARAMETERS "E1_INTERFACE"
|
||||
|
||||
#define GNB_CONFIG_E1_CU_TYPE_IDX 0
|
||||
#define GNB_CONFIG_E1_IPV4_ADDRESS_CUCP 1
|
||||
#define GNB_CONFIG_E1_IPV4_ADDRESS_CUUP 2
|
||||
#define GNB_CONFIG_E1_CN_SUPPORT 3
|
||||
|
||||
#define GNB_CONFIG_STRING_E1_CU_TYPE "type"
|
||||
#define GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUCP "ipv4_cucp"
|
||||
#define GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUUP "ipv4_cuup"
|
||||
#define GNB_CONFIG_STRING_E1_CN_SUPPORT "cn_support"
|
||||
|
||||
// clang-format off
|
||||
#define GNBE1PARAMS_DESC { \
|
||||
{GNB_CONFIG_STRING_E1_CU_TYPE, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUCP, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUUP, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_E1_CN_SUPPORT, NULL, 0, uptr :NULL, defintval:1L, TYPE_UINT, 0} \
|
||||
}
|
||||
// clang-format on
|
||||
/* L1 configuration section names */
|
||||
#define CONFIG_STRING_L1_LIST "L1s"
|
||||
#define CONFIG_STRING_L1_CONFIG "l1_config"
|
||||
|
||||
@@ -664,8 +664,6 @@ int remove_ue_list(UE_list_t *listP, int UE_id);
|
||||
void dump_ue_list(UE_list_t *listP);
|
||||
void init_ue_list(UE_list_t *listP);
|
||||
int UE_num_active_CC(UE_info_t *listP, int ue_idP);
|
||||
int UE_PCCID(module_id_t mod_idP, int ue_idP);
|
||||
rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP);
|
||||
|
||||
uint8_t find_rb_table_index(uint8_t average_rbs);
|
||||
|
||||
|
||||
@@ -249,14 +249,11 @@ void mac_top_init_gNB(ngran_node_t node_type)
|
||||
AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n");
|
||||
|
||||
// These should be out of here later
|
||||
pdcp_layer_init();
|
||||
if (get_softmodem_params()->usim_test == 0 ) pdcp_layer_init();
|
||||
|
||||
if(IS_SOFTMODEM_NOS1 && get_softmodem_params()->phy_test)
|
||||
nr_DRB_preconfiguration(0x1234);
|
||||
|
||||
rrc_init_nr_global_param();
|
||||
|
||||
|
||||
} else {
|
||||
RC.nrmac = NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include "nr_pdcp_e1_api.h"
|
||||
|
||||
void e1_add_drb(int is_gnb,
|
||||
uint64_t ue_id,
|
||||
struct NR_DRB_ToAddMod *s,
|
||||
int ciphering_algorithm,
|
||||
int integrity_algorithm,
|
||||
unsigned char *ciphering_key,
|
||||
unsigned char *integrity_key)
|
||||
{
|
||||
add_drb_am(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm,
|
||||
ciphering_key, integrity_key);
|
||||
LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id);
|
||||
}
|
||||
|
||||
void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag,
|
||||
uint64_t ue_id,
|
||||
NR_DRB_ToAddModList_t *const drb2add_list,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint) {
|
||||
|
||||
if (drb2add_list != NULL) {
|
||||
for (int i = 0; i < drb2add_list->list.count; i++) {
|
||||
e1_add_drb(enb_flag, ue_id, drb2add_list->list.array[i],
|
||||
security_modeP & 0x0f, (security_modeP >> 4) & 0x0f,
|
||||
kUPenc, kUPint);
|
||||
}
|
||||
} else
|
||||
LOG_W(PDCP, "%s with void list\n", __FUNCTION__);
|
||||
if (kUPenc)
|
||||
free(kUPenc);
|
||||
if (kUPint)
|
||||
free(kUPint);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include "common/utils/oai_asn1.h"
|
||||
#include "NR_RadioBearerConfig.h"
|
||||
|
||||
#include "pdcp.h"
|
||||
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
|
||||
|
||||
void e1_add_drb(int is_gnb,
|
||||
uint64_t ue_id,
|
||||
struct NR_DRB_ToAddMod *s,
|
||||
int ciphering_algorithm,
|
||||
int integrity_algorithm,
|
||||
unsigned char *ciphering_key,
|
||||
unsigned char *integrity_key);
|
||||
|
||||
void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag,
|
||||
uint64_t ue_id,
|
||||
NR_DRB_ToAddModList_t *const drb2add_list,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint);
|
||||
|
||||
void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s,
|
||||
int ciphering_algorithm,
|
||||
int integrity_algorithm,
|
||||
unsigned char *ciphering_key,
|
||||
unsigned char *integrity_key);
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
|
||||
#include "nr_pdcp_e1_api.h"
|
||||
#include "gnb_config.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
#define TODO do { \
|
||||
@@ -56,10 +58,11 @@ static int nr_pdcp_current_time_last_subframe;
|
||||
hash_table_t *pdcp_coll_p;
|
||||
static uint64_t pdcp_optmask;
|
||||
|
||||
ngran_node_t node_type = ngran_gNB;
|
||||
uint8_t first_dcch = 0;
|
||||
uint8_t proto_agent_flag = 0;
|
||||
|
||||
static ngran_node_t node_type;
|
||||
|
||||
/****************************************************************************/
|
||||
/* rlc_data_req queue - begin */
|
||||
/****************************************************************************/
|
||||
@@ -524,6 +527,10 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_node_type() {
|
||||
node_type = get_node_type();
|
||||
}
|
||||
|
||||
void pdcp_layer_init(void)
|
||||
{
|
||||
/* hack: be sure to initialize only once */
|
||||
@@ -539,7 +546,9 @@ void pdcp_layer_init(void)
|
||||
|
||||
nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
|
||||
|
||||
if ((RC.nrrrc == NULL) || (!NODE_IS_CU(RC.nrrrc[0]->node_type))) {
|
||||
set_node_type();
|
||||
|
||||
if ((RC.nrrrc == NULL) || (!NODE_IS_CU(node_type))) {
|
||||
init_nr_rlc_data_req_queue();
|
||||
}
|
||||
|
||||
@@ -667,7 +676,7 @@ rb_found:
|
||||
ctxt.brOption = 0;
|
||||
|
||||
ctxt.rntiMaybeUEid = ue->rntiMaybeUEid;
|
||||
if (RC.nrrrc != NULL && NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
if (NODE_IS_CU(node_type)) {
|
||||
MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
|
||||
GTPV1U_TUNNEL_DATA_REQ,
|
||||
sizeof(gtpv1u_tunnel_data_req_t)
|
||||
@@ -688,7 +697,6 @@ rb_found:
|
||||
extern instance_t CUuniqInstance;
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, CUuniqInstance, message_p);
|
||||
} else {
|
||||
|
||||
memblock = get_free_mem_block(size, __FUNCTION__);
|
||||
memcpy(memblock->data, buf, size);
|
||||
LOG_D(PDCP, "%s(): (drb %d) calling rlc_data_req size %d\n", __func__, rb_id, size);
|
||||
@@ -764,7 +772,7 @@ srb_found:
|
||||
LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, srb_id, size);
|
||||
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
|
||||
//printf("\n");
|
||||
if ((RC.nrrrc == NULL) || (!NODE_IS_CU(RC.nrrrc[0]->node_type))) {
|
||||
if ((RC.nrrrc == NULL) || (!NODE_IS_CU(node_type))) {
|
||||
if (entity->is_gnb) {
|
||||
f1ap_dl_rrc_message_t dl_rrc = {.old_gNB_DU_ue_id = 0xFFFFFF, .rrc_container = (uint8_t *)buf, .rrc_container_length = size, .rnti = ue->rntiMaybeUEid, .srb_id = DCCH};
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||
@@ -1056,35 +1064,30 @@ void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid)
|
||||
drb_ToAddMod->reestablishPDCP = NULL;
|
||||
drb_ToAddMod->recoverPDCP = NULL;
|
||||
drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
|
||||
drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb));
|
||||
drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer));
|
||||
*drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_infinity;
|
||||
drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL));
|
||||
*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
|
||||
drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL));
|
||||
*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
|
||||
drb_ToAddMod->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
drb_ToAddMod->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
|
||||
asn1cCalloc(drb_ToAddMod->pdcp_Config->drb, drb);
|
||||
asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity);
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits);
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits);
|
||||
drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
drb->headerCompression.choice.notUsed = 0;
|
||||
|
||||
drb_ToAddMod->pdcp_Config->drb->integrityProtection=NULL;
|
||||
drb_ToAddMod->pdcp_Config->drb->statusReportRequired=NULL;
|
||||
drb_ToAddMod->pdcp_Config->drb->outOfOrderDelivery=NULL;
|
||||
drb->integrityProtection = NULL;
|
||||
drb->statusReportRequired = NULL;
|
||||
drb->outOfOrderDelivery = NULL;
|
||||
drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL;
|
||||
|
||||
drb_ToAddMod->pdcp_Config->t_Reordering = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->t_Reordering));
|
||||
*drb_ToAddMod->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
|
||||
asn1cCallocOne(drb_ToAddMod->pdcp_Config->t_Reordering, NR_PDCP_Config__t_Reordering_ms0);
|
||||
drb_ToAddMod->pdcp_Config->ext1 = NULL;
|
||||
|
||||
asn1cSeqAdd(&rbconfig->drb_ToAddModList->list,drb_ToAddMod);
|
||||
|
||||
rbconfig->drb_ToReleaseList = NULL;
|
||||
|
||||
rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig));
|
||||
rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig));
|
||||
rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
|
||||
rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL;
|
||||
rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
|
||||
*rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
|
||||
asn1cCalloc(rbconfig->securityConfig, secConf);
|
||||
asn1cCalloc(secConf->securityAlgorithmConfig, secConfAlgo);
|
||||
secConfAlgo->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
|
||||
secConfAlgo->integrityProtAlgorithm = NULL;
|
||||
asn1cCallocOne(secConf->keyToUse, NR_SecurityConfig__keyToUse_master);
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
|
||||
@@ -1108,11 +1111,7 @@ void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid)
|
||||
|
||||
nr_pdcp_add_drbs(ctxt.enb_flag, ctxt.rntiMaybeUEid, rbconfig->drb_ToAddModList, 0, NULL, NULL, Rlc_Bearer_ToAdd_list);
|
||||
|
||||
nr_rrc_rlc_config_asn1_req (&ctxt,
|
||||
(NR_SRB_ToAddModList_t *) NULL,
|
||||
rbconfig->drb_ToAddModList,
|
||||
rbconfig->drb_ToReleaseList,
|
||||
Rlc_Bearer_ToAdd_list);
|
||||
nr_rrc_rlc_config_asn1_req(&ctxt, (NR_SRB_ToAddModList_t *)NULL, rbconfig->drb_ToAddModList, rbconfig->drb_ToReleaseList, Rlc_Bearer_ToAdd_list);
|
||||
|
||||
LOG_D(PDCP, "%s:%d: done RRC PDCP/RLC ASN1 request for UE ID/RNTI %ld\n", __FUNCTION__, __LINE__, ctxt.rntiMaybeUEid);
|
||||
}
|
||||
|
||||
@@ -985,6 +985,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity){
|
||||
if(srb2add_listP->list.array[i]->srb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.srb_Identity){
|
||||
add_rlc_srb(rnti, srb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]);
|
||||
LOG_D(RLC, "Add srb %ld\n", srb2add_listP->list.array[i]->srb_Identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ typedef void nr_rlc_ue_manager_t;
|
||||
|
||||
typedef struct nr_rlc_ue_t {
|
||||
int rnti;
|
||||
ue_id_t ue_id;
|
||||
nr_rlc_entity_t *srb0;
|
||||
nr_rlc_entity_t *srb[3];
|
||||
nr_rlc_entity_t *drb[MAX_DRBS_PER_UE];
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
|
||||
# include "intertask_interface.h"
|
||||
# include "s1ap_eNB.h"
|
||||
#include "sctp_eNB_task.h"
|
||||
# include "sctp_eNB_task.h"
|
||||
# include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
|
||||
# include "x2ap_eNB.h"
|
||||
# include "x2ap_messages_types.h"
|
||||
|
||||
@@ -5629,6 +5629,7 @@ rrc_eNB_generate_RRCConnectionSetup(
|
||||
case ngran_eNB_CU :
|
||||
case ngran_ng_eNB_CU :
|
||||
case ngran_gNB_CU :
|
||||
case ngran_gNB_CUCP :
|
||||
// create an ITTI message
|
||||
/* TODO: F1 IDs ar missing in RRC */
|
||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, F1AP_DL_RRC_MESSAGE);
|
||||
|
||||
@@ -295,11 +295,6 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) {
|
||||
24);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
if (enc_rval.encoded==-1) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
@@ -638,11 +633,6 @@ uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
100);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
if (enc_rval.encoded==-1) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
@@ -690,11 +680,8 @@ int do_RRCReject(uint8_t Mod_id,
|
||||
buffer,
|
||||
100);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
LOG_D(NR_RRC,"RRCReject Encoded %zd bits (%zd bytes)\n",
|
||||
enc_rval.encoded,(enc_rval.encoded+7)/8);
|
||||
@@ -1297,13 +1284,11 @@ int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
(void *)&dl_ccch_msg,
|
||||
buffer,
|
||||
1000);
|
||||
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
LOG_D(NR_RRC,"RRCSetup Encoded %zd bits (%zd bytes)\n",
|
||||
enc_rval.encoded,(enc_rval.encoded+7)/8);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
@@ -1346,19 +1331,11 @@ uint8_t do_NR_SecurityModeCommand(
|
||||
buffer,
|
||||
100);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
AssertFatal(enc_rval.encoded >0 , "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
LOG_D(NR_RRC, "[gNB %d] securityModeCommand for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8);
|
||||
|
||||
if (enc_rval.encoded==-1) {
|
||||
LOG_E(NR_RRC, "[gNB %d] ASN1 : securityModeCommand encoding failed for UE %lx\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// rrc_ue_process_ueCapabilityEnquiry(0,1000,&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry,0);
|
||||
// exit(-1);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
@@ -1411,6 +1388,9 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
(void *)sa_band_filter,
|
||||
req_freq_buf,
|
||||
1024);
|
||||
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_UE_CapabilityRequestFilterNR, (void *)sa_band_filter);
|
||||
@@ -1435,19 +1415,11 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
buffer,
|
||||
100);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
|
||||
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
LOG_D(NR_RRC, "[gNB %d] NR UECapabilityRequest for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8);
|
||||
|
||||
if (enc_rval.encoded==-1) {
|
||||
LOG_E(NR_RRC, "[gNB %d] ASN1 : NR UECapabilityRequest encoding failed for UE %lx\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
@@ -1480,11 +1452,8 @@ uint8_t do_NR_RRCRelease(uint8_t *buffer,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
buffer_size);
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
@@ -1508,19 +1477,18 @@ int16_t do_RRCReconfiguration(
|
||||
NR_CellGroupConfig_t *cellGroupConfig)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg;
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg={0};
|
||||
asn_enc_rval_t enc_rval;
|
||||
NR_RRCReconfiguration_IEs_t *ie;
|
||||
unsigned char masterCellGroup_buf[1000];
|
||||
|
||||
memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
|
||||
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
|
||||
dl_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1));
|
||||
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
|
||||
asn1cCalloc(dl_dcch_msg.message.choice.c1, c1);// = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1));
|
||||
c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration = calloc(1, sizeof(NR_RRCReconfiguration_t));
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier = Transaction_id;
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
|
||||
asn1cCalloc(c1->choice.rrcReconfiguration, rrcReconf); // = calloc(1, sizeof(NR_RRCReconfiguration_t));
|
||||
rrcReconf->rrc_TransactionIdentifier = Transaction_id;
|
||||
rrcReconf->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
|
||||
|
||||
/******************** Radio Bearer Config ********************/
|
||||
/* Configure Security */
|
||||
@@ -1532,7 +1500,8 @@ int16_t do_RRCReconfiguration(
|
||||
// *security_config->keyToUse = NR_SecurityConfig__keyToUse_master;
|
||||
|
||||
ie = calloc(1, sizeof(NR_RRCReconfiguration_IEs_t));
|
||||
if (SRB_configList || DRB_configList) {
|
||||
if ((SRB_configList && SRB_configList->list.size) ||
|
||||
(DRB_configList && DRB_configList->list.size)) {
|
||||
ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t));
|
||||
ie->radioBearerConfig->srb_ToAddModList = SRB_configList;
|
||||
ie->radioBearerConfig->drb_ToAddModList = DRB_configList;
|
||||
@@ -1561,42 +1530,42 @@ int16_t do_RRCReconfiguration(
|
||||
configuration);
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
|
||||
NULL,
|
||||
(void *)cellGroupConfig,
|
||||
masterCellGroup_buf,
|
||||
1000);
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_E(NR_RRC, "ASN1 message CellGroupConfig encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
NULL,
|
||||
(void *)cellGroupConfig,
|
||||
masterCellGroup_buf,
|
||||
1000);
|
||||
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||
}
|
||||
ie->nonCriticalExtension->masterCellGroup = calloc(1,sizeof(OCTET_STRING_t));
|
||||
|
||||
|
||||
ie->nonCriticalExtension->masterCellGroup->buf = masterCellGroup_buf;
|
||||
ie->nonCriticalExtension->masterCellGroup->size = (enc_rval.encoded+7)/8;
|
||||
}
|
||||
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
|
||||
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
}
|
||||
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
buffer_size);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
buffer_size);
|
||||
|
||||
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
LOG_D(NR_RRC,"[gNB %d] RRCReconfiguration for UE %lx Encoded %zd bits (%zd bytes)\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->rntiMaybeUEid,
|
||||
enc_rval.encoded,
|
||||
(enc_rval.encoded+7)/8);
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
@@ -1731,9 +1700,9 @@ uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size,
|
||||
NR_UL_DCCH_Message_t ul_dcch_msg;
|
||||
NR_RRCSetupComplete_t *RrcSetupComplete;
|
||||
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
|
||||
|
||||
|
||||
uint8_t buf[6];
|
||||
|
||||
|
||||
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
|
||||
ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1));
|
||||
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete;
|
||||
@@ -1746,7 +1715,7 @@ uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size,
|
||||
// sizeof(*RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension));
|
||||
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->selectedPLMN_Identity = sel_plmn_id;
|
||||
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->registeredAMF = NULL;
|
||||
|
||||
|
||||
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value));
|
||||
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI;
|
||||
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size = 6;
|
||||
@@ -1757,23 +1726,23 @@ uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size,
|
||||
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[3] = 0x78;
|
||||
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[4] = 0x9A;
|
||||
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[5] = 0xBC;
|
||||
|
||||
memset(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t));
|
||||
OCTET_STRING_fromBuf(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,dedicatedInfoNAS,dedicatedInfoNASLength);
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
|
||||
}
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
|
||||
NULL,
|
||||
(void *)&ul_dcch_msg,
|
||||
buffer,
|
||||
buffer_size);
|
||||
AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name,enc_rval.encoded);
|
||||
LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
|
||||
memset(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t));
|
||||
OCTET_STRING_fromBuf(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,dedicatedInfoNAS,dedicatedInfoNASLength);
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
|
||||
}
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
|
||||
NULL,
|
||||
(void *)&ul_dcch_msg,
|
||||
buffer,
|
||||
buffer_size);
|
||||
AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name,enc_rval.encoded);
|
||||
LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -1993,11 +1962,8 @@ NR_SRB_ToAddModList_t **SRB_configList
|
||||
buffer,
|
||||
100);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
LOG_D(NR_RRC,"RRCReestablishment Encoded %u bits (%u bytes)\n",
|
||||
(uint32_t)enc_rval.encoded, (uint32_t)(enc_rval.encoded+7)/8);
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* 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:
|
||||
* conmnc_digit_lengtht@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "cucp_cuup_if.h"
|
||||
#include "platform_types.h"
|
||||
#include "nr_rrc_defs.h"
|
||||
|
||||
#include "softmodem-common.h"
|
||||
#include "nr_rrc_proto.h"
|
||||
#include "nr_rrc_extern.h"
|
||||
#include "openair2/COMMON/e1ap_messages_types.h"
|
||||
#include "UTIL/OSA/osa_defs.h"
|
||||
#include "nr_pdcp/nr_pdcp_entity.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h"
|
||||
#include <openair2/RRC/NR/rrc_gNB_UE_context.h>
|
||||
#include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
#include "rrc_gNB_GTPV1U.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "openair2/F1AP/f1ap_common.h"
|
||||
#include "openair2/E1AP/e1ap_common.h"
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
void fill_e1ap_bearer_setup_resp(e1ap_bearer_setup_resp_t *resp,
|
||||
e1ap_bearer_setup_req_t *const req,
|
||||
instance_t gtpInst,
|
||||
ue_id_t ue_id,
|
||||
int remote_port,
|
||||
in_addr_t my_addr) {
|
||||
|
||||
resp->numPDUSessions = req->numPDUSessions;
|
||||
transport_layer_addr_t dummy_address = {0};
|
||||
dummy_address.length = 32; // IPv4
|
||||
for (int i=0; i < req->numPDUSessions; i++) {
|
||||
resp->pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup;
|
||||
for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) {
|
||||
DRB_nGRAN_to_setup_t *drb2Setup = req->pduSession[i].DRBnGRanList + j;
|
||||
DRB_nGRAN_setup_t *drbSetup = resp->pduSession[i].DRBnGRanList + j;
|
||||
|
||||
drbSetup->numUpParam = 1;
|
||||
drbSetup->UpParamList[0].tlAddress = my_addr;
|
||||
drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst,
|
||||
(ue_id & 0xFFFF),
|
||||
drb2Setup->id,
|
||||
drb2Setup->id,
|
||||
0xFFFF, // We will set the right value from DU answer
|
||||
-1, // no qfi
|
||||
dummy_address, // We will set the right value from DU answer
|
||||
remote_port,
|
||||
cu_f1u_data_req,
|
||||
NULL);
|
||||
drbSetup->id = drb2Setup->id;
|
||||
|
||||
drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup;
|
||||
for (int k=0; k < drbSetup->numQosFlowSetup; k++) {
|
||||
drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CU_update_UP_DL_tunnel(e1ap_bearer_setup_req_t *const req, instance_t instance, ue_id_t ue_id) {
|
||||
for (int i=0; i < req->numPDUSessionsMod; i++) {
|
||||
for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) {
|
||||
DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j;
|
||||
|
||||
transport_layer_addr_t newRemoteAddr;
|
||||
newRemoteAddr.length = 32; // IPv4
|
||||
memcpy(newRemoteAddr.buffer,
|
||||
&drb_p->DlUpParamList[0].tlAddress,
|
||||
sizeof(in_addr_t));
|
||||
|
||||
GtpuUpdateTunnelOutgoingAddressAndTeid(instance,
|
||||
(ue_id & 0xFFFF),
|
||||
(ebi_t)drb_p->id,
|
||||
*(in_addr_t*)&newRemoteAddr.buffer,
|
||||
drb_p->DlUpParamList[0].teId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
rrc_gNB_ue_context_t *ue_context_p,
|
||||
e1ap_bearer_setup_req_t *const req,
|
||||
NR_DRB_ToAddModList_t *DRB_configList,
|
||||
NR_SRB_ToAddModList_t *SRB_configList,
|
||||
instance_t instance) {
|
||||
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
|
||||
|
||||
for (int i=0; i < ue_context_p->ue_context.nb_of_pdusessions; i++) {
|
||||
pdu_session_param_t *pdu = ue_context_p->ue_context.pduSession + i;
|
||||
create_tunnel_req.pdusession_id[i] = pdu->param.pdusession_id;
|
||||
create_tunnel_req.incoming_rb_id[i] = i + 1;
|
||||
create_tunnel_req.outgoing_qfi[i] = req->pduSession[i].DRBnGRanList[0].qosFlows[0].id;
|
||||
memcpy(&create_tunnel_req.dst_addr[i].buffer,
|
||||
&pdu->param.upf_addr.buffer,
|
||||
sizeof(uint8_t)*20);
|
||||
create_tunnel_req.dst_addr[i].length = pdu->param.upf_addr.length;
|
||||
create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid;
|
||||
}
|
||||
create_tunnel_req.num_tunnels = ue_context_p->ue_context.nb_of_pdusessions;
|
||||
create_tunnel_req.ue_id = ue_context_p->ue_context.rnti;
|
||||
|
||||
int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3, &create_tunnel_req, &create_tunnel_resp);
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE rnti %ld\n",
|
||||
create_tunnel_req.ue_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p,
|
||||
&create_tunnel_resp);
|
||||
|
||||
uint8_t *kRRCenc = NULL;
|
||||
uint8_t *kRRCint = NULL;
|
||||
uint8_t *kUPenc = NULL;
|
||||
uint8_t *kUPint = NULL;
|
||||
/* Derive the keys from kgnb */
|
||||
if (DRB_configList != NULL) {
|
||||
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPenc);
|
||||
nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPint);
|
||||
}
|
||||
|
||||
nr_derive_key_rrc_enc(ue_context_p->ue_context.ciphering_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kRRCenc);
|
||||
nr_derive_key_rrc_int(ue_context_p->ue_context.integrity_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kRRCint);
|
||||
/* Refresh SRBs/DRBs */
|
||||
|
||||
LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_p->ue_context.rnti);
|
||||
|
||||
nr_pdcp_add_srbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid,
|
||||
SRB_configList,
|
||||
(ue_context_p->ue_context.integrity_algorithm << 4)
|
||||
| ue_context_p->ue_context.ciphering_algorithm,
|
||||
kRRCenc,
|
||||
kRRCint);
|
||||
|
||||
nr_pdcp_add_drbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid,
|
||||
DRB_configList,
|
||||
(ue_context_p->ue_context.integrity_algorithm << 4)
|
||||
| ue_context_p->ue_context.ciphering_algorithm,
|
||||
kUPenc,
|
||||
kUPint,
|
||||
get_softmodem_params()->sa ? ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, NR_SRB_ToAddModList_t *SRB_configList, uint8_t xid)
|
||||
{
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||
|
||||
SRB_configList2 = &ue->SRB_configList2[xid];
|
||||
if (*SRB_configList2 == NULL) {
|
||||
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
|
||||
NR_SRB_ToAddMod_t *SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
SRB2_config->srb_Identity = 2;
|
||||
asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
|
||||
asn1cSeqAdd(&SRB_configList->list, SRB2_config);
|
||||
}
|
||||
|
||||
return SRB_configList2;
|
||||
}
|
||||
static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) {
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti);
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
|
||||
|
||||
fill_DRB_configList(&ctxt, ue_context_p);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
// Fixme: xid not random, but almost!
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = generateSRB2_confList(&ue_context_p->ue_context, ue_context_p->ue_context.SRB_configList, ue_context_p->ue_context.pduSession[0].xid);
|
||||
// GTP tunnel for UL
|
||||
int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, ue_context_p->ue_context.DRB_configList, *SRB_configList2, rrc->e1_inst);
|
||||
if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n");
|
||||
|
||||
if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) {
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL);
|
||||
} else {
|
||||
e1ap_bearer_setup_resp_t resp; // Used to store teids
|
||||
int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
|
||||
in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
|
||||
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
|
||||
// GTP tunnel for DL
|
||||
fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, ue_context_p->ue_context.rnti, remote_port, my_addr);
|
||||
|
||||
prepare_and_send_ue_context_modification_f1(ue_context_p, &resp);
|
||||
}
|
||||
}
|
||||
|
||||
static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) {
|
||||
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
|
||||
CU_update_UP_DL_tunnel(req, gtpInst, req->rnti);
|
||||
}
|
||||
|
||||
void cucp_cuup_message_transfer_direct_init(gNB_RRC_INST *rrc) {
|
||||
rrc->cucp_cuup.bearer_context_setup = cucp_cuup_bearer_context_setup_direct;
|
||||
rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_mod_direct;
|
||||
}
|
||||
@@ -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:
|
||||
* conmnc_digit_lengtht@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "cucp_cuup_if.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "platform_types.h"
|
||||
#include "nr_rrc_defs.h"
|
||||
|
||||
#include "nr_rrc_proto.h"
|
||||
#include "nr_rrc_extern.h"
|
||||
#include "cucp_cuup_if.h"
|
||||
#include "openair2/COMMON/e1ap_messages_types.h"
|
||||
#include "UTIL/OSA/osa_defs.h"
|
||||
#include <openair2/RRC/NR/rrc_gNB_UE_context.h>
|
||||
#include "common/ran_context.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) {
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti);
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
|
||||
|
||||
fill_DRB_configList(&ctxt, ue_context_p);
|
||||
MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ);
|
||||
e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p);
|
||||
memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t));
|
||||
|
||||
itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p);
|
||||
}
|
||||
|
||||
static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ);
|
||||
e1ap_bearer_setup_req_t *req_msg = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg);
|
||||
memcpy(req_msg, req, sizeof(*req));
|
||||
itti_send_msg_to_task(TASK_CUCP_E1, instance, msg);
|
||||
}
|
||||
|
||||
void cucp_cuup_message_transfer_e1ap_init(gNB_RRC_INST *rrc) {
|
||||
rrc->cucp_cuup.bearer_context_setup = cucp_cuup_bearer_context_setup_e1ap;
|
||||
rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_mod_e1ap;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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:
|
||||
* conmnc_digit_lengtht@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef CUCP_CUUP_IF_H
|
||||
#define CUCP_CUUP_IF_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include "platform_types.h"
|
||||
|
||||
struct e1ap_bearer_setup_req_s;
|
||||
struct e1ap_bearer_setup_resp_s;
|
||||
typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance);
|
||||
|
||||
struct gNB_RRC_INST_s;
|
||||
void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc);
|
||||
void cucp_cuup_message_transfer_e1ap_init(struct gNB_RRC_INST_s *rrc);
|
||||
void fill_e1ap_bearer_setup_resp(struct e1ap_bearer_setup_resp_s *resp,
|
||||
struct e1ap_bearer_setup_req_s *const req,
|
||||
instance_t gtpInst,
|
||||
ue_id_t ue_id,
|
||||
int remote_port,
|
||||
in_addr_t my_addr);
|
||||
void CU_update_UP_DL_tunnel(struct e1ap_bearer_setup_req_s *const req, instance_t instance, ue_id_t ue_id);
|
||||
#endif
|
||||
@@ -49,21 +49,14 @@ extern UE_MAC_INST *UE_mac_inst;
|
||||
extern mui_t rrc_gNB_mui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int rrc_init_nr_global_param(void){
|
||||
|
||||
void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan)
|
||||
{
|
||||
rrc_rlc_register_rrc (rrc_data_ind, NULL); //register with rlc
|
||||
|
||||
DCCH_LCHAN_DESC.transport_block_size = 4;
|
||||
DCCH_LCHAN_DESC.max_transport_blocks = 16;
|
||||
DCCH_LCHAN_DESC.Delay_class = 1;
|
||||
DTCH_DL_LCHAN_DESC.transport_block_size = 52;
|
||||
DTCH_DL_LCHAN_DESC.max_transport_blocks = 20;
|
||||
DTCH_DL_LCHAN_DESC.Delay_class = 1;
|
||||
DTCH_UL_LCHAN_DESC.transport_block_size = 52;
|
||||
DTCH_UL_LCHAN_DESC.max_transport_blocks = 20;
|
||||
DTCH_UL_LCHAN_DESC.Delay_class = 1;
|
||||
|
||||
return 0;
|
||||
chan->transport_block_size = 4;
|
||||
chan->max_transport_blocks = 16;
|
||||
chan->Delay_class = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "common/platform_constants.h"
|
||||
#include "COMMON/platform_types.h"
|
||||
#include "mac_rrc_dl.h"
|
||||
#include "cucp_cuup_if.h"
|
||||
|
||||
//#include "COMMON/mac_rrc_primitives.h"
|
||||
|
||||
@@ -416,7 +417,7 @@ typedef struct rrc_gNB_ue_context_s {
|
||||
// another key for protocol layers but should not be used as a key for RB tree
|
||||
uid_t local_uid;
|
||||
|
||||
/* UE id for initial connection to S1AP */
|
||||
/* UE id for initial connection to NGAP */
|
||||
struct gNB_RRC_UE_s ue_context;
|
||||
} rrc_gNB_ue_context_t;
|
||||
|
||||
@@ -476,6 +477,11 @@ typedef struct nr_mac_rrc_dl_if_s {
|
||||
dl_rrc_message_transfer_func_t dl_rrc_message_transfer;
|
||||
} nr_mac_rrc_dl_if_t;
|
||||
|
||||
typedef struct cucp_cuup_if_s {
|
||||
cucp_cuup_bearer_context_setup_func_t bearer_context_setup;
|
||||
cucp_cuup_bearer_context_setup_func_t bearer_context_mod;
|
||||
} cucp_cuup_if_t;
|
||||
|
||||
//---NR---(completely change)---------------------
|
||||
typedef struct gNB_RRC_INST_s {
|
||||
|
||||
@@ -499,6 +505,9 @@ typedef struct gNB_RRC_INST_s {
|
||||
// RRC configuration
|
||||
gNB_RrcConfigurationReq configuration;
|
||||
|
||||
// gNB N3 GTPU instance
|
||||
instance_t e1_inst;
|
||||
|
||||
// other PLMN parameters
|
||||
/// Mobile country code
|
||||
int mcc;
|
||||
@@ -527,6 +536,8 @@ typedef struct gNB_RRC_INST_s {
|
||||
nr_security_configuration_t security;
|
||||
|
||||
nr_mac_rrc_dl_if_t mac_rrc;
|
||||
cucp_cuup_if_t cucp_cuup;
|
||||
|
||||
} gNB_RRC_INST;
|
||||
|
||||
#include "nr_rrc_proto.h" //should be put here otherwise compilation error
|
||||
|
||||
@@ -53,8 +53,7 @@ extern void* bigphys_malloc(int);
|
||||
|
||||
//uint8_t RACH_TIME_ALLOC;
|
||||
extern uint16_t RACH_FREQ_ALLOC;
|
||||
//uint8_t NB_RACH;
|
||||
extern LCHAN_DESC BCCH_LCHAN_DESC,CCCH_LCHAN_DESC,DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
|
||||
// uint8_t NB_RACH;
|
||||
extern MAC_MEAS_T BCCH_MEAS_TRIGGER,CCCH_MEAS_TRIGGER,DCCH_MEAS_TRIGGER,DTCH_MEAS_TRIGGER;
|
||||
extern MAC_AVG_T BCCH_MEAS_AVG,CCCH_MEAS_AVG,DCCH_MEAS_AVG, DTCH_MEAS_AVG;
|
||||
|
||||
@@ -63,7 +62,6 @@ extern UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
|
||||
extern pthread_mutex_t ue_pf_po_mutex;
|
||||
|
||||
extern uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2];
|
||||
char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -44,12 +44,7 @@
|
||||
#include "NR_SecurityConfig.h"
|
||||
|
||||
#define NR_MAX_SUPPORTED_DL_LAYERS 2
|
||||
|
||||
int rrc_init_nr_global_param(void);
|
||||
|
||||
void rrc_config_nr_buffer(NR_SRB_INFO* Srb_info,
|
||||
uint8_t Lchan_type,
|
||||
uint8_t Role);
|
||||
void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan);
|
||||
|
||||
uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
|
||||
const int CC_id,
|
||||
@@ -104,18 +99,6 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
|
||||
NR_RRCReconfiguration_t *reconfig,
|
||||
NR_RadioBearerConfig_t *rbconfig);
|
||||
|
||||
void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP );
|
||||
|
||||
void
|
||||
rrc_gNB_generate_RRCSetup(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const uint8_t *masterCellGroup,
|
||||
int masterCellGroup_len,
|
||||
NR_ServingCellConfigCommon_t *scc);
|
||||
|
||||
int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m);
|
||||
|
||||
void
|
||||
@@ -124,10 +107,7 @@ rrc_gNB_generate_SecurityModeCommand(
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
);
|
||||
|
||||
uint8_t
|
||||
rrc_gNB_get_next_transaction_identifier(
|
||||
module_id_t gnb_mod_idP
|
||||
);
|
||||
unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP);
|
||||
|
||||
void
|
||||
rrc_gNB_generate_UECapabilityEnquiry(
|
||||
@@ -209,6 +189,23 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt
|
||||
const NR_DRB_ToReleaseList_t * const drb2release_listP,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
|
||||
|
||||
void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req,
|
||||
instance_t instance);
|
||||
|
||||
void bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *req,
|
||||
instance_t instance);
|
||||
|
||||
void ue_cxt_mod_send_e1ap(MessageDef *msg,
|
||||
instance_t instance);
|
||||
|
||||
void ue_cxt_mod_direct(MessageDef *msg,
|
||||
instance_t instance);
|
||||
|
||||
void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP);
|
||||
|
||||
void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p,
|
||||
e1ap_bearer_setup_resp_t *e1ap_resp);
|
||||
void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddModList_t *const srb2add_list, const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kUPint);
|
||||
|
||||
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
|
||||
|
||||
+267
-286
@@ -99,6 +99,10 @@
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include <openair2/RRC/NR/nr_rrc_proto.h>
|
||||
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h"
|
||||
#include "openair2/F1AP/f1ap_common.h"
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
|
||||
#include "cucp_cuup_if.h"
|
||||
|
||||
#include "BIT_STRING.h"
|
||||
#include "assertions.h"
|
||||
@@ -132,10 +136,12 @@ bool DURecvCb(protocol_ctxt_t *ctxt_pP,
|
||||
return true;
|
||||
}
|
||||
|
||||
void openair_nr_rrc_on(const protocol_ctxt_t *const ctxt_pP) {
|
||||
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" gNB:OPENAIR NR RRC IN....\n",PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP));
|
||||
rrc_config_nr_buffer (&RC.nrrrc[ctxt_pP->module_id]->carrier.SI, BCCH, 1);
|
||||
RC.nrrrc[ctxt_pP->module_id]->carrier.SI.Active = 1;
|
||||
static void openair_nr_rrc_on(gNB_RRC_INST *rrc)
|
||||
{
|
||||
NR_SRB_INFO *si = &rrc->carrier.SI;
|
||||
si->Rx_buffer.payload_size = 0;
|
||||
si->Tx_buffer.payload_size = 0;
|
||||
si->Active = 1;
|
||||
}
|
||||
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
@@ -193,27 +199,34 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
|
||||
}
|
||||
}
|
||||
|
||||
static void rrc_gNB_mac_rrc_init(gNB_RRC_INST *rrc)
|
||||
static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc)
|
||||
{
|
||||
switch (rrc->node_type) {
|
||||
case ngran_gNB_CUCP:
|
||||
mac_rrc_dl_f1ap_init(&rrc->mac_rrc);
|
||||
cucp_cuup_message_transfer_e1ap_init(rrc);
|
||||
break;
|
||||
case ngran_gNB_CU:
|
||||
mac_rrc_dl_f1ap_init(&rrc->mac_rrc);
|
||||
cucp_cuup_message_transfer_direct_init(rrc);
|
||||
break;
|
||||
case ngran_gNB:
|
||||
mac_rrc_dl_direct_init(&rrc->mac_rrc);
|
||||
cucp_cuup_message_transfer_direct_init(rrc);
|
||||
break;
|
||||
case ngran_gNB_DU:
|
||||
/* silently drop this, as we currently still need the RRC at the DU. As
|
||||
* soon as this is not the case anymore, we can add the AssertFatal() */
|
||||
//AssertFatal(1==0,"nothing to do for DU\n");
|
||||
break;
|
||||
case ngran_gNB:
|
||||
mac_rrc_dl_direct_init(&rrc->mac_rrc);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration) {
|
||||
static void openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration)
|
||||
{
|
||||
protocol_ctxt_t ctxt = { 0 };
|
||||
gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP];
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gnb_mod_idP, GNB_FLAG_YES, NOT_A_RNTI, 0, 0,gnb_mod_idP);
|
||||
@@ -225,7 +238,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
|
||||
AssertFatal(configuration!=NULL,"configuration input is null\n");
|
||||
rrc->module_id = gnb_mod_idP;
|
||||
rrc->Nb_ue = 0;
|
||||
rrc_gNB_mac_rrc_init(rrc);
|
||||
rrc_gNB_CU_DU_init(rrc);
|
||||
uid_linear_allocator_init(&rrc->uid_allocator);
|
||||
RB_INIT(&rrc->rrc_ue_head);
|
||||
rrc->initial_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL);
|
||||
@@ -241,13 +254,12 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
|
||||
rrc->cell_info_configured = 0;
|
||||
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Checking release \n",PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt));
|
||||
init_NR_SI(rrc, configuration);
|
||||
rrc_init_nr_global_param();
|
||||
openair_nr_rrc_on(&ctxt);
|
||||
return 0;
|
||||
}//END openair_rrc_gNB_configuration
|
||||
openair_nr_rrc_on(rrc);
|
||||
return;
|
||||
} // END openair_rrc_gNB_configuration
|
||||
|
||||
|
||||
void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_addition_req_t *m) {
|
||||
static void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_addition_req_t *m)
|
||||
{
|
||||
struct NR_CG_ConfigInfo *cg_configinfo = NULL;
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||
&asn_DEF_NR_CG_ConfigInfo,
|
||||
@@ -272,24 +284,20 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x
|
||||
dec_rval.consumed, (dec_rval.consumed +7/8));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
uint8_t
|
||||
rrc_gNB_get_next_transaction_identifier(
|
||||
module_id_t gnb_mod_idP
|
||||
)
|
||||
unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
static uint8_t nr_rrc_transaction_identifier[NUMBER_OF_gNB_MAX];
|
||||
nr_rrc_transaction_identifier[gnb_mod_idP] = (nr_rrc_transaction_identifier[gnb_mod_idP] + 1) % NR_RRC_TRANSACTION_IDENTIFIER_NUMBER;
|
||||
LOG_T(NR_RRC, "generated xid is %d\n", nr_rrc_transaction_identifier[gnb_mod_idP]);
|
||||
return nr_rrc_transaction_identifier[gnb_mod_idP];
|
||||
static unsigned int transaction_id[NUMBER_OF_gNB_MAX] = {0};
|
||||
// used also in NGAP thread, so need thread safe operation
|
||||
unsigned int tmp = __atomic_add_fetch(&transaction_id[gnb_mod_idP], 1, __ATOMIC_SEQ_CST);
|
||||
tmp %= NR_RRC_TRANSACTION_IDENTIFIER_NUMBER;
|
||||
LOG_T(NR_RRC, "generated xid is %d\n", tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP ) {
|
||||
|
||||
static void apply_macrlc_config(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP)
|
||||
{
|
||||
NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL;
|
||||
rrc_mac_config_req_gNB(rrc->module_id,
|
||||
rrc->configuration.pdsch_AntennaPorts,
|
||||
@@ -308,27 +316,18 @@ void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
ue_context_pP->ue_context.DRB_configList,
|
||||
NULL,
|
||||
get_softmodem_params()->sa ? cgc->rlc_BearerToAddModList : NULL);
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_generate_RRCSetup(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const uint8_t *masterCellGroup,
|
||||
int masterCellGroup_len,
|
||||
NR_ServingCellConfigCommon_t *scc)
|
||||
static void rrc_gNB_generate_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const uint8_t *masterCellGroup,
|
||||
int masterCellGroup_len,
|
||||
NR_ServingCellConfigCommon_t *scc)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup for RNTI %04lx\n", ctxt_pP->rntiMaybeUEid);
|
||||
|
||||
// T(T_GNB_RRC_SETUP,
|
||||
// T_INT(ctxt_pP->module_id),
|
||||
// T_INT(ctxt_pP->frame),
|
||||
// T_INT(ctxt_pP->subframe),
|
||||
// T_INT(ctxt_pP->rnti));
|
||||
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
unsigned char buf[1024];
|
||||
@@ -368,11 +367,7 @@ rrc_gNB_generate_RRCSetup(
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const int CC_id
|
||||
)
|
||||
static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(const protocol_ctxt_t *const ctxt_pP, const int CC_id)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n");
|
||||
@@ -440,10 +435,7 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
|
||||
rrc_instance_p->mac_rrc.dl_rrc_message_transfer(ctxt_pP->module_id, &dl_rrc);
|
||||
}
|
||||
|
||||
void
|
||||
rrc_gNB_generate_RRCReject(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP)
|
||||
static void rrc_gNB_generate_RRCReject(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
LOG_I(NR_RRC, "rrc_gNB_generate_RRCReject \n");
|
||||
@@ -482,12 +474,7 @@ rrc_gNB_generate_RRCReject(
|
||||
/*
|
||||
* Process the rrc setup complete message from UE (SRB1 Active)
|
||||
*/
|
||||
void
|
||||
rrc_gNB_process_RRCSetupComplete(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
NR_RRCSetupComplete_IEs_t *rrcSetupComplete
|
||||
)
|
||||
static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, NR_RRCSetupComplete_IEs_t *rrcSetupComplete)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
LOG_A(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing NR_RRCSetupComplete from UE (SRB1 Active)\n",
|
||||
@@ -504,22 +491,9 @@ rrc_gNB_process_RRCSetupComplete(
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP
|
||||
)
|
||||
static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
uint8_t buffer[RRC_BUF_SIZE];
|
||||
int16_t size;
|
||||
/*NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||
NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList;
|
||||
NR_DRB_ToAddModList_t **DRB_configList = NULL;
|
||||
NR_DRB_ToAddModList_t **DRB_configList2 = NULL;
|
||||
NR_SRB_ToAddMod_t *SRB2_config = NULL;
|
||||
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
||||
NR_SDAP_Config_t *sdap_config = NULL;*/
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
|
||||
*dedicatedNAS_MessageList = NULL;
|
||||
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
|
||||
@@ -527,66 +501,6 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
|
||||
/******************** Radio Bearer Config ********************/
|
||||
/* Configure SRB2 */
|
||||
/*SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
|
||||
if (*SRB_configList2) {
|
||||
free(*SRB_configList2);
|
||||
}
|
||||
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
|
||||
memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
|
||||
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
SRB2_config->srb_Identity = 2;
|
||||
asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
|
||||
asn1cSeqAdd(&SRB_configList->list, SRB2_config);*/
|
||||
|
||||
/* Configure DRB */
|
||||
/*DRB_configList = &ue_context_pP->ue_context.DRB_configList;
|
||||
if (*DRB_configList) {
|
||||
free(*DRB_configList);
|
||||
}
|
||||
*DRB_configList = CALLOC(1, sizeof(**DRB_configList));
|
||||
memset(*DRB_configList, 0, sizeof(**DRB_configList));
|
||||
|
||||
DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[xid];
|
||||
if (*DRB_configList2) {
|
||||
free(*DRB_configList2);
|
||||
}
|
||||
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
|
||||
memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
|
||||
|
||||
DRB_config = CALLOC(1, sizeof(*DRB_config));
|
||||
DRB_config->drb_Identity = 1;
|
||||
DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
|
||||
DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||
// TODO sdap_Config
|
||||
sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
|
||||
DRB_config->cnAssociation->choice.sdap_Config = sdap_config;
|
||||
// TODO pdcp_Config
|
||||
DRB_config->reestablishPDCP = NULL;
|
||||
DRB_config->recoverPDCP = NULL;
|
||||
DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config));
|
||||
DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb));
|
||||
DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer));
|
||||
*DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
|
||||
DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL));
|
||||
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
|
||||
DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL));
|
||||
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
|
||||
DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
|
||||
|
||||
DRB_config->pdcp_Config->drb->integrityProtection = NULL;
|
||||
DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
|
||||
DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
|
||||
DRB_config->pdcp_Config->moreThanOneRLC = NULL;
|
||||
|
||||
DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
|
||||
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
|
||||
DRB_config->pdcp_Config->ext1 = NULL;
|
||||
|
||||
asn1cSeqAdd(&(*DRB_configList)->list, DRB_config);
|
||||
asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);*/
|
||||
|
||||
dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
|
||||
|
||||
@@ -594,7 +508,6 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
|
||||
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
|
||||
memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
|
||||
OCTET_STRING_fromBuf(dedicatedNAS_Message,
|
||||
(char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer,
|
||||
ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length);
|
||||
@@ -608,7 +521,6 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
|
||||
if (ue_context_pP->ue_context.nas_pdu_flag == 1) {
|
||||
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
|
||||
memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
|
||||
OCTET_STRING_fromBuf(dedicatedNAS_Message,
|
||||
(char *)ue_context_pP->ue_context.nas_pdu.buffer,
|
||||
ue_context_pP->ue_context.nas_pdu.length);
|
||||
@@ -625,21 +537,23 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
NR_MeasConfig_t *measconfig = get_defaultMeasConfig(&rrc->configuration);
|
||||
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer),
|
||||
xid,
|
||||
NULL, //*SRB_configList2,
|
||||
NULL, //*DRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
measconfig,
|
||||
dedicatedNAS_MessageList,
|
||||
ue_context_pP,
|
||||
&rrc->carrier,
|
||||
&rrc->configuration,
|
||||
NULL,
|
||||
ue_p->masterCellGroup);
|
||||
uint8_t buffer[RRC_BUF_SIZE] = {0};
|
||||
int size = do_RRCReconfiguration(ctxt_pP,
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
xid,
|
||||
NULL, //*SRB_configList2,
|
||||
NULL, //*DRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
measconfig,
|
||||
dedicatedNAS_MessageList,
|
||||
ue_context_pP,
|
||||
&rrc->carrier,
|
||||
&rrc->configuration,
|
||||
NULL,
|
||||
ue_p->masterCellGroup);
|
||||
AssertFatal(size > 0, "cannot encode RRCReconfiguration in %s()\n", __func__);
|
||||
LOG_W(RRC, "do_RRCReconfiguration(): size %d\n", size);
|
||||
|
||||
@@ -647,6 +561,7 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, ue_p->masterCellGroup);
|
||||
}
|
||||
|
||||
// suspicious if it is always malloced before ?
|
||||
free(ue_context_pP->ue_context.nas_pdu.buffer);
|
||||
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n");
|
||||
@@ -666,6 +581,8 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
ue_context_pP->ue_context.rnti);
|
||||
switch (RC.nrrrc[ctxt_pP->module_id]->node_type) {
|
||||
case ngran_gNB_CU:
|
||||
case ngran_gNB_CUCP:
|
||||
case ngran_gNB:
|
||||
nr_rrc_data_req(ctxt_pP,
|
||||
DCCH,
|
||||
rrc_gNB_mui++,
|
||||
@@ -682,28 +599,6 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
AssertFatal(1==0,"nothing to do for DU\n");
|
||||
break;
|
||||
|
||||
case ngran_gNB:
|
||||
{
|
||||
LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
|
||||
ctxt_pP->frame,
|
||||
ctxt_pP->module_id,
|
||||
size,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
rrc_gNB_mui,
|
||||
ctxt_pP->module_id,
|
||||
DCCH);
|
||||
nr_rrc_data_req(ctxt_pP,
|
||||
DCCH,
|
||||
rrc_gNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
// rrc_pdcp_config_asn1_req
|
||||
// rrc_rlc_config_asn1_req
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt_pP->module_id]->node_type);
|
||||
}
|
||||
@@ -735,37 +630,22 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
NR_CellGroupConfig_t *cell_groupConfig_from_DU
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP) {
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
NR_DRB_ToAddModList_t **DRB_configList = NULL;
|
||||
NR_DRB_ToAddModList_t **DRB_configList2 = NULL;
|
||||
NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList;
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
|
||||
*dedicatedNAS_MessageList = NULL;
|
||||
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
|
||||
uint8_t buffer[RRC_BUF_SIZE];
|
||||
uint16_t size;
|
||||
int qos_flow_index = 0;
|
||||
int pdu_sessions_done = 0;
|
||||
int i;
|
||||
uint8_t drb_id_to_setup_start = 0;
|
||||
uint8_t nb_drb_to_setup = rrc->configuration.drbs;
|
||||
long drb_priority[NGAP_MAX_DRBS_PER_UE];
|
||||
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = generateSRB2_confList(ue_p, SRB_configList, xid);
|
||||
|
||||
DRB_configList = &ue_context_pP->ue_context.DRB_configList;
|
||||
if (*DRB_configList) {
|
||||
free(*DRB_configList);
|
||||
@@ -780,8 +660,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
|
||||
memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
|
||||
|
||||
dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
|
||||
|
||||
for (i = 0; i < ue_context_pP->ue_context.setup_pdu_sessions; i++) {
|
||||
if (pdu_sessions_done >= ue_context_pP->ue_context.nb_of_pdusessions) {
|
||||
break;
|
||||
@@ -880,11 +758,42 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
asn1cSeqAdd(&(*DRB_configList)->list, DRB_config);
|
||||
asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
|
||||
}
|
||||
LOG_D(RRC, "DRB Priority %ld\n", drb_priority[drb_id]); // To supress warning for now
|
||||
}
|
||||
}
|
||||
|
||||
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
ue_context_pP->ue_context.pduSession[i].xid = xid;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
NR_CellGroupConfig_t *cell_groupConfig_from_DU
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future)
|
||||
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||
uint8_t buffer[RRC_BUF_SIZE];
|
||||
uint16_t size;
|
||||
int xid = -1;
|
||||
|
||||
int drb_id_to_setup_start = 1;
|
||||
NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList;
|
||||
int nb_drb_to_setup = DRB_configList->list.count;
|
||||
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL;
|
||||
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
|
||||
dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
|
||||
|
||||
for (int i=0; i < nb_drb_to_setup; i++) {
|
||||
NR_DRB_ToAddMod_t *DRB_config = DRB_configList->list.array[i];
|
||||
if (drb_id_to_setup_start == 1) drb_id_to_setup_start = DRB_config->drb_Identity;
|
||||
|
||||
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
|
||||
@@ -899,6 +808,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
// TODO
|
||||
LOG_E(NR_RRC,"no NAS info (pdusession id %d)\n", i);
|
||||
}
|
||||
|
||||
xid = ue_context_pP->ue_context.pduSession[i].xid;
|
||||
}
|
||||
|
||||
/* If list is empty free the list and reset the address */
|
||||
@@ -919,10 +830,14 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
cellGroupConfig = cell_groupConfig_from_DU;
|
||||
}
|
||||
|
||||
AssertFatal(xid > -1, "Invalid xid %d. No PDU sessions setup to configure.\n", xid);
|
||||
NR_SRB_ToAddModList_t *SRB_configList2 = NULL;
|
||||
SRB_configList2 = ue_context_pP->ue_context.SRB_configList2[xid];
|
||||
|
||||
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer),
|
||||
xid,
|
||||
*SRB_configList2,
|
||||
*DRB_configList,
|
||||
SRB_configList2,
|
||||
DRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -936,7 +851,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Reconfiguration\n");
|
||||
|
||||
/* Free all NAS PDUs */
|
||||
for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
|
||||
for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
|
||||
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
/* Free the NAS PDU buffer and invalidate it */
|
||||
free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
|
||||
@@ -1208,19 +1123,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
||||
}
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid,
|
||||
NULL,
|
||||
NULL,
|
||||
*DRB_Release_configList2,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
dedicatedNAS_MessageList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, NULL, NULL, *DRB_Release_configList2, NULL, NULL, NULL, dedicatedNAS_MessageList, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
ue_context_pP->ue_context.pdu_session_release_command_flag = 1;
|
||||
|
||||
@@ -1273,10 +1176,6 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
||||
)
|
||||
{
|
||||
int drb_id;
|
||||
uint8_t *kRRCenc = NULL;
|
||||
uint8_t *kRRCint = NULL;
|
||||
uint8_t *kUPenc = NULL;
|
||||
uint8_t *kUPint = NULL;
|
||||
NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid];
|
||||
NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid];
|
||||
NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
|
||||
@@ -1285,36 +1184,6 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
||||
|
||||
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
|
||||
|
||||
/* Derive the keys from kgnb */
|
||||
if (DRB_configList != NULL) {
|
||||
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&kUPenc);
|
||||
nr_derive_key_up_int(ue_context_pP->ue_context.integrity_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&kUPint);
|
||||
}
|
||||
|
||||
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&kRRCenc);
|
||||
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&kRRCint);
|
||||
/* Refresh SRBs/DRBs */
|
||||
|
||||
LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
|
||||
|
||||
nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, SRB_configList, (ue_context_pP->ue_context.integrity_algorithm << 4) | ue_context_pP->ue_context.ciphering_algorithm, kRRCenc, kRRCint);
|
||||
|
||||
nr_pdcp_add_drbs(ctxt_pP->enb_flag,
|
||||
ctxt_pP->rntiMaybeUEid,
|
||||
DRB_configList,
|
||||
(ue_context_pP->ue_context.integrity_algorithm << 4) | ue_context_pP->ue_context.ciphering_algorithm,
|
||||
kUPenc,
|
||||
kUPint,
|
||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
|
||||
/* Refresh SRBs/DRBs */
|
||||
if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||
LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
|
||||
@@ -1500,13 +1369,7 @@ rrc_gNB_generate_RRCReestablishment(
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const rnti_t reestablish_rnti,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
const uint8_t xid
|
||||
)
|
||||
void rrc_gNB_process_RRCConnectionReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, const rnti_t reestablish_rnti, rrc_gNB_ue_context_t *ue_context_pP, const uint8_t old_xid)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
LOG_I(NR_RRC,
|
||||
@@ -1524,12 +1387,12 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
uint8_t buffer[RRC_BUF_SIZE];
|
||||
uint16_t size;
|
||||
|
||||
uint8_t next_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
int ret = 0;
|
||||
ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED;
|
||||
ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
|
||||
ue_context_pP->ue_context.reestablishment_xid = next_xid;
|
||||
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
|
||||
ue_context_pP->ue_context.reestablishment_xid = new_xid;
|
||||
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[old_xid];
|
||||
|
||||
// get old configuration of SRB2
|
||||
if (*SRB_configList2 != NULL) {
|
||||
@@ -1540,7 +1403,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
|
||||
for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
|
||||
if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) {
|
||||
LOG_D(NR_RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", xid);
|
||||
LOG_D(NR_RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", old_xid);
|
||||
SRB2_config = (*SRB_configList2)->list.array[i];
|
||||
break;
|
||||
}
|
||||
@@ -1550,12 +1413,12 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
// SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
// SRB2_config->srb_Identity = 2;
|
||||
|
||||
SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[next_xid]);
|
||||
DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[next_xid]);
|
||||
SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[new_xid]);
|
||||
DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[new_xid]);
|
||||
|
||||
if (*SRB_configList2) {
|
||||
free(*SRB_configList2);
|
||||
LOG_D(NR_RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid);
|
||||
LOG_D(NR_RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", new_xid);
|
||||
}
|
||||
|
||||
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
|
||||
@@ -1566,8 +1429,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
|
||||
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n",
|
||||
SRB2_config->srb_Identity);
|
||||
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n",
|
||||
SRB2_config->srb_Identity, next_xid);
|
||||
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid);
|
||||
} else {
|
||||
// SRB configuration list only contains SRB1.
|
||||
LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n");
|
||||
@@ -1575,7 +1437,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
|
||||
if (*DRB_configList2) {
|
||||
free(*DRB_configList2);
|
||||
LOG_D(NR_RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid);
|
||||
LOG_D(NR_RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", new_xid);
|
||||
}
|
||||
|
||||
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
|
||||
@@ -1691,27 +1553,29 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
/* TODO parameters yet to process ... */
|
||||
/* TODO should test if pdu session are Ok before! */
|
||||
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
ue_context_pP->ue_context.pduSession[i].xid = xid;
|
||||
ue_context_pP->ue_context.pduSession[i].xid = old_xid;
|
||||
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
|
||||
i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE");
|
||||
}
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer),
|
||||
xid,
|
||||
size = do_RRCReconfiguration(ctxt_pP,
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
old_xid,
|
||||
*SRB_configList2,
|
||||
DRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // MeasObj_list,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
DRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // MeasObj_list,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n");
|
||||
|
||||
@@ -2135,21 +1999,13 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
|
||||
// SRB1
|
||||
ue_context_p->ue_context.Srb1.Active = 1;
|
||||
ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx;
|
||||
memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0],
|
||||
&DCCH_LCHAN_DESC,
|
||||
LCHAN_DESC_SIZE);
|
||||
memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1],
|
||||
&DCCH_LCHAN_DESC,
|
||||
LCHAN_DESC_SIZE);
|
||||
rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0]);
|
||||
rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1]);
|
||||
// SRB2: set it to go through SRB1 with id 1 (DCCH)
|
||||
ue_context_p->ue_context.Srb2.Active = 1;
|
||||
ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx;
|
||||
memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0],
|
||||
&DCCH_LCHAN_DESC,
|
||||
LCHAN_DESC_SIZE);
|
||||
memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1],
|
||||
&DCCH_LCHAN_DESC,
|
||||
LCHAN_DESC_SIZE);
|
||||
rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0]);
|
||||
rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1]);
|
||||
|
||||
rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, 0);
|
||||
|
||||
@@ -2483,7 +2339,6 @@ rrc_gNB_decode_dcch(
|
||||
nr_rrc_pdcp_config_security(ctxt_pP, ue_context_p, 1);
|
||||
|
||||
rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p);
|
||||
//rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
|
||||
break;
|
||||
case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure:
|
||||
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
|
||||
@@ -3499,6 +3354,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) {
|
||||
fill_DRB_configList(&ctxt, ue_context_p);
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig);
|
||||
} else {
|
||||
rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p);
|
||||
@@ -3511,10 +3367,31 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch
|
||||
|
||||
static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, const char *msg_name, instance_t instance){
|
||||
|
||||
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
|
||||
f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
|
||||
protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
|
||||
|
||||
e1ap_bearer_setup_req_t req = {0};
|
||||
req.numPDUSessionsMod = ue_context_p->ue_context.nb_of_pdusessions;
|
||||
req.gNB_cu_cp_ue_id = ue_context_p->ue_context.gNB_ue_ngap_id;
|
||||
req.rnti = ue_context_p->ue_context.rnti;
|
||||
for (int i=0; i < req.numPDUSessionsMod; i++) {
|
||||
req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length;
|
||||
for (int j=0; j < resp->drbs_to_be_setup_length; j++) {
|
||||
f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j;
|
||||
DRB_nGRAN_to_setup_t *drb_e1 = req.pduSessionMod[i].DRBnGRanModList + j;
|
||||
|
||||
drb_e1->id = drb_f1->drb_id;
|
||||
drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length;
|
||||
drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address;
|
||||
drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid;
|
||||
}
|
||||
}
|
||||
|
||||
// send the F1 response message up to update F1-U tunnel info
|
||||
rrc->cucp_cuup.bearer_context_mod(&req, instance);
|
||||
|
||||
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||
|
||||
if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){
|
||||
@@ -3803,6 +3680,98 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
}
|
||||
}
|
||||
|
||||
int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) {
|
||||
|
||||
AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n");
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[0]; //TODO: remove hardcoding of RC index here
|
||||
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, instance, E1AP_SETUP_RESP);
|
||||
|
||||
e1ap_setup_resp_t *resp = &E1AP_SETUP_RESP(msg_p);
|
||||
resp->transac_id = req->transac_id;
|
||||
|
||||
for (int i=0; i < req->supported_plmns; i++) {
|
||||
if (rrc->configuration.mcc[i] == req->plmns[i].mcc &&
|
||||
rrc->configuration.mnc[i] == req->plmns[i].mnc) {
|
||||
LOG_E(NR_RRC, "PLMNs received from CUUP (mcc:%d, mnc:%d) did not match with PLMNs in RRC (mcc:%d, mnc:%d)\n",
|
||||
req->plmns[i].mcc, req->plmns[i].mnc, rrc->configuration.mcc[i], rrc->configuration.mnc[i]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_CUCP_E1, instance, msg_p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p,
|
||||
e1ap_bearer_setup_resp_t *e1ap_resp) {
|
||||
|
||||
/*Generate a UE context modification request message towards the DU to instruct the DU
|
||||
*for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/
|
||||
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
|
||||
// TODO: So many hard codings
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
|
||||
f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(message_p);
|
||||
req->rnti = ue_context_p->ue_context.rnti;
|
||||
req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0];
|
||||
req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0];
|
||||
req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0];
|
||||
req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid;
|
||||
|
||||
/*Instruction towards the DU for SRB2 configuration*/
|
||||
req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t));
|
||||
req->srbs_to_be_setup_length = 1;
|
||||
f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup;
|
||||
SRBs[0].srb_id = 2;
|
||||
SRBs[0].lcid = 2;
|
||||
|
||||
/*Instruction towards the DU for DRB configuration and tunnel creation*/
|
||||
req->drbs_to_be_setup_length = e1ap_resp->pduSession[0].numDRBSetup;
|
||||
req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)*req->drbs_to_be_setup_length);
|
||||
for (int i=0; i < e1ap_resp->pduSession[0].numDRBSetup; i++) {
|
||||
f1ap_drb_to_be_setup_t *DRBs = req->drbs_to_be_setup + i;
|
||||
DRBs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id;
|
||||
DRBs[i].rlc_mode = RLC_MODE_AM;
|
||||
DRBs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress;
|
||||
DRBs[i].up_ul_tnl[0].port = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
|
||||
DRBs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId;
|
||||
DRBs[i].up_ul_tnl_length = 1;
|
||||
}
|
||||
|
||||
itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p);
|
||||
}
|
||||
|
||||
void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) {
|
||||
// Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU
|
||||
|
||||
uint16_t ue_initial_id = 0; // Making an invalid UE initial ID
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, resp->gNB_cu_cp_ue_id);
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
|
||||
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
|
||||
create_tunnel_resp.num_tunnels = resp->numPDUSessions;
|
||||
for (int i=0; i < resp->numPDUSessions; i++) {
|
||||
create_tunnel_resp.pdusession_id[i] = resp->pduSession[i].id;
|
||||
create_tunnel_resp.gnb_NGu_teid[i] = resp->pduSession[i].teId;
|
||||
memcpy(create_tunnel_resp.gnb_addr.buffer,
|
||||
&resp->pduSession[i].tlAddress,
|
||||
sizeof(in_addr_t));
|
||||
create_tunnel_resp.gnb_addr.length = sizeof(in_addr_t); // IPv4 byte length
|
||||
}
|
||||
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt,
|
||||
&create_tunnel_resp);
|
||||
|
||||
ue_context_p->ue_context.setup_pdu_sessions += resp->numPDUSessions;
|
||||
|
||||
// TODO: SV: combine e1ap_bearer_setup_req_t and e1ap_bearer_setup_resp_t and minimize assignments
|
||||
prepare_and_send_ue_context_modification_f1(ue_context_p, resp);
|
||||
}
|
||||
|
||||
static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults)
|
||||
{
|
||||
DevAssert(measresults->measResultServingMOList.list.count >= 1);
|
||||
@@ -4021,6 +3990,15 @@ void *rrc_gnb_task(void *args_p) {
|
||||
rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance);
|
||||
break;
|
||||
|
||||
case E1AP_SETUP_REQ:
|
||||
LOG_I(NR_RRC, "Received E1AP_SETUP_REQ for instance %d\n", (int)instance);
|
||||
rrc_gNB_process_e1_setup_req(&E1AP_SETUP_REQ(msg_p), instance);
|
||||
break;
|
||||
|
||||
case E1AP_BEARER_CONTEXT_SETUP_RESP:
|
||||
LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_SETUP_RESP for instance %d\n", (int)instance);
|
||||
rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance);
|
||||
|
||||
case NGAP_PAGING_IND:
|
||||
rrc_gNB_process_PAGING_IND(msg_p, msg_name_p, instance);
|
||||
break;
|
||||
@@ -4063,6 +4041,7 @@ rrc_gNB_generate_SecurityModeCommand(
|
||||
|
||||
switch (RC.nrrrc[ctxt_pP->module_id]->node_type) {
|
||||
case ngran_gNB_CU:
|
||||
case ngran_gNB_CUCP:
|
||||
// create an ITTI message
|
||||
memcpy(ue_context_pP->ue_context.Srb1.Srb_info.Tx_buffer.Payload, buffer, size);
|
||||
ue_context_pP->ue_context.Srb1.Srb_info.Tx_buffer.payload_size = size;
|
||||
@@ -4125,6 +4104,7 @@ rrc_gNB_generate_UECapabilityEnquiry(
|
||||
size);
|
||||
switch (RC.nrrrc[ctxt_pP->module_id]->node_type) {
|
||||
case ngran_gNB_CU:
|
||||
case ngran_gNB_CUCP:
|
||||
nr_rrc_data_req(
|
||||
ctxt_pP,
|
||||
DCCH,
|
||||
@@ -4352,3 +4332,4 @@ void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe)
|
||||
LOG_D(NR_RRC, "Time in RRC: %u/ %u \n", frame, subframe);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
) {
|
||||
rnti_t rnti;
|
||||
int i;
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
@@ -57,7 +56,6 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->num_tunnels);
|
||||
rnti = create_tunnel_resp_pP->rnti;
|
||||
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
|
||||
|
||||
for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
|
||||
@@ -74,7 +72,6 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
create_tunnel_resp_pP->enb_addr.length);
|
||||
}
|
||||
|
||||
(void)rnti; /* avoid gcc warning "set but not used" */
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
@@ -84,10 +81,8 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
int
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP
|
||||
) {
|
||||
rnti_t rnti;
|
||||
int i;
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
@@ -95,24 +90,21 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->num_tunnels);
|
||||
rnti = create_tunnel_resp_pP->ue_id;
|
||||
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
|
||||
|
||||
for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
|
||||
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->gnb_NGu_teid[i];
|
||||
ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->gnb_addr;
|
||||
ue_context_p->ue_context.gnb_gtp_psi[inde_list[i]] = create_tunnel_resp_pP->pdusession_id[i];
|
||||
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
|
||||
ue_context_p->ue_context.gnb_gtp_teid[i] = create_tunnel_resp_pP->gnb_NGu_teid[i];
|
||||
ue_context_p->ue_context.gnb_gtp_addrs[i] = create_tunnel_resp_pP->gnb_addr;
|
||||
ue_context_p->ue_context.gnb_gtp_psi[i] = create_tunnel_resp_pP->pdusession_id[i];
|
||||
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, id %u, gtp addr len %d \n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->gnb_NGu_teid[i],
|
||||
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]],
|
||||
inde_list[i],
|
||||
ue_context_p->ue_context.gnb_gtp_teid[i],
|
||||
i,
|
||||
create_tunnel_resp_pP->pdusession_id[i],
|
||||
create_tunnel_resp_pP->gnb_addr.length);
|
||||
}
|
||||
|
||||
(void)rnti; /* avoid gcc warning "set but not used" */
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
|
||||
@@ -41,8 +41,7 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
int
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
+106
-114
@@ -57,6 +57,7 @@
|
||||
#include "NGAP_Cause.h"
|
||||
#include "NGAP_CauseRadioNetwork.h"
|
||||
#include "f1ap_messages_types.h"
|
||||
#include "openair2/E1AP/e1ap_asnc.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
@@ -242,7 +243,7 @@ rrc_gNB_NGAP_get_ue_ids(
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static struct rrc_gNB_ue_context_s *
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_get_ue_context_from_ngap_ids(
|
||||
const instance_t instanceP,
|
||||
const uint16_t ue_initial_idP,
|
||||
@@ -474,7 +475,6 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
protocol_ctxt_t ctxt={0};
|
||||
uint8_t pdu_sessions_done = 0;
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp;
|
||||
uint8_t inde_list[NR_NB_RB_MAX - 3]= {0};
|
||||
int ret = 0;
|
||||
|
||||
ue_initial_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id;
|
||||
@@ -495,12 +495,14 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
return (-1);
|
||||
} else {
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).gNB_ue_ngap_id;
|
||||
ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id;
|
||||
ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag;
|
||||
|
||||
uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
|
||||
if (nb_pdusessions_tosetup != 0) {
|
||||
AssertFatal(rrc->node_type != ngran_gNB_CUCP, "PDU sessions in Initial context setup request not handled by E1 yet\n");
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
|
||||
if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
|
||||
@@ -520,7 +522,6 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
i,
|
||||
create_tunnel_req.outgoing_teid[pdu_sessions_done],
|
||||
create_tunnel_req.pdusession_id[pdu_sessions_done]);
|
||||
inde_list[pdu_sessions_done] = i;
|
||||
pdu_sessions_done++;
|
||||
|
||||
if(pdu_sessions_done >= nb_pdusessions_tosetup) {
|
||||
@@ -549,9 +550,8 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
&ctxt,
|
||||
&create_tunnel_resp,
|
||||
&inde_list[0]);
|
||||
ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup;
|
||||
&create_tunnel_resp);
|
||||
ue_context_p->ue_context.setup_pdu_sessions += NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
|
||||
ue_context_p->ue_context.established_pdu_sessions_flag = 1;
|
||||
}
|
||||
|
||||
@@ -804,6 +804,7 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS(
|
||||
*/
|
||||
switch (RC.nrrrc[ctxt.module_id]->node_type) {
|
||||
case ngran_gNB_CU:
|
||||
case ngran_gNB_CUCP:
|
||||
/* Transfer data to PDCP */
|
||||
nr_rrc_data_req (
|
||||
&ctxt,
|
||||
@@ -945,7 +946,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
void
|
||||
rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
@@ -953,21 +954,20 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
gNB_RRC_INST *rrc;
|
||||
uint16_t ue_initial_id;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
protocol_ctxt_t ctxt={0};
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
|
||||
uint8_t pdu_sessions_done;
|
||||
uint8_t inde_list[NR_NB_RB_MAX - 3]= {0};
|
||||
int ret = 0;
|
||||
|
||||
ue_initial_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).ue_initial_id;
|
||||
gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id;
|
||||
ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p);
|
||||
ue_initial_id = msg->ue_initial_id;
|
||||
gNB_ue_ngap_id = msg->gNB_ue_ngap_id;
|
||||
ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
|
||||
rrc = RC.nrrrc[ctxt.module_id];
|
||||
LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u \n",
|
||||
instance, msg_name, ue_initial_id, gNB_ue_ngap_id);
|
||||
instance, msg_name, ue_initial_id, gNB_ue_ngap_id);
|
||||
|
||||
if (ue_context_p == NULL) {
|
||||
MessageDef *msg_fail_p = NULL;
|
||||
@@ -976,110 +976,102 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
||||
NGAP_PDUSESSION_SETUP_REQ(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id;
|
||||
// TODO add failure cause when defined!
|
||||
itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p);
|
||||
return (-1);
|
||||
} else {
|
||||
memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
|
||||
uint8_t nb_pdusessions_tosetup = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup;
|
||||
pdu_sessions_done = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
ue_context_p->ue_context.nb_of_pdusessions = msg->nb_pdusessions_tosetup;
|
||||
ue_context_p->ue_context.gNB_ue_ngap_id = msg->gNB_ue_ngap_id;
|
||||
ue_context_p->ue_context.amf_ue_ngap_id = msg->amf_ue_ngap_id;
|
||||
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
|
||||
for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
|
||||
if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
|
||||
continue;
|
||||
ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_NEW;
|
||||
ue_context_p->ue_context.pduSession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
|
||||
create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id;
|
||||
create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1;
|
||||
create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid;
|
||||
create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].qos[0].qfi;
|
||||
memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer,
|
||||
NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer,
|
||||
sizeof(uint8_t)*20);
|
||||
create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length;
|
||||
LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n",
|
||||
i,
|
||||
create_tunnel_req.outgoing_teid[pdu_sessions_done],
|
||||
create_tunnel_req.pdusession_id[pdu_sessions_done]);
|
||||
inde_list[pdu_sessions_done] = i;
|
||||
pdu_sessions_done++;
|
||||
/* Configurations are referred from rrc_gNB_generate_dedicatedRRCReconfiguration() and
|
||||
rrc_gNB_process_RRCReconfigurationComplete()
|
||||
|
||||
if(pdu_sessions_done >= nb_pdusessions_tosetup) {
|
||||
break;
|
||||
At CU-CP we configure the E1 bearer context setup parameters (PDU sessions, DRBs and
|
||||
QoS flows) same as in these functions. At CU-UP we create PDU Sessions and allocate DRBs.
|
||||
*/
|
||||
e1ap_bearer_setup_req_t bearer_req;
|
||||
|
||||
bearer_req.gNB_cu_cp_ue_id = gNB_ue_ngap_id;
|
||||
bearer_req.rnti = ue_context_p->ue_context.rnti;
|
||||
bearer_req.cipheringAlgorithm = ue_context_p->ue_context.ciphering_algorithm;
|
||||
memcpy(bearer_req.encryptionKey, ue_context_p->ue_context.kgnb, sizeof(ue_context_p->ue_context.kgnb));
|
||||
bearer_req.integrityProtectionAlgorithm = ue_context_p->ue_context.integrity_algorithm;
|
||||
memcpy(bearer_req.integrityProtectionKey, ue_context_p->ue_context.kgnb, sizeof(ue_context_p->ue_context.kgnb));
|
||||
bearer_req.ueDlAggMaxBitRate = msg->ueAggMaxBitRateDownlink;
|
||||
|
||||
bearer_req.numPDUSessions = msg->nb_pdusessions_tosetup;
|
||||
|
||||
for (int i=0; i < bearer_req.numPDUSessions; i++) {
|
||||
ue_context_p->ue_context.pduSession[i].param = msg->pdusession_setup_params[i];
|
||||
|
||||
pdu_session_to_setup_t *pdu = bearer_req.pduSession + i;
|
||||
pdu->sessionId = msg->pdusession_setup_params[i].pdusession_id;
|
||||
pdu->sessionType = msg->pdusession_setup_params[i].upf_addr.pdu_session_type;
|
||||
pdu->sst = msg->allowed_nssai[i].sST;
|
||||
if (rrc->security.do_drb_integrity) {
|
||||
pdu->integrityProtectionIndication = E1AP_IntegrityProtectionIndication_required;
|
||||
} else {
|
||||
pdu->integrityProtectionIndication = E1AP_IntegrityProtectionIndication_not_needed;
|
||||
}
|
||||
|
||||
if (rrc->security.do_drb_ciphering) {
|
||||
pdu->confidentialityProtectionIndication = E1AP_ConfidentialityProtectionIndication_required;
|
||||
} else {
|
||||
pdu->confidentialityProtectionIndication = E1AP_ConfidentialityProtectionIndication_not_needed;
|
||||
}
|
||||
pdu->teId = msg->pdusession_setup_params[i].gtp_teid;
|
||||
memcpy(&pdu->tlAddress,
|
||||
msg->pdusession_setup_params[i].upf_addr.buffer,
|
||||
sizeof(uint8_t)*4);
|
||||
|
||||
ue_context_p->ue_context.pduSession[i].param = msg->pdusession_setup_params[i];
|
||||
ue_context_p->ue_context.nb_of_pdusessions = msg->nb_pdusessions_tosetup;
|
||||
ue_context_p->ue_context.gNB_ue_ngap_id = msg->gNB_ue_ngap_id;
|
||||
ue_context_p->ue_context.amf_ue_ngap_id = msg->amf_ue_ngap_id;
|
||||
pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
|
||||
ue_context_p->ue_context.setup_pdu_sessions += pdu->numDRB2Setup;
|
||||
for (int j=0; j < pdu->numDRB2Setup; j++) {
|
||||
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
|
||||
|
||||
drb->id = i + j + 1;
|
||||
|
||||
drb->defaultDRB = E1AP_DefaultDRB_true;
|
||||
|
||||
drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap);
|
||||
drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap);
|
||||
|
||||
drb->pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_18;
|
||||
drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18;
|
||||
|
||||
drb->discardTimer = E1AP_DiscardTimer_infinity;
|
||||
drb->reorderingTimer = E1AP_T_Reordering_ms0;
|
||||
|
||||
drb->rLC_Mode = E1AP_RLC_Mode_rlc_am;
|
||||
|
||||
drb->numCellGroups = 1; // assume one cell group associated with a DRB
|
||||
|
||||
for (int k=0; k < drb->numCellGroups; k++) {
|
||||
cell_group_t *cellGroup = drb->cellGroupList + k;
|
||||
cellGroup->id = 0; // MCG
|
||||
}
|
||||
|
||||
drb->numQosFlow2Setup = msg->pdusession_setup_params[i].nb_qos;
|
||||
for (int k=0; k < drb->numQosFlow2Setup; k++) {
|
||||
qos_flow_to_setup_t *qos = drb->qosFlows + k;
|
||||
|
||||
qos->id = msg->pdusession_setup_params[i].qos[k].qfi;
|
||||
qos->fiveQI = msg->pdusession_setup_params[i].qos[k].fiveQI;
|
||||
qos->fiveQI_type = msg->pdusession_setup_params[i].qos[k].fiveQI_type;
|
||||
|
||||
qos->qoSPriorityLevel = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.priority_level;
|
||||
qos->pre_emptionCapability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_capability;
|
||||
qos->pre_emptionVulnerability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_vulnerability;
|
||||
}
|
||||
}
|
||||
|
||||
ue_context_p->ue_context.nb_of_pdusessions = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup;
|
||||
ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id;
|
||||
ue_context_p->ue_context.amf_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).amf_ue_ngap_id;
|
||||
create_tunnel_req.ue_id = ue_context_p->ue_context.rnti;
|
||||
create_tunnel_req.num_tunnels = pdu_sessions_done;
|
||||
|
||||
ret = gtpv1u_create_ngu_tunnel(
|
||||
instance,
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp);
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti);
|
||||
ue_context_p->ue_context.ue_release_timer_ng = 1;
|
||||
ue_context_p->ue_context.ue_release_timer_thres_ng = 100;
|
||||
ue_context_p->ue_context.ue_release_timer = 0;
|
||||
ue_context_p->ue_context.ue_reestablishment_timer = 0;
|
||||
ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
|
||||
// rrc_gNB_free_UE(ctxt.module_id,ue_context_p);
|
||||
ue_context_p->ue_context.ul_failure_timer = 0;
|
||||
return (0);
|
||||
}
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
&ctxt,
|
||||
&create_tunnel_resp,
|
||||
&inde_list[0]);
|
||||
ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup;
|
||||
|
||||
// TEST
|
||||
// ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE;
|
||||
// rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0);
|
||||
if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)){
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL);
|
||||
}
|
||||
else{
|
||||
/*Generate a UE context modification request message towards the DU to instruct the DU
|
||||
*for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
|
||||
f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ (message_p);
|
||||
req->rnti = ue_context_p->ue_context.rnti;
|
||||
req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0];
|
||||
req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0];
|
||||
req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0];
|
||||
req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid;
|
||||
|
||||
/*Instruction towards the DU for SRB2 configuration*/
|
||||
req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t));
|
||||
req->srbs_to_be_setup_length = 1;
|
||||
f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup;
|
||||
SRBs[0].srb_id = 2;
|
||||
SRBs[0].lcid = 2;
|
||||
|
||||
/*Instruction towards the DU for DRB configuration and tunnel creation*/
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
||||
memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
|
||||
req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t));
|
||||
req->drbs_to_be_setup_length = 1;
|
||||
f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup;
|
||||
LOG_D(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length);
|
||||
DRBs[0].drb_id = 1;
|
||||
DRBs[0].rlc_mode = RLC_MODE_AM;
|
||||
DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
|
||||
DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
|
||||
DRBs[0].up_ul_tnl_length = 1;
|
||||
DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr);
|
||||
DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
|
||||
DRBs[0].up_dl_tnl_length = 1;
|
||||
|
||||
itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -101,7 +101,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
uint8_t xid
|
||||
);
|
||||
|
||||
int
|
||||
void
|
||||
rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
@@ -189,6 +189,13 @@ nr_rrc_pdcp_config_security(
|
||||
const uint8_t send_security_mode_command
|
||||
);
|
||||
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_get_ue_context_from_ngap_ids(
|
||||
const instance_t instanceP,
|
||||
const uint16_t ue_initial_idP,
|
||||
const uint32_t gNB_ue_ngap_idP
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_PAGING_IND(
|
||||
MessageDef *msg_p,
|
||||
|
||||
@@ -22,32 +22,6 @@
|
||||
#include "rrc_gNB_radio_bearers.h"
|
||||
#include "oai_asn1.h"
|
||||
|
||||
NR_SRB_ToAddMod_t *generateSRB2() {
|
||||
NR_SRB_ToAddMod_t *SRB2_config = NULL;
|
||||
|
||||
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
SRB2_config->srb_Identity = 2;
|
||||
|
||||
return SRB2_config;
|
||||
}
|
||||
|
||||
NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue,
|
||||
NR_SRB_ToAddModList_t *SRB_configList,
|
||||
uint8_t xid) {
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||
|
||||
SRB_configList2 = &ue->SRB_configList2[xid];
|
||||
if (*SRB_configList2 == NULL) {
|
||||
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
|
||||
memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
|
||||
NR_SRB_ToAddMod_t *SRB2_config = generateSRB2();
|
||||
asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
|
||||
asn1cSeqAdd(&SRB_configList->list, SRB2_config);
|
||||
}
|
||||
|
||||
return SRB_configList2;
|
||||
}
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue,
|
||||
uint8_t drb_id,
|
||||
const pdu_session_param_t *pduSession,
|
||||
|
||||
@@ -35,10 +35,6 @@
|
||||
#define GBR_FLOW (1)
|
||||
#define NONGBR_FLOW (0)
|
||||
|
||||
NR_SRB_ToAddMod_t *generateSRB2(void);
|
||||
NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue,
|
||||
NR_SRB_ToAddModList_t *SRB_configList,
|
||||
uint8_t xid);
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue,
|
||||
uint8_t drb_id,
|
||||
const pdu_session_param_t *pduSession,
|
||||
|
||||
@@ -35,6 +35,8 @@ typedef struct {
|
||||
|
||||
static nr_sdap_entity_info sdap_info;
|
||||
|
||||
instance_t *N3GTPUInst = NULL;
|
||||
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager(void);
|
||||
|
||||
void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu)
|
||||
@@ -216,7 +218,8 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
|
||||
req->ue_id = ue_id;
|
||||
req->bearer_id = pdusession_id;
|
||||
LOG_D(SDAP, "%s() sending message to gtp size %d\n", __func__, size-offset);
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
|
||||
// very very dirty hack gloabl var N3GTPUInst
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, *N3GTPUInst, message_p);
|
||||
} else { //nrUE
|
||||
/*
|
||||
* TS 37.324 5.2 Data transfer
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
* the GTP-U Extension Header. Inside the DL PDU SESSION INFORMATION frame.
|
||||
* TS 38.415 Fig. 5.5.2.1-1
|
||||
*/
|
||||
|
||||
extern instance_t *N3GTPUInst;
|
||||
|
||||
typedef struct nr_sdap_dl_hdr_s {
|
||||
uint8_t QFI:6;
|
||||
uint8_t RQI:1;
|
||||
|
||||
Reference in New Issue
Block a user