owned this note
owned this note
Published
Linked with GitHub
:::warning
# <center><i class="fa fa-edit"></i> FlexRIC RIC implementation </center>
:::
###### tags: `FlexRIC` `TEEP` `Internship`
:::success
**Learning Objective:**
The study objectives were to:
- Explore files, structures and functions of RIC module
- Understand the meaning of the files
- Understand the connection of RIC to other modules
:::
[TOC]
## Module 8: FlexRIC RIC implementation
RIC, or Server Library, is the third module of FlexRIC. It contains iApps and the interface for connection to xApps.

## 1. Source files of RIC implementation
```
ric
├── asio_ric.h
├── e2ap_ric.h
├── e2_node.h
├── endpoint_ric.h
├── iApps
│ ├── influx.h
│ ├── nng
│ │ ├── keep_alive
│ │ │ └── keep_alive_timer.h
│ │ ├── msgs
│ │ │ └── xapp_msgs.h
│ │ ├── notify_nng_listener.h
│ │ └── req_reply.h
│ ├── redis.h
│ ├── stdout.h
│ └── string_parser.h
├── msg_handler_ric.h
├── near_ric_api.h
├── near_ric.h
└── plugin_ric.h
```
|File | Function | Remarks |
|---- | -------- | ------- |
|[asio_ric.h](#211-asio_rich)|Asyn. IO||
|[e2ap_ric.h](#212-e2ap_ric.h)|E2AP|Encode/decode E2 MSG|
|[e2_node.h](#213-e2_node.h)|E2 Node structure||
|[endpoint_ric.h](#214-endpoint_ric.h)|Endpoint||
|[msg_handler_ric.h](#2113-msg_handler_ric.h)|MSG Handler|Agent MSG Handlers|
|[near_ric_api.h](#214-near_ric_api.h)|API to Near-RIC||
|[near_ric.h](#215-near_ric.h)|Main Near-RIC functionality|Event loop|
|[plugin_ric.h](#216-plugin_ric.h)|SM Plugins||
|[influx.h](#215-influx.h), [redis.h](#216-redis.h), [stdout.h](#217-stdout.h) and [notify_nng_listener.h](#218-notify_nng_listener.h)|Listeners|Receive notifications from RIC Events and transfer it to InfluxDB, Redis, NNG or output|
|[string_parser.h](#2112-string_parser.h)|Converts MAC, RLC, PDCP, Slice stats to string.||
|[req_reply.h](#2111-req_reply.h)|Request NNG reply from xApps|Runs in a separate thread|
|[keep_alive_timer.h](#219-keep_alive_timer.h)|Timer||
|[xapp_msgs.h](#2110-xapp_msgs.h)|Typedefs of NNG xApps messages||
## 2. FlexRIC RIC Block Diagram
### 2.1. Relationship between RIC files in FlexRIC

___
#### 2.1.1. asio_ric.h
Identical to `asio_agent.h` (see [FlexRIC Agent implementation](https://hackmd.io/69m_bUtkR76kExxteiudfg?view=)).
___
#### 2.1.2. e2ap_ric.h
Identical to `e2ap_agent.h`.
___
#### 2.1.3. e2_node.h
Contains a structure of E2 node.
```c=
typedef struct{
global_e2_node_id_t id;
accepted_ran_function_t* accepted;
size_t len_acc;
} e2_node_t ;
```
Also, contains functions for initialization and freeing E2 node.
```c=
void init_e2_node(e2_node_t* n, global_e2_node_id_t const* id, size_t len_acc, accepted_ran_function_t accepted[len_acc]);
void free_e2_node(e2_node_t* n);
```
___
#### 2.1.4. endpoint_ric.h
Identical to `endpoint_agent.h`.
___
#### 2.1.5. influx.h
#### 2.1.6. redis.h
#### 2.1.7. stdout.h
#### 2.1.8. notify_nng_listener.h
Listeners. They can optionally be associated with certain RIC functions, for example, receiving MAC stats (`MAC_STATS_V0`). They take received data and output it to:
* stdout
* Influx Database
* Redis
* NNG (Nanomessages)
```c=
void notify_influx_listener(sm_ag_if_rd_t const* data);
void notify_redis_listener(sm_ag_if_rd_t const* data);
void notify_stdout_listener(sm_ag_if_rd_t const* data);
void notify_nng_listener(sm_ag_if_rd_t const* data);
```
Here is an example of association (taken from `test/near_ric.c`):
```c=
static
void load_default_pub_sub_ric(near_ric_t* ric)
{
assert(ric != NULL);
void* it = assoc_front(&ric->plugin.sm_ds);
void* end_it = assoc_end(&ric->plugin.sm_ds);
while(it != end_it){
const uint16_t *ran_func_id = assoc_key(&ric->plugin.sm_ds, it);
subs_ric_t std_listener = {.name = "stdout listener", .fp = notify_stdout_listener };
register_listeners_for_ran_func_id(ric, ran_func_id, std_listener);
subs_ric_t redis_listener = {.name = "redis listener", .fp = notify_redis_listener };
register_listeners_for_ran_func_id(ric, ran_func_id, redis_listener);
subs_ric_t influx_listener = {.name = "influx listener", .fp = notify_influx_listener };
register_listeners_for_ran_func_id(ric, ran_func_id, influx_listener);
subs_ric_t nng_listener = {.name = "nanomsg listener", .fp = notify_nng_listener };
register_listeners_for_ran_func_id(ric, ran_func_id, nng_listener);
it = assoc_next(&ric->plugin.sm_ds, it);
}
}
```
Here, all three listeners are associated with each RIC function.
___
#### 2.1.9. keep_alive_timer.h
```c=
/*
* Naive timer that expires every exp_time_ms and calls the function fun(void* data)
*/
void init_keep_alive_timer(uint32_t exp_time_ms, void (*fun)(void*), void* data);
void stop_keep_alive_timer(void);
```
___
#### 2.1.10. xapp_msgs.h
Structures of NNG xApp messages, for example:
```c=
typedef enum{
XAPP_MAC_REPORT,
XAPP_RLC_REPORT,
XAPP_PDCP_REPORT,
XAPP_RRC_REPORT,
XAPP_SLICE_REPORT,
} xapp_report_e;
typedef enum{
XAPP_ANS_OK,
XAPP_ANS_UNKNOWN_ID,
XAPP_ANS_ERROR,
XAPP_ANS_NOT_IMPLEMENTED
} xapp_request_answer_e;
```
___
#### 2.1.11. req_reply.h
Creates separate threads which wait for NNG messages from xApps.
```c=
void init_req_reply_server_ping(req_reply_server_arg_t* arg);
void init_req_reply_server_msg(req_reply_server_arg_t* arg);
void stop_req_reply_server_ping(void);
void stop_req_reply_server_msg(void);
```
___
#### 2.1.12. string_parser.h
Converts MAC, RLC, PDCP, Slice stats to string.
```c=
void to_string_mac_ue_stats(mac_ue_stats_impl_t* stats, int64_t tstamp, char* out, size_t out_len);
void to_string_rlc_rb(rlc_radio_bearer_stats_t* rlc, int64_t tstamp, char* out, size_t out_len);
void to_string_pdcp_rb(pdcp_radio_bearer_stats_t* pdcp, int64_t tstamp, char* out, size_t out_len);
void to_string_slice(slice_ind_msg_t const* slice, int64_t tstamp, char* out, size_t out_len);
```
___
#### 2.1.13 msg_handler_ric.h
Similarly to `msg_handler_agent.h`, it defines functions to handle messages from Agent and from xApps.
___
#### 2.1.14. near_ric_api.h
API to near-RIC. Provides interface for initializing and stopping RIC, as well as for RIC Services, subscribing and unsubscribing for updates from Agent.
```c=
void init_near_ric_api(void /* const char* addr , int port*/ );
void stop_near_ric_api(void);
void report_service_near_ric_api(/*global_e2_node_id_t const* id,*/ uint16_t ran_func_id, const char* cmd );
void rm_report_service_near_ric_api(/*global_e2_node_id_t const* id,*/ uint16_t ran_func_id, const char* cmd );
void control_service_near_ric_api(uint16_t sm_id, const char* cmd);
void insert_service_near_ric_api(uint16_t sm_id, const char* cmd);
void policy_service_near_ric_api(uint16_t sm_id, const char* cmd);
void load_sm_near_ric_api(const char* file_path);
// Observer pattern. Interface for subscription/publish for xApps
typedef struct{
void (*update)(const char* data);
} subs_t;
void susbscribe_near_ric(/*global_e2_node_id_t const* id,*/ uint16_t sm_id, subs_t subscription);
void unsusbscribe_near_ric( /*global_e2_node_id_t const* id,*/ uint16_t sm_id, subs_t subscription);
```
___
#### 2.1.15. near_ric.h
Main source file for Near-RIC related functionality. For example, `near_ric_t` initialization, freeing, generating requests, register listeners:
```c=
near_ric_t* init_near_ric(const char* addr);
void start_near_ric(near_ric_t* ric);
void free_near_ric(near_ric_t* ric);
size_t num_conn_e2_nodes(near_ric_t* ric);
void report_service_near_ric(near_ric_t* ric, /*global_e2_node_id_t const* id,*/ uint16_t ran_func_id, const char* cmd);
void rm_report_service_near_ric(near_ric_t* ric, /*global_e2_node_id_t const* id,*/ uint16_t ran_func_id, const char* cmd);
void control_service_near_ric(near_ric_t* ric, /*global_e2_node_id_t const* id,*/ uint16_t ran_func_id, const char* cmd);
static void register_listeners_for_ran_func_id(near_ric_t* ric, uint16_t const* ran_func_id, subs_ric_t subs)
static ric_control_request_t generate_control_request(near_ric_t* ric, sm_ric_t* sm, sm_ag_if_wr_t* wr )
```
___
#### 2.1.16. plugin_ric.h
Identical to `plugin_agent.h`.