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
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
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
OpenXG
OpenXG-RAN
Commits
df365d9a
Commit
df365d9a
authored
Feb 10, 2025
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add F1 Reset Ack enc/dec/cp/eq/free library and test
parent
4c9ed9d7
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
171 additions
and
6 deletions
+171
-6
openair2/COMMON/f1ap_messages_types.h
openair2/COMMON/f1ap_messages_types.h
+4
-6
openair2/F1AP/lib/f1ap_interface_management.c
openair2/F1AP/lib/f1ap_interface_management.c
+115
-0
openair2/F1AP/lib/f1ap_interface_management.h
openair2/F1AP/lib/f1ap_interface_management.h
+7
-0
openair2/F1AP/tests/f1ap_lib_test.c
openair2/F1AP/tests/f1ap_lib_test.c
+45
-0
No files found.
openair2/COMMON/f1ap_messages_types.h
View file @
df365d9a
...
...
@@ -578,12 +578,10 @@ typedef struct f1ap_reset_t {
}
f1ap_reset_t
;
typedef
struct
f1ap_reset_ack_t
{
uint64_t
transaction_id
;
struct
{
uint32_t
gNB_CU_ue_id
;
uint32_t
gNB_DU_ue_id
;
}
ue_to_reset
[
F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET
];
uint16_t
criticality_diagnostics
;
uint64_t
transaction_id
;
int
num_ue_to_reset
;
f1ap_ue_to_reset_t
*
ue_to_reset
;
// array of num_ue_to_reset elements
//uint16_t criticality_diagnostics; // not implemented as of now
}
f1ap_reset_ack_t
;
#endif
/* F1AP_MESSAGES_TYPES_H_ */
openair2/F1AP/lib/f1ap_interface_management.c
View file @
df365d9a
...
...
@@ -252,6 +252,121 @@ f1ap_reset_t cp_f1ap_reset(const f1ap_reset_t *orig)
return
cp
;
}
/* @brief encode F1 Reset Ack (9.2.1.2 in TS 38.473) */
struct
F1AP_F1AP_PDU
*
encode_f1ap_reset_ack
(
const
f1ap_reset_ack_t
*
msg
)
{
F1AP_F1AP_PDU_t
*
pdu
=
calloc_or_fail
(
1
,
sizeof
(
*
pdu
));
/* Create Message Type */
pdu
->
present
=
F1AP_F1AP_PDU_PR_successfulOutcome
;
asn1cCalloc
(
pdu
->
choice
.
successfulOutcome
,
so
);
so
->
procedureCode
=
F1AP_ProcedureCode_id_Reset
;
so
->
criticality
=
F1AP_Criticality_reject
;
so
->
value
.
present
=
F1AP_SuccessfulOutcome__value_PR_ResetAcknowledge
;
F1AP_ResetAcknowledge_t
*
reset_ack
=
&
so
->
value
.
choice
.
ResetAcknowledge
;
/* (M) Transaction ID */
asn1cSequenceAdd
(
reset_ack
->
protocolIEs
.
list
,
F1AP_ResetAcknowledgeIEs_t
,
ieC1
);
ieC1
->
id
=
F1AP_ProtocolIE_ID_id_TransactionID
;
ieC1
->
criticality
=
F1AP_Criticality_reject
;
ieC1
->
value
.
present
=
F1AP_ResetAcknowledgeIEs__value_PR_TransactionID
;
ieC1
->
value
.
choice
.
TransactionID
=
msg
->
transaction_id
;
/* TODO criticality diagnostics */
/* 0:N UEs to reset */
if
(
msg
->
num_ue_to_reset
==
0
)
return
pdu
;
/* no UEs to encode */
asn1cSequenceAdd
(
reset_ack
->
protocolIEs
.
list
,
F1AP_ResetAcknowledgeIEs_t
,
ieC2
);
ieC2
->
id
=
F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionListResAck
;
ieC2
->
criticality
=
F1AP_Criticality_ignore
;
ieC2
->
value
.
present
=
F1AP_ResetAcknowledgeIEs__value_PR_UE_associatedLogicalF1_ConnectionListResAck
;
F1AP_UE_associatedLogicalF1_ConnectionListResAck_t
*
ue_to_reset
=
&
ieC2
->
value
.
choice
.
UE_associatedLogicalF1_ConnectionListResAck
;
for
(
int
i
=
0
;
i
<
msg
->
num_ue_to_reset
;
++
i
)
{
asn1cSequenceAdd
(
ue_to_reset
->
list
,
F1AP_UE_associatedLogicalF1_ConnectionItemResAck_t
,
conn_it_res
);
conn_it_res
->
id
=
F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionItem
;
conn_it_res
->
criticality
=
F1AP_Criticality_ignore
;
conn_it_res
->
value
.
present
=
F1AP_UE_associatedLogicalF1_ConnectionItemResAck__value_PR_UE_associatedLogicalF1_ConnectionItem
;
conn_it_res
->
value
.
choice
.
UE_associatedLogicalF1_ConnectionItem
=
encode_f1ap_ue_to_reset
(
&
msg
->
ue_to_reset
[
i
]);
}
return
pdu
;
}
/* @brief decode F1 Reset Ack (9.2.1.2 in TS 38.473) */
bool
decode_f1ap_reset_ack
(
const
struct
F1AP_F1AP_PDU
*
pdu
,
f1ap_reset_ack_t
*
out
)
{
_F1_EQ_CHECK_INT
(
pdu
->
present
,
F1AP_F1AP_PDU_PR_successfulOutcome
);
AssertError
(
pdu
->
choice
.
successfulOutcome
!=
NULL
,
return
false
,
"pdu->choice.initiatingMessage is NULL"
);
_F1_EQ_CHECK_LONG
(
pdu
->
choice
.
successfulOutcome
->
procedureCode
,
F1AP_ProcedureCode_id_Reset
);
_F1_EQ_CHECK_INT
(
pdu
->
choice
.
successfulOutcome
->
value
.
present
,
F1AP_SuccessfulOutcome__value_PR_ResetAcknowledge
);
/* Check presence of mandatory IEs */
F1AP_ResetAcknowledge_t
*
in
=
&
pdu
->
choice
.
successfulOutcome
->
value
.
choice
.
ResetAcknowledge
;
F1AP_ResetAcknowledgeIEs_t
*
ie
;
F1AP_LIB_FIND_IE
(
F1AP_ResetAcknowledgeIEs_t
,
ie
,
in
,
F1AP_ProtocolIE_ID_id_TransactionID
,
true
);
/* Loop over all IEs */
for
(
int
i
=
0
;
i
<
in
->
protocolIEs
.
list
.
count
;
i
++
)
{
AssertError
(
in
->
protocolIEs
.
list
.
array
[
i
]
!=
NULL
,
return
false
,
"in->protocolIEs.list.array[i] is NULL"
);
ie
=
in
->
protocolIEs
.
list
.
array
[
i
];
switch
(
ie
->
id
)
{
case
F1AP_ProtocolIE_ID_id_TransactionID
:
// (M) Transaction ID
_F1_EQ_CHECK_INT
(
ie
->
value
.
present
,
F1AP_ResetAcknowledgeIEs__value_PR_TransactionID
);
out
->
transaction_id
=
ie
->
value
.
choice
.
TransactionID
;
break
;
case
F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionListResAck
:
_F1_EQ_CHECK_INT
(
ie
->
value
.
present
,
F1AP_ResetAcknowledgeIEs__value_PR_UE_associatedLogicalF1_ConnectionListResAck
);
{
const
F1AP_UE_associatedLogicalF1_ConnectionListResAck_t
*
conn_list
=
&
ie
->
value
.
choice
.
UE_associatedLogicalF1_ConnectionListResAck
;
AssertError
(
conn_list
->
list
.
count
>
0
,
return
false
,
"no UEs for partially reset F1 interface
\n
"
);
out
->
num_ue_to_reset
=
conn_list
->
list
.
count
;
out
->
ue_to_reset
=
calloc_or_fail
(
out
->
num_ue_to_reset
,
sizeof
(
*
out
->
ue_to_reset
));
for
(
int
i
=
0
;
i
<
out
->
num_ue_to_reset
;
++
i
)
{
const
F1AP_UE_associatedLogicalF1_ConnectionItemResAck_t
*
it_res
=
(
const
F1AP_UE_associatedLogicalF1_ConnectionItemResAck_t
*
)
conn_list
->
list
.
array
[
i
];
_F1_EQ_CHECK_LONG
(
it_res
->
id
,
F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionItem
);
_F1_EQ_CHECK_INT
(
it_res
->
value
.
present
,
F1AP_UE_associatedLogicalF1_ConnectionItemResAck__value_PR_UE_associatedLogicalF1_ConnectionItem
);
out
->
ue_to_reset
[
i
]
=
decode_f1ap_ue_to_reset
(
&
it_res
->
value
.
choice
.
UE_associatedLogicalF1_ConnectionItem
);
}
}
break
;
default:
AssertError
(
true
,
return
false
,
"Reset Acknowledge: ProtocolIE id %ld not implemented, ignoring IE
\n
"
,
ie
->
id
);
break
;
}
}
return
true
;
}
void
free_f1ap_reset_ack
(
f1ap_reset_ack_t
*
msg
)
{
for
(
int
i
=
0
;
i
<
msg
->
num_ue_to_reset
;
++
i
)
free_f1ap_ue_to_reset
(
&
msg
->
ue_to_reset
[
i
]);
free
(
msg
->
ue_to_reset
);
}
bool
eq_f1ap_reset_ack
(
const
f1ap_reset_ack_t
*
a
,
const
f1ap_reset_ack_t
*
b
)
{
_F1_EQ_CHECK_LONG
(
a
->
transaction_id
,
b
->
transaction_id
);
_F1_EQ_CHECK_INT
(
a
->
num_ue_to_reset
,
b
->
num_ue_to_reset
);
for
(
int
i
=
0
;
i
<
a
->
num_ue_to_reset
;
++
i
)
{
if
(
!
eq_f1ap_ue_to_reset
(
&
a
->
ue_to_reset
[
i
],
&
b
->
ue_to_reset
[
i
]))
return
false
;
}
return
true
;
}
f1ap_reset_ack_t
cp_f1ap_reset_ack
(
const
f1ap_reset_ack_t
*
orig
)
{
f1ap_reset_ack_t
cp
=
{.
transaction_id
=
orig
->
transaction_id
,
.
num_ue_to_reset
=
orig
->
num_ue_to_reset
};
if
(
cp
.
num_ue_to_reset
>
0
)
{
cp
.
ue_to_reset
=
calloc_or_fail
(
cp
.
num_ue_to_reset
,
sizeof
(
*
cp
.
ue_to_reset
));
for
(
int
i
=
0
;
i
<
cp
.
num_ue_to_reset
;
++
i
)
cp
.
ue_to_reset
[
i
]
=
cp_f1ap_ue_to_reset
(
&
orig
->
ue_to_reset
[
i
]);
}
return
cp
;
}
static
const
int
nrb_lut
[
29
]
=
{
11
,
18
,
24
,
25
,
31
,
32
,
38
,
51
,
52
,
65
,
66
,
78
,
79
,
93
,
106
,
107
,
121
,
132
,
133
,
135
,
160
,
162
,
189
,
216
,
217
,
245
,
264
,
270
,
273
};
...
...
openair2/F1AP/lib/f1ap_interface_management.h
View file @
df365d9a
...
...
@@ -34,6 +34,13 @@ void free_f1ap_reset(f1ap_reset_t *msg);
bool
eq_f1ap_reset
(
const
f1ap_reset_t
*
a
,
const
f1ap_reset_t
*
b
);
f1ap_reset_t
cp_f1ap_reset
(
const
f1ap_reset_t
*
orig
);
/* F1 Reset Ack */
struct
F1AP_F1AP_PDU
*
encode_f1ap_reset_ack
(
const
f1ap_reset_ack_t
*
msg
);
bool
decode_f1ap_reset_ack
(
const
struct
F1AP_F1AP_PDU
*
pdu
,
f1ap_reset_ack_t
*
out
);
void
free_f1ap_reset_ack
(
f1ap_reset_ack_t
*
msg
);
bool
eq_f1ap_reset_ack
(
const
f1ap_reset_ack_t
*
a
,
const
f1ap_reset_ack_t
*
b
);
f1ap_reset_ack_t
cp_f1ap_reset_ack
(
const
f1ap_reset_ack_t
*
orig
);
struct
F1AP_F1AP_PDU
*
encode_f1ap_setup_request
(
const
f1ap_setup_req_t
*
msg
);
bool
decode_f1ap_setup_request
(
const
struct
F1AP_F1AP_PDU
*
pdu
,
f1ap_setup_req_t
*
out
);
f1ap_setup_req_t
cp_f1ap_setup_request
(
const
f1ap_setup_req_t
*
msg
);
...
...
openair2/F1AP/tests/f1ap_lib_test.c
View file @
df365d9a
...
...
@@ -447,6 +447,50 @@ static void test_f1ap_reset_part(void)
free_f1ap_reset
(
&
orig
);
}
/**
* @brief Test F1 reset ack with differently ack'd UEs ("generic ack" is
* special case with no individual UE acked)
*/
static
void
test_f1ap_reset_ack
(
void
)
{
f1ap_reset_ack_t
orig
=
{
.
transaction_id
=
4
,
.
num_ue_to_reset
=
4
,
};
orig
.
ue_to_reset
=
calloc_or_fail
(
orig
.
num_ue_to_reset
,
sizeof
(
*
orig
.
ue_to_reset
));
orig
.
ue_to_reset
[
0
].
gNB_CU_ue_id
=
malloc_or_fail
(
sizeof
(
*
orig
.
ue_to_reset
[
0
].
gNB_CU_ue_id
));
*
orig
.
ue_to_reset
[
0
].
gNB_CU_ue_id
=
10
;
orig
.
ue_to_reset
[
1
].
gNB_DU_ue_id
=
malloc_or_fail
(
sizeof
(
*
orig
.
ue_to_reset
[
1
].
gNB_DU_ue_id
));
*
orig
.
ue_to_reset
[
1
].
gNB_DU_ue_id
=
11
;
orig
.
ue_to_reset
[
2
].
gNB_CU_ue_id
=
malloc_or_fail
(
sizeof
(
*
orig
.
ue_to_reset
[
2
].
gNB_CU_ue_id
));
*
orig
.
ue_to_reset
[
2
].
gNB_CU_ue_id
=
12
;
orig
.
ue_to_reset
[
2
].
gNB_DU_ue_id
=
malloc_or_fail
(
sizeof
(
*
orig
.
ue_to_reset
[
2
].
gNB_DU_ue_id
));
*
orig
.
ue_to_reset
[
2
].
gNB_DU_ue_id
=
13
;
// orig.ue_to_reset[3] intentionally empty (because it is allowed, both IDs are optional)
F1AP_F1AP_PDU_t
*
f1enc
=
encode_f1ap_reset_ack
(
&
orig
);
F1AP_F1AP_PDU_t
*
f1dec
=
f1ap_encode_decode
(
f1enc
);
f1ap_msg_free
(
f1enc
);
f1ap_reset_ack_t
decoded
=
{
0
};
bool
ret
=
decode_f1ap_reset_ack
(
f1dec
,
&
decoded
);
AssertFatal
(
ret
,
"decode_f1ap_reset_ack(): could not decode message
\n
"
);
f1ap_msg_free
(
f1dec
);
ret
=
eq_f1ap_reset_ack
(
&
orig
,
&
decoded
);
AssertFatal
(
ret
,
"eq_f1ap_reset_ack(): decoded message doesn't match original
\n
"
);
free_f1ap_reset_ack
(
&
decoded
);
f1ap_reset_ack_t
cp
=
cp_f1ap_reset_ack
(
&
orig
);
ret
=
eq_f1ap_reset_ack
(
&
orig
,
&
cp
);
AssertFatal
(
ret
,
"eq_f1ap_reset_ack(): copied message doesn't match original
\n
"
);
free_f1ap_reset_ack
(
&
cp
);
printf
(
"f1ap_reset_ack successful
\n
"
);
free_f1ap_reset_ack
(
&
orig
);
}
/**
* @brief Test F1 gNB-DU Configuration Update
*/
...
...
@@ -671,6 +715,7 @@ int main()
test_f1ap_setup_failure
();
test_f1ap_reset_all
();
test_f1ap_reset_part
();
test_f1ap_reset_ack
();
test_f1ap_du_configuration_update
();
test_f1ap_cu_configuration_update
();
test_f1ap_cu_configuration_update_acknowledge
();
...
...
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