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

📄 ipdispatchp.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 3 页
字号:
        message_t *replacement = call FragPool.get();
        send_entry_t *s_entry = call SendEntryPool.get();
        uint16_t lowpan_size;
        uint8_t lowpan_offset;

        if (replacement == NULL || s_entry == NULL) {
          // we have to drop the rest of the framents if we don't have
          // a buffer...
          if (replacement != NULL)
            call FragPool.put(replacement);
          if (s_entry != NULL)
            call SendEntryPool.put(s_entry);

          BLIP_STATS_INCR(stats.fw_drop);
          fwd->timeout = T_FAILED1;
          goto fail;
        }
        // keep a reference for ourself, and pass it off to the
        // send_entry_t
        SENDINFO_INCR(fwd->s_info);

        getFragDgramOffset(&lowmsg, &lowpan_offset);
        getFragDgramSize(&lowmsg, &lowpan_size);
        if ((lowpan_offset * 8) + (lowmsg.len - (payload - lowmsg.data)) == lowpan_size) {
          // this is the last fragment. since delivery is in-order,
          // we want to free up that forwarding table entry.
          // take back the reference the table had.
          SENDINFO_DECR(fwd->s_info);
          fwd->timeout = T_UNUSED;
        }

        setFragDgramTag(&lowmsg, fwd->new_tag);

        s_entry->msg = msg;
        s_entry->info = fwd->s_info;

        dbg("IPDispatch", "forwarding: dest: 0x%x\n", 
            fwd->s_info->policy.dest[s_entry->info->policy.current]);

        if (call SendQueue.enqueue(s_entry) != SUCCESS) {
          BLIP_STATS_INCR(stats.encfail);
          dbg("Drops", "drops: receive enqueue failed\n");
        }
        post sendTask();
        return replacement;

      } else goto fail;
      goto done;
    }

  fail:
    dbg("Drops", "drops: receive()\n");;
    BLIP_STATS_INCR(stats.rx_drop);
  done:
    return msg;
  }


  /*
   * Send-side functionality
   */



  task void sendTask() {
    send_entry_t *s_entry;
    if (radioBusy || state != S_RUNNING) return;
    if (call SendQueue.empty()) return;
    // this does not dequeue
    s_entry = call SendQueue.head();


    call Ieee154Packet.setDestination(s_entry->msg, 
                                      s_entry->info->policy.dest[s_entry->info->policy.current]);
    call PacketLink.setRetries(s_entry->msg, s_entry->info->policy.retries);
    call PacketLink.setRetryDelay(s_entry->msg, s_entry->info->policy.delay);
#ifdef LPL_SLEEP_INTERVAL
    call LowPowerListening.setRemoteWakeupInterval(s_entry->msg, 
            call LowPowerListening.getLocalWakeupInterval());
#endif

    dbg("IPDispatch", "sendTask dest: 0x%x len: 0x%x \n", 
        call Ieee154Packet.destination(s_entry->msg),
        call Packet.payloadLength(s_entry->msg));
    
    if (s_entry->info->failed) {
      dbg("Drops", "drops: sendTask: dropping failed fragment\n");
      goto fail;
    }
          
    if ((call Ieee154Send.send(call Ieee154Packet.destination(s_entry->msg),
                               s_entry->msg,
                               call Packet.payloadLength(s_entry->msg))) != SUCCESS) {
      dbg("Drops", "drops: sendTask: send failed\n");
      goto fail;
    }
    radioBusy = TRUE;
    if (call SendQueue.empty()) return;
    // this does not dequeue
    s_entry = call SendQueue.head();

    return;
  fail:
    post sendTask();
    BLIP_STATS_INCR(stats.tx_drop);

    // deallocate the memory associated with this request.
    // other fragments associated with this packet will get dropped.
    s_entry->info->failed = TRUE;
    SENDINFO_DECR(s_entry->info);
    call FragPool.put(s_entry->msg);
    call SendEntryPool.put(s_entry);
    call SendQueue.dequeue();
  }
  

  /*
   * this interface is only for grownups; it is also only called for
   * local sends.
   *
   *  it will pack the message into the fragment pool and enqueue
   *  those fragments for sending
   *
   * it will set
   *  - payload length
   *  - version, traffic class and flow label
   *
   * the source and destination IP addresses must be set by higher
   * layers.
   */
  command error_t IP.send[uint8_t prot](struct split_ip_msg *msg) {
    msg->hdr.nxt_hdr = prot;
    return call IP.bareSend[prot](msg, NULL, 0);
  }

  command error_t IP.bareSend[uint8_t prot](struct split_ip_msg *msg, 
                              struct ip6_route *route,
                              int flags) {
    uint16_t payload_length;

    if (state != S_RUNNING) {
      return EOFF;
    }

    if (msg->hdr.hlim != 0xff)
      msg->hdr.hlim = call IPRouting.getHopLimit();

    printfUART("sending...\n");

    ip_memclr(msg->hdr.vlfc, 4);
    msg->hdr.vlfc[0] = IPV6_VERSION << 4;

    current_local_label++;
    if (!(flags & IP_NOHEADERS)) {
      call InternalIPExtension.addHeaders(msg, prot, current_local_label);

      if (route == NULL)
        route = call IPRouting.insertRoutingHeader(msg);
    }
                             
    payload_length = msg->data_len;
    {
      struct generic_header *cur = msg->headers;
      while (cur != NULL) {
        payload_length += cur->len;
        cur = cur->next;
      }
    }

    msg->hdr.plen = htons(payload_length);
    printfUART("sending: total length is: %i\n", payload_length);
    
    // okay, so we ought to have a fully setup chain of headers here,
    // so we ought to be able to compress everything into fragments.
    //

    {
      error_t rc = SUCCESS;
      send_info_t  *s_info;
      send_entry_t *s_entry;
      uint8_t frag_len = 1;
      message_t *outgoing;
      fragment_t progress;
      struct source_header *sh;
      progress.offset = 0;

      s_info = getSendInfo();
      if (s_info == NULL) {
        rc = ERETRY;
        goto cleanup_outer;
      }
      s_info->local_flow_label = current_local_label;

      // fill in destination information on outgoing fragments.
      sh = (msg->headers != NULL) ? (struct source_header *)msg->headers->hdr.ext : NULL;
      if (call IPRouting.getNextHop(&msg->hdr, route, 0x0,
                                    &s_info->policy) != SUCCESS) {
        dbg("Drops", "drops: IP send: getNextHop failed\n");
        goto done;
      }

      //goto done;
      while (frag_len > 0) {
        s_entry  = call SendEntryPool.get();
        outgoing = call FragPool.get();

        if (s_entry == NULL || outgoing == NULL) {
          if (s_entry != NULL)
            call SendEntryPool.put(s_entry);
          if (outgoing != NULL)
            call FragPool.put(outgoing);
          // this will cause any fragments we have already enqueued to
          // be dropped by the send task.
          s_info->failed = TRUE;
          dbg("Drops", "drops: IP send: no fragments\n");
          goto done;
        }

        // printfUART("getting frag... ");
        // ip_dump_msg(msg);

        frag_len = getNextFrag(msg, &progress, 
                               call Packet.getPayload(outgoing, call Packet.maxPayloadLength()),
                               call Packet.maxPayloadLength());
        // printfUART("got frag: len: %i\n", frag_len);
        if (frag_len == 0) {
          call FragPool.put(outgoing);
          call SendEntryPool.put(s_entry);
          goto done;
        }
        call Packet.setPayloadLength(outgoing, frag_len);

        s_entry->msg = outgoing;
        s_entry->info = s_info;

        if (call SendQueue.enqueue(s_entry) != SUCCESS) {
          BLIP_STATS_INCR(stats.encfail);
          dbg("Drops", "drops: IP send: enqueue failed\n");
          goto done;
        }

        SENDINFO_INCR(s_info);
//        printfUART("enqueue len 0x%x dest: 0x%x retries: 0x%x delay: 0x%x\n",frag_len,
//                   s_info->policy.dest, s_info->policy.retries, s_info->policy.delay);
      }
    done:
      BLIP_STATS_INCR(stats.sent);
      SENDINFO_DECR(s_info);
      post sendTask();
    cleanup_outer:
      call InternalIPExtension.free();

      return rc;
      
    }
  }

  event void Ieee154Send.sendDone(message_t *msg, error_t error) {
    send_entry_t *s_entry = call SendQueue.head();

    radioBusy = FALSE;

    if (state == S_STOPPING) {
      call RadioControl.stop();
      state = S_STOPPED;
      goto fail;
    }


    if (!call PacketLink.wasDelivered(msg)) {

      // if we haven't sent out any fragments yet, we can try rerouting
      if (s_entry->info->frags_sent == 0) {
        // SDH : TODO : if sending a fragment fails, abandon the rest of
        // the fragments
        s_entry->info->policy.current++;
        if (s_entry->info->policy.current < s_entry->info->policy.nchoices) {
          // this is the retry case; we don't need to change anything.
          post sendTask();
          return;
        }
        // no more next hops to try, so free the buffers and move on
      }    
      // a fragment failed, and it wasn't the first.  we drop all
      // remaining fragments.
      goto fail;
    } else {
      // the fragment was successfully sent.
      s_entry->info->frags_sent++;
      goto done;
    }
    goto done;
    
  fail:
    s_entry->info->failed = TRUE;
    if (s_entry->info->policy.dest[0] != 0xffff)
      dbg("Drops", "drops: sendDone: frag was not delivered\n");
    BLIP_STATS_INCR(stats.tx_drop);

  done:
    s_entry->info->policy.actRetries = call PacketLink.getRetries(msg);
    signal IPExtensions.reportTransmission(s_entry->info->local_flow_label, &s_entry->info->policy);
    // kill off any pending fragments
    SENDINFO_DECR(s_entry->info);
    call FragPool.put(s_entry->msg);
    call SendEntryPool.put(s_entry);
    call SendQueue.dequeue();

    post sendTask();
  }

  command struct tlv_hdr *IPExtensions.findTlv(struct ip6_ext *ext, uint8_t tlv_val) {
    int len = ext->len - sizeof(struct ip6_ext);
    struct tlv_hdr *tlv = (struct tlv_hdr *)(ext + 1);
    while (len > 0) {
      if (tlv->type == tlv_val) return tlv;
      if (tlv->len == 0) return NULL;
      tlv = (struct tlv_hdr *)(((uint8_t *)tlv) + tlv->len);
      len -= tlv->len;
    }
    return NULL;
  }

  event void ICMP.solicitationDone() {

  }

  /*
   * Statistics interface
   */
  command void Statistics.get(ip_statistics_t *statistics) {
#ifdef BLIP_STATS_IP_MEM
    stats.fragpool = call FragPool.size();
    stats.sendinfo = call SendInfoPool.size();
    stats.sendentry= call SendEntryPool.size();
    stats.sndqueue = call SendQueue.size();
    stats.heapfree = ip_malloc_freespace();
    printfUART("frag: %i sendinfo: %i sendentry: %i sendqueue: %i heap: %i\n",
               stats.fragpool,
               stats.sendinfo,
               stats.sendentry,
               stats.sndqueue,
               stats.heapfree);
#endif
    ip_memcpy(statistics, &stats, sizeof(ip_statistics_t));

  }

  command void Statistics.clear() {
    ip_memclr((uint8_t *)&stats, sizeof(ip_statistics_t));
  }

  default event void IP.recv[uint8_t nxt_hdr](struct ip6_hdr *iph,
                                              void *payload,
                                              struct ip_metadata *meta) {
  }
}

⌨️ 快捷键说明

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