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

📄 trackflowsp.nc

📁 tinyos-2.x.rar
💻 NC
字号:

#include "TrackFlows.h"

module TrackFlowsP {
  uses {
    interface Boot;
    interface SplitControl as SerialControl;
    interface IPExtensions;
    interface TLVHeader as Headers;
    interface AMSend as FlowSend;
  }
} implementation {
  

  bool flow_send_busy = FALSE;
  uint16_t current_flowid = 0;
  message_t flow_send;

  int send_flow_idx = -1, cur_idx = 0;
  nx_struct {
    nx_uint8_t flags;
    nx_uint8_t label;
    nx_struct flow_id_msg flow;
  } flow_cache[N_FORWARD_ENT * 3];

  int get_entry() {
    cur_idx = (cur_idx + 1) % (N_FORWARD_ENT * 3);
    return cur_idx;
  }
  int lookup_entry(uint8_t label) {
    int i;
    for (i = 0; i < N_FORWARD_ENT * 3; i++) {
      if (flow_cache[i].flags == 1 && flow_cache[i].label == label)
        return i;
    } 
    return -1;
  }
  
  event void Boot.booted() {
    call SerialControl.start();
    flow_send_busy = FALSE;
    ip_memclr((void *)flow_cache, sizeof(flow_cache));
  }

  event void FlowSend.sendDone(message_t *msg, error_t error) {
    flow_send_busy = FALSE;
    flow_cache[send_flow_idx].flags = 0;
  }

  void update_msg(struct ip6_hdr *iph, nx_struct flow_id *flow, uint8_t label, uint8_t nxt_hdr) {
    nx_struct flow_id_msg *payload;
    int i = get_entry();
    if (i < 0) return;
    flow_cache[i].flags = 1;
    flow_cache[i].label = label;
    payload = &flow_cache[i].flow;

    memcpy(&payload->flow, flow, sizeof(nx_struct flow_id));
    payload->src = ntohs(iph->ip6_src.s6_addr16[7]);
    payload->dst = ntohs(iph->ip6_dst.s6_addr16[7]);
    payload->local_address = TOS_NODE_ID;
    payload->nxt_hdr = nxt_hdr;
  }

  event void IPExtensions.handleExtensions(uint8_t label,
                                           struct ip6_hdr *iph,
                                           struct ip6_ext *hop,
                                           struct ip6_ext *dst,
                                           struct ip6_route *route,
                                           uint8_t nxt_hdr) {
    if (hop != NULL) {
      struct tlv_hdr *tlv = call IPExtensions.findTlv(hop, TLV_TYPE_FLOW);
      if (tlv != NULL && tlv->len == sizeof(struct tlv_hdr) + sizeof(nx_struct flow_id)) {
        update_msg(iph, (nx_struct flow_id *)(tlv + 1), label, nxt_hdr);
      }
    }
  }

  event void IPExtensions.reportTransmission(uint8_t label, send_policy_t *send) {
    int i, flow_idx = lookup_entry(label);
    nx_struct flow_id_msg *payload =
      (nx_struct flow_id_msg *)call FlowSend.getPayload(&flow_send, sizeof(nx_struct flow_id_msg));

    
    if (flow_idx < 0) return;
    memcpy(payload, &flow_cache[flow_idx].flow, sizeof(nx_struct flow_id_msg));


    payload->n_attempts = 0;
    for (i = 0; i < send->current && i < 3; i++) {
      // if (send->dest[i] == IEEE154_BROADCAST_ADDR) return;
      
      payload->attempts[i].next_hop = send->dest[i];
      payload->attempts[i].tx = send->retries;
    }
    if (i < 3) {
      payload->attempts[i].next_hop = send->dest[i];
      payload->attempts[i].tx = send->actRetries;
      i++;
    }
    payload->n_attempts = i;
    
    if (!flow_send_busy) {
      if (call FlowSend.send(0xffff, &flow_send, sizeof(nx_struct flow_id_msg)) == SUCCESS) {
        flow_send_busy = TRUE;
        send_flow_idx = flow_idx;
        return;
      } 
      // otherwise fall through and invalidate the cache
    }
    flow_cache[flow_idx].flags = 0;
  }

  event struct tlv_hdr *Headers.getHeader(uint8_t label,
                                          struct ip6_hdr *msg,
                                          uint8_t nxt_hdr) {
    static uint8_t buf[sizeof(struct tlv_hdr) + sizeof(nx_struct flow_id)];
    struct tlv_hdr *tlv;
    nx_struct flow_id *flow;
    tlv = (struct tlv_hdr *)buf;
    flow = (nx_struct flow_id *)(tlv + 1);

    tlv->type = TLV_TYPE_FLOW;
    tlv->len = sizeof(struct tlv_hdr) + sizeof(nx_struct flow_id);

/*     if (msg->ip6_dst.s6_addr[0] != 0xff ||  */
/*         (msg->ip6_dst.s6_addr[0] == 0xff &&  */
/*          (msg->ip6_dst.s6_addr[1] & 0x0f) > 2)) { */
      flow->id  = current_flowid++;

      update_msg(msg, flow, label, nxt_hdr);
      return tlv;
/*     } */
/*     return NULL; */
  }

  event void SerialControl.startDone(error_t e) { }
  event void SerialControl.stopDone(error_t e) { }

}

⌨️ 快捷键说明

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