Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lizhongxiao
OpenXG-RAN
Commits
6a7d7e18
Commit
6a7d7e18
authored
May 31, 2023
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Telnet module to manually/release DRBs of UE
parent
203df298
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
269 additions
and
1 deletion
+269
-1
common/utils/telnetsrv/CMakeLists.txt
common/utils/telnetsrv/CMakeLists.txt
+6
-1
common/utils/telnetsrv/telnetsrv_bearer.c
common/utils/telnetsrv/telnetsrv_bearer.c
+121
-0
openair2/RRC/NR/rrc_gNB.c
openair2/RRC/NR/rrc_gNB.c
+142
-0
No files found.
common/utils/telnetsrv/CMakeLists.txt
View file @
6a7d7e18
...
...
@@ -59,8 +59,13 @@ add_library(telnetsrv_ci MODULE telnetsrv_ci.c)
target_link_libraries
(
telnetsrv_ci PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs
)
add_dependencies
(
telnetsrv telnetsrv_ci
)
message
(
STATUS
"Add bearer specific telnet functions in libtelnetsrv_bearer.so"
)
add_library
(
telnetsrv_bearer MODULE telnetsrv_bearer.c
)
target_link_libraries
(
telnetsrv_bearer PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs
)
add_dependencies
(
telnetsrv telnetsrv_bearer
)
# all libraries should be written to root build dir
set_target_properties
(
telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci
set_target_properties
(
telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci
telnetsrv_bearer
PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../../..
)
common/utils/telnetsrv/telnetsrv_bearer.c
0 → 100644
View file @
6a7d7e18
/*
* 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 <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
#define TELNETSERVERCODE
#include "telnetsrv.h"
#define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return 1; } while (0)
static
int
get_single_ue_rnti
(
void
)
{
rrc_gNB_ue_context_t
*
ue_context_p
=
NULL
;
RB_FOREACH
(
ue_context_p
,
rrc_nr_ue_tree_s
,
&
(
RC
.
nrrrc
[
0
]
->
rrc_ue_head
))
{
return
ue_context_p
->
ue_context
.
rnti
;
}
return
-
1
;
}
int
get_single_rnti
(
char
*
buf
,
int
debug
,
telnet_printfunc_t
prnt
)
{
if
(
buf
)
ERROR_MSG_RET
(
"no parameter allowed
\n
"
);
int
rnti
=
get_single_ue_rnti
();
if
(
rnti
<
1
)
ERROR_MSG_RET
(
"different number of UEs
\n
"
);
prnt
(
"single UE RNTI %04x
\n
"
,
rnti
);
return
0
;
}
void
rrc_gNB_trigger_new_bearer
(
int
rnti
);
int
add_bearer
(
char
*
buf
,
int
debug
,
telnet_printfunc_t
prnt
)
{
int
rnti
=
-
1
;
if
(
!
buf
)
{
rnti
=
get_single_ue_rnti
();
if
(
rnti
<
1
)
ERROR_MSG_RET
(
"no UE found
\n
"
);
}
else
{
rnti
=
strtol
(
buf
,
NULL
,
16
);
if
(
rnti
<
1
||
rnti
>=
0xfffe
)
ERROR_MSG_RET
(
"RNTI needs to be [1,0xfffe]
\n
"
);
}
// verify it exists in RRC as well
rrc_gNB_ue_context_t
*
rrcue
=
rrc_gNB_get_ue_context_by_rnti
(
RC
.
nrrrc
[
0
],
rnti
);
if
(
!
rrcue
)
ERROR_MSG_RET
(
"could not find UE with RNTI %04x
\n
"
,
rnti
);
rrc_gNB_trigger_new_bearer
(
rnti
);
prnt
(
"called rrc_gNB_trigger_new_bearer(%04x)
\n
"
,
rnti
);
return
0
;
}
void
rrc_gNB_trigger_release_bearer
(
int
rnti
);
int
release_bearer
(
char
*
buf
,
int
debug
,
telnet_printfunc_t
prnt
)
{
int
rnti
=
-
1
;
if
(
!
buf
)
{
rnti
=
get_single_ue_rnti
();
if
(
rnti
<
1
)
ERROR_MSG_RET
(
"no UE found
\n
"
);
}
else
{
rnti
=
strtol
(
buf
,
NULL
,
16
);
if
(
rnti
<
1
||
rnti
>=
0xfffe
)
ERROR_MSG_RET
(
"RNTI needs to be [1,0xfffe]
\n
"
);
}
// verify it exists in RRC as well
rrc_gNB_ue_context_t
*
rrcue
=
rrc_gNB_get_ue_context_by_rnti
(
RC
.
nrrrc
[
0
],
rnti
);
if
(
!
rrcue
)
ERROR_MSG_RET
(
"could not find UE with RNTI %04x
\n
"
,
rnti
);
rrc_gNB_trigger_release_bearer
(
rnti
);
prnt
(
"called rrc_gNB_trigger_release_bearer(%04x)
\n
"
,
rnti
);
return
0
;
}
static
telnetshell_cmddef_t
bearercmds
[]
=
{
{
"get_single_rnti"
,
""
,
get_single_rnti
},
{
"add_bearer"
,
"[rnti(hex,opt)]"
,
add_bearer
},
{
"release_bearer"
,
"[rnti(hex,opt)]"
,
release_bearer
},
{
""
,
""
,
NULL
},
};
static
telnetshell_vardef_t
bearervars
[]
=
{
{
""
,
0
,
0
,
NULL
}
};
void
add_bearer_cmds
(
void
)
{
add_telnetcmd
(
"bearer"
,
bearervars
,
bearercmds
);
}
openair2/RRC/NR/rrc_gNB.c
View file @
6a7d7e18
...
...
@@ -46,6 +46,7 @@
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "RRC/NR/MESSAGES/asn1_msg.h"
#include "openair2/E1AP/e1ap_asnc.h"
#include "NR_BCCH-BCH-Message.h"
#include "NR_UL-DCCH-Message.h"
...
...
@@ -2858,6 +2859,147 @@ rrc_gNB_generate_RRCRelease(
/* UE will be freed after UE context release complete */
}
void
rrc_gNB_trigger_new_bearer
(
int
rnti
)
{
/* get RRC and UE */
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
0
];
rrc_gNB_ue_context_t
*
ue_context_p
=
rrc_gNB_get_ue_context_by_rnti
(
rrc
,
rnti
);
if
(
ue_context_p
==
NULL
)
{
LOG_E
(
RRC
,
"unknown UE RNTI %04x
\n
"
,
rnti
);
return
;
}
gNB_RRC_UE_t
*
ue
=
&
ue_context_p
->
ue_context
;
/* get the existing PDU sessoin */
if
(
ue
->
nb_of_pdusessions
<
1
)
{
LOG_E
(
RRC
,
"no PDU session set up yet, cannot create additional bearer
\n
"
);
return
;
}
if
(
ue
->
established_drbs
[
0
].
status
!=
DRB_INACTIVE
&&
ue
->
established_drbs
[
1
].
status
!=
DRB_INACTIVE
)
{
LOG_E
(
RRC
,
"already have two established bearers, aborting
\n
"
);
return
;
}
e1ap_bearer_setup_req_t
bearer_req
=
{
0
};
bearer_req
.
gNB_cu_cp_ue_id
=
ue
->
rrc_ue_id
;
bearer_req
.
cipheringAlgorithm
=
ue
->
ciphering_algorithm
;
memcpy
(
bearer_req
.
encryptionKey
,
ue
->
kgnb
,
sizeof
(
ue
->
kgnb
));
bearer_req
.
integrityProtectionAlgorithm
=
ue
->
integrity_algorithm
;
memcpy
(
bearer_req
.
integrityProtectionKey
,
ue
->
kgnb
,
sizeof
(
ue
->
kgnb
));
bearer_req
.
ueDlAggMaxBitRate
=
10000
;
/* probably does not matter */
pdu_session_to_setup_t
*
pdu
=
&
bearer_req
.
pduSession
[
0
];
//bearer_req.numPDUSessions++;
bearer_req
.
numPDUSessions
=
1
;
//pdu->sessionId = session->pdusession_id;
//pdu->sst = msg->allowed_nssai[i].sST;
//pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed;
//pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
//pdu->teId = session->gtp_teid;
pdu
->
numDRB2Setup
=
1
;
// One DRB per PDU Session. TODO: Remove hardcoding
DRB_nGRAN_to_setup_t
*
drb
=
&
pdu
->
DRBnGRanList
[
0
];
int
drb_id
=
2
;
drb
->
id
=
drb_id
;
drb
->
defaultDRB
=
E1AP_DefaultDRB_false
;
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
}
int
xid
=
rrc_gNB_get_next_transaction_identifier
(
0
);
/* generate a new bearer, it will be put into internal RRC state and picked
* up later */
generateDRB
(
ue
,
drb_id
,
&
ue
->
pduSession
[
0
],
rrc
->
configuration
.
enable_sdap
,
rrc
->
security
.
do_drb_integrity
,
rrc
->
security
.
do_drb_ciphering
);
/* associate the new bearer to it */
ue
->
xids
[
xid
]
=
RRC_PDUSESSION_MODIFY
;
ue
->
pduSession
[
0
].
xid
=
xid
;
// hack: fake xid for ongoing PDU session
LOG_W
(
RRC
,
"trigger new bearer %ld for UE %04x xid %d
\n
"
,
drb
->
id
,
ue
->
rnti
,
xid
);
rrc
->
cucp_cuup
.
bearer_context_setup
(
&
bearer_req
,
0
);
}
void
rrc_gNB_trigger_release_bearer
(
int
rnti
)
{
/* get RRC and UE */
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
0
];
rrc_gNB_ue_context_t
*
ue_context_p
=
rrc_gNB_get_ue_context_by_rnti
(
rrc
,
rnti
);
if
(
ue_context_p
==
NULL
)
{
LOG_E
(
RRC
,
"unknown UE RNTI %04x
\n
"
,
rnti
);
return
;
}
gNB_RRC_UE_t
*
ue
=
&
ue_context_p
->
ue_context
;
if
(
ue
->
established_drbs
[
1
].
status
==
DRB_INACTIVE
)
{
LOG_E
(
RRC
,
"no second bearer, aborting
\n
"
);
return
;
}
// don't use E1: bearer release is not implemented, call directly
// into PDCP/SDAP and then send corresponding message via F1
int
drb_id
=
2
;
ue
->
established_drbs
[
1
].
status
=
DRB_INACTIVE
;
ue
->
DRB_ReleaseList
=
calloc
(
1
,
sizeof
(
*
ue
->
DRB_ReleaseList
));
AssertFatal
(
ue
->
DRB_ReleaseList
!=
NULL
,
"out of memory
\n
"
);
NR_DRB_Identity_t
*
asn1_drb
=
malloc
(
sizeof
(
*
asn1_drb
));
AssertFatal
(
asn1_drb
!=
NULL
,
"out of memory
\n
"
);
int
idx
=
0
;
NR_DRB_ToAddModList_t
*
drb_list
=
createDRBlist
(
ue
,
false
);
while
(
idx
<
drb_list
->
list
.
count
)
{
const
NR_DRB_ToAddMod_t
*
drbc
=
drb_list
->
list
.
array
[
idx
];
if
(
drbc
->
drb_Identity
==
drb_id
)
break
;
++
idx
;
}
if
(
idx
<
drb_list
->
list
.
count
)
{
nr_pdcp_release_drb
(
rnti
,
drb_id
);
asn_sequence_del
(
&
drb_list
->
list
,
idx
,
1
);
}
*
asn1_drb
=
drb_id
;
asn1cSeqAdd
(
&
ue
->
DRB_ReleaseList
->
list
,
asn1_drb
);
f1ap_drb_to_be_released_t
drbs_to_be_released
[
1
]
=
{{.
rb_id
=
drb_id
}};
f1_ue_data_t
ue_data
=
cu_get_f1_ue_data
(
ue
->
rrc_ue_id
);
f1ap_ue_context_modif_req_t
ue_context_modif_req
=
{
.
gNB_CU_ue_id
=
ue
->
rrc_ue_id
,
.
gNB_DU_ue_id
=
ue_data
.
secondary_ue
,
.
plmn
.
mcc
=
rrc
->
configuration
.
mcc
[
0
],
.
plmn
.
mnc
=
rrc
->
configuration
.
mnc
[
0
],
.
plmn
.
mnc_digit_length
=
rrc
->
configuration
.
mnc_digit_length
[
0
],
.
nr_cellid
=
rrc
->
nr_cellid
,
.
servCellId
=
0
,
/* TODO: correct value? */
.
srbs_to_be_setup_length
=
0
,
.
srbs_to_be_setup
=
NULL
,
.
drbs_to_be_setup_length
=
0
,
.
drbs_to_be_setup
=
NULL
,
.
drbs_to_be_released_length
=
1
,
.
drbs_to_be_released
=
drbs_to_be_released
,
};
rrc
->
mac_rrc
.
ue_context_modification_request
(
&
ue_context_modif_req
);
}
int
rrc_gNB_generate_pcch_msg
(
uint32_t
tmsi
,
uint8_t
paging_drx
,
instance_t
instance
,
uint8_t
CC_id
){
const
unsigned
int
Ttab
[
4
]
=
{
32
,
64
,
128
,
256
};
uint8_t
Tc
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment