void aps_retry_add(buffer_t *buf, aps_hdr_t *hdr, U8 handle) { mem_ptr_t *mem_ptr; if ((mem_ptr = aps_retry_alloc()) != NULL) { APS_RETRY_ENTRY(mem_ptr)->buf = buf; APS_RETRY_ENTRY(mem_ptr)->handle = handle; memcpy(&APS_RETRY_ENTRY(mem_ptr)->hdr, hdr, sizeof(aps_hdr_t)); } }
static mem_ptr_t *aps_retry_alloc() { mem_ptr_t *mem_ptr; if ((mem_ptr = mem_heap_alloc(sizeof(aps_retry_t))) != NULL) { APS_RETRY_ENTRY(mem_ptr)->retries = APS_MAX_FRAME_RETRIES; APS_RETRY_ENTRY(mem_ptr)->expiry = APS_ACK_WAIT_DURATION; } return mem_ptr; }
void aps_retry_ack_handler(const aps_hdr_t *hdr) { mem_ptr_t *mem_ptr; for (mem_ptr = list_head(aps_retry); mem_ptr != NULL; mem_ptr = mem_ptr->next) { if ((APS_RETRY_ENTRY(mem_ptr)->hdr.aps_ctr == hdr->aps_ctr) && (APS_RETRY_ENTRY(mem_ptr)->hdr.clust_id == hdr->clust_id) && (APS_RETRY_ENTRY(mem_ptr)->hdr.dest_ep == hdr->src_ep)) { aps_retry_free(mem_ptr); aps_conf(APS_SUCCESS, APS_RETRY_ENTRY(mem_ptr)->handle); } } }
static void aps_retry_free(mem_ptr_t *mem_ptr) { if (mem_ptr) { buf_free(APS_RETRY_ENTRY(mem_ptr)->buf); list_remove(aps_retry, mem_ptr); mem_heap_free(mem_ptr); } }
void aps_retry_periodic() { mem_ptr_t *mem_ptr; for (mem_ptr = list_head(aps_retry); mem_ptr != NULL; mem_ptr = mem_ptr->next) { // go through the retry list and check for expired entries. if any // are expired, then process them. otherwise, decrement the expiry. if (APS_RETRY_ENTRY(mem_ptr)->expiry == 0) { aps_retry_expire(mem_ptr); } else { APS_RETRY_ENTRY(mem_ptr)->expiry--; } } }
static mem_ptr_t *aps_retry_find(U8 handle) { mem_ptr_t *mem_ptr; for (mem_ptr = list_head(aps_retry); mem_ptr != NULL; mem_ptr = mem_ptr->next) { if (APS_RETRY_ENTRY(mem_ptr)->handle == handle) { break; } } return mem_ptr; }
void aps_retry_expire(mem_ptr_t *mem_ptr) { if (mem_ptr) { APS_RETRY_ENTRY(mem_ptr)->retries--; if (APS_RETRY_ENTRY(mem_ptr)->retries > 0) { APS_RETRY_ENTRY(mem_ptr)->expiry = APS_ACK_WAIT_DURATION; aps_tx(APS_RETRY_ENTRY(mem_ptr)->buf, &APS_RETRY_ENTRY(mem_ptr)->hdr); } else { // we've used up all the retries. retire the entry. aps_conf(APS_NO_ACK, APS_RETRY_ENTRY(mem_ptr)->handle); aps_retry_free(mem_ptr); } } }