⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linkestimatorp.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 2 页
字号:

    if (NeighborTable[idx].rcvcnt >= BLQ_PKT_WINDOW) {
      updateNeighborTableEst(NeighborTable[idx].ll_addr);
    }

  }



  // print the neighbor table. for debugging.
  void print_neighbor_table() {
    uint8_t i;
    neighbor_table_entry_t *ne;
    for (i = 0; i < NEIGHBOR_TABLE_SIZE; i++) {
      ne = &NeighborTable[i];
      if (ne->flags & VALID_ENTRY) {
	dbg("LI,LITest", "%d:%d inQ=%d, inA=%d, outQ=%d, outA=%d, rcv=%d, fail=%d, biQ=%d\n",
	    i, ne->ll_addr, ne->inquality, ne->inage, ne->outquality, ne->outage,
	    ne->rcvcnt, ne->failcnt, computeBidirEETX(ne->inquality, ne->outquality));
      }
    }
  }

  // print the packet. for debugging.
  void print_packet(message_t* msg, uint8_t len) {
    uint8_t i;
    uint8_t* b;

    b = (uint8_t *)msg->data;
    for(i=0; i<len; i++)
      dbg_clear("LI", "%x ", b[i]);
    dbg_clear("LI", "\n");
  }

  // initialize the neighbor table in the very beginning
  void initNeighborTable() {
    uint8_t i;

    for (i = 0; i < NEIGHBOR_TABLE_SIZE; i++) {
      NeighborTable[i].flags = 0;
    }
  }

  command error_t StdControl.start() {
    dbg("LI", "Link estimator start\n");
    return SUCCESS;
  }

  command error_t StdControl.stop() {
    return SUCCESS;
  }

  // initialize the link estimator
  command error_t Init.init() {
    dbg("LI", "Link estimator init\n");
    initNeighborTable();
    return SUCCESS;
  }

  // return bi-directional link quality to the neighbor
  command uint16_t LinkEstimator.getLinkQuality(am_addr_t neighbor) {
    uint8_t idx;
    idx = findIdx(neighbor);
    if (idx == INVALID_RVAL) {
      return VERY_LARGE_EETX_VALUE;
    } else {
      if (NeighborTable[idx].flags & MATURE_ENTRY) {
	return NeighborTable[idx].eetx;
      } else {
	return VERY_LARGE_EETX_VALUE;
      }
    }
  }

  // return the quality of the link: neighor->self
  command uint16_t LinkEstimator.getReverseQuality(am_addr_t neighbor) {
    uint8_t idx;
    idx = findIdx(neighbor);
    if (idx == INVALID_RVAL) {
      return VERY_LARGE_EETX_VALUE;
    } else {
      if (NeighborTable[idx].flags & MATURE_ENTRY) {
	return computeEETX(NeighborTable[idx].inquality);
      } else {
	return VERY_LARGE_EETX_VALUE;
      }
    }
  }

  // return the quality of the link: self->neighbor
  command uint16_t LinkEstimator.getForwardQuality(am_addr_t neighbor) {
    uint8_t idx;
    idx = findIdx(neighbor);
    if (idx == INVALID_RVAL) {
      return VERY_LARGE_EETX_VALUE;
    } else {
      if (NeighborTable[idx].flags & MATURE_ENTRY) {
	return computeEETX(NeighborTable[idx].outquality);
      } else {
	return VERY_LARGE_EETX_VALUE;
      }
    }
  }

  // insert the neighbor at any cost (if there is a room for it)
  // even if eviction of a perfectly fine neighbor is called for
  command error_t LinkEstimator.insertNeighbor(am_addr_t neighbor) {
    uint8_t nidx;

    nidx = findIdx(neighbor);
    if (nidx != INVALID_RVAL) {
      dbg("LI", "insert: Found the entry, no need to insert\n");
      return SUCCESS;
    }

    nidx = findEmptyNeighborIdx();
    if (nidx != INVALID_RVAL) {
      dbg("LI", "insert: inserted into the empty slot\n");
      initNeighborIdx(nidx, neighbor);
      return SUCCESS;
    } else {
      nidx = findWorstNeighborIdx(BEST_EETX);
      if (nidx != INVALID_RVAL) {
	dbg("LI", "insert: inserted by replacing an entry for neighbor: %d\n",
	    NeighborTable[nidx].ll_addr);
	signal LinkEstimator.evicted(NeighborTable[nidx].ll_addr);
	initNeighborIdx(nidx, neighbor);
	return SUCCESS;
      }
    }
    return FAIL;
  }

  // pin a neighbor so that it does not get evicted
  command error_t LinkEstimator.pinNeighbor(am_addr_t neighbor) {
    uint8_t nidx = findIdx(neighbor);
    if (nidx == INVALID_RVAL) {
      return FAIL;
    }
    NeighborTable[nidx].flags |= PINNED_ENTRY;
    return SUCCESS;
  }

  // pin a neighbor so that it does not get evicted
  command error_t LinkEstimator.unpinNeighbor(am_addr_t neighbor) {
    uint8_t nidx = findIdx(neighbor);
    if (nidx == INVALID_RVAL) {
      return FAIL;
    }
    NeighborTable[nidx].flags &= ~PINNED_ENTRY;
    return SUCCESS;
  }


  // called when an acknowledgement is received; sign of a successful
  // data transmission; to update forward link quality
  command error_t LinkEstimator.txAck(am_addr_t neighbor) {
    neighbor_table_entry_t *ne;
    uint8_t nidx = findIdx(neighbor);
    if (nidx == INVALID_RVAL) {
      return FAIL;
    }
    ne = &NeighborTable[nidx];
    ne->data_success++;
    ne->data_total++;
    if (ne->data_total >= DLQ_PKT_WINDOW) {
      updateDEETX(ne);
    }
    return SUCCESS;
  }

  // called when an acknowledgement is not received; could be due to
  // data pkt or acknowledgement loss; to update forward link quality
  command error_t LinkEstimator.txNoAck(am_addr_t neighbor) {
    neighbor_table_entry_t *ne;
    uint8_t nidx = findIdx(neighbor);
    if (nidx == INVALID_RVAL) {
      return FAIL;
    }

    ne = &NeighborTable[nidx];
    ne->data_total++;
    if (ne->data_total >= DLQ_PKT_WINDOW) {
      updateDEETX(ne);
    }
    return SUCCESS;
  }

  // called when the parent changes; clear state about data-driven link quality
  command error_t LinkEstimator.clearDLQ(am_addr_t neighbor) {
    neighbor_table_entry_t *ne;
    uint8_t nidx = findIdx(neighbor);
    if (nidx == INVALID_RVAL) {
      return FAIL;
    }
    ne = &NeighborTable[nidx];
    ne->data_total = 0;
    ne->data_success = 0;
    return SUCCESS;
  }


  // user of link estimator calls send here
  // slap the header and footer before sending the message
  command error_t Send.send(am_addr_t addr, message_t* msg, uint8_t len) {
    uint8_t newlen;
    newlen = addLinkEstHeaderAndFooter(msg, len);
    dbg("LITest", "%s packet of length %hhu became %hhu\n", __FUNCTION__, len, newlen);
    dbg("LI", "Sending seq: %d\n", linkEstSeq);
    print_packet(msg, newlen);
    return call AMSend.send(addr, msg, newlen);
  }

  // done sending the message that originated by
  // the user of this component
  event void AMSend.sendDone(message_t* msg, error_t error ) {
    return signal Send.sendDone(msg, error);
  }

  // cascade the calls down
  command uint8_t Send.cancel(message_t* msg) {
    return call AMSend.cancel(msg);
  }

  command uint8_t Send.maxPayloadLength() {
    return call Packet.maxPayloadLength();
  }

  command void* Send.getPayload(message_t* msg, uint8_t len) {
    return call Packet.getPayload(msg, len);
  }

  // called when link estimator generator packet or
  // packets from upper layer that are wired to pass through
  // link estimator is received
  void processReceivedMessage(message_t* ONE msg, void* COUNT_NOK(len) payload, uint8_t len) {
    uint8_t nidx;
    uint8_t num_entries;

    dbg("LI", "LI receiving packet, buf addr: %x\n", payload);
    print_packet(msg, len);

    if (call SubAMPacket.destination(msg) == AM_BROADCAST_ADDR) {
      linkest_header_t* hdr = getHeader(msg);
      linkest_footer_t* ONE footer;
      am_addr_t ll_addr;

      ll_addr = call SubAMPacket.source(msg);

      dbg("LI", "Got seq: %d from link: %d\n", hdr->seq, ll_addr);

      num_entries = hdr->flags & NUM_ENTRIES_FLAG;
      print_neighbor_table();

      // update neighbor table with this information
      // find the neighbor
      // if found
      //   update the entry
      // else
      //   find an empty entry
      //   if found
      //     initialize the entry
      //   else
      //     find a bad neighbor to be evicted
      //     if found
      //       evict the neighbor and init the entry
      //     else
      //       we can not accommodate this neighbor in the table
      nidx = findIdx(ll_addr);
      if (nidx != INVALID_RVAL) {
	dbg("LI", "Found the entry so updating\n");
	updateNeighborEntryIdx(nidx, hdr->seq);
      } else {
	nidx = findEmptyNeighborIdx();
	if (nidx != INVALID_RVAL) {
	  dbg("LI", "Found an empty entry\n");
	  initNeighborIdx(nidx, ll_addr);
	  updateNeighborEntryIdx(nidx, hdr->seq);
	} else {
	  nidx = findWorstNeighborIdx(EVICT_EETX_THRESHOLD);
	  if (nidx != INVALID_RVAL) {
	    dbg("LI", "Evicted neighbor %d at idx %d\n",
		NeighborTable[nidx].ll_addr, nidx);
	    signal LinkEstimator.evicted(NeighborTable[nidx].ll_addr);
	    initNeighborIdx(nidx, ll_addr);
	  } else {
	    dbg("LI", "No room in the table\n");
	  }
	}
      }


      /* Graphical explanation of how we get to the head of the
       * footer in the following code 
       * <---------------------- payloadLen ------------------->
       * -------------------------------------------------------
       * linkest_header_t  | payload  | linkest_footer_t* ...|
       * -------------------------------------------------------
       * ^                              ^                      ^
       * |                              |                      |
       * subpayload                     |                      payloadEnd
       *                                |
       *                                payloadEnd - footersize*num footers
      */

      if ((nidx != INVALID_RVAL) && (num_entries > 0)) {
	uint8_t payloadLen = call SubPacket.payloadLength(msg);
	void* COUNT_NOK(payloadLen) subPayload = call SubPacket.getPayload(msg, payloadLen);
	void* payloadEnd = subPayload + payloadLen;
	dbg("LI", "Number of footer entries: %d\n", num_entries);
	
	footer = TCAST(linkest_footer_t* COUNT(num_entries), (payloadEnd - (num_entries*sizeof(linkest_footer_t))));
	{
	  uint8_t i;
	  am_addr_t my_ll_addr;
          neighbor_stat_entry_t * COUNT(num_entries) neighborLists;
	  my_ll_addr = call SubAMPacket.address();
          neighborLists = TCAST(neighbor_stat_entry_t * COUNT(num_entries), footer->neighborList);
	  for (i = 0; i < num_entries; i++) {
	    dbg("LI", "%d %d %d\n", i, neighborLists[i].ll_addr,
	    	neighborLists[i].inquality);
	    if (neighborLists[i].ll_addr == my_ll_addr) {
	      updateReverseQuality(ll_addr, neighborLists[i].inquality);
	    }
	  }
	}
      }
      print_neighbor_table();
    }


  }

  // new messages are received here
  // update the neighbor table with the header
  // and footer in the message
  // then signal the user of this component
  event message_t* SubReceive.receive(message_t* msg,
				      void* payload,
				      uint8_t len) {
    dbg("LI", "Received upper packet. Will signal up\n");
    processReceivedMessage(msg, payload, len);
    return signal Receive.receive(msg,
				  call Packet.getPayload(msg, call Packet.payloadLength(msg)),
				  call Packet.payloadLength(msg));
  }

  command void Packet.clear(message_t* msg) {
    call SubPacket.clear(msg);
  }

  // subtract the space occupied by the link estimation
  // header and footer from the incoming payload size
  command uint8_t Packet.payloadLength(message_t* msg) {
    linkest_header_t *hdr;
    hdr = getHeader(msg);
    return call SubPacket.payloadLength(msg)
      - sizeof(linkest_header_t)
      - sizeof(linkest_footer_t)*(NUM_ENTRIES_FLAG & hdr->flags);
  }

  // account for the space used by header and footer
  // while setting the payload length
  command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
    linkest_header_t *hdr;
    hdr = getHeader(msg);
    call SubPacket.setPayloadLength(msg,
				    len
				    + sizeof(linkest_header_t)
				    + sizeof(linkest_footer_t)*(NUM_ENTRIES_FLAG & hdr->flags));
  }

  command uint8_t Packet.maxPayloadLength() {
    return call SubPacket.maxPayloadLength() - sizeof(linkest_header_t);
  }

  // application payload pointer is just past the link estimation header
  command void* Packet.getPayload(message_t* msg, uint8_t len) {
    void* payload = call SubPacket.getPayload(msg, len +  sizeof(linkest_header_t));
    if (payload != NULL) {
      payload += sizeof(linkest_header_t);
    }
    return payload;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -