*** 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;itype!=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;