coap_timer.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #include "node.h"
  2. #include "coap_timer.h"
  3. #include "os_type.h"
  4. static os_timer_t coap_timer;
  5. static coap_tick_t basetime = 0;
  6. void coap_timer_elapsed(coap_tick_t *diff){
  7. coap_tick_t now = system_get_time() / 1000; // coap_tick_t is in ms. also sys_timer
  8. if(now>=basetime){
  9. *diff = now-basetime;
  10. } else {
  11. *diff = now + SYS_TIME_MAX -basetime;
  12. }
  13. basetime = now;
  14. }
  15. void coap_timer_tick(void *arg){
  16. if( !arg )
  17. return;
  18. coap_queue_t **queue = (coap_queue_t **)arg;
  19. if( !(*queue) )
  20. return;
  21. coap_queue_t *node = coap_pop_next( queue );
  22. /* re-initialize timeout when maximum number of retransmissions are not reached yet */
  23. if (node->retransmit_cnt < COAP_DEFAULT_MAX_RETRANSMIT) {
  24. node->retransmit_cnt++;
  25. node->t = node->timeout << node->retransmit_cnt;
  26. NODE_DBG("** retransmission #%d of transaction %d\n",
  27. node->retransmit_cnt, (((uint16_t)(node->pdu->pkt->hdr.id[0]))<<8)+node->pdu->pkt->hdr.id[1]);
  28. node->id = coap_send(node->pconn, node->pdu);
  29. if (COAP_INVALID_TID == node->id) {
  30. NODE_DBG("retransmission: error sending pdu\n");
  31. coap_delete_node(node);
  32. } else {
  33. coap_insert_node(queue, node);
  34. }
  35. } else {
  36. /* And finally delete the node */
  37. coap_delete_node( node );
  38. }
  39. coap_timer_start(queue);
  40. }
  41. void coap_timer_setup(coap_queue_t ** queue, coap_tick_t t){
  42. os_timer_disarm(&coap_timer);
  43. os_timer_setfn(&coap_timer, (os_timer_func_t *)coap_timer_tick, queue);
  44. os_timer_arm(&coap_timer, t, 0); // no repeat
  45. }
  46. void coap_timer_stop(void){
  47. os_timer_disarm(&coap_timer);
  48. }
  49. void coap_timer_update(coap_queue_t ** queue){
  50. if (!queue)
  51. return;
  52. coap_tick_t diff = 0;
  53. coap_queue_t *first = *queue;
  54. coap_timer_elapsed(&diff); // update: basetime = now, diff = now - oldbase, means time elapsed
  55. if (first) {
  56. // diff ms time is elapsed, re-calculate the first node->t
  57. if (first->t >= diff){
  58. first->t -= diff;
  59. } else {
  60. first->t = 0; // when timer enabled, time out almost immediately
  61. }
  62. }
  63. }
  64. void coap_timer_start(coap_queue_t ** queue){
  65. if(*queue){ // if there is node in the queue, set timeout to its ->t.
  66. coap_timer_setup(queue, (*queue)->t);
  67. }
  68. }