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

📄 udpp.nc

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

#include <ip_malloc.h>
#include <in_cksum.h>
#include <Statistics.h>

module UdpP {
  provides interface UDP[uint8_t clnt];
  provides interface Init;
  provides interface Statistics<udp_statistics_t>;
  uses interface IP;
  uses interface IPAddress;
} implementation {

#ifdef PRINTFUART_ENABLED
#undef dbg
#define dbg(X,fmt, args...) printfUART(fmt, ##args)
#endif

  enum {
    N_CLIENTS = uniqueCount("UDP_CLIENT"),
  };

  udp_statistics_t stats;
  uint16_t local_ports[N_CLIENTS];

  enum {
    LOCAL_PORT_START = 51024U,
    LOCAL_PORT_STOP  = 54999U,
  };
  uint16_t last_localport = LOCAL_PORT_START;

  uint16_t alloc_lport(uint8_t clnt) {
    int i, done = 0;
    uint16_t compare = htons(last_localport);
    last_localport = (last_localport < LOCAL_PORT_START) ? last_localport + 1 : LOCAL_PORT_START;
    while (!done) {
      done = 1;
      for (i = 0; i < N_CLIENTS; i++) {
        if (local_ports[i] == compare) {
          last_localport = (last_localport < LOCAL_PORT_START) ? last_localport + 1 : LOCAL_PORT_START;
          compare = htons(last_localport);
          done = 0;
          break;
        }
      }
    }
    return last_localport;
  }

  command error_t Init.init() {
    call Statistics.clear();
    ip_memclr((uint8_t *)local_ports, sizeof(uint16_t) * N_CLIENTS);
    return SUCCESS;
  }

  command error_t UDP.bind[uint8_t clnt](uint16_t port) {
    int i;
    port = htons(port);
    if (port > 0) {
      for (i = 0; i < N_CLIENTS; i++)
        if (i != clnt && local_ports[i] == port)
          return FAIL;
    }
    local_ports[clnt] = port;
    return SUCCESS;
  }

  event void IP.recv(struct ip6_hdr *iph,
                     void *payload,
                     struct ip_metadata *meta) {
    int i;
    struct sockaddr_in6 addr;
    struct udp_hdr *udph = (struct udp_hdr *)payload;

    dbg("UDP", "UDP - IP.recv: len: %i srcport: %i dstport: %i\n",
        ntohs(iph->plen), ntohs(udph->srcport), ntohs(udph->dstport));

    for (i = 0; i < N_CLIENTS; i++)
      if (local_ports[i] == udph->dstport)
        break;

    if (i == N_CLIENTS) {
      // TODO : send ICMP port closed message here.
      return;
    }
    ip_memcpy(&addr.sin6_addr, &iph->ip6_src, 16);
    addr.sin6_port = udph->srcport;


    { 
      uint16_t rx_cksum = ntohs(udph->chksum), my_cksum;
      vec_t cksum_vec[4];
      uint32_t hdr[2];

      udph->chksum = 0;

      cksum_vec[0].ptr = (uint8_t *)(iph->ip6_src.s6_addr);
      cksum_vec[0].len = 16;
      cksum_vec[1].ptr = (uint8_t *)(iph->ip6_dst.s6_addr);
      cksum_vec[1].len = 16;
      cksum_vec[2].ptr = (uint8_t *)hdr;
      cksum_vec[2].len = 8;
      hdr[0] = iph->plen;
      hdr[1] = htonl(IANA_UDP);
      cksum_vec[3].ptr = payload;
      cksum_vec[3].len = ntohs(iph->plen);

      my_cksum = in_cksum(cksum_vec, 4);
      printfUART("rx cksum: %x calc: %x\n", rx_cksum, my_cksum);
      if (rx_cksum != my_cksum) {
        BLIP_STATS_INCR(stats.cksum);
        // return;
      }
    }

    BLIP_STATS_INCR(stats.rcvd);
    signal UDP.recvfrom[i](&addr, (void *)(udph + 1), ntohs(iph->plen) - sizeof(struct udp_hdr), meta);
  }

  /*
   * Injection point of IP datagrams.  This is only called for packets
   * being sent from this mote; packets which are being forwarded
   * never lave the stack and so never use this entry point.
   *
   * @msg an IP datagram with header fields (except for length)
   * @plen the length of the data payload added after the headers.
   */
  command error_t UDP.sendto[uint8_t clnt](struct sockaddr_in6 *dest, void *payload, 
                                           uint16_t len) {
    struct split_ip_msg *msg;
    struct udp_hdr *udp;
    struct generic_header *g_udp;
    error_t rc;

    // todo check + alloc local port

    msg = (struct split_ip_msg *)ip_malloc(sizeof(struct split_ip_msg) +
                                        sizeof(struct udp_hdr) +
                                        sizeof(struct generic_header));

    if (msg == NULL) {
      dbg("Drops", "drops: UDP send: malloc failure\n");
      return ERETRY;
    }
    udp = (struct udp_hdr *)(msg + 1);
    g_udp = (struct generic_header *)(udp + 1);

    // fill in all the packet fields
    ip_memclr((uint8_t *)msg, sizeof(struct split_ip_msg));
    ip_memclr((uint8_t *)udp, sizeof(struct udp_hdr));
    
    memcpy(&msg->hdr.ip6_dst, dest->sin6_addr.s6_addr, 16);
    call IPAddress.setSource(&msg->hdr);
    
    if (local_ports[clnt] == 0 && (local_ports[clnt] = alloc_lport(clnt)) == 0) {
      ip_free(msg);
      return FAIL;
    }
    udp->srcport = local_ports[clnt];
    udp->dstport = dest->sin6_port;
    udp->len = htons(len + sizeof(struct udp_hdr));
    udp->chksum = 0;

    // set up the pointers
    g_udp->len = sizeof(struct udp_hdr);
    g_udp->hdr.udp = udp;
    g_udp->next = NULL;
    msg->headers = g_udp;
    msg->data_len = len;
    msg->data = payload;
    msg->hdr.plen = udp->len;

    udp->chksum = htons(msg_cksum(msg, IANA_UDP)); 

    rc = call IP.send(msg);
    BLIP_STATS_INCR(stats.sent);

    ip_free(msg);
    return rc;

  }

  command void Statistics.clear() {
#ifdef BLIP_STATS
    ip_memclr((uint8_t *)&stats, sizeof(udp_statistics_t));
#endif
  }

  command void Statistics.get(udp_statistics_t *buf) {
#ifdef BLIP_STATS
    ip_memcpy(buf, &stats, sizeof(udp_statistics_t));
#endif
  }

  default event void UDP.recvfrom[uint8_t clnt](struct sockaddr_in6 *from, void *payload,
                                               uint16_t len, struct ip_metadata *meta) {

 }
}

⌨️ 快捷键说明

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