/************************************************************************* * will be called by post_net, etc functions to send message * *************************************************************************/ void radio_msg_alloc(Message *msg) { HAS_CRITICAL_SECTION; uint16_t sleeptime = 0; uint8_t resend_pack = 1; ENTER_CRITICAL_SECTION(); if( Radio_Check_CCA() ) { incSeq(); if(radio_msg_send(msg)) { resend_pack = 0; msg_send_senddone(msg, 1, RADIO_PID); } } if(resend_pack) { if( getMsgNumOfQueue() < MAX_MSGS_IN_QUEUE ) //queue is full? { mq_enqueue(&vmac_pq, msg); ENTER_CRITICAL_SECTION(); // most probably mq_enqueue calls LEAVE_CRITICAL_SECTION somewhere! } else { msg_send_senddone(msg, 0, RADIO_PID); //release the memory for the msg ENTER_CRITICAL_SECTION(); // most probably msg_send_senddone calls LEAVE_CRITICAL_SECTION somewhere! } sleeptime = MacBackoff_congestionBackoff(retry_count); ker_timer_restart(RADIO_PID, WAKEUP_TIMER_TID, sleeptime); // setup backoff timer } LEAVE_CRITICAL_SECTION(); }
int8_t ker_sys_timer_restart(uint8_t tid, int32_t interval) { sos_pid_t my_id = ker_get_current_pid(); if( ker_timer_restart(my_id, tid, interval) != SOS_OK ) { return ker_mod_panic(my_id); } return SOS_OK; }
static int8_t handle_request(Message *msg) { int8_t ret; //! setup a periodic timer to send fragments if(send_state.map == NULL) { fetcher_bitmap_t *b = (fetcher_bitmap_t*) msg->data; ret = set_num_funcs_in_send_state(b->key); if( ret != SOS_OK ) { // cannot find num funcs, give up return SOS_OK; } ret = ker_timer_restart(KER_FETCHER_PID, FETCHER_TRANSMIT_TID, FETCHER_SENDING_FRAGMENT_INTERVAL); if(ret == SOS_OK) { send_state.map = (fetcher_bitmap_t*)ker_msg_take_data(KER_FETCHER_PID, msg); send_state.dest = msg->saddr; DEBUG_PID(KER_FETCHER_PID,"send_state.map = 0x%x send_state.dest = 0x%x\n", (int)send_state.map, send_state.dest); } else { return -ENOMEM; } } else { fetcher_bitmap_t *map = (fetcher_bitmap_t*)msg->data; //! XXX change to broadcast //send_state.dest = BCAST_ADDRESS; DEBUG_PID(KER_FETCHER_PID,"else send_state.dest = %x\n", send_state.dest); //! merge wanted list if((send_state.map->key == map->key)) { uint8_t i; for(i = 0; i < send_state.map->bitmap_size && i < map->bitmap_size; i++) { send_state.map->bitmap[i] |= map->bitmap[i]; } } } if( fst != NULL && (fst->map.key == send_state.map->key) ) { //! send only those we have uint8_t i; for(i = 0; i < send_state.map->bitmap_size; i++ ) { uint8_t tmp; //! this is the fragment that has been requested but we dont have tmp = send_state.map->bitmap[i] & fst->map.bitmap[i]; send_state.map->bitmap[i] &= ~tmp; } } return SOS_OK; }
static inline void restart_request_timer() { ker_timer_restart(KER_FETCHER_PID, FETCHER_REQUEST_TID, FETCHER_REQUEST_WATCHDOG + (FETCHER_REQUEST_BACKOFF_SLOT * ((ker_rand() % FETCHER_REQUEST_MAX_SLOT) + 1))); }
/************************************************************************* * implement backoff mechanism for Colliosn Avoidance * *************************************************************************/ void backoff_timeout() { // Dimitrios HAS_CRITICAL_SECTION; uint8_t tx_failed=0; ENTER_CRITICAL_SECTION(); if( isQueueEmpty() ) { LEAVE_CRITICAL_SECTION(); return; } if(valid_msg==0) { vmac_msg = NULL; vmac_msg = mq_dequeue(&vmac_pq); // dequeue packet from mq if(vmac_msg) valid_msg=1; } if(valid_msg==1) { if( Radio_Check_CCA() ) { if(radio_msg_send(vmac_msg)) { valid_msg=0; msg_send_senddone(vmac_msg, 1, RADIO_PID); ENTER_CRITICAL_SECTION(); resetRetries(); //set retry_count 0 } else { tx_failed=1; } } else { tx_failed=1; } } // Message transmission did not work! if(tx_failed==1) { if( getRetries() < (uint8_t)MAX_RETRIES ) { incRetries(); //increase retry_count } else { if(vmac_msg) { valid_msg=0; msg_send_senddone(vmac_msg, 0, RADIO_PID); //to release the memory for this msg ENTER_CRITICAL_SECTION(); resetRetries(); //set retry_count 0 } } } uint16_t sleeptime = MacBackoff_congestionBackoff(retry_count); ker_timer_restart(RADIO_PID, WAKEUP_TIMER_TID, sleeptime); // setup new backoff timer LEAVE_CRITICAL_SECTION(); }