diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 8c30843807..5ea99de7ea 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -59,6 +59,7 @@ #include "openair2/PHY_INTERFACE/queue_t.h" #include "gnb_ind_vars.h" #include "nr_fapi_p7_utils.h" +#include "nr_fapi_p5_utils.h" #include #ifdef ENABLE_AERIAL @@ -1622,6 +1623,21 @@ int nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_resp return 0; } +int nr_error_ind_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_error_indication_scf_t *resp) +{ + NFAPI_TRACE(NFAPI_TRACE_WARN, + "[VNF] Received NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION idx:%d phy_id:%d\n", + p5_idx, + resp->header.phy_id); + NFAPI_TRACE(NFAPI_TRACE_WARN, "[VNF] Previous message 0x%02x resulted in an error on the PNF \n", resp->message_id); + NFAPI_TRACE(NFAPI_TRACE_WARN, + "[VNF] Received error code 0x%02x (%s)\n", + resp->error_code, + error_ind_code_to_str(resp->error_code)); + // TODO: add error handling to the VNF instead of only reporting the received error + return 0; +} + int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, void *msg) { NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__); @@ -1762,6 +1778,7 @@ void configure_nr_nfapi_vnf(eth_params_t params) config->nr_param_resp = &nr_param_resp_cb; config->nr_config_resp = &nr_config_resp_cb; config->nr_start_resp = &nr_start_resp_cb; + config->nr_error_ind = &nr_error_ind_cb; config->vendor_ext = &vendor_nr_ext_cb; config->user_data = &vnf; // To allow custom vendor extentions to be added to nfapi diff --git a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h index 8ef5fbade2..9d96a3be36 100644 --- a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h +++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h @@ -64,6 +64,7 @@ void dump_start_request(const nfapi_nr_start_request_scf_t *msg); void dump_start_response(const nfapi_nr_start_response_scf_t *msg); void dump_stop_request(const nfapi_nr_stop_request_scf_t *msg); void dump_stop_indication(const nfapi_nr_stop_indication_scf_t *msg); +char* error_ind_code_to_str(nfapi_nr_phy_notifications_errors_e error_code); void dump_error_indication(const nfapi_nr_error_indication_scf_t *msg); diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c index 4c3f32ef27..a810b199ff 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c @@ -1469,29 +1469,13 @@ void dump_stop_indication(const nfapi_nr_stop_indication_scf_t *msg) dump_p5_message_header(&msg->header,depth); } -static char *error_code_to_str(uint8_t error_code) +char* error_ind_code_to_str(nfapi_nr_phy_notifications_errors_e error_code) { switch (error_code) { - case NFAPI_NR_PHY_API_MSG_OK: - return "NFAPI_NR_PHY_API_MSG_OK"; - case NFAPI_NR_PHY_API_MSG_INVALID_STATE: - return "NFAPI_NR_PHY_API_MSG_INVALID_STATE"; - case NFAPI_NR_PHY_API_MSG_INVALID_CONFIG: - return "NFAPI_NR_PHY_API_MSG_INVALID_CONFIG"; - case NFAPI_NR_PHY_API_SFN_OUT_OF_SYNC: - return "NFAPI_NR_PHY_API_SFN_OUT_OF_SYNC"; - case NFAPI_NR_PHY_API_MSG_SLOR_ERR: - return "NFAPI_NR_PHY_API_MSG_SLOR_ERR"; - case NFAPI_NR_PHY_API_MSG_BCH_MISSING: - return "NFAPI_NR_PHY_API_MSG_BCH_MISSING"; - case NFAPI_NR_PHY_API_MSG_INVALID_SFN: - return "NFAPI_NR_PHY_API_MSG_INVALID_SFN"; - case NFAPI_NR_PHY_API_MSG_UL_DCI_ERR: - return "NFAPI_NR_PHY_API_MSG_UL_DCI_ERR"; - case NFAPI_NR_PHY_API_MSG_TX_ERR: - return "NFAPI_NR_PHY_API_MSG_TX_ERR"; - default: - return "Unknown Error code"; +#define X(name, value) case name: return #name; + NFAPI_PHY_ERROR_LIST +#undef X + default: return "UNKNOWN_ERROR"; } } @@ -1503,6 +1487,6 @@ void dump_error_indication(const nfapi_nr_error_indication_scf_t *msg) INDENTED_PRINTF("SFN = 0x%02x (%d)\n", msg->sfn, msg->sfn); INDENTED_PRINTF("Slot = 0x%02x (%d)\n", msg->slot, msg->slot); INDENTED_PRINTF("Message ID = 0x%02x\n", msg->message_id); - INDENTED_PRINTF("Error Code = 0x%02x (%s) \n", msg->error_code, error_code_to_str(msg->error_code)); + INDENTED_PRINTF("Error Code = 0x%02x (%s) \n", msg->error_code, error_ind_code_to_str(msg->error_code)); depth--; } diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index f213868328..e19dab108c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -701,16 +701,22 @@ typedef enum { } nfapi_nr_stop_errors_e; //3.3.5 PHY Notifications + +#define NFAPI_PHY_ERROR_LIST \ +X(NFAPI_NR_PHY_API_MSG_OK ,0x0)\ +X(NFAPI_NR_PHY_API_MSG_INVALID_STATE ,0x1)\ +X(NFAPI_NR_PHY_API_MSG_INVALID_CONFIG ,0x2)\ +X(NFAPI_NR_PHY_API_SFN_OUT_OF_SYNC ,0X3)\ +X(NFAPI_NR_PHY_API_MSG_SLOR_ERR ,0X4)\ +X(NFAPI_NR_PHY_API_MSG_BCH_MISSING ,0X5)\ +X(NFAPI_NR_PHY_API_MSG_INVALID_SFN ,0X6)\ +X(NFAPI_NR_PHY_API_MSG_UL_DCI_ERR ,0X7)\ +X(NFAPI_NR_PHY_API_MSG_TX_ERR ,0X8) + typedef enum { - NFAPI_NR_PHY_API_MSG_OK =0x0, - NFAPI_NR_PHY_API_MSG_INVALID_STATE =0x1, - NFAPI_NR_PHY_API_MSG_INVALID_CONFIG =0x2, - NFAPI_NR_PHY_API_SFN_OUT_OF_SYNC =0X3, - NFAPI_NR_PHY_API_MSG_SLOR_ERR =0X4, - NFAPI_NR_PHY_API_MSG_BCH_MISSING =0X5, - NFAPI_NR_PHY_API_MSG_INVALID_SFN =0X6, - NFAPI_NR_PHY_API_MSG_UL_DCI_ERR =0X7, - NFAPI_NR_PHY_API_MSG_TX_ERR =0X8 +#define X(name, value) name = value, + NFAPI_PHY_ERROR_LIST +#undef X } nfapi_nr_phy_notifications_errors_e; typedef struct { diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h index b98a91e2ac..db303b8b4a 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -294,7 +294,25 @@ typedef struct nfapi_vnf_config */ int (*start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp); int (*nr_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_response_scf_t* resp); - + + /*! A callback for the ERROR.indication + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param ind A data structure for the decoded ERROR.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ERROR.indication contains a reported error from the PNF, often signifying that a message has been sent too late + * + * + * The ind may contain pointers to dynamically allocated sub structures + * such as the vendor_extension. The dynamically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*nr_error_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_error_indication_scf_t* ind); + /*! A callback for the STOP.resp * \param config A pointer to the vnf configuration * \param p5_idx The p5 index used to indicate a particular pnf p5 connection diff --git a/nfapi/open-nFAPI/vnf/src/vnf.c b/nfapi/open-nFAPI/vnf/src/vnf.c index d669573168..b61d5f26ae 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf.c +++ b/nfapi/open-nFAPI/vnf/src/vnf.c @@ -633,6 +633,39 @@ void vnf_nr_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_conf } } +void vnf_nr_handle_error_indication(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received ERROR.indication\n"); + + nfapi_nr_error_indication_scf_t msg; + + // unpack the message + if (config->unpack_func(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config)) + { + if (config->nr_error_ind){ + (config->nr_error_ind)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dynamic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + + void vnf_handle_stop_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) { @@ -1125,7 +1158,11 @@ void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfa case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: vnf_nr_handle_config_response(pRecvMsg, recvMsgLen, config, p5_idx); - break; + break; + + case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION: + vnf_nr_handle_error_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE: vnf_nr_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx);