Merge remote-tracking branch 'origin/ocp-enb-cmake' into integration_2023_w08b

This commit is contained in:
Robert Schmidt
2023-02-24 18:49:30 +01:00
30 changed files with 51 additions and 3977 deletions
+3 -3
View File
@@ -36,7 +36,6 @@
#include "RRC/LTE/rrc_defs.h"
# include "enb_app.h"
# include "openair2/LAYER2/MAC/mac_proto.h"
#include <executables/split_headers.h>
#include <openair3/ocp-gtpu/gtp_itf.h>
extern RAN_CONTEXT_t RC;
@@ -52,12 +51,13 @@ int create_tasks(uint32_t enb_nb) {
AssertFatal(rc >= 0, "Create task for eNB APP failed\n");
rrc_enb_init();
itti_mark_task_ready(TASK_RRC_ENB);
if (get_softmodem_params()->emulate_l1 || (EPC_MODE_ENABLED && split73 != SPLIT73_DU)) {
if (get_softmodem_params()->emulate_l1 || EPC_MODE_ENABLED) {
rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL);
AssertFatal(rc >= 0, "Create task for SCTP failed\n");
}
if (EPC_MODE_ENABLED && ! ( split73==SPLIT73_DU ) ) {
if (EPC_MODE_ENABLED) {
rc = itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL);
AssertFatal(rc >= 0, "Create task for S1AP failed\n");
rc = itti_create_task(TASK_GTPV1_U, gtpv1uTask, NULL);
-9
View File
@@ -84,7 +84,6 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "lte-softmodem.h"
#include "NB_IoT_interface.h"
#include <executables/split_headers.h>
#if USING_GPROF
# include "sys/gmon.h"
@@ -146,14 +145,6 @@ int otg_enabled;
uint64_t num_missed_slots=0; // counter for the number of missed slots
int split73=0;
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
AssertFatal(false, "Must not be called in this context\n");
}
void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) {
AssertFatal(false, "Must not be called in this context\n");
}
RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond);
RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-1
View File
@@ -56,7 +56,6 @@
#include "openair2/ENB_APP/enb_paramdef.h"
#include "system.h"
#include <executables/split_headers.h>
#include <executables/softmodem-common.h>
#include <executables/thread-common.h>
-11
View File
@@ -153,19 +153,8 @@ int otg_enabled;
uint32_t timing_advance = 0;
uint64_t num_missed_slots=0; // counter for the number of missed slots
#include <executables/split_headers.h>
#include <SIMULATION/ETH_TRANSPORT/proto.h>
int split73=0;
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
AssertFatal(false, "Must not be called in this context\n");
}
void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask,
uint16_t rnti, int32_t stat) {
AssertFatal(false, "Must not be called in this context\n");
}
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
-4
View File
@@ -108,7 +108,6 @@ extern "C"
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
#define RF_CONFIG_FILE softmodem_params.rf_config_file
#define SPLIT73 softmodem_params.split73
#define TP_CONFIG softmodem_params.threadPoolConfig
#define PHY_TEST softmodem_params.phy_test
#define DO_RA softmodem_params.do_ra
@@ -138,7 +137,6 @@ extern "C"
extern int usrp_tx_thread;
#define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, 0},\
{"split73", CONFIG_HLP_SPLIT73, 0, strptr:&SPLIT73, defstrval:NULL, TYPE_STRING, 0}, \
{"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:&TP_CONFIG, defstrval:"-1,-1,-1,-1,-1,-1,-1,-1", TYPE_STRING, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, iptr:&DO_RA, defintval:0, TYPE_INT, 0}, \
@@ -210,7 +208,6 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s3a = { config_checkstr_assign_integer, \
{"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
@@ -292,7 +289,6 @@ typedef struct {
uint64_t optmask;
//THREAD_STRUCT thread_struct;
char *rf_config_file;
char *split73;
char *threadPoolConfig;
int phy_test;
int do_ra;
-331
View File
@@ -1,331 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Author and copyright: Laurent Thomas, open-cells.com
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __SPLIT_HEADERS_H
#define __SPLIT_HEADERS_H
#include <stdint.h>
#include <stdbool.h>
#include <openair1/PHY/defs_eNB.h>
#include <common/utils/telnetsrv/telnetsrv_proccmd.h>
#define CU_PORT "7878"
#define DU_PORT "8787"
#define SPLIT73_CU 1
#define SPLIT73_DU 2
extern int split73;
#define MTU 65536
#define UDP_TIMEOUT 900000L // in micro second (struct timeval, NOT struct timespec)
// linux may timeout for a much longer time (up to 10ms)
#define blockAlign 32 //bytes to align memory for SIMD copy (256 bits vectors)
// FS6 transport configuration and handler
typedef struct {
char *sourceIP;
char *sourcePort;
char *destIP;
char *destPort;
struct addrinfo *destAddr;
int sockHandler;
} UDPsock_t;
#define CTsentCUv0 0xA500
#define CTsentDUv0 0x5A00
// Main FS6 transport layer header
// All packets starts with this header
typedef struct commonUDP_s {
uint64_t timestamp; // id of the group (subframe for LTE)
uint16_t nbBlocks; // total number of blocks for this timestamp
uint16_t blockID; // id: 0..nbBocks-1
uint16_t contentType; // defines the content format
uint16_t contentBytes; // will be sent in a UDP packet, so must be < 2^16 bytes
uint64_t senderClock;
} commonUDP_t;
// FS6 UL common header (DU to CU)
// gives the RACH detection data and is always sent to inform the CU that a subframe arrived
typedef struct {
uint16_t max_preamble[4];
uint16_t max_preamble_energy[4];
uint16_t max_preamble_delay[4];
uint16_t avg_preamble_energy[4];
} fs6_ul_t;
// FS6 DL common header (CU to DU)
// gives the DCI configuration from each subframe
typedef struct {
uint8_t pbch_pdu[4];
int num_pdcch_symbols;
int num_dci;
DCI_ALLOC_t dci_alloc[8];
int num_mdci;
int amp;
LTE_eNB_PHICH phich_vars;
uint64_t DuClock;
uint64_t CuSpentMicroSec;
} fs6_dl_t;
// a value to type all sub packets,
// to detect errors, and to be able to extend to other versions
// the first byte of each sub structure should match one of these values
enum pckType {
fs6UlConfig=25,
fs6DlConfig=26,
fs6ULConfigCCH=27,
fs6ULsch=28,
fs6ULcch=29,
fs6ULindicationHarq=40,
fs6ULindicationSr=41,
};
// CU to DU definition of a future UL subframe decode
// defines a UE future data plane
typedef struct {
enum pckType type:8;
uint16_t UE_id;
int8_t harq_pid;
UE_type_t ue_type;
uint8_t dci_alloc;
uint8_t rar_alloc;
SCH_status_t status;
uint8_t Msg3_flag;
uint8_t subframe;
uint32_t frame;
uint8_t handled;
uint8_t phich_active;
uint8_t phich_ACK;
uint16_t previous_first_rb;
uint32_t B;
uint32_t G;
UCI_format_t uci_format;
uint8_t Or2;
uint8_t o_RI[2];
uint8_t o_ACK[4];
uint8_t O_ACK;
uint8_t o_RCC;
int16_t q_ACK[MAX_ACK_PAYLOAD];
int16_t q_RI[MAX_RI_PAYLOAD];
uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS];
uint8_t ndi;
uint8_t round;
uint8_t rvidx;
uint8_t Nl;
uint8_t n_DMRS;
uint8_t previous_n_DMRS;
uint8_t n_DMRS2;
int32_t delta_TF;
uint32_t repetition_number ;
uint32_t total_number_of_repetitions;
uint16_t harq_mask;
uint16_t nb_rb;
uint8_t Qm;
uint16_t first_rb;
uint8_t O_RI;
uint8_t Or1;
uint16_t Msc_initial;
uint8_t Nsymb_initial;
uint8_t V_UL_DAI;
uint8_t srs_active;
uint32_t TBS;
uint8_t Nsymb_pusch;
uint8_t Mlimit;
uint8_t max_turbo_iterations;
uint8_t bundling;
uint16_t beta_offset_cqi_times8;
uint16_t beta_offset_ri_times8;
uint16_t beta_offset_harqack_times8;
uint8_t Msg3_active;
uint16_t rnti;
uint8_t cyclicShift;
uint8_t cooperation_flag;
uint8_t num_active_cba_groups;
uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
} fs6_dl_ulsched_t;
// CU to DU defintion of a DL packet for a given UE
// The data itself is padded at the end of this structure
typedef struct {
enum pckType type:8;
int UE_id;
int8_t harq_pid;
uint16_t rnti;
int16_t sqrt_rho_a;
int16_t sqrt_rho_b;
CEmode_t CEmode:8;
uint16_t nb_rb;
uint8_t Qm;
int8_t Nl;
uint8_t pdsch_start;
uint8_t sib1_br_flag;
uint16_t i0;
uint32_t rb_alloc[4];
int dataLen;
} fs6_dl_uespec_t;
// CU to DU definition of CCH channel
typedef struct {
int16_t UE_id;
LTE_eNB_UCI cch_vars;
} fs6_dl_uespec_ulcch_element_t;
// header to group all UE CCH channels definitions in one UDP packet
typedef struct {
enum pckType type:8;
int16_t nb_active_ue;
} fs6_dl_uespec_ulcch_t;
// code internal, not transmitted as this
typedef struct {
int ta;
} ul_propagation_t;
// One UE UL data, data plane, UE data appended after the header
typedef struct {
enum pckType type:8;
short UE_id;
uint8_t harq_id;
uint8_t segment;
int segLen;
int r_offset;
int G;
int ulsch_power[2];
uint8_t o_ACK[4];
uint8_t O_ACK;
int ta;
uint8_t o[MAX_CQI_BYTES];
uint8_t cqi_crc_status;
} fs6_ul_uespec_t;
// UL UCI (control plane), per UE
typedef struct {
enum pckType type:8;
int UEid;
int frame;
int subframe;
LTE_eNB_UCI uci;
uint8_t harq_ack[4];
uint8_t tdd_mapping_mode;
uint16_t tdd_multiplexing_mask;
unsigned short n0_subband_power_dB;
uint16_t rnti;
int32_t stat;
} fs6_ul_uespec_uci_element_t;
// all segments UCI grouped in one UDP packet
typedef struct {
enum pckType type:8;
int16_t nb_active_ue;
} fs6_ul_uespec_uci_t;
bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result);
int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType);
int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType);
#define initBufferZone(xBuf) \
uint8_t xBuf[FS6_BUF_SIZE]; \
((commonUDP_t *)xBuf)->nbBlocks=0;
#define hUDP(xBuf) ((commonUDP_t *)xBuf)
#define hDL(xBuf) ((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))
#define hUL(xBuf) ((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))
#define hDLUE(xBuf) ((fs6_dl_uespec_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1))
#define hTxULUE(xBuf) ((fs6_dl_ulsched_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1))
#define hTxULcch(xBuf) ((fs6_dl_uespec_ulcch_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1))
#define hULUE(xBuf) ((fs6_ul_uespec_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1))
#define hULUEuci(xBuf) ((fs6_ul_uespec_uci_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1))
static inline size_t alignedSize(uint8_t *ptr) {
commonUDP_t *header=(commonUDP_t *) ptr;
return ((header->contentBytes+sizeof(commonUDP_t)+blockAlign-1)/blockAlign)*blockAlign;
}
static inline void *commonUDPdata(uint8_t *ptr) {
return (void *) (((commonUDP_t *)ptr)+1);
}
void setAllfromTS(uint64_t TS, L1_rxtx_proc_t *proc);
void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask,
uint16_t rnti, int32_t stat);
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset);
void *cu_fs6(void *arg);
void *du_fs6(void *arg);
void fill_rf_config(RU_t *ru, char *rf_config_file);
int init_rf(RU_t *ru);
void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe);
void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, int fembms_flag);
bool dlsch_procedures(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
int harq_pid,
LTE_eNB_DLSCH_t *dlsch,
LTE_eNB_UE_stats *ue_stats) ;
void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req);
void pdsch_procedures(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
int harq_pid,
LTE_eNB_DLSCH_t *dlsch,
LTE_eNB_DLSCH_t *dlsch1);
void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
void uci_procedures(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc);
void ocp_rx_prach(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
RU_t *ru,
uint16_t *max_preamble,
uint16_t *max_preamble_energy,
uint16_t *max_preamble_delay,
uint16_t *avg_preamble_energy,
uint16_t Nf,
uint8_t tdd_mapindex,
uint8_t br_flag);
void rx_prach0(PHY_VARS_eNB *eNB,
RU_t *ru,
int frame_prach,
int subframe,
uint16_t *max_preamble,
uint16_t *max_preamble_energy,
uint16_t *max_preamble_delay,
uint16_t *avg_preamble_energy,
uint16_t Nf,
uint8_t tdd_mapindex,
uint8_t br_flag,
uint8_t ce_level
);
void ocp_tx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
// mistakes in main OAI
void phy_init_RU(RU_t *);
void fep_full(RU_t *ru, int subframe);
void feptx_prec(RU_t *ru,int frame,int subframe);
void feptx_ofdm(RU_t *ru, int frame, int subframe);
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
void softmodem_printresources(int sig, telnet_printfunc_t pf);
extern uint16_t sf_ahead;
#endif
-195
View File
@@ -1,195 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Author and copyright: Laurent Thomas, open-cells.com
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <executables/split_headers.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <netdb.h>
#include "executables/lte-softmodem.h"
bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result) {
struct addrinfo hints= {0}, *servinfo, *p;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
int status;
if ((status = getaddrinfo(sourceIP, sourcePort, &hints, &servinfo)) != 0) {
LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status));
return false;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((result->sockHandler = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
LOG_W(GTPU,"socket: %s\n", strerror(errno));
continue;
}
if (bind(result->sockHandler, p->ai_addr, p->ai_addrlen) == -1) {
close(result->sockHandler);
LOG_W(GTPU,"bind: %s\n", strerror(errno));
continue;
}
break; // if we get here, we must have connected successfully
}
if (p == NULL) {
// looped off the end of the list with no successful bind
LOG_E(GTPU,"failed to bind socket: %s %s \n",sourceIP,sourcePort);
return false;
}
freeaddrinfo(servinfo); // all done with this structure
if ((status = getaddrinfo(destIP, destPort, &hints, &servinfo)) != 0) {
LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status));
return false;
}
if (servinfo) {
result->destAddr=servinfo;
} else {
LOG_E(PHY,"No valid UDP addr: %s:%s\n",destIP, destPort);
return false;
}
int enable=1;
AssertFatal(setsockopt(result->sockHandler, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,"");
struct timeval tv= {0,UDP_TIMEOUT};
if (IS_SOFTMODEM_RFSIM)
tv.tv_sec=2; //debug: wait 2 seconds for human understanding
AssertFatal(setsockopt(result->sockHandler, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,"");
// Make a send/recv buffer larger than a a couple of subframe
// so the kernel will store for us in and out paquets
int buff=1000*1000*10;
AssertFatal ( setsockopt(result->sockHandler, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, "");
AssertFatal ( setsockopt(result->sockHandler, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, "");
return true;
}
// sock: udp socket
// bufferZone: a reception area of bufferSize
int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType) {
int rcved=0;
commonUDP_t *bufOrigin=(commonUDP_t *)bufferZone;
static uint8_t crossData[65536];
static int crossDataSize=0;
if (crossDataSize) {
LOG_D(HW,"copy a block received in previous subframe\n");
memcpy(bufferZone, crossData, crossDataSize);
rcved=1;
bufferZone+=crossDataSize;
crossDataSize=0;
}
do {
//read all subframe data from the control unit
int ret=recv(sock->sockHandler, bufferZone, bufferSize, 0);
if ( ret==-1) {
if ( errno == EWOULDBLOCK || errno== EINTR ) {
LOG_I(HW,"Received: Timeout, subframe incomplete\n");
return rcved;
} else {
LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno));
return -1;
}
} else {
if (hUDP(bufferZone)->contentType != contentType)
abort();
if (rcved && bufOrigin->timestamp != hUDP(bufferZone)->timestamp ) {
if ( hUDP(bufferZone)->timestamp > bufOrigin->timestamp ) {
LOG_W(HW,"Received data for TS: %lu before end of TS : %lu completion\n",
hUDP(bufferZone)->timestamp,
bufOrigin->timestamp);
memcpy(crossData, bufferZone, ret );
crossDataSize=ret;
return rcved;
} else {
LOG_W(HW,"Dropping late packet\n");
continue;
}
}
rcved++;
bufferZone+=ret;
}
LOG_D(HW,"Received: blocks: %d/%d, size %d, TS: %lu\n",
rcved, bufOrigin->nbBlocks, ret, bufOrigin->timestamp);
} while ( rcved == 0 || rcved < bufOrigin->nbBlocks );
return rcved;
}
int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType) {
commonUDP_t *UDPheader=(commonUDP_t *)bufferZone ;
UDPheader->contentType=contentType;
UDPheader->senderClock=rdtsc_oai();
int nbBlocks=UDPheader->nbBlocks;
int blockId=0;
if (nbBlocks <= 0 ) {
LOG_E(PHY,"FS6: can't send blocks: %d\n", nbBlocks);
return 0;
}
do {
if (blockId > 0 ) {
commonUDP_t *currentHeader=(commonUDP_t *)bufferZone;
currentHeader->timestamp=UDPheader->timestamp;
currentHeader->nbBlocks=UDPheader->nbBlocks;
currentHeader->blockID=blockId;
currentHeader->contentType=UDPheader->contentType;
memcpy(commonUDPdata((void *)currentHeader), commonUDPdata(bufferZone), secondHeaderSize);
}
blockId++;
int sz=alignedSize(bufferZone);
// Let's use the first address returned by getaddrinfo()
int ret=sendto(sock->sockHandler, bufferZone, sz, 0,
sock->destAddr->ai_addr, sock->destAddr->ai_addrlen);
if ( ret != sz )
LOG_W(HW,"Wrote socket doesn't return size %d (val: %d, errno:%d, %s)\n",
sz, ret, errno, strerror(errno));
LOG_D(HW,"Sent: TS: %lu, blocks %d/%d, block size : %d \n",
UDPheader->timestamp, UDPheader->nbBlocks-nbBlocks, UDPheader->nbBlocks, sz);
bufferZone+=sz;
nbBlocks--;
} while (nbBlocks);
return 0;
}