mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
ba3088c4bd
into separate patch files
580 lines
18 KiB
Diff
580 lines
18 KiB
Diff
*** stock_iot-lab_M3/openwsn/02b-MAChigh/schedule.c Thu Apr 24 11:01:36 2014
|
|
--- riot-openwsn-wip/openwsn/02b-MAChigh/schedule.c Thu Apr 24 16:55:54 2014
|
|
***************
|
|
*** 2,26 ****
|
|
#include "schedule.h"
|
|
#include "openserial.h"
|
|
#include "openrandom.h"
|
|
|
|
//=========================== variables =======================================
|
|
|
|
- typedef struct {
|
|
- scheduleEntry_t scheduleBuf[MAXACTIVESLOTS];
|
|
- scheduleEntry_t* currentScheduleEntry;
|
|
- uint16_t frameLength;
|
|
- uint8_t backoffExponent;
|
|
- uint8_t backoff;
|
|
- slotOffset_t debugPrintRow;
|
|
- } schedule_vars_t;
|
|
-
|
|
schedule_vars_t schedule_vars;
|
|
-
|
|
- typedef struct {
|
|
- uint8_t numActiveSlotsCur;
|
|
- uint8_t numActiveSlotsMax;
|
|
- } schedule_dbg_t;
|
|
-
|
|
schedule_dbg_t schedule_dbg;
|
|
|
|
//=========================== prototypes ======================================
|
|
--- 2,12 ----
|
|
#include "schedule.h"
|
|
#include "openserial.h"
|
|
#include "openrandom.h"
|
|
+ #include "packetfunctions.h"
|
|
|
|
//=========================== variables =======================================
|
|
|
|
schedule_vars_t schedule_vars;
|
|
schedule_dbg_t schedule_dbg;
|
|
|
|
//=========================== prototypes ======================================
|
|
***************
|
|
*** 31,44 ****
|
|
|
|
//=== admin
|
|
|
|
! void schedule_init() {
|
|
uint8_t i;
|
|
slotOffset_t running_slotOffset;
|
|
open_addr_t temp_neighbor;
|
|
|
|
// reset local variables
|
|
memset(&schedule_vars,0,sizeof(schedule_vars_t));
|
|
! for (i=0;i<MAXACTIVESLOTS;i++){
|
|
schedule_resetEntry(&schedule_vars.scheduleBuf[i]);
|
|
}
|
|
schedule_vars.backoffExponent = MINBE-1;
|
|
--- 17,30 ----
|
|
|
|
//=== admin
|
|
|
|
! void schedule_init(void) {
|
|
uint8_t i;
|
|
slotOffset_t running_slotOffset;
|
|
open_addr_t temp_neighbor;
|
|
|
|
// reset local variables
|
|
memset(&schedule_vars,0,sizeof(schedule_vars_t));
|
|
! for (i=0;i<MAXACTIVESLOTS;i++) {
|
|
schedule_resetEntry(&schedule_vars.scheduleBuf[i]);
|
|
}
|
|
schedule_vars.backoffExponent = MINBE-1;
|
|
***************
|
|
*** 58,64 ****
|
|
CELLTYPE_ADV, // type of slot
|
|
FALSE, // shared?
|
|
0, // channel offset
|
|
! &temp_neighbor // neighbor
|
|
);
|
|
running_slotOffset++;
|
|
}
|
|
--- 44,51 ----
|
|
CELLTYPE_ADV, // type of slot
|
|
FALSE, // shared?
|
|
0, // channel offset
|
|
! &temp_neighbor, // neighbor
|
|
! FALSE //no update but insert
|
|
);
|
|
running_slotOffset++;
|
|
}
|
|
***************
|
|
*** 72,78 ****
|
|
CELLTYPE_TXRX, // type of slot
|
|
TRUE, // shared?
|
|
0, // channel offset
|
|
! &temp_neighbor // neighbor
|
|
);
|
|
running_slotOffset++;
|
|
}
|
|
--- 59,66 ----
|
|
CELLTYPE_TXRX, // type of slot
|
|
TRUE, // shared?
|
|
0, // channel offset
|
|
! &temp_neighbor, // neighbor
|
|
! FALSE //no update but insert
|
|
);
|
|
running_slotOffset++;
|
|
}
|
|
***************
|
|
*** 84,90 ****
|
|
CELLTYPE_SERIALRX, // type of slot
|
|
FALSE, // shared?
|
|
0, // channel offset
|
|
! &temp_neighbor // neighbor
|
|
);
|
|
running_slotOffset++;
|
|
/*
|
|
--- 72,79 ----
|
|
CELLTYPE_SERIALRX, // type of slot
|
|
FALSE, // shared?
|
|
0, // channel offset
|
|
! &temp_neighbor, // neighbor
|
|
! FALSE //no update but insert
|
|
);
|
|
running_slotOffset++;
|
|
/*
|
|
***************
|
|
*** 109,132 ****
|
|
|
|
\returns TRUE if this function printed something, FALSE otherwise.
|
|
*/
|
|
! bool debugPrint_schedule() {
|
|
debugScheduleEntry_t temp;
|
|
! schedule_vars.debugPrintRow = (schedule_vars.debugPrintRow+1)%MAXACTIVESLOTS;
|
|
! temp.row = schedule_vars.debugPrintRow;
|
|
! //copy element by element to the struct that will be serialized. we don't want to sent the pointer through the serial port.
|
|
! temp.scheduleEntry.channelOffset = schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].channelOffset;
|
|
! temp.scheduleEntry.numRx = schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numRx;
|
|
! temp.scheduleEntry.numTx=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTx;
|
|
! temp.scheduleEntry.numTxACK=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTxACK;
|
|
! temp.scheduleEntry.lastUsedAsn=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].lastUsedAsn;
|
|
! temp.scheduleEntry.neighbor=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].neighbor;
|
|
! temp.scheduleEntry.shared=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].shared;
|
|
! temp.scheduleEntry.slotOffset=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].slotOffset;
|
|
! temp.scheduleEntry.type=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].type;
|
|
!
|
|
openserial_printStatus(STATUS_SCHEDULE,
|
|
(uint8_t*)&temp,
|
|
! sizeof(debugScheduleEntry_t));
|
|
return TRUE;
|
|
}
|
|
|
|
--- 98,139 ----
|
|
|
|
\returns TRUE if this function printed something, FALSE otherwise.
|
|
*/
|
|
! bool debugPrint_schedule(void) {
|
|
debugScheduleEntry_t temp;
|
|
!
|
|
! schedule_vars.debugPrintRow = (schedule_vars.debugPrintRow+1)%MAXACTIVESLOTS;
|
|
!
|
|
! temp.row = schedule_vars.debugPrintRow;
|
|
! temp.slotOffset = \
|
|
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].slotOffset;
|
|
! temp.type = \
|
|
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].type;
|
|
! temp.shared = \
|
|
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].shared;
|
|
! temp.channelOffset = \
|
|
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].channelOffset;
|
|
! memcpy(
|
|
! &temp.neighbor,
|
|
! &schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].neighbor,
|
|
! sizeof(open_addr_t)
|
|
! );
|
|
! temp.numRx = \
|
|
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numRx;
|
|
! temp.numTx = \
|
|
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTx;
|
|
! temp.numTxACK = \
|
|
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTxACK;
|
|
! memcpy(
|
|
! &temp.lastUsedAsn,
|
|
! &schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].lastUsedAsn,
|
|
! sizeof(asn_t)
|
|
! );
|
|
!
|
|
openserial_printStatus(STATUS_SCHEDULE,
|
|
(uint8_t*)&temp,
|
|
! sizeof(debugScheduleEntry_t)
|
|
! );
|
|
!
|
|
return TRUE;
|
|
}
|
|
|
|
***************
|
|
*** 138,144 ****
|
|
|
|
\returns TRUE if this function printed something, FALSE otherwise.
|
|
*/
|
|
! bool debugPrint_backoff() {
|
|
uint8_t temp[2];
|
|
temp[0] = schedule_vars.backoffExponent;
|
|
temp[1] = schedule_vars.backoff;
|
|
--- 145,151 ----
|
|
|
|
\returns TRUE if this function printed something, FALSE otherwise.
|
|
*/
|
|
! bool debugPrint_backoff(void) {
|
|
uint8_t temp[2];
|
|
temp[0] = schedule_vars.backoffExponent;
|
|
temp[1] = schedule_vars.backoff;
|
|
***************
|
|
*** 163,194 ****
|
|
}
|
|
|
|
/**
|
|
\brief Add a new active slot into the schedule.
|
|
|
|
! \param newFrameLength The new frame length.
|
|
*/
|
|
! void schedule_addActiveSlot(slotOffset_t slotOffset,
|
|
cellType_t type,
|
|
bool shared,
|
|
! uint8_t channelOffset,
|
|
! open_addr_t* neighbor) {
|
|
scheduleEntry_t* slotContainer;
|
|
scheduleEntry_t* previousSlotWalker;
|
|
scheduleEntry_t* nextSlotWalker;
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
!
|
|
// find an empty schedule entry container
|
|
slotContainer = &schedule_vars.scheduleBuf[0];
|
|
while (slotContainer->type!=CELLTYPE_OFF &&
|
|
slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) {
|
|
! slotContainer++;
|
|
}
|
|
if (slotContainer>&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) {
|
|
// schedule has overflown
|
|
openserial_printCritical(COMPONENT_SCHEDULE,ERR_SCHEDULE_OVERFLOWN,
|
|
(errorparameter_t)0,
|
|
(errorparameter_t)0);
|
|
}
|
|
// fill that schedule entry with parameters passed
|
|
slotContainer->slotOffset = slotOffset;
|
|
--- 170,274 ----
|
|
}
|
|
|
|
/**
|
|
+ \brief get the information of a spcific slot.
|
|
+
|
|
+ \param slotOffset
|
|
+ \param neighbor
|
|
+ \param info
|
|
+ */
|
|
+ void schedule_getSlotInfo(
|
|
+ slotOffset_t slotOffset,
|
|
+ open_addr_t* neighbor,
|
|
+ slotinfo_element_t* info
|
|
+ ){
|
|
+
|
|
+ scheduleEntry_t* slotContainer;
|
|
+
|
|
+ // find an empty schedule entry container
|
|
+ slotContainer = &schedule_vars.scheduleBuf[0];
|
|
+ while (slotContainer->type!=CELLTYPE_OFF && slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) {
|
|
+ //check that this entry for that neighbour and timeslot is not already scheduled.
|
|
+ if (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))&& (slotContainer->slotOffset==slotOffset)){
|
|
+ //it exists so this is an update.
|
|
+ info->link_type = slotContainer->type;
|
|
+ info->shared =slotContainer->shared;
|
|
+ info->channelOffset = slotContainer->channelOffset;
|
|
+ return; //as this is an update. No need to re-insert as it is in the same position on the list.
|
|
+ }
|
|
+ slotContainer++;
|
|
+ }
|
|
+ //return cell type off.
|
|
+ info->link_type = CELLTYPE_OFF;
|
|
+ info->shared = FALSE;
|
|
+ info->channelOffset = 0;//set to zero if not set.
|
|
+ }
|
|
+
|
|
+ /**
|
|
\brief Add a new active slot into the schedule.
|
|
|
|
! If udpate param is set then update it in case it exists.
|
|
!
|
|
! \param slotOffset
|
|
! \param type
|
|
! \param shared
|
|
! \param channelOffset
|
|
! \param neighbor
|
|
! \param isUpdate
|
|
*/
|
|
! owerror_t schedule_addActiveSlot(
|
|
! slotOffset_t slotOffset,
|
|
cellType_t type,
|
|
bool shared,
|
|
! channelOffset_t channelOffset,
|
|
! open_addr_t* neighbor,
|
|
! bool isUpdate
|
|
! ) {
|
|
!
|
|
! owerror_t outcome;
|
|
!
|
|
scheduleEntry_t* slotContainer;
|
|
scheduleEntry_t* previousSlotWalker;
|
|
scheduleEntry_t* nextSlotWalker;
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
!
|
|
!
|
|
// find an empty schedule entry container
|
|
slotContainer = &schedule_vars.scheduleBuf[0];
|
|
while (slotContainer->type!=CELLTYPE_OFF &&
|
|
slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) {
|
|
!
|
|
! //check that this entry for that neighbour and timeslot is not already scheduled.
|
|
! if (type!=CELLTYPE_SERIALRX && type!=CELLTYPE_MORESERIALRX &&
|
|
! (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))||
|
|
! (slotContainer->neighbor.type==ADDR_ANYCAST && isUpdate==TRUE))
|
|
! &&(slotContainer->slotOffset==slotOffset)){
|
|
! //it exists so this is an update.
|
|
! slotContainer->type = type;
|
|
! slotContainer->shared = shared;
|
|
! slotContainer->channelOffset = channelOffset;
|
|
! memcpy(&slotContainer->neighbor,neighbor,sizeof(open_addr_t));//update the address too!
|
|
! schedule_dbg.numUpdatedSlotsCur++;
|
|
! ENABLE_INTERRUPTS();
|
|
! return E_SUCCESS; //as this is an update. No need to re-insert as it is in the same position on the list.
|
|
! }
|
|
!
|
|
! slotContainer++;
|
|
! }
|
|
!
|
|
! if (isUpdate==TRUE) {
|
|
! //we are trying to update an item that is not in the schedule list.
|
|
! ENABLE_INTERRUPTS();
|
|
! return E_FAIL;
|
|
}
|
|
if (slotContainer>&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) {
|
|
// schedule has overflown
|
|
+ outcome=E_FAIL;
|
|
openserial_printCritical(COMPONENT_SCHEDULE,ERR_SCHEDULE_OVERFLOWN,
|
|
(errorparameter_t)0,
|
|
(errorparameter_t)0);
|
|
+
|
|
+
|
|
}
|
|
// fill that schedule entry with parameters passed
|
|
slotContainer->slotOffset = slotOffset;
|
|
***************
|
|
*** 242,250 ****
|
|
--- 322,399 ----
|
|
if (schedule_dbg.numActiveSlotsCur>schedule_dbg.numActiveSlotsMax) {
|
|
schedule_dbg.numActiveSlotsMax = schedule_dbg.numActiveSlotsCur;
|
|
}
|
|
+ outcome=E_SUCCESS;
|
|
ENABLE_INTERRUPTS();
|
|
+ return outcome;
|
|
+ }
|
|
+
|
|
+
|
|
+
|
|
+ owerror_t schedule_removeActiveSlot(slotOffset_t slotOffset, open_addr_t* neighbor){
|
|
+
|
|
+ owerror_t outcome;
|
|
+
|
|
+ scheduleEntry_t* slotContainer;
|
|
+ scheduleEntry_t* previousSlotWalker;
|
|
+
|
|
+ INTERRUPT_DECLARATION();
|
|
+ DISABLE_INTERRUPTS();
|
|
+
|
|
+
|
|
+ // find the schedule entry
|
|
+ slotContainer = &schedule_vars.scheduleBuf[0];
|
|
+ while (slotContainer->type!=CELLTYPE_OFF && slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) {
|
|
+ //check that this entry for that neighbour and timeslot is not already scheduled.
|
|
+ if (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))&& (slotContainer->slotOffset==slotOffset)){
|
|
+ break;
|
|
+ }
|
|
+ slotContainer++;
|
|
+ }
|
|
+
|
|
+ if (slotContainer->next==slotContainer) {
|
|
+ // this is the last active slot
|
|
+
|
|
+ // the next slot of this slot is NULL
|
|
+ slotContainer->next = NULL;
|
|
+
|
|
+ // current slot points to this slot
|
|
+ schedule_vars.currentScheduleEntry = NULL;
|
|
+ } else {
|
|
+ // this is NOT the last active slot
|
|
+
|
|
+ // find the previous in the schedule
|
|
+ previousSlotWalker = schedule_vars.currentScheduleEntry;
|
|
+
|
|
+ while (1) {
|
|
+ if ((previousSlotWalker->next=slotContainer)){
|
|
+ break;
|
|
+ }
|
|
+ previousSlotWalker = previousSlotWalker->next;
|
|
+ }
|
|
+ // remove this element from the linked list
|
|
+ previousSlotWalker->next = slotContainer->next;//my next;
|
|
+ slotContainer->next = NULL;
|
|
+ }
|
|
+
|
|
+ // clear that schedule entry
|
|
+ slotContainer->slotOffset = 0;
|
|
+ slotContainer->type = CELLTYPE_OFF;
|
|
+ slotContainer->shared = FALSE;
|
|
+ slotContainer->channelOffset = 0;
|
|
+ memset(&slotContainer->neighbor,0,sizeof(open_addr_t));
|
|
+
|
|
+ // maintain debug stats
|
|
+ schedule_dbg.numActiveSlotsCur--;
|
|
+
|
|
+ outcome=E_SUCCESS;
|
|
+ ENABLE_INTERRUPTS();
|
|
+
|
|
+ return outcome;
|
|
}
|
|
|
|
+
|
|
+
|
|
+
|
|
//=== from IEEE802154E: reading the schedule and updating statistics
|
|
|
|
void schedule_syncSlotOffset(slotOffset_t targetSlotOffset) {
|
|
***************
|
|
*** 256,262 ****
|
|
ENABLE_INTERRUPTS();
|
|
}
|
|
|
|
! void schedule_advanceSlot() {
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
// advance to next active slot
|
|
--- 405,411 ----
|
|
ENABLE_INTERRUPTS();
|
|
}
|
|
|
|
! void schedule_advanceSlot(void) {
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
// advance to next active slot
|
|
***************
|
|
*** 264,270 ****
|
|
ENABLE_INTERRUPTS();
|
|
}
|
|
|
|
! slotOffset_t schedule_getNextActiveSlotOffset() {
|
|
slotOffset_t res;
|
|
INTERRUPT_DECLARATION();
|
|
|
|
--- 413,419 ----
|
|
ENABLE_INTERRUPTS();
|
|
}
|
|
|
|
! slotOffset_t schedule_getNextActiveSlotOffset(void) {
|
|
slotOffset_t res;
|
|
INTERRUPT_DECLARATION();
|
|
|
|
***************
|
|
*** 281,287 ****
|
|
|
|
\returns The frame length.
|
|
*/
|
|
! frameLength_t schedule_getFrameLength() {
|
|
frameLength_t res;
|
|
INTERRUPT_DECLARATION();
|
|
|
|
--- 430,436 ----
|
|
|
|
\returns The frame length.
|
|
*/
|
|
! frameLength_t schedule_getFrameLength(void) {
|
|
frameLength_t res;
|
|
INTERRUPT_DECLARATION();
|
|
|
|
***************
|
|
*** 297,303 ****
|
|
|
|
\returns The type of the current schedule entry.
|
|
*/
|
|
! cellType_t schedule_getType() {
|
|
cellType_t res;
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
--- 446,452 ----
|
|
|
|
\returns The type of the current schedule entry.
|
|
*/
|
|
! cellType_t schedule_getType(void) {
|
|
cellType_t res;
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
***************
|
|
*** 323,329 ****
|
|
|
|
\returns The channel offset of the current schedule entry.
|
|
*/
|
|
! channelOffset_t schedule_getChannelOffset() {
|
|
channelOffset_t res;
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
--- 472,478 ----
|
|
|
|
\returns The channel offset of the current schedule entry.
|
|
*/
|
|
! channelOffset_t schedule_getChannelOffset(void) {
|
|
channelOffset_t res;
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
***************
|
|
*** 344,350 ****
|
|
|
|
\returns TRUE if it is OK to send on this slot, FALSE otherwise.
|
|
*/
|
|
! bool schedule_getOkToSend() {
|
|
bool returnVal;
|
|
|
|
INTERRUPT_DECLARATION();
|
|
--- 493,499 ----
|
|
|
|
\returns TRUE if it is OK to send on this slot, FALSE otherwise.
|
|
*/
|
|
! bool schedule_getOkToSend(void) {
|
|
bool returnVal;
|
|
|
|
INTERRUPT_DECLARATION();
|
|
***************
|
|
*** 377,383 ****
|
|
/**
|
|
\brief Reset the backoff and backoffExponent.
|
|
*/
|
|
! void schedule_resetBackoff() {
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
|
|
--- 526,532 ----
|
|
/**
|
|
\brief Reset the backoff and backoffExponent.
|
|
*/
|
|
! void schedule_resetBackoff(void) {
|
|
INTERRUPT_DECLARATION();
|
|
DISABLE_INTERRUPTS();
|
|
|
|
***************
|
|
*** 459,472 ****
|
|
pScheduleEntry->type = CELLTYPE_OFF;
|
|
pScheduleEntry->shared = FALSE;
|
|
pScheduleEntry->channelOffset = 0;
|
|
pScheduleEntry->neighbor.type = ADDR_NONE;
|
|
! pScheduleEntry->neighbor.addr_64b[0] = 0x14;
|
|
! pScheduleEntry->neighbor.addr_64b[1] = 0x15;
|
|
! pScheduleEntry->neighbor.addr_64b[2] = 0x92;
|
|
! pScheduleEntry->neighbor.addr_64b[3] = 0x09;
|
|
! pScheduleEntry->neighbor.addr_64b[4] = 0x02;
|
|
! pScheduleEntry->neighbor.addr_64b[5] = 0x2c;
|
|
! pScheduleEntry->neighbor.addr_64b[6] = 0x00;
|
|
pScheduleEntry->numRx = 0;
|
|
pScheduleEntry->numTx = 0;
|
|
pScheduleEntry->numTxACK = 0;
|
|
--- 608,617 ----
|
|
pScheduleEntry->type = CELLTYPE_OFF;
|
|
pScheduleEntry->shared = FALSE;
|
|
pScheduleEntry->channelOffset = 0;
|
|
+
|
|
pScheduleEntry->neighbor.type = ADDR_NONE;
|
|
! memset(&pScheduleEntry->neighbor.addr_64b[0], 0x00, sizeof(pScheduleEntry->neighbor.addr_64b));
|
|
!
|
|
pScheduleEntry->numRx = 0;
|
|
pScheduleEntry->numTx = 0;
|
|
pScheduleEntry->numTxACK = 0;
|