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

📄 udpshellp.nc

📁 tinyos-2.x.rar
💻 NC
字号:
/*
 * "Copyright (c) 2008 The Regents of the University  of California.
 * All rights reserved."
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */

#include <ip.h>
#include <IPDispatch.h>
#include <ICMP.h>
#include "Shell.h"

module UDPShellP {
  provides {
    interface ShellCommand[uint8_t cmd_id];
    interface RegisterShellCommand[uint8_t cmd_id];
  }
  uses {
    interface Boot;
    interface UDP;
    interface Leds;
    
    interface ICMPPing;
#if defined(PLATFORM_TELOSB) || defined(PLATFORM_EPIC)
    interface Counter<TMilli, uint32_t> as Uptime;
#endif

  }

} implementation {

  bool session_active;
  struct sockaddr_in6 session_endpoint;
  uint32_t boot_time;
  uint64_t uptime;

  enum {
    N_EXTERNAL = uniqueCount("UDPSHELL_CLIENTCOUNT"),
  };

  // and corresponding indeces
  enum {
    N_BUILTINS = 5,
    // the maximum number of arguments a command can take
    N_ARGS = 10,
    CMD_HELP = 0,
    CMD_ECHO = 1,
    CMD_PING6 = 2,
    CMD_TRACERT6 = 3,

    CMD_NO_CMD = 0xfe,
    CMDNAMSIZ = 10,
  };
  
  struct cmd_name {
    uint8_t c_len;
    char c_name[CMDNAMSIZ];
  };
  struct cmd_builtin {
    void (*action)(int, char **);
  };

  struct cmd_name externals[N_EXTERNAL];


  event void Boot.booted() {
    int i;
    atomic {
      uptime = 0;
#if defined(PLATFORM_TELOSB) || defined(PLATFORM_EPIC)
      boot_time = call Uptime.get();
#endif
    }
    for (i = 0; i < N_EXTERNAL; i++) {
      externals[i].c_name[CMDNAMSIZ-1] = '\0';
      strncpy(externals[i].c_name, signal RegisterShellCommand.getCommandName[i](), CMDNAMSIZ);
      externals[i].c_len = strlen(externals[i].c_name);
    }
    call UDP.bind(2000);
  }


#define DEREF(X)  #X
#define QUOTE(X)  DEREF(X)
  char reply_buf[MAX_REPLY_LEN];
  char *help_str = "sdsh-0.9\tbuiltins: [help, echo, ping6, uptime, ident]\n";
  const char *ping_fmt = " icmp_seq=%i ttl=%i time=%i ms\n";
  const char *ping_summary = "%i packets transmitted, %i received\n";
  char *ident_string = "\t[app: "
    IDENT_APPNAME "]\n\t[user: " IDENT_USERNAME "]\n\t[host: " IDENT_HOSTNAME
    "]\n\t[time: " QUOTE(IDENT_TIMESTAMP) "]\n";
  

  void action_help(int argc, char **argv) {
    int i = 0;
    char *pos = reply_buf;
    call UDP.sendto(&session_endpoint, help_str, strlen(help_str));
    if (N_EXTERNAL > 0) {
      strcpy(pos, "\t\t[");
      pos += 3;
      for (i = 0; i < N_EXTERNAL; i++) {
        if (externals[i].c_len + 4 < MAX_REPLY_LEN - (pos - reply_buf)) {
          memcpy(pos, externals[i].c_name, externals[i].c_len);
          pos += externals[i].c_len;
          if (i < N_EXTERNAL-1) {
            pos[0] = ',';
            pos[1] = ' ';
            pos += 2;
          } 
        } else {
          pos[0] = '.';
          pos[1] = '.';
          pos[2] = '.';
          pos += 3;
          break;
        }
      }
      *pos++ = ']';
      *pos++ = '\n';
      call UDP.sendto(&session_endpoint, reply_buf, pos - reply_buf);
    }
  }

  command char *ShellCommand.getBuffer[uint8_t cmd_id](uint16_t len) {
    reply_buf[0] = '\0';
    if (len <= MAX_REPLY_LEN) return reply_buf;
    return NULL;
  }

  command void ShellCommand.write[uint8_t cmd_id](char *str, int len) {
    call UDP.sendto(&session_endpoint, str, len);    
  }

  void action_echo(int argc, char **argv) {
    int i, arg_len;
    char *payload = reply_buf;

    if (argc < 2) return;
    for (i = 1; i < argc; i++) {
      arg_len = strlen(argv[i]);
      if ((payload - reply_buf) + arg_len + 1 > MAX_REPLY_LEN) break;
      memcpy(payload, argv[i], arg_len);
      payload += arg_len;
      *payload = ' ';
      payload++;
    }
    *(payload - 1) = '\n';

    call UDP.sendto(&session_endpoint, reply_buf, payload - reply_buf);
  }

  void action_ping6(int argc, char **argv) {
    struct in6_addr dest;

    if (argc < 2) return;
        inet_pton6(argv[1], &dest);
    call ICMPPing.ping(&dest, 1024, 10);
  }


  void action_uptime(int argc, char **argv) {
#if defined(PLATFORM_TELOSB) || defined(PLATFORM_EPIC)
    int len;
    uint64_t tval = call Uptime.get();
    atomic
      tval = (uptime + tval - boot_time) / 1024;
    len = snprintf(reply_buf, MAX_REPLY_LEN, "up %li seconds\n",
                   (uint32_t)tval);
    call UDP.sendto(&session_endpoint, reply_buf, len);
#endif
  }

  void action_ident(int argc, char **argv) {
    call UDP.sendto(&session_endpoint, ident_string, strlen(ident_string));
  }

  // commands 
  struct cmd_name builtins[N_BUILTINS] = {{4, "help"},
                                          {4, "echo"},  
                                          {5, "ping6"},
                                          {6, "uptime"},
                                          {5, "ident"}};
  struct cmd_builtin builtin_actions[N_BUILTINS] = {{action_help},
                                                    {action_echo},
                                                    {action_ping6},
                                                    {action_uptime},
                                                    {action_ident}};


  // break up a command given as a string into a sequence of null terminated
  // strings, and initialize the argv array to point into it.
  void init_argv(char *cmd, uint16_t len, char **argv, int *argc) {
    int inArg = 0;
    *argc = 0;
    while (len > 0 && *argc < N_ARGS) {
      if (*cmd == ' ' || *cmd == '\n' || *cmd == '\t' || *cmd == '\0' || len == 1){
        if (inArg) {
          *argc = *argc + 1;
          inArg = 0;
          *cmd = '\0';
        }
      } else if (!inArg) {
        argv[*argc] = cmd;
        inArg = 1;
      }
      cmd ++;
      len --;
    }
  }

  int lookup_cmd(char *cmd, int dbsize, struct cmd_name *db) {
    int i;
    for (i = 0; i < dbsize; i++) {
      if (memcmp(cmd, db[i].c_name, db[i].c_len) == 0 
          && cmd[db[i].c_len] == '\0')
        return i;
    }
    return CMD_NO_CMD;
  }

  event void UDP.recvfrom(struct sockaddr_in6 *from, void *data, 
                          uint16_t len, struct ip_metadata *meta) {
    char *argv[N_ARGS];
    int argc, cmd;

    memcpy(&session_endpoint, from, sizeof(struct sockaddr_in6));
    init_argv((char *)data, len, argv, &argc);

    if (argc > 0) {
      cmd = lookup_cmd(argv[0], N_BUILTINS, builtins);
      if (cmd != CMD_NO_CMD) {
        builtin_actions[cmd].action(argc, argv);
        return;
      }
      cmd = lookup_cmd(argv[0], N_EXTERNAL, externals);
      if (cmd != CMD_NO_CMD) {
        char *reply = signal ShellCommand.eval[cmd](argc, argv);
        if (reply != NULL)
          call UDP.sendto(&session_endpoint, reply, strlen(reply));
        return;
      }
      cmd = snprintf(reply_buf, MAX_REPLY_LEN, "sdsh: %s: command not found\n", argv[0]);
      call UDP.sendto(&session_endpoint, reply_buf, cmd);
    }
  }

  event void ICMPPing.pingReply(struct in6_addr *source, struct icmp_stats *stats) {
    int len;
    len = inet_ntop6(source, reply_buf, MAX_REPLY_LEN);
    if (len > 0) {
      len += snprintf(reply_buf + len - 1, MAX_REPLY_LEN - len + 1, ping_fmt,
                      stats->seq, stats->ttl, stats->rtt);
      call UDP.sendto(&session_endpoint, reply_buf, len);
    }
  }

  event void ICMPPing.pingDone(uint16_t ping_rcv, uint16_t ping_n) {
    int len;
    len = snprintf(reply_buf, MAX_REPLY_LEN, ping_summary, ping_n, ping_rcv);
    call UDP.sendto(&session_endpoint, reply_buf, len);
  }

#if  defined(PLATFORM_TELOSB) || defined(PLATFORM_EPIC)
  async event void Uptime.overflow() {
    atomic
      uptime += 0xffffffff;
  }
#endif

  default event char *ShellCommand.eval[uint8_t cmd_id](int argc, char **argv) {
    return NULL;
  }
  default event char *RegisterShellCommand.getCommandName[uint8_t cmd_id]() {
    return NULL;
  }
}

⌨️ 快捷键说明

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