arch/dev/radio/dw1000/tsm/trex-tsm.c
/* This function is the main interface with the higher layer.
 * It fills in the previous action interface structure,
 * calls the higher-layer callback, and analyses its response
 * recorded in the next action interface structure.
 */
This function is the main interface with the higher layer.
It fills in the previous action interface structure,
calls the higher-layer callback, and analyses its response
recorded in the next action interface structure.
This function is the main interface with the higher layer . It fills in the previous action interface structure calls the higher - layer callback and analyses its response recorded in the next action interface structure .
static void tsm_slot_event() {
  bool recall;  
  do {
    recall = 0; 
    if (context.slot_action == TSM_ACTION_SCAN
          && context.slot_status == TREX_RX_SUCCESS) {
      context.slot_idx = context.tentative_slot_idx;
      context.tref = context.tentative_slot_tref - context.tentative_slot_idx*context.slot_duration;
    }
    tsm_next_action = TSM_NEXT_ACTION_INITIALIZER;
    tsm_prev_action.action   = context.slot_action;
    tsm_prev_action.slot_idx = context.slot_idx; 
    tsm_prev_action.status   = context.slot_status; 
    tsm_prev_action.remote_slot_idx = context.tentative_slot_idx;
    DBG("Calling higher layer");
    context.cb();
    if (tsm_next_action.accept_sync
          && context.slot_action == TSM_ACTION_RX
          && context.slot_status == TREX_RX_SUCCESS) {
      context.slot_idx = context.tentative_slot_idx;
      context.tref = context.tentative_slot_tref - context.tentative_slot_idx*context.slot_duration;
    }
    if (tsm_next_action.rx_guard_time == TSM_DEFAULT_RXGUARD) {
        trexd_set_rx_slot_preambleto_pacs(context.default_preambleto_pacs);
    } else {
        trexd_set_rx_slot_preambleto_pacs(0);
    }
#if TSM_LOG_SLOTS
    if (context.slot_status != TREX_NONE) {
      struct tsm_log entry;
      entry.status = context.slot_status;
      entry.action = context.slot_action;
      entry.progress = tsm_next_action.progress_slots;
      entry.slot_idx = context.slot_idx;
      if (context.slot_status == TREX_RX_SUCCESS) {
        entry.idx_diff = context.slot_idx - context.tentative_slot_idx;
      }
      else {
        entry.idx_diff = 0;
      }
      if (context.slot_status == TREX_RX_SUCCESS && (
            tsm_next_action.accept_sync || context.slot_action == TSM_ACTION_SCAN)) {
        entry.status = TSM_LOG_STATUS_RX_WITH_SYNCH; 
      }
      tsm_log_append(&entry);
    }
#endif
    int ret = -1;
    context.slot_action = TSM_ACTION_NONE; 
    switch(tsm_next_action.action) {
      case TSM_ACTION_TX:
        WARNIF(tsm_next_action.progress_slots == 0); 
        context.slot_idx  += tsm_next_action.progress_slots; 
        ret = tsm_tx(tsm_next_action.buffer, tsm_next_action.payload_len);
        break;
      case TSM_ACTION_RX:
        WARNIF(tsm_next_action.progress_slots == 0); 
        context.slot_idx  += tsm_next_action.progress_slots; 
        ret = tsm_rx(tsm_next_action.buffer);
        break;
      case TSM_ACTION_SCAN:
        if (context.slot_idx == -1) {
            context.slot_idx  = 0; 
            ret = tsm_scan_next_epoch(tsm_next_action.buffer);
        }
        else {
            context.slot_idx  = 0; 
            ret = tsm_scan(tsm_next_action.buffer);
        }
        break;
      case TSM_ACTION_RESTART: 
        context.tref += tsm_next_action.restart_interval;
        context.slot_idx = -1;
        context.slot_status = TREX_NONE;
        recall = 1; 
        trexd_stats_print();
        trexd_stats_reset();
#if TSM_LOG_SLOTS
        tsm_log_print();
#endif
        continue;   
      case TSM_ACTION_STOP:
        return;
      default: ERR("Unexpected action requested %u", tsm_next_action.action);
        return;
    }
    if (ret >= 0) {
      context.slot_action = tsm_next_action.action;
    }
    else {
      ERR("Failed to schedule a slot action %u", tsm_next_action.action);
      return;
    }
  } while (recall);
}
static void tsm_slot_event ( ) { bool recall ; do { recall = 0 ; if ( context . slot_action == TSM_ACTION_SCAN && context . slot_status == TREX_RX_SUCCESS ) { context . slot_idx = context . tentative_slot_idx ; context . tref = context . tentative_slot_tref - context . tentative_slot_idx * context . slot_duration ; } tsm_next_action = TSM_NEXT_ACTION_INITIALIZER ; tsm_prev_action . action = context . slot_action ; tsm_prev_action . slot_idx = context . slot_idx ; tsm_prev_action . status = context . slot_status ; tsm_prev_action . remote_slot_idx = context . tentative_slot_idx ; DBG ( " " ) ; context . cb ( ) ; if ( tsm_next_action . accept_sync && context . slot_action == TSM_ACTION_RX && context . slot_status == TREX_RX_SUCCESS ) { context . slot_idx = context . tentative_slot_idx ; context . tref = context . tentative_slot_tref - context . tentative_slot_idx * context . slot_duration ; } if ( tsm_next_action . rx_guard_time == TSM_DEFAULT_RXGUARD ) { trexd_set_rx_slot_preambleto_pacs ( context . default_preambleto_pacs ) ; } else { trexd_set_rx_slot_preambleto_pacs ( 0 ) ; } #if TSM_LOG_SLOTS if ( context . slot_status != TREX_NONE ) { struct tsm_log entry ; entry . status = context . slot_status ; entry . action = context . slot_action ; entry . progress = tsm_next_action . progress_slots ; entry . slot_idx = context . slot_idx ; if ( context . slot_status == TREX_RX_SUCCESS ) { entry . idx_diff = context . slot_idx - context . tentative_slot_idx ; } else { entry . idx_diff = 0 ; } if ( context . slot_status == TREX_RX_SUCCESS && ( tsm_next_action . accept_sync || context . slot_action == TSM_ACTION_SCAN ) ) { entry . status = TSM_LOG_STATUS_RX_WITH_SYNCH ; } tsm_log_append ( & entry ) ; } #endif int ret = -1 ; context . slot_action = TSM_ACTION_NONE ; switch ( tsm_next_action . action ) { case TSM_ACTION_TX : WARNIF ( tsm_next_action . progress_slots == 0 ) ; context . slot_idx += tsm_next_action . progress_slots ; ret = tsm_tx ( tsm_next_action . buffer , tsm_next_action . payload_len ) ; break ; case TSM_ACTION_RX : WARNIF ( tsm_next_action . progress_slots == 0 ) ; context . slot_idx += tsm_next_action . progress_slots ; ret = tsm_rx ( tsm_next_action . buffer ) ; break ; case TSM_ACTION_SCAN : if ( context . slot_idx == -1 ) { context . slot_idx = 0 ; ret = tsm_scan_next_epoch ( tsm_next_action . buffer ) ; } else { context . slot_idx = 0 ; ret = tsm_scan ( tsm_next_action . buffer ) ; } break ; case TSM_ACTION_RESTART : context . tref += tsm_next_action . restart_interval ; context . slot_idx = -1 ; context . slot_status = TREX_NONE ; recall = 1 ; trexd_stats_print ( ) ; trexd_stats_reset ( ) ; #if TSM_LOG_SLOTS tsm_log_print ( ) ; #endif continue ; case TSM_ACTION_STOP : return ; default : ERR ( " " , tsm_next_action . action ) ; return ; } if ( ret >= 0 ) { context . slot_action = tsm_next_action . action ; } else { ERR ( " " , tsm_next_action . action ) ; return ; } } while ( recall ) ; }
This function is the main interface with the higher layer.
This function is the main interface with the higher layer .
// should we call the callback again? // by default we don't want to call it again // first, update the sync info if we were scanning // (this is processed in the slot after the successful scan //  takes place and allows the higher layer to have an up to //  date and trustable slot_idx) // prepare the interface structures // If the higher layer explicitly requested sync // (we know this only after context.cb() is issued) // fall back to default preamble timeout for tx slots // the gaurd time used has changed, ignore preamble timeout for // the next operation // the callback should have filled in the action request for // the next slot, now we look into it // mark that the sync was accepted // now, process the next requested action /* in case anything goes wrong */ // cannot TX in the same slot twice // progress the slot idx // continuing RX in the same slot is currently not implemented (TODO) // progress the slot idx // start listening in the next epoch // reset the slot idx, to an unitialized state // reset the slot idx, to an unitialized state // call the callback again // restart the loop from the beginning // the action request was succesfull, so we must receive a callback // when it is done // TODO: try to recover instead, call the cb again reporting the error?