RUN cd build/odu && make clean_odu odu MACHINE=BIT64 MODE=FDD
+RUN cd build/odu && make clean_odu odu MACHINE=BIT64 MODE=TDD
#CMD /opt/o-du-l2/bin/odu/odu
#cleanup netconf folder and install libraries
/* fill TDD table */
fillTlvs(&configReq->tlvs[index++], FAPI_TDD_PERIOD_TAG, \
sizeof(uint8_t), macCfgParams.tddCfg.tddPeriod, &msgLen);
- for(slotIdx =0 ;slotIdx< MAXIMUM_TDD_PERIODICITY; slotIdx++)
+ for(slotIdx =0 ;slotIdx< MAX_TDD_PERIODICITY_SLOTS; slotIdx++)
{
for(symbolIdx = 0; symbolIdx< MAX_SYMB_PER_SLOT; symbolIdx++)
{
memset(&schCellCfg, 0, sizeof(SchCellCfg));
schCellCfg.cellId = macCellCfg->cellId;
schCellCfg.phyCellId = macCellCfg->phyCellId;
- schCellCfg.bandwidth = macCellCfg->dlCarrCfg.bw;
schCellCfg.numerology = macCellCfg->numerology;
schCellCfg.dupMode = macCellCfg->dupType;
+ schCellCfg.bandwidth = macCellCfg->dlCarrCfg.bw;
+ schCellCfg.dlFreq = macCellCfg->dlCarrCfg.freq;
+ schCellCfg.ulFreq = macCellCfg->ulCarrCfg.freq;
/* fill ssb scheduler parameters */
schCellCfg.ssbSchCfg.ssbPbchPwr = macCellCfg->ssbCfg.ssbPbchPwr;
*
* @param[in] schCellCb *cell
* @param[in] SchCellCfg *schCellCfg
- * @return int
- * -# ROK
- * -# RFAILED
+ * @return void
**/
void schInitTddSlotCfg(SchCellCb *cell, SchCellCfg *schCellCfg)
{
int8_t slotIdx, symbIdx;
periodicityInMicroSec = schGetPeriodicityInMsec(schCellCfg->tddCfg.tddPeriod);
- schCellCfg->numerology = 1; //TODO: Remove this
cell->numSlotsInPeriodicity = (periodicityInMicroSec * pow(2, schCellCfg->numerology))/1000;
cell->slotFrmtBitMap = 0;
cell->symbFrmtBitMap = 0;
}
#endif
+/**
+ * @brief Fill SSB start symbol
+ *
+ * @details
+ *
+ * Function : fillSsbStartSymb
+ *
+ * This API stores SSB start index per beam
+ *
+ * @param[in] SchCellCb *cellCb
+ * @return int
+ * -# ROK
+ * -# RFAILED
+ **/
+void fillSsbStartSymb(SchCellCb *cellCb)
+{
+ uint8_t cnt, scs, symbIdx, ssbStartSymbArr[SCH_MAX_SSB_BEAM];
+
+ scs = cellCb->cellCfg.ssbSchCfg.scsCommon;
+
+ memset(ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
+ symbIdx = 0;
+ /* Determine value of "n" based on Section 4.1 of 3GPP TS 38.213 */
+ switch(scs)
+ {
+ case SCS_15KHZ:
+ {
+ if(cellCb->cellCfg.dlFreq <= 300000)
+ cnt = 2;/* n = 0, 1 */
+ else
+ cnt = 4; /* n = 0, 1, 2, 3 */
+ for(uint8_t idx=0; idx<cnt; idx++)
+ {
+ /* start symbol determined using {2, 8} + 14n */
+ ssbStartSymbArr[symbIdx++] = 2 + SCH_SYMBOL_PER_SLOT*idx;
+ ssbStartSymbArr[symbIdx++] = 8 + SCH_SYMBOL_PER_SLOT*idx;
+ }
+ }
+ break;
+ case SCS_30KHZ:
+ {
+ if(cellCb->cellCfg.dlFreq <= 300000)
+ cnt = 1;/* n = 0 */
+ else
+ cnt = 2; /* n = 0, 1 */
+ for(uint8_t idx=0; idx<cnt; idx++)
+ {
+ /* start symbol determined using {4, 8, 16, 20} + 28n */
+ ssbStartSymbArr[symbIdx++] = 4 + SCH_SYMBOL_PER_SLOT*idx;
+ ssbStartSymbArr[symbIdx++] = 8 + SCH_SYMBOL_PER_SLOT*idx;
+ ssbStartSymbArr[symbIdx++] = 16 + SCH_SYMBOL_PER_SLOT*idx;
+ ssbStartSymbArr[symbIdx++] = 20 + SCH_SYMBOL_PER_SLOT*idx;
+ }
+ }
+ break;
+ default:
+ DU_LOG("\nERROR --> SCH : SCS %d is currently not supported", scs);
+ }
+ memset(cellCb->ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
+ memcpy(cellCb->ssbStartSymbArr, ssbStartSymbArr, SCH_MAX_SSB_BEAM);
+
+}
+
/**
* @brief init cellCb based on cellCfg
cell->schUlSlotInfo[idx] = schUlSlotInfo;
}
+ fillSsbStartSymb(cell);
schCb[inst].cells[inst] = cell;
DU_LOG("\nINFO --> SCH : Cell init completed for cellId:%d", cell->cellId);
}
-/**
- * @brief Fill SSB start symbol
- *
- * @details
- *
- * Function : fillSsbStartSymb
- *
- * This API stores SSB start index per beam
- *
- * @param[in] SchCellCb *cellCb
- * @return int
- * -# ROK
- * -# RFAILED
- **/
-void fillSsbStartSymb(SchCellCb *cellCb)
-{
- uint8_t cnt, scs;
-
- scs = cellCb->cellCfg.ssbSchCfg.scsCommon;
- uint8_t ssbStartSymbArr[SCH_MAX_SSB_BEAM];
-
- memset(ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
- /* Determine value of "n" based on Section 4.1 of 3GPP TS 38.213 */
- switch(scs)
- {
- case SCH_SCS_15KHZ:
- {
- uint8_t symbIdx=0;
- cnt = 2;/* n = 0, 1 for SCS = 15KHz */
- for(uint8_t idx=0; idx<cnt; idx++)
- {
- /* start symbol determined using {2, 8} + 14n */
- ssbStartSymbArr[symbIdx++] = 2 + SCH_SYMBOL_PER_SLOT*idx;
- ssbStartSymbArr[symbIdx++] = 8 + SCH_SYMBOL_PER_SLOT*idx;
- }
- }
- break;
- default:
- DU_LOG("\nERROR --> SCH : SCS %d is currently not supported", scs);
- }
- memset(cellCb->ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
- memcpy(cellCb->ssbStartSymbArr, ssbStartSymbArr, SCH_MAX_SSB_BEAM);
-
-}
-
/**
* @brief cell config from MAC to SCH.
*
#define MAX_NUM_RB 106 /* value for numerology 0 15Khz */
#define SCH_MIB_TRANS 80
#define SCH_NUM_SC_PRB 12 /* number of SCs in a PRB */
-#define SCH_MAX_SSB_BEAM 4 /* since we are supporting only SCS=15KHz */
-#define SCH_SCS_15KHZ 0 /* numerology 0 and 15Khz */
+#define SCH_MAX_SSB_BEAM 8 /* since we are supporting only SCS=15KHz and 30KHz */
#define SCH_SYMBOL_PER_SLOT 14
#define SCH_SSB_NUM_SYMB 4
#define SCH_SSB_NUM_PRB 20
schDlSlotInfo = cell->schDlSlotInfo[slot];
if(dlBrdcstAlloc->ssbTrans)
{
- ssbStartPrb = cell->cellCfg.ssbSchCfg.ssbOffsetPointA;
+ ssbStartPrb = cell->cellCfg.ssbSchCfg.ssbOffsetPointA; //+Kssb
ssbStartSymb = cell->ssbStartSymbArr[dlBrdcstAlloc->ssbIdxSupported-1]; /*since we are
supporting only 1 ssb beam */
}
}
+#ifdef NR_TDD
+
+/**
+ * @brief determines slot format
+ *
+ * @details
+ *
+ * Function : schGetSlotFrmt
+ *
+ * This API is invoked to determine if current slot is DL or UL
+ *
+ * @param[in] uint16_t slot
+ * @param[in] uint32_t slotBitMap from cellCb
+ * @return SlotConfig
+ * -# DL - 0
+ * -# UL - 1
+ * -# FLEXI - 2
+ **/
+SlotConfig schGetSlotFrmt(uint16_t slot, uint32_t slotBitMap)
+{
+ SlotConfig slotFrmt;
+ int mask1 = 0, mask2 = 0;
+
+ slot = (slot%10)*2;
+ mask1 = 1<<(slot);
+ mask2 = 1<<(slot+1);
+ slotFrmt = ((mask1 & slotBitMap)>>slot) + (2*((mask2 & slotBitMap)>>(slot+1)));
+
+ //printf("\n\n\n\n*****FormatType:%d Slot:%d****\n\n\n\n", slotFrmt, slot/2);
+
+ return slotFrmt;
+}
+
+#endif
/**********************************************************************
End of file
**********************************************************************/
SchUeCb* schGetUeCb(SchCellCb *cellCb, uint16_t crnti);
void schInitUlSlot(SchUlSlotInfo *schUlSlotInfo);
void schInitDlSlot(SchDlSlotInfo *schDlSlotInfo);
-
+#ifdef NR_TDD
+SlotConfig schGetSlotFrmt(uint16_t slot, uint32_t slotBitMap);
+#endif
/**********************************************************************
End of file
}DlUlTxPeriodicity;
#endif
+typedef enum
+{
+ SCS_15KHZ,
+ SCS_30KHZ,
+ SCS_60KHZ,
+ SCS_120KHZ,
+ SCS_240KHZ
+}SCS;
+
typedef struct slotIndInfo
{
uint16_t cellId;
{
uint16_t cellId; /* Cell Id */
uint16_t phyCellId; /* Physical cell id */
- uint8_t bandwidth; /* Supported B/W */
uint8_t numerology; /* Supported numerology */
SchDuplexMode dupMode; /* Duplex type: TDD/FDD */
+ uint8_t bandwidth; /* Supported B/W */
+ uint32_t dlFreq; /* DL Frequency */
+ uint32_t ulFreq; /* UL Frequency */
SchSsbCfg ssbSchCfg; /* SSB config */
SchSib1Cfg sib1SchCfg; /* SIB1 config */
SchRachCfg schRachCfg; /* PRACH config */
/* DL carrier configuration */
duCfgParam.macCellCfg.dlCarrCfg.pres = TRUE;
+#ifdef NR_TDD
+ duCfgParam.macCellCfg.dlCarrCfg.bw = BANDWIDTH_100MHZ;
+#else
duCfgParam.macCellCfg.dlCarrCfg.bw = BANDWIDTH_20MHZ;
+#endif
duCfgParam.macCellCfg.dlCarrCfg.freq = NR_DL_ARFCN;
duCfgParam.macCellCfg.dlCarrCfg.k0[0] = 1;
duCfgParam.macCellCfg.dlCarrCfg.k0[1] = 1;
/* UL Carrier configuration */
duCfgParam.macCellCfg.ulCarrCfg.pres = TRUE;
+#ifdef NR_TDD
+ duCfgParam.macCellCfg.dlCarrCfg.bw = BANDWIDTH_100MHZ;
+#else
duCfgParam.macCellCfg.ulCarrCfg.bw = BANDWIDTH_20MHZ;
+#endif
duCfgParam.macCellCfg.ulCarrCfg.freq = NR_UL_ARFCN;
duCfgParam.macCellCfg.ulCarrCfg.k0[0] = 1;
duCfgParam.macCellCfg.ulCarrCfg.k0[1] = 1;
/* SSB configuration */
duCfgParam.macCellCfg.ssbCfg.ssbPbchPwr = SSB_PBCH_PWR;
duCfgParam.macCellCfg.ssbCfg.bchPayloadFlag = BCH_PAYLOAD;
- duCfgParam.macCellCfg.ssbCfg.scsCmn = SUBCARRIER_SPACING;
+#ifdef NR_TDD
+ duCfgParam.macCellCfg.ssbCfg.scsCmn = SCS_30KHZ;
+#else
+ duCfgParam.macCellCfg.ssbCfg.scsCmn = SCS_15KHZ;
+#endif
duCfgParam.macCellCfg.ssbCfg.ssbOffsetPointA = OFFSET_TO_POINT_A;
duCfgParam.macCellCfg.ssbCfg.betaPss = BETA_PSS;
duCfgParam.macCellCfg.ssbCfg.ssbPeriod = SSB_PRDCTY_MS_20;
/* fill Intial DL BWP */
duCfgParam.macCellCfg.initialDlBwp.bwp.firstPrb = 0;
duCfgParam.macCellCfg.initialDlBwp.bwp.numPrb = TOTAL_PRB_20MHZ_MU0; /* configured to total BW */
- duCfgParam.macCellCfg.initialDlBwp.bwp.scs = SUBCARRIER_SPACING; /* numerology is 0, 15Khz */
+#ifdef NR_TDD
+ duCfgParam.macCellCfg.initialDlBwp.bwp.scs = SCS_30KHZ; /* numerology is 1, 30Khz */
+#else
+ duCfgParam.macCellCfg.initialDlBwp.bwp.scs = SCS_15KHZ; /* numerology is 0, 15Khz */
+#endif
duCfgParam.macCellCfg.initialDlBwp.bwp.cyclicPrefix = NORMAL_CYCLIC_PREFIX;
duCfgParam.macCellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.searchSpaceId = SEARCHSPACE_1_INDEX;
duCfgParam.macCellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.coresetId = CORESET_0_INDEX;
/* fill Intial UL BWP */
duCfgParam.macCellCfg.initialUlBwp.bwp.firstPrb = 0;
duCfgParam.macCellCfg.initialUlBwp.bwp.numPrb = TOTAL_PRB_20MHZ_MU0; /* configured to total BW */
- duCfgParam.macCellCfg.initialUlBwp.bwp.scs = SUBCARRIER_SPACING; /* numerology is 0, 15Khz */
+#ifdef NR_TDD
+ duCfgParam.macCellCfg.initialUlBwp.bwp.scs = SCS_30KHZ; /* numerology is 1, 30Khz */
+#else
+ duCfgParam.macCellCfg.initialUlBwp.bwp.scs = SCS_15KHZ; /* numerology is 0, 15Khz */
+#endif
duCfgParam.macCellCfg.initialUlBwp.bwp.cyclicPrefix = NORMAL_CYCLIC_PREFIX;
duCfgParam.macCellCfg.initialUlBwp.puschCommon.k2 = PUSCH_K2;
duCfgParam.macCellCfg.initialUlBwp.puschCommon.mappingType =
TddUlDlCfgCommon tddCfg;
/* Configuring DL Config Common for SIB1*/
- srvCellCfgComm->dlCfg.freqBandInd = NR_FREQ_BAND_IND;
+ srvCellCfgComm->dlCfg.freqBandInd = NR_FREQ_BAND;
srvCellCfgComm->dlCfg.offsetToPointA = OFFSET_TO_POINT_A;
srvCellCfgComm->dlCfg.dlScsCarrier.scsOffset = SSB_SUBCARRIER_OFFSET;
- srvCellCfgComm->dlCfg.dlScsCarrier.scs = SUBCARRIER_SPACING;
+#ifdef NR_TDD
+ srvCellCfgComm->dlCfg.dlScsCarrier.scs = SCS_30KHZ;
+ srvCellCfgComm->dlCfg.dlScsCarrier.scsBw = BANDWIDTH_100MHZ;
+#else
+ srvCellCfgComm->dlCfg.dlScsCarrier.scs = SCS_15KHZ;
srvCellCfgComm->dlCfg.dlScsCarrier.scsBw = BANDWIDTH_20MHZ;
+#endif
srvCellCfgComm->dlCfg.locAndBw = FREQ_LOC_BW;
/* Configuring PDCCH Config Common For SIB1 */
/* Configuring UL Config Common */
srvCellCfgComm->ulCfg.ulScsCarrier.scsOffset = SSB_SUBCARRIER_OFFSET;
- srvCellCfgComm->ulCfg.ulScsCarrier.scs = SUBCARRIER_SPACING;
+#ifdef NR_TDD
+ srvCellCfgComm->ulCfg.ulScsCarrier.scs = SCS_30KHZ;
+ srvCellCfgComm->ulCfg.ulScsCarrier.scsBw = BANDWIDTH_100MHZ;
+#else
+ srvCellCfgComm->ulCfg.ulScsCarrier.scs = SCS_15KHZ;
srvCellCfgComm->ulCfg.ulScsCarrier.scsBw = BANDWIDTH_20MHZ;
+#endif
srvCellCfgComm->ulCfg.pMax = UL_P_MAX;
srvCellCfgComm->ulCfg.locAndBw = FREQ_LOC_BW;
srvCellCfgComm->ulCfg.timeAlignTimerComm = TimeAlignmentTimer_infinity;
mib.dmrs_TypeA_Position = MIB__dmrs_TypeA_Position_pos2;
mib.controlResourceSetZero = CORESET_0_INDEX;
mib.searchSpaceZero = SEARCHSPACE_0_INDEX;
- mib.cellBarred = MIB__cellBarred_barred;
+ mib.cellBarred = MIB__cellBarred_notBarred;
mib.intraFreqReselection =
MIB__intraFreqReselection_notAllowed;
duCfgParam.mibParams = mib;
/*gnb DU System Info mib msg*/
BuildMibMsg();
- DU_ALLOC(duCfgParam.srvdCellLst[i].duSysInfo.mibMsg,\
- strlen(encBuf));
+ DU_ALLOC(duCfgParam.srvdCellLst[i].duSysInfo.mibMsg, encBufSize);
if(!(duCfgParam.srvdCellLst[i].duSysInfo.mibMsg))
{
DU_LOG("\nERROR --> DU APP : Memory allocation failure at readCfg");
return RFAILED;
}
- strcpy((char *)duCfgParam.srvdCellLst[i].duSysInfo.mibMsg, encBuf);
+ memcpy(duCfgParam.srvdCellLst[i].duSysInfo.mibMsg, encBuf, encBufSize);
duCfgParam.srvdCellLst[i].duSysInfo.mibLen = encBufSize;
/*gnb DU System Info mib msg*/
#define CU_EGTP_PORT 39002
#define NR_PCI 1
#define NR_CELL_ID 1
-#define NR_NUMEROLOGY 0
#define DU_NAME "ORAN_OAM_DU"
#define CELL_TYPE SMALL
-#define DUPLEX_MODE DUP_MODE_FDD
+//TODO: while testing for TDD, Mu1 and 100 MHz, this flag must be enabled
#ifdef NR_TDD
#define DUPLEX_MODE DUP_MODE_TDD
+#define NR_NUMEROLOGY 1
+#define NR_DL_ARFCN 623400
+#define NR_UL_ARFCN 623400
+#define NR_FREQ_BAND 78
+#else
+#define DUPLEX_MODE DUP_MODE_FDD
+#define NR_NUMEROLOGY 0
+#define NR_DL_ARFCN 428000
+#define NR_UL_ARFCN 390000
+#define NR_FREQ_BAND 1
#endif
#define DU_TAC 1
#define PLMN_SIZE 3
/* Spec 30.104 Table 5.4.2.3-1:Applicable NR-ARFCN per operating band in FR1 */
-#define NR_DL_ARFCN 428000
-#define NR_UL_ARFCN 390000
#define SUL_ARFCN 100
-#define NR_FREQ_BAND 1
-#define NR_FREQ_BAND_IND 1
#define SUL_BAND 2
+
+
#define TIME_CFG 0
#define CARRIER_IDX 1
#define NUM_TX_ANT 2
#define FREQ_SHIFT_7P5KHZ FALSE
#define SSB_PBCH_PWR 0
#define BCH_PAYLOAD PHY_GEN_TIMING_PBCH_BIT
-#define SUBCARRIER_SPACING 0
#define NORMAL_CYCLIC_PREFIX 0
#define OFFSET_TO_POINT_A 24 /* PRB Offset to Point A */
#define BETA_PSS BETA_PSS_0DB
/* Macro definitions for MIB/SIB1 */
#define SYS_FRAME_NUM 0
#define SPARE 0
-#define SSB_SC_OFFSET 8
+#define SSB_SC_OFFSET 0
#define DU_RANAC 1
#define CELL_IDENTITY 32
&recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
if(ret == ROK && recvBuf != NULLP)
{
- DU_LOG("\nDEBUG --> EGTP : Received DL Message[%d]\n", gDlDataRcvdCnt + 1);
+ DU_LOG("\nDEBUG --> EGTP : Received DL Message[%ld]\n", gDlDataRcvdCnt + 1);
ODU_PRINT_MSG(recvBuf, 0 ,0);
egtpHdlRecvData(recvBuf);
gDlDataRcvdCnt++;
* @return Actual value of pollPdu
*
* ****************************************************************/
-int16_t getPollPdu(uint8_t pollPduCfg)
+int32_t getPollPdu(uint8_t pollPduCfg)
{
- int16_t pollPdu;
+ int32_t pollPdu;
switch(pollPduCfg)
{
case PollPDU_p4:
return RFAILED;
}
/* MIB */
- srvCellItem->gNB_DU_System_Information->mIB_message.size =\
- strlen(( char *)duCfgParam.srvdCellLst[0].duSysInfo.mibMsg);
+ srvCellItem->gNB_DU_System_Information->mIB_message.size = duCfgParam.srvdCellLst[0].duSysInfo.mibLen;
DU_ALLOC(srvCellItem->gNB_DU_System_Information->mIB_message.buf,
srvCellItem->gNB_DU_System_Information->mIB_message.size);
if(!srvCellItem->gNB_DU_System_Information->mIB_message.buf)
{
return RFAILED;
}
- strcpy((char *)srvCellItem->gNB_DU_System_Information->mIB_message.buf,
- (char *)duCfgParam.srvdCellLst[0].duSysInfo.mibMsg);
+ memcpy(srvCellItem->gNB_DU_System_Information->mIB_message.buf, duCfgParam.srvdCellLst[0].duSysInfo.mibMsg, \
+ srvCellItem->gNB_DU_System_Information->mIB_message.size);
/* SIB1 */
srvCellItem->gNB_DU_System_Information->sIB1_message.size =\
* ****************************************************************/
uint8_t BuildMibPdu()
{
- uint8_t BuildMibret;
uint8_t ret = RFAILED;
BCCH_BCH_Message_t *bcchMsg;
asn_enc_rval_t encRetVal; /* Encoder return value */
DU_LOG("\nERROR --> Memory allocation failure in BuildMibPdu");
break;
}
- BuildMibret = BuildMib(bcchMsg->message.choice.mib);
- if(BuildMibret != ROK)
+ if(BuildMib(bcchMsg->message.choice.mib) != ROK)
{
break;
}
encRetVal = aper_encode(&asn_DEF_BCCH_BCH_Message, 0,
bcchMsg, PrepFinalEncBuf, encBuf);
printf("\nencbufSize:%d\n", encBufSize);
- if(encRetVal.encoded == -1)
+ if(encRetVal.encoded == -1)
{
DU_LOG("\nERROR --> DU APP: Could not encode BCCH BCH Message Type structure(at %s)\n",
encRetVal.failed_type?\
MIB_t *mibMsg;
asn_enc_rval_t encRetVal; /* Encoder return value */
uint8_t ret = RFAILED;
- uint8_t BuildMibret;
while(true)
{
DU_ALLOC(mibMsg, sizeof(MIB_t));
DU_LOG("\nERROR --> DU APP: MIB msg memory allocation failure");
return RFAILED;
}
- BuildMibret = BuildMib(mibMsg);
- if(BuildMibret != ROK)
+ if(BuildMib(mibMsg) != ROK)
{
break;
}
*******************************************************************************/
#include <unistd.h>
+#ifdef NR_TDD
+#define MAX_SLOT_VALUE 19
+#else
#define MAX_SLOT_VALUE 9
+#endif
#define MAX_SFN_VALUE 1023
#define NR_PCI 1
#define SLOT_DELAY 3
* ****************************************************************/
void *GenerateTicks(void *arg)
{
- int milisec = 1; /* 1ms */
+#ifdef NR_TDD
+ int milisec = 0.5; /* 0.5ms */
+#else
+ int milisec = 1; /* 1ms */
+#endif
struct timespec req = {0};
req.tv_sec = 0;
while(1)
{
- nanosleep(&req, (struct timespec *)NULL);
-
+ clock_nanosleep(CLOCK_REALTIME, 0, &req, NULL);
/* Send Slot indication indication to lower mac */
l1BuildAndSendSlotIndication();
}