Merge remote-tracking branch 'origin/fapi-wls-integration' into integration_2025_w29 (!3346)

Add WLS as a transport option for VNF/PNF, refactor existing options

This MR adds a new transport mechanism for the VNF and PNF split, using
the Intel WLS library, which makes use of DPDK and shared memory to
transport messages. This transport mechanism is what is used to
interface with Radisys ODU, while also working with OAI VNF/PNF.

The VNF and PNF have been refactored so that the transport-specific
functions are isolated from the rest of the logic, and as such,
interchangeable by means of function pointers.

The same change is done for the packing/unpacking procedures, allowing
to switch between FAPI and nFAPI encoding.

This MR also reduces the amount of duplicated code, by refactoring the
VNF with Aerial, which now only has the transport-relevant functions, as
well as the ones that are unique to it ( for example, the unpacking
procedures where a secondary data buffer is used for the message
payloads )

Additionally a new callback is added to the VNF to process
ERROR.indication messages, which currently only indicates which message
originated the error, and which error occurred.
This commit is contained in:
Robert Schmidt
2025-07-15 15:44:02 +02:00
88 changed files with 4871 additions and 3525 deletions
+2 -2
View File
@@ -889,8 +889,8 @@ int unpack_nr_tlv_list(unpack_tlv_t unpack_fns[],
nfapi_tl_t generic_tl;
uint8_t numBadTags = 0;
uint16_t idx = 0;
while ((uint8_t *)(*ppReadPackedMsg) < end) {
if (size == 0) { return 1; }
while ((uint8_t *)(*ppReadPackedMsg) + 4 < end) {
// unpack the tl and process the values accordingly
if (unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
return 0;
+6
View File
@@ -22,3 +22,9 @@ if (OAI_AERIAL)
target_compile_definitions(nr_fapi_p5 PRIVATE ENABLE_AERIAL)
target_compile_definitions(nr_fapi_p7 PRIVATE ENABLE_AERIAL)
endif ()
if(OAI_WLS)
target_compile_definitions(nr_fapi_common PRIVATE ENABLE_WLS)
else()
target_compile_definitions(nr_fapi_common PRIVATE ENABLE_SOCKET)
endif()
+28 -1
View File
@@ -77,10 +77,37 @@ bool isFAPIMessageIDValid(uint16_t id);
int check_nr_fapi_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen);
int fapi_nr_message_header_unpack(uint8_t **pMessageBuf,
/*! \brief Decodes a FAPI P5 message header
* \param pMessageBuf A pointer to an encoded P5 message header
* \param messageBufLen The size of the encoded P5 message header
* \param pUnpackedBuf A pointer to the fapi_message_header
* \param unpackedBufLen The size of fapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true on success, false on failure.
*
* The function will decode a byte stream pointed to by pMessageBuf into a FAPI p5 header structure pointed to by pUnpackedBuf
*/
bool fapi_nr_message_header_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p4_p5_codec_config_t *config);
/*! \brief Decodes a FAPI P7 message header
* \param pMessageBuf A pointer to an encoded P5 message header
* \param messageBufLen The size of the encoded P5 message header
* \param pUnpackedBuf A pointer to the fapi_message_header
* \param unpackedBufLen The size of fapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true on success, false on failure.
*
* This function is a dummy function that points to fapi_nr_message_header_unpack,
* since in FAPI there's no difference in the structure of the message headers for P5 and P7
*/
bool fapi_nr_p7_message_header_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p7_codec_config_t *config);
#endif // OPENAIRINTERFACE_NR_FAPI_H
+1 -1
View File
@@ -30,7 +30,7 @@ int fapi_nr_p5_message_pack(void *pMessageBuf,
uint32_t packedBufLen,
nfapi_p4_p5_codec_config_t *config);
int fapi_nr_p5_message_unpack(void *pMessageBuf,
bool fapi_nr_p5_message_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
+2 -1
View File
@@ -23,7 +23,7 @@
#define OPENAIRINTERFACE_NR_FAPI_P5_UTILS_H
#include "stdio.h"
#include "stdint.h"
#include "nr_fapi.h"
#include "nfapi/open-nFAPI/fapi/inc/nr_fapi.h"
#include "nfapi/oai_integration/vendor_ext.h"
bool eq_param_request(const nfapi_nr_param_request_scf_t *unpacked_req, const nfapi_nr_param_request_scf_t *req);
@@ -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);
+1 -1
View File
@@ -23,7 +23,7 @@
int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config);
int fapi_nr_p7_message_unpack(void *pMessageBuf,
bool fapi_nr_p7_message_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
+1 -1
View File
@@ -33,7 +33,7 @@
#define OPENAIRINTERFACE_NR_FAPI_P7_UTILS_H
#include "stdio.h"
#include "stdint.h"
#include "nr_fapi.h"
#include "nfapi/open-nFAPI/fapi/inc/nr_fapi.h"
bool eq_dl_tti_request(const nfapi_nr_dl_tti_request_t *a, const nfapi_nr_dl_tti_request_t *b);
bool eq_ul_tti_request(const nfapi_nr_ul_tti_request_t *a, const nfapi_nr_ul_tti_request_t *b);
+20 -8
View File
@@ -54,7 +54,6 @@ bool isFAPIMessageIDValid(const uint16_t id)
int check_nr_fapi_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen)
{
int retLen = 0;
// check for size of nFAPI struct without the nFAPI specific parameters
switch (msgId) {
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
@@ -165,24 +164,37 @@ int check_nr_fapi_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpacked
return retLen;
}
int fapi_nr_message_header_unpack(uint8_t **pMessageBuf,
bool fapi_nr_p7_message_header_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p7_codec_config_t *config)
{
return fapi_nr_message_header_unpack(pMessageBuf,
messageBufLen,
pUnpackedBuf,
unpackedBufLen,
NULL);
}
bool fapi_nr_message_header_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p4_p5_codec_config_t *config)
{
uint8_t **pReadPackedMessage = pMessageBuf;
uint8_t *pReadPackedMessage = pMessageBuf;
nfapi_nr_p4_p5_message_header_t *header = pUnpackedBuf;
fapi_message_header_t fapi_msg = {0};
if (pMessageBuf == NULL || pUnpackedBuf == NULL || messageBufLen < NFAPI_HEADER_LENGTH
|| unpackedBufLen < sizeof(fapi_message_header_t)) {
return -1;
return false;
}
uint8_t *end = *pMessageBuf + messageBufLen;
uint8_t *end = pMessageBuf + messageBufLen;
// process the header
int result =
(pull8(pReadPackedMessage, &fapi_msg.num_msg, end) && pull8(pReadPackedMessage, &fapi_msg.opaque_handle, end)
&& pull16(pReadPackedMessage, &header->message_id, end) && pull32(pReadPackedMessage, &header->message_length, end));
return (result);
(pull8(&pReadPackedMessage, &fapi_msg.num_msg, end) && pull8(&pReadPackedMessage, &fapi_msg.opaque_handle, end)
&& pull16(&pReadPackedMessage, &header->message_id, end) && pull32(&pReadPackedMessage, &header->message_length, end));
return result != 0;
}
+9 -11
View File
@@ -128,41 +128,39 @@ int fapi_nr_p5_message_pack(void *pMessageBuf,
return packedMsgLen;
}
int fapi_nr_p5_message_unpack(void *pMessageBuf,
bool fapi_nr_p5_message_unpack(void *pMessageBuf,
const uint32_t messageBufLen,
void *pUnpackedBuf,
const uint32_t unpackedBufLen,
nfapi_p4_p5_codec_config_t *config)
{
fapi_message_header_t *pMessageHeader = pUnpackedBuf;
uint8_t *pReadPackedMessage = pMessageBuf;
AssertFatal(pMessageBuf != NULL && pUnpackedBuf != NULL, "P5 unpack supplied pointers are null");
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
AssertFatal(messageBufLen >= NFAPI_HEADER_LENGTH && unpackedBufLen >= sizeof(fapi_message_header_t),
"P5 unpack supplied message buffer is too small %d, %d\n",
messageBufLen,
unpackedBufLen);
// clean the supplied buffer for - tag value blanking
(void)memset(pUnpackedBuf, 0, unpackedBufLen);
if (fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, pMessageHeader, sizeof(fapi_message_header_t), 0)
< 0) {
if (!fapi_nr_message_header_unpack(pMessageBuf, NFAPI_HEADER_LENGTH, pMessageHeader, sizeof(fapi_message_header_t), 0)) {
// failed to read the header
return -1;
return false;
}
uint8_t *pReadPackedMessage = pMessageBuf + NFAPI_HEADER_LENGTH;
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
int result = -1;
if (check_nr_fapi_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) {
// the unpack buffer is not big enough for the struct
return -1;
return false;
}
// look for the specific message
switch (pMessageHeader->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
// PARAM request has no body;
result = 0;
result = 1;
break;
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
@@ -210,7 +208,7 @@ int fapi_nr_p5_message_unpack(void *pMessageBuf,
break;
}
return result;
return result != 0;
}
uint8_t pack_nr_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config)
@@ -1349,7 +1347,7 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
nfapi_tl_t generic_tl;
uint8_t numBadTags = 0;
unsigned long idx = 0;
while ((uint8_t *)(*ppReadPackedMsg) < end) {
while ((uint8_t *)(*ppReadPackedMsg) + 4 < end) {
// unpack the tl and process the values accordingly
if (unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
return 0;
+6 -22
View File
@@ -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--;
}
+9 -10
View File
@@ -134,7 +134,7 @@ int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packed
return packedMsgLen;
}
int fapi_nr_p7_message_unpack(void *pMessageBuf,
bool fapi_nr_p7_message_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
@@ -143,25 +143,24 @@ int fapi_nr_p7_message_unpack(void *pMessageBuf,
int result = 0;
nfapi_nr_p7_message_header_t *pMessageHeader = (nfapi_nr_p7_message_header_t *)pUnpackedBuf;
fapi_message_header_t fapi_hdr;
uint8_t *pReadPackedMessage = pMessageBuf;
AssertFatal(pMessageBuf != NULL && pUnpackedBuf != NULL, "P7 unpack supplied pointers are null");
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
AssertFatal(messageBufLen >= NFAPI_HEADER_LENGTH && unpackedBufLen >= sizeof(fapi_message_header_t),
"P5 unpack supplied message buffer is too small %d, %d\n",
messageBufLen,
unpackedBufLen);
if (fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &fapi_hdr, sizeof(fapi_message_header_t), 0) < 0) {
if (!fapi_nr_message_header_unpack(pMessageBuf, NFAPI_HEADER_LENGTH, &fapi_hdr, sizeof(fapi_message_header_t), 0)) {
// failed to read the header
return -1;
return false;
}
uint8_t *pReadPackedMessage = pMessageBuf + NFAPI_HEADER_LENGTH;
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
pMessageHeader->message_length = fapi_hdr.message_length;
pMessageHeader->message_id = fapi_hdr.message_id;
if ((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
return -1;
return false;
}
// look for the specific message
@@ -232,9 +231,9 @@ int fapi_nr_p7_message_unpack(void *pMessageBuf,
if (result == 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Unpack failed to unpack message\n");
return -1;
return false;
}
return 0;
return true;
}
static uint8_t pack_nr_tx_beamforming_pdu(const nfapi_nr_tx_precoding_and_beamforming_t *beamforming_pdu,
@@ -28,8 +28,11 @@
#define NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH 3
#define NFAPI_MAX_NUM_RF_BANDS 16
#ifdef ENABLE_WLS
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 1024*1024*2
#else
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
#endif
// The following definition control the size of arrays used in the interface.
// These may be changed if desired. They are used in the encoder to make sure
// that the user has not specified a 'count' larger than the max array, and also
@@ -115,7 +118,8 @@ typedef struct {
#define NFAPI_P7_GET_MORE(_mss) ( ((_mss) & 0x8000) >> 15 )
#define NFAPI_P7_GET_SEGMENT(_mss) ( ((_mss) & 0x7F00) >> 8 )
#define NFAPI_P7_GET_SEQUENCE(_mss) ( (_mss) & 0x00FF )
#define NFAPI_P7_SET_MSS(_more, _segm, _sequ) ( (((_more) & 0x1) << 7) | (((_segm) & 0x7) << 4) | ((_sequ) & 0xF) )
#define NFAPI_NR_P7_SET_MSS(_more, _segm, _sequ) ( (((_more) & 0x1) << 15) | (((_segm) & 0x7F) << 8) | ((_sequ) & 0xFF) )
#define NFAPI_P7_SET_MSS(_more, _segm, _sequ) ( (((_more) & 0x1) << 7) | (((_segm) & 0x7F) << 4) | ((_sequ) & 0xF) )
#define NFAPI_TAG_LENGTH_PACKED_LEN 4
@@ -110,11 +110,11 @@ uint8_t pack_nr_p5_message_body(nfapi_nr_p4_p5_message_header_t *header,
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return 10 ( size of the unpacked header ) on success, -1 on failure.
* \return true on success, false on failure.
*
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 header structure pointed to by pUnpackedBuf
*/
int nfapi_nr_p5_message_header_unpack(void *pMessageBuf,
bool nfapi_nr_p5_message_header_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
@@ -126,11 +126,11 @@ int nfapi_nr_p5_message_header_unpack(void *pMessageBuf,
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return != -1 means success, -1 means failure.
* \return true on success, false on failure.
*
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf
*/
int nfapi_nr_p5_message_unpack(void *pMessageBuf,
bool nfapi_nr_p5_message_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
@@ -154,13 +154,13 @@ int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packe
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return 0 means success, -1 means failure.
* \return true on success, false on failure.
*
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi_p7_message_header structure pointer to by
pUnpackedBuf
*/
int nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
bool nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
@@ -172,11 +172,11 @@ int nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return 0 means success, -1 means failure.
* \return true on success, false failure.
*
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p7 message structure pointer to by pUnpackedBuf
*/
int nfapi_nr_p7_message_unpack(void *pMessageBuf,
bool nfapi_nr_p7_message_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
@@ -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 {
+11 -11
View File
@@ -2325,7 +2325,7 @@ int nfapi_p5_message_header_unpack(void *pMessageBuf,
return 8;
}
int nfapi_nr_p5_message_header_unpack(void *pMessageBuf,
bool nfapi_nr_p5_message_header_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
@@ -2336,25 +2336,25 @@ int nfapi_nr_p5_message_header_unpack(void *pMessageBuf,
if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied pointers are null\n");
return -1;
return false;
}
uint8_t *end = pMessageBuf + messageBufLen;
if (messageBufLen < NFAPI_NR_P5_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_nr_p4_p5_message_header_t)) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
return -1;
return false;
}
// process the header
if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
&& pull32(&pReadPackedMessage, &pMessageHeader->message_length, end)
&& pull16(&pReadPackedMessage, &pMessageHeader->spare, end))) {
return -1;
return false;
}
return NFAPI_NR_P5_HEADER_LENGTH;
return true;
}
int nfapi_nr_p5_message_unpack(void *pMessageBuf,
bool nfapi_nr_p5_message_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
@@ -2362,11 +2362,11 @@ int nfapi_nr_p5_message_unpack(void *pMessageBuf,
{
if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied pointers are null\n");
return -1;
return false;
}
if (messageBufLen < NFAPI_NR_P5_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_nr_p4_p5_message_header_t)) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
return -1;
return false;
}
nfapi_nr_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
@@ -2374,7 +2374,7 @@ int nfapi_nr_p5_message_unpack(void *pMessageBuf,
(void)memset(pUnpackedBuf, 0, unpackedBufLen);
// process the header
if (!nfapi_nr_p5_message_header_unpack(pMessageBuf, messageBufLen, pMessageHeader, unpackedBufLen, config)) {
return -1;
return false;
}
uint8_t *pReadPackedMessage = pMessageBuf + NFAPI_NR_P5_HEADER_LENGTH;
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
@@ -2382,7 +2382,7 @@ int nfapi_nr_p5_message_unpack(void *pMessageBuf,
if (check_nr_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) {
// the unpack buffer is not big enough for the struct
return -1;
return false;
}
// look for the specific message
@@ -2476,7 +2476,7 @@ int nfapi_nr_p5_message_unpack(void *pMessageBuf,
break;
}
return result;
return result == 1;
}
int nfapi_p5_message_unpack(void *pMessageBuf,
+19 -12
View File
@@ -5930,7 +5930,7 @@ int nfapi_p7_message_header_unpack(void *pMessageBuf,
return 0;
}
int nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
bool nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
@@ -5941,14 +5941,14 @@ int nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied pointers are null\n");
return -1;
return false;
}
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
if (messageBufLen < NFAPI_NR_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_nr_p7_message_header_t)) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
return -1;
return false;
}
// process the header
if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
@@ -5956,9 +5956,9 @@ int nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
&& pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end)
&& pull32(&pReadPackedMessage, &pMessageHeader->checksum, end)
&& pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
return -1;
return false;
return 0;
return true;
}
int nfapi_p7_message_unpack(void *pMessageBuf,
@@ -6203,7 +6203,14 @@ int nfapi_p7_message_unpack(void *pMessageBuf,
bool peek_nr_nfapi_p7_sfn_slot(void *pMessageBuf, uint32_t messageBufLen, uint16_t *SFN, uint16_t *Slot)
{
#ifdef ENABLE_SOCKET
// Socket transport will always use nFAPI encoding
uint8_t *pReadPackedMessage = &((uint8_t *)pMessageBuf)[NFAPI_NR_P7_HEADER_LENGTH];
#endif
#ifdef ENABLE_WLS
// WLS transport will always use FAPI encoding
uint8_t *pReadPackedMessage = &((uint8_t *)pMessageBuf)[NFAPI_HEADER_LENGTH];
#endif
uint8_t *end = (uint8_t*)pMessageBuf + messageBufLen;
if(!(pull16(&pReadPackedMessage, SFN, end) && pull16(&pReadPackedMessage, Slot, end))) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to peek SFN.Slot\n");
@@ -6213,7 +6220,7 @@ bool peek_nr_nfapi_p7_sfn_slot(void *pMessageBuf, uint32_t messageBufLen, uint16
return true;
}
int nfapi_nr_p7_message_unpack(void *pMessageBuf,
bool nfapi_nr_p7_message_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
@@ -6225,14 +6232,14 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf,
if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n");
return -1;
return false;
}
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
if (messageBufLen < NFAPI_NR_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_nr_p7_message_header_t)) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
return -1;
return false;
}
// process the header
@@ -6242,11 +6249,11 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf,
&& pull32(&pReadPackedMessage, &pMessageHeader->checksum, end)
&& pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n");
return -1;
return false;
}
if ((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
return -1;
return false;
}
/*
@@ -6356,7 +6363,7 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf,
if (result == 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
return -1;
return false;
}
return 0;
return true;
}
+13 -5
View File
@@ -20,9 +20,8 @@
#include "nfapi_pnf_interface.h"
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
typedef struct {
struct pnf_t {
nfapi_pnf_config_t _public;
@@ -33,19 +32,28 @@ typedef struct {
uint8_t terminate;
} pnf_t;
};
int pnf_connect(pnf_t *pnf);
int pnf_message_pump(pnf_t *pnf);
int pnf_nr_message_pump(pnf_t *pnf);
int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_nr_p4_p5_message_header_t* msg, uint32_t msg_len);
void pnf_nr_handle_p5_message(pnf_t* pnf, void* pRecvMsg, int recvMsgLen);
int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_send_message(pnf_t* pnf, uint8_t* msg, uint32_t msg_len, uint16_t stream_id);
nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, uint16_t phy_id);
void pnf_nr_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen);
void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen);
void pnf_nr_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen);
void pnf_handle_pnf_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen);
void pnf_nr_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen);
void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen);
void pnf_nr_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen);
void pnf_nr_handle_stop_request(pnf_t* pnf, void* pRecvMsg, int recvMsgLen);
#endif // _PNF_H_
+8 -7
View File
@@ -25,7 +25,6 @@
#include "nfapi_pnf_interface.h"
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
typedef struct {
uint16_t dl_conf_ontime;
@@ -82,7 +81,7 @@ typedef struct {
} pnf_p7_rx_reassembly_queue_t;
typedef struct {
struct pnf_p7_t {
nfapi_pnf_p7_config_t _public;
@@ -139,12 +138,11 @@ typedef struct {
pnf_p7_stats_t stats;
pnf_p7_nr_stats_t nr_stats;
} pnf_p7_t;
};
int pnf_p7_message_pump(pnf_p7_t* pnf_p7);
int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7);
int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len);
int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_header_t* header, uint32_t msg_len);
int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
@@ -159,8 +157,11 @@ int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indica
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len);
void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg);
void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta);
int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_header_t* header, uint32_t msg_len);
void pnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t *pnf_p7, uint32_t rx_hr_time);
struct timespec pnf_timespec_sub(struct timespec lhs, struct timespec rhs);
uint32_t pnf_get_current_time_hr(void);
struct timespec pnf_timespec_add(struct timespec lhs, struct timespec rhs);
void pnf_p7_free(pnf_p7_t* pnf_p7, void* ptr);
void* pnf_p7_malloc(pnf_p7_t* pnf_p7, size_t size);
#endif /* _PNF_P7_H_ */
@@ -31,8 +31,8 @@ extern "C" {
#include <sys/types.h>
#include "openair1/PHY/defs_gNB.h"
typedef struct pnf_t pnf_t;
typedef struct pnf_p7_t pnf_p7_t;
/*! This enum is used to describe the states of the pnf
*/
@@ -319,8 +319,60 @@ typedef struct nfapi_pnf_config
*/
void (*deallocate_p4_p5_vendor_ext)(void* header);
/*! \brief Encodes an (n)FAPI P5 message to a buffer
*
* This function is called internally in send_p5_msg()
* \param pMessageBuf A pointer to a nfapi p5 message structure
* \param messageBufLen The size of the p5 message structure
* \param pPackedBuf A pointer to the buffer that the p5 message will be packed into
* \param packedBufLen The size of the buffer
* \param config A pointer to the nfapi configuration structure
* \return != 0 means success, -1 means failure.
*/
int (*pack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pPackedBuf,
uint32_t packedBufLen,
nfapi_p4_p5_codec_config_t* config);
/*! \brief Decodes a (n)FAPI P5 message
* \param pMessageBuf A pointer to an encoded P5 message
* \param messageBufLen The size of the encoded P5 message
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true on success, false on failure.
*/
bool (*unpack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p4_p5_codec_config_t* config);
/*! \brief Decodes an (n)FAPI P5 message header
* \param pMessageBuf A pointer to an encoded P5 message header
* \param messageBufLen The size of the encoded P5 message header
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true on success, false on failure.
*/
bool (*hdr_unpack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p4_p5_codec_config_t* config);
/*! \brief Sends a (N)FAPI P5 message
*
* This function internally packs the given message into a buffer by calling the previously defined pack_func() function pointer
* Then, having the message buffer populated, sends it to the VNF
* \param pnf A pointer to a pnf_t*
* \param msg A pointer to the P5 message
* \param msg_len The size of the encoded P5 message
* \return true on success, false on failure.
*/
bool (*send_p5_msg)(pnf_t* pnf, nfapi_nr_p4_p5_message_header_t* msg, uint32_t msg_len);
} nfapi_pnf_config_t;
/*! Create a pnf configuration
@@ -367,7 +419,6 @@ int nfapi_pnf_config_destroy(nfapi_pnf_config_t* config);
* \endcode
*/
int nfapi_pnf_start(nfapi_pnf_config_t* config);
int nfapi_nr_pnf_start(nfapi_pnf_config_t* config);
/*! Stop the PNF library.
* \param config A pointer to the pnf configuration
@@ -726,8 +777,55 @@ typedef struct nfapi_pnf_p7_config
*/
void (*deallocate_p7_vendor_ext)(void* header);
/*! A callback to pack a P7 message
*
* This function is called internally in send_p7_msg()
* \param pMessageBuf A pointer to a nfapi p7 message structure
* \param pPackedBuf A pointer to the buffer that the p7 message will be packed into
* \param packedBufLen The size of the buffer
* \param config A pointer to the nfapi configuration structure
* \return != -1 means success, -1 means failure.
*/
int (*pack_func)(void* pMessageBuf, void* pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
/*! A callback to unpack a P7 message
* \param pMessageBuf A pointer to an encoded P7 message header
* \param messageBufLen The size of the encoded P7 message header
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true success, false on failure.
*/
bool (*unpack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p7_codec_config_t* config);
/*! \brief Decodes a NFAPI P7 message header
* \param pMessageBuf A pointer to an encoded P5 message header
* \param messageBufLen The size of the encoded P5 message header
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true on success, false on failure.
*/
bool (*hdr_unpack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p7_codec_config_t* config);
/*! \brief Sends a (N)FAPI P7 message
*
* This function internally packs the given message into a buffer by calling the previously defined pack_func() function pointer
* Then, having the message buffer populated, sends it to the VNF
* \param pnf_p7 A pointer to a pnf_p7_t struct
* \param header A pointer to the P7 message to pack & send
* \param msg_len The P7 message length
* \return true on success, false on failure.
*/
bool (*send_p7_msg)(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_header_t* header, uint32_t msg_len);
} nfapi_pnf_p7_config_t;
/*! Create and initialise a nfapi_pnf_p7_config structure
@@ -748,7 +846,7 @@ int nfapi_pnf_p7_config_destroy(nfapi_pnf_p7_config_t* config);
* This function will not return until nfapi_pnf_p7_stop is called.
*/
int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config);
/*! Stop the PNF P7 library.
* \param config A pointer to a PNF P7 config
+61 -236
View File
@@ -30,6 +30,10 @@
#include "nfapi_nr_interface_scf.h"
#include "pnf.h"
#include <socket/include/socket_common.h>
#include "nfapi/open-nFAPI/fapi/inc/nr_fapi.h"
# if 1 // for hard-code (remove later)
#include "common/platform_types.h"
#include "common/platform_constants.h"
@@ -45,7 +49,9 @@
#include "NR_MIB.h"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#ifdef ENABLE_WLS
#include "wls_integration/include/wls_pnf.h"
#endif
#endif
#define MAX_SCTP_STREAMS 16
@@ -95,8 +101,9 @@ void pnf_nr_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_PARAM.request received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(nfapi_nr_pnf_param_request_t), &pnf->_public.codec_config) >= 0)
/// The unpack() function pointer is not called here due to the only possibility of entering being on a nFAPI message
const bool result = nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(nfapi_nr_pnf_param_request_t), &pnf->_public.codec_config);
if (result)
{
if(pnf->_public.state == NFAPI_PNF_IDLE)
{
@@ -251,8 +258,9 @@ void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_CONFIG.request received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0)
/// The unpack() function pointer is not called here due to the only possibility of entering being on a nFAPI message
const bool result = nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config);
if (result)
{
// ensure correct state
if(pnf->_public.state != NFAPI_PNF_RUNNING)
@@ -357,8 +365,9 @@ void pnf_nr_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_START.request Received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0)
/// The unpack() function pointer is not called here due to the only possibility of entering being on a nFAPI message
const bool result = nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config);
if (result)
{
if(pnf->_public.state == NFAPI_PNF_CONFIGURED)
{
@@ -517,7 +526,8 @@ void pnf_nr_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
NFAPI_TRACE(NFAPI_TRACE_INFO, "PARAM.request received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
const bool result = pnf->_public.unpack_func(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config);
if (result)
{
if(config->state == NFAPI_PNF_RUNNING)
{
@@ -662,7 +672,8 @@ void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
nfapi_pnf_config_t* config = &(pnf->_public);
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
const bool result = pnf->_public.unpack_func(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config);
if (result)
{
if(config->state == NFAPI_PNF_RUNNING)
{
@@ -806,7 +817,8 @@ void pnf_nr_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() START.request received state:%d\n", __FUNCTION__, config->state);
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
const bool result = pnf->_public.unpack_func(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config);
if (result)
{
if(config->state == NFAPI_PNF_RUNNING)
{
@@ -945,7 +957,8 @@ void pnf_nr_handle_stop_request(pnf_t* pnf, void* pRecvMsg, int recvMsgLen)
nfapi_pnf_config_t* config = &(pnf->_public);
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) {
const bool result = pnf->_public.unpack_func(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config);
if (result) {
if (config->state == NFAPI_PNF_RUNNING) {
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
if (phy) {
@@ -1525,12 +1538,8 @@ void pnf_nr_handle_p5_message(pnf_t* pnf, void* pRecvMsg, int recvMsgLen)
}
// unpack the message header
if (nfapi_nr_p5_message_header_unpack(pRecvMsg,
recvMsgLen,
&messageHeader,
sizeof(nfapi_nr_p4_p5_message_header_t),
&pnf->_public.codec_config)
< 0) {
const bool result = pnf->_public.hdr_unpack_func(pRecvMsg, recvMsgLen, &messageHeader, sizeof(messageHeader), &pnf->_public.codec_config);
if (!result) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
}
@@ -1702,20 +1711,6 @@ void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_nr_p4_p5_message_header_t* msg, uint32_t msg_len)
{
int packed_len =
nfapi_nr_p5_message_pack(msg, msg_len, pnf->tx_message_buffer, sizeof(pnf->tx_message_buffer), &pnf->_public.codec_config);
if (packed_len < 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_nr_p5_message_pack failed (%d)\n", packed_len);
return -1;
}
return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0 /*msg->stream_id*/);
}
int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len)
{
int packed_len = nfapi_p5_message_pack(msg, msg_len,
@@ -1748,8 +1743,6 @@ int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg,
return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0/*msg->stream_id*/);
}
int pnf_connect(pnf_t* pnf)
{
struct sockaddr_in servaddr;
@@ -1932,7 +1925,20 @@ int pnf_connect(pnf_t* pnf)
socketConnected = 1;
}
}
} else {
int error;
socklen_t len = sizeof(error);
if (getsockopt(pnf->p5_sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After getsockopt errno: %d\n", errno);
return -1;
} else {
// If error is zero, the socket is connected
if (error == 0) {
socketConnected = 1;
}
}
}
NFAPI_TRACE(NFAPI_TRACE_NOTE, "Socket %s\n", socketConnected ? "CONNECTED" : "NOT_CONNECTED");
return socketConnected;
@@ -1941,30 +1947,30 @@ int pnf_connect(pnf_t* pnf)
int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream)
{
if (pnf->sctp)
{
if (pnf->sctp)
{
#if 0
printf("\nPNF SENDS: \n");
for(int i=0; i<len; i++){
printf("%d", msg[i]);
}
printf("\n");
printf("\nPNF SENDS: \n");
for(int i=0; i<len; i++){
printf("%d", msg[i]);
}
printf("\n");
#endif
if (sctp_sendmsg(pnf->p5_sock, msg, len, NULL, 0, 42/*config->sctp_stream_number*/, 0, stream/*P5_STREAM_ID*/, 0, 0) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "sctp_sendmsg failed errno: %d\n", errno);
return -1;
}
}
else
{
if (write(pnf->p5_sock, msg, len) != len)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "read failed errno: %d\n", errno);
return -1;
}
}
if (sctp_sendmsg(pnf->p5_sock, msg, len, NULL, 0, 42/*config->sctp_stream_number*/, 0, stream/*P5_STREAM_ID*/, 0, 0) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "sctp_sendmsg failed errno: %d\n", errno);
return -1;
}
}
else
{
if (write(pnf->p5_sock, msg, len) != len)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "read failed errno: %d\n", errno);
return -1;
}
}
return 0;
}
@@ -2101,126 +2107,6 @@ int pnf_read_dispatch_message(pnf_t* pnf)
}
int pnf_nr_read_dispatch_message(pnf_t* pnf)
{
int socket_connected = 1;
// 1. Peek the message header
// 2. If the message is larger than the stack buffer then create a dynamic buffer
// 3. Read the buffer
// 4. Handle the p5 message
uint32_t header_buffer_size = NFAPI_NR_P5_HEADER_LENGTH;
uint8_t header_buffer[header_buffer_size];
uint32_t stack_buffer_size = 32; // should it be the size of then sctp_notificatoin structure
uint8_t stack_buffer[stack_buffer_size];
uint8_t* dynamic_buffer = 0;
uint8_t* read_buffer = &stack_buffer[0];
uint32_t message_size = 0;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
struct sctp_sndrcvinfo sndrcvinfo;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
{
int flags = MSG_PEEK;
message_size = sctp_recvmsg(pnf->p5_sock,
header_buffer,
header_buffer_size,
/*(struct sockaddr*)&addr, &addr_len*/ 0,
0,
&sndrcvinfo,
&flags);
if (message_size == -1) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to peek sctp message size errno:%d\n", errno);
return 0;
}
nfapi_nr_p4_p5_message_header_t header;
int unpack_result = nfapi_nr_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
if (unpack_result < 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n");
return 0;
}
message_size = header.message_length + header_buffer_size;
// now have the size of the mesage
}
if (message_size > stack_buffer_size) {
dynamic_buffer = (uint8_t*)malloc(message_size);
if (dynamic_buffer == NULL) {
// todo : add error mesage
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size);
return -1;
}
read_buffer = dynamic_buffer;
}
{
int flags = 0;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
int recvmsg_result =
sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
if (recvmsg_result == -1) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno);
} else {
#if 0
// print the received message
printf("\n MESSAGE RECEIVED: \n");
for(int i=0; i<message_size; i++){
printf("read_buffer[%d] = 0x%02x\n",i, read_buffer[i]);
}
printf("\n");
#endif
if (flags & MSG_NOTIFICATION) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
// todo - handle the events
} else {
/*
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n",
pnf->p5_sock,
inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port),
sndrcvinfo.sinfo_assoc_id,
sndrcvinfo.sinfo_stream,
ntohl(sndrcvinfo.sinfo_ppid),
message_size,
flags);
*/
// handle now if complete message in one or more segments
if ((flags & 0x80) == 0x80) {
pnf_nr_handle_p5_message(pnf, read_buffer, message_size);
} else {
NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags);
// assume socket disconnected
NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n");
socket_connected = 0;
}
}
}
}
if (dynamic_buffer) {
free(dynamic_buffer);
}
return socket_connected;
}
int pnf_message_pump(pnf_t* pnf)
{
uint8_t socketConnected = 1;
@@ -2272,67 +2158,6 @@ int pnf_message_pump(pnf_t* pnf)
pnf->_public.state = NFAPI_PNF_IDLE;
// close the connection and socket
if (close(pnf->p5_sock) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "close(sctpSock) failed errno: %d\n", errno);
}
return 0;
}
int pnf_nr_message_pump(pnf_t* pnf)
{
uint8_t socketConnected = 1;
while(socketConnected && pnf->terminate == 0)
{
fd_set rfds;
int selectRetval = 0;
// select on a timeout and then get the message
FD_ZERO(&rfds);
FD_SET(pnf->p5_sock, &rfds);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
selectRetval = select(pnf->p5_sock+1, &rfds, NULL, NULL, &timeout);
if(selectRetval == 0)
{
// timeout
continue;
}
else if (selectRetval == -1 && (errno == EINTR))
{
// interrupted by signal
NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 Signal Interrupt %d\n", errno);
continue;
}
else if (selectRetval == -1)
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 select() failed\n");
sleep(1);
continue;
}
if(FD_ISSET(pnf->p5_sock, &rfds))
{
socketConnected = pnf_nr_read_dispatch_message(pnf);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "Why are we here\n");
}
}
// Drop back to idle if we have lost connection
pnf->_public.state = NFAPI_PNF_IDLE;
// close the connection and socket
if (close(pnf->p5_sock) < 0)
{
+12 -42
View File
@@ -79,36 +79,6 @@ int nfapi_pnf_start(nfapi_pnf_config_t* config)
return 0;
}
int nfapi_nr_pnf_start(nfapi_pnf_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
pnf_t* _this = (pnf_t*)(config);
while (_this->terminate == 0)
{
int connect_result = pnf_connect(_this);
if(connect_result > 0)
{
pnf_nr_message_pump(_this);
}
else if(connect_result < 0)
{
return connect_result;
}
sleep(1);
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() terminate=1 - EXITTING............\n", __FUNCTION__);
return 0;
}
int nfapi_pnf_stop(nfapi_pnf_config_t* config)
{
// Verify that config is not null
@@ -135,8 +105,8 @@ int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_r
}
pnf_t* _this = (pnf_t*)(config);
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_param_response_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured!");
return config->send_p5_msg(_this, &(resp->header), sizeof(nfapi_nr_pnf_param_response_t));
}
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp)
@@ -188,8 +158,8 @@ int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config
}
pnf_t* _this = (pnf_t*)(config);
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_config_response_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured|");
return config->send_p5_msg(_this, &(resp->header), sizeof(nfapi_nr_pnf_config_response_t));
}
@@ -227,8 +197,8 @@ int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_r
}
pnf_t* _this = (pnf_t*)(config);
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_start_response_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured|");
return config->send_p5_msg(_this, &(resp->header), sizeof(nfapi_nr_pnf_start_response_t));
}
@@ -273,8 +243,8 @@ int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_
}
pnf_t* _this = (pnf_t*)(config);
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_param_response_scf_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured|");
return config->send_p5_msg(_this, &(resp->header), sizeof(nfapi_nr_param_response_scf_t));
}
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp)
@@ -329,8 +299,8 @@ int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_respons
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id);
return -1;
}
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_config_response_scf_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured|");
return config->send_p5_msg(_this, &(resp->header), sizeof(nfapi_nr_config_response_scf_t));
}
@@ -384,8 +354,8 @@ int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknown phy id %d\n", __FUNCTION__, resp->header.phy_id);
return -1;
}
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_start_response_scf_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured|");
return config->send_p5_msg(_this, &(resp->header), sizeof(nfapi_nr_start_response_scf_t));
}
+25 -457
View File
@@ -32,7 +32,6 @@
#include "common/ran_context.h"
#include <SCHED_NR/phy_frame_config_nr.h>
#define FAPI2_IP_DSCP 0
extern int sf_ahead;
@@ -464,10 +463,10 @@ int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t len)
socklen_t remote_addr_len = sizeof(struct sockaddr_in);
int sendto_result;
if ((sendto_result = sendto((int)pnf_p7->p7_sock, (const char*)msg, len, 0, (const struct sockaddr*)&remote_addr, remote_addr_len)) < 0)
//if ((sendto_result = sendto((int)pnf_p7->p7_sock,"hello", 6, 0, (const struct sockaddr*)&remote_addr, remote_addr_len)) < 0)
{
if ((sendto_result = sendto((int)pnf_p7->p7_sock, (const char*)msg, len, 0, (const struct sockaddr*)&remote_addr, remote_addr_len)) < 0)
//if ((sendto_result = sendto((int)pnf_p7->p7_sock,"hello", 6, 0, (const struct sockaddr*)&remote_addr, remote_addr_len)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s %s:%d sendto(%d, %p, %d) %d failed errno: %d\n", __FUNCTION__, pnf_p7->_public.remote_p7_addr, pnf_p7->_public.remote_p7_port, (int)pnf_p7->p7_sock, (const char*)msg, len, remote_addr_len, errno);
return -1;
}
@@ -569,87 +568,6 @@ int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t*
return 0;
}
int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_header_t* header, uint32_t msg_len)
{
header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, pnf_p7->sequence_number);
// Need to guard against different threads calling the encode function at the same time
if (pthread_mutex_lock(&(pnf_p7->pack_mutex)) != 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
return -1;
}
uint8_t tx_buf[131072]; // four times NFAPI_MAX_PACKED_MESSAGE_SIZE as of this commit
int len = nfapi_nr_p7_message_pack(header, tx_buf, sizeof(tx_buf), &pnf_p7->_public.codec_config);
if (len < 0) {
if (pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p7_message_pack failed with return %d\n", len);
return -1;
}
if (len > pnf_p7->_public.segment_size) {
int msg_body_len = len - NFAPI_NR_P7_HEADER_LENGTH;
int seg_body_len = pnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH;
int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0);
int segment = 0;
int offset = NFAPI_NR_P7_HEADER_LENGTH;
uint8_t buffer[pnf_p7->_public.segment_size];
for (segment = 0; segment < segment_count; ++segment) {
uint8_t last = 0;
uint32_t size = pnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH;
if (segment + 1 == segment_count) {
last = 1;
size = (msg_body_len) - (seg_body_len * segment);
}
uint32_t segment_size = size + NFAPI_NR_P7_HEADER_LENGTH;
// Update the header with the m and segement
memcpy(&buffer[0], tx_buf, NFAPI_NR_P7_HEADER_LENGTH);
// set the segment length
buffer[4] = (segment_size & 0xFF000000) >> 24;
buffer[5] = (segment_size & 0xFF0000) >> 16;
buffer[6] = (segment_size & 0xFF00) >> 8;
buffer[7] = (segment_size & 0xFF);
// set the m & segment number
buffer[8] = ((!last) << 7) + segment;
memcpy(&buffer[NFAPI_NR_P7_HEADER_LENGTH], tx_buf + offset, size);
offset += size;
if (pnf_p7->_public.checksum_enabled) {
nfapi_nr_p7_update_checksum(buffer, segment_size);
}
pnf_p7_send_message(pnf_p7, &buffer[0], segment_size);
}
} else {
if (pnf_p7->_public.checksum_enabled) {
nfapi_nr_p7_update_checksum(tx_buf, len);
}
// simple case that the message fits in a single segment
pnf_p7_send_message(pnf_p7, tx_buf, len);
}
pnf_p7->sequence_number++;
if (pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
return -1;
}
return 0;
}
void pnf_pack_and_send_timing_info(pnf_p7_t* pnf_p7)
{
nfapi_timing_info_t timing_info;
@@ -707,9 +625,8 @@ void pnf_nr_pack_and_send_timing_info(pnf_p7_t* pnf_p7)
timing_info.tx_data_request_earliest_arrival = 0;
timing_info.ul_tti_earliest_arrival = 0;
timing_info.ul_dci_earliest_arrival = 0;
pnf_nr_p7_pack_and_send_p7_message(pnf_p7, &(timing_info.header), sizeof(timing_info));
AssertFatal(pnf_p7->_public.send_p7_msg, "The function pointer to pack and send P7 messages must be set");
pnf_p7->_public.send_p7_msg(pnf_p7, &(timing_info.header), sizeof(timing_info));
pnf_p7->timing_info_ms_counter = 0;
}
@@ -1299,8 +1216,8 @@ void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
frame,
slot,
buffer_index);
if (nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(*req), &(pnf_p7->_public.codec_config)) != 0)
const bool result = pnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, req, sizeof(*req), &(pnf_p7->_public.codec_config));
if (!result)
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unpack request\n");
} else {
if (pnf_p7->_public.timing_info_mode_aperiodic)
@@ -1432,8 +1349,8 @@ void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
frame,
slot,
buffer_index);
if (nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(*req), &(pnf_p7->_public.codec_config)) != 0)
const bool result = pnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, req, sizeof(*req), &(pnf_p7->_public.codec_config));
if (!result)
NFAPI_TRACE(NFAPI_TRACE_ERROR, "failed to unpack UL_TTI.request\n");
} else {
NFAPI_TRACE(NFAPI_TRACE_NOTE,
@@ -1551,8 +1468,8 @@ void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
frame,
slot,
buffer_index);
if (nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(*req), &pnf_p7->_public.codec_config) != 0)
const bool result = pnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, req, sizeof(*req), &(pnf_p7->_public.codec_config));
if (!result)
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unpack request\n");
} else {
if (pnf_p7->_public.timing_info_mode_aperiodic) {
@@ -1664,8 +1581,8 @@ void pnf_handle_tx_data_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
frame,
slot,
buffer_index);
if (nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(*req), &pnf_p7->_public.codec_config) == 0) {
const bool result = pnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, req, sizeof(*req), &(pnf_p7->_public.codec_config));
if (result) {
for (int i = 0; i < req->Number_of_PDUs; ++i)
pnf_p7->nr_stats.dl.bytes += req->pdu_list[i].PDU_length;
} else {
@@ -2063,7 +1980,8 @@ void pnf_nr_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
}
// unpack the message
if (nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &dl_node_sync, sizeof(dl_node_sync), &pnf_p7->_public.codec_config) < 0)
const bool result = pnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, &dl_node_sync, sizeof(dl_node_sync), &pnf_p7->_public.codec_config);
if (!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
return;
@@ -2096,8 +2014,8 @@ void pnf_nr_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
return;
}
pnf_nr_p7_pack_and_send_p7_message(pnf_p7, &(ul_node_sync.header), sizeof(ul_node_sync));
AssertFatal(pnf_p7->_public.send_p7_msg, "Function pointer must be configured|");
pnf_p7->_public.send_p7_msg(pnf_p7, &(ul_node_sync.header), sizeof(ul_node_sync));
//printf("\nSSent UL Node Sync sfn:%d,slot:%d\n",pnf_p7->sfn,pnf_p7->slot);
}
@@ -2171,7 +2089,7 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,
}
}
void pnf_nr_dispatch_p7_message(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
void pnf_nr_handle_p7_message(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
{
nfapi_nr_p7_message_header_t header;
@@ -2182,7 +2100,8 @@ void pnf_nr_dispatch_p7_message(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
}
// unpack the message header
if (nfapi_nr_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &pnf_p7->_public.codec_config) < 0) {
const bool result = pnf_p7->_public.hdr_unpack_func(pRecvMsg, recvMsgLen, &header, sizeof(header), &pnf_p7->_public.codec_config);
if (!result) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
}
@@ -2325,113 +2244,6 @@ void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, ui
}
void pnf_nr_handle_p7_message(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
{
nfapi_nr_p7_message_header_t messageHeader;
// validate the input params
if (pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "pnf_handle_p7_message: invalid input params (%p %d %p)\n", pRecvMsg, recvMsgLen, pnf_p7);
return;
}
// unpack the message header
if (nfapi_nr_p7_message_header_unpack(pRecvMsg,
recvMsgLen,
&messageHeader,
sizeof(nfapi_nr_p7_message_header_t),
&pnf_p7->_public.codec_config)
< 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
}
uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence);
uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence);
uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence);
if (pnf_p7->_public.checksum_enabled) {
uint32_t checksum = nfapi_nr_p7_calculate_checksum(pRecvMsg, recvMsgLen);
if (checksum != messageHeader.checksum) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d\n", checksum, messageHeader.checksum);
return;
}
}
if (m == 0 && segment_num == 0) {
// we have a complete message
// ensure the message is sensible
if (recvMsgLen < 8 || pRecvMsg == NULL) {
NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
return;
}
pnf_nr_dispatch_p7_message(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
} else {
pnf_p7_rx_message_t* rx_msg = pnf_p7_rx_reassembly_queue_add_segment(pnf_p7,
&(pnf_p7->reassembly_queue),
rx_hr_time,
sequence_num,
segment_num,
m,
pRecvMsg,
recvMsgLen);
if (rx_msg->num_segments_received == rx_msg->num_segments_expected) {
// send the buffer on
uint16_t i = 0;
uint32_t length = 0;
for (i = 0; i < rx_msg->num_segments_expected; ++i) {
length += rx_msg->segments[i].length - (i > 0 ? NFAPI_NR_P7_HEADER_LENGTH : 0);
}
if (pnf_p7->reassemby_buffer_size < length) {
pnf_p7_free(pnf_p7, pnf_p7->reassemby_buffer);
pnf_p7->reassemby_buffer = 0;
}
if (pnf_p7->reassemby_buffer == 0) {
NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing PNF_P7 Reassembly buffer %d->%d\n", pnf_p7->reassemby_buffer_size, length);
pnf_p7->reassemby_buffer = (uint8_t*)pnf_p7_malloc(pnf_p7, length);
if (pnf_p7->reassemby_buffer == 0) {
NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate PNF_P7 reassemby buffer len:%d\n", length);
return;
}
memset(pnf_p7->reassemby_buffer, 0, length);
pnf_p7->reassemby_buffer_size = length;
}
uint32_t offset = 0;
for (i = 0; i < rx_msg->num_segments_expected; ++i) {
if (i == 0) {
memcpy(pnf_p7->reassemby_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length);
offset += rx_msg->segments[i].length;
} else {
memcpy(pnf_p7->reassemby_buffer + offset,
rx_msg->segments[i].buffer + NFAPI_NR_P7_HEADER_LENGTH,
rx_msg->segments[i].length - NFAPI_NR_P7_HEADER_LENGTH);
offset += rx_msg->segments[i].length - NFAPI_NR_P7_HEADER_LENGTH;
}
}
pnf_nr_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time);
// delete the structure
pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7, &(pnf_p7->reassembly_queue), rx_msg);
}
}
// The timeout used to be 1000, i.e., 1ms, which is too short. The below 10ms
// is selected to be able to encompass any "reasonable" slot ahead time for the VNF.
// Ideally, we would remove old msg (segments) if we detect packet loss
// (e.g., if the sequence numbers advances sufficiently); in the branch of
// this commit, our goal is to make the PNF work, so we content ourselves to
// just remove very old messages.
pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, 10000);
}
void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time)
{
int recvfrom_result = 0;
@@ -2501,68 +2313,6 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time)
while(recvfrom_result > 0);
}
void pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time)
{
int recvfrom_result = 0;
struct sockaddr_in remote_addr;
socklen_t remote_addr_size = sizeof(remote_addr);
remote_addr.sin_family = 2; // hardcoded
do {
// peek the header
uint8_t header_buffer[NFAPI_NR_P7_HEADER_LENGTH];
recvfrom_result = recvfrom(pnf_p7->p7_sock,
header_buffer,
NFAPI_NR_P7_HEADER_LENGTH,
MSG_DONTWAIT | MSG_PEEK,
(struct sockaddr*)&remote_addr,
&remote_addr_size);
if (recvfrom_result > 0) {
// get the segment size
nfapi_nr_p7_message_header_t header;
nfapi_nr_p7_message_header_unpack(header_buffer, NFAPI_NR_P7_HEADER_LENGTH, &header, 34, 0);
// resize the buffer if we have a large segment
if (header.message_length > pnf_p7->rx_message_buffer_size) {
NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length);
pnf_p7->rx_message_buffer = realloc(pnf_p7->rx_message_buffer, header.message_length);
pnf_p7->rx_message_buffer_size = header.message_length;
}
// read the segment
recvfrom_result = recvfrom(pnf_p7->p7_sock,
pnf_p7->rx_message_buffer,
header.message_length,
MSG_DONTWAIT,
(struct sockaddr*)&remote_addr,
&remote_addr_size);
now_hr_time = pnf_get_current_time_hr(); // moved to here - get closer timestamp???
if (recvfrom_result > 0) {
pnf_nr_handle_p7_message(pnf_p7->rx_message_buffer, recvfrom_result, pnf_p7, now_hr_time);
// printf("\npnf_handle_p7_message sfn=%d,slot=%d\n",pnf_p7->sfn,pnf_p7->slot);
}
} else if (recvfrom_result == 0) {
// recv zero length message
recvfrom_result =
recvfrom(pnf_p7->p7_sock, header_buffer, 0, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size);
}
if (recvfrom_result == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// return to the select
// NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno);
} else {
NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno);
}
}
// need to update the time as we would only use the value from the
// select
} while (recvfrom_result > 0);
}
int pnf_p7_message_pump(pnf_p7_t* pnf_p7)
{
@@ -2604,7 +2354,7 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7)
}
*/
int iptos_value = FAPI2_IP_DSCP << 2;
int iptos_value = 0;
if (setsockopt(pnf_p7->p7_sock, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (IPPROTO_IP, IP_TOS) failed errno: %d\n", errno);
@@ -2722,197 +2472,15 @@ struct timespec pnf_timespec_add(struct timespec lhs, struct timespec rhs)
struct timespec pnf_timespec_sub(struct timespec lhs, struct timespec rhs)
{
struct timespec result;
if ((lhs.tv_nsec-rhs.tv_nsec)<0)
if ((lhs.tv_nsec-rhs.tv_nsec)<0)
{
result.tv_sec = lhs.tv_sec-rhs.tv_sec-1;
result.tv_nsec = 1000000000+lhs.tv_nsec-rhs.tv_nsec;
}
else
}
else
{
result.tv_sec = lhs.tv_sec-rhs.tv_sec;
result.tv_nsec = lhs.tv_nsec-rhs.tv_nsec;
}
return result;
}
int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7)
{
// initialize the mutex lock
if(pthread_mutex_init(&(pnf_p7->mutex), NULL) != 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 mutex init: %d\n", errno);
return -1;
}
if(pthread_mutex_init(&(pnf_p7->pack_mutex), NULL) != 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 mutex init: %d\n", errno);
return -1;
}
// create the pnf p7 socket
if ((pnf_p7->p7_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 socket created (%d)...\n", pnf_p7->p7_sock);
// configure the UDP socket options
int reuseaddr_enable = 1;
if (setsockopt(pnf_p7->p7_sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_enable, sizeof(int)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (SOL_SOCKET, SO_REUSEADDR) failed errno: %d\n", errno);
return -1;
}
/*
int reuseport_enable = 1;
if (setsockopt(pnf_p7->p7_sock, SOL_SOCKET, SO_REUSEPORT, &reuseport_enable, sizeof(int)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (SOL_SOCKET, SO_REUSEPORT) failed errno: %d\n", errno);
return -1;
}
*/
int iptos_value = FAPI2_IP_DSCP << 2;
if (setsockopt(pnf_p7->p7_sock, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (IPPROTO_IP, IP_TOS) failed errno: %d\n", errno);
return -1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(pnf_p7->_public.local_p7_port);
if(pnf_p7->_public.local_p7_addr == 0)
{
addr.sin_addr.s_addr = INADDR_ANY;
}
else
{
//addr.sin_addr.s_addr = inet_addr(pnf_p7->_public.local_p7_addr);
if(inet_aton(pnf_p7->_public.local_p7_addr, &addr.sin_addr) == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "inet_aton failed\n");
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 binding %d too %s:%d\n", pnf_p7->p7_sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
if (bind(pnf_p7->p7_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF_P7 bind error fd:%d errno: %d\n", pnf_p7->p7_sock, errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 bind succeeded...\n");
//Initializaing timing structures needed for slot ticking
struct timespec slot_start;
clock_gettime(CLOCK_MONOTONIC, &slot_start);
struct timespec pselect_start;
struct timespec slot_duration;
slot_duration.tv_sec = 0;
slot_duration.tv_nsec = 0.5e6;
//Infinite loop
while(pnf_p7->terminate == 0)
{
fd_set rfds;
int selectRetval = 0;
// select on a timeout and then get the message
FD_ZERO(&rfds);
FD_SET(pnf_p7->p7_sock, &rfds);
struct timespec timeout;
timeout.tv_sec = 100;
timeout.tv_nsec = 0;
clock_gettime(CLOCK_MONOTONIC, &pselect_start);
//setting the timeout
if((pselect_start.tv_sec > slot_start.tv_sec) || ((pselect_start.tv_sec == slot_start.tv_sec) && (pselect_start.tv_nsec > slot_start.tv_nsec)))
{
// overran the end of the subframe we do not want to wait
timeout.tv_sec = 0;
timeout.tv_nsec = 0;
//struct timespec overrun = pnf_timespec_sub(pselect_start, sf_start);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Subframe overrun detected of %d.%d running to catchup\n", overrun.tv_sec, overrun.tv_nsec);
}
else
{
// still time before the end of the subframe wait
timeout = pnf_timespec_sub(slot_start, pselect_start);
}
selectRetval = pselect(pnf_p7->p7_sock+1, &rfds, NULL, NULL, &timeout, NULL);
uint32_t now_hr_time = pnf_get_current_time_hr();
if(selectRetval == 0)
{
// timeout
//update slot start timing
slot_start = pnf_timespec_add(slot_start, slot_duration);
//increment sfn/slot
if (++pnf_p7->slot == 20)
{
pnf_p7->slot = 0;
pnf_p7->sfn = (pnf_p7->sfn + 1) % 1024;
}
continue;
}
else if (selectRetval == -1 && (errno == EINTR))
{
// interrupted by signal
NFAPI_TRACE(NFAPI_TRACE_WARN, "PNF P7 Signal Interrupt %d\n", errno);
continue;
}
else if (selectRetval == -1)
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "PNF P7 select() failed\n");
sleep(1);
continue;
}
if(FD_ISSET(pnf_p7->p7_sock, &rfds))
{
pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7, now_hr_time);
}
}
NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF_P7 Terminating..\n");
// close the connection and socket
if (close(pnf_p7->p7_sock) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "close failed errno: %d\n", errno);
}
if(pthread_mutex_destroy(&(pnf_p7->pack_mutex)) != 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "mutex destroy failed errno: %d\n", errno);
}
if(pthread_mutex_destroy(&(pnf_p7->mutex)) != 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "mutex destroy failed errno: %d\n", errno);
}
return 0;
}
+12 -20
View File
@@ -74,20 +74,7 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config)
return 0;
}
int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
pnf_p7_t* _this = (pnf_p7_t*)(config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
pnf_nr_p7_message_pump(_this);
return 0;
}
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
@@ -260,7 +247,8 @@ int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indica
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_slot_indication_scf_t));
AssertFatal(_this->_public.send_p7_msg, "Function pointer must be configured|");
return _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_slot_indication_scf_t));
}
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind)
@@ -272,8 +260,8 @@ int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
int ret = pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
AssertFatal(_this->_public.send_p7_msg, "Function pointer must be configured|");
int ret = _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
if (ret == 0) {
for (int i = 0; i < ind->number_of_pdus; ++i)
_this->nr_stats.ul.bytes += ind->pdu_list[i].pdu_length;
@@ -290,7 +278,8 @@ int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indicati
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_crc_indication_t));
AssertFatal(_this->_public.send_p7_msg, "Function pointer must be configured|");
return _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_crc_indication_t));
}
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind)
@@ -302,7 +291,8 @@ int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indicati
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_srs_indication_t));
AssertFatal(_this->_public.send_p7_msg, "Function pointer must be configured|");
return _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_srs_indication_t));
}
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind)
@@ -314,7 +304,8 @@ int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indicati
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_uci_indication_t));
AssertFatal(_this->_public.send_p7_msg, "Function pointer must be configured|");
return _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_uci_indication_t));
}
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind)
@@ -326,5 +317,6 @@ int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indica
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rach_indication_t));
AssertFatal(_this->_public.send_p7_msg, "Function pointer must be configured|");
return _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rach_indication_t));
}
+1 -2
View File
@@ -281,10 +281,9 @@ int main(int argc, char *argv[])
printf("\n");
AssertFatal(byte_count >= sizeof(fapi_message_header_t), "Read byte amount not enough to encode the header. Should have a minimum of %lu bytes, aborting...", sizeof(fapi_message_header_t));
uint8_t *ptr = hex_values; // Points to the first element of the array
uint8_t **msg_ptr = &ptr; // Pointer to the pointer
fapi_message_header_t hdr = {.num_msg = 0, .opaque_handle = 0, .message_id = 0, .message_length = 0};
fapi_nr_message_header_unpack(msg_ptr, NFAPI_HEADER_LENGTH, &hdr, sizeof(fapi_message_header_t), 0);
fapi_nr_message_header_unpack(ptr, NFAPI_HEADER_LENGTH, &hdr, sizeof(fapi_message_header_t), 0);
printf("Decoded message %s message length 0x%02x\n", message_id_to_str(hdr.message_id), hdr.message_length);
// Unpack the message
+6 -4
View File
@@ -20,7 +20,7 @@
#include "nfapi_vnf_interface.h"
typedef struct
struct vnf_t
{
nfapi_vnf_config_t _public;
@@ -31,20 +31,22 @@ typedef struct
uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
uint16_t next_phy_id;
} vnf_t;
};
int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
void nfapi_vnf_phy_info_list_add(nfapi_vnf_config_t* config, nfapi_vnf_phy_info_t* info);
nfapi_vnf_phy_info_t* nfapi_vnf_phy_info_list_find(nfapi_vnf_config_t* config, uint16_t phy_id);
void nfapi_vnf_pnf_list_add(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* node);
nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5_idx);
void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config);
#endif // _VNF_H_
+10 -6
View File
@@ -19,7 +19,6 @@
#define _VNF_P7_H_
#include "nfapi_vnf_interface.h"
#define TIMEHR_SEC(_time_hr) ((uint32_t)(_time_hr) >> 20)
#define TIMEHR_USEC(_time_hr) ((uint32_t)(_time_hr) & 0xFFFFF)
#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF))
@@ -108,7 +107,7 @@ typedef struct nfapi_vnf_p7_connection_info {
} nfapi_vnf_p7_connection_info_t;
typedef struct {
struct vnf_p7_t{
nfapi_vnf_p7_config_t _public;
@@ -121,7 +120,7 @@ typedef struct {
uint8_t* rx_message_buffer; // would this be better put in the p7 conenction info?
uint16_t rx_message_buffer_size;
} vnf_p7_t;
};
uint32_t vnf_get_current_time_hr(void);
@@ -132,15 +131,20 @@ int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info);
int send_mac_subframe_indications(vnf_p7_t* config);
int send_mac_slot_indications(vnf_p7_t* config);
int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7);
vnf_p7_rx_message_t* vnf_p7_rx_reassembly_queue_add_segment(vnf_p7_t* vnf_p7, vnf_p7_rx_reassembly_queue_t* queue, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len);
void* vnf_p7_malloc(vnf_p7_t* vnf_p7, size_t size);
void vnf_p7_free(vnf_p7_t* vnf_p7, void* ptr);
void vnf_p7_rx_reassembly_queue_remove_msg(vnf_p7_t* vnf_p7, vnf_p7_rx_reassembly_queue_t* queue, vnf_p7_rx_message_t* msg);
void vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7_t* vnf_p7, vnf_p7_rx_reassembly_queue_t* queue, uint32_t delta);
uint32_t calculate_transmit_timestamp(int mu, uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr);
void vnf_p7_connection_info_list_add(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* node);
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p7, uint16_t phy_id);
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id);
int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_t* header);
void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
void vnf_p7_release_pdu(vnf_p7_t* vnf_p7, void* pdu);
@@ -30,7 +30,9 @@
extern "C" {
#endif
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
typedef struct vnf_t vnf_t;
typedef struct vnf_p7_t vnf_p7_t;
/*! The nfapi VNF phy configuration information
*/
@@ -292,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
@@ -449,10 +469,60 @@ typedef struct nfapi_vnf_config
*/
void (*deallocate_p4_p5_vendor_ext)(void* header);
/*! \brief Encodes a (n)FAPI P5 message to a buffer
* \param pMessageBuf A pointer to a (n)fapi p5 message structure
* \param messageBufLen The size of the p5 message structure
* \param pPackedBuf A pointer to the buffer that the p5 message will be packed into
* \param packedBufLen The size of the buffer
* \param config A pointer to the nfapi configuration structure
* \return != 0 means success, -1 means failure.
*/
int (*pack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pPackedBuf,
uint32_t packedBufLen,
nfapi_p4_p5_codec_config_t* config);
/*! \brief Decodes an (n)FAPI P5 message
* \param pMessageBuf A pointer to an encoded P5 message
* \param messageBufLen The size of the encoded P5 message
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true on success, false on failure
*/
bool (*unpack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p4_p5_codec_config_t* config);
/*! \brief Decodes an (n)FAPI P5 message header
* \param pMessageBuf A pointer to an encoded P5 message header
* \param messageBufLen The size of the encoded P5 message header
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true on success, false on failure
*/
bool (*hdr_unpack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p4_p5_codec_config_t* config);
/*! \brief Sends a (n)FAPI P5 message
*
* This function internally packs the given message into a buffer by calling the previously defined pack_func() function pointer
* Then, having the message buffer populated, sends it to the PNF
* \param vnf A pointer to a vnf_t*
* \param p5_idx The index of the P5 PNF intended to receive the message
* \param msg A pointer to the P5 message
* \param msg_len The size of the encoded P5 message header
* \return true on success, false on failure
*/
bool (*send_p5_msg)(vnf_t* vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t* msg, uint32_t msg_len);
} nfapi_vnf_config_t;
@@ -476,7 +546,6 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config);
*
* This function will not return untill nfapi_vnf_stop is called
*/
int nfapi_nr_vnf_start(nfapi_vnf_config_t* config);
int nfapi_vnf_start(nfapi_vnf_config_t* config);
@@ -878,7 +947,52 @@ typedef struct nfapi_vnf_p7_config
*/
void (*deallocate_p7_vendor_ext)(void* header);
/*! A callback to pack a P7 message
* \param pMessageBuf A pointer to a nfapi p7 message structure
* \param pPackedBuf A pointer to the buffer that the p7 message will be packed into
* \param packedBufLen The size of the buffer
* \param config A pointer to the nfapi configuration structure
* \return != -1 means success, -1 means failure.
*/
int (*pack_func)(void* pMessageBuf, void* pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
/*! A callback to unpack a P7 message
* \param pMessageBuf A pointer to an encoded P7 message header
* \param messageBufLen The size of the encoded P7 message header
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true on success, false on failure
*/
bool (*unpack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p7_codec_config_t* config);
/*! \brief Decodes an NFAPI P7 message header
* \param pMessageBuf A pointer to an encoded P5 message header
* \param messageBufLen The size of the encoded P5 message header
* \param pUnpackedBuf A pointer to the nfapi_message_header
* \param unpackedBufLen The size of nfapi_message_header structure.
* \param config A pointer to the nfapi configuration structure
* \return true on success, false on failure
*/
bool (*hdr_unpack_func)(void* pMessageBuf,
uint32_t messageBufLen,
void* pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p7_codec_config_t* config);
/*! \brief Sends a (n)FAPI P7 message
*
* This function internally packs the given message into a buffer by calling the previously defined pack_func() function pointer
* Then, having the message buffer populated, sends it to the PNF
* \param vnf_p7 A pointer to a vnf_p7_t struct
* \param header A pointer to the P7 message to pack & send
* \return true on success, false on failure
*/
bool (*send_p7_msg)(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_t* header);
} nfapi_vnf_p7_config_t;
/*! Creates and initializes the nfapi_vnf_p7_config structure before use
@@ -902,7 +1016,7 @@ void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config);
* function is called.
*/
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config);
int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config);
/*! Stop the VNF P7 library.
@@ -959,7 +1073,7 @@ int nfapi_vnf_p7_del_pnf(nfapi_vnf_p7_config_t* config, int phy_id);
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_request_t* req);
int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req);
bool nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req);
/*! Send the UL_CONFIG.request
* \param config A pointer to the vnf p7 configuration
@@ -970,7 +1084,7 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req);
int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req);
bool nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req);
/*! Send the HI_DCI0.request
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded HI_DCI0.request.
@@ -980,7 +1094,7 @@ int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_reque
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req);
bool nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req);
/*! Send the TX.req
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded HI_DCI0.request.
@@ -990,7 +1104,7 @@ int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_reque
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req);
int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req);
bool nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req);
/*! Send the LBT_DL_CONFIG.requst
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded LBT_DL_CONFIG.request.
+106 -205
View File
@@ -29,9 +29,14 @@
#include "nfapi_nr_interface_scf.h"
#ifdef ENABLE_AERIAL
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
#include "nr_fapi_p5.h"
#endif
#ifdef ENABLE_WLS
#include <wls_integration/include/wls_vnf.h>
#endif // ENABLE_WLS
#include <unistd.h>
#include "nfapi/oai_integration/vendor_ext.h"
void* vnf_malloc(nfapi_vnf_config_t* config, size_t size)
@@ -117,7 +122,8 @@ void vnf_nr_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_
nfapi_nr_pnf_param_response_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
const bool result = config->unpack_func(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config);
if (result)
{
// Invoke the call back
if(config->pnf_nr_param_resp)
@@ -188,7 +194,8 @@ void vnf_nr_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf
nfapi_nr_pnf_config_response_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
const bool result = config->unpack_func(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config);
if (result)
{
// Invoke the call back
if(config->pnf_nr_config_resp)
@@ -258,7 +265,8 @@ void vnf_nr_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_
nfapi_nr_pnf_start_response_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
const bool result = config->unpack_func(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config);
if (result)
{
if(config->pnf_nr_start_resp)
{
@@ -428,40 +436,39 @@ void vnf_nr_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_conf
nfapi_nr_param_response_scf_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
const bool result = config->unpack_func(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config);
if (result)
{
if (msg.error_code == NFAPI_NR_PARAM_MSG_OK)
{
nfapi_vnf_phy_info_t* phy_info = nfapi_vnf_phy_info_list_find(config, msg.header.phy_id);
if(msg.nfapi_config.p7_pnf_address_ipv4.tl.tag)
{
struct sockaddr_in sockAddr;
(void)memcpy(&sockAddr.sin_addr.s_addr, msg.nfapi_config.p7_pnf_address_ipv4.address, NFAPI_IPV4_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv4 address: %s\n", inet_ntoa(sockAddr.sin_addr));
// store address
phy_info->p7_pnf_address.sin_addr = sockAddr.sin_addr;
}
if(msg.nfapi_config.p7_pnf_address_ipv6.tl.tag)
{
struct sockaddr_in6 sockAddr6;
char addr6[64];
(void)memcpy(&sockAddr6.sin6_addr, msg.nfapi_config.p7_pnf_address_ipv6.address, NFAPI_IPV6_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv6 address: %s\n", inet_ntop(AF_INET6, &sockAddr6.sin6_addr, addr6, sizeof(addr6)));
}
if (msg.nfapi_config.p7_pnf_port.tl.tag)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 Port: %d\n", msg.nfapi_config.p7_pnf_port.value);
// store port
phy_info->p7_pnf_address.sin_port = htons(msg.nfapi_config.p7_pnf_port.value);
}
}
if (msg.error_code == NFAPI_NR_PARAM_MSG_OK) {
nfapi_vnf_phy_info_t *phy_info = nfapi_vnf_phy_info_list_find(config, msg.header.phy_id);
if (phy_info) {
if (msg.nfapi_config.p7_pnf_address_ipv4.tl.tag) {
struct sockaddr_in sockAddr;
(void)memcpy(&sockAddr.sin_addr.s_addr, msg.nfapi_config.p7_pnf_address_ipv4.address, NFAPI_IPV4_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv4 address: %s\n", inet_ntoa(sockAddr.sin_addr));
// store address
phy_info->p7_pnf_address.sin_addr = sockAddr.sin_addr;
}
if (msg.nfapi_config.p7_pnf_address_ipv6.tl.tag) {
struct sockaddr_in6 sockAddr6;
char addr6[64];
(void)memcpy(&sockAddr6.sin6_addr, msg.nfapi_config.p7_pnf_address_ipv6.address, NFAPI_IPV6_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO,
"PNF P7 IPv6 address: %s\n",
inet_ntop(AF_INET6, &sockAddr6.sin6_addr, addr6, sizeof(addr6)));
}
if (msg.nfapi_config.p7_pnf_port.tl.tag) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 Port: %d\n", msg.nfapi_config.p7_pnf_port.value);
// store port
phy_info->p7_pnf_address.sin_port = htons(msg.nfapi_config.p7_pnf_port.value);
}
}
}
if(config->nr_param_resp)
{
@@ -495,7 +502,8 @@ void vnf_nr_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_con
nfapi_nr_config_response_scf_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 )
const bool result = config->unpack_func(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config);
if (result)
{
// check the error code:
@@ -602,7 +610,8 @@ void vnf_nr_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_conf
nfapi_nr_start_response_scf_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
const bool result = config->unpack_func(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config);
if (result)
{ // check the error code
if (msg.error_code == NFAPI_NR_START_MSG_OK){
if(config->nr_start_resp)
@@ -624,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)
{
@@ -1085,7 +1127,8 @@ void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfa
}
// unpack the message header
if (nfapi_nr_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_nr_p4_p5_message_header_t), &config->codec_config) < 0)
const bool result = config->hdr_unpack_func(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_nr_p4_p5_message_header_t), &config->codec_config);
if (!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
@@ -1115,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);
@@ -1257,119 +1304,6 @@ void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_
}
}
int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf)
{
if (1) {
int socket_connected = 1;
// 1. Peek the message header
// 2. If the message is larger than the stack buffer then create a dynamic buffer
// 3. Read the buffer
// 4. Handle the p5 message
uint32_t header_buffer_size = NFAPI_NR_P5_HEADER_LENGTH;
uint8_t header_buffer[header_buffer_size];
uint32_t stack_buffer_size = 32; // should it be the size of then sctp_notificatoin structure
uint8_t stack_buffer[stack_buffer_size];
uint8_t* dynamic_buffer = 0;
uint8_t* read_buffer = &stack_buffer[0];
uint32_t message_size = 0;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
struct sctp_sndrcvinfo sndrcvinfo;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
{
int flags = MSG_PEEK;
message_size =
sctp_recvmsg(pnf->p5_sock, header_buffer, header_buffer_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
if (message_size == -1) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to peek sctp message size errno:%d\n", errno);
return 0;
}
nfapi_nr_p4_p5_message_header_t header;
int unpack_result = nfapi_nr_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
if (unpack_result < 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to decode message header %d\n", unpack_result);
return 0;
}
message_size = header.message_length + header_buffer_size;
// now have the size of the mesage
}
if (message_size > stack_buffer_size) {
dynamic_buffer = (uint8_t*)malloc(message_size);
if (dynamic_buffer == NULL) {
// todo : add error mesage
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size);
return -1;
}
read_buffer = dynamic_buffer;
}
{
int flags = 0;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
int recvmsg_result =
sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
if (recvmsg_result == -1) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno);
} else {
if (flags & MSG_NOTIFICATION) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
// todo - handle the events
} else {
/*
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n",
pnf->p5_sock,
inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port),
sndrcvinfo.sinfo_assoc_id,
sndrcvinfo.sinfo_stream,
ntohl(sndrcvinfo.sinfo_ppid),
message_size,
flags);
*/
// handle now if complete message in one or more segments
if ((flags & 0x80) == 0x80) {
// printf("\nVNF RECEIVES:\n");
// for(int i=0; i<message_size; i++){
// printf("%d", read_buffer[i]);
// }
// printf("\n");
vnf_nr_handle_p4_p5_message(read_buffer, message_size, pnf->p5_idx, config);
} else {
NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags);
// assume socket disconnected
NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n");
socket_connected = 0;
}
}
}
}
if (dynamic_buffer) {
free(dynamic_buffer);
}
return socket_connected;
}
}
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf)
{
@@ -1502,7 +1436,7 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t*
}
}
static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len, uint8_t stream)
static int vnf_send_p5_msg(vnf_t *vnf, nfapi_vnf_pnf_info_t *pnf, const void *msg, int len, uint8_t stream)
{
// printf("\n MESSAGE SENT: \n");
// for(int i=0; i<len; i++){
@@ -1512,7 +1446,21 @@ static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len,
//NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s len:%d stream:%d\n", __FUNCTION__, len, stream);
int result = sctp_sendmsg(pnf->p5_sock, msg, len, (struct sockaddr*)&pnf->p5_pnf_sockaddr, sizeof(pnf->p5_pnf_sockaddr),1, 0, stream, 0, 4);
ssize_t result = -1;
if (vnf->sctp) {
result = sctp_sendmsg(pnf->p5_sock,
msg,
len,
(struct sockaddr *)&pnf->p5_pnf_sockaddr,
sizeof(pnf->p5_pnf_sockaddr),
1,
0,
stream,
0,
4);
} else {
result = send(pnf->p5_sock, msg, len,0);
}
if(result != len)
{
@@ -1530,53 +1478,6 @@ static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len,
return 0;
}
int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t* msg, uint16_t msg_len)
{
nfapi_vnf_pnf_info_t* pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx);
if(pnf)
{
// pack the message for transmission
int packedMessageLength = 0;
if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
#ifdef ENABLE_AERIAL
// In case it is a FAPI message, create 2 messages, one with nFAPI header for OAI PNF and one with no nFAPI header for Aerial
// L1
// create FAPI tx_buffer
uint8_t tx_messagebufferFAPI[sizeof(vnf->tx_message_buffer)];
int packedMessageLengthFAPI = -1;
packedMessageLengthFAPI =
fapi_nr_p5_message_pack(msg, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &vnf->_public.codec_config);
return aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg);
#else
return 0;
#endif
} else {
packedMessageLength = nfapi_nr_p5_message_pack(msg,
msg_len,
vnf->tx_message_buffer,
sizeof(vnf->tx_message_buffer),
&vnf->_public.codec_config);
if (packedMessageLength < 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_nr_p5_message_pack failed with return %d\n", packedMessageLength);
return -1;
}
// printf("msg id = 0x%02x, entire message length: %d\n", msg->message_id, packedMessageLength);
// for (int i = 0; i < packedMessageLength; i++) {
// printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) vnf->tx_message_buffer)[i]);
// }
return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0);
}
} else {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx);
return -1;
}
}
int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len)
{
nfapi_vnf_pnf_info_t* pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx);
@@ -1592,7 +1493,7 @@ int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_messag
return -1;
}
return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0/*msg->phy_id*/);
return vnf_send_p5_msg(vnf, pnf, vnf->tx_message_buffer, packedMessageLength, 0/*msg->phy_id*/);
}
else
{
@@ -1617,7 +1518,7 @@ int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_messag
return -1;
}
return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0/*msg->phy_id*/);
return vnf_send_p5_msg(vnf, pnf, vnf->tx_message_buffer, packedMessageLength, 0/*msg->phy_id*/);
}
else
{
+18 -424
View File
@@ -1,12 +1,12 @@
/*
* Copyright 2017 Cisco Systems, Inc.
*
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
*
* 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.
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "assertions.h"
#include <sys/socket.h>
#include <sys/types.h>
@@ -64,413 +65,6 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config)
free(config);
}
int nfapi_nr_vnf_start(nfapi_vnf_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
int p5ListenSock, p5Sock;
struct sockaddr_in addr;
socklen_t addrSize;
struct sockaddr_in6 addr6;
struct sctp_event_subscribe events;
struct sctp_initmsg initMsg;
int noDelay;
(void)memset(&addr, 0, sizeof(struct sockaddr_in));
(void)memset(&addr6, 0, sizeof(struct sockaddr_in6));
(void)memset(&events, 0, sizeof(struct sctp_event_subscribe));
(void)memset(&initMsg, 0, sizeof(struct sctp_initmsg));
vnf_t* vnf = (vnf_t*)(config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "Starting P5 VNF connection on port %u\n", config->vnf_p5_port);
/*
char * host = 0;
char * port = "4242";
struct addrinfo hints;
bzero(&hints, sizeof(struct addrinfo));
//hints.ai_flags=AI_PASSIVE;
//hints.ai_flags=AI_DEFAULT;
hints.ai_family=AF_UNSPEC;
//hints.ai_family=AF_INET6;
hints.ai_socktype=SOCK_STREAM;
//hints.ai_protocol=IPPROTO_SCTP
struct addrinfo *aiHead = 0;
int result = getaddrinfo(host, port, &hints, &aiHead);
NFAPI_TRACE(NFAPI_TRACE_INFO, "getaddrinfo return %d %d\n", result, errno);
while(aiHead->ai_next != NULL)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "addr info %d (IP %d UDP %d SCTP %d)\n %d (%d)\n",
aiHead->ai_protocol, IPPROTO_IP, IPPROTO_UDP, IPPROTO_SCTP,
aiHead->ai_flags, AI_PASSIVE);
char hostBfr[ NI_MAXHOST ];
char servBfr[ NI_MAXSERV ];
getnameinfo(aiHead->ai_addr,
aiHead->ai_addrlen,
hostBfr,
sizeof( hostBfr ),
servBfr,
sizeof( servBfr ),
NI_NUMERICHOST | NI_NUMERICSERV );
switch(aiHead->ai_family)
{
case PF_INET:
{
struct sockaddr_in *pSadrIn = (struct sockaddr_in*) aiHead->ai_addr;
printf(
" ai_addr = sin_family: %d (AF_INET = %d, "
"AF_INET6 = %d)\n"
" sin_addr: %s\n"
" sin_port: %s\n",
pSadrIn->sin_family,
AF_INET,
AF_INET6,
hostBfr,
servBfr );
}
break;
case PF_INET6:
{
struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6*) aiHead->ai_addr;
fprintf( stderr,
" ai_addr = sin6_family: %d (AF_INET = %d, "
"AF_INET6 = %d) \n"
" sin6_addr: %s\n"
" sin6_port: %s\n"
" sin6_flowinfo: %d\n"
" sin6_scope_id: %d\n",
pSadrIn6->sin6_family,
AF_INET,
AF_INET6,
hostBfr,
servBfr,
pSadrIn6->sin6_flowinfo,
pSadrIn6->sin6_scope_id);
}
break;
default:
NFAPI_TRACE(NFAPI_TRACE_INFO, "Not ment to be here\n");
break;
}
aiHead = aiHead->ai_next;
}
*/
{
int protocol;
int domain;
if (vnf->sctp)
protocol = IPPROTO_SCTP;
else
protocol = IPPROTO_IP;
if(config->vnf_ipv6)
{
domain = PF_INET6;
}
else
{
domain = AF_INET;
}
// open the SCTP socket
if ((p5ListenSock = socket(domain, SOCK_STREAM, protocol)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P5 socket errno: %d\n", errno);
return 0;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "P5 socket created... %d\n", p5ListenSock);
}
if (vnf->sctp)
{
// configure for MSG_NOTIFICATION
if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(struct sctp_event_subscribe)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_EVENTS) errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF Setting the SCTP_INITMSG\n");
// configure the SCTP socket options
initMsg.sinit_num_ostreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater
initMsg.sinit_max_instreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater
if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_INITMSG) errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
noDelay = 1;
if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_NODELAY, &noDelay, sizeof(noDelay)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (STCP_NODELAY) errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
struct sctp_event_subscribe events;
memset( (void *)&events, 0, sizeof(events) );
events.sctp_data_io_event = 1;
if(setsockopt(p5ListenSock, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt errno: %d\n", errno);
close(p5ListenSock);
return -1;
}
}
if(config->vnf_ipv6)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV6 binding to port %d %d\n", config->vnf_p5_port, p5ListenSock);
addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(config->vnf_p5_port);
addr6.sin6_addr = in6addr_any;
// bind to the configured address and port
if (bind(p5ListenSock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
}
else if(config->vnf_ipv4)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV4 binding to port %d\n", config->vnf_p5_port);
addr.sin_family = AF_INET;
addr.sin_port = htons(config->vnf_p5_port);
addr.sin_addr.s_addr = INADDR_ANY;
// bind to the configured address and port
if (bind(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
//if (sctp_bindx(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), SCTP_BINDX_ADD_ADDR) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "bind succeeded..%d.\n", p5ListenSock);
// put the socket into listen mode
if (listen(p5ListenSock, 2) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After listen errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "listen succeeded...\n");
struct timeval tv;
fd_set read_fd_set;
int p5_idx = 0;
while(vnf->terminate == 0)
{
FD_ZERO(&read_fd_set);
FD_SET(p5ListenSock, &read_fd_set);
int max_fd = p5ListenSock;
tv.tv_sec = 5;
tv.tv_usec = 0;
nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
while(pnf != 0)
{
if(pnf->connected)
{
FD_SET(pnf->p5_sock, &read_fd_set);
if (pnf->p5_sock > max_fd)
{
max_fd = pnf->p5_sock;
}
}
pnf = pnf->next;
}
int select_result = select(max_fd + 1, &read_fd_set, 0, 0, &tv);
if(select_result == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "select result %d errno %d\n", select_result, errno);
close(p5ListenSock);
return 0;
}
else if(select_result)
{
if(FD_ISSET(p5ListenSock, &read_fd_set))
{
addrSize = sizeof(struct sockaddr_in);
NFAPI_TRACE(NFAPI_TRACE_INFO, "Accepting connection from PNF...\n");
p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize);
if (p5Sock < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to accept PNF connection reason:%d\n", errno);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF connection (fd:%d) accepted from %s:%d \n", p5Sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
nfapi_vnf_pnf_info_t* pnf = (nfapi_vnf_pnf_info_t*)malloc(sizeof(nfapi_vnf_pnf_info_t));
NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf);
memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t));
pnf->p5_sock = p5Sock;
pnf->p5_idx = p5_idx++;
pnf->p5_pnf_sockaddr = addr;
pnf->connected = 1;
nfapi_vnf_pnf_list_add(config, pnf);
// Inform mac that a pnf connection has been established
// todo : allow mac to 'accept' the connection. i.e. to
// reject it.
if(config->pnf_nr_connection_indication != 0)
{
(config->pnf_nr_connection_indication)(config, pnf->p5_idx);
}
// check the connection status
{
struct sctp_status status;
(void)memset(&status, 0, sizeof(struct sctp_status));
socklen_t optLen = (socklen_t) sizeof(struct sctp_status);
if (getsockopt(p5Sock, IPPROTO_SCTP, SCTP_STATUS, &status, &optLen) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After getsockopt errno: %d\n", errno);
return -1;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Association ID = %d\n", status.sstat_assoc_id);
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Receiver window size = %d\n", status.sstat_rwnd);
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF In Streams = %d\n", status.sstat_instrms);
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Out Streams = %d\n", status.sstat_outstrms);
}
}
}
}
else
{
uint8_t delete_pnfs = 0;
nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
while(pnf != 0)
{
if(FD_ISSET(pnf->p5_sock, &read_fd_set))
{
if(vnf_nr_read_dispatch_message(config, pnf) == 0)
{
if(config->pnf_disconnect_indication != 0)
{
(config->pnf_disconnect_indication)(config, pnf->p5_idx);
}
close(pnf->p5_sock);
pnf->to_delete = 1;
delete_pnfs = 1;
}
}
pnf = pnf->next;
}
if(delete_pnfs)
{
nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
nfapi_vnf_pnf_info_t* prev = 0;
while(pnf != 0)
{
nfapi_vnf_pnf_info_t* curr = pnf;
if(pnf->to_delete == 1)
{
if(prev == 0)
{
config->pnf_list = pnf->next;
}
else
{
prev->next = pnf->next;
}
pnf = pnf->next;
free(curr);
}
else
{
prev = pnf;
pnf = pnf->next;
}
}
}
}
continue;
}
else
{
// timeout
// Should we test for socket closure here every second?
continue;
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Sock socket's\n");
{
nfapi_vnf_pnf_info_t* curr = config->pnf_list;
while(curr != NULL)
{
if(config->pnf_disconnect_indication)
{
(config->pnf_disconnect_indication)(config, curr->p5_idx);
}
close(curr->p5_sock);
curr = curr->next;
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Listen socket\n");
close(p5ListenSock);
return 0;
}
int nfapi_vnf_start(nfapi_vnf_config_t* config)
{
@@ -894,8 +488,8 @@ int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_param_request_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured\n");
return config->send_p5_msg(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_param_request_t));
}
int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req)
@@ -914,8 +508,8 @@ int nfapi_nr_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_config_request_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured\n");
return config->send_p5_msg(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_config_request_t));
}
@@ -945,8 +539,8 @@ int nfapi_nr_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_start_request_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured\n");
return config->send_p5_msg(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_start_request_t));
}
int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_stop_request_t* req)
@@ -965,8 +559,8 @@ int nfapi_nr_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_para
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_param_request_scf_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured\n");
return config->send_p5_msg(_this, p5_idx, &req->header, sizeof(nfapi_nr_param_request_scf_t));
}
int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req)
@@ -983,9 +577,9 @@ int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_con
{
if(config == 0 || req == 0)
return -1;
AssertFatal(config->send_p5_msg, "Function pointer must be configured\n");
vnf_t* _this = (vnf_t*)(config);
#if !defined(ENABLE_WLS) && !defined(ENABLE_AERIAL)
nfapi_vnf_phy_info_t* phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
if(phy == NULL)
@@ -1006,8 +600,8 @@ int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_con
req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
req->nfapi_config.timing_info_period.value = phy->timing_info_period;
req->num_tlv++;
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_config_request_scf_t));
#endif
return config->send_p5_msg(_this, p5_idx, &req->header, sizeof(nfapi_nr_config_request_scf_t));
}
int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req)
@@ -1057,8 +651,8 @@ int nfapi_nr_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_star
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_start_request_scf_t));
AssertFatal(config->send_p5_msg, "Function pointer must be configured\n");
return config->send_p5_msg(_this, p5_idx, &req->header, sizeof(nfapi_nr_start_request_scf_t));
}
+28 -309
View File
@@ -29,6 +29,9 @@
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
#endif
#include "vnf_p7.h"
#ifdef ENABLE_WLS
#include <wls_integration/include/wls_vnf.h>
#endif
#include "nr_fapi_p7_utils.h"
#ifdef NDEBUG
@@ -473,102 +476,6 @@ int vnf_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info, u
return 0;
}
int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_t* header)
{
nfapi_vnf_p7_connection_info_t* p7_connection = vnf_p7_connection_info_list_find(vnf_p7, header->phy_id);
if(p7_connection)
{
int send_result = 0;
uint8_t buffer[1024*1024*3];
header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, p7_connection->sequence_number);
int len = nfapi_nr_p7_message_pack(header, buffer, sizeof(buffer), &vnf_p7->_public.codec_config);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size);
if(len < 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() failed to pack p7 message phy_id:%d\n", __FUNCTION__, header->phy_id);
return -1;
}
if(len > vnf_p7->_public.segment_size)
{
// todo : consider replacing with the sendmmsg call
// todo : worry about blocking writes?
// segmenting the transmit
int msg_body_len = len - NFAPI_NR_P7_HEADER_LENGTH ;
uint32_t seg_body_len = vnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH ;
int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0);
int segment = 0;
int offset = NFAPI_NR_P7_HEADER_LENGTH;
uint8_t tx_buffer[vnf_p7->_public.segment_size];
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s() MORE THAN ONE SEGMENT phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size);
for(segment = 0; segment < segment_count; ++segment)
{
uint8_t last = 0;
uint32_t size = vnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH;
if(segment + 1 == segment_count)
{
last = 1;
size = (msg_body_len) - (seg_body_len * segment);
}
uint32_t segment_size = size + NFAPI_NR_P7_HEADER_LENGTH;
// Update the header with the m and segement
memcpy(&tx_buffer[0], buffer, NFAPI_NR_P7_HEADER_LENGTH);
// set the segment length
tx_buffer[4] = (segment_size & 0xFF000000) >> 24;
tx_buffer[5] = (segment_size & 0xFF0000) >> 16;
tx_buffer[6] = (segment_size & 0xFF00) >> 8;
tx_buffer[7] = (segment_size & 0xFF);
// set the m & segment number
tx_buffer[8] = ((!last) << 7) + segment;
memcpy(&tx_buffer[NFAPI_NR_P7_HEADER_LENGTH], &buffer[0] + offset, size);
offset += size;
if(vnf_p7->_public.checksum_enabled)
{
nfapi_nr_p7_update_checksum(tx_buffer, segment_size);
}
nfapi_nr_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->mu, p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &tx_buffer[0], segment_size);
}
}
else
{
if(vnf_p7->_public.checksum_enabled)
{
nfapi_nr_p7_update_checksum(buffer, len);
}
nfapi_nr_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->mu, p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
// simple case that the message fits in a single segement
send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &buffer[0], len);
}
p7_connection->sequence_number++;
return send_result;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find p7 connection info for phy_id:%d\n", __FUNCTION__, header->phy_id);
return -1;
}
}
int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header)
{
@@ -676,7 +583,8 @@ int vnf_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t
}
int vnf_nr_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
{
{
nfapi_vnf_p7_config_t* config = (nfapi_vnf_p7_config_t*)vnf_p7;
nfapi_nr_dl_node_sync_t dl_node_sync;
memset(&dl_node_sync, 0, sizeof(dl_node_sync));
@@ -686,7 +594,7 @@ int vnf_nr_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_inf
dl_node_sync.t1 = calculate_nr_t1(p7_info->mu, p7_info->sfn,p7_info->slot, vnf_p7->slot_start_time_hr);
dl_node_sync.delta_sfn_slot = 0;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &dl_node_sync.header);
return config->send_p7_msg(vnf_p7, &dl_node_sync.header);
}
int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
@@ -1098,10 +1006,8 @@ void vnf_nr_handle_p7_vendor_extension(void *pRecvMsg, int recvMsgLen, vnf_p7_t*
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n", __FUNCTION__);
return;
}
int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, msg, msg_size, &vnf_p7->_public.codec_config);
if(unpack_result == 0)
const bool result = vnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, msg, msg_size, &vnf_p7->_public.codec_config);
if(!result)
{
if(vnf_p7->_public.vendor_ext)
vnf_p7->_public.vendor_ext(&(vnf_p7->_public), msg);
@@ -1497,8 +1403,8 @@ void vnf_handle_nr_slot_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf
else
{
nfapi_nr_slot_indication_scf_t ind = {0};
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
const bool result = vnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config);
if(!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
@@ -1524,8 +1430,8 @@ void vnf_handle_nr_rx_data_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t*
else
{
nfapi_nr_rx_data_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
const bool result = vnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config);
if(!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
@@ -1551,8 +1457,8 @@ void vnf_handle_nr_crc_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
else
{
nfapi_nr_crc_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
const bool result = vnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config);
if(!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
@@ -1578,8 +1484,8 @@ void vnf_handle_nr_srs_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
else
{
nfapi_nr_srs_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
const bool result = vnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config);
if(!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
@@ -1604,8 +1510,8 @@ void vnf_handle_nr_uci_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
else
{
nfapi_nr_uci_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
const bool result = vnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config);
if(!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
@@ -1631,8 +1537,8 @@ void vnf_handle_nr_rach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf
else
{
nfapi_nr_rach_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
const bool result = vnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config);
if(!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
@@ -1661,7 +1567,8 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
}
nfapi_nr_ul_node_sync_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_nr_ul_node_sync_t), &vnf_p7->_public.codec_config) < 0)
const bool result = vnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_nr_ul_node_sync_t), &vnf_p7->_public.codec_config);
if(!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack ul_node_sync\n");
return;
@@ -2096,7 +2003,8 @@ void vnf_nr_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
}
nfapi_nr_timing_info_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_timing_info_t), &vnf_p7->_public.codec_config) < 0)
const bool result = vnf_p7->_public.unpack_func(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_timing_info_t), &vnf_p7->_public.codec_config);
if(!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack timing_info\n");
return;
@@ -2220,7 +2128,7 @@ void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
}
}
void vnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
nfapi_nr_p7_message_header_t header;
@@ -2232,7 +2140,8 @@ void vnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
}
// unpack the message header
if (nfapi_nr_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &vnf_p7->_public.codec_config) < 0)
const bool result = vnf_p7->_public.hdr_unpack_func(pRecvMsg, recvMsgLen, &header, sizeof(header), &vnf_p7->_public.codec_config);
if (!result)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
@@ -2417,196 +2326,6 @@ void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
}
}
void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
nfapi_nr_p7_message_header_t messageHeader;
// validate the input params
if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p7_message: invalid input params (%p %d %p)\n", pRecvMsg, recvMsgLen, vnf_p7);
return;
}
// unpack the message header
if (nfapi_nr_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_nr_p7_message_header_t), &vnf_p7->_public.codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
}
if(vnf_p7->_public.checksum_enabled)
{
uint32_t checksum = nfapi_nr_p7_calculate_checksum(pRecvMsg, recvMsgLen);
if(checksum != messageHeader.checksum)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d msg:%d len:%d\n", checksum, messageHeader.checksum, messageHeader.message_id, recvMsgLen);
return;
}
}
uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence);
uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence);
uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence);
if(m == 0 && segment_num == 0)
{
// we have a complete message
// ensure the message is sensible
if (recvMsgLen < 8 || pRecvMsg == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
return;
}
//vnf_dispatch_p7_message(&messageHeader, pRecvMsg, recvMsgLen, vnf_p7);
vnf_nr_dispatch_p7_message(pRecvMsg, recvMsgLen, vnf_p7);
}
else
{
nfapi_vnf_p7_connection_info_t* phy = vnf_p7_connection_info_list_find(vnf_p7, messageHeader.phy_id);
if(phy)
{
vnf_p7_rx_message_t* rx_msg = vnf_p7_rx_reassembly_queue_add_segment(vnf_p7, &(phy->reassembly_queue), sequence_num, segment_num, m, pRecvMsg, recvMsgLen);
if(rx_msg->num_segments_received == rx_msg->num_segments_expected)
{
// send the buffer on
uint16_t i = 0;
uint16_t length = 0;
for(i = 0; i < rx_msg->num_segments_expected; ++i)
{
length += rx_msg->segments[i].length - (i > 0 ? NFAPI_NR_P7_HEADER_LENGTH : 0);
}
if(phy->reassembly_buffer_size < length)
{
vnf_p7_free(vnf_p7, phy->reassembly_buffer);
phy->reassembly_buffer = 0;
}
if(phy->reassembly_buffer == 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing VNF_P7 Reassembly buffer %d->%d\n", phy->reassembly_buffer_size, length);
phy->reassembly_buffer = (uint8_t*)vnf_p7_malloc(vnf_p7, length);
if(phy->reassembly_buffer == 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate VNF_P7 reassemby buffer len:%d\n", length);
return;
}
memset(phy->reassembly_buffer, 0, length);
phy->reassembly_buffer_size = length;
}
uint16_t offset = 0;
for(i = 0; i < rx_msg->num_segments_expected; ++i)
{
if(i == 0)
{
memcpy(phy->reassembly_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length);
offset += rx_msg->segments[i].length;
}
else
{
memcpy(phy->reassembly_buffer + offset, rx_msg->segments[i].buffer + NFAPI_NR_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_NR_P7_HEADER_LENGTH);
offset += rx_msg->segments[i].length - NFAPI_NR_P7_HEADER_LENGTH;
}
}
//pnf_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time);
vnf_nr_dispatch_p7_message(phy->reassembly_buffer, length , vnf_p7);
// delete the structure
vnf_p7_rx_reassembly_queue_remove_msg(vnf_p7, &(phy->reassembly_queue), rx_msg);
}
// see corresponding comment in pnf_nr_handle_p7_message() [same commit]
vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7, &(phy->reassembly_queue), 10000);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Unknown phy id %d\n", messageHeader.phy_id);
}
}
}
int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7)
{
int recvfrom_result = 0;
struct sockaddr_in remote_addr;
socklen_t remote_addr_size = sizeof(remote_addr);
do
{
// peek the header
uint8_t header_buffer[NFAPI_NR_P7_HEADER_LENGTH];
recvfrom_result = recvfrom(vnf_p7->socket, header_buffer, NFAPI_NR_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size);
if(recvfrom_result > 0)
{
// get the segment size
nfapi_nr_p7_message_header_t header;
if(nfapi_nr_p7_message_header_unpack(header_buffer, NFAPI_NR_P7_HEADER_LENGTH, &header, sizeof(header), 0) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return -1;
}
// resize the buffer if we have a large segment
if(header.message_length > vnf_p7->rx_message_buffer_size)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length);
vnf_p7->rx_message_buffer = realloc(vnf_p7->rx_message_buffer, header.message_length);
vnf_p7->rx_message_buffer_size = header.message_length;
}
// read the segment
recvfrom_result = recvfrom(vnf_p7->socket, vnf_p7->rx_message_buffer, header.message_length, MSG_WAITALL | MSG_TRUNC, (struct sockaddr*)&remote_addr, &remote_addr_size);
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "recvfrom_result = %d from %s():%d\n", recvfrom_result, __FUNCTION__, __LINE__);
// todo : how to handle incomplete readfroms, need some sort of buffer/select
if (recvfrom_result > 0)
{
if (recvfrom_result != header.message_length)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "(%d) Received unexpected number of bytes. %d != %d",
__LINE__, recvfrom_result, header.message_length);
break;
}
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Calling vnf_nr_handle_p7_message from %d\n", __LINE__);
vnf_nr_handle_p7_message(vnf_p7->rx_message_buffer, recvfrom_result, vnf_p7);
return 0;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "recvfrom failed %d %d\n", recvfrom_result, errno);
}
}
if(recvfrom_result == -1)
{
if(errno == EAGAIN || errno == EWOULDBLOCK)
{
// return to the select
//NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno);
}
}
}
while(recvfrom_result > 0);
return 0;
}
int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7)
{
@@ -2652,7 +2371,7 @@ int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7)
__LINE__, recvfrom_result, header.message_length);
break;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Calling vnf_nr_handle_p7_message from %d\n", __LINE__);
NFAPI_TRACE(NFAPI_TRACE_INFO, "Calling vnf_nr_reassemble_p7_message from %d\n", __LINE__);
vnf_handle_p7_message(vnf_p7->rx_message_buffer, recvfrom_result, vnf_p7);
return 0;
}
+16 -121
View File
@@ -30,7 +30,7 @@
#include "common/ran_context.h"
#include "openair1/PHY/defs_gNB.h"
#define FAPI2_IP_DSCP 0
extern RAN_CONTEXT_t RC;
@@ -96,115 +96,6 @@ struct timespec timespec_sub(struct timespec lhs, struct timespec rhs)
// monitor the p7 endpoints and the timing loop and
// send indications to mac
int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
{
if(config == 0)
return -1;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
// Create p7 receive udp port
// todo : this needs updating for Ipv6
NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port);
// open the UDP socket
if ((vnf_p7->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 socket created...\n");
// configure the UDP socket options
int iptos_value = FAPI2_IP_DSCP << 2;
if (setsockopt(vnf_p7->socket, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 setsockopt succeeded...\n");
// Create the address structure
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(config->port);
addr.sin_addr.s_addr = INADDR_ANY;
// bind to the configured port
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 binding too %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
if (bind(vnf_p7->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
//if (sctp_bindx(config->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), 0) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 bind succeeded...\n");
//struct timespec original_pselect_timeout;
struct timespec pselect_timeout;
pselect_timeout.tv_sec = 100;
pselect_timeout.tv_nsec = 0;
struct timespec ref_time;
clock_gettime(CLOCK_MONOTONIC, &ref_time);
while(vnf_p7->terminate == 0)
{
fd_set rfds;
int maxSock = 0;
FD_ZERO(&rfds);
int selectRetval = 0;
// Add the p7 socket
FD_SET(vnf_p7->socket, &rfds);
maxSock = vnf_p7->socket;
selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
if(selectRetval == 0)
{
// pselect timed out, continue
}
else if(selectRetval > 0)
{
// have a p7 message
if(FD_ISSET(vnf_p7->socket, &rfds))
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
}
}
else
{
// pselect error
if(selectRetval == -1 && errno == EINTR)
{
// a sigal was received.
}
else
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond);
// should we exit now?
if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration
{
usleep(100000);
}
}
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
close(vnf_p7->socket);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
return 0;
}
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
@@ -231,7 +122,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 socket created...\n");
// configure the UDP socket options
int iptos_value = FAPI2_IP_DSCP << 2;
int iptos_value = 0;
if (setsockopt(vnf_p7->socket, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno);
@@ -559,12 +450,12 @@ int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr,
node->slot = 0;
node->min_sync_cycle_count = 8;
node->mu = mu;
#ifndef ENABLE_AERIAL
// save the remote endpoint information
node->remote_addr.sin_family = AF_INET;
node->remote_addr.sin_port = pnf_p7_port;//htons(pnf_p7_port);
node->remote_addr.sin_addr.s_addr = inet_addr(pnf_p7_addr);
#endif
vnf_p7_connection_info_list_add(vnf_p7, node);
return 0;
@@ -600,7 +491,7 @@ int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_re
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req)
bool nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p req:%p)\n", __FUNCTION__, config, req);
@@ -608,15 +499,17 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
AssertFatal(config->send_p7_msg, "Function pointer must be configured|");
return config->send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req)
bool nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
AssertFatal(config->send_p7_msg, "Function pointer must be configured|");
return config->send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req)
@@ -627,13 +520,14 @@ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_re
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req)
bool nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
AssertFatal(config->send_p7_msg, "Function pointer must be configured|");
return config->send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req)
{
@@ -643,13 +537,14 @@ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_reques
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req)
bool nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
AssertFatal(config->send_p7_msg, "Function pointer must be configured|");
return config->send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req)
{