diff --git a/CMakeLists.txt b/CMakeLists.txt index 06184ac619b2843b9933b445f1acc38a04b4ffa4..0f9e7a8db94a2470fcf8e10f773787f1a96721ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2803,7 +2803,8 @@ target_link_libraries (nr-softmodem -Wl,--end-group z dl) target_link_libraries (nr-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-softmodem pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-softmodem pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES} + ${OPENAIR_DIR}/executables/agent_if/libe2_agent.a) target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) diff --git a/executables/agent_if/README.md b/executables/agent_if/README.md new file mode 100644 index 0000000000000000000000000000000000000000..015b54ec9e2712d534258c6531d0ea1a3cb926b2 --- /dev/null +++ b/executables/agent_if/README.md @@ -0,0 +1 @@ +Bad design decision. Fix it after the Hackfest!!! diff --git a/executables/agent_if/ans/sm_ag_if_ans.h b/executables/agent_if/ans/sm_ag_if_ans.h new file mode 100644 index 0000000000000000000000000000000000000000..b28f70f69f0225bdbb33ee333ed935da790a62f2 --- /dev/null +++ b/executables/agent_if/ans/sm_ag_if_ans.h @@ -0,0 +1,58 @@ +/* + * 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 SM_ANSWER_INTERFACE_H +#define SM_ANSWER_INTERFACE_H + + +#include "../ie/mac_data_ie.h" +#include "../ie/rlc_data_ie.h" +#include "../ie/pdcp_data_ie.h" +#include "../ie/slice_data_ie.h" + + + +typedef enum{ + PDCP_AGENT_IF_CTRL_ANS_V0, + RLC_AGENT_IF_CTRL_ANS_V0, + MAC_AGENT_IF_CTRL_ANS_V0, + SLICE_AGENT_IF_CTRL_ANS_V0, + + SM_AGENT_IF_ANS_V0_END, +} sm_ag_if_ans_e; + +typedef struct{ + union { + mac_ctrl_out_t mac; + rlc_ctrl_out_t rlc; + pdcp_ctrl_out_t pdcp; + slice_ctrl_out_t slice; + }; + sm_ag_if_ans_e type; +} sm_ag_if_ans_t; + + + + +#endif + diff --git a/executables/agent_if/e2_agent_api.h b/executables/agent_if/e2_agent_api.h new file mode 100644 index 0000000000000000000000000000000000000000..654ae3c2e740c9c82a533e31f835028cd06edb97 --- /dev/null +++ b/executables/agent_if/e2_agent_api.h @@ -0,0 +1,17 @@ +#ifndef E2_AGENT_API_MOSAIC_H +#define E2_AGENT_API_MOSAIC_H + +#include "sm_io.h" + + +void init_agent_api(const char* server_ip_str, + int mcc, + int mnc, + int mnc_digit_len, + int nb_id, + sm_io_ag_t io); + +void stop_agent_api(void); + +#endif + diff --git a/executables/agent_if/ie/mac_data_ie.h b/executables/agent_if/ie/mac_data_ie.h new file mode 100644 index 0000000000000000000000000000000000000000..c9dbee6cf818dc968b3506f12430ca99f0bb9d39 --- /dev/null +++ b/executables/agent_if/ie/mac_data_ie.h @@ -0,0 +1,257 @@ +#ifndef MAC_DATA_INFORMATION_ELEMENTS_H +#define MAC_DATA_INFORMATION_ELEMENTS_H + +/* + * 9 Information Elements (IE) , RIC Event Trigger Definition, RIC Action Definition, RIC Indication Header, RIC Indication Message, RIC Call Process ID, RIC Control Header, RIC Control Message, RIC Control Outcome and RAN Function Definition defined by ORAN-WG3.E2SM-v01.00.00 at Section 5 + */ + + +#include <stdbool.h> +#include <stdint.h> + +////////////////////////////////////// +// RIC Event Trigger Definition +///////////////////////////////////// + +typedef struct { + uint32_t ms; +} mac_event_trigger_t; + +void free_mac_event_trigger(mac_event_trigger_t* src); + +mac_event_trigger_t cp_mac_event_trigger( mac_event_trigger_t* src); + +bool eq_mac_event_trigger(mac_event_trigger_t* m0, mac_event_trigger_t* m1); + + + +////////////////////////////////////// +// RIC Action Definition +///////////////////////////////////// + + +typedef struct { + uint32_t dummy; +} mac_action_def_t; + +void free_mac_action_def(mac_action_def_t* src); + +mac_action_def_t cp_mac_action_def(mac_action_def_t* src); + +bool eq_mac_action_def(mac_event_trigger_t* m0, mac_event_trigger_t* m1); + + + +////////////////////////////////////// +// RIC Indication Header +///////////////////////////////////// + + +typedef struct{ + uint32_t dummy; +} mac_ind_hdr_t; + +void free_mac_ind_hdr(mac_ind_hdr_t* src); + +mac_ind_hdr_t cp_mac_ind_hdr(mac_ind_hdr_t* src); + +bool eq_mac_ind_hdr(mac_ind_hdr_t* m0, mac_ind_hdr_t* m1); + +////////////////////////////////////// +// RIC Indication Message +///////////////////////////////////// + +typedef struct +{ + uint64_t dl_aggr_tbs; + uint64_t ul_aggr_tbs; + uint64_t dl_aggr_bytes_sdus; + uint64_t ul_aggr_bytes_sdus; + uint64_t dl_curr_tbs; + uint64_t ul_curr_tbs; + uint64_t dl_sched_rb; + uint64_t ul_sched_rb; + + float pusch_snr; //: float = -64; + float pucch_snr; //: float = -64; + + uint32_t rnti; + uint32_t dl_aggr_prb; + uint32_t ul_aggr_prb; + uint32_t dl_aggr_sdus; + uint32_t ul_aggr_sdus; + uint32_t dl_aggr_retx_prb; + uint32_t ul_aggr_retx_prb; + + uint8_t wb_cqi; + uint8_t dl_mcs1; + uint8_t ul_mcs1; + uint8_t dl_mcs2; + uint8_t ul_mcs2; + int8_t phr; + uint32_t bsr; + float dl_bler; + float ul_bler; + + int dl_num_harq; + int ul_num_harq; + uint32_t dl_harq[5]; + uint32_t ul_harq[5]; + + int16_t frame; + int16_t slot; +} mac_ue_stats_impl_t; + +typedef struct { + uint32_t len_ue_stats; + mac_ue_stats_impl_t* ue_stats; + int64_t tstamp; +} mac_ind_msg_t; + +void free_mac_ind_msg(mac_ind_msg_t* src); + +mac_ind_msg_t cp_mac_ind_msg(mac_ind_msg_t* src); + +bool eq_mac_ind_msg(mac_ind_msg_t* m0, mac_ind_msg_t* m1); + + +////////////////////////////////////// +// RIC Call Process ID +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} mac_call_proc_id_t; + +void free_mac_call_proc_id( mac_call_proc_id_t* src); + +mac_call_proc_id_t cp_mac_call_proc_id( mac_call_proc_id_t* src); + +bool eq_mac_call_proc_id(mac_call_proc_id_t* m0, mac_call_proc_id_t* m1); + +////////////////////////////////////// +// RIC Control Header +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} mac_ctrl_hdr_t; + +void free_mac_ctrl_hdr( mac_ctrl_hdr_t* src); + +mac_ctrl_hdr_t cp_mac_ctrl_hdr(mac_ctrl_hdr_t* src); + +bool eq_mac_ctrl_hdr(mac_ctrl_hdr_t* m0, mac_ctrl_hdr_t* m1); + +////////////////////////////////////// +// RIC Control Message +///////////////////////////////////// + +typedef struct { + uint32_t action; +} mac_ctrl_msg_t; + +void free_mac_ctrl_msg( mac_ctrl_msg_t* src); + +mac_ctrl_msg_t cp_mac_ctrl_msg(mac_ctrl_msg_t* src); + +bool eq_mac_ctrl_msg(mac_ctrl_msg_t* m0, mac_ctrl_msg_t* m1); + + +////////////////////////////////////// +// RIC Control Outcome +///////////////////////////////////// + +typedef enum{ + MAC_CTRL_OUT_OK, + + + MAC_CTRL_OUT_END +} mac_ctrl_out_e; + +typedef struct { + mac_ctrl_out_e ans; +} mac_ctrl_out_t; + +void free_mac_ctrl_out(mac_ctrl_out_t* src); + +mac_ctrl_out_t cp_mac_ctrl_out(mac_ctrl_out_t* src); + +bool eq_mac_ctrl_out(mac_ctrl_out_t* m0, mac_ctrl_out_t* m1); + + +////////////////////////////////////// +// RAN Function Definition +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} mac_func_def_t; + +void free_mac_func_def( mac_func_def_t* src); + +mac_func_def_t cp_mac_func_def(mac_func_def_t* src); + +bool eq_mac_func_def(mac_func_def_t* m0, mac_func_def_t* m1); + + +///////////////////////////////////////////////// +////////////////////////////////////////////////// +///////////////////////////////////////////////// + + +/* + * O-RAN defined 5 Procedures: RIC Subscription, RIC Indication, RIC Control, E2 Setup and RIC Service Update + * */ + + +/////////////// +/// RIC Subscription +/////////////// + +typedef struct{ + mac_event_trigger_t et; + mac_action_def_t* ad; +} mac_sub_data_t; + +/////////////// +// RIC Indication +/////////////// + +typedef struct{ + mac_ind_hdr_t hdr; + mac_ind_msg_t msg; + mac_call_proc_id_t* proc_id; +} mac_ind_data_t; + +/////////////// +// RIC Control +/////////////// + +typedef struct{ + mac_ctrl_hdr_t hdr; + mac_ctrl_msg_t msg; +} mac_ctrl_req_data_t; + +typedef struct{ + mac_ctrl_out_t* out; +} mac_ctrl_out_data_t; + +/////////////// +// E2 Setup +/////////////// + +typedef struct{ + mac_func_def_t func_def; +} mac_e2_setup_data_t; + +/////////////// +// RIC Service Update +/////////////// + +typedef struct{ + mac_func_def_t func_def; +} mac_ric_service_update_t; + +#endif + diff --git a/executables/agent_if/ie/pdcp_data_ie.h b/executables/agent_if/ie/pdcp_data_ie.h new file mode 100644 index 0000000000000000000000000000000000000000..67ffd27cc4a6dd116dcbb6145821ce460b0964ae --- /dev/null +++ b/executables/agent_if/ie/pdcp_data_ie.h @@ -0,0 +1,257 @@ +/* + * 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 PDCP_DATA_INFORMATION_ELEMENTS_H +#define PDCP_DATA_INFORMATION_ELEMENTS_H + +/* + * 9 Information Elements (IE) , RIC Event Trigger Definition, RIC Action Definition, RIC Indication Header, RIC Indication Message, RIC Call Process ID, RIC Control Header, RIC Control Message, RIC Control Outcome and RAN Function Definition defined by ORAN-WG3.E2SM-v01.00.00 at Section 5 + */ + +#include <stdbool.h> +#include <stdint.h> + + +////////////////////////////////////// +// RIC Event Trigger Definition +///////////////////////////////////// + +typedef struct { + uint32_t ms; +} pdcp_event_trigger_t; + +void free_pdcp_event_trigger(pdcp_event_trigger_t* src); + +pdcp_event_trigger_t cp_pdcp_event_trigger( pdcp_event_trigger_t* src); + +bool eq_pdcp_event_trigger(pdcp_event_trigger_t* m0, pdcp_event_trigger_t* m1); + +////////////////////////////////////// +// RIC Action Definition +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} pdcp_action_def_t; + +void free_pdcp_action_def(pdcp_action_def_t* src); + +pdcp_action_def_t cp_pdcp_action_def(pdcp_action_def_t* src); + +bool eq_pdcp_action_def(pdcp_event_trigger_t* m0, pdcp_event_trigger_t* m1); + +////////////////////////////////////// +// RIC Indication Header +///////////////////////////////////// + +typedef struct{ + uint32_t dummy; +} pdcp_ind_hdr_t; + +void free_pdcp_ind_hdr(pdcp_ind_hdr_t* src); + +pdcp_ind_hdr_t cp_pdcp_ind_hdr(pdcp_ind_hdr_t* src); + +bool eq_pdcp_ind_hdr(pdcp_ind_hdr_t* m0, pdcp_ind_hdr_t* m1); + +////////////////////////////////////// +// RIC Indication Message +///////////////////////////////////// + +typedef struct{ + uint32_t txpdu_pkts; /* aggregated number of tx packets */ + uint32_t txpdu_bytes; /* aggregated bytes of tx packets */ + uint32_t txpdu_sn; /* current sequence number of last tx packet (or TX_NEXT) */ + uint32_t rxpdu_pkts; /* aggregated number of rx packets */ + uint32_t rxpdu_bytes; /* aggregated bytes of rx packets */ + uint32_t rxpdu_sn; /* current sequence number of last rx packet (or RX_NEXT) */ + uint32_t rxpdu_oo_pkts; /* aggregated number of out-of-order rx pkts (or RX_REORD) */ + uint32_t rxpdu_oo_bytes; /* aggregated amount of out-of-order rx bytes */ + uint32_t rxpdu_dd_pkts; /* aggregated number of duplicated discarded packets */ + uint32_t rxpdu_dd_bytes; /* aggregated amount of discarded packets' bytes */ + uint32_t rxpdu_ro_count; /* this state variable indicates the COUNT value */ + uint32_t txsdu_pkts; /* number of SDUs delivered */ + uint32_t txsdu_bytes; /* number of bytes of SDUs delivered */ + uint32_t rxsdu_pkts; /* number of SDUs received */ + uint32_t rxsdu_bytes; /* number of bytes of SDUs received */ + uint32_t rnti; + uint8_t mode; /* 0: PDCP AM, 1: PDCP UM, 2: PDCP TM */ + uint8_t rbid; +} pdcp_radio_bearer_stats_t; + +typedef struct { + uint32_t len; + pdcp_radio_bearer_stats_t* rb; + int64_t tstamp; + +// uint16_t frame; +// uint8_t slot; +} pdcp_ind_msg_t; + +void free_pdcp_ind_msg(pdcp_ind_msg_t* msg); + +pdcp_ind_msg_t cp_pdcp_ind_msg(pdcp_ind_msg_t* src); + +bool eq_pdcp_ind_msg(pdcp_ind_msg_t* m0, pdcp_ind_msg_t* m1); + +////////////////////////////////////// +// RIC Call Process ID +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} pdcp_call_proc_id_t; + +void free_pdcp_call_proc_id( pdcp_call_proc_id_t* src); + +pdcp_call_proc_id_t cp_pdcp_call_proc_id( pdcp_call_proc_id_t* src); + +bool eq_pdcp_call_proc_id(pdcp_call_proc_id_t* m0, pdcp_call_proc_id_t* m1); + + +////////////////////////////////////// +// RIC Control Header +///////////////////////////////////// + + +typedef struct { + uint32_t dummy; +} pdcp_ctrl_hdr_t; + +void free_pdcp_ctrl_hdr( pdcp_ctrl_hdr_t* src); + +pdcp_ctrl_hdr_t cp_pdcp_ctrl_hdr(pdcp_ctrl_hdr_t* src); + +bool eq_pdcp_ctrl_hdr(pdcp_ctrl_hdr_t* m0, pdcp_ctrl_hdr_t* m1); + +////////////////////////////////////// +// RIC Control Message +///////////////////////////////////// + +typedef struct { + uint32_t action; +} pdcp_ctrl_msg_t; + +void free_pdcp_ctrl_msg( pdcp_ctrl_msg_t* src); + +pdcp_ctrl_msg_t cp_pdcp_ctrl_msg(pdcp_ctrl_msg_t* src); + +bool eq_pdcp_ctrl_msg(pdcp_ctrl_msg_t* m0, pdcp_ctrl_msg_t* m1); + +////////////////////////////////////// +// RIC Control Outcome +///////////////////////////////////// + +typedef enum{ + PDCP_CTRL_OUT_OK, + + + PDCP_CTRL_OUT_END +} pdcp_ctrl_out_e; + +typedef struct { + pdcp_ctrl_out_e ans; +} pdcp_ctrl_out_t; + +void free_pdcp_ctrl_out(pdcp_ctrl_out_t* src); + +pdcp_ctrl_out_t cp_pdcp_ctrl_out(pdcp_ctrl_out_t* src); + +bool eq_pdcp_ctrl_out(pdcp_ctrl_out_t* m0, pdcp_ctrl_out_t* m1); + + +////////////////////////////////////// +// RAN Function Definition +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} pdcp_func_def_t; + +void free_pdcp_func_def( pdcp_func_def_t* src); + +pdcp_func_def_t cp_pdcp_func_def(pdcp_func_def_t* src); + +bool eq_pdcp_func_def(pdcp_func_def_t* m0, pdcp_func_def_t* m1); + +///////////////////////////////////////////////// +////////////////////////////////////////////////// +///////////////////////////////////////////////// + + +/* + * O-RAN defined 5 Procedures: RIC Subscription, RIC Indication, RIC Control, E2 Setup and RIC Service Update + * */ + + +/////////////// +/// RIC Subscription +/////////////// + +typedef struct{ + pdcp_event_trigger_t et; + pdcp_action_def_t* ad; +} pdcp_sub_data_t; + + +/////////////// +// RIC Indication +/////////////// + +typedef struct{ + pdcp_ind_hdr_t hdr; + pdcp_ind_msg_t msg; + pdcp_call_proc_id_t* proc_id; +} pdcp_ind_data_t; + +/////////////// +// RIC Control +/////////////// + +typedef struct{ + pdcp_ctrl_hdr_t hdr; + pdcp_ctrl_msg_t msg; +} pdcp_ctrl_req_data_t; + +typedef struct{ + pdcp_ctrl_out_t* out; +} pdcp_ctrl_out_data_t; + +/////////////// +// E2 Setup +/////////////// + +typedef struct{ + pdcp_func_def_t func_def; +} pdcp_e2_setup_data_t; + +/////////////// +// RIC Service Update +/////////////// + +typedef struct{ + pdcp_func_def_t func_def; +} pdcp_ric_service_update_t; + +#endif + diff --git a/executables/agent_if/ie/rlc_data_ie.h b/executables/agent_if/ie/rlc_data_ie.h new file mode 100644 index 0000000000000000000000000000000000000000..3c703be088fbf2f13e488b770d61ac398f3a974b --- /dev/null +++ b/executables/agent_if/ie/rlc_data_ie.h @@ -0,0 +1,308 @@ +/* + * 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 RLC_DATA_INFORMATION_ELEMENTS_H +#define RLC_DATA_INFORMATION_ELEMENTS_H + + +/* + * 9 Information Elements (IE) , RIC Event Trigger Definition, RIC Action Definition, RIC Indication Header, RIC Indication Message, RIC Call Process ID, RIC Control Header, RIC Control Message, RIC Control Outcome and RAN Function Definition defined by ORAN-WG3.E2SM-v01.00.00 at Section 5 + */ + +#include <stdbool.h> +#include <stdint.h> + +////////////////////////////////////// +// RIC Event Trigger Definition +///////////////////////////////////// + +typedef struct { + uint32_t ms; +} rlc_event_trigger_t; + +void free_rlc_event_trigger(rlc_event_trigger_t* src); + +rlc_event_trigger_t cp_rlc_event_trigger( rlc_event_trigger_t* src); + +bool eq_rlc_event_trigger(rlc_event_trigger_t* m0, rlc_event_trigger_t* m1); + + + +////////////////////////////////////// +// RIC Action Definition +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} rlc_action_def_t; + +void free_rlc_action_def(rlc_action_def_t* src); + +rlc_action_def_t cp_rlc_action_def(rlc_action_def_t* src); + +bool eq_rlc_action_def(rlc_event_trigger_t* m0, rlc_event_trigger_t* m1); + + + +////////////////////////////////////// +// RIC Indication Header +///////////////////////////////////// + +typedef struct{ + uint32_t dummy; +} rlc_ind_hdr_t; + +void free_rlc_ind_hdr(rlc_ind_hdr_t* src); + +rlc_ind_hdr_t cp_rlc_ind_hdr(rlc_ind_hdr_t* src); + +bool eq_rlc_ind_hdr(rlc_ind_hdr_t* m0, rlc_ind_hdr_t* m1); + + + + +////////////////////////////////////// +// RIC Indication Message +///////////////////////////////////// + +typedef struct { + /* PDU stats */ + /* TX */ + uint32_t txpdu_pkts; /* aggregated number of transmitted RLC PDUs */ + uint32_t txpdu_bytes; /* aggregated amount of transmitted bytes in RLC PDUs */ + /* TODO? */ + uint32_t txpdu_wt_ms; /* aggregated head-of-line tx packet waiting time to be transmitted (i.e. send to the MAC layer) */ + uint32_t txpdu_dd_pkts; /* aggregated number of dropped or discarded tx packets by RLC */ + uint32_t txpdu_dd_bytes; /* aggregated amount of bytes dropped or discarded tx packets by RLC */ + uint32_t txpdu_retx_pkts; /* aggregated number of tx pdus/pkts to be re-transmitted (only applicable to RLC AM) */ + uint32_t txpdu_retx_bytes; /* aggregated amount of bytes to be re-transmitted (only applicable to RLC AM) */ + uint32_t txpdu_segmented; /* aggregated number of segmentations */ + uint32_t txpdu_status_pkts; /* aggregated number of tx status pdus/pkts (only applicable to RLC AM) */ + uint32_t txpdu_status_bytes; /* aggregated amount of tx status bytes (only applicable to RLC AM) */ + /* TODO? */ + uint32_t txbuf_occ_bytes; /* current tx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */ + /* TODO? */ + uint32_t txbuf_occ_pkts; /* current tx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */ + /* txbuf_wd_ms: the time window for which the txbuf occupancy value is obtained - NOT IMPLEMENTED */ + + /* RX */ + uint32_t rxpdu_pkts; /* aggregated number of received RLC PDUs */ + uint32_t rxpdu_bytes; /* amount of bytes received by the RLC */ + uint32_t rxpdu_dup_pkts; /* aggregated number of duplicate packets */ + uint32_t rxpdu_dup_bytes; /* aggregated amount of duplicated bytes */ + uint32_t rxpdu_dd_pkts; /* aggregated number of rx packets dropped or discarded by RLC */ + uint32_t rxpdu_dd_bytes; /* aggregated amount of rx bytes dropped or discarded by RLC */ + uint32_t rxpdu_ow_pkts; /* aggregated number of out of window received RLC pdu */ + uint32_t rxpdu_ow_bytes; /* aggregated number of out of window bytes received RLC pdu */ + uint32_t rxpdu_status_pkts; /* aggregated number of rx status pdus/pkts (only applicable to RLC AM) */ + uint32_t rxpdu_status_bytes; /* aggregated amount of rx status bytes (only applicable to RLC AM) */ + /* rxpdu_rotout_ms: flag indicating rx reordering timeout in ms - NOT IMPLEMENTED */ + /* rxpdu_potout_ms: flag indicating the poll retransmit time out in ms - NOT IMPLEMENTED */ + /* rxpdu_sptout_ms: flag indicating status prohibit timeout in ms - NOT IMPLEMENTED */ + /* TODO? */ + uint32_t rxbuf_occ_bytes; /* current rx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */ + /* TODO? */ + uint32_t rxbuf_occ_pkts; /* current rx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */ + + /* SDU stats */ + /* TX */ + uint32_t txsdu_pkts; /* number of SDUs delivered */ + uint32_t txsdu_bytes; /* number of bytes of SDUs delivered */ + + /* RX */ + uint32_t rxsdu_pkts; /* number of SDUs received */ + uint32_t rxsdu_bytes; /* number of bytes of SDUs received */ + uint32_t rxsdu_dd_pkts; /* number of dropped or discarded SDUs */ + uint32_t rxsdu_dd_bytes; /* number of bytes of SDUs dropped or discarded */ + + uint32_t rnti; + uint8_t mode; /* 0: RLC AM, 1: RLC UM, 2: RLC TM */ + uint8_t rbid; + +} rlc_radio_bearer_stats_t; + +typedef struct { + rlc_radio_bearer_stats_t* rb; + uint32_t len; + + int64_t tstamp; +// uint16_t frame; +// uint8_t slot; +} rlc_ind_msg_t; + +void free_rlc_ind_msg(rlc_ind_msg_t* src); + +rlc_ind_msg_t cp_rlc_ind_msg(rlc_ind_msg_t* src); + +bool eq_rlc_ind_msg(rlc_ind_msg_t* m0, rlc_ind_msg_t* m1); + + +////////////////////////////////////// +// RIC Call Process ID +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} rlc_call_proc_id_t; + +void free_rlc_call_proc_id( rlc_call_proc_id_t* src); + +rlc_call_proc_id_t cp_rlc_call_proc_id( rlc_call_proc_id_t* src); + +bool eq_rlc_call_proc_id(rlc_call_proc_id_t* m0, rlc_call_proc_id_t* m1); + + + +////////////////////////////////////// +// RIC Control Header +///////////////////////////////////// + + +typedef struct { + uint32_t dummy; +} rlc_ctrl_hdr_t; + +void free_rlc_ctrl_hdr( rlc_ctrl_hdr_t* src); + +rlc_ctrl_hdr_t cp_rlc_ctrl_hdr(rlc_ctrl_hdr_t* src); + +bool eq_rlc_ctrl_hdr(rlc_ctrl_hdr_t* m0, rlc_ctrl_hdr_t* m1); + + + +////////////////////////////////////// +// RIC Control Message +///////////////////////////////////// + + +typedef struct { + uint32_t action; +} rlc_ctrl_msg_t; + +void free_rlc_ctrl_msg( rlc_ctrl_msg_t* src); + +rlc_ctrl_msg_t cp_rlc_ctrl_msg(rlc_ctrl_msg_t* src); + +bool eq_rlc_ctrl_msg(rlc_ctrl_msg_t* m0, rlc_ctrl_msg_t* m1); + + + +////////////////////////////////////// +// RIC Control Outcome +///////////////////////////////////// + +typedef enum{ + RLC_CTRL_OUT_OK, + + RLC_CTRL_OUT_END +} rlc_ctrl_out_e; + + +typedef struct { + rlc_ctrl_out_e ans; +} rlc_ctrl_out_t; + +void free_rlc_ctrl_out(rlc_ctrl_out_t* src); + +rlc_ctrl_out_t cp_rlc_ctrl_out(rlc_ctrl_out_t* src); + +bool eq_rlc_ctrl_out(rlc_ctrl_out_t* m0, rlc_ctrl_out_t* m1); + + +////////////////////////////////////// +// RAN Function Definition +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} rlc_func_def_t; + +void free_rlc_func_def( rlc_func_def_t* src); + +rlc_func_def_t cp_rlc_func_def(rlc_func_def_t* src); + +bool eq_rlc_func_def(rlc_func_def_t* m0, rlc_func_def_t* m1); + +///////////////////////////////////////////////// +////////////////////////////////////////////////// +///////////////////////////////////////////////// + + +/* + * O-RAN defined 5 Procedures: RIC Subscription, RIC Indication, RIC Control, E2 Setup and RIC Service Update + * */ + + +/////////////// +/// RIC Subscription +/////////////// + +typedef struct{ + rlc_event_trigger_t et; + rlc_action_def_t* ad; +} rlc_sub_data_t; + +/////////////// +// RIC Indication +/////////////// + +typedef struct{ + rlc_ind_hdr_t hdr; + rlc_ind_msg_t msg; + rlc_call_proc_id_t* proc_id; +} rlc_ind_data_t; + +/////////////// +// RIC Control +/////////////// + +typedef struct{ + rlc_ctrl_hdr_t hdr; + rlc_ctrl_msg_t msg; +} rlc_ctrl_req_data_t; + +typedef struct{ + rlc_ctrl_out_t* out; +} rlc_ctrl_out_data_t; + +/////////////// +// E2 Setup +/////////////// + +typedef struct{ + rlc_func_def_t func_def; +} rlc_e2_setup_data_t; + +/////////////// +// RIC Service Update +/////////////// + +typedef struct{ + rlc_func_def_t func_def; +} rlc_ric_service_update_t; + + + + + + +#endif + diff --git a/executables/agent_if/ie/slice_data_ie.h b/executables/agent_if/ie/slice_data_ie.h new file mode 100644 index 0000000000000000000000000000000000000000..c772ff6e3aa50f77566dc42f24dfb961a705e811 --- /dev/null +++ b/executables/agent_if/ie/slice_data_ie.h @@ -0,0 +1,519 @@ +/* + * 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 SLICE_DATA_INFORMATION_ELEMENTS_H +#define SLICE_DATA_INFORMATION_ELEMENTS_H + +/* + * 9 Information Elements (IE) , RIC Event Trigger Definition, RIC Action Definition, RIC Indication Header, RIC Indication Message, RIC Call Process ID, RIC Control Header, RIC Control Message, RIC Control Outcome and RAN Function Definition defined by ORAN-WG3.E2SM-v01.00.00 at Section 5 + */ + +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> + + +static_assert(sizeof(float) == 4, "Assumption that float types are 4 bytes long invalid. Check where the float type is used"); + +////////////////////////////////////// +// RIC Event Trigger Definition +///////////////////////////////////// + +typedef struct { + uint32_t ms; +} slice_event_trigger_t; + +void free_slice_event_trigger(slice_event_trigger_t* src); + +slice_event_trigger_t cp_slice_event_trigger( slice_event_trigger_t* src); + +bool eq_slice_event_trigger(slice_event_trigger_t* m0, slice_event_trigger_t* m1); + + + +////////////////////////////////////// +// RIC Action Definition +///////////////////////////////////// + +typedef struct { + +} slice_action_def_t; + +void free_slice_action_def(slice_action_def_t* src); + +slice_action_def_t cp_slice_action_def(slice_action_def_t* src); + +bool eq_slice_action_def(slice_event_trigger_t* m0, slice_event_trigger_t* m1); + + + +////////////////////////////////////// +// RIC Indication Header +///////////////////////////////////// + +typedef struct{ + uint32_t dummy; +} slice_ind_hdr_t; + +void free_slice_ind_hdr(slice_ind_hdr_t* src); + +slice_ind_hdr_t cp_slice_ind_hdr(slice_ind_hdr_t* src); + +bool eq_slice_ind_hdr(slice_ind_hdr_t* m0, slice_ind_hdr_t* m1); + + + +////////////////////////////////////// +// RIC Indication Message +///////////////////////////////////// + + +typedef enum{ + SLICE_ALG_SM_V0_NONE = 0, + SLICE_ALG_SM_V0_STATIC = 1, + SLICE_ALG_SM_V0_NVS = 2, + SLICE_ALG_SM_V0_SCN19 = 3, + SLICE_ALG_SM_V0_EDF = 4, + + SLICE_ALG_SM_V0_END +} slice_algorithm_e; + + +typedef struct{ + uint32_t pos_low; + uint32_t pos_high; +} static_slice_t ; + + +typedef enum { + SLICE_SM_NVS_V0_RATE, + SLICE_SM_NVS_V0_CAPACITY, + + SLICE_SM_NVS_V0_END +} nvs_slice_conf_e; + +/* +typedef struct{ + union{ + uint8_t mbps_required_byte[4]; + float mbps_required; + }; + union{ + uint8_t mbps_reference_byte[4]; + float mbps_reference; + }; +} nvs_rate_t ; +*/ + typedef union { + uint8_t mbps_required_byte[4]; + float mbps_required; + } nvs_rate_req_u; + + typedef union { + uint8_t mbps_reference_byte[4]; + float mbps_reference; + } nvs_rate_ref_u; + + + typedef struct{ + nvs_rate_req_u u1; + nvs_rate_ref_u u2; + } nvs_rate_t ; + + + +/* +typedef struct{ + union{ + uint8_t pct_reserved_byte[4]; + float pct_reserved; + }; +} nvs_capacity_t; + +typedef struct{ + nvs_slice_conf_e conf; + union{ + nvs_rate_t rate; + nvs_capacity_t capacity; + }; +} nvs_slice_t ; +*/ + + typedef union{ + uint8_t pct_reserved_byte[4]; + float pct_reserved; + } nvs_capacity_u; + + typedef struct{ + nvs_capacity_u u; + } nvs_capacity_t; + + typedef union{ + nvs_rate_t rate; + nvs_capacity_t capacity; + } nvs_slice_u; + + + typedef struct{ + nvs_slice_conf_e conf; + nvs_slice_u u; + } nvs_slice_t ; + + + + +typedef enum{ + SLICE_SCN19_SM_V0_DYNAMIC, + SLICE_SCN19_SM_V0_FIXED, + SLICE_SCN19_SM_V0_ON_DEMAND, + + SLICE_SCN19_SM_V0_END, +} scn19_slice_conf_e ; + +/* +typedef struct{ + union{ + uint8_t pct_reserved_byte[4]; + float pct_reserved; + }; + union{ + uint8_t log_delta_byte; + float log_delta; + }; + uint32_t tau; +} scn19_on_demand_t ; +*/ + + typedef struct{ + float pct_reserved; + float log_delta; + uint32_t tau; + } scn19_on_demand_t ; + + + +/* +typedef struct{ + scn19_slice_conf_e conf; + union{ + nvs_rate_t dynamic; + static_slice_t fixed; + scn19_on_demand_t on_demand; + }; +} scn19_slice_t; +*/ + + typedef union{ + nvs_rate_t dynamic; + static_slice_t fixed; + scn19_on_demand_t on_demand; + } scn19_slice_u; + + typedef struct{ + scn19_slice_conf_e conf; + scn19_slice_u u; + } scn19_slice_t; + + + + + + +typedef struct{ + uint32_t deadline; + uint32_t guaranteed_prbs; + uint32_t max_replenish; + uint32_t len_over; + uint32_t* over; +} edf_slice_t ; + +/* +typedef struct{ + slice_algorithm_e type; + union{ + static_slice_t sta; + nvs_slice_t nvs; + scn19_slice_t scn19; + edf_slice_t edf; + } ; +} slice_params_t; +*/ + + typedef union{ + static_slice_t sta; + nvs_slice_t nvs; + scn19_slice_t scn19; + edf_slice_t edf; + } slice_params_u; + + + typedef struct{ + slice_algorithm_e type; + slice_params_u u; + } slice_params_t; + + + + + + +typedef struct{ + uint32_t id; + + uint32_t len_label; + char* label; + + uint32_t len_sched; + char* sched; + + slice_params_t params; +} fr_slice_t ; + +typedef struct{ + uint32_t len_slices; + fr_slice_t* slices; + + uint32_t len_sched_name; + char* sched_name; +} ul_dl_slice_conf_t ; + +typedef struct{ + ul_dl_slice_conf_t dl; + ul_dl_slice_conf_t ul; +} slice_conf_t ; + +typedef struct{ + uint32_t dl_id; + uint32_t ul_id; + uint16_t rnti; +}ue_slice_assoc_t; + +typedef struct{ + uint32_t len_ue_slice; + ue_slice_assoc_t * ues; +} ue_slice_conf_t; + + +typedef struct { + slice_conf_t slice_conf; + ue_slice_conf_t ue_slice_conf; + int64_t tstamp; +} slice_ind_msg_t; + +void free_slice_ind_msg(slice_ind_msg_t* src); + +slice_ind_msg_t cp_slice_ind_msg(slice_ind_msg_t* src); + +bool eq_slice_ind_msg(slice_ind_msg_t const* m0, slice_ind_msg_t const* m1); + + + +////////////////////////////////////// +// RIC Call Process ID +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} slice_call_proc_id_t; + +void free_slice_call_proc_id( slice_call_proc_id_t* src); + +slice_call_proc_id_t cp_slice_call_proc_id( slice_call_proc_id_t* src); + +bool eq_slice_call_proc_id(slice_call_proc_id_t* m0, slice_call_proc_id_t* m1); + + + + +////////////////////////////////////// +// RIC Control Header +///////////////////////////////////// + +typedef struct { + uint32_t dummy; +} slice_ctrl_hdr_t; + +void free_slice_ctrl_hdr( slice_ctrl_hdr_t* src); + +slice_ctrl_hdr_t cp_slice_ctrl_hdr(slice_ctrl_hdr_t* src); + +bool eq_slice_ctrl_hdr(slice_ctrl_hdr_t const* m0, slice_ctrl_hdr_t const* m1); + + +////////////////////////////////////// +// RIC Control Message +///////////////////////////////////// + +typedef enum{ + SLICE_CTRL_SM_V0_ADD, + SLICE_CTRL_SM_V0_DEL, + SLICE_CTRL_SM_V0_UE_SLICE_ASSOC, + + SLICE_CTRL_SM_V0_END +} slice_ctrl_msg_e ; + +typedef struct{ + uint32_t len_dl; + uint32_t* dl; + uint32_t len_ul; + uint32_t* ul; +} del_slice_conf_t; +/* +typedef struct { + slice_ctrl_msg_e type; + union{ + slice_conf_t add_mod_slice; + del_slice_conf_t del_slice; + ue_slice_conf_t ue_slice; + }; +} slice_ctrl_msg_t; +*/ + + typedef union{ + slice_conf_t add_mod_slice; + del_slice_conf_t del_slice; + ue_slice_conf_t ue_slice; + } slice_ctrl_msg_u; + + typedef struct { + slice_ctrl_msg_e type; + slice_ctrl_msg_u u; + } slice_ctrl_msg_t; + + + + +void free_slice_ctrl_msg( slice_ctrl_msg_t* src); + +slice_ctrl_msg_t cp_slice_ctrl_msg(slice_ctrl_msg_t* src); + +bool eq_slice_ctrl_msg(slice_ctrl_msg_t const* m0, slice_ctrl_msg_t const* m1); + + +////////////////////////////////////// +// RIC Control Outcome +///////////////////////////////////// + +typedef enum{ + SLICE_CTRL_OUT_OK, + SLICE_CTRL_OUT_ERROR, + + SLICE_ANS_END +} slice_ctrl_out_e; + +typedef struct { + slice_ctrl_out_e ans; + uint32_t len_diag; + char* diagnostic; // human-readable diagnostic for northbound +} slice_ctrl_out_t; + +void free_slice_ctrl_out(slice_ctrl_out_t* src); + +slice_ctrl_out_t cp_slice_ctrl_out(slice_ctrl_out_t* src); + +bool eq_slice_ctrl_out(slice_ctrl_out_t* m0, slice_ctrl_out_t* m1); + + + +////////////////////////////////////// +// RAN Function Definition +///////////////////////////////////// + +typedef struct { + uint32_t len_supported_alg; + slice_algorithm_e* supported_alg; +} slice_func_def_t; + +void free_slice_func_def( slice_func_def_t* src); + +slice_func_def_t cp_slice_func_def(slice_func_def_t* src); + +bool eq_slice_func_def(slice_func_def_t* m0, slice_func_def_t* m1); + + + +void slice_free_ind_msg(slice_ind_msg_t* msg); + +void slice_free_ctrl_msg(slice_ctrl_msg_t* msg); + +void slice_free_ctrl_out(slice_ctrl_out_t* out); + +///////////////////////////////////////////////// +////////////////////////////////////////////////// +///////////////////////////////////////////////// + + +/* + * O-RAN defined 5 Procedures: RIC Subscription, RIC Indication, RIC Control, E2 Setup and RIC Service Update + * */ + + +/////////////// +/// RIC Subscription +/////////////// + +typedef struct{ + slice_event_trigger_t et; + slice_action_def_t* ad; +} slice_sub_data_t; + +/////////////// +// RIC Indication +/////////////// + +typedef struct{ + slice_ind_hdr_t hdr; + slice_ind_msg_t msg; + slice_call_proc_id_t* proc_id; +} slice_ind_data_t; + +/////////////// +// RIC Control +/////////////// + +typedef struct{ + slice_ctrl_hdr_t hdr; + slice_ctrl_msg_t msg; +} slice_ctrl_req_data_t; + +typedef struct{ + slice_ctrl_out_t* out; +} slice_ctrl_out_data_t; + +/////////////// +// E2 Setup +/////////////// + +typedef struct{ + slice_func_def_t func_def; +} slice_e2_setup_data_t; + +/////////////// +// RIC Service Update +/////////////// + +typedef struct{ + slice_func_def_t func_def; +} slice_ric_service_update_t; + + +#endif + diff --git a/executables/agent_if/libe2_agent.a b/executables/agent_if/libe2_agent.a new file mode 100644 index 0000000000000000000000000000000000000000..bd7789fe1f3f5c56aa3a40c0ac114599039cf86e Binary files /dev/null and b/executables/agent_if/libe2_agent.a differ diff --git a/executables/agent_if/read/README.md b/executables/agent_if/read/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8c6c7b3d1998f93f91d98b74f34fb46a9ce9fc62 --- /dev/null +++ b/executables/agent_if/read/README.md @@ -0,0 +1,2 @@ +I do not like the idea of duplicating structs. Rethink the implementation! + diff --git a/executables/agent_if/read/sm_ag_if_rd.c b/executables/agent_if/read/sm_ag_if_rd.c new file mode 100644 index 0000000000000000000000000000000000000000..1c9a857f69cd7f87a2d75865ad367989e1ffb9c0 --- /dev/null +++ b/executables/agent_if/read/sm_ag_if_rd.c @@ -0,0 +1,54 @@ +/* + * 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 "sm_ag_if_rd.h" + +#include <assert.h> +#include <stdlib.h> + +void free_sm_rd_if(sm_ag_if_rd_t* d) +{ + assert(d != NULL); + /* + if(d->type == MAC_STATS_V0){ + mac_ind_data_t* ind = &d->mac_stats; + free_mac_ind_hdr(&ind->hdr); + free_mac_ind_msg(&ind->msg); + free_mac_call_proc_id(ind->proc_id); + } else if(d->type == RLC_STATS_V0){ + rlc_ind_data_t* ind = &d->rlc_stats; + free_rlc_ind_hdr(&ind->hdr); + free_rlc_ind_msg(&ind->msg); + free_rlc_call_proc_id(ind->proc_id); + } else +*/ + if(d->type == PDCP_STATS_V0){ +// pdcp_ind_data_t* ind = &d->pdcp_stats; +// free_pdcp_ind_hdr(&ind->hdr); +// free_pdcp_ind_msg(&ind->msg); +// free_pdcp_call_proc_id(ind->proc_id); + } else { + assert(0!=0 && "Unforeseen case"); + } + +} + diff --git a/executables/agent_if/read/sm_ag_if_rd.h b/executables/agent_if/read/sm_ag_if_rd.h new file mode 100644 index 0000000000000000000000000000000000000000..42fd4074899caea44d99c8dc1513c3f046dfe657 --- /dev/null +++ b/executables/agent_if/read/sm_ag_if_rd.h @@ -0,0 +1,60 @@ +/* + * 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 SM_READ_INTERFACE_H +#define SM_READ_INTERFACE_H + +// Interface between the SM and the agent/server. +// The SM can call the functions here defined and implemented on the RAN/server to read data. + +#include "../ie/mac_data_ie.h" +#include "../ie/rlc_data_ie.h" +#include "../ie/pdcp_data_ie.h" +#include "../ie/slice_data_ie.h" + + +typedef enum{ + MAC_STATS_V0, + RLC_STATS_V0, + PDCP_STATS_V0, + SLICE_STATS_V0, + + SM_AGENT_IF_READ_V0_END, +} sm_ag_if_rd_e; + +// Do not change the order of data in the struct +typedef struct{ + union { + mac_ind_data_t mac_stats; + rlc_ind_data_t rlc_stats; + pdcp_ind_data_t pdcp_stats; + slice_ind_data_t slice_stats; + }; + sm_ag_if_rd_e type; +} sm_ag_if_rd_t; + + +void free_sm_rd_if(sm_ag_if_rd_t* d); + + +#endif + diff --git a/executables/agent_if/sm_io.h b/executables/agent_if/sm_io.h new file mode 100644 index 0000000000000000000000000000000000000000..97eac10d37d98218ac5cef1e293cb9433cc70fdc --- /dev/null +++ b/executables/agent_if/sm_io.h @@ -0,0 +1,39 @@ +/* + * 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 SM_INPUT_OUTPUT_H +#define SM_INPUT_OUTPUT_H + +#include "read/sm_ag_if_rd.h" +#include "write/sm_ag_if_wr.h" +#include "ans/sm_ag_if_ans.h" + +// The SM agent uses this two functions to communicate with the RAN and with the server. +typedef struct{ + + void (*read)(sm_ag_if_rd_t* data); + + sm_ag_if_ans_t (*write)(sm_ag_if_wr_t const* data); + +} sm_io_ag_t; + +#endif + diff --git a/executables/agent_if/write/sm_ag_if_wr.h b/executables/agent_if/write/sm_ag_if_wr.h new file mode 100644 index 0000000000000000000000000000000000000000..4a206fcd56e9f34d89755516d20db5932269c4ee --- /dev/null +++ b/executables/agent_if/write/sm_ag_if_wr.h @@ -0,0 +1,54 @@ +/* + * 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 E2AP_SM_WR_IF_H +#define E2AP_SM_WR_IF_H + +#include "subscribe_timer.h" +#include "../ie/pdcp_data_ie.h" +#include "../ie/rlc_data_ie.h" +#include "../ie/mac_data_ie.h" +#include "../ie/slice_data_ie.h" + +typedef enum{ + SUBSCRIBE_TIMER = 0, + MAC_CTRL_REQ_V0 = 1, + RLC_CTRL_REQ_V0 = 2, + PDCP_CTRL_REQ_V0 = 3, + SLICE_CTRL_REQ_V0 = 4, + + SM_AGENT_IF_WRITE_V0_END, +} sm_ag_if_wr_e; + +typedef struct { + union{ + subscribe_timer_t sub_timer; + mac_ctrl_req_data_t mac_ctrl; + rlc_ctrl_req_data_t rlc_ctrl; + pdcp_ctrl_req_data_t pdcp_req_ctrl; + slice_ctrl_req_data_t slice_req_ctrl; + }; + sm_ag_if_wr_e type; +} sm_ag_if_wr_t; + +#endif + diff --git a/executables/agent_if/write/subscribe_timer.h b/executables/agent_if/write/subscribe_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..103edaeeeb861479ed6ee071988bd35e231e2baa --- /dev/null +++ b/executables/agent_if/write/subscribe_timer.h @@ -0,0 +1,12 @@ +#ifndef SUBSCRIBE_TIMER_EUR_H +#define SUBSCRIBE_TIMER_EUR_H + +#include <stdint.h> + +typedef struct{ + uint32_t ms; +} subscribe_timer_t; + +#endif + + diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index e3998975e85d744ebc0be2e8a224973e6e318f5f..8de81cd9caf5cfe66a115e0e25323cf2bacd26e2 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -81,6 +81,26 @@ unsigned short config_frames[4] = {2,9,11,13}; #include <openair3/ocp-gtpu/gtp_itf.h> #include "nfapi/oai_integration/vendor_ext.h" + +////////////////////////////////// +//// E2 Agent headers +////////////////////////////////// + +#include "agent_if/read/sm_ag_if_rd.h" +#include "agent_if/sm_io.h" +#include "agent_if/e2_agent_api.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_entity.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" +#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" +#include <time.h> + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// + + pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex @@ -594,6 +614,316 @@ void init_pdcp(void) { } } + +static +const int mod_id = 0; + +static +int64_t time_now_us(void) +{ + struct timespec tms; + + /* The C11 way */ + /* if (! timespec_get(&tms, TIME_UTC)) */ + + /* POSIX.1-2008 way */ + if (clock_gettime(CLOCK_REALTIME,&tms)) { + return -1; + } + /* seconds, multiplied with 1 million */ + int64_t micros = tms.tv_sec * 1000000; + /* Add full microseconds */ + micros += tms.tv_nsec/1000; + /* round up if necessary */ + if (tms.tv_nsec % 1000 >= 500) { + ++micros; + } + return micros; +} + + +static +void read_mac_sm(mac_ind_msg_t* data) +{ + assert(data != NULL); + + data->tstamp = time_now_us(); + +// assert(0!=0 && "Read MAC called"); + + NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info; + size_t num_ues = 0; + UE_iterator(UE_info->list, ue) { + if (ue) + num_ues += 1; + } + + data->len_ue_stats = num_ues; + if(data->len_ue_stats > 0){ + data->ue_stats = calloc(data->len_ue_stats, sizeof(mac_ue_stats_impl_t)); + assert( data->ue_stats != NULL && "Memory exhausted" ); + } + + size_t i = 0; //TODO + UE_iterator(UE_info->list, UE) { + const NR_UE_sched_ctrl_t* sched_ctrl = &UE->UE_sched_ctrl; + mac_ue_stats_impl_t* rd = &data->ue_stats[i]; + + rd->frame = RC.nrmac[mod_id]->frame; + rd->slot = RC.nrmac[mod_id]->slot; + + rd->dl_aggr_tbs = UE->mac_stats.dl.total_bytes; + rd->ul_aggr_tbs = UE->mac_stats.ul.total_bytes; + + if (is_xlsch_in_slot(RC.nrmac[mod_id]->dlsch_slot_bitmap[rd->slot / 64], rd->slot)) { + rd->dl_curr_tbs = UE->mac_stats.dl.current_bytes; + rd->dl_sched_rb = UE->mac_stats.dl.current_rbs; + } + if (is_xlsch_in_slot(RC.nrmac[mod_id]->ulsch_slot_bitmap[rd->slot / 64], rd->slot)) { + rd->ul_curr_tbs = UE->mac_stats.ul.current_bytes; + rd->ul_sched_rb = sched_ctrl->sched_pusch.rbSize; + } + + rd->rnti = UE->rnti; + rd->dl_aggr_prb = UE->mac_stats.dl.total_rbs; + rd->ul_aggr_prb = UE->mac_stats.ul.total_rbs; + rd->dl_aggr_retx_prb = UE->mac_stats.dl.total_rbs_retx; + rd->ul_aggr_retx_prb = UE->mac_stats.ul.total_rbs_retx; + + rd->dl_aggr_bytes_sdus = UE->mac_stats.dl.lc_bytes[3]; + rd->ul_aggr_bytes_sdus = UE->mac_stats.ul.lc_bytes[3]; + + rd->dl_aggr_sdus = UE->mac_stats.dl.num_mac_sdu; + rd->ul_aggr_sdus = UE->mac_stats.ul.num_mac_sdu; + + rd->pusch_snr = (float) sched_ctrl->pusch_snrx10 / 10; //: float = -64; + rd->pucch_snr = (float) sched_ctrl->pucch_snrx10 / 10; //: float = -64; + + rd->wb_cqi = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb; + rd->dl_mcs1 = sched_ctrl->dl_bler_stats.mcs; + rd->dl_bler = sched_ctrl->dl_bler_stats.bler; + rd->ul_mcs1 = sched_ctrl->ul_bler_stats.mcs; + rd->ul_bler = sched_ctrl->ul_bler_stats.bler; + rd->dl_mcs2 = 0; + rd->ul_mcs2 = 0; + rd->phr = sched_ctrl->ph; + + const uint32_t bufferSize = sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes; + rd->bsr = bufferSize; + + const size_t numDLHarq = 4; + rd->dl_num_harq = numDLHarq; + for (uint8_t j = 0; j < numDLHarq; ++j) + rd->dl_harq[j] = UE->mac_stats.dl.rounds[j]; + rd->dl_harq[numDLHarq] = UE->mac_stats.dl.errors; + + const size_t numUlHarq = 4; + rd->ul_num_harq = numUlHarq; + for (uint8_t j = 0; j < numUlHarq; ++j) + rd->ul_harq[j] = UE->mac_stats.ul.rounds[j]; + rd->ul_harq[numUlHarq] = UE->mac_stats.ul.errors; + + ++i; + } +} + +static +uint32_t num_act_rb(NR_UEs_t* UE_info) +{ + assert(UE_info!= NULL); + + + uint32_t act_rb = 0; + UE_iterator(UE_info->list, UE) { + uint16_t const rnti = UE->rnti; + for(int rb_id = 1; rb_id < 6; ++rb_id ){ + nr_rlc_statistics_t rlc = {0}; + const int srb_flag = 0; + const int rc = nr_rlc_get_statistics(rnti, srb_flag, rb_id, &rlc); + if(rc == 1) ++act_rb; + } + } + return act_rb; +} + + +static +void read_rlc_sm(rlc_ind_msg_t* data) +{ + assert(data != NULL); + + // use MAC structures to get RNTIs + NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info; + uint32_t const act_rb = num_act_rb(UE_info); + + //assert(0!=0 && "Read RLC called"); + + data->len = act_rb; + if(data->len > 0){ + data->rb = calloc(data->len, sizeof(rlc_radio_bearer_stats_t)); + assert(data->rb != NULL && "Memory exhausted"); + } + + data->tstamp = time_now_us(); + + uint32_t i = 0; + UE_iterator(UE_info->list, UE) { + uint16_t const rnti = UE->rnti; + //for every LC ID + for(int rb_id = 1; rb_id < 6; ++rb_id ){ + nr_rlc_statistics_t rb_rlc = {0}; + const int srb_flag = 0; + const int rc = nr_rlc_get_statistics(rnti, srb_flag, rb_id, &rb_rlc); + if(rc == 0) continue; + rlc_radio_bearer_stats_t* sm_rb = &data->rb[i]; + + sm_rb->txpdu_pkts = rb_rlc.txpdu_pkts; + sm_rb->txpdu_bytes = rb_rlc.txpdu_bytes; /* aggregated amount of transmitted bytes in RLC PDUs */ + sm_rb->txpdu_wt_ms = rb_rlc.txpdu_wt_ms; /* aggregated head-of-line tx packet waiting time to be transmitted (i.e. send to the MAC layer) */ + sm_rb->txpdu_dd_pkts = rb_rlc.txpdu_dd_pkts; /* aggregated number of dropped or discarded tx packets by RLC */ + sm_rb->txpdu_dd_bytes = rb_rlc.txpdu_dd_bytes; /* aggregated amount of bytes dropped or discarded tx packets by RLC */ + sm_rb->txpdu_retx_pkts = rb_rlc.txpdu_retx_pkts; /* aggregated number of tx pdus/pkts to be re-transmitted (only applicable to RLC AM) */ + sm_rb->txpdu_retx_bytes = rb_rlc.txpdu_retx_bytes ; /* aggregated amount of bytes to be re-transmitted (only applicable to RLC AM) */ + sm_rb->txpdu_segmented = rb_rlc.txpdu_segmented ; /* aggregated number of segmentations */ + sm_rb->txpdu_status_pkts = rb_rlc.txpdu_status_pkts ; /* aggregated number of tx status pdus/pkts (only applicable to RLC AM) */ + sm_rb->txpdu_status_bytes = rb_rlc.txpdu_status_bytes ; /* aggregated amount of tx status bytes (only applicable to RLC AM) */ + sm_rb->txbuf_occ_bytes = rb_rlc.txbuf_occ_bytes ; /* current tx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */ + sm_rb->txbuf_occ_pkts = rb_rlc.txbuf_occ_pkts ; /* current tx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */ + + /* RX */ + sm_rb->rxpdu_pkts = rb_rlc.rxpdu_pkts ; /* aggregated number of received RLC PDUs */ + sm_rb->rxpdu_bytes = rb_rlc.rxpdu_bytes ; /* amount of bytes received by the RLC */ + sm_rb->rxpdu_dup_pkts = rb_rlc.rxpdu_dup_pkts ; /* aggregated number of duplicate packets */ + sm_rb->rxpdu_dup_bytes = rb_rlc.rxpdu_dup_bytes ; /* aggregated amount of duplicated bytes */ + sm_rb->rxpdu_dd_pkts = rb_rlc.rxpdu_dd_pkts ; /* aggregated number of rx packets dropped or discarded by RLC */ + sm_rb->rxpdu_dd_bytes = rb_rlc.rxpdu_dd_bytes ; /* aggregated amount of rx bytes dropped or discarded by RLC */ + sm_rb->rxpdu_ow_pkts = rb_rlc.rxpdu_ow_pkts ; /* aggregated number of out of window received RLC pdu */ + sm_rb->rxpdu_ow_bytes = rb_rlc.rxpdu_ow_bytes ; /* aggregated number of out of window bytes received RLC pdu */ + sm_rb->rxpdu_status_pkts = rb_rlc.rxpdu_status_pkts ; /* aggregated number of rx status pdus/pkts (only applicable to RLC AM) */ + sm_rb->rxpdu_status_bytes = rb_rlc.rxpdu_status_bytes ; /* aggregated amount of rx status bytes (only applicable to RLC AM) */ + + sm_rb->rxbuf_occ_bytes = rb_rlc.rxbuf_occ_bytes ; /* current rx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */ + sm_rb->rxbuf_occ_pkts = rb_rlc.rxbuf_occ_pkts ; /* current rx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */ + + /* TX */ + sm_rb->txsdu_pkts = rb_rlc.txsdu_pkts ; /* number of SDUs delivered */ + sm_rb->txsdu_bytes = rb_rlc.txsdu_bytes ; /* number of bytes of SDUs delivered */ + + /* RX */ + sm_rb->rxsdu_pkts = rb_rlc.rxsdu_pkts ; /* number of SDUs received */ + sm_rb->rxsdu_bytes = rb_rlc.rxsdu_bytes ; /* number of bytes of SDUs received */ + sm_rb->rxsdu_dd_pkts = rb_rlc.rxsdu_dd_pkts ; /* number of dropped or discarded SDUs */ + sm_rb->rxsdu_dd_bytes = rb_rlc.rxsdu_dd_bytes ; /* number of bytes of SDUs dropped or discarded */ + + sm_rb->mode = rb_rlc.mode; /* 0: RLC AM, 1: RLC UM, 2: RLC TM */ + sm_rb->rnti = rnti; + sm_rb->rbid = rb_id; + + ++i; + } + } +} + + +static +void read_pdcp_sm(pdcp_ind_msg_t* data) +{ + assert(data != NULL); + + //assert(0!=0 && "Calling PDCP"); + // for the moment and while we don't have a split base station, we use the + // MAC structures to obtain the RNTIs which we use to query the PDCP + NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info; + uint32_t const act_rb = num_act_rb(UE_info); + + data->len = act_rb; + data->tstamp = time_now_us(); +// data->slot = 0; + + if(data->len > 0){ + data->rb = calloc(data->len , sizeof(pdcp_radio_bearer_stats_t)); + assert(data->rb != NULL && "Memory exhausted!"); + } + + size_t i = 0; + UE_iterator(UE_info->list, UE) { + + const int rnti = UE->rnti; + for(size_t rb_id = 1; rb_id < 6; ++rb_id){ + nr_pdcp_statistics_t pdcp = {0}; + + const int srb_flag = 0; + const int rc = nr_pdcp_get_statistics(rnti, srb_flag, rb_id, &pdcp); + + if(rc == 0) continue; + + pdcp_radio_bearer_stats_t* rd = &data->rb[i]; + + + rd->txpdu_pkts = pdcp.txpdu_pkts ; /* aggregated number of tx packets */ + rd->txpdu_bytes = pdcp.txpdu_bytes; /* aggregated bytes of tx packets */ + rd->txpdu_sn = pdcp.txpdu_sn ; /* current sequence number of last tx packet (or TX_NEXT) */ + rd->rxpdu_pkts = pdcp.rxpdu_pkts ; /* aggregated number of rx packets */ + rd->rxpdu_bytes = pdcp.rxpdu_bytes ; /* aggregated bytes of rx packets */ + rd->rxpdu_sn = pdcp.rxpdu_sn ; /* current sequence number of last rx packet (or RX_NEXT) */ + rd->rxpdu_oo_pkts = pdcp.rxpdu_oo_pkts ; /* aggregated number of out-of-order rx pkts (or RX_REORD) */ + rd->rxpdu_oo_bytes = pdcp.rxpdu_oo_bytes ; /* aggregated amount of out-of-order rx bytes */ + rd->rxpdu_dd_pkts = pdcp.rxpdu_dd_pkts ; /* aggregated number of duplicated discarded packets (or dropped packets because of other reasons such as integrity failure) (or RX_DELIV) */ + rd->rxpdu_dd_bytes = pdcp.rxpdu_dd_bytes; /* aggregated amount of discarded packets' bytes */ + rd->rxpdu_ro_count = pdcp.rxpdu_ro_count ; /* this state variable indicates the COUNT value following the COUNT value associated with the PDCP Data PDU which triggered t-Reordering. (RX_REORD) */ + rd->txsdu_pkts = pdcp.txsdu_pkts ; /* number of SDUs delivered */ + rd->txsdu_bytes = pdcp.txsdu_bytes ; /* number of bytes of SDUs delivered */ + rd->rxsdu_pkts = pdcp.rxsdu_pkts ; /* number of SDUs received */ + rd->rxsdu_bytes = pdcp.rxsdu_bytes ; /* number of bytes of SDUs received */ + rd->rnti = rnti; + rd->mode = pdcp.mode; /* 0: PDCP AM, 1: PDCP UM, 2: PDCP TM */ + rd->rbid = rb_id; + + ++i; + } + } +} + + + + + +static +void read_RAN(sm_ag_if_rd_t* data) +{ + assert(data != NULL); + assert(data->type == MAC_STATS_V0 + || data->type == RLC_STATS_V0 + || data->type == PDCP_STATS_V0 + ); + + if(data->type == MAC_STATS_V0 ){ + read_mac_sm(&data->mac_stats.msg); + // printf("calling REAd MAC\n"); + }else if(data->type == RLC_STATS_V0) { + read_rlc_sm(&data->rlc_stats.msg); + // printf("calling REAd RLC\n"); + } else if(data->type == PDCP_STATS_V0){ + read_pdcp_sm(&data->pdcp_stats.msg); + //printf("calling REAd PDCP\n"); +// } else if(RRC_STATS_V0){ +// read_rrc_sm(&data->rrc_stats); + } else { + assert(0!=0 && "Unknown data type!"); + } + +} + +static +sm_ag_if_ans_t write_RAN(sm_ag_if_wr_t const* data) +{ + assert(data != NULL); + assert(0!=0 && "Not implemented"); + sm_ag_if_ans_t ans = {.type = MAC_AGENT_IF_CTRL_ANS_V0 }; + + return ans; +} + int main( int argc, char **argv ) { int ru_id, CC_id = 0; start_background_system(); @@ -603,6 +933,25 @@ int main( int argc, char **argv ) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } +////////////////////////////////// +////////////////////////////////// +//// Init the E2 Agent + const char server_ip_str[] = "192.168.52.10"; + +// const gNB_RRC_INST* rrc = RC.nrrrc[mod_id]; +// assert(rrc); + + const int mcc = 208; //rrc->configuration.mcc[0]; // 208; + const int mnc = 94; // rrc->configuration.mnc[0]; // 94; + const int mnc_digit_len = 2; // rrc->configuration.mnc_digit_length[0]; // 2; + const int nb_id = 42; // rrc->configuration.cell_identity; //42; + sm_io_ag_t io = {.read = read_RAN, .write = write_RAN}; + + init_agent_api(server_ip_str, mcc, mnc, mnc_digit_len, nb_id, io); +////////////////////////////////// +////////////////////////////////// + + set_softmodem_sighandler(); #ifdef DEBUG_CONSOLE setvbuf(stdout, NULL, _IONBF, 0);