PBCH working
This commit is contained in:
@@ -102,7 +102,40 @@ nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
void vnf_nr_handle_pnf_param_response(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 PNF_PARAM.reponse\n");
|
||||
|
||||
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)
|
||||
{
|
||||
// Invoke the call back
|
||||
if(config->pnf_nr_param_resp)
|
||||
{
|
||||
(config->pnf_nr_param_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
// make sure to release any dyanmic part of the message
|
||||
if(msg.vendor_extension)
|
||||
config->codec_config.deallocate(msg.vendor_extension);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
|
||||
{
|
||||
// ensure it's valid
|
||||
@@ -820,6 +853,123 @@ void vnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, nfapi_vnf_confi
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config)
|
||||
{
|
||||
nfapi_p4_p5_message_header_t messageHeader;
|
||||
|
||||
// validate the input params
|
||||
if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH || config == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p4_p5_message: invalid input params\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// unpack the message header
|
||||
if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &config->codec_config) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (messageHeader.message_id)
|
||||
{
|
||||
case NFAPI_PNF_PARAM_RESPONSE:
|
||||
vnf_nr_handle_pnf_param_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_PNF_CONFIG_RESPONSE:
|
||||
vnf_handle_pnf_config_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_PNF_START_RESPONSE:
|
||||
vnf_handle_pnf_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_PNF_STOP_RESPONSE:
|
||||
vnf_handle_pnf_stop_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_PARAM_RESPONSE:
|
||||
vnf_handle_param_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_CONFIG_RESPONSE:
|
||||
vnf_handle_config_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_START_RESPONSE:
|
||||
vnf_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_STOP_RESPONSE:
|
||||
vnf_handle_stop_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_MEASUREMENT_RESPONSE:
|
||||
vnf_handle_measurement_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_RSSI_RESPONSE:
|
||||
vnf_handle_rssi_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_RSSI_INDICATION:
|
||||
vnf_handle_rssi_indication(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_CELL_SEARCH_RESPONSE:
|
||||
vnf_handle_cell_search_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_CELL_SEARCH_INDICATION:
|
||||
vnf_handle_cell_search_indication(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_BROADCAST_DETECT_RESPONSE:
|
||||
vnf_handle_broadcast_detect_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_BROADCAST_DETECT_INDICATION:
|
||||
vnf_handle_broadcast_detect_indication(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE:
|
||||
vnf_handle_system_information_schedule_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION:
|
||||
vnf_handle_system_information_schedule_indication(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_SYSTEM_INFORMATION_RESPONSE:
|
||||
vnf_handle_system_information_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_SYSTEM_INFORMATION_INDICATION:
|
||||
vnf_handle_system_information_indication(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
case NFAPI_NMM_STOP_RESPONSE:
|
||||
vnf_handle_nmm_stop_response(pRecvMsg, recvMsgLen, config, p5_idx);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
|
||||
messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
|
||||
{
|
||||
vnf_handle_vendor_extension(pRecvMsg, recvMsgLen, config, p5_idx, messageHeader.message_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config)
|
||||
{
|
||||
nfapi_p4_p5_message_header_t messageHeader;
|
||||
@@ -935,6 +1085,7 @@ void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf)
|
||||
{
|
||||
if(1)
|
||||
@@ -1092,6 +1243,31 @@ 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_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 = 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_p5_message_pack failed with return %d\n", packedMessageLength);
|
||||
return -1;
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -62,7 +62,419 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config)
|
||||
{
|
||||
free(config);
|
||||
}
|
||||
#if 0
|
||||
int nfapi_nr_vnf_start(nfapi_vnf_config_t* config)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
// Make sure to set the defined trace function before using NFAPI_TRACE
|
||||
if(config->trace)
|
||||
nfapi_trace_g = (nfapi_trace_fn_t)config->trace;
|
||||
|
||||
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_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;
|
||||
|
||||
}
|
||||
#endif
|
||||
int nfapi_vnf_start(nfapi_vnf_config_t* config)
|
||||
{
|
||||
// Verify that config is not null
|
||||
@@ -486,8 +898,18 @@ int nfapi_vnf_stop(nfapi_vnf_config_t* config)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_request_t* req)
|
||||
// {
|
||||
// if(config == 0 || req == 0)
|
||||
// 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));
|
||||
// }
|
||||
|
||||
int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req)
|
||||
{ printf("nfapi_vnf_pnf_param_req\n");
|
||||
{
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -361,7 +361,7 @@ uint32_t calculate_t1(uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
|
||||
uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
|
||||
|
||||
uint32_t t1 = (NFAPI_SFNSLOT2DEC(sfn,slot) * 500) + slot_time_us;
|
||||
|
||||
|
||||
return t1;
|
||||
}
|
||||
|
||||
@@ -381,7 +381,7 @@ uint32_t calculate_t4(uint32_t now_time_hr, uint16_t sfn, uint16_t slot, uint32_
|
||||
uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
|
||||
|
||||
uint32_t t4 = (NFAPI_SFNSLOT2DEC(sfn,slot) * 500) + slot_time_us;
|
||||
|
||||
|
||||
return t4;
|
||||
|
||||
}
|
||||
@@ -394,7 +394,7 @@ uint32_t calculate_transmit_timestamp(uint16_t sfn, uint16_t slot, uint32_t slot
|
||||
uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
|
||||
|
||||
uint32_t tt = (NFAPI_SFNSLOT2DEC(sfn, slot) * 500) + slot_time_us;
|
||||
|
||||
|
||||
return tt;
|
||||
}
|
||||
|
||||
@@ -982,9 +982,9 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
{
|
||||
phy->latency[phy->min_sync_cycle_count] = latency;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) PNF to VNF !sync phy_id:%d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d\n",
|
||||
phy->sfn, phy->slot, ind.header.phy_id, ind.t1, ind.t2, ind.t3, t4,
|
||||
tx_2_rx, pnf_proc_time, latency);
|
||||
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) PNF to VNF !sync phy_id:%d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d\n",
|
||||
// phy->sfn, phy->slot, ind.header.phy_id, ind.t1, ind.t2, ind.t3, t4,
|
||||
// tx_2_rx, pnf_proc_time, latency);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1027,11 +1027,11 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n",
|
||||
phy->sfn, phy->slot, ts.tv_sec, ts.tv_nsec, ind.header.phy_id,
|
||||
ind.t1, ind.t2, ind.t3, t4,
|
||||
tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->slot_offset, phy->slot_offset_filtered,
|
||||
(ind.t1<phy->previous_t1), (ind.t2<phy->previous_t2));
|
||||
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n",
|
||||
// phy->sfn, phy->slot, ts.tv_sec, ts.tv_nsec, ind.header.phy_id,
|
||||
// ind.t1, ind.t2, ind.t3, t4,
|
||||
// tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->slot_offset, phy->slot_offset_filtered,
|
||||
// (ind.t1<phy->previous_t1), (ind.t2<phy->previous_t2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1068,10 +1068,15 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
phy->slot_offset = ind.t2 - (ind.t1 - phy->average_latency);
|
||||
|
||||
sfn_slot_dec += (phy->slot_offset / 500);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF slot offset:%d sfn :%d slot:%d \n",phy->slot_offset,NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec),NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec) );
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sfn_slot_dec += ((phy->slot_offset_filtered + 250) / 500); //Round up to go from microsecond to slot
|
||||
|
||||
}
|
||||
|
||||
if(sfn_slot_dec < 0)
|
||||
@@ -1090,7 +1095,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
{
|
||||
phy->adjustment = NFAPI_SFNSLOT2DEC(new_sfn, new_slot) - NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF phy_id:%d adjustment%d phy->previous_slot_offset_filtered:%d phy->previous_slot_offset_filtered:%d phy->slot_offset_trend:%d\n", ind.header.phy_id, phy->adjustment, phy->previous_slot_offset_filtered, phy->previous_slot_offset_filtered, phy->slot_offset_trend);
|
||||
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF phy_id:%d adjustment%d phy->previous_slot_offset_filtered:%d phy->previous_slot_offset_filtered:%d phy->slot_offset_trend:%d\n", ind.header.phy_id, phy->adjustment, phy->previous_slot_offset_filtered, phy->previous_slot_offset_filtered, phy->slot_offset_trend);
|
||||
|
||||
phy->previous_t1 = 0;
|
||||
phy->previous_t2 = 0;
|
||||
@@ -1196,14 +1201,14 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
|
||||
if(phy->insync_minor_adjustment != 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adjustment:%d\n",
|
||||
phy->sfn, phy->slot, ind.header.phy_id,
|
||||
phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration,
|
||||
phy->slot_offset_filtered,
|
||||
insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend,
|
||||
NFAPI_SFNSLOT2DEC(new_sfn, new_slot),
|
||||
NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot),
|
||||
phy->adjustment);
|
||||
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adjustment:%d\n",
|
||||
// phy->sfn, phy->slot, ind.header.phy_id,
|
||||
// phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration,
|
||||
// phy->slot_offset_filtered,
|
||||
// insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend,
|
||||
// NFAPI_SFNSLOT2DEC(new_sfn, new_slot),
|
||||
// NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot),
|
||||
// phy->adjustment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1239,13 +1244,13 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
// out of sync?
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adj:%d\n",
|
||||
phy->sfn, phy->slot, ind.header.phy_id,
|
||||
phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->slot_offset_filtered,
|
||||
insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend,
|
||||
NFAPI_SFNSLOT2DEC(new_sfn, new_slot),
|
||||
NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot),
|
||||
phy->adjustment);
|
||||
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adj:%d\n",
|
||||
// phy->sfn, phy->slot, ind.header.phy_id,
|
||||
// phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->slot_offset_filtered,
|
||||
// insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend,
|
||||
// NFAPI_SFNSLOT2DEC(new_sfn, new_slot),
|
||||
// NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot),
|
||||
// phy->adjustment);
|
||||
|
||||
}
|
||||
else if(phy->adjustment < 0)
|
||||
@@ -1272,10 +1277,10 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
// out of sync?
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d slot_offset_filtered:%d) %d %d %d\n",
|
||||
phy->sfn, phy->slot, ind.header.phy_id,
|
||||
phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->slot_offset_filtered,
|
||||
insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend);
|
||||
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d slot_offset_filtered:%d) %d %d %d\n",
|
||||
// phy->sfn, phy->slot, ind.header.phy_id,
|
||||
// phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->slot_offset_filtered,
|
||||
// insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1349,12 +1354,13 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
|
||||
// Panos: Careful here!!! Modification of the original nfapi-code
|
||||
//if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1)
|
||||
//printf("VNF-PNF delta - %d", vnf_pnf_sfnslot_delta);
|
||||
if (vnf_pnf_sfnslot_delta>0 || vnf_pnf_sfnslot_delta < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnslot_delta,NFAPI_SFNSLOT2DEC(vnf_p7->p7_connections[0].sfn,vnf_p7->p7_connections[0].slot),NFAPI_SFNSLOT2DEC(ind.last_sfn,ind.last_slot)) ;
|
||||
// Panos: Careful here!!! Modification of the original nfapi-code
|
||||
vnf_p7->p7_connections[0].sfn = ind.last_sfn;
|
||||
vnf_p7->p7_connections[0].slot = ind.last_slot;
|
||||
// vnf_p7->p7_connections[0].sfn = ind.last_sfn;
|
||||
// vnf_p7->p7_connections[0].slot = ind.last_slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#define FAPI2_IP_DSCP 0
|
||||
|
||||
|
||||
nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
|
||||
{
|
||||
vnf_p7_t* _this = (vnf_p7_t*)calloc(1, sizeof(vnf_p7_t));
|
||||
@@ -145,7 +146,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
|
||||
//struct timespec original_pselect_timeout;
|
||||
struct timespec pselect_timeout;
|
||||
pselect_timeout.tv_sec = 0;
|
||||
pselect_timeout.tv_nsec = 500000; // ns in a 1 ms (Change?)
|
||||
pselect_timeout.tv_nsec = 500000; // ns in a 0.5 ms
|
||||
//pselect_timeout.tv_nsec = 500000;
|
||||
|
||||
struct timespec pselect_start;
|
||||
@@ -161,21 +162,21 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
|
||||
// sf_duration.tv_nsec = 0.5e6; // We want 1ms pause //We want 0.5 ms pause for NR
|
||||
struct timespec slot_duration;
|
||||
slot_duration.tv_sec = 0;
|
||||
//slot_duration.tv_nsec = 0.5e6;
|
||||
slot_duration.tv_nsec = 0.5e6;
|
||||
|
||||
|
||||
|
||||
// struct timespec sf_start; //Change to slot_start?
|
||||
struct timespec slot_start;
|
||||
// clock_gettime(CLOCK_MONOTONIC, &sf_start);
|
||||
clock_gettime(CLOCK_MONOTONIC, &slot_start);
|
||||
// long millisecond = sf_start.tv_nsec / 1e6; //Check if we have to change
|
||||
long millisecond = slot_start.tv_nsec / 1e6;
|
||||
long millisecond = slot_start.tv_nsec / 1e6; //Check if we have to change
|
||||
//long millisecond = slot_start.tv_nsec / 0.5e6;
|
||||
// sf_start = timespec_add(sf_start, sf_duration);
|
||||
slot_start = timespec_add(slot_start, slot_duration);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "next slot will start at %d.%d\n", slot_start.tv_sec, slot_start.tv_nsec);
|
||||
|
||||
//printf("next slot will start at %d.%d\n",slot_start.tv_sec, slot_start.tv_nsec);
|
||||
while(vnf_p7->terminate == 0)
|
||||
{
|
||||
fd_set rfds;
|
||||
@@ -346,8 +347,8 @@ NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d]
|
||||
|
||||
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d duration:%u\n",
|
||||
// phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration);
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Slot minor adjustment %dus slot_start.tv_nsec:%d duration:%u\n",
|
||||
phy->insync_minor_adjustment, slot_start.tv_nsec, phy->insync_minor_adjustment_duration);
|
||||
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Slot minor adjustment %dus slot_start.tv_nsec:%d duration:%u\n",
|
||||
// phy->insync_minor_adjustment, slot_start.tv_nsec, phy->insync_minor_adjustment_duration);
|
||||
|
||||
if (phy->insync_minor_adjustment_duration==0)
|
||||
{
|
||||
@@ -391,37 +392,31 @@ NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d]
|
||||
{
|
||||
//vnf_p7->sf_start_time_hr = vnf_get_current_time_hr();
|
||||
vnf_p7->slot_start_time_hr = vnf_get_current_time_hr();
|
||||
|
||||
struct timespec current_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
||||
// pselect timed out
|
||||
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
|
||||
|
||||
while(curr != 0)
|
||||
{
|
||||
|
||||
if (curr->slot == 19)
|
||||
{
|
||||
curr->sfn++;
|
||||
curr->slot = 0; //Correct? - gokul
|
||||
}
|
||||
else if(curr->slot > 19)
|
||||
{
|
||||
//error
|
||||
{ //curr->slot = 0;
|
||||
if(curr->sfn == 1023)
|
||||
curr->sfn=0;
|
||||
else
|
||||
curr->sfn++;
|
||||
curr->slot=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
curr->slot++;
|
||||
}
|
||||
//curr->sfn_sf = increment_sfn_sf(curr->sfn_sf);
|
||||
|
||||
vnf_sync(vnf_p7, curr);
|
||||
//printf("sfn:%d, slot:%d",curr->sfn,curr->slot); //remove later - gokul
|
||||
curr = curr->next;
|
||||
|
||||
vnf_sync(vnf_p7, curr);
|
||||
//printf("\nsfn:%d, slot:%d\n current time:%d.%d",curr->sfn,curr->slot,current_time.tv_sec, current_time.tv_nsec); //remove later - gokul
|
||||
//printf("next slot will start at %d.%d\n",current_time.tv_sec, current_time.tv_nsec);
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
//send_mac_subframe_indications(vnf_p7);
|
||||
send_mac_slot_indications(vnf_p7);
|
||||
|
||||
}
|
||||
else if(selectRetval > 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user