diff --git a/executables/dl_fs6.c b/executables/dl_fs6.c index 5ad6ddfd3b..2dcdca2365 100644 --- a/executables/dl_fs6.c +++ b/executables/dl_fs6.c @@ -4,7 +4,7 @@ #include #define FS6_BUF_SIZE 100*1000 -static int sockFS6; +static UDPsock_t sockFS6; #if 0 void pdsch_procedures(PHY_VARS_eNB *eNB, @@ -66,14 +66,26 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, dlsch->active = 0; dlsch_harq->round++; } +#endif -phy_procedures_eNB_TX_fs6(int sockFS6, uint64_t TS) { - uint8_t bufferZone[FS6_BUF_SIZE]; - receiveSubFrame(sockFS6, TS, bufferZone, sizeof(bufferZone) ); - +void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int do_meas ) { // We got // subframe number // + int frame=proc->frame_tx; + int subframe=proc->subframe_tx; + uint32_t i,aa; + uint8_t harq_pid; + int16_t UE_id=0; + uint8_t num_pdcch_symbols=0; + uint8_t num_dci=0; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint8_t num_mdci = 0; +#endif + uint8_t ul_subframe; + uint32_t ul_frame; + LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; + LTE_UL_eNB_HARQ_t *ulsch_harq; for (int aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) { memset (&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * fp->symbols_per_tti], @@ -165,13 +177,15 @@ phy_procedures_eNB_TX_fs6(int sockFS6, uint64_t TS) { harq_pid,UE_id,frame,subframe,dlsch0->rnti); } else { // generate pdsch - pdsch_procedures_fs6(eNB, - proc, - harq_pid, - dlsch0, - dlsch1, - &eNB->UE_stats[(uint32_t)UE_id], - 0); + /* + pdsch_procedures_fs6(eNB, + proc, + harq_pid, + dlsch0, + dlsch1, + &eNB->UE_stats[(uint32_t)UE_id], + 0); + */ } } else if ((dlsch0)&&(dlsch0->rnti>0)&& (dlsch0->active == 0) @@ -185,21 +199,32 @@ phy_procedures_eNB_TX_fs6(int sockFS6, uint64_t TS) { proc, AMP); } -#endif -void prach_eNB_extract(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { +void prach_eNB_extract(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe, uint8_t *buf, int bufSize) { + commonUDP_t *header=(commonUDP_t *) buf; + header->contentBytes=1000; + header->nbBlocks=1; + return; } void prach_eNB_process(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { } -void phy_procedures_eNB_uespec_RX_extract(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc) { +void phy_procedures_eNB_uespec_RX_extract(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc, uint8_t *buf, int bufSize) { + commonUDP_t *header=(commonUDP_t *) buf; + header->contentBytes=1000; + header->nbBlocks=1; + return; } void phy_procedures_eNB_uespec_RX_process(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc) { } -void phy_procedures_eNB_TX_fs6() { +void phy_procedures_eNB_TX_extract(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int do_meas, uint8_t *buf, int bufSize) { + commonUDP_t *header=(commonUDP_t *) buf; + header->contentBytes=1000; + header->nbBlocks=1; + return; } void DL_du_fs6(RU_t *ru, int frame, int subframe, uint64_t TS) { @@ -207,10 +232,10 @@ void DL_du_fs6(RU_t *ru, int frame, int subframe, uint64_t TS) { for (int i=0; inum_eNB; i++) { uint8_t bufferZone[FS6_BUF_SIZE]; - receiveSubFrame(sockFS6, TS, bufferZone, sizeof(bufferZone) ); + receiveSubFrame(&sockFS6, TS, bufferZone, sizeof(bufferZone) ); + phy_procedures_eNB_TX_process( bufferZone, sizeof(bufferZone), ru->eNB_list[i], &ru->eNB_list[i]->proc.L1_proc, 1); } - phy_procedures_eNB_TX_fs6(); /* Fixme: datamodel issue: a ru is supposed to be connected to several eNB L1_rxtx_proc_t * L1_proc = &proc->L1_proc; ru_proc->timestamp_tx = L1_proc->timestamp_tx; @@ -244,14 +269,14 @@ void UL_du_fs6(RU_t *ru, int frame, int subframe) { } uint8_t bufferZone[FS6_BUF_SIZE]; - prach_eNB_extract(eNB,NULL,proc->frame_rx,proc->subframe_rx); + prach_eNB_extract(eNB,NULL,proc->frame_rx,proc->subframe_rx, bufferZone, FS6_BUF_SIZE); if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { - phy_procedures_eNB_uespec_RX_extract(eNB, &proc->L1_proc); + phy_procedures_eNB_uespec_RX_extract(eNB, &proc->L1_proc, bufferZone, FS6_BUF_SIZE); } for (int i=0; inum_eNB; i++) { - sendSubFrame(sockFS6,bufferZone, sizeof(bufferZone) ); + sendSubFrame(&sockFS6,bufferZone); } } @@ -267,13 +292,13 @@ void DL_cu_fs6(RU_t *ru,int frame, int subframe) { eNB->if_inst->UL_indication(&eNB->UL_INFO); pthread_mutex_unlock(&eNB->UL_INFO_mutex); uint8_t bufferZone[FS6_BUF_SIZE]; - phy_procedures_eNB_TX(eNB, &proc->L1_proc, 1); - sendSubFrame(sockFS6, bufferZone, sizeof(bufferZone) ); + phy_procedures_eNB_TX_extract(eNB, &proc->L1_proc, 1, bufferZone, FS6_BUF_SIZE); + sendSubFrame(&sockFS6, bufferZone ); } void UL_cu_fs6(RU_t *ru,int frame, int subframe, uint64_t TS) { uint8_t bufferZone[FS6_BUF_SIZE]; - receiveSubFrame(sockFS6, TS, bufferZone, sizeof(bufferZone) ); + receiveSubFrame(&sockFS6, TS, bufferZone, sizeof(bufferZone) ); // Fixme: datamodel issue PHY_VARS_eNB *eNB = RC.eNB[0][0]; L1_proc_t *proc = &eNB->proc; @@ -289,8 +314,11 @@ void *cu_fs6(void *arg) { RU_t *ru = (RU_t *)arg; RU_proc_t *proc = &ru->proc; int64_t AbsoluteSubframe=-1; + fill_rf_config(ru,ru->rf_config_file); init_frame_parms(&ru->frame_parms,1); + phy_init_RU(ru); wait_sync("ru_thread"); + AssertFatal(createUDPsock(NULL, "8888", "127.0.0.1", "7777", &sockFS6), ""); while(1) { AbsoluteSubframe++; @@ -312,6 +340,7 @@ void *du_fs6(void *arg) { phy_init_RU(ru); openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); wait_sync("ru_thread"); + AssertFatal(createUDPsock(NULL, "7777", "127.0.0.1", "8888", &sockFS6),""); while(1) { AbsoluteSubframe++; diff --git a/executables/main-ocp.c b/executables/main-ocp.c index db64e47732..13464ed166 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -107,9 +107,9 @@ void init_RU_proc(RU_t *ru) { char *fs6=getenv("fs6"); if (fs6) { - if ( strncasecmp(fs6,"cu", 2) ) + if ( strncasecmp(fs6,"cu", 2) == 0 ) threadCreate(&t, cu_fs6, (void *)ru, "MainCu", -1, OAI_PRIORITY_RT_MAX); - else if ( strncasecmp(fs6,"du", 2) ) + else if ( strncasecmp(fs6,"du", 2) == 0 ) threadCreate(&t, du_fs6, (void *)ru, "MainDu", -1, OAI_PRIORITY_RT_MAX); else AssertFatal(false, "environement variable fs6 is not cu or du"); diff --git a/executables/split_headers.h b/executables/split_headers.h index 68bb3925d7..064615284f 100644 --- a/executables/split_headers.h +++ b/executables/split_headers.h @@ -2,12 +2,22 @@ #define __SPLIT_HEADERS_H #include +#include #include #define MTU 65536 #define UDP_TIMEOUT 100000L // in nano second #define MAX_BLOCKS 16 #define blockAlign 32 //bytes +typedef struct { + char *sourceIP; + char *sourcePort; + char *destIP; + char *destPort; + struct addrinfo *destAddr; + int sockHandler; +} UDPsock_t; + typedef struct commonUDP_s { uint64_t timestamp; // id of the group (subframe for LTE) uint16_t nbBlocks; // total number of blocks for this timestamp @@ -24,9 +34,9 @@ typedef struct frequency_s { int nbSamples; } frequency_t; -int createListner (int port); -int receiveSubFrame(int sock, uint64_t expectedTS, void *bufferZone, int bufferSize); -int sendSubFrame(int sock, void *bufferZone, int nbBlocks); +bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result); +int receiveSubFrame(UDPsock_t *sock, uint64_t expectedTS, void *bufferZone, int bufferSize); +int sendSubFrame(UDPsock_t *sock, void *bufferZone); inline size_t alignedSize(void *ptr) { commonUDP_t *header=(commonUDP_t *) ptr; return ((header->contentBytes+sizeof(commonUDP_t)+blockAlign-1)/blockAlign)*blockAlign; @@ -37,6 +47,8 @@ void *du_fs6(void *arg); void fill_rf_config(RU_t *ru, char *rf_config_file); void rx_rf(RU_t *ru,int *frame,int *subframe); void tx_rf(RU_t *ru); +void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe); +void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc); // mistakes in main OAI void phy_init_RU(RU_t *); diff --git a/executables/transport_split.c b/executables/transport_split.c index 8f0ac5108c..00de32a156 100644 --- a/executables/transport_split.c +++ b/executables/transport_split.c @@ -3,40 +3,79 @@ #include #include #include +#include + +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 createListner (int port) { - int sock; - AssertFatal((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0, ""); - struct sockaddr_in addr = { -sin_family: - AF_INET, -sin_port: - htons(port), -sin_addr: - { s_addr: INADDR_ANY } - }; int enable=1; - AssertFatal(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,""); - AssertFatal(bind(sock, (const struct sockaddr *) &addr, sizeof(addr))==0,""); + AssertFatal(setsockopt(result->sockHandler, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,""); struct timeval tv= {0,UDP_TIMEOUT}; - AssertFatal(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,""); + 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(sock, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, ""); - AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, ""); + 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 // expectedTS: the expected timestamp, 0 if unknown // bufferZone: a reception area of bufferSize -int receiveSubFrame(int sock, uint64_t expectedTS, void *bufferZone, int bufferSize) { +int receiveSubFrame(UDPsock_t *sock, uint64_t expectedTS, void *bufferZone, int bufferSize) { int rcved=0; commonUDP_t *tmp=NULL; do { //read all subframe data from the control unit - int ret=recv(sock, bufferZone, bufferSize, 0); + int ret=recv(sock->sockHandler, bufferZone, bufferSize, 0); if ( ret==-1) { if ( errno == EWOULDBLOCK || errno== EINTR ) { @@ -60,14 +99,19 @@ int receiveSubFrame(int sock, uint64_t expectedTS, void *bufferZone, int buffer return rcved; } -int sendSubFrame(int sock, void *bufferZone, int nbBlocks) { +int sendSubFrame(UDPsock_t *sock, void *bufferZone) { + commonUDP_t *header=(commonUDP_t *)bufferZone ; + int nbBlocks=header->nbBlocks; + do { int sz=alignedSize(bufferZone); - int ret=send(sock, bufferZone, sz, 0); + // 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)\n", - sz, ret, errno); + LOG_W(HW,"Wrote socket doesn't return size %d (val: %d, errno:%d, %s)\n", + sz, ret, errno, strerror(errno)); bufferZone+=sz; nbBlocks--;